@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.
|
@@ -235,7 +235,8 @@ export class InventoryHistoryQuery {
|
|
|
235
235
|
OR Lower(prd.description) LIKE ANY(ARRAY[${productValue}])
|
|
236
236
|
OR Lower(prd.brand) LIKE ANY(ARRAY[${productValue}])
|
|
237
237
|
OR Lower(prd.brand_sku) LIKE ANY(ARRAY[${productValue}])
|
|
238
|
-
)
|
|
238
|
+
)
|
|
239
|
+
`
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
let productDescQuery = ''
|
|
@@ -247,12 +248,11 @@ export class InventoryHistoryQuery {
|
|
|
247
248
|
if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
|
|
248
249
|
hasTransactionOrBalanceQuery = 'and (src.totalRow > 1 or src.totalQty <> 0)'
|
|
249
250
|
}
|
|
250
|
-
|
|
251
251
|
await tx.query(
|
|
252
252
|
`
|
|
253
253
|
create temp table temp_products AS
|
|
254
254
|
(
|
|
255
|
-
select prd
|
|
255
|
+
select prd.id, prd.sku, prd.name, prd.description, prd.type, prd.aux_value_1 from products prd
|
|
256
256
|
inner join bizplaces b on b.id = prd.bizplace_id
|
|
257
257
|
inner join companies c on c.domain_id = b.domain_id
|
|
258
258
|
inner join bizplaces b2 on b2.company_id = c.id
|
|
@@ -261,20 +261,20 @@ export class InventoryHistoryQuery {
|
|
|
261
261
|
)`,
|
|
262
262
|
[bizplace.id]
|
|
263
263
|
)
|
|
264
|
-
|
|
265
264
|
await tx.query(
|
|
266
265
|
`
|
|
267
266
|
create temp table temp_data_src AS
|
|
268
267
|
(
|
|
269
268
|
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,
|
|
270
|
-
invh.packing_type, invh.bizplace_id,
|
|
271
|
-
invh.
|
|
269
|
+
invh.packing_type, invh.bizplace_id,
|
|
270
|
+
invh.order_no, invh.order_ref_no, invh.transaction_type, invh.status, invh.created_at,
|
|
272
271
|
TRUNC(CAST(invh.qty AS NUMERIC), 3) as qty, TRUNC(CAST(invh.opening_qty AS NUMERIC), 3) as opening_qty,
|
|
273
272
|
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
|
|
274
|
-
FROM
|
|
273
|
+
FROM inventory_histories invh
|
|
275
274
|
INNER JOIN temp_products prd ON prd.id = invh.product_id::uuid
|
|
276
275
|
WHERE
|
|
277
|
-
invh.
|
|
276
|
+
(invh.qty <> 0 OR invh.uom_value <> 0)
|
|
277
|
+
AND invh.domain_id = $1
|
|
278
278
|
AND invh.bizplace_id = $2
|
|
279
279
|
AND invh.created_at <= $3::timestamp
|
|
280
280
|
${batchNoQuery}
|
|
@@ -285,105 +285,94 @@ export class InventoryHistoryQuery {
|
|
|
285
285
|
|
|
286
286
|
await tx.query(
|
|
287
287
|
`
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
src.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
288
|
+
CREATE TEMP TABLE temp_inv_history AS (
|
|
289
|
+
SELECT
|
|
290
|
+
src.sku,
|
|
291
|
+
src.product_name,
|
|
292
|
+
src.product_description,
|
|
293
|
+
src.product_type,
|
|
294
|
+
src.product_aux_value_1,
|
|
295
|
+
src.batch_id,
|
|
296
|
+
src.product_id,
|
|
297
|
+
src.packing_type,
|
|
298
|
+
src.uom,
|
|
299
|
+
src.bizplace_id,
|
|
300
|
+
TRUNC(CAST(SUM(COALESCE(src.qty, 0)) AS NUMERIC), 3) AS qty,
|
|
301
|
+
TRUNC(CAST(SUM(COALESCE(src.opening_qty, 0)) AS NUMERIC), 3) AS opening_qty,
|
|
302
|
+
TRUNC(CAST(SUM(COALESCE(src.uom_value, 0)) AS NUMERIC), 3) AS uom_value,
|
|
303
|
+
TRUNC(CAST(SUM(COALESCE(src.opening_uom_value, 0)) AS NUMERIC), 3) AS opening_uom_value,
|
|
295
304
|
'Opening Balance' AS order_name,
|
|
296
305
|
'-' AS ref_no,
|
|
297
|
-
'-'
|
|
306
|
+
'-' AS transaction_type,
|
|
298
307
|
0 AS rn,
|
|
299
|
-
$1::timestamp AS created_at
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
src.
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
308
|
+
$1::timestamp AS created_at
|
|
309
|
+
FROM temp_data_src src
|
|
310
|
+
WHERE src.created_at < $1::timestamp
|
|
311
|
+
GROUP BY
|
|
312
|
+
src.sku,
|
|
313
|
+
src.product_name,
|
|
314
|
+
src.product_description,
|
|
315
|
+
src.product_type,
|
|
316
|
+
src.product_aux_value_1,
|
|
317
|
+
src.batch_id,
|
|
318
|
+
src.product_id,
|
|
319
|
+
src.packing_type,
|
|
320
|
+
src.uom,
|
|
321
|
+
src.bizplace_id
|
|
322
|
+
|
|
323
|
+
UNION ALL
|
|
324
|
+
|
|
325
|
+
-- Part 2: All Inventory Movements (combined into a single scan)
|
|
326
|
+
-- This SELECT statement replaces the three separate UNION ALLs for
|
|
327
|
+
-- transaction movements, using CASE statements to handle different
|
|
328
|
+
-- transaction types and statuses in a single pass.
|
|
329
|
+
SELECT
|
|
330
|
+
sku,
|
|
331
|
+
product_name,
|
|
332
|
+
product_description,
|
|
333
|
+
product_type,
|
|
334
|
+
product_aux_value_1,
|
|
335
|
+
batch_id,
|
|
336
|
+
product_id,
|
|
337
|
+
packing_type,
|
|
338
|
+
uom,
|
|
339
|
+
bizplace_id,
|
|
340
|
+
TRUNC(CAST(SUM(
|
|
341
|
+
-- qty and uom_value logic for all cases combined
|
|
342
|
+
CASE
|
|
343
|
+
WHEN transaction_type = 'ADJUSTMENT' AND status = 'MISSING' THEN -opening_qty
|
|
344
|
+
ELSE qty
|
|
345
|
+
END
|
|
346
|
+
) AS NUMERIC), 3) AS qty,
|
|
347
|
+
TRUNC(CAST(SUM(opening_qty) AS NUMERIC), 3) AS opening_qty,
|
|
348
|
+
TRUNC(CAST(SUM(
|
|
349
|
+
CASE
|
|
350
|
+
WHEN transaction_type = 'ADJUSTMENT' AND status = 'MISSING' THEN -opening_uom_value
|
|
351
|
+
ELSE uom_value
|
|
352
|
+
END
|
|
353
|
+
) AS NUMERIC), 3) AS uom_value,
|
|
354
|
+
TRUNC(CAST(SUM(opening_uom_value) AS NUMERIC), 3) AS opening_uom_value,
|
|
335
355
|
CASE
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
(invh.transaction_type = 'ADJUSTMENT'
|
|
357
|
-
OR invh.transaction_type = 'PICKING'
|
|
358
|
-
OR invh.transaction_type = 'CANCEL_ORDER'
|
|
359
|
-
OR invh.transaction_type = 'NEW')
|
|
360
|
-
AND invh.created_at >= $1::timestamp
|
|
361
|
-
) AS inv_movement
|
|
362
|
-
GROUP BY
|
|
363
|
-
sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
364
|
-
domain_id, inv_movement.transaction_type,inv_movement.order_no,order_name, ref_no, rn, created_at
|
|
365
|
-
UNION ALL
|
|
366
|
-
SELECT sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
367
|
-
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,
|
|
368
|
-
order_name, ref_no, transaction_type,1 AS rn, created_at - $2::interval as created_at, created_at::date as created_date
|
|
369
|
-
FROM (
|
|
370
|
-
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,
|
|
371
|
-
invh.domain_id,
|
|
372
|
-
invh.qty, invh.opening_qty, invh.uom_value, invh.opening_uom_value,
|
|
373
|
-
invh.transaction_type as transaction_type,
|
|
374
|
-
invh.transaction_type AS order_name,
|
|
375
|
-
invh.transaction_type AS ref_no,
|
|
376
|
-
invh.created_at,
|
|
377
|
-
invh.created_at:: date as created_date
|
|
378
|
-
FROM temp_data_src invh
|
|
379
|
-
WHERE
|
|
380
|
-
invh.transaction_type = 'ADJUSTMENT'
|
|
381
|
-
AND invh.status = 'MISSING'
|
|
382
|
-
AND invh.created_at >= $1::timestamp
|
|
383
|
-
) AS inv_movement
|
|
384
|
-
GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
385
|
-
domain_id, order_name, ref_no, inv_movement.transaction_type,rn, created_at
|
|
386
|
-
)`,
|
|
356
|
+
WHEN transaction_type IN ('PICKING', 'CANCEL_ORDER') THEN order_no
|
|
357
|
+
WHEN transaction_type IN ('ADJUSTMENT', 'NEW') THEN transaction_type
|
|
358
|
+
ELSE COALESCE(order_no, '-')
|
|
359
|
+
END AS order_name,
|
|
360
|
+
CASE
|
|
361
|
+
WHEN transaction_type IN ('PICKING', 'CANCEL_ORDER') THEN order_ref_no
|
|
362
|
+
WHEN transaction_type IN ('ADJUSTMENT', 'NEW') THEN transaction_type
|
|
363
|
+
ELSE COALESCE(order_ref_no, '-')
|
|
364
|
+
END AS ref_no,
|
|
365
|
+
transaction_type,
|
|
366
|
+
1 AS rn,
|
|
367
|
+
MIN(created_at) - $2::interval AS created_at
|
|
368
|
+
FROM temp_data_src
|
|
369
|
+
WHERE
|
|
370
|
+
created_at >= $1::timestamp
|
|
371
|
+
GROUP BY
|
|
372
|
+
sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id,
|
|
373
|
+
packing_type, uom, bizplace_id,
|
|
374
|
+
order_name, ref_no, transaction_type
|
|
375
|
+
)`,
|
|
387
376
|
[fromDate.value, tzoffset]
|
|
388
377
|
)
|
|
389
378
|
|
|
@@ -393,7 +382,7 @@ export class InventoryHistoryQuery {
|
|
|
393
382
|
result = await tx.query(
|
|
394
383
|
`
|
|
395
384
|
select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
396
|
-
|
|
385
|
+
qty, opening_qty, round(uom_value::decimal,2) as uom_value, opening_uom_value, order_name, ref_no, transaction_type,created_at::date
|
|
397
386
|
from temp_inv_history invh where
|
|
398
387
|
exists (
|
|
399
388
|
select 1 from (
|
|
@@ -410,10 +399,10 @@ export class InventoryHistoryQuery {
|
|
|
410
399
|
result = await tx.query(
|
|
411
400
|
`
|
|
412
401
|
select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
413
|
-
|
|
402
|
+
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
|
|
414
403
|
from(
|
|
415
404
|
select sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
416
|
-
|
|
405
|
+
qty, opening_qty, TRUNC(CAST(uom_value AS NUMERIC), 3) as uom_value, opening_uom_value, order_name, ref_no, transaction_type,created_at
|
|
417
406
|
from temp_inv_history invh where
|
|
418
407
|
exists (
|
|
419
408
|
select 1 from (
|
|
@@ -425,7 +414,7 @@ export class InventoryHistoryQuery {
|
|
|
425
414
|
)
|
|
426
415
|
) foo
|
|
427
416
|
GROUP BY sku, product_name, product_description, product_type, product_aux_value_1, batch_id, product_id, packing_type, uom, bizplace_id,
|
|
428
|
-
|
|
417
|
+
order_name, ref_no, transaction_type, created_at
|
|
429
418
|
ORDER BY sku asc, product_name asc, product_description asc, packing_type asc, batch_id asc, uom asc, created_at asc,
|
|
430
419
|
CASE
|
|
431
420
|
WHEN transaction_type = 'CANCEL_ORDER' THEN 2
|
|
@@ -1712,92 +1701,252 @@ async function massageInventoryPalletSummary(tx: EntityManager, params: ListPara
|
|
|
1712
1701
|
|
|
1713
1702
|
let hasTransactionOrBalanceQuery = ''
|
|
1714
1703
|
if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
|
|
1715
|
-
hasTransactionOrBalanceQuery = 'and (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)'
|
|
1704
|
+
hasTransactionOrBalanceQuery = 'and (c.opening_qty > 0 or c.total_in_qty > 0 or c.adjustment_qty > 0)'
|
|
1716
1705
|
}
|
|
1706
|
+
|
|
1717
1707
|
await tx.query(
|
|
1718
1708
|
`
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1709
|
+
create temp table temp_inventory_pallet_summary ON COMMIT DROP as
|
|
1710
|
+
with params as (
|
|
1711
|
+
select $1::timestamp as t1, $2::timestamp as t2
|
|
1712
|
+
),
|
|
1713
|
+
base as (
|
|
1714
|
+
select
|
|
1715
|
+
invh.*,
|
|
1716
|
+
prd.sku as product_sku,
|
|
1717
|
+
prd.name as product_name,
|
|
1718
|
+
prd.description as product_description,
|
|
1719
|
+
prd.type as product_type
|
|
1720
|
+
from temp_inv_history invh
|
|
1721
|
+
join temp_products prd on prd.id = invh.product_id
|
|
1722
|
+
),
|
|
1723
|
+
|
|
1724
|
+
/* ---- Opening snapshot as-of t1 (FIX) ----
|
|
1725
|
+
For each pallet, take the last row <= t1; if status='STORED',
|
|
1726
|
+
count it toward that row's product_id opening.
|
|
1727
|
+
*/
|
|
1728
|
+
opening_last_asof as (
|
|
1729
|
+
select *
|
|
1730
|
+
from (
|
|
1731
|
+
select h.*,
|
|
1732
|
+
row_number() over (partition by h.pallet_id order by h.created_at desc, h.seq desc) as rn
|
|
1733
|
+
from temp_inv_history h
|
|
1734
|
+
join params p on true
|
|
1735
|
+
where h.created_at <= p.t1
|
|
1736
|
+
) x
|
|
1737
|
+
where rn = 1 and status = 'STORED'
|
|
1738
|
+
),
|
|
1739
|
+
opening_agg as (
|
|
1740
|
+
select
|
|
1741
|
+
p.sku as product_sku,
|
|
1742
|
+
p.id as product_id,
|
|
1743
|
+
p.name as product_name,
|
|
1744
|
+
p.description as product_description,
|
|
1745
|
+
p.type as product_type,
|
|
1746
|
+
count(*)::int as opening_qty
|
|
1747
|
+
from opening_last_asof o
|
|
1748
|
+
join temp_products p on p.id = o.product_id
|
|
1749
|
+
group by p.sku, p.id, p.name, p.description, p.type
|
|
1750
|
+
),
|
|
1751
|
+
|
|
1752
|
+
/* ---- Arrivals inside window: first arrival-like row per pallet (your rule) ---- */
|
|
1753
|
+
invIn as (
|
|
1754
|
+
select b.*,
|
|
1755
|
+
row_number() over (partition by b.pallet_id order by b.created_at, b.seq) as rn
|
|
1756
|
+
from base b
|
|
1757
|
+
join params p on true
|
|
1758
|
+
where b.transaction_type in ('UNLOADING','NEW','CANCEL_ORDER')
|
|
1759
|
+
and b.created_at >= p.t1
|
|
1760
|
+
),
|
|
1761
|
+
invIn_first as (
|
|
1762
|
+
select
|
|
1763
|
+
pallet_id, seq, status, transaction_type,
|
|
1764
|
+
product_sku, product_id, product_name, product_description, product_type,
|
|
1765
|
+
inventory_history_id, packing_type, packing_size, qty, opening_qty, created_at
|
|
1766
|
+
from invIn
|
|
1767
|
+
where rn = 1
|
|
1768
|
+
),
|
|
1769
|
+
|
|
1770
|
+
/* ---- TERMINATED reps (incl. ADJUSTMENT terminations), using your runs logic ---- */
|
|
1771
|
+
status_runs as (
|
|
1772
|
+
select
|
|
1773
|
+
endData.pallet_id,
|
|
1774
|
+
min(endData.created_at) as started_at,
|
|
1775
|
+
max(endData.created_at) as ended_at,
|
|
1776
|
+
min(endData.seq) as min_seq,
|
|
1777
|
+
max(endData.seq) as max_seq,
|
|
1778
|
+
endData.status
|
|
1779
|
+
from (
|
|
1780
|
+
select startData.*,
|
|
1781
|
+
sum(startflag) over (partition by startData.pallet_id order by startData.seq) as grp
|
|
1782
|
+
from (
|
|
1783
|
+
select s.*,
|
|
1784
|
+
case when lag(s.status) over (partition by s.pallet_id order by s.seq) = s.status then 0 else 1 end as startflag
|
|
1785
|
+
from temp_inv_history s
|
|
1786
|
+
) startData
|
|
1787
|
+
) endData
|
|
1788
|
+
group by endData.pallet_id, endData.status, endData.grp
|
|
1789
|
+
),
|
|
1790
|
+
invOut_base as (
|
|
1791
|
+
select b.*, r.started_at
|
|
1792
|
+
from base b
|
|
1793
|
+
join status_runs r
|
|
1794
|
+
on r.pallet_id = b.pallet_id
|
|
1795
|
+
and r.min_seq <= b.seq
|
|
1796
|
+
and r.max_seq >= b.seq
|
|
1797
|
+
where b.status = 'TERMINATED'
|
|
1798
|
+
and b.transaction_type in ('TERMINATED','ADJUSTMENT')
|
|
1799
|
+
),
|
|
1800
|
+
|
|
1801
|
+
/* ---- Transfer pairing (seq-gap tolerant & tolerant txn tags) ---- */
|
|
1802
|
+
/* STORED side in-window; pair to nearest prior TERMINATED (from raw history), different product */
|
|
1803
|
+
adj_stored AS (
|
|
1804
|
+
SELECT b.*
|
|
1805
|
+
FROM base b
|
|
1806
|
+
JOIN params p ON TRUE
|
|
1807
|
+
WHERE b.status = 'STORED'
|
|
1808
|
+
AND b.created_at BETWEEN p.t1 AND p.t2
|
|
1809
|
+
),
|
|
1810
|
+
adj_pairs AS (
|
|
1811
|
+
SELECT
|
|
1812
|
+
s.pallet_id,
|
|
1813
|
+
s.seq AS stored_seq,
|
|
1814
|
+
t.seq AS terminated_seq,
|
|
1815
|
+
s.product_id AS new_product_id,
|
|
1816
|
+
t.product_id AS old_product_id,
|
|
1817
|
+
s.inventory_history_id AS stored_inventory_history_id,
|
|
1818
|
+
t.inventory_history_id AS terminated_inventory_history_id,
|
|
1819
|
+
s.created_at AS stored_at,
|
|
1820
|
+
t.created_at AS terminated_at,
|
|
1821
|
+
s.transaction_type AS stored_txn,
|
|
1822
|
+
t.transaction_type AS terminated_txn
|
|
1823
|
+
FROM adj_stored s
|
|
1824
|
+
JOIN LATERAL (
|
|
1825
|
+
SELECT t.*
|
|
1826
|
+
FROM temp_inv_history t -- use raw history (old product may be outside temp_products)
|
|
1827
|
+
WHERE t.pallet_id = s.pallet_id
|
|
1828
|
+
AND t.seq < s.seq
|
|
1829
|
+
AND t.status = 'TERMINATED'
|
|
1830
|
+
ORDER BY t.seq DESC
|
|
1831
|
+
LIMIT 1
|
|
1832
|
+
) t ON TRUE
|
|
1833
|
+
WHERE t.product_id IS DISTINCT FROM s.product_id
|
|
1834
|
+
AND (s.transaction_type='ADJUSTMENT' OR t.transaction_type='ADJUSTMENT')
|
|
1835
|
+
),
|
|
1836
|
+
adj_pairs_terminated_keys AS (
|
|
1837
|
+
SELECT pallet_id, terminated_seq AS seq
|
|
1838
|
+
FROM adj_pairs
|
|
1839
|
+
),
|
|
1840
|
+
|
|
1841
|
+
/* Representative TERMINATED per (pallet, product), EXCLUDING those used by a pair (avoid double-count) */
|
|
1842
|
+
invOut_rep AS (
|
|
1843
|
+
SELECT *
|
|
1844
|
+
FROM (
|
|
1845
|
+
SELECT iob.*,
|
|
1846
|
+
row_number() over (partition by iob.pallet_id, iob.product_id order by iob.seq desc) as rn
|
|
1847
|
+
FROM invOut_base iob
|
|
1848
|
+
LEFT JOIN adj_pairs_terminated_keys k
|
|
1849
|
+
ON k.pallet_id = iob.pallet_id
|
|
1850
|
+
AND k.seq = iob.seq
|
|
1851
|
+
WHERE k.pallet_id IS NULL
|
|
1852
|
+
) z
|
|
1853
|
+
WHERE rn = 1
|
|
1854
|
+
),
|
|
1855
|
+
|
|
1856
|
+
/* Materialize both sides of the paired transfer */
|
|
1857
|
+
adj_pairs_stored_rows AS (
|
|
1858
|
+
SELECT
|
|
1859
|
+
b.pallet_id, b.seq, b.status, b.transaction_type,
|
|
1860
|
+
b.product_sku, b.product_id, b.product_name, b.product_description, b.product_type,
|
|
1861
|
+
b.inventory_history_id, b.packing_type, b.packing_size, b.qty, b.opening_qty, b.created_at
|
|
1862
|
+
FROM base b
|
|
1863
|
+
JOIN adj_pairs ap
|
|
1864
|
+
ON ap.pallet_id = b.pallet_id
|
|
1865
|
+
AND ap.stored_seq = b.seq
|
|
1866
|
+
),
|
|
1867
|
+
adj_pairs_terminated_rows AS (
|
|
1868
|
+
SELECT
|
|
1869
|
+
b.pallet_id, b.seq, b.status, b.transaction_type,
|
|
1870
|
+
b.product_sku, b.product_id, b.product_name, b.product_description, b.product_type,
|
|
1871
|
+
b.inventory_history_id, b.packing_type, b.packing_size, b.qty, b.opening_qty, b.created_at
|
|
1872
|
+
FROM base b
|
|
1873
|
+
JOIN adj_pairs ap
|
|
1874
|
+
ON ap.pallet_id = b.pallet_id
|
|
1875
|
+
AND ap.terminated_seq = b.seq
|
|
1876
|
+
),
|
|
1877
|
+
|
|
1878
|
+
/* ---- Unified stream for window movement ---- */
|
|
1879
|
+
invHistory as (
|
|
1880
|
+
select * from invIn_first
|
|
1881
|
+
union all
|
|
1882
|
+
select
|
|
1883
|
+
pallet_id, seq, status, transaction_type,
|
|
1884
|
+
product_sku, product_id, product_name, product_description, product_type,
|
|
1885
|
+
inventory_history_id, packing_type, packing_size, qty, opening_qty, created_at
|
|
1886
|
+
from invOut_rep
|
|
1887
|
+
union all
|
|
1888
|
+
select * from adj_pairs_stored_rows
|
|
1889
|
+
union all
|
|
1890
|
+
select * from adj_pairs_terminated_rows
|
|
1891
|
+
),
|
|
1892
|
+
|
|
1893
|
+
/* ---- Movement aggregation only (no opening here) ---- */
|
|
1894
|
+
movement_agg as (
|
|
1895
|
+
select
|
|
1896
|
+
ih.product_sku,
|
|
1897
|
+
ih.product_id,
|
|
1898
|
+
ih.product_name,
|
|
1899
|
+
ih.product_description,
|
|
1900
|
+
ih.product_type,
|
|
1901
|
+
|
|
1902
|
+
sum(case when ih.created_at >= (select t1 from params)
|
|
1903
|
+
and ih.created_at <= (select t2 from params) then
|
|
1904
|
+
case when ih.transaction_type in ('UNLOADING','NEW','CANCEL_ORDER') then 1 else 0 end
|
|
1905
|
+
else 0 end)::int as total_in_qty,
|
|
1906
|
+
|
|
1907
|
+
sum(case when ih.created_at >= (select t1 from params)
|
|
1908
|
+
and ih.created_at <= (select t2 from params) then
|
|
1909
|
+
case when ih.status = 'TERMINATED'
|
|
1910
|
+
and ih.transaction_type <> 'ADJUSTMENT' then -1 else 0 end
|
|
1911
|
+
else 0 end)::int as total_out_qty,
|
|
1912
|
+
|
|
1913
|
+
sum(case when ih.created_at >= (select t1 from params)
|
|
1914
|
+
and ih.created_at <= (select t2 from params) then
|
|
1915
|
+
case when ih.status = 'TERMINATED' and ih.transaction_type = 'ADJUSTMENT' then -1
|
|
1916
|
+
when ih.status = 'STORED' and ih.transaction_type = 'ADJUSTMENT' then 1
|
|
1917
|
+
else 0 end
|
|
1918
|
+
else 0 end)::int as adjustment_qty
|
|
1919
|
+
|
|
1920
|
+
from invHistory ih
|
|
1921
|
+
group by ih.product_sku, ih.product_id, ih.product_name, ih.product_description, ih.product_type
|
|
1922
|
+
),
|
|
1923
|
+
|
|
1924
|
+
/* ---- Combine opening snapshot + window movement ---- */
|
|
1925
|
+
combined as (
|
|
1926
|
+
select
|
|
1927
|
+
coalesce(o.product_sku, m.product_sku) as product_sku,
|
|
1928
|
+
coalesce(o.product_id, m.product_id) as product_id,
|
|
1929
|
+
coalesce(o.product_name,m.product_name) as product_name,
|
|
1930
|
+
coalesce(o.product_description,m.product_description) as product_description,
|
|
1931
|
+
coalesce(o.product_type,m.product_type) as product_type,
|
|
1932
|
+
|
|
1933
|
+
coalesce(o.opening_qty, 0) as opening_qty,
|
|
1934
|
+
coalesce(m.total_in_qty, 0) as total_in_qty,
|
|
1935
|
+
coalesce(m.total_out_qty, 0) as total_out_qty,
|
|
1936
|
+
coalesce(m.adjustment_qty, 0) as adjustment_qty
|
|
1937
|
+
from opening_agg o
|
|
1938
|
+
full outer join movement_agg m
|
|
1939
|
+
on m.product_id = o.product_id
|
|
1799
1940
|
)
|
|
1800
|
-
|
|
1941
|
+
|
|
1942
|
+
select
|
|
1943
|
+
c.*,
|
|
1944
|
+
(c.opening_qty + c.total_in_qty + c.total_out_qty + c.adjustment_qty) as closing_qty
|
|
1945
|
+
from combined c
|
|
1946
|
+
where 1=1
|
|
1947
|
+
${hasTransactionOrBalanceQuery}
|
|
1948
|
+
;
|
|
1949
|
+
`,
|
|
1801
1950
|
[fromDate.value, toDate.value]
|
|
1802
1951
|
)
|
|
1803
1952
|
|