Blame | Last modification | View Log | RSS feed
-- 2026-09-24 - Mark debit notes settled by the pre-workflow returns flow as APPROVED.---- APPLIED on hadb1 2026-09-24. Recorded here for the audit trail; do not re-run blindly.---- Why: returns settled before the receive workflow (first purchase_return_order 2026-03-16 12:52) wrote the-- warehouse SALE_RET scan, a returnorderinfo row and a wallet refund, but never touched the debit note. So-- 5,557 fully settled notes still read status='CREATED' with no purchase_return_order, and every receive-- screen decides on exactly those two things - the note looked like it was still awaiting receipt, Receive-- button included. Re-receiving one (DN UPBLY975/4, IMEI 864973083197734) handed a partner back a phone that-- had already been returned, refunded and resold, and a duplicate debit note followed.---- Evidence rule (mirrors PurchaseReturnServiceImpl.applyReceipt, which refuses to return a unit twice):-- a note qualifies only when EVERY unit on it is-- (a) returned - a SALE_RET / DOA_IN / SALE_RET_UNUSABLE scan for that unit against the order its-- invoice was billed on, and-- (b) refunded - the order's refunded returnorderinfo quantity covers its returned units.-- Serialized units match by IMEI through line_item_imei (holds even where the SALE scan was deleted);-- non-serialized ones qualify only when the invoice has no returnable quantity left for that item.-- End state written is the one the new flow writes at refund: debit_note APPROVED, items RETURNED with-- return_timestamp = the return scan and refund_timestamp = the refund. No purchase_return_order is-- invented - these were never received through the workflow, and a PRO would falsify who received what.---- Result: 4,154 debit notes and 6,639 return items. Open notes 5,557 -> 1,404.-- Backups: fofo._bak_dn_status_20260924, fofo._bak_dn_pri_status_20260924.-- Per-unit evidence and bucket per unit: fofo._dn_backfill_20260922 (+ _dn_backfill_dn_20260922 per note).---- NOT backfilled, left at CREATED for review (see the bucket column):-- C_REFUNDED_NOT_RETURNED 1,011 notes - refunded with no return scan (refund-leak / re-bill pattern)-- E_NOT_RETURNED_NOT_REFUNDED 293 notes - raised and abandoned, oldest 2018-- B_RETURNED_NOT_REFUNDED 82 notes - goods back, no refund recorded: partners may be owed money-- D_NO_SALE_SCAN 24 notes - sale scan deleted or IMEI mismatch-- X_ORDER_NOT_FOUND 2 notes-- Only 5 of the remainder belong to internal stores (fofo_store.internal = 1).-- Guards matter: the tables below are a snapshot, and the live flow keeps settling notes. Both statements-- re-check status and the absence of a purchase_return_order at execution time (DN 7228 was received-- normally between the snapshot and the run, and correctly dropped out).UPDATE fofo.debit_note dnJOIN fofo._dn_backfill_dn_20260922 b ON b.dn = dn.id AND b.units = b.ok_unitsSET dn.status = 'APPROVED'WHERE dn.status = 'CREATED'AND NOT EXISTS (SELECT 1 FROM fofo.purchase_return_order pro WHERE pro.debit_note_id = dn.id);UPDATE fofo.purchase_return_item priJOIN fofo._dn_backfill_20260922 u ON u.pri = pri.idJOIN fofo.debit_note dn ON dn.id = pri.debit_note_id AND dn.status = 'APPROVED'JOIN fofo._dn_backfill_dn_20260922 b ON b.dn = dn.id AND b.units = b.ok_unitsSET pri.status = 'RETURNED', pri.return_timestamp = u.returned_at, pri.refund_timestamp = u.refunded_atWHERE pri.status = 'DEBIT_NOTE_CREATED' AND u.bucket = 'A_RETURNED_REFUNDED'AND NOT EXISTS (SELECT 1 FROM fofo.purchase_return_order pro WHERE pro.debit_note_id = dn.id);-- Verify-- SELECT status, COUNT(*) FROM fofo.debit_note GROUP BY status; -- APPROVED 4539, CANCELLED 6, CREATED 1404-- SELECT COUNT(*) FROM fofo.debit_note dn WHERE dn.status='CREATED'-- AND NOT EXISTS (SELECT 1 FROM fofo.purchase_return_order pro WHERE pro.debit_note_id=dn.id); -- 1404