Files
FT546MWS/fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql

1328 lines
68 KiB
Transact-SQL

/*
FT546 shadow-only read model for SQL Server 2016 RTM (13.0).
This package writes only alg.* and never changes Legacy WMS business rows.
A clean install creates an INITIALIZING state for warehouse 01. The v3
worker owns the first refresh and publication.
*/
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
IF SCHEMA_ID(N'alg') IS NOT NULL
THROW 51000, 'FT546 shadow install refused: alg schema already exists', 1;
CREATE SCHEMA alg;
GO
CREATE TABLE alg.shadow_package_manifest (
package_id varchar(80) NOT NULL CONSTRAINT PK_alg_shadow_package_manifest PRIMARY KEY,
package_version varchar(40) NOT NULL,
installed_at datetime2 NOT NULL CONSTRAINT DF_alg_shadow_package_manifest_installed_at DEFAULT SYSUTCDATETIME()
);
INSERT INTO alg.shadow_package_manifest (package_id, package_version)
VALUES ('FT546WMS_SHADOW_ONLY', '2026-09-03-3');
GO
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
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
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
CREATE TABLE alg.space_topology (
warehouse_id varchar(80) NOT NULL,
space_id varchar(80) NOT NULL,
lane_code varchar(80) NOT NULL,
lane_depth int NOT NULL,
base_zone varchar(20) NOT NULL,
snapshot_generation bigint NOT NULL,
rebuilt_at datetime2 NOT NULL CONSTRAINT DF_alg_space_topology_rebuilt_at DEFAULT SYSUTCDATETIME(),
CONSTRAINT PK_alg_space_topology PRIMARY KEY (warehouse_id, space_id),
CONSTRAINT CK_alg_space_topology_base_zone CHECK (base_zone IN ('CACHE', 'RESERVE', 'MAIN', 'FLEX'))
);
GO
CREATE INDEX IX_alg_space_topology_warehouse_lane ON alg.space_topology(warehouse_id, lane_code);
GO
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,
snapshot_generation bigint NOT 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
CREATE INDEX IX_alg_inventory_item_snapshot_space
ON alg.inventory_item_snapshot(warehouse_id, space_id);
GO
CREATE INDEX IX_alg_inventory_item_snapshot_tray
ON alg.inventory_item_snapshot(warehouse_id, tray_code)
INCLUDE (space_id, project_no, product_no, snapshot_generation);
GO
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, snapshot_generation);
GO
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,
snapshot_generation bigint 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
CREATE INDEX IX_alg_space_inventory_summary_space
ON alg.space_inventory_summary(space_id, warehouse_id);
GO
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,
snapshot_generation bigint NOT 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
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
CREATE UNIQUE INDEX UX_alg_reservation_active_space
ON alg.reservation(space_id) WHERE status = 'ACTIVE';
GO
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
CREATE UNIQUE INDEX UX_alg_deep_workflow_lock_active_floor
ON alg.deep_workflow_lock(warehouse_id, floor_no) WHERE status = 'ACTIVE';
GO
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 nvarchar(4000) NULL,
created_at datetime2 NOT NULL CONSTRAINT DF_alg_decision_log_created_at DEFAULT SYSUTCDATETIME()
);
GO
CREATE TABLE alg.shadow_snapshot_state (
warehouse_id varchar(80) NOT NULL PRIMARY KEY,
snapshot_generation bigint NOT NULL,
snapshot_status varchar(20) NOT NULL,
synchronized_at datetime2 NULL,
source_signature varbinary(32) NULL,
source_row_count bigint NULL,
instance_id varchar(80) NULL,
last_error varchar(1000) NULL,
CONSTRAINT CK_alg_shadow_snapshot_state_status CHECK (snapshot_status IN ('INITIALIZING', 'REFRESHING', 'PUBLISHED', 'FAILED'))
);
GO
INSERT INTO alg.shadow_snapshot_state (warehouse_id, snapshot_generation, snapshot_status)
VALUES ('01', 0, 'INITIALIZING');
GO
CREATE TABLE alg.cargo_space_snapshot (
warehouse_id varchar(80) NOT NULL,
space_id varchar(80) NOT NULL,
lane_code varchar(80) NULL,
cargo_area_id varchar(80) NULL,
roadway_id varchar(80) NULL,
display_name varchar(255) NULL,
platoon int NULL,
column_no int NULL,
floor_no int NULL,
depth_raw varchar(80) NULL,
space_status varchar(20) NULL,
locked varchar(20) NULL,
tray_code varchar(255) NULL,
snapshot_generation bigint NOT NULL,
synchronized_at datetime2 NOT NULL,
CONSTRAINT PK_alg_cargo_space_snapshot PRIMARY KEY (warehouse_id, space_id)
);
GO
CREATE TABLE alg.active_job_snapshot (
warehouse_id varchar(80) NOT NULL,
job_id varchar(80) NOT NULL,
task_no varchar(80) NULL,
tray_code varchar(255) NULL,
source_space_id varchar(80) NULL,
target_space_id varchar(80) NULL,
status varchar(20) NULL,
in_or_out varchar(20) NULL,
create_time_raw varchar(80) NULL,
snapshot_generation bigint NOT NULL,
synchronized_at datetime2 NOT NULL,
CONSTRAINT PK_alg_active_job_snapshot PRIMARY KEY (warehouse_id, job_id)
);
GO
CREATE TABLE alg.shadow_inbound_request_snapshot (
warehouse_id varchar(80) NOT NULL,
task_no varchar(80) NOT NULL,
tray_no varchar(255) NOT NULL,
request_id varchar(80) NULL,
raw_warehouse_id varchar(80) NULL,
project_no varchar(255) NULL,
product_id varchar(255) NULL,
lot_no varchar(80) NULL,
snapshot_generation bigint NOT NULL,
synchronized_at datetime2 NOT NULL,
CONSTRAINT PK_alg_shadow_inbound_request_snapshot PRIMARY KEY (warehouse_id, task_no, tray_no)
);
GO
CREATE TABLE alg.shadow_outbound_request_snapshot (
warehouse_id varchar(80) NOT NULL,
stockout_detail_id varchar(80) NOT NULL,
raw_warehouse_id varchar(80) NULL,
project_no varchar(255) NULL,
product_id varchar(255) NULL,
requested_quantity decimal(38,6) NULL,
snapshot_generation bigint NOT NULL,
synchronized_at datetime2 NOT NULL,
CONSTRAINT PK_alg_shadow_outbound_request_snapshot PRIMARY KEY (warehouse_id, stockout_detail_id)
);
GO
CREATE TABLE alg.shadow_runtime_metric (
warehouse_id varchar(80) NOT NULL,
metric_name varchar(80) NOT NULL,
bucket_upper_micros bigint NOT NULL,
metric_count bigint NOT NULL CONSTRAINT DF_alg_shadow_runtime_metric_count DEFAULT 0,
metric_total_micros bigint NOT NULL CONSTRAINT DF_alg_shadow_runtime_metric_total DEFAULT 0,
metric_max_micros bigint NOT NULL CONSTRAINT DF_alg_shadow_runtime_metric_max DEFAULT 0,
flushed_at datetime2 NULL,
CONSTRAINT PK_alg_shadow_runtime_metric PRIMARY KEY (warehouse_id, metric_name, bucket_upper_micros)
);
GO
CREATE TABLE alg.shadow_instance_heartbeat (
warehouse_id varchar(80) NOT NULL PRIMARY KEY,
instance_id varchar(80) NOT NULL,
claimed_at datetime2 NOT NULL,
last_seen_at datetime2 NOT NULL
);
GO
CREATE PROCEDURE alg.usp_rebuild_space_topology
@warehouse_id varchar(80) = NULL,
@snapshot_generation bigint = NULL
AS
BEGIN
SET NOCOUNT ON;
IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '') IS NULL
THROW 51019, 'warehouse_id is required', 1;
DECLARE @generation bigint;
SET @generation = @snapshot_generation;
IF @generation IS NULL
SELECT @generation = state.snapshot_generation
FROM alg.shadow_snapshot_state state
WHERE state.warehouse_id = @warehouse_id
AND state.snapshot_status = 'PUBLISHED';
IF @generation IS NULL
THROW 51020, 'FT546 shadow topology rebuild requires a snapshot generation', 1;
;WITH lane_topology AS (
SELECT cargo.warehouse_id, cargo.lane_code,
COUNT(*) AS lane_depth,
MAX(cargo.column_no) AS column_no,
MIN(cargo.platoon) AS row_no,
MIN(cargo.floor_no) AS floor_no,
MIN(cargo.space_id) AS stable_id
FROM alg.cargo_space_snapshot cargo
WHERE cargo.snapshot_generation = @generation
AND NULLIF(LTRIM(RTRIM(cargo.lane_code)), '') IS NOT NULL
AND TRY_CONVERT(int, cargo.depth_raw) IS NOT NULL
AND (@warehouse_id IS NULL OR cargo.warehouse_id = @warehouse_id)
GROUP BY cargo.warehouse_id, cargo.lane_code
), ranked_lanes AS (
SELECT lane_topology.*,
CASE WHEN lane_depth = 1 THEN ROW_NUMBER() OVER (
PARTITION BY warehouse_id
ORDER BY column_no DESC, row_no ASC, floor_no ASC, stable_id ASC
) END AS single_depth_rank
FROM lane_topology
), source_rows AS (
SELECT cargo.warehouse_id, cargo.space_id, cargo.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 alg.cargo_space_snapshot cargo
JOIN ranked_lanes ON ranked_lanes.warehouse_id = cargo.warehouse_id
AND ranked_lanes.lane_code = cargo.lane_code
WHERE cargo.snapshot_generation = @generation
AND NULLIF(LTRIM(RTRIM(cargo.lane_code)), '') IS NOT NULL
AND TRY_CONVERT(int, cargo.depth_raw) IS NOT NULL
AND (@warehouse_id IS NULL OR cargo.warehouse_id = @warehouse_id)
)
MERGE alg.space_topology WITH (HOLDLOCK) AS target
USING source_rows AS source
ON target.warehouse_id = source.warehouse_id AND target.space_id = source.space_id
WHEN MATCHED AND (target.lane_code <> source.lane_code OR target.lane_depth <> source.lane_depth
OR target.base_zone <> source.base_zone OR target.snapshot_generation <> @generation)
THEN UPDATE SET lane_code = source.lane_code, lane_depth = source.lane_depth,
base_zone = source.base_zone, snapshot_generation = @generation,
rebuilt_at = SYSUTCDATETIME()
WHEN NOT MATCHED BY TARGET THEN
INSERT (warehouse_id, space_id, lane_code, lane_depth, base_zone, snapshot_generation)
VALUES (source.warehouse_id, source.space_id, source.lane_code, source.lane_depth,
source.base_zone, @generation)
WHEN NOT MATCHED BY SOURCE AND (@warehouse_id IS NULL OR target.warehouse_id = @warehouse_id)
THEN DELETE;
END;
GO
CREATE PROCEDURE alg.usp_sync_inventory_snapshot
@warehouse_id varchar(80) = NULL,
@snapshot_generation bigint = NULL
AS
BEGIN
SET NOCOUNT ON;
IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '') IS NULL
THROW 51019, 'warehouse_id is required', 1;
DECLARE @generation bigint;
SET @generation = @snapshot_generation;
IF @generation IS NULL
SELECT @generation = state.snapshot_generation
FROM alg.shadow_snapshot_state state
WHERE state.warehouse_id = @warehouse_id
AND state.snapshot_status = 'PUBLISHED';
IF @generation IS NULL
THROW 51021, 'FT546 shadow inventory summary requires a snapshot generation', 1;
DELETE summary
FROM alg.space_inventory_summary summary
WHERE (@warehouse_id IS NULL OR summary.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, snapshot_generation, 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)), '')),
@generation, SYSUTCDATETIME()
FROM alg.inventory_item_snapshot item
WHERE item.snapshot_generation = @generation
AND (@warehouse_id IS NULL OR item.warehouse_id = @warehouse_id)
GROUP BY item.warehouse_id, item.space_id;
END;
GO
CREATE VIEW alg.v_inventory_item
AS
-- generation contract: WHERE snapshot_generation = published_snapshot.snapshot_generation
SELECT item.warehouse_id, item.stock_id, item.space_id, item.tray_code,
item.project_no, item.product_no, item.lot_no, item.inbound_time_raw,
item.inbound_at, item.quantity, item.out_quantity, item.snapshot_generation
FROM alg.inventory_item_snapshot item
JOIN alg.shadow_snapshot_state published_snapshot
ON published_snapshot.warehouse_id = item.warehouse_id
AND published_snapshot.snapshot_status = 'PUBLISHED'
AND item.snapshot_generation = published_snapshot.snapshot_generation;
GO
CREATE VIEW alg.v_active_job
AS
WITH published_jobs AS (
SELECT job.warehouse_id, job.job_id, job.task_no, job.tray_code,
job.source_space_id, job.target_space_id, job.status, job.in_or_out,
job.create_time_raw, job.snapshot_generation
FROM alg.active_job_snapshot job
JOIN alg.shadow_snapshot_state published_snapshot
ON published_snapshot.warehouse_id = job.warehouse_id
AND published_snapshot.snapshot_status = 'PUBLISHED'
AND job.snapshot_generation = published_snapshot.snapshot_generation
), tray_candidates AS (
SELECT job.warehouse_id, job.job_id, job.snapshot_generation,
COUNT(DISTINCT stock.space_id) AS space_count,
MIN(stock.space_id) AS cargo_space_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 published_jobs job
JOIN alg.inventory_item_snapshot stock
ON stock.warehouse_id = job.warehouse_id
AND stock.snapshot_generation = job.snapshot_generation
AND stock.tray_code = NULLIF(LTRIM(RTRIM(job.tray_code)), '')
GROUP BY job.warehouse_id, job.job_id, job.snapshot_generation
), resolved_jobs AS (
SELECT job.job_id, job.task_no, job.tray_code, job.target_space_id,
job.warehouse_id, job.status, job.in_or_out, job.create_time_raw,
job.snapshot_generation,
COALESCE(NULLIF(LTRIM(RTRIM(job.source_space_id)), ''),
CASE WHEN tray_candidates.space_count = 1 THEN tray_candidates.cargo_space_id END) AS source_space_id,
CASE WHEN NULLIF(LTRIM(RTRIM(job.source_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 published_jobs job
LEFT JOIN tray_candidates
ON tray_candidates.warehouse_id = job.warehouse_id
AND tray_candidates.job_id = job.job_id
AND tray_candidates.snapshot_generation = job.snapshot_generation
WHERE job.snapshot_generation IS NOT NULL
), source_scope AS (
SELECT resolved.warehouse_id, resolved.job_id, resolved.snapshot_generation,
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 resolved
JOIN alg.inventory_item_snapshot stock
ON stock.warehouse_id = resolved.warehouse_id
AND stock.snapshot_generation = resolved.snapshot_generation
AND stock.space_id = resolved.source_space_id
GROUP BY resolved.warehouse_id, resolved.job_id, resolved.snapshot_generation
)
SELECT resolved.job_id, resolved.task_no, resolved.tray_code,
CASE WHEN resolved.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.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.source_space_id, resolved.target_space_id AS target_cargo_space_id,
resolved.warehouse_id, resolved.status, resolved.in_or_out,
resolved.create_time_raw, source_cargo.lane_code AS source_lane_code,
resolved.source_resolution, resolved.snapshot_generation
FROM resolved_jobs resolved
LEFT JOIN tray_candidates
ON tray_candidates.warehouse_id = resolved.warehouse_id
AND tray_candidates.job_id = resolved.job_id
AND tray_candidates.snapshot_generation = resolved.snapshot_generation
LEFT JOIN source_scope
ON source_scope.warehouse_id = resolved.warehouse_id
AND source_scope.job_id = resolved.job_id
AND source_scope.snapshot_generation = resolved.snapshot_generation
LEFT JOIN alg.cargo_space_snapshot source_cargo
ON source_cargo.warehouse_id = resolved.warehouse_id
AND source_cargo.space_id = resolved.source_space_id
AND source_cargo.snapshot_generation = resolved.snapshot_generation;
GO
CREATE VIEW alg.v_space_state
AS
WITH published_snapshot AS (
SELECT state.warehouse_id, state.snapshot_generation
FROM alg.shadow_snapshot_state state
WHERE state.snapshot_status = 'PUBLISHED'
), outbound_lanes AS (
SELECT DISTINCT job.warehouse_id, job.source_lane_code AS lane_code,
job.snapshot_generation
FROM alg.v_active_job job
WHERE TRY_CONVERT(int, job.in_or_out) >= 20
AND job.source_lane_code IS NOT NULL
), lane_gaps AS (
SELECT DISTINCT inner_space.warehouse_id, inner_space.lane_code,
inner_space.snapshot_generation
FROM alg.cargo_space_snapshot inner_space
JOIN alg.cargo_space_snapshot outer_space
ON outer_space.warehouse_id = inner_space.warehouse_id
AND outer_space.lane_code = inner_space.lane_code
AND outer_space.snapshot_generation = inner_space.snapshot_generation
AND TRY_CONVERT(int, outer_space.depth_raw) > TRY_CONVERT(int, inner_space.depth_raw)
JOIN published_snapshot published
ON published.warehouse_id = inner_space.warehouse_id
AND published.snapshot_generation = inner_space.snapshot_generation
LEFT JOIN alg.space_inventory_summary inner_stock
ON inner_stock.warehouse_id = inner_space.warehouse_id
AND inner_stock.space_id = inner_space.space_id
AND inner_stock.snapshot_generation = inner_space.snapshot_generation
LEFT JOIN alg.space_inventory_summary outer_stock
ON outer_stock.warehouse_id = outer_space.warehouse_id
AND outer_stock.space_id = outer_space.space_id
AND outer_stock.snapshot_generation = outer_space.snapshot_generation
WHERE TRY_CONVERT(int, inner_space.depth_raw) IS NOT NULL
AND TRY_CONVERT(int, outer_space.depth_raw) IS NOT NULL
AND NULLIF(LTRIM(RTRIM(inner_space.tray_code)), '') IS NULL
AND inner_stock.space_id IS NULL
AND (NULLIF(LTRIM(RTRIM(outer_space.tray_code)), '') IS NOT NULL
OR outer_stock.space_id IS NOT NULL)
)
SELECT cargo.space_id, cargo.warehouse_id, cargo.lane_code,
cargo.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,
cargo.roadway_id, cargo.display_name, cargo.platoon, cargo.column_no,
cargo.floor_no, cargo.depth_raw,
TRY_CONVERT(int, cargo.depth_raw) AS depth, cargo.space_status,
cargo.locked, cargo.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 cargo.space_status IS NULL OR cargo.space_status <> '1' THEN 0
WHEN NULLIF(LTRIM(RTRIM(cargo.locked)), '') IS NOT NULL
AND LTRIM(RTRIM(cargo.locked)) NOT IN ('0', 'N') THEN 0
WHEN NULLIF(LTRIM(RTRIM(cargo.tray_code)), '') IS NOT NULL THEN 0
WHEN ISNULL(stock.stock_detail_count, 0) <> 0 THEN 0
WHEN TRY_CONVERT(int, cargo.depth_raw) 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 EXISTS (
SELECT 1
FROM alg.cargo_space_snapshot inner_candidate
LEFT JOIN alg.space_inventory_summary inner_candidate_stock
ON inner_candidate_stock.warehouse_id = inner_candidate.warehouse_id
AND inner_candidate_stock.space_id = inner_candidate.space_id
AND inner_candidate_stock.snapshot_generation = inner_candidate.snapshot_generation
WHERE inner_candidate.warehouse_id = cargo.warehouse_id
AND inner_candidate.lane_code = cargo.lane_code
AND inner_candidate.snapshot_generation = cargo.snapshot_generation
AND TRY_CONVERT(int, inner_candidate.depth_raw) < TRY_CONVERT(int, cargo.depth_raw)
AND inner_candidate.space_status = '1'
AND NULLIF(LTRIM(RTRIM(inner_candidate.tray_code)), '') IS NULL
AND inner_candidate_stock.space_id IS NULL
) THEN 0
ELSE 1 END) AS inbound_available,
cargo.snapshot_generation
FROM alg.cargo_space_snapshot cargo
JOIN published_snapshot published
ON published.warehouse_id = cargo.warehouse_id
AND published.snapshot_generation = cargo.snapshot_generation
JOIN alg.space_topology topology
ON topology.warehouse_id = cargo.warehouse_id
AND topology.space_id = cargo.space_id
AND topology.snapshot_generation = cargo.snapshot_generation
LEFT JOIN alg.space_inventory_summary stock
ON stock.warehouse_id = cargo.warehouse_id
AND stock.space_id = cargo.space_id
AND stock.snapshot_generation = cargo.snapshot_generation
LEFT JOIN alg.space_role role ON role.space_id = cargo.space_id
LEFT JOIN outbound_lanes
ON outbound_lanes.warehouse_id = cargo.warehouse_id
AND outbound_lanes.lane_code = cargo.lane_code
AND outbound_lanes.snapshot_generation = cargo.snapshot_generation
LEFT JOIN alg.reservation active_reservations
ON active_reservations.space_id = cargo.space_id
AND active_reservations.status = 'ACTIVE'
LEFT JOIN lane_gaps
ON lane_gaps.warehouse_id = cargo.warehouse_id
AND lane_gaps.lane_code = cargo.lane_code
AND lane_gaps.snapshot_generation = cargo.snapshot_generation;
GO
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) = 'SNAPSHOT',
@snapshot_generation bigint = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @generation bigint, @payload nvarchar(max);
IF @inventory_source <> 'SNAPSHOT'
THROW 51022, 'FT546 shadow fingerprint source must be SNAPSHOT', 1;
SELECT @generation = COALESCE(@snapshot_generation, state.snapshot_generation)
FROM alg.shadow_snapshot_state state
WHERE state.warehouse_id = @warehouse_id
AND state.snapshot_status = 'PUBLISHED';
IF @generation IS NULL
THROW 51023, 'FT546 shadow fingerprint requires a snapshot generation', 1;
SELECT @payload = ISNULL(CONVERT(nvarchar(max), (
SELECT cargo.space_id AS [@space_id], cargo.space_status AS [@status],
cargo.locked AS [@locked], cargo.tray_code AS [@tray_code],
cargo.depth_raw AS [@depth], cargo.platoon AS [@platoon],
cargo.column_no AS [@column], cargo.floor_no AS [@floor],
topology.lane_depth AS [@lane_depth], topology.base_zone AS [@base_zone],
ISNULL(role.role, 'STORAGE') AS [@role]
FROM alg.cargo_space_snapshot cargo
LEFT JOIN alg.space_topology topology
ON topology.warehouse_id = cargo.warehouse_id
AND topology.space_id = cargo.space_id
AND topology.snapshot_generation = @generation
LEFT JOIN alg.space_role role ON role.space_id = cargo.space_id
WHERE cargo.warehouse_id = @warehouse_id
AND cargo.lane_code = @lane_code
AND cargo.snapshot_generation = @generation
ORDER BY TRY_CONVERT(int, cargo.depth_raw), cargo.space_id
FOR XML PATH('space'), ROOT('spaces'), TYPE
)), '');
SET @payload = @payload + '|INVENTORY|' + ISNULL(CONVERT(nvarchar(max), (
SELECT item.stock_id AS [@stock_id], item.space_id AS [@space_id],
item.tray_code AS [@tray_code], item.project_no AS [@project_no],
item.product_no AS [@product_no], item.lot_no AS [@lot_no],
item.inbound_time_raw AS [@inbound_time], item.quantity AS [@quantity],
item.out_quantity AS [@out_quantity]
FROM alg.inventory_item_snapshot item
WHERE item.warehouse_id = @warehouse_id
AND item.snapshot_generation = @generation
AND EXISTS (SELECT 1 FROM alg.cargo_space_snapshot cargo
WHERE cargo.warehouse_id = item.warehouse_id
AND cargo.space_id = item.space_id
AND cargo.lane_code = @lane_code
AND cargo.snapshot_generation = @generation)
ORDER BY item.space_id, item.stock_id
FOR XML PATH('item'), ROOT('inventory'), TYPE
)), '');
SET @payload = @payload + '|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_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.active_job_snapshot job
JOIN alg.cargo_space_snapshot source_cargo
ON source_cargo.warehouse_id = job.warehouse_id
AND source_cargo.space_id = job.source_space_id
AND source_cargo.snapshot_generation = job.snapshot_generation
WHERE job.warehouse_id = @warehouse_id
AND source_cargo.lane_code = @lane_code
AND job.snapshot_generation = @generation
ORDER BY job.job_id
FOR XML PATH('job'), ROOT('jobs'), TYPE
)), '');
SET @payload = @payload + '|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
)), '');
SET @payload = @payload + '|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
)), '');
SET @payload = @payload + '|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
)), '');
SET @semantic_fingerprint = HASHBYTES('SHA2_256', CONVERT(varbinary(max), @payload));
END;
GO
CREATE PROCEDURE alg.usp_rebuild_lane_state
@warehouse_id varchar(80) = NULL,
@lane_code varchar(80) = NULL,
@snapshot_generation bigint = NULL
AS
BEGIN
SET NOCOUNT ON;
IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '') IS NULL
THROW 51019, 'warehouse_id is required', 1;
DECLARE @generation bigint;
SET @generation = @snapshot_generation;
IF @generation IS NULL
SELECT @generation = state.snapshot_generation
FROM alg.shadow_snapshot_state state
WHERE state.warehouse_id = @warehouse_id
AND state.snapshot_status = 'PUBLISHED';
IF @generation IS NULL
THROW 51024, 'FT546 shadow lane rebuild requires a snapshot generation', 1;
;WITH outbound_lanes AS (
SELECT DISTINCT job.warehouse_id, cargo.lane_code
FROM alg.active_job_snapshot job
JOIN alg.cargo_space_snapshot cargo
ON cargo.warehouse_id = job.warehouse_id
AND cargo.space_id = job.source_space_id
AND cargo.snapshot_generation = @generation
WHERE job.snapshot_generation = @generation
AND TRY_CONVERT(int, job.in_or_out) >= 20
AND cargo.lane_code IS NOT NULL
), lane_gaps AS (
SELECT DISTINCT inner_space.warehouse_id, inner_space.lane_code
FROM alg.cargo_space_snapshot inner_space
JOIN alg.cargo_space_snapshot outer_space
ON outer_space.warehouse_id = inner_space.warehouse_id
AND outer_space.lane_code = inner_space.lane_code
AND outer_space.snapshot_generation = @generation
AND TRY_CONVERT(int, outer_space.depth_raw) > TRY_CONVERT(int, inner_space.depth_raw)
LEFT JOIN alg.space_inventory_summary inner_stock
ON inner_stock.warehouse_id = inner_space.warehouse_id
AND inner_stock.space_id = inner_space.space_id
AND inner_stock.snapshot_generation = @generation
LEFT JOIN alg.space_inventory_summary outer_stock
ON outer_stock.warehouse_id = outer_space.warehouse_id
AND outer_stock.space_id = outer_space.space_id
AND outer_stock.snapshot_generation = @generation
WHERE inner_space.snapshot_generation = @generation
AND NULLIF(LTRIM(RTRIM(inner_space.tray_code)), '') IS NULL
AND inner_stock.space_id IS NULL
AND (NULLIF(LTRIM(RTRIM(outer_space.tray_code)), '') IS NOT NULL
OR outer_stock.space_id IS NOT NULL)
)
SELECT cargo.warehouse_id, cargo.lane_code,
COUNT(*) AS space_count,
SUM(CASE WHEN cargo.space_status = '2' OR ISNULL(stock.stock_detail_count, 0) > 0 THEN 1 ELSE 0 END) AS occupied_count,
SUM(CASE WHEN cargo.space_status = '1'
AND (NULLIF(LTRIM(RTRIM(cargo.locked)), '') IS NULL OR LTRIM(RTRIM(cargo.locked)) IN ('0', 'N'))
AND NULLIF(LTRIM(RTRIM(cargo.tray_code)), '') IS NULL
AND ISNULL(stock.stock_detail_count, 0) = 0
AND ISNULL(role.role, 'STORAGE') = 'STORAGE'
AND outbound_lanes.lane_code IS NULL
AND reservation.reservation_id IS NULL
AND lane_gaps.lane_code IS NULL
THEN 1 ELSE 0 END) AS available_count,
CONVERT(bit, CASE WHEN outbound_lanes.lane_code IS NULL THEN 0 ELSE 1 END) AS pending_outbound,
CONVERT(bit, CASE WHEN lane_gaps.lane_code IS NULL THEN 0 ELSE 1 END) AS has_gap,
CAST(NULL AS varbinary(32)) AS semantic_fingerprint
INTO #source_state
FROM alg.cargo_space_snapshot cargo
LEFT JOIN alg.space_inventory_summary stock
ON stock.warehouse_id = cargo.warehouse_id
AND stock.space_id = cargo.space_id
AND stock.snapshot_generation = @generation
LEFT JOIN alg.space_role role ON role.space_id = cargo.space_id
LEFT JOIN outbound_lanes
ON outbound_lanes.warehouse_id = cargo.warehouse_id
AND outbound_lanes.lane_code = cargo.lane_code
LEFT JOIN alg.reservation reservation
ON reservation.space_id = cargo.space_id
AND reservation.status = 'ACTIVE'
LEFT JOIN lane_gaps
ON lane_gaps.warehouse_id = cargo.warehouse_id
AND lane_gaps.lane_code = cargo.lane_code
WHERE cargo.snapshot_generation = @generation
AND (@warehouse_id IS NULL OR cargo.warehouse_id = @warehouse_id)
AND (@lane_code IS NULL OR cargo.lane_code = @lane_code)
GROUP BY cargo.warehouse_id, cargo.lane_code,
outbound_lanes.lane_code, lane_gaps.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',
@snapshot_generation = @generation;
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.snapshot_generation <> @generation 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,
snapshot_generation = @generation,
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, snapshot_generation)
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, @generation)
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
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 51002, 'warehouse_id is required', 1;
DECLARE @generation bigint;
SELECT @generation = snapshot_generation
FROM alg.shadow_snapshot_state
WHERE warehouse_id = @warehouse_id AND snapshot_status = 'PUBLISHED';
IF @generation IS NULL
THROW 51003, 'published snapshot is required', 1;
EXEC alg.usp_rebuild_space_topology @warehouse_id = @warehouse_id,
@snapshot_generation = @generation;
EXEC alg.usp_sync_inventory_snapshot @warehouse_id = @warehouse_id,
@snapshot_generation = @generation;
EXEC alg.usp_rebuild_lane_state @warehouse_id = @warehouse_id,
@snapshot_generation = @generation;
END;
GO
CREATE PROCEDURE alg.usp_claim_shadow_instance
@warehouse_id varchar(80),
@instance_id varchar(80),
@claimed bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SET @claimed = 0;
IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '') IS NULL
THROW 51004, 'warehouse_id is required', 1;
IF NULLIF(LTRIM(RTRIM(@instance_id)), '') IS NULL
THROW 51005, 'instance_id is required', 1;
DECLARE @now datetime2 = SYSUTCDATETIME(), @current_instance varchar(80),
@last_seen_at datetime2;
BEGIN TRY
BEGIN TRANSACTION;
SELECT @current_instance = heartbeat.instance_id, @last_seen_at = heartbeat.last_seen_at
FROM alg.shadow_instance_heartbeat heartbeat WITH (UPDLOCK, HOLDLOCK)
WHERE heartbeat.warehouse_id = @warehouse_id;
IF @current_instance IS NULL
BEGIN
INSERT INTO alg.shadow_instance_heartbeat (warehouse_id, instance_id, claimed_at, last_seen_at)
VALUES (@warehouse_id, @instance_id, @now, @now);
SET @claimed = 1;
END
ELSE IF @current_instance = @instance_id
BEGIN
UPDATE alg.shadow_instance_heartbeat
SET last_seen_at = @now
WHERE warehouse_id = @warehouse_id;
SET @claimed = 1;
END
ELSE IF @last_seen_at < DATEADD(second, -120, @now)
BEGIN
UPDATE alg.shadow_instance_heartbeat
SET instance_id = @instance_id, claimed_at = @now, last_seen_at = @now
WHERE warehouse_id = @warehouse_id;
SET @claimed = 1;
END;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
THROW;
END CATCH;
SELECT @claimed AS claimed;
END;
GO
CREATE PROCEDURE alg.usp_refresh_shadow_snapshot
@warehouse_id varchar(80),
@snapshot_generation bigint,
@instance_id varchar(80)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '') IS NULL
THROW 51006, 'warehouse_id is required', 1;
IF NULLIF(LTRIM(RTRIM(@instance_id)), '') IS NULL
THROW 51007, 'instance_id is required', 1;
IF @snapshot_generation <= 0
THROW 51008, 'snapshot_generation must be positive', 1;
DECLARE @pre_source_count bigint, @post_source_count bigint,
@pre_source_signature varbinary(32), @post_source_signature varbinary(32),
@source_payload nvarchar(max), @synchronized_at datetime2,
@numeric_warehouse_id decimal(38,0),
@current_generation bigint;
IF LTRIM(RTRIM(@warehouse_id)) NOT LIKE '%[^0-9]%'
SET @numeric_warehouse_id = TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(@warehouse_id)));
BEGIN TRY
BEGIN TRANSACTION;
SELECT @current_generation = state.snapshot_generation
FROM alg.shadow_snapshot_state state WITH (UPDLOCK, HOLDLOCK)
WHERE state.warehouse_id = @warehouse_id;
IF @current_generation IS NOT NULL AND @snapshot_generation <= @current_generation
THROW 51009, 'snapshot_generation must advance the published generation', 1;
SELECT @pre_source_count =
(SELECT COUNT_BIG(*) FROM dbo.bas_cargo_space cargo WITH (NOLOCK) WHERE cargo.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.bas_stock stock WITH (NOLOCK)
JOIN dbo.bas_cargo_space cargo WITH (NOLOCK) ON cargo.cargo_space_id = stock.cargo_space_id
WHERE cargo.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.mydo_job job WITH (NOLOCK) WHERE job.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.mydo_job_detail detail WITH (NOLOCK)
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
WHERE job.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.in_stockin_detail inbound WITH (NOLOCK)
JOIN dbo.mydo_job_detail detail WITH (NOLOCK) ON detail.stockin_detail_id = inbound.stockin_detail_id
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
JOIN dbo.in_stockin stockin WITH (NOLOCK) ON stockin.stockin_id = inbound.stockin_id
WHERE (job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '')
AND (LTRIM(RTRIM(stockin.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockin.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockin.warehouse_id))) = @numeric_warehouse_id)))
+ (SELECT COUNT_BIG(*) FROM dbo.out_stockout_detail outbound WITH (NOLOCK)
JOIN dbo.out_stockout stockout WITH (NOLOCK) ON stockout.stockout_id = outbound.stockout_id
WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)
AND (LTRIM(RTRIM(stockout.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockout.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockout.warehouse_id))) = @numeric_warehouse_id)));
SELECT @source_payload = ISNULL(CONVERT(nvarchar(max), (
SELECT cargo.cargo_space_id AS [@space_id], cargo.warehouse_id AS [@warehouse_id],
cargo.group_coding_no AS [@lane_code], cargo.cargo_area_id AS [@cargo_area_id],
cargo.roadway_id AS [@roadway_id], cargo.cargo_space_name AS [@display_name],
cargo.the_platoon AS [@platoon], cargo.the_column AS [@column_no],
cargo.the_floor AS [@floor_no], cargo.group_coding AS [@depth_raw],
cargo.status AS [@space_status], cargo.locked AS [@locked], cargo.tray_code AS [@tray_code]
FROM dbo.bas_cargo_space cargo WITH (NOLOCK)
WHERE cargo.warehouse_id = @warehouse_id
ORDER BY cargo.cargo_space_id
FOR XML PATH('cargo'), ROOT('cargo_spaces'), TYPE
)), '');
SET @source_payload = @source_payload + '|STOCK|' + ISNULL(CONVERT(nvarchar(max), (
SELECT stock.stock_id AS [@stock_id], stock.cargo_space_id AS [@space_id],
stock.warehouse_id AS [@warehouse_id], stock.tray_code AS [@tray_code],
stock.spare4 AS [@project_no], stock.product_id AS [@product_no],
stock.lot_no AS [@lot_no], stock.in_date AS [@in_date],
stock.quantity AS [@quantity], stock.out_quantity AS [@out_quantity]
FROM dbo.bas_stock stock WITH (NOLOCK)
JOIN dbo.bas_cargo_space cargo WITH (NOLOCK) ON cargo.cargo_space_id = stock.cargo_space_id
WHERE cargo.warehouse_id = @warehouse_id
ORDER BY stock.stock_id
FOR XML PATH('stock'), ROOT('stocks'), TYPE
)), '');
SET @source_payload = @source_payload + '|JOB|' + ISNULL(CONVERT(nvarchar(max), (
SELECT job.job_id AS [@job_id], job.status AS [@status], job.task_no AS [@task_no],
job.tray_code AS [@tray_code], job.cargo_space_id AS [@source_space_id],
job.target_cargo_space_id AS [@target_space_id], job.in_or_out AS [@in_or_out],
job.create_time AS [@create_time], job.finish_time AS [@finish_time],
job.warehouse_id AS [@warehouse_id]
FROM dbo.mydo_job job WITH (NOLOCK)
WHERE job.warehouse_id = @warehouse_id
ORDER BY job.job_id
FOR XML PATH('job'), ROOT('jobs'), TYPE
)), '');
SET @source_payload = @source_payload + '|JOB_DETAIL|' + ISNULL(CONVERT(nvarchar(max), (
SELECT detail.job_detail_id AS [@job_detail_id], detail.job_id AS [@job_id],
detail.stock_id AS [@stock_id], detail.lot_no AS [@lot_no],
detail.in_date AS [@in_date], detail.in_or_out_id AS [@request_id],
detail.in_or_out_d_id AS [@request_detail_id], detail.product_id AS [@product_id],
detail.stock_status AS [@stock_status], detail.in_quantity AS [@in_quantity],
detail.stock_quantity AS [@stock_quantity], detail.out_quantity AS [@out_quantity],
detail.pick_quantity AS [@pick_quantity], detail.stockin_detail_id AS [@stockin_detail_id]
FROM dbo.mydo_job_detail detail WITH (NOLOCK)
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
WHERE job.warehouse_id = @warehouse_id
ORDER BY detail.job_detail_id
FOR XML PATH('job_detail'), ROOT('job_details'), TYPE
)), '');
SET @source_payload = @source_payload + '|INBOUND|' + ISNULL(CONVERT(nvarchar(max), (
SELECT inbound.stockin_detail_id AS [@stockin_detail_id], inbound.stockin_guid AS [@stockin_guid],
inbound.stockin_id AS [@stockin_id], inbound.lot_no AS [@lot_no],
inbound.product_id AS [@product_id], inbound.quantity AS [@quantity],
inbound.assign_num AS [@assign_num], inbound.spare4 AS [@project_no],
job.warehouse_id AS [@warehouse_id], stockin.warehouse_id AS [@source_warehouse_id],
job.task_no AS [@task_no],
job.tray_code AS [@tray_code], detail.job_id AS [@job_id],
detail.in_or_out_id AS [@request_id]
FROM dbo.in_stockin_detail inbound WITH (NOLOCK)
JOIN dbo.mydo_job_detail detail WITH (NOLOCK) ON detail.stockin_detail_id = inbound.stockin_detail_id
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
JOIN dbo.in_stockin stockin WITH (NOLOCK) ON stockin.stockin_id = inbound.stockin_id
WHERE (job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '')
AND (LTRIM(RTRIM(stockin.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockin.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockin.warehouse_id))) = @numeric_warehouse_id))
ORDER BY inbound.stockin_detail_id
FOR XML PATH('inbound'), ROOT('inbound_requests'), TYPE
)), '');
SET @source_payload = @source_payload + '|OUTBOUND|' + ISNULL(CONVERT(nvarchar(max), (
SELECT outbound.stockout_detail_id AS [@stockout_detail_id], outbound.warehouse_id AS [@warehouse_id],
stockout.warehouse_id AS [@source_warehouse_id],
warehouse.project_no AS [@project_no],
outbound.product_id AS [@product_id], outbound.lot_no AS [@lot_no],
outbound.quantity AS [@quantity], outbound.assign_num AS [@assign_num],
outbound.allot_quantity AS [@allot_quantity]
FROM dbo.out_stockout_detail outbound WITH (NOLOCK)
JOIN dbo.out_stockout stockout WITH (NOLOCK) ON stockout.stockout_id = outbound.stockout_id
LEFT JOIN dbo.bas_warehouse warehouse WITH (NOLOCK)
ON warehouse.warehouse_id = @warehouse_id
WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)
AND (LTRIM(RTRIM(stockout.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockout.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockout.warehouse_id))) = @numeric_warehouse_id))
ORDER BY outbound.stockout_detail_id
FOR XML PATH('outbound'), ROOT('outbound_requests'), TYPE
)), '');
SET @pre_source_signature = HASHBYTES('SHA2_256', CONVERT(varbinary(max), @source_payload));
DELETE FROM alg.cargo_space_snapshot WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.inventory_item_snapshot WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.active_job_snapshot WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.shadow_inbound_request_snapshot WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.shadow_outbound_request_snapshot WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.space_topology WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.space_inventory_summary WHERE warehouse_id = @warehouse_id;
DELETE FROM alg.lane_state WHERE warehouse_id = @warehouse_id;
SET @synchronized_at = SYSUTCDATETIME();
INSERT INTO alg.cargo_space_snapshot (
warehouse_id, space_id, lane_code, cargo_area_id, roadway_id, display_name,
platoon, column_no, floor_no, depth_raw, space_status, locked, tray_code,
snapshot_generation, synchronized_at)
SELECT cargo.warehouse_id, cargo.cargo_space_id, cargo.group_coding_no,
cargo.cargo_area_id, cargo.roadway_id, cargo.cargo_space_name,
cargo.the_platoon, cargo.the_column, cargo.the_floor, cargo.group_coding,
cargo.status, cargo.locked, cargo.tray_code,
@snapshot_generation, @synchronized_at
FROM dbo.bas_cargo_space cargo WITH (NOLOCK)
WHERE cargo.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, snapshot_generation, synchronized_at)
SELECT cargo.warehouse_id, stock.stock_id, stock.cargo_space_id, stock.tray_code,
stock.spare4, stock.product_id, stock.lot_no, stock.in_date,
TRY_CONVERT(datetime2, stock.in_date), stock.quantity, stock.out_quantity,
@snapshot_generation, @synchronized_at
FROM dbo.bas_stock stock WITH (NOLOCK)
JOIN dbo.bas_cargo_space cargo WITH (NOLOCK) ON cargo.cargo_space_id = stock.cargo_space_id
WHERE cargo.warehouse_id = @warehouse_id;
INSERT INTO alg.active_job_snapshot (
warehouse_id, job_id, task_no, tray_code, source_space_id, target_space_id,
status, in_or_out, create_time_raw, snapshot_generation, synchronized_at)
SELECT job.warehouse_id, job.job_id, job.task_no, job.tray_code,
NULLIF(LTRIM(RTRIM(job.cargo_space_id)), ''),
NULLIF(LTRIM(RTRIM(job.target_cargo_space_id)), ''), job.status,
job.in_or_out, job.create_time, @snapshot_generation, @synchronized_at
FROM dbo.mydo_job job WITH (NOLOCK)
WHERE job.warehouse_id = @warehouse_id
AND (job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '');
;WITH inbound_source AS (
SELECT @warehouse_id AS warehouse_id, job.task_no, job.tray_code,
detail.in_or_out_id AS request_id, job.warehouse_id AS raw_warehouse_id,
inbound.spare4 AS project_no, inbound.product_id, inbound.lot_no,
ROW_NUMBER() OVER (
PARTITION BY job.task_no, job.tray_code
ORDER BY inbound.stockin_detail_id, detail.job_detail_id) AS source_rank
FROM dbo.in_stockin_detail inbound WITH (NOLOCK)
JOIN dbo.mydo_job_detail detail WITH (NOLOCK)
ON detail.stockin_detail_id = inbound.stockin_detail_id
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
JOIN dbo.in_stockin stockin WITH (NOLOCK) ON stockin.stockin_id = inbound.stockin_id
WHERE (job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '')
AND (LTRIM(RTRIM(stockin.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockin.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockin.warehouse_id))) = @numeric_warehouse_id))
)
INSERT INTO alg.shadow_inbound_request_snapshot (
warehouse_id, task_no, tray_no, request_id, raw_warehouse_id,
project_no, product_id, lot_no, snapshot_generation, synchronized_at)
SELECT @warehouse_id, ISNULL(task_no, ''), ISNULL(tray_code, ''), request_id,
raw_warehouse_id, project_no, product_id, lot_no,
@snapshot_generation, @synchronized_at
FROM inbound_source
WHERE source_rank = 1;
INSERT INTO alg.shadow_outbound_request_snapshot (
warehouse_id, stockout_detail_id, raw_warehouse_id, project_no, product_id,
requested_quantity, snapshot_generation, synchronized_at)
SELECT @warehouse_id, outbound.stockout_detail_id, outbound.warehouse_id,
NULLIF(LTRIM(RTRIM(warehouse.project_no)), ''), outbound.product_id,
CONVERT(decimal(38,6), outbound.quantity),
@snapshot_generation, @synchronized_at
FROM dbo.out_stockout_detail outbound WITH (NOLOCK)
JOIN dbo.out_stockout stockout WITH (NOLOCK) ON stockout.stockout_id = outbound.stockout_id
LEFT JOIN dbo.bas_warehouse warehouse WITH (NOLOCK)
ON warehouse.warehouse_id = @warehouse_id
WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)
AND (LTRIM(RTRIM(stockout.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockout.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockout.warehouse_id))) = @numeric_warehouse_id));
EXEC alg.usp_rebuild_space_topology @warehouse_id = @warehouse_id,
@snapshot_generation = @snapshot_generation;
EXEC alg.usp_sync_inventory_snapshot @warehouse_id = @warehouse_id,
@snapshot_generation = @snapshot_generation;
EXEC alg.usp_rebuild_lane_state @warehouse_id = @warehouse_id,
@snapshot_generation = @snapshot_generation;
SELECT @post_source_count =
(SELECT COUNT_BIG(*) FROM dbo.bas_cargo_space cargo WITH (NOLOCK) WHERE cargo.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.bas_stock stock WITH (NOLOCK)
JOIN dbo.bas_cargo_space cargo WITH (NOLOCK) ON cargo.cargo_space_id = stock.cargo_space_id
WHERE cargo.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.mydo_job job WITH (NOLOCK) WHERE job.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.mydo_job_detail detail WITH (NOLOCK)
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
WHERE job.warehouse_id = @warehouse_id)
+ (SELECT COUNT_BIG(*) FROM dbo.in_stockin_detail inbound WITH (NOLOCK)
JOIN dbo.mydo_job_detail detail WITH (NOLOCK) ON detail.stockin_detail_id = inbound.stockin_detail_id
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
JOIN dbo.in_stockin stockin WITH (NOLOCK) ON stockin.stockin_id = inbound.stockin_id
WHERE (job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '')
AND (LTRIM(RTRIM(stockin.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockin.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockin.warehouse_id))) = @numeric_warehouse_id)))
+ (SELECT COUNT_BIG(*) FROM dbo.out_stockout_detail outbound WITH (NOLOCK)
JOIN dbo.out_stockout stockout WITH (NOLOCK) ON stockout.stockout_id = outbound.stockout_id
WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)
AND (LTRIM(RTRIM(stockout.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockout.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockout.warehouse_id))) = @numeric_warehouse_id)));
SELECT @source_payload = ISNULL(CONVERT(nvarchar(max), (
SELECT cargo.cargo_space_id AS [@space_id], cargo.warehouse_id AS [@warehouse_id],
cargo.group_coding_no AS [@lane_code], cargo.cargo_area_id AS [@cargo_area_id],
cargo.roadway_id AS [@roadway_id], cargo.cargo_space_name AS [@display_name],
cargo.the_platoon AS [@platoon], cargo.the_column AS [@column_no],
cargo.the_floor AS [@floor_no], cargo.group_coding AS [@depth_raw],
cargo.status AS [@space_status], cargo.locked AS [@locked], cargo.tray_code AS [@tray_code]
FROM dbo.bas_cargo_space cargo WITH (NOLOCK)
WHERE cargo.warehouse_id = @warehouse_id
ORDER BY cargo.cargo_space_id
FOR XML PATH('cargo'), ROOT('cargo_spaces'), TYPE
)), '');
SET @source_payload = @source_payload + '|STOCK|' + ISNULL(CONVERT(nvarchar(max), (
SELECT stock.stock_id AS [@stock_id], stock.cargo_space_id AS [@space_id],
stock.warehouse_id AS [@warehouse_id], stock.tray_code AS [@tray_code],
stock.spare4 AS [@project_no], stock.product_id AS [@product_no],
stock.lot_no AS [@lot_no], stock.in_date AS [@in_date],
stock.quantity AS [@quantity], stock.out_quantity AS [@out_quantity]
FROM dbo.bas_stock stock WITH (NOLOCK)
JOIN dbo.bas_cargo_space cargo WITH (NOLOCK) ON cargo.cargo_space_id = stock.cargo_space_id
WHERE cargo.warehouse_id = @warehouse_id
ORDER BY stock.stock_id
FOR XML PATH('stock'), ROOT('stocks'), TYPE
)), '');
SET @source_payload = @source_payload + '|JOB|' + ISNULL(CONVERT(nvarchar(max), (
SELECT job.job_id AS [@job_id], job.status AS [@status], job.task_no AS [@task_no],
job.tray_code AS [@tray_code], job.cargo_space_id AS [@source_space_id],
job.target_cargo_space_id AS [@target_space_id], job.in_or_out AS [@in_or_out],
job.create_time AS [@create_time], job.finish_time AS [@finish_time],
job.warehouse_id AS [@warehouse_id]
FROM dbo.mydo_job job WITH (NOLOCK)
WHERE job.warehouse_id = @warehouse_id
ORDER BY job.job_id
FOR XML PATH('job'), ROOT('jobs'), TYPE
)), '');
SET @source_payload = @source_payload + '|JOB_DETAIL|' + ISNULL(CONVERT(nvarchar(max), (
SELECT detail.job_detail_id AS [@job_detail_id], detail.job_id AS [@job_id],
detail.stock_id AS [@stock_id], detail.lot_no AS [@lot_no],
detail.in_date AS [@in_date], detail.in_or_out_id AS [@request_id],
detail.in_or_out_d_id AS [@request_detail_id], detail.product_id AS [@product_id],
detail.stock_status AS [@stock_status], detail.in_quantity AS [@in_quantity],
detail.stock_quantity AS [@stock_quantity], detail.out_quantity AS [@out_quantity],
detail.pick_quantity AS [@pick_quantity], detail.stockin_detail_id AS [@stockin_detail_id]
FROM dbo.mydo_job_detail detail WITH (NOLOCK)
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
WHERE job.warehouse_id = @warehouse_id
ORDER BY detail.job_detail_id
FOR XML PATH('job_detail'), ROOT('job_details'), TYPE
)), '');
SET @source_payload = @source_payload + '|INBOUND|' + ISNULL(CONVERT(nvarchar(max), (
SELECT inbound.stockin_detail_id AS [@stockin_detail_id], inbound.stockin_guid AS [@stockin_guid],
inbound.stockin_id AS [@stockin_id], inbound.lot_no AS [@lot_no],
inbound.product_id AS [@product_id], inbound.quantity AS [@quantity],
inbound.assign_num AS [@assign_num], inbound.spare4 AS [@project_no],
job.warehouse_id AS [@warehouse_id], stockin.warehouse_id AS [@source_warehouse_id],
job.task_no AS [@task_no],
job.tray_code AS [@tray_code], detail.job_id AS [@job_id],
detail.in_or_out_id AS [@request_id]
FROM dbo.in_stockin_detail inbound WITH (NOLOCK)
JOIN dbo.mydo_job_detail detail WITH (NOLOCK) ON detail.stockin_detail_id = inbound.stockin_detail_id
JOIN dbo.mydo_job job WITH (NOLOCK) ON job.job_id = detail.job_id
JOIN dbo.in_stockin stockin WITH (NOLOCK) ON stockin.stockin_id = inbound.stockin_id
WHERE (job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '')
AND (LTRIM(RTRIM(stockin.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockin.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockin.warehouse_id))) = @numeric_warehouse_id))
ORDER BY inbound.stockin_detail_id
FOR XML PATH('inbound'), ROOT('inbound_requests'), TYPE
)), '');
SET @source_payload = @source_payload + '|OUTBOUND|' + ISNULL(CONVERT(nvarchar(max), (
SELECT outbound.stockout_detail_id AS [@stockout_detail_id], outbound.warehouse_id AS [@warehouse_id],
stockout.warehouse_id AS [@source_warehouse_id],
warehouse.project_no AS [@project_no],
outbound.product_id AS [@product_id], outbound.lot_no AS [@lot_no],
outbound.quantity AS [@quantity], outbound.assign_num AS [@assign_num],
outbound.allot_quantity AS [@allot_quantity]
FROM dbo.out_stockout_detail outbound WITH (NOLOCK)
JOIN dbo.out_stockout stockout WITH (NOLOCK) ON stockout.stockout_id = outbound.stockout_id
LEFT JOIN dbo.bas_warehouse warehouse WITH (NOLOCK)
ON warehouse.warehouse_id = @warehouse_id
WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)
AND (LTRIM(RTRIM(stockout.warehouse_id)) = LTRIM(RTRIM(@warehouse_id))
OR (@numeric_warehouse_id IS NOT NULL
AND LTRIM(RTRIM(stockout.warehouse_id)) NOT LIKE '%[^0-9]%'
AND TRY_CONVERT(decimal(38,0), LTRIM(RTRIM(stockout.warehouse_id))) = @numeric_warehouse_id))
ORDER BY outbound.stockout_detail_id
FOR XML PATH('outbound'), ROOT('outbound_requests'), TYPE
)), '');
SET @post_source_signature = HASHBYTES('SHA2_256', CONVERT(varbinary(max), @source_payload));
IF @pre_source_count <> @post_source_count
OR @pre_source_signature <> @post_source_signature
THROW 51025, 'FT546 shadow refresh refused: source changed during refresh', 1;
MERGE alg.shadow_snapshot_state WITH (HOLDLOCK) AS target
USING (SELECT @warehouse_id AS warehouse_id) AS source
ON source.warehouse_id = target.warehouse_id
WHEN MATCHED THEN UPDATE SET
snapshot_generation = @snapshot_generation,
snapshot_status = 'PUBLISHED',
synchronized_at = SYSUTCDATETIME(),
source_signature = @post_source_signature,
source_row_count = @post_source_count,
instance_id = @instance_id,
last_error = NULL
WHEN NOT MATCHED THEN INSERT (
warehouse_id, snapshot_generation, snapshot_status, synchronized_at,
source_signature, source_row_count, instance_id, last_error)
VALUES (
@warehouse_id, @snapshot_generation, 'PUBLISHED', SYSUTCDATETIME(),
@post_source_signature, @post_source_count, @instance_id, NULL);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
THROW;
END CATCH;
END;
GO