@things-factory/warehouse-base 4.3.686 → 4.3.689
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.
- package/dist-server/service/inventory-change/inventory-change-mutation.js +1 -1
- package/dist-server/service/inventory-change/inventory-change-mutation.js.map +1 -1
- package/dist-server/service/inventory-history/inventory-history-query.js +208 -234
- package/dist-server/service/inventory-history/inventory-history-query.js.map +1 -1
- package/package.json +10 -10
- package/server/service/inventory-change/inventory-change-mutation.ts +0 -1
- package/server/service/inventory-history/inventory-history-query.ts +233 -243
|
@@ -1513,251 +1513,202 @@ async function massageInventoryPalletSummary(tx, params, bizplace, context) {
|
|
|
1513
1513
|
let fromDate = params.filters.find(data => data.name === 'fromDate');
|
|
1514
1514
|
let toDate = params.filters.find(data => data.name === 'toDate');
|
|
1515
1515
|
let hasTransactionOrBalanceFilter = params.filters.find(data => data.name === 'hasTransactionOrBalance');
|
|
1516
|
-
let hasTransactionOrBalanceQuery = '';
|
|
1516
|
+
let hasTransactionOrBalanceQuery = 'TRUE';
|
|
1517
1517
|
if (hasTransactionOrBalanceFilter && hasTransactionOrBalanceFilter.value) {
|
|
1518
|
-
hasTransactionOrBalanceQuery = '
|
|
1518
|
+
hasTransactionOrBalanceQuery = '(merged.opening_qty > 0 or merged.total_in_qty > 0 or merged.adjustment_qty > 0)';
|
|
1519
1519
|
}
|
|
1520
|
+
// Build a slimmer history table for pallet summary to minimize scans
|
|
1520
1521
|
await tx.query(`
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
)
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
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
|
-
),
|
|
1522
|
+
create temp table temp_inv_history_ps on commit drop as (
|
|
1523
|
+
select pallet_id, product_id, seq, status, transaction_type, created_at
|
|
1524
|
+
from temp_inv_history
|
|
1525
|
+
where (transaction_type in ('UNLOADING','NEW','CANCEL_ORDER','ADJUSTMENT')
|
|
1526
|
+
or status in ('STORED','TERMINATED'))
|
|
1527
|
+
and created_at <= $1::timestamp
|
|
1528
|
+
);
|
|
1529
|
+
`, [toDate.value]);
|
|
1530
|
+
await tx.query(`
|
|
1531
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_created_at ON temp_inv_history_ps (created_at);
|
|
1532
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_pallet_seq ON temp_inv_history_ps (pallet_id, seq);
|
|
1533
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_pallet_product_seq ON temp_inv_history_ps (pallet_id, product_id, seq);
|
|
1534
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_product ON temp_inv_history_ps (product_id);
|
|
1535
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_product_created ON temp_inv_history_ps (product_id, created_at);
|
|
1536
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_status ON temp_inv_history_ps (status);
|
|
1537
|
+
CREATE INDEX IF NOT EXISTS idx_tihps_txn ON temp_inv_history_ps (transaction_type);
|
|
1538
|
+
ANALYZE temp_inv_history_ps;
|
|
1539
|
+
`);
|
|
1540
|
+
await tx.query(`
|
|
1541
|
+
-- Params:
|
|
1542
|
+
-- $1 = t1 ::timestamp
|
|
1543
|
+
-- $2 = t2 ::timestamp
|
|
1652
1544
|
|
|
1653
|
-
|
|
1654
|
-
|
|
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
|
-
),
|
|
1545
|
+
CREATE TEMP TABLE temp_inventory_pallet_summary ON COMMIT DROP AS
|
|
1546
|
+
WITH
|
|
1547
|
+
params AS (SELECT $1::timestamp AS t1, $2::timestamp AS t2),
|
|
1667
1548
|
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
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
|
-
),
|
|
1549
|
+
/* Pre-filtered slices (minimal cols) */
|
|
1550
|
+
rows_le_t1 AS (
|
|
1551
|
+
SELECT pallet_id, product_id, seq, status
|
|
1552
|
+
FROM temp_inv_history_ps
|
|
1553
|
+
WHERE created_at <= (SELECT t1 FROM params)
|
|
1554
|
+
),
|
|
1555
|
+
rows_win AS (
|
|
1556
|
+
SELECT pallet_id, product_id, seq, status, transaction_type
|
|
1557
|
+
FROM temp_inv_history_ps
|
|
1558
|
+
WHERE created_at BETWEEN (SELECT t1 FROM params) AND (SELECT t2 FROM params)
|
|
1559
|
+
),
|
|
1560
|
+
rows_le_t2 AS (
|
|
1561
|
+
SELECT pallet_id, product_id, seq, status, transaction_type
|
|
1562
|
+
FROM temp_inv_history_ps
|
|
1563
|
+
WHERE created_at <= (SELECT t2 FROM params)
|
|
1564
|
+
),
|
|
1689
1565
|
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
union all
|
|
1702
|
-
select * from adj_pairs_terminated_rows
|
|
1703
|
-
),
|
|
1566
|
+
/* Opening (<= t1): last-by-seq per pallet, must be STORED */
|
|
1567
|
+
opening_last_asof AS (
|
|
1568
|
+
SELECT DISTINCT ON (h.pallet_id) h.pallet_id, h.product_id, h.seq, h.status
|
|
1569
|
+
FROM rows_le_t1 h
|
|
1570
|
+
ORDER BY h.pallet_id, h.seq DESC
|
|
1571
|
+
),
|
|
1572
|
+
opening_anchor AS (
|
|
1573
|
+
SELECT pallet_id, product_id
|
|
1574
|
+
FROM opening_last_asof
|
|
1575
|
+
WHERE status = 'STORED'
|
|
1576
|
+
),
|
|
1704
1577
|
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1578
|
+
/* Closing (<= t2): last STORED per (pallet, product) by seq + validity */
|
|
1579
|
+
closing_last_stored AS (
|
|
1580
|
+
SELECT DISTINCT ON (h.pallet_id, h.product_id) h.pallet_id, h.product_id, h.seq
|
|
1581
|
+
FROM rows_le_t2 h
|
|
1582
|
+
WHERE h.status = 'STORED'
|
|
1583
|
+
ORDER BY h.pallet_id, h.product_id, h.seq DESC
|
|
1584
|
+
),
|
|
1585
|
+
last_term_by_pair AS (
|
|
1586
|
+
SELECT DISTINCT ON (h.pallet_id, h.product_id) h.pallet_id, h.product_id, h.seq AS last_term_seq
|
|
1587
|
+
FROM rows_le_t2 h
|
|
1588
|
+
WHERE h.status = 'TERMINATED'
|
|
1589
|
+
ORDER BY h.pallet_id, h.product_id, h.seq DESC
|
|
1590
|
+
),
|
|
1591
|
+
inbound_after_term AS (
|
|
1592
|
+
SELECT cls.pallet_id, cls.product_id
|
|
1593
|
+
FROM closing_last_stored cls
|
|
1594
|
+
LEFT JOIN last_term_by_pair lt
|
|
1595
|
+
ON lt.pallet_id = cls.pallet_id AND lt.product_id = cls.product_id
|
|
1596
|
+
WHERE EXISTS (
|
|
1597
|
+
SELECT 1
|
|
1598
|
+
FROM rows_le_t2 h
|
|
1599
|
+
WHERE h.pallet_id = cls.pallet_id
|
|
1600
|
+
AND h.product_id = cls.product_id
|
|
1601
|
+
AND h.transaction_type IN ('UNLOADING','NEW','CANCEL_ORDER')
|
|
1602
|
+
AND h.seq <= cls.seq
|
|
1603
|
+
AND (lt.last_term_seq IS NULL OR h.seq > lt.last_term_seq)
|
|
1604
|
+
)
|
|
1605
|
+
),
|
|
1606
|
+
valid_closing AS (
|
|
1607
|
+
SELECT cls.pallet_id, cls.product_id
|
|
1608
|
+
FROM closing_last_stored cls
|
|
1609
|
+
LEFT JOIN inbound_after_term ia
|
|
1610
|
+
ON ia.pallet_id = cls.pallet_id AND ia.product_id = cls.product_id
|
|
1611
|
+
LEFT JOIN last_term_by_pair lt
|
|
1612
|
+
ON lt.pallet_id = cls.pallet_id AND lt.product_id = cls.product_id
|
|
1613
|
+
WHERE lt.last_term_seq IS NULL OR ia.pallet_id IS NOT NULL
|
|
1614
|
+
),
|
|
1615
|
+
closing_anchor AS (
|
|
1616
|
+
SELECT pallet_id, product_id FROM valid_closing
|
|
1617
|
+
),
|
|
1718
1618
|
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1619
|
+
/* Movement presence in window */
|
|
1620
|
+
inbound_pairs AS (
|
|
1621
|
+
SELECT pallet_id, product_id
|
|
1622
|
+
FROM rows_win
|
|
1623
|
+
WHERE transaction_type IN ('UNLOADING','NEW','CANCEL_ORDER')
|
|
1624
|
+
GROUP BY pallet_id, product_id
|
|
1625
|
+
),
|
|
1626
|
+
terminated_pairs AS (
|
|
1627
|
+
SELECT pallet_id, product_id
|
|
1628
|
+
FROM rows_win
|
|
1629
|
+
WHERE status = 'TERMINATED' AND transaction_type <> 'ADJUSTMENT'
|
|
1630
|
+
GROUP BY pallet_id, product_id
|
|
1631
|
+
),
|
|
1632
|
+
adjustment_last AS (
|
|
1633
|
+
SELECT x.pallet_id, x.product_id,
|
|
1634
|
+
CASE WHEN x.status = 'TERMINATED' THEN -1
|
|
1635
|
+
WHEN x.status = 'STORED' THEN 1
|
|
1636
|
+
ELSE 0 END AS adj_sign
|
|
1637
|
+
FROM (
|
|
1638
|
+
SELECT a.pallet_id, a.product_id, MAX(a.seq) AS max_seq
|
|
1639
|
+
FROM rows_win a
|
|
1640
|
+
WHERE a.transaction_type = 'ADJUSTMENT'
|
|
1641
|
+
GROUP BY a.pallet_id, a.product_id
|
|
1642
|
+
) s
|
|
1643
|
+
JOIN rows_win x
|
|
1644
|
+
ON x.pallet_id = s.pallet_id AND x.product_id = s.product_id AND x.seq = s.max_seq
|
|
1645
|
+
),
|
|
1724
1646
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1647
|
+
/* Union anchor (opening OR any movement OR valid closing) */
|
|
1648
|
+
anchor_union AS (
|
|
1649
|
+
SELECT * FROM opening_anchor
|
|
1650
|
+
UNION ALL
|
|
1651
|
+
SELECT * FROM inbound_pairs
|
|
1652
|
+
UNION ALL
|
|
1653
|
+
SELECT * FROM terminated_pairs
|
|
1654
|
+
UNION ALL
|
|
1655
|
+
SELECT * FROM closing_anchor
|
|
1656
|
+
),
|
|
1657
|
+
anchor_distinct AS (
|
|
1658
|
+
SELECT DISTINCT pallet_id, product_id FROM anchor_union
|
|
1659
|
+
),
|
|
1731
1660
|
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1661
|
+
/* Opening aggregation (anchored) */
|
|
1662
|
+
opening_agg AS (
|
|
1663
|
+
SELECT ol.product_id,
|
|
1664
|
+
COUNT(*) FILTER (WHERE ol.status = 'STORED')::int AS opening_qty
|
|
1665
|
+
FROM opening_last_asof ol
|
|
1666
|
+
JOIN anchor_distinct au ON au.pallet_id = ol.pallet_id AND au.product_id = ol.product_id
|
|
1667
|
+
GROUP BY ol.product_id
|
|
1668
|
+
),
|
|
1735
1669
|
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1670
|
+
/* Movement aggregation (anchored) */
|
|
1671
|
+
movement_agg AS (
|
|
1672
|
+
SELECT
|
|
1673
|
+
COALESCE(inb.product_id, term.product_id, adj.product_id) AS product_id,
|
|
1674
|
+
SUM((inb.pallet_id IS NOT NULL)::int) AS total_in_qty,
|
|
1675
|
+
SUM((term.pallet_id IS NOT NULL)::int) AS total_out_qty,
|
|
1676
|
+
COALESCE(SUM(adj.adj_sign), 0)::int AS adjustment_qty
|
|
1677
|
+
FROM anchor_distinct au
|
|
1678
|
+
LEFT JOIN inbound_pairs inb ON inb.pallet_id = au.pallet_id AND inb.product_id = au.product_id
|
|
1679
|
+
LEFT JOIN terminated_pairs term ON term.pallet_id = au.pallet_id AND term.product_id = au.product_id
|
|
1680
|
+
LEFT JOIN adjustment_last adj ON adj.pallet_id = au.pallet_id AND adj.product_id = au.product_id
|
|
1681
|
+
GROUP BY COALESCE(inb.product_id, term.product_id, adj.product_id)
|
|
1682
|
+
),
|
|
1744
1683
|
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1684
|
+
merged AS (
|
|
1685
|
+
SELECT
|
|
1686
|
+
COALESCE(o.product_id, m.product_id) AS product_id,
|
|
1687
|
+
COALESCE(o.opening_qty, 0) AS opening_qty,
|
|
1688
|
+
COALESCE(m.total_in_qty, 0) AS total_in_qty,
|
|
1689
|
+
COALESCE(m.total_out_qty, 0) AS total_out_qty,
|
|
1690
|
+
COALESCE(m.adjustment_qty, 0) AS adjustment_qty
|
|
1691
|
+
FROM opening_agg o
|
|
1692
|
+
FULL JOIN movement_agg m ON m.product_id = o.product_id
|
|
1693
|
+
)
|
|
1753
1694
|
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1695
|
+
SELECT
|
|
1696
|
+
p.sku AS product_sku,
|
|
1697
|
+
p.id AS product_id,
|
|
1698
|
+
p.name AS product_name,
|
|
1699
|
+
p.description AS product_description,
|
|
1700
|
+
p.type AS product_type,
|
|
1701
|
+
COALESCE(merged.opening_qty, 0) AS opening_qty,
|
|
1702
|
+
COALESCE(merged.total_in_qty, 0) AS total_in_qty,
|
|
1703
|
+
COALESCE(merged.total_out_qty, 0) AS total_out_qty,
|
|
1704
|
+
COALESCE(merged.adjustment_qty, 0) AS adjustment_qty,
|
|
1705
|
+
(COALESCE(merged.opening_qty, 0)
|
|
1706
|
+
+ COALESCE(merged.total_in_qty, 0)
|
|
1707
|
+
+ COALESCE(merged.total_out_qty, 0)
|
|
1708
|
+
+ COALESCE(merged.adjustment_qty, 0))::int AS closing_qty
|
|
1709
|
+
FROM merged
|
|
1710
|
+
JOIN temp_products p ON p.id = merged.product_id
|
|
1711
|
+
WHERE ${hasTransactionOrBalanceQuery};
|
|
1761
1712
|
`, [fromDate.value, toDate.value]);
|
|
1762
1713
|
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`);
|
|
1763
1714
|
const result = await tx.query(`
|
|
@@ -1805,6 +1756,10 @@ async function productsQuery(tx, params, bizplace) {
|
|
|
1805
1756
|
${productTypeQuery}
|
|
1806
1757
|
GROUP BY prd.id, prd.sku, prd.name, prd.description
|
|
1807
1758
|
)`, [bizplace.id]);
|
|
1759
|
+
await tx.query(`
|
|
1760
|
+
CREATE INDEX IF NOT EXISTS idx_tprod_id ON temp_products (id);
|
|
1761
|
+
ANALYZE temp_products;
|
|
1762
|
+
`);
|
|
1808
1763
|
}
|
|
1809
1764
|
async function filterInventoryQuery(tx, params, bizplace, context) {
|
|
1810
1765
|
let toDate = params.filters.find(data => data.name === 'toDate');
|
|
@@ -1843,9 +1798,18 @@ async function filterInventoryQuery(tx, params, bizplace, context) {
|
|
|
1843
1798
|
WHERE ih.domain_id = $1
|
|
1844
1799
|
AND ih.bizplace_id = $2
|
|
1845
1800
|
AND ih.created_at <= $3
|
|
1846
|
-
AND (
|
|
1801
|
+
AND EXISTS (SELECT 1 FROM temp_products prd WHERE prd.id = ih.product_id::uuid)
|
|
1802
|
+
${batchNoQuery}
|
|
1847
1803
|
)
|
|
1848
1804
|
`, [context.state.domain.id, bizplace.id, toDate.value]);
|
|
1805
|
+
// Speed up joins and windowed lookups that follow
|
|
1806
|
+
await tx.query(`
|
|
1807
|
+
CREATE INDEX IF NOT EXISTS idx_tfh_pallet_domain ON temp_filtered_histories (pallet_id, domain_id);
|
|
1808
|
+
CREATE INDEX IF NOT EXISTS idx_tfh_product ON temp_filtered_histories (product_id);
|
|
1809
|
+
CREATE INDEX IF NOT EXISTS idx_tfh_created_at ON temp_filtered_histories (created_at);
|
|
1810
|
+
CREATE INDEX IF NOT EXISTS idx_tfh_pallet_seq ON temp_filtered_histories (pallet_id, seq);
|
|
1811
|
+
ANALYZE temp_filtered_histories;
|
|
1812
|
+
`);
|
|
1849
1813
|
/* Step 2: build temp_inv_history by joining inventories with indexed temp_filtered_histories and temp_products */
|
|
1850
1814
|
await tx.query(`
|
|
1851
1815
|
create temp table temp_inv_history ON COMMIT DROP as (
|
|
@@ -1857,8 +1821,18 @@ async function filterInventoryQuery(tx, params, bizplace, context) {
|
|
|
1857
1821
|
AND ih.domain_id = i2.domain_id
|
|
1858
1822
|
INNER JOIN temp_products prd
|
|
1859
1823
|
ON prd.id = ih.product_id::uuid
|
|
1860
|
-
${batchNoQuery}
|
|
1861
1824
|
)
|
|
1862
1825
|
`);
|
|
1826
|
+
// Critical indexes for the heavy pallet summary query
|
|
1827
|
+
await tx.query(`
|
|
1828
|
+
CREATE INDEX IF NOT EXISTS idx_tih_created_at ON temp_inv_history (created_at);
|
|
1829
|
+
CREATE INDEX IF NOT EXISTS idx_tih_pallet_seq ON temp_inv_history (pallet_id, seq);
|
|
1830
|
+
CREATE INDEX IF NOT EXISTS idx_tih_pallet_product_seq ON temp_inv_history (pallet_id, product_id, seq);
|
|
1831
|
+
CREATE INDEX IF NOT EXISTS idx_tih_product ON temp_inv_history (product_id);
|
|
1832
|
+
CREATE INDEX IF NOT EXISTS idx_tih_pallet_product ON temp_inv_history (pallet_id, product_id);
|
|
1833
|
+
CREATE INDEX IF NOT EXISTS idx_tih_status ON temp_inv_history (status);
|
|
1834
|
+
CREATE INDEX IF NOT EXISTS idx_tih_txn ON temp_inv_history (transaction_type);
|
|
1835
|
+
ANALYZE temp_inv_history;
|
|
1836
|
+
`);
|
|
1863
1837
|
}
|
|
1864
1838
|
//# sourceMappingURL=inventory-history-query.js.map
|