|
- -- Rewrite identifying values in fpsms_demo. Does not delete rows.
- -- Ids, foreign keys, statuses, quantities stay.
- -- Item codes, lot numbers, warehouse codes, and floors (1/F–4/F) stay.
- -- Shop codes, delivery-order codes, and purchase-order codes are rewritten
- -- and the same old string is updated everywhere it was copied.
- -- The three most recent delivery and purchase arrival dates move to
- -- today, tomorrow, and the day after. Today is the real calendar day
- -- 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.
- -- Opening the backend does not move dates. On a later demo day, run
- -- scripts/refresh_demo_dates.sql.
- --
- -- Run only against a disposable full copy of production:
- -- mysql -h127.0.0.1 -P3306 -uroot -p fpsms_demo < scripts/anonymize_demo_copy.sql
- --
- -- 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!.
- --
- -- MySQL Workbench stops a query after 30 seconds and reports error 2013.
- -- Before running: Preferences, SQL Editor, DBMS connection read timeout = 3600.
- -- Reconnect, select fpsms_demo, then run this whole file.
-
- SET NAMES utf8mb4;
- SET SESSION time_zone = '+08:00';
- SET SESSION sql_safe_updates = 0;
- SET SESSION group_concat_max_len = 1000000;
- SET SESSION net_read_timeout = 7200;
- SET SESSION net_write_timeout = 7200;
- SET SESSION wait_timeout = 28800;
-
- DROP PROCEDURE IF EXISTS demo_exec_if_table;
- DROP PROCEDURE IF EXISTS demo_apply_map;
- DROP PROCEDURE IF EXISTS demo_apply_pair;
- DROP PROCEDURE IF EXISTS demo_add_missing;
- DROP PROCEDURE IF EXISTS demo_blank_columns;
- DROP PROCEDURE IF EXISTS demo_replace_floors;
- DROP PROCEDURE IF EXISTS demo_remap_shop_csv;
- DROP PROCEDURE IF EXISTS demo_drop_maps;
- DROP PROCEDURE IF EXISTS anonymize_demo_copy;
-
- DELIMITER $$
-
- CREATE PROCEDURE demo_drop_maps()
- BEGIN
- DROP TABLE IF EXISTS _demo_map_shop;
- DROP TABLE IF EXISTS _demo_map_do;
- DROP TABLE IF EXISTS _demo_map_po;
- DROP TABLE IF EXISTS _demo_map_user;
- DROP TABLE IF EXISTS _demo_map_username;
- DROP TABLE IF EXISTS _demo_map_person;
- END$$
-
- CREATE PROCEDURE demo_exec_if_table(IN p_table VARCHAR(64), IN p_sql TEXT)
- BEGIN
- DECLARE n INT DEFAULT 0;
- SELECT COUNT(*) INTO n
- FROM information_schema.tables
- WHERE table_schema = DATABASE() AND table_name = p_table;
- IF n > 0 THEN
- SET @demo_sql = p_sql;
- PREPARE demo_stmt FROM @demo_sql;
- EXECUTE demo_stmt;
- DEALLOCATE PREPARE demo_stmt;
- END IF;
- END$$
-
- CREATE PROCEDURE demo_apply_map(IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_map VARCHAR(64))
- BEGIN
- DECLARE n INT DEFAULT 0;
- SELECT COUNT(*) INTO n
- FROM information_schema.columns
- WHERE table_schema = DATABASE()
- AND table_name = p_table
- AND column_name = p_column;
- IF n > 0 THEN
- SET @demo_sql = CONCAT(
- 'UPDATE `', p_table, '` t INNER JOIN `', p_map, '` m ',
- 'ON t.`', p_column, '` COLLATE utf8mb4_unicode_ci = m.old_value ',
- 'SET t.`', p_column, '` = m.new_value'
- );
- PREPARE demo_stmt FROM @demo_sql;
- EXECUTE demo_stmt;
- DEALLOCATE PREPARE demo_stmt;
- END IF;
- END$$
-
- CREATE PROCEDURE demo_apply_pair(
- IN p_table VARCHAR(64),
- IN p_code VARCHAR(64),
- IN p_name VARCHAR(64),
- IN p_map VARCHAR(64)
- )
- BEGIN
- DECLARE ncode INT DEFAULT 0;
- DECLARE nname INT DEFAULT 0;
- SELECT COUNT(*) INTO ncode
- FROM information_schema.columns
- WHERE table_schema = DATABASE() AND table_name = p_table AND column_name = p_code;
- SELECT COUNT(*) INTO nname
- FROM information_schema.columns
- WHERE table_schema = DATABASE() AND table_name = p_table AND column_name = p_name;
- IF ncode > 0 AND nname > 0 THEN
- SET @demo_sql = CONCAT(
- 'UPDATE `', p_table, '` t INNER JOIN `', p_map, '` m ',
- 'ON t.`', p_code, '` COLLATE utf8mb4_unicode_ci = m.old_value ',
- 'SET t.`', p_code, '` = m.new_value, t.`', p_name, '` = m.new_name'
- );
- PREPARE demo_stmt FROM @demo_sql;
- EXECUTE demo_stmt;
- DEALLOCATE PREPARE demo_stmt;
- ELSEIF ncode > 0 THEN
- CALL demo_apply_map(p_table, p_code, p_map);
- END IF;
- END$$
-
- CREATE PROCEDURE anonymize_demo_copy()
- BEGIN
- DECLARE marker_count INT DEFAULT 0;
- DECLARE demo_id BIGINT DEFAULT NULL;
- DECLARE stock_id BIGINT DEFAULT NULL;
- DECLARE prod_id BIGINT DEFAULT NULL;
- DECLARE pwd_hash VARCHAR(80) DEFAULT '$2a$10$9eqxnNGtxFADAW9AbbjRIevr8YWgBqkLr//23U6qYOWs5U9figE2u';
- DECLARE expiry_delta INT DEFAULT NULL;
-
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET demo_id = demo_id;
- DECLARE EXIT HANDLER FOR SQLEXCEPTION
- BEGIN
- ROLLBACK;
- CALL demo_drop_maps();
- RESIGNAL;
- END;
-
- IF DATABASE() IS NULL OR DATABASE() <> 'fpsms_demo' THEN
- SIGNAL SQLSTATE '45000'
- SET MESSAGE_TEXT = 'Refusing to anonymize: current database is not fpsms_demo';
- END IF;
-
- SELECT COUNT(*) INTO marker_count FROM settings WHERE name = 'DEMO.anonymized.v1';
- IF marker_count > 0 THEN
- SIGNAL SQLSTATE '45000'
- SET MESSAGE_TEXT = 'Refusing to anonymize: DEMO.anonymized.v1 already exists';
- END IF;
-
- CALL demo_drop_maps();
-
- CREATE TABLE _demo_map_shop (
- old_value VARCHAR(255) NOT NULL,
- new_value VARCHAR(255) NOT NULL,
- new_name VARCHAR(255) NOT NULL,
- PRIMARY KEY (old_value)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
- CREATE TABLE _demo_map_do (
- old_value VARCHAR(255) NOT NULL,
- new_value VARCHAR(255) NOT NULL,
- PRIMARY KEY (old_value)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
- CREATE TABLE _demo_map_po (
- old_value VARCHAR(255) NOT NULL,
- new_value VARCHAR(255) NOT NULL,
- PRIMARY KEY (old_value)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
- CREATE TABLE _demo_map_user (
- user_id BIGINT NOT NULL,
- old_username VARCHAR(255) NULL,
- new_username VARCHAR(255) NOT NULL,
- old_name VARCHAR(255) NULL,
- new_name VARCHAR(255) NOT NULL,
- PRIMARY KEY (user_id)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
- CREATE TABLE _demo_map_username (
- old_value VARCHAR(255) NOT NULL,
- new_value VARCHAR(255) NOT NULL,
- PRIMARY KEY (old_value)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
- CREATE TABLE _demo_map_person (
- old_value VARCHAR(255) NOT NULL,
- new_value VARCHAR(255) NOT NULL,
- PRIMARY KEY (old_value)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
- SELECT u.id INTO demo_id
- FROM `user` u
- JOIN user_authority ua ON ua.userId = u.id
- JOIN authority a ON a.id = ua.authId
- WHERE a.authority = 'ADMIN'
- ORDER BY u.deleted, u.id
- LIMIT 1;
-
- IF demo_id IS NULL THEN
- SELECT id INTO demo_id FROM `user` ORDER BY deleted, id LIMIT 1;
- END IF;
-
- SELECT u.id INTO stock_id
- FROM `user` u
- WHERE u.id <> IFNULL(demo_id, -1)
- AND EXISTS (
- SELECT 1 FROM user_authority ua
- JOIN authority a ON a.id = ua.authId
- WHERE ua.userId = u.id AND a.authority = 'STOCK'
- )
- AND NOT EXISTS (
- SELECT 1 FROM user_authority ua
- JOIN authority a ON a.id = ua.authId
- WHERE ua.userId = u.id AND a.authority = 'ADMIN'
- )
- ORDER BY u.deleted, u.id
- LIMIT 1;
-
- SELECT u.id INTO prod_id
- FROM `user` u
- WHERE u.id <> IFNULL(demo_id, -1)
- AND u.id <> IFNULL(stock_id, -1)
- AND EXISTS (
- SELECT 1 FROM user_authority ua
- JOIN authority a ON a.id = ua.authId
- WHERE ua.userId = u.id AND a.authority = 'PROD'
- )
- AND NOT EXISTS (
- SELECT 1 FROM user_authority ua
- JOIN authority a ON a.id = ua.authId
- WHERE ua.userId = u.id AND a.authority = 'ADMIN'
- )
- ORDER BY u.deleted, u.id
- LIMIT 1;
-
- INSERT INTO _demo_map_user (user_id, old_username, new_username, old_name, new_name)
- SELECT id,
- NULLIF(username, ''),
- CASE
- WHEN id = demo_id THEN 'demo'
- WHEN id = stock_id THEN 'demo.stock'
- WHEN id = prod_id THEN 'demo.prod'
- ELSE CONCAT('USER-', id)
- END,
- NULLIF(name, ''),
- CASE
- WHEN id = demo_id THEN 'Demo'
- WHEN id = stock_id THEN 'Demo Stock'
- WHEN id = prod_id THEN 'Demo Prod'
- ELSE CONCAT('User ', id)
- END
- FROM `user`;
-
- INSERT INTO _demo_map_username (old_value, new_value)
- SELECT old_username, MIN(new_username)
- FROM _demo_map_user
- WHERE old_username IS NOT NULL
- GROUP BY old_username;
-
- INSERT INTO _demo_map_person (old_value, new_value)
- SELECT old_name, MIN(new_name)
- FROM _demo_map_user
- WHERE old_name IS NOT NULL
- GROUP BY old_name;
-
- INSERT INTO _demo_map_shop (old_value, new_value, new_name)
- SELECT code, CONCAT('S', MIN(id)), CONCAT('Shop ', MIN(id))
- FROM shop
- WHERE code IS NOT NULL AND code <> ''
- GROUP BY code;
-
- INSERT INTO _demo_map_do (old_value, new_value)
- SELECT code,
- CASE
- WHEN stripped = '' THEN CONCAT('DO-', min_id)
- WHEN dup_count > 1 THEN CONCAT(stripped, '-', min_id)
- ELSE stripped
- END
- FROM (
- SELECT g.code,
- g.stripped,
- g.min_id,
- COUNT(*) OVER (PARTITION BY g.stripped) AS dup_count
- FROM (
- SELECT code,
- REPLACE(code, 'TO', '') AS stripped,
- MIN(id) AS min_id
- FROM delivery_order
- WHERE code IS NOT NULL AND code <> ''
- GROUP BY code
- ) g
- ) numbered;
-
- INSERT INTO _demo_map_po (old_value, new_value)
- SELECT code,
- CASE
- WHEN stripped = '' THEN CONCAT('PO-', min_id)
- WHEN dup_count > 1 THEN CONCAT(stripped, '-', min_id)
- ELSE stripped
- END
- FROM (
- SELECT g.code,
- g.stripped,
- g.min_id,
- COUNT(*) OVER (PARTITION BY g.stripped) AS dup_count
- FROM (
- SELECT code,
- REPLACE(REPLACE(code, 'PF', ''), 'PP', '') AS stripped,
- MIN(id) AS min_id
- FROM purchase_order
- WHERE code IS NOT NULL AND code <> ''
- GROUP BY code
- ) g
- ) numbered;
-
- START TRANSACTION;
-
- UPDATE `user` u
- JOIN _demo_map_user m ON m.user_id = u.id
- SET u.username = CONCAT('~u', u.id);
-
- UPDATE `user` u
- JOIN _demo_map_user m ON m.user_id = u.id
- SET u.username = m.new_username,
- u.password = pwd_hash,
- u.name = m.new_name,
- u.fullname = m.new_name,
- u.firstname = 'User',
- u.lastname = CAST(u.id AS CHAR),
- u.email = CASE m.new_username
- WHEN 'demo' THEN '[email protected]'
- WHEN 'demo.stock' THEN '[email protected]'
- WHEN 'demo.prod' THEN '[email protected]'
- ELSE CONCAT('user', u.id, '@example.com')
- END,
- u.phone1 = '',
- u.phone2 = '',
- u.department = '',
- u.title = '',
- u.remarks = '',
- u.staffNo = '';
-
- CALL demo_apply_map('item_lot_trace_log', 'username', '_demo_map_username');
- CALL demo_apply_map('stocktakerecord', 'createdBy', '_demo_map_username');
- CALL demo_apply_map('pick_execution_issue', 'createdBy', '_demo_map_username');
- CALL demo_apply_map('pick_execution_issue', 'modifiedBy', '_demo_map_username');
- CALL demo_apply_map('pick_execution_issue', 'handled_by', '_demo_map_username');
- CALL demo_apply_map('do_pick_order', 'createdBy', '_demo_map_username');
- CALL demo_apply_map('do_pick_order', 'modifiedBy', '_demo_map_username');
- CALL demo_apply_map('do_pick_order_record', 'createdBy', '_demo_map_username');
- CALL demo_apply_map('do_pick_order_record', 'modifiedBy', '_demo_map_username');
- CALL demo_apply_map('delivery_order_pick_order', 'createdBy', '_demo_map_username');
- CALL demo_apply_map('delivery_order_pick_order', 'modifiedBy', '_demo_map_username');
-
- CALL demo_apply_map('stocktakerecord', 'approverName', '_demo_map_person');
- CALL demo_apply_map('stocktakerecord', 'stockTakerName', '_demo_map_person');
- CALL demo_apply_map('do_pick_order', 'handler_name', '_demo_map_person');
- CALL demo_apply_map('do_pick_order_record', 'handler_name', '_demo_map_person');
- CALL demo_apply_map('delivery_order_pick_order', 'handlerName', '_demo_map_person');
- CALL demo_apply_map('pick_execution_issue', 'picker_name', '_demo_map_person');
-
- UPDATE items
- SET name = REPLACE(REPLACE(IFNULL(name, ''), 'TOA', ''), '平記', ''),
- description = REPLACE(REPLACE(IFNULL(description, ''), 'TOA', ''), '平記', '');
-
- UPDATE shop
- SET code = CONCAT('S', id),
- name = CONCAT('Shop ', id),
- contactNo = '88888888',
- addr1 = CONCAT('Addr row 1 ', id),
- addr2 = CONCAT('Addr row 2 ', id),
- addr3 = '香港';
-
- CALL demo_apply_pair('truck', 'ShopCode', 'ShopName', '_demo_map_shop');
- CALL demo_apply_pair('truck_lane_schedule_line', 'shopCode', 'shopName', '_demo_map_shop');
- CALL demo_apply_pair('delivery_order_pick_order', 'shopCode', 'shopName', '_demo_map_shop');
- CALL demo_apply_pair('do_pick_order', 'ShopCode', 'ShopName', '_demo_map_shop');
- CALL demo_apply_pair('do_pick_order_record', 'ShopCode', 'ShopName', '_demo_map_shop');
- CALL demo_apply_pair('do_replenishment', 'shopCode', 'shopName', '_demo_map_shop');
- CALL demo_apply_pair('truck_lane_version_line', 'shopCode', 'branchName', '_demo_map_shop');
- CALL demo_apply_map('truck', 'ShopCode', '_demo_map_shop');
- CALL demo_apply_map('do_replenishment', 'shopCode', '_demo_map_shop');
-
- CALL demo_apply_map('delivery_order', 'code', '_demo_map_do');
- CALL demo_apply_map('do_pick_order', 'delivery_order_code', '_demo_map_do');
- CALL demo_apply_map('do_pick_order_record', 'delivery_order_code', '_demo_map_do');
- CALL demo_apply_map('do_pick_order_line', 'delivery_order_code', '_demo_map_do');
- CALL demo_apply_map('do_pick_order_line_record', 'delivery_order_code', '_demo_map_do');
- CALL demo_apply_map('stock_out', 'deliveryOrderCode', '_demo_map_do');
- CALL demo_apply_map('do_replenishment', 'sourceDoCode', '_demo_map_do');
- CALL demo_apply_map('do_replenishment', 'targetDoCode', '_demo_map_do');
-
- CALL demo_apply_map('purchase_order', 'code', '_demo_map_po');
-
- UPDATE truck
- SET TruckLanceCode = REPLACE(TruckLanceCode, 'P06B', 'AA'),
- remark = REPLACE(remark, 'P06B', 'AA');
- CALL demo_exec_if_table('truck_lane_version',
- 'UPDATE truck_lane_version SET truckLanceCode = REPLACE(truckLanceCode, ''P06B'', ''AA'')');
- CALL demo_exec_if_table('truck_lane_version_line',
- 'UPDATE truck_lane_version_line SET truckLanceCode = REPLACE(truckLanceCode, ''P06B'', ''AA'')');
- CALL demo_exec_if_table('truck_lane_schedule_line',
- 'UPDATE truck_lane_schedule_line SET fromTruckLanceCode = REPLACE(fromTruckLanceCode, ''P06B'', ''AA''), toTruckLanceCode = REPLACE(toTruckLanceCode, ''P06B'', ''AA'')');
- CALL demo_exec_if_table('delivery_order_pick_order',
- 'UPDATE delivery_order_pick_order SET truckLanceCode = REPLACE(truckLanceCode, ''P06B'', ''AA'')');
- CALL demo_exec_if_table('do_pick_order',
- 'UPDATE do_pick_order SET TruckLanceCode = REPLACE(TruckLanceCode, ''P06B'', ''AA'')');
- CALL demo_exec_if_table('do_pick_order_record',
- 'UPDATE do_pick_order_record SET TruckLanceCode = REPLACE(TruckLanceCode, ''P06B'', ''AA'')');
- CALL demo_exec_if_table('do_replenishment',
- 'UPDATE do_replenishment SET truckLaneCode = REPLACE(truckLaneCode, ''P06B'', ''AA'')');
-
- UPDATE purchase_order_line SET price = 1, up = 1;
- UPDATE delivery_order_line SET price = 1, up = 1;
-
- SELECT DATEDIFF(CURDATE(), MAX(DATE(estimatedArrivalDate)))
- INTO expiry_delta
- FROM delivery_order
- WHERE deleted = 0 AND estimatedArrivalDate IS NOT NULL;
-
- IF expiry_delta IS NOT NULL AND expiry_delta > 0 THEN
- UPDATE inventory_lot
- SET expiryDate = DATE_ADD(expiryDate, INTERVAL expiry_delta DAY)
- WHERE expiryDate IS NOT NULL;
- END IF;
-
- UPDATE delivery_order d
- JOIN (
- SELECT eta_day, rn
- FROM (
- SELECT
- DATE(estimatedArrivalDate) AS eta_day,
- ROW_NUMBER() OVER (ORDER BY DATE(estimatedArrivalDate) DESC) AS rn
- FROM delivery_order
- WHERE deleted = 0 AND estimatedArrivalDate IS NOT NULL
- GROUP BY DATE(estimatedArrivalDate)
- ) t
- WHERE rn <= 3
- ) m ON DATE(d.estimatedArrivalDate) = m.eta_day
- SET d.estimatedArrivalDate = TIMESTAMP(
- DATE_ADD(CURDATE(), INTERVAL (m.rn - 1) DAY),
- TIME(d.estimatedArrivalDate)
- )
- WHERE d.deleted = 0;
-
- UPDATE purchase_order p
- JOIN (
- SELECT eta_day, rn
- FROM (
- SELECT
- DATE(estimatedArrivalDate) AS eta_day,
- ROW_NUMBER() OVER (ORDER BY DATE(estimatedArrivalDate) DESC) AS rn
- FROM purchase_order
- WHERE deleted = 0 AND estimatedArrivalDate IS NOT NULL
- GROUP BY DATE(estimatedArrivalDate)
- ) t
- WHERE rn <= 3
- ) m ON DATE(p.estimatedArrivalDate) = m.eta_day
- SET p.estimatedArrivalDate = TIMESTAMP(
- DATE_ADD(CURDATE(), INTERVAL (m.rn - 1) DAY),
- TIME(p.estimatedArrivalDate)
- )
- 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');
-
- INSERT INTO settings (name, value, category, type)
- VALUES ('DEMO.anonymized.v1', '1', 'DEMO', 'string');
-
- INSERT INTO settings (name, value, category, type)
- VALUES ('DEMO.dateAnchor', DATE_FORMAT(CURDATE(), '%Y-%m-%d'), 'DEMO', 'string');
-
- COMMIT;
- CALL demo_drop_maps();
- END$$
-
- DELIMITER ;
-
- CALL anonymize_demo_copy();
-
- DROP PROCEDURE IF EXISTS demo_exec_if_table;
- DROP PROCEDURE IF EXISTS demo_apply_map;
- DROP PROCEDURE IF EXISTS demo_apply_pair;
- DROP PROCEDURE IF EXISTS demo_drop_maps;
- DROP PROCEDURE IF EXISTS anonymize_demo_copy;
-
- SELECT name, value FROM settings WHERE name IN ('DEMO.anonymized.v1', 'DEMO.dateAnchor');
|