@things-factory/warehouse-base 4.3.678 → 4.3.681
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -177,7 +177,8 @@ let InventoryHistoryQuery = class InventoryHistoryQuery {
|
|
|
177
177
|
OR Lower(prd.description) LIKE ANY(ARRAY[${productValue}])
|
|
178
178
|
OR Lower(prd.brand) LIKE ANY(ARRAY[${productValue}])
|
|
179
179
|
OR Lower(prd.brand_sku) LIKE ANY(ARRAY[${productValue}])
|
|
180
|
-
)
|
|
180
|
+
)
|
|
181
|
+
`;
|
|
181
182
|
}
|
|
182
183
|
let productDescQuery = '';
|
|
183
184
|
if (productDesc) {
|
|
@@ -190,7 +191,7 @@ let InventoryHistoryQuery = class InventoryHistoryQuery {
|
|
|
190
191
|
await tx.query(`
|
|
191
192
|
create temp table temp_products AS
|
|
192
193
|
(
|
|
193
|
-
select prd
|
|
194
|
+
select prd.id, prd.sku, prd.name, prd.description, prd.type, prd.aux_value_1 from products prd
|
|
194
195
|
inner join bizplaces b on b.id = prd.bizplace_id
|
|
195
196
|
inner join companies c on c.domain_id = b.domain_id
|
|
196
197
|
inner join bizplaces b2 on b2.company_id = c.id
|
|
@@ -201,124 +202,114 @@ let InventoryHistoryQuery = class InventoryHistoryQuery {
|
|
|
201
202
|
create temp table temp_data_src AS
|
|
202
203
|
(
|
|
203
204
|
SELECT prd.sku as sku, prd.name AS product_name, prd.description AS product_description, prd.type as product_type, prd.aux_value_1 AS product_aux_value_1, trim(invh.batch_id) as batch_id, invh.product_id,
|
|
204
|
-
invh.packing_type, invh.bizplace_id,
|
|
205
|
-
invh.
|
|
205
|
+
invh.packing_type, invh.bizplace_id,
|
|
206
|
+
invh.order_no, invh.order_ref_no, invh.transaction_type, invh.status, invh.created_at,
|
|
206
207
|
TRUNC(CAST(invh.qty AS NUMERIC), 3) as qty, TRUNC(CAST(invh.opening_qty AS NUMERIC), 3) as opening_qty,
|
|
207
208
|
invh.uom, TRUNC(CAST(COALESCE(invh.uom_value, 0) AS NUMERIC), 3) as uom_value, TRUNC(CAST(COALESCE(invh.opening_uom_value, 0) AS NUMERIC), 3) as opening_uom_value
|
|
208
|
-
FROM
|
|
209
|
+
FROM inventory_histories invh
|
|
209
210
|
INNER JOIN temp_products prd ON prd.id = invh.product_id::uuid
|
|
210
211
|
WHERE
|
|
211
|
-
invh.
|
|
212
|
+
(invh.qty <> 0 OR invh.uom_value <> 0)
|
|
213
|
+
AND invh.domain_id = $1
|
|
212
214
|
AND invh.bizplace_id = $2
|
|
213
215
|
AND invh.created_at <= $3::timestamp
|
|
214
216
|
${batchNoQuery}
|
|
215
217
|
)
|
|
216
218
|
`, [domain.id, bizplace.id, toDate.value]);
|
|
217
219
|
await tx.query(`
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
src.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
220
|
+
CREATE TEMP TABLE temp_inv_history AS (
|
|
221
|
+
SELECT
|
|
222
|
+
src.sku,
|
|
223
|
+
src.product_name,
|
|
224
|
+
src.product_description,
|
|
225
|
+
src.product_type,
|
|
226
|
+
src.product_aux_value_1,
|
|
227
|
+
src.batch_id,
|
|
228
|
+
src.product_id,
|
|
229
|
+
src.packing_type,
|
|
230
|
+
src.uom,
|
|
231
|
+
src.bizplace_id,
|
|
232
|
+
TRUNC(CAST(SUM(COALESCE(src.qty, 0)) AS NUMERIC), 3) AS qty,
|
|
233
|
+
TRUNC(CAST(SUM(COALESCE(src.opening_qty, 0)) AS NUMERIC), 3) AS opening_qty,
|
|
234
|
+
TRUNC(CAST(SUM(COALESCE(src.uom_value, 0)) AS NUMERIC), 3) AS uom_value,
|
|
235
|
+
TRUNC(CAST(SUM(COALESCE(src.opening_uom_value, 0)) AS NUMERIC), 3) AS opening_uom_value,
|
|
225
236
|
'Opening Balance' AS order_name,
|
|
226
237
|
'-' AS ref_no,
|
|
227
|
-
'-'
|
|
238
|
+
'-' AS transaction_type,
|
|
228
239
|
0 AS rn,
|
|
229
|
-
$1::timestamp AS created_at
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
src.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
240
|
+
$1::timestamp AS created_at
|
|
241
|
+
FROM temp_data_src src
|
|
242
|
+
WHERE src.created_at < $1::timestamp
|
|
243
|
+
GROUP BY
|
|
244
|
+
src.sku,
|
|
245
|
+
src.product_name,
|
|
246
|
+
src.product_description,
|
|
247
|
+
src.product_type,
|
|
248
|
+
src.product_aux_value_1,
|
|
249
|
+
src.batch_id,
|
|
250
|
+
src.product_id,
|
|
251
|
+
src.packing_type,
|
|
252
|
+
src.uom,
|
|
253
|
+
src.bizplace_id
|
|
254
|
+
|
|
255
|
+
UNION ALL
|
|
256
|
+
|
|
257
|
+
-- Part 2: All Inventory Movements (combined into a single scan)
|
|
258
|
+
-- This SELECT statement replaces the three separate UNION ALLs for
|
|
259
|
+
-- transaction movements, using CASE statements to handle different
|
|
260
|
+
-- transaction types and statuses in a single pass.
|
|
261
|
+
SELECT
|
|
262
|
+
sku,
|
|
263
|
+
product_name,
|
|
264
|
+
product_description,
|
|
265
|
+
product_type,
|
|
266
|
+
product_aux_value_1,
|
|
267
|
+
batch_id,
|
|
268
|
+
product_id,
|
|
269
|
+
packing_type,
|
|
270
|
+
uom,
|
|
271
|
+
bizplace_id,
|
|
272
|
+
TRUNC(CAST(SUM(
|
|
273
|
+
-- qty and uom_value logic for all cases combined
|
|
274
|
+
CASE
|
|
275
|
+
WHEN transaction_type = 'ADJUSTMENT' AND status = 'MISSING' THEN -opening_qty
|
|
276
|
+
ELSE qty
|
|
277
|
+
END
|
|
278
|
+
) AS NUMERIC), 3) AS qty,
|
|
279
|
+
TRUNC(CAST(SUM(opening_qty) AS NUMERIC), 3) AS opening_qty,
|
|
280
|
+
TRUNC(CAST(SUM(
|
|
281
|
+
CASE
|
|
282
|
+
WHEN transaction_type = 'ADJUSTMENT' AND status = 'MISSING' THEN -opening_uom_value
|
|
283
|
+
ELSE uom_value
|
|
284
|
+
END
|
|
285
|
+
) AS NUMERIC), 3) AS uom_value,
|
|
286
|
+
TRUNC(CAST(SUM(opening_uom_value) AS NUMERIC), 3) AS opening_uom_value,
|
|
287
|
+
CASE
|
|
288
|
+
WHEN transaction_type IN ('PICKING', 'CANCEL_ORDER') THEN order_no
|
|
289
|
+
WHEN transaction_type IN ('ADJUSTMENT', 'NEW') THEN transaction_type
|
|
290
|
+
ELSE COALESCE(order_no, '-')
|
|
291
|
+
END AS order_name,
|
|
265
292
|
CASE
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
created_at::
|
|
273
|
-
FROM
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
order_ref_no AS ref_no,
|
|
282
|
-
invh.created_at,
|
|
283
|
-
invh.created_at::date as created_date
|
|
284
|
-
FROM temp_data_src invh
|
|
285
|
-
WHERE (invh.qty <> 0 OR invh.uom_value <> 0) AND
|
|
286
|
-
(invh.transaction_type = 'ADJUSTMENT'
|
|
287
|
-
OR invh.transaction_type = 'PICKING'
|
|
288
|
-
OR invh.transaction_type = 'CANCEL_ORDER'
|
|
289
|
-
OR invh.transaction_type = 'NEW')
|
|
290
|
-
AND invh.created_at >= $1::timestamp
|
|
291
|
-
) AS inv_movement
|
|
292
|
-
GROUP BY
|
|
293
|
-
sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
294
|
-
domain_id, inv_movement.transaction_type,inv_movement.order_no,order_name, ref_no, rn, created_at
|
|
295
|
-
UNION ALL
|
|
296
|
-
SELECT sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
297
|
-
domain_id, TRUNC(CAST(sum(-opening_qty) AS NUMERIC), 3) as qty, TRUNC(CAST(sum(opening_qty) AS NUMERIC), 3) as opening_qty, TRUNC(CAST(sum(-opening_uom_value) AS NUMERIC), 3) as uom_value, TRUNC(CAST(sum(opening_uom_value) AS NUMERIC), 3) as opening_uom_value,
|
|
298
|
-
order_name, ref_no, transaction_type,1 AS rn, created_at - $2::interval as created_at, created_at::date as created_date
|
|
299
|
-
FROM (
|
|
300
|
-
SELECT invh.sku, invh.product_name, invh.product_description, invh.product_type, invh.product_aux_value_1, invh.batch_id, invh.product_id, invh.packing_type, invh.uom, invh.bizplace_id,
|
|
301
|
-
invh.domain_id,
|
|
302
|
-
invh.qty, invh.opening_qty, invh.uom_value, invh.opening_uom_value,
|
|
303
|
-
invh.transaction_type as transaction_type,
|
|
304
|
-
invh.transaction_type AS order_name,
|
|
305
|
-
invh.transaction_type AS ref_no,
|
|
306
|
-
invh.created_at,
|
|
307
|
-
invh.created_at:: date as created_date
|
|
308
|
-
FROM temp_data_src invh
|
|
309
|
-
WHERE
|
|
310
|
-
invh.transaction_type = 'ADJUSTMENT'
|
|
311
|
-
AND invh.status = 'MISSING'
|
|
312
|
-
AND invh.created_at >= $1::timestamp
|
|
313
|
-
) AS inv_movement
|
|
314
|
-
GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
315
|
-
domain_id, order_name, ref_no, inv_movement.transaction_type,rn, created_at
|
|
316
|
-
)`, [fromDate.value, tzoffset]);
|
|
293
|
+
WHEN transaction_type IN ('PICKING', 'CANCEL_ORDER') THEN order_ref_no
|
|
294
|
+
WHEN transaction_type IN ('ADJUSTMENT', 'NEW') THEN transaction_type
|
|
295
|
+
ELSE COALESCE(order_ref_no, '-')
|
|
296
|
+
END AS ref_no,
|
|
297
|
+
transaction_type,
|
|
298
|
+
1 AS rn,
|
|
299
|
+
MIN(created_at) - $2::interval AS created_at
|
|
300
|
+
FROM temp_data_src
|
|
301
|
+
WHERE
|
|
302
|
+
created_at >= $1::timestamp
|
|
303
|
+
GROUP BY
|
|
304
|
+
sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id,
|
|
305
|
+
packing_type, uom, bizplace_id,
|
|
306
|
+
order_name, ref_no, transaction_type
|
|
307
|
+
)`, [fromDate.value, tzoffset]);
|
|
317
308
|
let result;
|
|
318
309
|
if ((byPallet === null || byPallet === void 0 ? void 0 : byPallet.value) === true) {
|
|
319
310
|
result = await tx.query(`
|
|
320
311
|
select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
321
|
-
|
|
312
|
+
qty, opening_qty, round(uom_value::decimal,2) as uom_value, opening_uom_value, order_name, ref_no, transaction_type,created_at::date
|
|
322
313
|
from temp_inv_history invh where
|
|
323
314
|
exists (
|
|
324
315
|
select 1 from (
|
|
@@ -334,10 +325,10 @@ let InventoryHistoryQuery = class InventoryHistoryQuery {
|
|
|
334
325
|
else {
|
|
335
326
|
result = await tx.query(`
|
|
336
327
|
select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
337
|
-
|
|
328
|
+
sum(qty) as qty, sum(opening_qty) as opening_qty, sum(uom_value) as uom_value, sum(opening_uom_value) as opening_uom_value, order_name, ref_no, transaction_type, created_at::date
|
|
338
329
|
from(
|
|
339
330
|
select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
340
|
-
|
|
331
|
+
qty, opening_qty, TRUNC(CAST(uom_value AS NUMERIC), 3) as uom_value, opening_uom_value, order_name, ref_no, transaction_type,created_at
|
|
341
332
|
from temp_inv_history invh where
|
|
342
333
|
exists (
|
|
343
334
|
select 1 from (
|
|
@@ -349,7 +340,7 @@ let InventoryHistoryQuery = class InventoryHistoryQuery {
|
|
|
349
340
|
)
|
|
350
341
|
) foo
|
|
351
342
|
GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
352
|
-
|
|
343
|
+
order_name, ref_no, transaction_type, created_at
|
|
353
344
|
ORDER BY sku asc, product_name asc, product_description asc, packing_type asc, batch_id asc, uom asc, created_at asc,
|
|
354
345
|
CASE
|
|
355
346
|
WHEN transaction_type = 'CANCEL_ORDER' THEN 2
|
|
@@ -1524,91 +1515,250 @@ async function massageInventoryPalletSummary(tx, params, bizplace, context) {
|
|
|
1524
1515
|
let hasTransactionOrBalanceFilter = params.filters.find(data => data.name === 'hasTransactionOrBalance');
|
|
1525
1516
|
let hasTransactionOrBalanceQuery = '';
|
|
1526
1517
|
if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
|
|
1527
|
-
hasTransactionOrBalanceQuery = 'and (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)';
|
|
1518
|
+
hasTransactionOrBalanceQuery = 'and (c.opening_qty > 0 or c.total_in_qty > 0 or c.adjustment_qty > 0)';
|
|
1528
1519
|
}
|
|
1529
1520
|
await tx.query(`
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1521
|
+
create temp table temp_inventory_pallet_summary ON COMMIT DROP as
|
|
1522
|
+
with params as (
|
|
1523
|
+
select $1::timestamp as t1, $2::timestamp as t2
|
|
1524
|
+
),
|
|
1525
|
+
base as (
|
|
1526
|
+
select
|
|
1527
|
+
invh.*,
|
|
1528
|
+
prd.sku as product_sku,
|
|
1529
|
+
prd.name as product_name,
|
|
1530
|
+
prd.description as product_description,
|
|
1531
|
+
prd.type as product_type
|
|
1532
|
+
from temp_inv_history invh
|
|
1533
|
+
join temp_products prd on prd.id = invh.product_id
|
|
1534
|
+
),
|
|
1535
|
+
|
|
1536
|
+
/* ---- Opening snapshot as-of t1 (FIX) ----
|
|
1537
|
+
For each pallet, take the last row <= t1; if status='STORED',
|
|
1538
|
+
count it toward that row's product_id opening.
|
|
1539
|
+
*/
|
|
1540
|
+
opening_last_asof as (
|
|
1541
|
+
select *
|
|
1542
|
+
from (
|
|
1543
|
+
select h.*,
|
|
1544
|
+
row_number() over (partition by h.pallet_id order by h.created_at desc, h.seq desc) as rn
|
|
1545
|
+
from temp_inv_history h
|
|
1546
|
+
join params p on true
|
|
1547
|
+
where h.created_at <= p.t1
|
|
1548
|
+
) x
|
|
1549
|
+
where rn = 1 and status = 'STORED'
|
|
1550
|
+
),
|
|
1551
|
+
opening_agg as (
|
|
1552
|
+
select
|
|
1553
|
+
p.sku as product_sku,
|
|
1554
|
+
p.id as product_id,
|
|
1555
|
+
p.name as product_name,
|
|
1556
|
+
p.description as product_description,
|
|
1557
|
+
p.type as product_type,
|
|
1558
|
+
count(*)::int as opening_qty
|
|
1559
|
+
from opening_last_asof o
|
|
1560
|
+
join temp_products p on p.id = o.product_id
|
|
1561
|
+
group by p.sku, p.id, p.name, p.description, p.type
|
|
1562
|
+
),
|
|
1563
|
+
|
|
1564
|
+
/* ---- Arrivals inside window: first arrival-like row per pallet (your rule) ---- */
|
|
1565
|
+
invIn as (
|
|
1566
|
+
select b.*,
|
|
1567
|
+
row_number() over (partition by b.pallet_id order by b.created_at, b.seq) as rn
|
|
1568
|
+
from base b
|
|
1569
|
+
join params p on true
|
|
1570
|
+
where b.transaction_type in ('UNLOADING','NEW','CANCEL_ORDER')
|
|
1571
|
+
and b.created_at >= p.t1
|
|
1572
|
+
),
|
|
1573
|
+
invIn_first as (
|
|
1574
|
+
select
|
|
1575
|
+
pallet_id, seq, status, transaction_type,
|
|
1576
|
+
product_sku, product_id, product_name, product_description, product_type,
|
|
1577
|
+
inventory_history_id, packing_type, packing_size, qty, opening_qty, created_at
|
|
1578
|
+
from invIn
|
|
1579
|
+
where rn = 1
|
|
1580
|
+
),
|
|
1581
|
+
|
|
1582
|
+
/* ---- TERMINATED reps (incl. ADJUSTMENT terminations), using your runs logic ---- */
|
|
1583
|
+
status_runs as (
|
|
1584
|
+
select
|
|
1585
|
+
endData.pallet_id,
|
|
1586
|
+
min(endData.created_at) as started_at,
|
|
1587
|
+
max(endData.created_at) as ended_at,
|
|
1588
|
+
min(endData.seq) as min_seq,
|
|
1589
|
+
max(endData.seq) as max_seq,
|
|
1590
|
+
endData.status
|
|
1591
|
+
from (
|
|
1592
|
+
select startData.*,
|
|
1593
|
+
sum(startflag) over (partition by startData.pallet_id order by startData.seq) as grp
|
|
1594
|
+
from (
|
|
1595
|
+
select s.*,
|
|
1596
|
+
case when lag(s.status) over (partition by s.pallet_id order by s.seq) = s.status then 0 else 1 end as startflag
|
|
1597
|
+
from temp_inv_history s
|
|
1598
|
+
) startData
|
|
1599
|
+
) endData
|
|
1600
|
+
group by endData.pallet_id, endData.status, endData.grp
|
|
1601
|
+
),
|
|
1602
|
+
invOut_base as (
|
|
1603
|
+
select b.*, r.started_at
|
|
1604
|
+
from base b
|
|
1605
|
+
join status_runs r
|
|
1606
|
+
on r.pallet_id = b.pallet_id
|
|
1607
|
+
and r.min_seq <= b.seq
|
|
1608
|
+
and r.max_seq >= b.seq
|
|
1609
|
+
where b.status = 'TERMINATED'
|
|
1610
|
+
and b.transaction_type in ('TERMINATED','ADJUSTMENT')
|
|
1611
|
+
),
|
|
1612
|
+
|
|
1613
|
+
/* ---- Transfer pairing (seq-gap tolerant & tolerant txn tags) ---- */
|
|
1614
|
+
/* STORED side in-window; pair to nearest prior TERMINATED (from raw history), different product */
|
|
1615
|
+
adj_stored AS (
|
|
1616
|
+
SELECT b.*
|
|
1617
|
+
FROM base b
|
|
1618
|
+
JOIN params p ON TRUE
|
|
1619
|
+
WHERE b.status = 'STORED'
|
|
1620
|
+
AND b.created_at BETWEEN p.t1 AND p.t2
|
|
1621
|
+
),
|
|
1622
|
+
adj_pairs AS (
|
|
1623
|
+
SELECT
|
|
1624
|
+
s.pallet_id,
|
|
1625
|
+
s.seq AS stored_seq,
|
|
1626
|
+
t.seq AS terminated_seq,
|
|
1627
|
+
s.product_id AS new_product_id,
|
|
1628
|
+
t.product_id AS old_product_id,
|
|
1629
|
+
s.inventory_history_id AS stored_inventory_history_id,
|
|
1630
|
+
t.inventory_history_id AS terminated_inventory_history_id,
|
|
1631
|
+
s.created_at AS stored_at,
|
|
1632
|
+
t.created_at AS terminated_at,
|
|
1633
|
+
s.transaction_type AS stored_txn,
|
|
1634
|
+
t.transaction_type AS terminated_txn
|
|
1635
|
+
FROM adj_stored s
|
|
1636
|
+
JOIN LATERAL (
|
|
1637
|
+
SELECT t.*
|
|
1638
|
+
FROM temp_inv_history t -- use raw history (old product may be outside temp_products)
|
|
1639
|
+
WHERE t.pallet_id = s.pallet_id
|
|
1640
|
+
AND t.seq < s.seq
|
|
1641
|
+
AND t.status = 'TERMINATED'
|
|
1642
|
+
ORDER BY t.seq DESC
|
|
1643
|
+
LIMIT 1
|
|
1644
|
+
) t ON TRUE
|
|
1645
|
+
WHERE t.product_id IS DISTINCT FROM s.product_id
|
|
1646
|
+
AND (s.transaction_type='ADJUSTMENT' OR t.transaction_type='ADJUSTMENT')
|
|
1647
|
+
),
|
|
1648
|
+
adj_pairs_terminated_keys AS (
|
|
1649
|
+
SELECT pallet_id, terminated_seq AS seq
|
|
1650
|
+
FROM adj_pairs
|
|
1651
|
+
),
|
|
1652
|
+
|
|
1653
|
+
/* Representative TERMINATED per (pallet, product), EXCLUDING those used by a pair (avoid double-count) */
|
|
1654
|
+
invOut_rep AS (
|
|
1655
|
+
SELECT *
|
|
1656
|
+
FROM (
|
|
1657
|
+
SELECT iob.*,
|
|
1658
|
+
row_number() over (partition by iob.pallet_id, iob.product_id order by iob.seq desc) as rn
|
|
1659
|
+
FROM invOut_base iob
|
|
1660
|
+
LEFT JOIN adj_pairs_terminated_keys k
|
|
1661
|
+
ON k.pallet_id = iob.pallet_id
|
|
1662
|
+
AND k.seq = iob.seq
|
|
1663
|
+
WHERE k.pallet_id IS NULL
|
|
1664
|
+
) z
|
|
1665
|
+
WHERE rn = 1
|
|
1666
|
+
),
|
|
1667
|
+
|
|
1668
|
+
/* Materialize both sides of the paired transfer */
|
|
1669
|
+
adj_pairs_stored_rows AS (
|
|
1670
|
+
SELECT
|
|
1671
|
+
b.pallet_id, b.seq, b.status, b.transaction_type,
|
|
1672
|
+
b.product_sku, b.product_id, b.product_name, b.product_description, b.product_type,
|
|
1673
|
+
b.inventory_history_id, b.packing_type, b.packing_size, b.qty, b.opening_qty, b.created_at
|
|
1674
|
+
FROM base b
|
|
1675
|
+
JOIN adj_pairs ap
|
|
1676
|
+
ON ap.pallet_id = b.pallet_id
|
|
1677
|
+
AND ap.stored_seq = b.seq
|
|
1678
|
+
),
|
|
1679
|
+
adj_pairs_terminated_rows AS (
|
|
1680
|
+
SELECT
|
|
1681
|
+
b.pallet_id, b.seq, b.status, b.transaction_type,
|
|
1682
|
+
b.product_sku, b.product_id, b.product_name, b.product_description, b.product_type,
|
|
1683
|
+
b.inventory_history_id, b.packing_type, b.packing_size, b.qty, b.opening_qty, b.created_at
|
|
1684
|
+
FROM base b
|
|
1685
|
+
JOIN adj_pairs ap
|
|
1686
|
+
ON ap.pallet_id = b.pallet_id
|
|
1687
|
+
AND ap.terminated_seq = b.seq
|
|
1688
|
+
),
|
|
1689
|
+
|
|
1690
|
+
/* ---- Unified stream for window movement ---- */
|
|
1691
|
+
invHistory as (
|
|
1692
|
+
select * from invIn_first
|
|
1693
|
+
union all
|
|
1694
|
+
select
|
|
1695
|
+
pallet_id, seq, status, transaction_type,
|
|
1696
|
+
product_sku, product_id, product_name, product_description, product_type,
|
|
1697
|
+
inventory_history_id, packing_type, packing_size, qty, opening_qty, created_at
|
|
1698
|
+
from invOut_rep
|
|
1699
|
+
union all
|
|
1700
|
+
select * from adj_pairs_stored_rows
|
|
1701
|
+
union all
|
|
1702
|
+
select * from adj_pairs_terminated_rows
|
|
1703
|
+
),
|
|
1704
|
+
|
|
1705
|
+
/* ---- Movement aggregation only (no opening here) ---- */
|
|
1706
|
+
movement_agg as (
|
|
1707
|
+
select
|
|
1708
|
+
ih.product_sku,
|
|
1709
|
+
ih.product_id,
|
|
1710
|
+
ih.product_name,
|
|
1711
|
+
ih.product_description,
|
|
1712
|
+
ih.product_type,
|
|
1713
|
+
|
|
1714
|
+
sum(case when ih.created_at >= (select t1 from params)
|
|
1715
|
+
and ih.created_at <= (select t2 from params) then
|
|
1716
|
+
case when ih.transaction_type in ('UNLOADING','NEW','CANCEL_ORDER') then 1 else 0 end
|
|
1717
|
+
else 0 end)::int as total_in_qty,
|
|
1718
|
+
|
|
1719
|
+
sum(case when ih.created_at >= (select t1 from params)
|
|
1720
|
+
and ih.created_at <= (select t2 from params) then
|
|
1721
|
+
case when ih.status = 'TERMINATED'
|
|
1722
|
+
and ih.transaction_type <> 'ADJUSTMENT' then -1 else 0 end
|
|
1723
|
+
else 0 end)::int as total_out_qty,
|
|
1724
|
+
|
|
1725
|
+
sum(case when ih.created_at >= (select t1 from params)
|
|
1726
|
+
and ih.created_at <= (select t2 from params) then
|
|
1727
|
+
case when ih.status = 'TERMINATED' and ih.transaction_type = 'ADJUSTMENT' then -1
|
|
1728
|
+
when ih.status = 'STORED' and ih.transaction_type = 'ADJUSTMENT' then 1
|
|
1729
|
+
else 0 end
|
|
1730
|
+
else 0 end)::int as adjustment_qty
|
|
1731
|
+
|
|
1732
|
+
from invHistory ih
|
|
1733
|
+
group by ih.product_sku, ih.product_id, ih.product_name, ih.product_description, ih.product_type
|
|
1734
|
+
),
|
|
1735
|
+
|
|
1736
|
+
/* ---- Combine opening snapshot + window movement ---- */
|
|
1737
|
+
combined as (
|
|
1738
|
+
select
|
|
1739
|
+
coalesce(o.product_sku, m.product_sku) as product_sku,
|
|
1740
|
+
coalesce(o.product_id, m.product_id) as product_id,
|
|
1741
|
+
coalesce(o.product_name,m.product_name) as product_name,
|
|
1742
|
+
coalesce(o.product_description,m.product_description) as product_description,
|
|
1743
|
+
coalesce(o.product_type,m.product_type) as product_type,
|
|
1744
|
+
|
|
1745
|
+
coalesce(o.opening_qty, 0) as opening_qty,
|
|
1746
|
+
coalesce(m.total_in_qty, 0) as total_in_qty,
|
|
1747
|
+
coalesce(m.total_out_qty, 0) as total_out_qty,
|
|
1748
|
+
coalesce(m.adjustment_qty, 0) as adjustment_qty
|
|
1749
|
+
from opening_agg o
|
|
1750
|
+
full outer join movement_agg m
|
|
1751
|
+
on m.product_id = o.product_id
|
|
1610
1752
|
)
|
|
1611
|
-
|
|
1753
|
+
|
|
1754
|
+
select
|
|
1755
|
+
c.*,
|
|
1756
|
+
(c.opening_qty + c.total_in_qty + c.total_out_qty + c.adjustment_qty) as closing_qty
|
|
1757
|
+
from combined c
|
|
1758
|
+
where 1=1
|
|
1759
|
+
${hasTransactionOrBalanceQuery}
|
|
1760
|
+
;
|
|
1761
|
+
`, [fromDate.value, toDate.value]);
|
|
1612
1762
|
const total = await tx.query(`select count(*) as count, sum(total_in_qty) as totalInQty, sum(opening_qty) as totalOpeningBal from temp_inventory_pallet_summary`);
|
|
1613
1763
|
const result = await tx.query(`
|
|
1614
1764
|
select *, 'PALLET' as packing_type from temp_inventory_pallet_summary ORDER BY product_name, product_description OFFSET $1 LIMIT $2
|