Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
37694 amit 1
-- Record where stock came from and what it cost, on the stock itself (2026-09-17)
2
--
3
-- WHY
4
--   Stock carried no record of its source, so every internal movement re-derived the origin by tracing serials
5
--   (impossible for non-serialised stock that had already moved) and then priced the move from that vendor's CURRENT
6
--   catalog TP. Standard practice is a receipt layer: each row of stock knows which outside vendor it came from and
7
--   what it cost when it arrived, and an internal movement moves it at that cost.
8
--
9
--   inventoryItem.origin_vendor_id   - outside vendor the unit came from. NULL = genuinely unknown; never a guess
10
--                                      and never an internal supplier.
11
--   inventoryItem.receipt_unit_cost  - unit price the stock was received at (warehouse.lineitem.unitPrice of the PO
12
--                                      line it arrived on). What an internal movement moves it at.
13
--   lineitem.origin_vendor_id        - origin the PO line was priced from, so a receiving GRN can copy it onward.
14
--
15
-- ORDERING: run before deploying the code that writes these columns. Both ALTERs are ADD COLUMN, which MySQL 5.7 does
16
-- INPLACE and allows reads/writes throughout; inventoryItem is ~1.5M rows so expect a couple of minutes.
17
 
18
ALTER TABLE warehouse.inventoryItem
19
  ADD COLUMN origin_vendor_id INT NULL
20
    COMMENT 'outside vendor this stock came from; NULL = unknown, never an internal supplier',
21
  ADD COLUMN receipt_unit_cost FLOAT NULL
22
    COMMENT 'unit price this stock was received at; what an internal movement moves it at';
23
 
24
ALTER TABLE warehouse.lineitem
25
  ADD COLUMN origin_vendor_id INT NULL
26
    COMMENT 'origin vendor this PO line was priced from; copied onto stock at GRN';
27
 
28
-- Backfill, facts only --------------------------------------------------------------------------------------------
29
-- 1. Stock received directly on an outside vendor's PO: that vendor, and the price on its PO line.
30
UPDATE warehouse.inventoryItem ii
31
  JOIN warehouse.purchase p        ON p.id = ii.purchaseId
32
  JOIN warehouse.purchaseorder po  ON po.id = p.purchaseOrder_id
33
  JOIN warehouse.supplier s        ON s.id = po.supplierId AND s.internal = 0
34
  LEFT JOIN warehouse.lineitem li  ON li.purchaseOrder_id = po.id AND li.itemId = ii.itemId
35
   SET ii.origin_vendor_id = po.supplierId,
36
       ii.receipt_unit_cost = li.unitPrice
37
 WHERE ii.origin_vendor_id IS NULL;
38
 
39
-- 2. Serialised stock that moved internally: the vendor of the most recent external purchase of that serial, and the
40
--    cost recorded against that purchase. Same rule billing uses to price a sale.
41
UPDATE warehouse.inventoryItem ii
42
  JOIN (SELECT o.id,
43
               (SELECT po2.supplierId FROM warehouse.inventoryItem o2
44
                  JOIN warehouse.purchase p2 ON p2.id = o2.purchaseId
45
                  JOIN warehouse.purchaseorder po2 ON po2.id = p2.purchaseOrder_id
46
                  JOIN warehouse.supplier s2 ON s2.id = po2.supplierId AND s2.internal = 0
47
                 WHERE o2.serialNumber = o.serialNumber AND o2.itemId = o.itemId
48
                 ORDER BY o2.created DESC, o2.id DESC LIMIT 1) AS origin_vendor_id,
49
               (SELECT o3.receipt_unit_cost FROM warehouse.inventoryItem o3
50
                  JOIN warehouse.purchase p3 ON p3.id = o3.purchaseId
51
                  JOIN warehouse.purchaseorder po3 ON po3.id = p3.purchaseOrder_id
52
                  JOIN warehouse.supplier s3 ON s3.id = po3.supplierId AND s3.internal = 0
53
                 WHERE o3.serialNumber = o.serialNumber AND o3.itemId = o.itemId
54
                 ORDER BY o3.created DESC, o3.id DESC LIMIT 1) AS receipt_unit_cost
55
          FROM warehouse.inventoryItem o
56
         WHERE o.origin_vendor_id IS NULL AND o.serialNumber IS NOT NULL AND LENGTH(o.serialNumber) > 0
57
           AND o.currentQuantity > 0) traced ON traced.id = ii.id
58
   SET ii.origin_vendor_id  = traced.origin_vendor_id,
59
       ii.receipt_unit_cost = traced.receipt_unit_cost
60
 WHERE traced.origin_vendor_id IS NOT NULL;
61
 
62
-- 3. Everything else keeps NULL: non-serialised stock that has already moved internally has no recoverable origin,
63
--    and a guess must never be written as a fact. Those units are priced from the latest externally approved catalog
64
--    price at movement time, as before.
65
 
66
-- What the backfill reached, for stock currently held.
67
SELECT COUNT(*) AS in_stock_rows,
68
       SUM(origin_vendor_id IS NOT NULL) AS with_origin,
69
       SUM(receipt_unit_cost IS NOT NULL) AS with_cost,
70
       SUM(origin_vendor_id IS NULL) AS unknown_origin
71
  FROM warehouse.inventoryItem WHERE currentQuantity > 0;