/* FT546 shadow-only read model for SQL Server 2016 RTM (13.0). This package creates no Legacy-table triggers and never inserts, updates, or deletes Legacy WMS business rows. */ SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; IF SCHEMA_ID(N'alg') IS NULL EXEC(N'CREATE SCHEMA alg'); GO IF OBJECT_ID(N'alg.warehouse_policy', N'U') IS NULL CREATE TABLE alg.warehouse_policy ( warehouse_id varchar(80) NOT NULL PRIMARY KEY, target_fill_rate decimal(9,4) NULL, fifo_tolerance_hours int NULL, updated_at datetime2 NOT NULL CONSTRAINT DF_alg_warehouse_policy_updated_at DEFAULT SYSUTCDATETIME() ); GO IF OBJECT_ID(N'alg.project_policy', N'U') IS NULL CREATE TABLE alg.project_policy ( project_no varchar(255) NOT NULL PRIMARY KEY, is_isolated bit NOT NULL CONSTRAINT DF_alg_project_policy_isolated DEFAULT 0, is_common bit NOT NULL CONSTRAINT DF_alg_project_policy_common DEFAULT 0, allow_mixed bit NOT NULL CONSTRAINT DF_alg_project_policy_mixed DEFAULT 0, updated_at datetime2 NOT NULL CONSTRAINT DF_alg_project_policy_updated_at DEFAULT SYSUTCDATETIME() ); GO IF OBJECT_ID(N'alg.space_role', N'U') IS NULL CREATE TABLE alg.space_role ( space_id varchar(80) NOT NULL PRIMARY KEY, role varchar(40) NOT NULL, updated_at datetime2 NOT NULL CONSTRAINT DF_alg_space_role_updated_at DEFAULT SYSUTCDATETIME(), CONSTRAINT CK_alg_space_role_role CHECK (role IN ('STORAGE', 'RELOCATION_BUFFER', 'OUTBOUND_BUFFER', 'PROTECTED_CORE')) ); GO IF OBJECT_ID(N'alg.space_topology', N'U') IS NULL CREATE TABLE alg.space_topology ( warehouse_id varchar(80) NOT NULL, space_id varchar(80) NOT NULL CONSTRAINT PK_alg_space_topology PRIMARY KEY, lane_code varchar(80) NOT NULL, lane_depth int NOT NULL, base_zone varchar(20) NOT NULL, rebuilt_at datetime2 NOT NULL CONSTRAINT DF_alg_space_topology_rebuilt_at DEFAULT SYSUTCDATETIME(), CONSTRAINT CK_alg_space_topology_base_zone CHECK (base_zone IN ('CACHE', 'RESERVE', 'MAIN', 'FLEX')) ); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.space_topology') AND name = N'IX_alg_space_topology_warehouse_lane') CREATE INDEX IX_alg_space_topology_warehouse_lane ON alg.space_topology(warehouse_id, lane_code); GO IF OBJECT_ID(N'alg.inventory_item_snapshot', N'U') IS NULL CREATE TABLE alg.inventory_item_snapshot ( warehouse_id varchar(80) NOT NULL, stock_id varchar(80) NOT NULL, space_id varchar(80) NOT NULL, tray_code varchar(255) NULL, project_no varchar(255) NULL, product_no varchar(255) NULL, lot_no varchar(80) NULL, inbound_time_raw varchar(80) NULL, inbound_at datetime2 NULL, quantity decimal(38,6) NULL, out_quantity decimal(38,6) NULL, synchronized_at datetime2 NOT NULL CONSTRAINT DF_alg_inventory_item_snapshot_sync DEFAULT SYSUTCDATETIME(), CONSTRAINT PK_alg_inventory_item_snapshot PRIMARY KEY (warehouse_id, stock_id) ); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.inventory_item_snapshot') AND name = N'IX_alg_inventory_item_snapshot_space') CREATE INDEX IX_alg_inventory_item_snapshot_space ON alg.inventory_item_snapshot(warehouse_id, space_id); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.inventory_item_snapshot') AND name = N'IX_alg_inventory_item_snapshot_tray') CREATE INDEX IX_alg_inventory_item_snapshot_tray ON alg.inventory_item_snapshot(warehouse_id, tray_code) INCLUDE (space_id, project_no, product_no); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.inventory_item_snapshot') AND name = N'IX_alg_inventory_item_snapshot_project_product') CREATE INDEX IX_alg_inventory_item_snapshot_project_product ON alg.inventory_item_snapshot(warehouse_id, project_no, product_no) INCLUDE (space_id, tray_code, inbound_at); GO IF OBJECT_ID(N'alg.space_inventory_summary', N'U') IS NULL CREATE TABLE alg.space_inventory_summary ( warehouse_id varchar(80) NOT NULL, space_id varchar(80) NOT NULL, stock_detail_count int NOT NULL, stock_tray_count int NOT NULL, stock_project_count int NOT NULL, stock_product_count int NOT NULL, synchronized_at datetime2 NOT NULL CONSTRAINT DF_alg_space_inventory_summary_sync DEFAULT SYSUTCDATETIME(), CONSTRAINT PK_alg_space_inventory_summary PRIMARY KEY (warehouse_id, space_id) ); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.space_inventory_summary') AND name = N'IX_alg_space_inventory_summary_space') CREATE INDEX IX_alg_space_inventory_summary_space ON alg.space_inventory_summary(space_id, warehouse_id); GO IF OBJECT_ID(N'alg.lane_state', N'U') IS NULL CREATE TABLE alg.lane_state ( warehouse_id varchar(80) NOT NULL, lane_code varchar(80) NOT NULL, space_count int NOT NULL CONSTRAINT DF_alg_lane_state_space_count DEFAULT 0, occupied_count int NOT NULL CONSTRAINT DF_alg_lane_state_occupied_count DEFAULT 0, available_count int NOT NULL CONSTRAINT DF_alg_lane_state_available_count DEFAULT 0, pending_outbound bit NOT NULL CONSTRAINT DF_alg_lane_state_pending_outbound DEFAULT 0, has_gap bit NOT NULL CONSTRAINT DF_alg_lane_state_has_gap DEFAULT 0, semantic_fingerprint varbinary(32) NULL, state_version rowversion NOT NULL, rebuilt_at datetime2 NOT NULL CONSTRAINT DF_alg_lane_state_rebuilt_at DEFAULT SYSUTCDATETIME(), CONSTRAINT PK_alg_lane_state PRIMARY KEY (warehouse_id, lane_code) ); GO IF COL_LENGTH(N'alg.lane_state', N'semantic_fingerprint') IS NULL ALTER TABLE alg.lane_state ADD semantic_fingerprint varbinary(32) NULL; GO IF OBJECT_ID(N'alg.reservation', N'U') IS NULL CREATE TABLE alg.reservation ( reservation_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_reservation PRIMARY KEY, warehouse_id varchar(80) NOT NULL, lane_code varchar(80) NOT NULL, space_id varchar(80) NOT NULL, project_no varchar(255) NULL, status varchar(20) NOT NULL, created_at datetime2 NOT NULL CONSTRAINT DF_alg_reservation_created_at DEFAULT SYSUTCDATETIME(), released_at datetime2 NULL, CONSTRAINT CK_alg_reservation_status CHECK (status IN ('ACTIVE', 'RELEASED', 'EXPIRED')) ); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.reservation') AND name = N'UX_alg_reservation_active_space') CREATE UNIQUE INDEX UX_alg_reservation_active_space ON alg.reservation(space_id) WHERE status = 'ACTIVE'; GO IF OBJECT_ID(N'alg.deep_workflow_lock', N'U') IS NULL CREATE TABLE alg.deep_workflow_lock ( lock_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_deep_workflow_lock PRIMARY KEY, request_id varchar(80) NOT NULL, warehouse_id varchar(80) NOT NULL, floor_no int NOT NULL, status varchar(20) NOT NULL, created_at datetime2 NOT NULL CONSTRAINT DF_alg_deep_workflow_lock_created_at DEFAULT SYSUTCDATETIME(), released_at datetime2 NULL, CONSTRAINT CK_alg_deep_workflow_lock_status CHECK (status IN ('ACTIVE', 'RELEASED')) ); GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.deep_workflow_lock') AND name = N'UX_alg_deep_workflow_lock_active_floor') CREATE UNIQUE INDEX UX_alg_deep_workflow_lock_active_floor ON alg.deep_workflow_lock(warehouse_id, floor_no) WHERE status = 'ACTIVE'; GO IF OBJECT_ID(N'alg.decision_log', N'U') IS NULL CREATE TABLE alg.decision_log ( decision_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_decision_log PRIMARY KEY, warehouse_id varchar(80) NULL, decision_type varchar(40) NOT NULL, input_version binary(8) NULL, result_code varchar(80) NULL, reason varchar(2000) NULL, created_at datetime2 NOT NULL CONSTRAINT DF_alg_decision_log_created_at DEFAULT SYSUTCDATETIME() ); GO IF OBJECT_ID(N'alg.usp_rebuild_space_topology', N'P') IS NOT NULL DROP PROCEDURE alg.usp_rebuild_space_topology; GO EXEC(N' CREATE PROCEDURE alg.usp_rebuild_space_topology @warehouse_id varchar(80) = NULL AS BEGIN SET NOCOUNT ON; ;WITH lane_topology AS ( SELECT warehouse_id, group_coding_no AS lane_code, COUNT(*) AS lane_depth, MAX(the_column) AS column_no, MIN(the_platoon) AS row_no, MIN(the_floor) AS floor_no, MIN(cargo_space_id) AS stable_id FROM dbo.bas_cargo_space WHERE NULLIF(LTRIM(RTRIM(group_coding_no)), '''') IS NOT NULL AND TRY_CONVERT(int, group_coding) IS NOT NULL AND (@warehouse_id IS NULL OR warehouse_id = @warehouse_id) GROUP BY warehouse_id, group_coding_no ), ranked_lanes AS ( SELECT lane_topology.*, CASE WHEN lane_depth = 1 THEN ROW_NUMBER() OVER ( PARTITION BY warehouse_id ORDER BY CASE WHEN lane_depth = 1 THEN 0 ELSE 1 END, column_no DESC, row_no ASC, floor_no ASC, stable_id ASC ) END AS single_depth_rank FROM lane_topology ), source AS ( SELECT c.warehouse_id, c.cargo_space_id AS space_id, c.group_coding_no AS lane_code, ranked_lanes.lane_depth, CASE WHEN ranked_lanes.lane_depth = 1 AND ranked_lanes.single_depth_rank <= 80 THEN ''CACHE'' WHEN ranked_lanes.lane_depth = 1 AND ranked_lanes.single_depth_rank <= 133 THEN ''RESERVE'' WHEN ranked_lanes.lane_depth = 5 THEN ''MAIN'' ELSE ''FLEX'' END AS base_zone FROM dbo.bas_cargo_space c JOIN ranked_lanes ON ranked_lanes.warehouse_id = c.warehouse_id AND ranked_lanes.lane_code = c.group_coding_no WHERE NULLIF(LTRIM(RTRIM(c.group_coding_no)), '''') IS NOT NULL AND TRY_CONVERT(int, c.group_coding) IS NOT NULL AND (@warehouse_id IS NULL OR c.warehouse_id = @warehouse_id) ) MERGE alg.space_topology AS target USING source ON source.space_id = target.space_id WHEN MATCHED AND (target.warehouse_id <> source.warehouse_id OR target.lane_code <> source.lane_code OR target.lane_depth <> source.lane_depth OR target.base_zone <> source.base_zone) THEN UPDATE SET warehouse_id = source.warehouse_id, lane_code = source.lane_code, lane_depth = source.lane_depth, base_zone = source.base_zone, rebuilt_at = SYSUTCDATETIME() WHEN NOT MATCHED BY TARGET THEN INSERT (warehouse_id, space_id, lane_code, lane_depth, base_zone) VALUES (source.warehouse_id, source.space_id, source.lane_code, source.lane_depth, source.base_zone) WHEN NOT MATCHED BY SOURCE AND (@warehouse_id IS NULL OR target.warehouse_id = @warehouse_id) THEN DELETE; END;'); GO IF OBJECT_ID(N'alg.usp_sync_inventory_snapshot', N'P') IS NOT NULL DROP PROCEDURE alg.usp_sync_inventory_snapshot; GO EXEC(N' CREATE PROCEDURE alg.usp_sync_inventory_snapshot @warehouse_id varchar(80) = NULL AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; BEGIN TRANSACTION; DELETE summary FROM alg.space_inventory_summary summary WHERE @warehouse_id IS NULL OR summary.warehouse_id = @warehouse_id; DELETE item FROM alg.inventory_item_snapshot item WHERE @warehouse_id IS NULL OR item.warehouse_id = @warehouse_id; INSERT INTO alg.inventory_item_snapshot ( warehouse_id, stock_id, space_id, tray_code, project_no, product_no, lot_no, inbound_time_raw, inbound_at, quantity, out_quantity, synchronized_at) SELECT space.warehouse_id, stock.stock_id, stock.cargo_space_id, stock.tray_code, stock.spare4, stock.product_id, stock.lot_no, CONVERT(varchar(80), stock.in_date), TRY_CONVERT(datetime2, stock.in_date), stock.quantity, stock.out_quantity, SYSUTCDATETIME() FROM dbo.bas_stock stock JOIN dbo.bas_cargo_space space ON space.cargo_space_id = stock.cargo_space_id WHERE @warehouse_id IS NULL OR space.warehouse_id = @warehouse_id; INSERT INTO alg.space_inventory_summary ( warehouse_id, space_id, stock_detail_count, stock_tray_count, stock_project_count, stock_product_count, synchronized_at) SELECT item.warehouse_id, item.space_id, COUNT(*), COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.tray_code)), '''')), COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.project_no)), '''')), COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.product_no)), '''')), SYSUTCDATETIME() FROM alg.inventory_item_snapshot item WHERE @warehouse_id IS NULL OR item.warehouse_id = @warehouse_id GROUP BY item.warehouse_id, item.space_id; COMMIT TRANSACTION; END;'); GO IF OBJECT_ID(N'alg.v_inventory_item', N'V') IS NOT NULL DROP VIEW alg.v_inventory_item; GO EXEC(N' CREATE VIEW alg.v_inventory_item AS SELECT stock_id, space_id, tray_code, project_no, product_no, lot_no, inbound_time_raw, inbound_at, quantity, out_quantity FROM alg.inventory_item_snapshot;'); GO IF OBJECT_ID(N'alg.v_active_job', N'V') IS NOT NULL DROP VIEW alg.v_active_job; GO EXEC(N' CREATE VIEW alg.v_active_job AS WITH tray_candidates AS ( SELECT j.job_id, COUNT(DISTINCT s.space_id) AS space_count, MIN(s.space_id) AS cargo_space_id, COUNT(DISTINCT NULLIF(LTRIM(RTRIM(s.project_no)), '''')) AS project_count, MIN(NULLIF(LTRIM(RTRIM(s.project_no)), '''')) AS project_no, COUNT(DISTINCT NULLIF(LTRIM(RTRIM(s.product_no)), '''')) AS product_count, MIN(NULLIF(LTRIM(RTRIM(s.product_no)), '''')) AS product_no FROM dbo.mydo_job j JOIN alg.inventory_item_snapshot s ON s.warehouse_id = j.warehouse_id AND s.tray_code = NULLIF(LTRIM(RTRIM(j.tray_code)), '''') GROUP BY j.job_id ), resolved_jobs AS ( SELECT j.job_id, j.task_no, j.tray_code, j.target_cargo_space_id, j.warehouse_id, j.status, j.in_or_out, j.create_time AS create_time_raw, COALESCE(source_space.cargo_space_id, CASE WHEN tray_candidates.space_count = 1 THEN tray_candidates.cargo_space_id END) AS source_space_id, CASE WHEN source_space.cargo_space_id IS NOT NULL THEN ''EXPLICIT'' WHEN tray_candidates.space_count = 1 THEN ''TRAY'' WHEN tray_candidates.space_count > 1 THEN ''AMBIGUOUS_TRAY'' ELSE ''UNRESOLVED'' END AS source_resolution FROM dbo.mydo_job j LEFT JOIN dbo.bas_cargo_space source_space ON source_space.cargo_space_id = NULLIF(LTRIM(RTRIM(j.cargo_space_id)), '''') AND source_space.warehouse_id = j.warehouse_id LEFT JOIN tray_candidates ON tray_candidates.job_id = j.job_id WHERE j.finish_time IS NULL OR LTRIM(RTRIM(j.finish_time)) = '''' ), source_scope AS ( SELECT resolved_jobs.job_id, COUNT(DISTINCT NULLIF(LTRIM(RTRIM(stock.project_no)), '''')) AS project_count, MIN(NULLIF(LTRIM(RTRIM(stock.project_no)), '''')) AS project_no, COUNT(DISTINCT NULLIF(LTRIM(RTRIM(stock.product_no)), '''')) AS product_count, MIN(NULLIF(LTRIM(RTRIM(stock.product_no)), '''')) AS product_no FROM resolved_jobs JOIN alg.inventory_item_snapshot stock ON stock.warehouse_id = resolved_jobs.warehouse_id AND stock.space_id = resolved_jobs.source_space_id GROUP BY resolved_jobs.job_id ) SELECT resolved_jobs.job_id, resolved_jobs.task_no, resolved_jobs.tray_code, CASE WHEN resolved_jobs.source_space_id IS NOT NULL THEN CASE WHEN source_scope.project_count = 1 THEN source_scope.project_no END ELSE CASE WHEN tray_candidates.project_count = 1 THEN tray_candidates.project_no END END AS project_no, CASE WHEN resolved_jobs.source_space_id IS NOT NULL THEN CASE WHEN source_scope.product_count = 1 THEN source_scope.product_no END ELSE CASE WHEN tray_candidates.product_count = 1 THEN tray_candidates.product_no END END AS product_no, resolved_jobs.source_space_id, resolved_jobs.target_cargo_space_id, resolved_jobs.warehouse_id, resolved_jobs.status, resolved_jobs.in_or_out, resolved_jobs.create_time_raw, resolved_space.group_coding_no AS source_lane_code, resolved_jobs.source_resolution FROM resolved_jobs LEFT JOIN tray_candidates ON tray_candidates.job_id = resolved_jobs.job_id LEFT JOIN source_scope ON source_scope.job_id = resolved_jobs.job_id LEFT JOIN dbo.bas_cargo_space resolved_space ON resolved_space.cargo_space_id = resolved_jobs.source_space_id;'); GO IF OBJECT_ID(N'alg.v_space_state', N'V') IS NOT NULL DROP VIEW alg.v_space_state; GO EXEC(N' CREATE VIEW alg.v_space_state AS WITH outbound_lanes AS ( SELECT DISTINCT warehouse_id, source_lane_code AS lane_code FROM alg.v_active_job WHERE in_or_out >= 20 AND source_lane_code IS NOT NULL ), lane_gaps AS ( SELECT DISTINCT inner_space.warehouse_id, inner_space.group_coding_no AS lane_code FROM dbo.bas_cargo_space inner_space JOIN dbo.bas_cargo_space outer_space ON outer_space.warehouse_id = inner_space.warehouse_id AND outer_space.group_coding_no = inner_space.group_coding_no AND TRY_CONVERT(int, outer_space.group_coding) > TRY_CONVERT(int, inner_space.group_coding) WHERE TRY_CONVERT(int, inner_space.group_coding) IS NOT NULL AND TRY_CONVERT(int, outer_space.group_coding) IS NOT NULL AND NULLIF(LTRIM(RTRIM(inner_space.tray_code)), '''') IS NULL AND NOT EXISTS ( SELECT 1 FROM alg.inventory_item_snapshot inner_stock WHERE inner_stock.warehouse_id = inner_space.warehouse_id AND inner_stock.space_id = inner_space.cargo_space_id ) AND ( NULLIF(LTRIM(RTRIM(outer_space.tray_code)), '''') IS NOT NULL OR EXISTS ( SELECT 1 FROM alg.inventory_item_snapshot outer_stock WHERE outer_stock.warehouse_id = outer_space.warehouse_id AND outer_stock.space_id = outer_space.cargo_space_id ) ) ) SELECT c.cargo_space_id AS space_id, c.warehouse_id, c.group_coding_no AS lane_code, c.cargo_area_id AS area_id, CASE WHEN ISNULL(role.role, ''STORAGE'') IN (''RELOCATION_BUFFER'', ''OUTBOUND_BUFFER'') THEN ''CACHE'' WHEN ISNULL(role.role, ''STORAGE'') = ''PROTECTED_CORE'' THEN ''RESERVE'' ELSE topology.base_zone END AS zone_code, c.roadway_id, c.cargo_space_name AS display_name, c.the_platoon AS platoon, c.the_column AS column_no, c.the_floor AS floor_no, c.group_coding AS depth_raw, TRY_CONVERT(int, c.group_coding) AS depth, c.status AS space_status, c.locked, c.tray_code AS space_tray_code, ISNULL(role.role, ''STORAGE'') AS role, ISNULL(stock.stock_detail_count, 0) AS stock_detail_count, ISNULL(stock.stock_tray_count, 0) AS stock_tray_count, ISNULL(stock.stock_project_count, 0) AS stock_project_count, ISNULL(stock.stock_product_count, 0) AS stock_product_count, CONVERT(bit, CASE WHEN ISNULL(stock.stock_tray_count, 0) > 1 THEN 1 ELSE 0 END) AS tray_conflict, CONVERT(bit, CASE WHEN ISNULL(stock.stock_project_count, 0) > 1 THEN 1 ELSE 0 END) AS project_conflict, CONVERT(bit, 0) AS product_conflict, CONVERT(bit, CASE WHEN outbound_lanes.lane_code IS NULL THEN 0 ELSE 1 END) AS pending_outbound, active_reservations.reservation_id, CONVERT(bit, CASE WHEN active_reservations.reservation_id IS NULL THEN 0 ELSE 1 END) AS reserved, CONVERT(bit, CASE WHEN lane_gaps.lane_code IS NULL THEN 0 ELSE 1 END) AS has_gap, CONVERT(bit, CASE WHEN c.status IS NULL OR c.status <> ''1'' THEN 0 WHEN NULLIF(LTRIM(RTRIM(c.locked)), '''') IS NOT NULL AND LTRIM(RTRIM(c.locked)) NOT IN (''0'', ''N'') THEN 0 WHEN NULLIF(LTRIM(RTRIM(c.tray_code)), '''') IS NOT NULL THEN 0 WHEN ISNULL(stock.stock_detail_count, 0) <> 0 THEN 0 WHEN TRY_CONVERT(int, c.group_coding) IS NULL THEN 0 WHEN ISNULL(role.role, ''STORAGE'') <> ''STORAGE'' THEN 0 WHEN outbound_lanes.lane_code IS NOT NULL THEN 0 WHEN active_reservations.reservation_id IS NOT NULL THEN 0 WHEN lane_gaps.lane_code IS NOT NULL THEN 0 WHEN EXISTS ( SELECT 1 FROM dbo.bas_cargo_space inner_candidate LEFT JOIN alg.space_inventory_summary inner_stock ON inner_stock.warehouse_id = inner_candidate.warehouse_id AND inner_stock.space_id = inner_candidate.cargo_space_id WHERE inner_candidate.warehouse_id = c.warehouse_id AND inner_candidate.group_coding_no = c.group_coding_no AND TRY_CONVERT(int, inner_candidate.group_coding) < TRY_CONVERT(int, c.group_coding) AND inner_candidate.status = ''1'' AND NULLIF(LTRIM(RTRIM(inner_candidate.tray_code)), '''') IS NULL AND inner_stock.space_id IS NULL ) THEN 0 ELSE 1 END) AS inbound_available FROM dbo.bas_cargo_space c JOIN alg.space_topology topology ON topology.space_id = c.cargo_space_id LEFT JOIN alg.space_inventory_summary stock ON stock.warehouse_id = c.warehouse_id AND stock.space_id = c.cargo_space_id LEFT JOIN alg.space_role role ON role.space_id = c.cargo_space_id LEFT JOIN outbound_lanes ON outbound_lanes.warehouse_id = c.warehouse_id AND outbound_lanes.lane_code = c.group_coding_no LEFT JOIN alg.reservation active_reservations ON active_reservations.space_id = c.cargo_space_id AND active_reservations.status = ''ACTIVE'' LEFT JOIN lane_gaps ON lane_gaps.warehouse_id = c.warehouse_id AND lane_gaps.lane_code = c.group_coding_no;'); GO IF OBJECT_ID(N'alg.usp_compute_lane_semantic_fingerprint', N'P') IS NOT NULL DROP PROCEDURE alg.usp_compute_lane_semantic_fingerprint; GO EXEC(N' CREATE PROCEDURE alg.usp_compute_lane_semantic_fingerprint @warehouse_id varchar(80), @lane_code varchar(80), @semantic_fingerprint varbinary(32) OUTPUT, @inventory_source varchar(20) = ''LIVE'' AS BEGIN SET NOCOUNT ON; DECLARE @payload nvarchar(max); CREATE TABLE #fingerprint_inventory ( stock_id varchar(80) NOT NULL, space_id varchar(80) NOT NULL, tray_code varchar(255) NULL, project_no varchar(255) NULL, product_no varchar(255) NULL, lot_no varchar(80) NULL, inbound_time varchar(80) NULL, quantity decimal(38,6) NULL, out_quantity decimal(38,6) NULL ); IF @inventory_source = ''SNAPSHOT'' BEGIN INSERT INTO #fingerprint_inventory ( stock_id, space_id, tray_code, project_no, product_no, lot_no, inbound_time, quantity, out_quantity) SELECT stock.stock_id, stock.space_id, stock.tray_code, stock.project_no, stock.product_no, stock.lot_no, stock.inbound_time_raw, CONVERT(decimal(38,6), stock.quantity), CONVERT(decimal(38,6), stock.out_quantity) FROM alg.inventory_item_snapshot stock JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = stock.space_id AND cargo.warehouse_id = stock.warehouse_id WHERE cargo.warehouse_id = @warehouse_id AND cargo.group_coding_no = @lane_code; END ELSE IF @inventory_source = ''LIVE'' BEGIN INSERT INTO #fingerprint_inventory ( stock_id, space_id, tray_code, project_no, product_no, lot_no, inbound_time, quantity, out_quantity) SELECT stock.stock_id, stock.cargo_space_id, stock.tray_code, stock.spare4, stock.product_id, stock.lot_no, CONVERT(varchar(80), stock.in_date), CONVERT(decimal(38,6), stock.quantity), CONVERT(decimal(38,6), stock.out_quantity) FROM dbo.bas_stock stock JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = stock.cargo_space_id WHERE cargo.warehouse_id = @warehouse_id AND cargo.group_coding_no = @lane_code; END ELSE BEGIN THROW 50001, ''Unsupported inventory fingerprint source'', 1; END; SELECT @payload = ISNULL(CONVERT(nvarchar(max), ( SELECT cargo.cargo_space_id AS [@space_id], cargo.status AS [@status], cargo.locked AS [@locked], cargo.tray_code AS [@tray_code], cargo.group_coding AS [@depth], cargo.the_platoon AS [@platoon], cargo.the_column AS [@column], cargo.the_floor AS [@floor], topology.lane_depth AS [@lane_depth], topology.base_zone AS [@base_zone], ISNULL(role.role, ''STORAGE'') AS [@role] FROM dbo.bas_cargo_space cargo LEFT JOIN alg.space_topology topology ON topology.space_id = cargo.cargo_space_id LEFT JOIN alg.space_role role ON role.space_id = cargo.cargo_space_id WHERE cargo.warehouse_id = @warehouse_id AND cargo.group_coding_no = @lane_code ORDER BY TRY_CONVERT(int, cargo.group_coding), cargo.cargo_space_id FOR XML PATH(''space''), ROOT(''spaces''), TYPE )), N''''); SET @payload = @payload + N''|INVENTORY|'' + ISNULL(CONVERT(nvarchar(max), ( SELECT stock.stock_id AS [@stock_id], stock.space_id AS [@space_id], stock.tray_code AS [@tray_code], stock.project_no AS [@project_no], stock.product_no AS [@product_no], stock.lot_no AS [@lot_no], stock.inbound_time AS [@inbound_time], stock.quantity AS [@quantity], stock.out_quantity AS [@out_quantity] FROM #fingerprint_inventory stock ORDER BY stock.space_id, stock.stock_id FOR XML PATH(''item''), ROOT(''inventory''), TYPE )), N''''); SET @payload = @payload + N''|ACTIVE_JOBS|'' + ISNULL(CONVERT(nvarchar(max), ( SELECT job.job_id AS [@job_id], job.task_no AS [@task_no], job.tray_code AS [@tray_code], job.source_space_id AS [@source_space_id], job.target_cargo_space_id AS [@target_space_id], job.status AS [@status], job.in_or_out AS [@in_or_out], job.create_time_raw AS [@create_time] FROM alg.v_active_job job WHERE job.warehouse_id = @warehouse_id AND job.source_lane_code = @lane_code ORDER BY job.job_id FOR XML PATH(''job''), ROOT(''jobs''), TYPE )), N''''); SET @payload = @payload + N''|PROJECT_POLICY|'' + ISNULL(CONVERT(nvarchar(max), ( SELECT policy.project_no AS [@project_no], policy.is_isolated AS [@is_isolated], policy.is_common AS [@is_common], policy.allow_mixed AS [@allow_mixed] FROM alg.project_policy policy ORDER BY policy.project_no FOR XML PATH(''project''), ROOT(''project_policy''), TYPE )), N''''); SET @payload = @payload + N''|WAREHOUSE_POLICY|'' + ISNULL(CONVERT(nvarchar(max), ( SELECT policy.warehouse_id AS [@warehouse_id], policy.target_fill_rate AS [@target_fill_rate], policy.fifo_tolerance_hours AS [@fifo_tolerance_hours] FROM alg.warehouse_policy policy WHERE policy.warehouse_id = @warehouse_id FOR XML PATH(''warehouse''), ROOT(''warehouse_policy''), TYPE )), N''''); SET @payload = @payload + N''|RESERVATIONS|'' + ISNULL(CONVERT(nvarchar(max), ( SELECT reservation.reservation_id AS [@reservation_id], reservation.space_id AS [@space_id], reservation.project_no AS [@project_no], reservation.status AS [@status] FROM alg.reservation reservation WHERE reservation.warehouse_id = @warehouse_id AND reservation.lane_code = @lane_code AND reservation.status = ''ACTIVE'' ORDER BY reservation.space_id, reservation.reservation_id FOR XML PATH(''reservation''), ROOT(''reservations''), TYPE )), N''''); SET @semantic_fingerprint = HASHBYTES(''SHA2_256'', CONVERT(varbinary(max), @payload)); END;'); GO IF OBJECT_ID(N'alg.usp_rebuild_lane_state', N'P') IS NOT NULL DROP PROCEDURE alg.usp_rebuild_lane_state; GO EXEC(N' CREATE PROCEDURE alg.usp_rebuild_lane_state @warehouse_id varchar(80) = NULL, @lane_code varchar(80) = NULL AS BEGIN SET NOCOUNT ON; SELECT warehouse_id, lane_code, COUNT(*) AS space_count, SUM(CASE WHEN space_status = ''2'' OR stock_detail_count > 0 THEN 1 ELSE 0 END) AS occupied_count, SUM(CASE WHEN inbound_available = 1 THEN 1 ELSE 0 END) AS available_count, MAX(CASE WHEN pending_outbound = 1 THEN 1 ELSE 0 END) AS pending_outbound, MAX(CASE WHEN has_gap = 1 THEN 1 ELSE 0 END) AS has_gap, CAST(NULL AS varbinary(32)) AS semantic_fingerprint INTO #source_state FROM alg.v_space_state WHERE (@warehouse_id IS NULL OR warehouse_id = @warehouse_id) AND (@lane_code IS NULL OR lane_code = @lane_code) GROUP BY warehouse_id, lane_code; DECLARE @fingerprint_warehouse varchar(80), @fingerprint_lane varchar(80), @fingerprint varbinary(32); DECLARE fingerprint_cursor CURSOR LOCAL FAST_FORWARD FOR SELECT warehouse_id, lane_code FROM #source_state ORDER BY warehouse_id, lane_code; OPEN fingerprint_cursor; FETCH NEXT FROM fingerprint_cursor INTO @fingerprint_warehouse, @fingerprint_lane; WHILE @@FETCH_STATUS = 0 BEGIN EXEC alg.usp_compute_lane_semantic_fingerprint @warehouse_id = @fingerprint_warehouse, @lane_code = @fingerprint_lane, @semantic_fingerprint = @fingerprint OUTPUT, @inventory_source = ''SNAPSHOT''; UPDATE #source_state SET semantic_fingerprint = @fingerprint WHERE warehouse_id = @fingerprint_warehouse AND lane_code = @fingerprint_lane; FETCH NEXT FROM fingerprint_cursor INTO @fingerprint_warehouse, @fingerprint_lane; END; CLOSE fingerprint_cursor; DEALLOCATE fingerprint_cursor; MERGE alg.lane_state WITH (HOLDLOCK) AS target USING #source_state AS source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code WHEN MATCHED AND (target.space_count <> source.space_count OR target.occupied_count <> source.occupied_count OR target.available_count <> source.available_count OR target.pending_outbound <> source.pending_outbound OR target.has_gap <> source.has_gap OR target.semantic_fingerprint IS NULL OR target.semantic_fingerprint <> source.semantic_fingerprint) THEN UPDATE SET space_count = source.space_count, occupied_count = source.occupied_count, available_count = source.available_count, pending_outbound = source.pending_outbound, has_gap = source.has_gap, semantic_fingerprint = source.semantic_fingerprint, rebuilt_at = SYSUTCDATETIME() WHEN NOT MATCHED BY TARGET THEN INSERT (warehouse_id, lane_code, space_count, occupied_count, available_count, pending_outbound, has_gap, semantic_fingerprint) VALUES (source.warehouse_id, source.lane_code, source.space_count, source.occupied_count, source.available_count, source.pending_outbound, source.has_gap, source.semantic_fingerprint) WHEN NOT MATCHED BY SOURCE AND (@warehouse_id IS NULL OR target.warehouse_id = @warehouse_id) AND (@lane_code IS NULL OR target.lane_code = @lane_code) THEN DELETE; END;'); GO IF OBJECT_ID(N'alg.usp_refresh_dirty_lanes', N'P') IS NOT NULL DROP PROCEDURE alg.usp_refresh_dirty_lanes; GO EXEC(N' CREATE PROCEDURE alg.usp_refresh_dirty_lanes @warehouse_id varchar(80) AS BEGIN SET NOCOUNT ON; IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '''') IS NULL THROW 50002, ''warehouse_id is required'', 1; EXEC alg.usp_rebuild_space_topology @warehouse_id = @warehouse_id; EXEC alg.usp_sync_inventory_snapshot @warehouse_id = @warehouse_id; EXEC alg.usp_rebuild_lane_state @warehouse_id = @warehouse_id; END;'); GO IF NOT EXISTS (SELECT 1 FROM alg.space_topology) AND NOT EXISTS (SELECT 1 FROM alg.inventory_item_snapshot) AND NOT EXISTS (SELECT 1 FROM alg.lane_state) BEGIN EXEC alg.usp_rebuild_space_topology; EXEC alg.usp_sync_inventory_snapshot; EXEC alg.usp_rebuild_lane_state; END; GO