From 84272739bd5bb6e627b066a9873ad4e128d07e18 Mon Sep 17 00:00:00 2001 From: "kelvin.yau" Date: Thu, 22 Oct 2026 17:45:26 +0800 Subject: [PATCH] Harden demo anonymize for staff scan, floor routing, and pickable stock. Assign STAFF* staffNo, remap 2F/4F supplier lists separately, and top up MG1757 plus PP2236/PP2237 so JO/DO demo flows are not blocked. --- scripts/anonymize_demo_copy.sql | 102 ++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 12 deletions(-) diff --git a/scripts/anonymize_demo_copy.sql b/scripts/anonymize_demo_copy.sql index 5e179424..5ff3a1c4 100644 --- a/scripts/anonymize_demo_copy.sql +++ b/scripts/anonymize_demo_copy.sql @@ -8,6 +8,12 @@ -- in UTC+8. Lot expiry dates move forward by the same number of days -- as the newest delivery arrival day, so usable stock stays usable. -- settings DEMO.dateAnchor stores that day. Line prices become 1. +-- Also tops up depleted MG1757 lots (PP2220 JO pick material) so demo +-- 提料 is not blocked by zero olive-oil stock. +-- Makes PP2236/PP2237 lot lines pickable (status available; move off Hold +-- bin 2F-W202-01-00) so DO 執貨 with those FGs can suggest lots. +-- DO.floor.suppliers.2F / 4F keep production split; shop codes expand to +-- all matching S{id} (do not copy the same CSV into both floors). -- Opening the backend does not move dates. On a later demo day, run -- scripts/refresh_demo_dates.sql. -- @@ -17,6 +23,8 @@ -- Refuses to run unless the current database is fpsms_demo. -- Refuses to run again once settings.name = DEMO.anonymized.v1 exists. -- Password for every user, including demo / demo.stock / demo.prod, is Demo2026!. +-- staffNo is set for JO production scan: demo=STAFF001, demo.stock=STAFF002, +-- demo.prod=STAFF003, others=STAFF{id}. -- -- MySQL Workbench stops a query after 30 seconds and reports error 2013. -- Before running: Preferences, SQL Editor, DBMS connection read timeout = 3600. @@ -335,7 +343,14 @@ BEGIN u.department = '', u.title = '', u.remarks = '', - u.staffNo = ''; + -- Keep scannable staffNo for JO production (findByStaffNo). + -- Prefix STAFF so camera/keyboard plain-text scan is accepted by FE. + u.staffNo = CASE m.new_username + WHEN 'demo' THEN 'STAFF001' + WHEN 'demo.stock' THEN 'STAFF002' + WHEN 'demo.prod' THEN 'STAFF003' + ELSE CONCAT('STAFF', u.id) + END; CALL demo_apply_map('item_lot_trace_log', 'username', '_demo_map_username'); CALL demo_apply_map('stocktakerecord', 'createdBy', '_demo_map_username'); @@ -360,6 +375,34 @@ BEGIN SET name = REPLACE(REPLACE(IFNULL(name, ''), 'TOA', ''), '平記', ''), description = REPLACE(REPLACE(IFNULL(description, ''), 'TOA', ''), '平記', ''); + -- Remap floor supplier CSVs while shop.code is still the production code. + -- Expand each listed code to every shop row with that code → S{id}, so DO + -- supplierId rows keep matching after shop codes become unique. + SELECT IFNULL(value, '') INTO @demo_floor_2f + FROM settings WHERE name = 'DO.floor.suppliers.2F' LIMIT 1; + SELECT IFNULL(value, '') INTO @demo_floor_4f + FROM settings WHERE name = 'DO.floor.suppliers.4F' LIMIT 1; + + UPDATE settings + SET value = IFNULL(( + SELECT GROUP_CONCAT(DISTINCT CONCAT('S', s.id) ORDER BY s.id SEPARATOR ',') + FROM shop s + WHERE IFNULL(s.deleted, 0) = 0 + AND @demo_floor_2f <> '' + AND FIND_IN_SET(s.code, REPLACE(@demo_floor_2f, ' ', '')) + ), '') + WHERE name = 'DO.floor.suppliers.2F'; + + UPDATE settings + SET value = IFNULL(( + SELECT GROUP_CONCAT(DISTINCT CONCAT('S', s.id) ORDER BY s.id SEPARATOR ',') + FROM shop s + WHERE IFNULL(s.deleted, 0) = 0 + AND @demo_floor_4f <> '' + AND FIND_IN_SET(s.code, REPLACE(@demo_floor_4f, ' ', '')) + ), '') + WHERE name = 'DO.floor.suppliers.4F'; + UPDATE shop SET code = CONCAT('S', id), name = CONCAT('Shop ', id), @@ -464,17 +507,52 @@ BEGIN ) WHERE p.deleted = 0; - UPDATE settings - SET value = ( - SELECT GROUP_CONCAT(DISTINCT s.code ORDER BY s.code SEPARATOR ',') - FROM delivery_order d - JOIN shop s ON s.id = d.supplierId AND s.deleted = 0 - WHERE d.deleted = 0 - AND d.estimatedArrivalDate IS NOT NULL - AND DATE(d.estimatedArrivalDate) BETWEEN CURDATE() - AND DATE_ADD(CURDATE(), INTERVAL 2 DAY) - ) - WHERE name IN ('DO.floor.suppliers.2F', 'DO.floor.suppliers.4F'); + -- Demo hero PP2220: MG1757 (olive oil) is often fully issued on the + -- production copy. Restore usable qty on depleted lot lines so JO 提料 + -- can pick. inventory_lot_line AFTER UPDATE trigger syncs inventory. + UPDATE inventory_lot_line ill + JOIN inventory_lot l + ON l.id = ill.inventoryLotId AND IFNULL(l.deleted, 0) = 0 + JOIN items i + ON i.id = l.itemId + AND i.code = 'MG1757' + AND IFNULL(i.deleted, 0) = 0 + SET ill.inQty = IFNULL(ill.outQty, 0) + 20, + ill.holdQty = 0 + WHERE IFNULL(ill.deleted, 0) = 0 + AND ( + IFNULL(ill.inQty, 0) + - IFNULL(ill.outQty, 0) + - IFNULL(ill.holdQty, 0) + ) <= 0; + + -- Demo DO 執貨: PP2236 / PP2237 often sit unavailable (and on Hold bin). + -- Mark remaining qty available and move Hold → 2F-W201-#J-01 when present. + UPDATE inventory_lot_line ill + JOIN inventory_lot l + ON l.id = ill.inventoryLotId AND IFNULL(l.deleted, 0) = 0 + JOIN items i + ON i.id = l.itemId + AND i.code IN ('PP2236', 'PP2237') + AND IFNULL(i.deleted, 0) = 0 + LEFT JOIN warehouse w + ON w.id = ill.warehouseId + LEFT JOIN warehouse w_pick + ON w_pick.code = '2F-W201-#J-01' + AND IFNULL(w_pick.deleted, 0) = 0 + SET ill.status = 'available', + ill.holdQty = 0, + ill.warehouseId = IF( + w.code = '2F-W202-01-00' AND w_pick.id IS NOT NULL, + w_pick.id, + ill.warehouseId + ) + WHERE IFNULL(ill.deleted, 0) = 0 + AND ( + IFNULL(ill.inQty, 0) + - IFNULL(ill.outQty, 0) + - IFNULL(ill.holdQty, 0) + ) > 0; INSERT INTO settings (name, value, category, type) VALUES ('DEMO.anonymized.v1', '1', 'DEMO', 'string');