diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql index afce064..b269df4 100644 --- a/fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/install-shadow.sql @@ -168,7 +168,7 @@ CREATE TABLE alg.decision_log ( decision_type varchar(40) NOT NULL, input_version binary(8) NULL, result_code varchar(80) NULL, - reason varchar(2000) NULL, + reason nvarchar(4000) NULL, created_at datetime2 NOT NULL CONSTRAINT DF_alg_decision_log_created_at DEFAULT SYSUTCDATETIME() ); GO @@ -942,8 +942,12 @@ BEGIN 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; @@ -963,12 +967,22 @@ BEGIN + (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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '') - + (SELECT COUNT_BIG(*) FROM dbo.out_stockout_detail outbound WITH (NOLOCK) - WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)); + + (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], @@ -1028,27 +1042,39 @@ BEGIN 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], job.task_no AS [@task_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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '' + 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], outbound.create_time AS [@create_time] 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 = outbound.warehouse_id + 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 )), ''); @@ -1111,7 +1137,12 @@ BEGIN 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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '' + 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, @@ -1130,9 +1161,14 @@ BEGIN 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 = outbound.warehouse_id - WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0); + 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; @@ -1150,12 +1186,22 @@ BEGIN + (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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '') - + (SELECT COUNT_BIG(*) FROM dbo.out_stockout_detail outbound WITH (NOLOCK) - WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)); + + (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], @@ -1211,26 +1257,38 @@ BEGIN 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], job.task_no AS [@task_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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '' + 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], outbound.create_time AS [@create_time] 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 = outbound.warehouse_id + 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 )), ''); diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql index 8dc1e12..852cea7 100644 --- a/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/upgrade-shadow-v2-to-v3.sql @@ -144,6 +144,8 @@ IF EXISTS ( BEGIN TRY BEGIN TRANSACTION; + ALTER TABLE alg.decision_log ALTER COLUMN reason nvarchar(4000) NULL; + ALTER TABLE alg.space_topology ADD snapshot_generation bigint NOT NULL CONSTRAINT DF_alg_space_topology_snapshot_generation DEFAULT 0 WITH VALUES; @@ -277,8 +279,12 @@ BEGIN 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; @@ -304,9 +310,19 @@ BEGIN 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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '') + 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) - WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)); + 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], @@ -363,27 +379,39 @@ BEGIN 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], job.task_no AS [@task_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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '' + 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], outbound.create_time AS [@create_time] 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 = outbound.warehouse_id + 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 )), ''); @@ -445,7 +473,12 @@ BEGIN 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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '' + 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, @@ -464,9 +497,14 @@ BEGIN 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 = outbound.warehouse_id - WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0); + 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; @@ -487,9 +525,19 @@ BEGIN + (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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '') + 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) - WHERE ISNULL(outbound.quantity, 0) > ISNULL(outbound.allot_quantity, 0)); + 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], @@ -544,25 +592,37 @@ BEGIN 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], job.task_no AS [@task_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 - WHERE job.finish_time IS NULL OR LTRIM(RTRIM(job.finish_time)) = '' + 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], outbound.create_time AS [@create_time] 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 = outbound.warehouse_id + 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 )), ''); diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java index 6a26d0f..9ecc6fc 100644 --- a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/ShadowSqlServerMigrationScriptTest.java @@ -218,15 +218,30 @@ class ShadowSqlServerMigrationScriptTest { assertThat(refresh).as(script).contains( "select @warehouse_id, isnull(task_no, ''), isnull(tray_code, ''), request_id, raw_warehouse_id", "select @warehouse_id, outbound.stockout_detail_id, outbound.warehouse_id", + "join dbo.in_stockin stockin with (nolock) on stockin.stockin_id = inbound.stockin_id", + "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", "nullif(ltrim(rtrim(warehouse.project_no)), '')", + "try_convert(decimal(38,0), ltrim(rtrim(stockin.warehouse_id))) = @numeric_warehouse_id", + "try_convert(decimal(38,0), ltrim(rtrim(stockout.warehouse_id))) = @numeric_warehouse_id", "job.finish_time is null or ltrim(rtrim(job.finish_time)) = ''", "isnull(outbound.quantity, 0) > isnull(outbound.allot_quantity, 0)"); assertThat(refresh).as(script).doesNotContain( - "select outbound.warehouse_id, outbound.stockout_detail_id, outbound.warehouse_id, null"); + "select outbound.warehouse_id, outbound.stockout_detail_id, outbound.warehouse_id, null", + "on warehouse.warehouse_id = outbound.warehouse_id"); } } + @Test + void decisionReasonStoresBoundedUnicodeDiagnosticsAcrossCleanInstallAndUpgrade() throws IOException { + String install = normalize(resource("db/sqlserver/install-shadow.sql")); + String upgrade = normalize(resource("db/sqlserver/upgrade-shadow-v2-to-v3.sql")); + + assertThat(install).contains("reason nvarchar(4000) null"); + assertThat(upgrade).contains("alter table alg.decision_log alter column reason nvarchar(4000) null"); + } + @Test void plannerViewsContainOnlyGenerationQualifiedAlgSnapshots() throws IOException { String install = normalize(resource("db/sqlserver/install-shadow.sql")); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngine.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngine.java index 7643006..671afbe 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngine.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngine.java @@ -21,7 +21,7 @@ import java.util.function.Supplier; @Component public class ShadowPlanningEngine { private static final int INSTANCE_STALE_SECONDS = 120; - private static final int DECISION_REASON_MAX_LENGTH = 2000; + private static final int DECISION_REASON_MAX_LENGTH = 4000; private static final String PUBLISHED = "PUBLISHED"; private final SchedulingFacade schedulingFacade; @@ -128,9 +128,9 @@ public class ShadowPlanningEngine { + "; request=" + observation.requestId() + "; shadow=" + observation.resultCode() + "; proposedSpace=" + nullSafe(observation.proposedSpaceId()) - + "; shadowReason=" + nullSafe(observation.reason()) + "; legacy=" + nullSafe(legacyResultCode) - + "; legacySpace=" + nullSafe(legacySpaceId), DECISION_REASON_MAX_LENGTH)); + + "; legacySpace=" + nullSafe(legacySpaceId) + + "; shadowReason=" + nullSafe(observation.reason()), DECISION_REASON_MAX_LENGTH)); requireComparisonInserted(inserted); }); } @@ -149,8 +149,8 @@ public class ShadowPlanningEngine { + "; shadow=" + observation.resultCode() + "; proposedStock=" + nullSafe(observation.proposedStockId()) + "; proposedSpace=" + nullSafe(observation.proposedSpaceId()) - + "; shadowReason=" + nullSafe(observation.reason()) - + "; legacy=" + nullSafe(legacyResultCode), DECISION_REASON_MAX_LENGTH)); + + "; legacy=" + nullSafe(legacyResultCode) + + "; shadowReason=" + nullSafe(observation.reason()), DECISION_REASON_MAX_LENGTH)); requireComparisonInserted(inserted); }); } diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngineTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngineTest.java index 975c4e5..7448128 100644 --- a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngineTest.java +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/shadow/ShadowPlanningEngineTest.java @@ -13,6 +13,7 @@ import com.ruoyi.algorithm.repository.VersionToken; import com.ruoyi.algorithm.service.InboundPlanningResult; import com.ruoyi.algorithm.shadow.mapper.ShadowInputMapper; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; @@ -207,20 +208,49 @@ class ShadowPlanningEngineTest { } @Test - void comparisonReasonIsBoundedToDecisionLogCapacity() { + void inboundComparisonRetainsRequiredEvidenceWhenUnicodeReasonIsOversized() { ShadowInputMapper mapper = mock(ShadowInputMapper.class); when(mapper.insertComparison(any(), any(), any(), any(Long.class), any(Instant.class), any(), any(), any())).thenReturn(1); ShadowPlanningEngine engine = engine(mock(SchedulingFacade.class), mapper); + String shadowDiagnostic = "snapshotGeneration=42; snapshotSync=2026-09-03T00:00:00Z" + + "; sourceSignature=ABC123; project=" + "中".repeat(255) + + "; shadowCandidates=17; reason=" + "长".repeat(5000); InboundShadowObservation observation = new InboundShadowObservation( true, 42L, "01", SNAPSHOT.synchronizedAt(), SNAPSHOT.sourceSignature(), - "JOB-1", "READY", "SPACE-9", "X".repeat(2500)); + "JOB-1", "READY", "SPACE-9", shadowDiagnostic); - engine.compareInbound(observation, "READY", "SPACE-9"); + engine.compareInbound(observation, "READY", "LEGACY-SPACE-9"); + ArgumentCaptor reason = ArgumentCaptor.forClass(String.class); verify(mapper).insertComparison(any(), any(), any(), any(Long.class), any(Instant.class), any(), any(), - argThat(reason -> reason.length() <= 2000)); + reason.capture()); + assertThat(reason.getValue()).hasSizeLessThanOrEqualTo(4000) + .contains("sourceSignature=ABC123", "shadowCandidates=17", + "legacy=READY", "legacySpace=LEGACY-SPACE-9"); + } + + @Test + void outboundComparisonRetainsLegacyOutcomeAndCandidateEvidenceWhenReasonIsOversized() { + ShadowInputMapper mapper = mock(ShadowInputMapper.class); + when(mapper.insertComparison(any(), any(), any(), any(Long.class), + any(Instant.class), any(), any(), any())).thenReturn(1); + ShadowPlanningEngine engine = engine(mock(SchedulingFacade.class), mapper); + String shadowDiagnostic = "snapshotGeneration=42; snapshotSync=2026-09-03T00:00:00Z" + + "; sourceSignature=ABC123; project=" + "中".repeat(255) + + "; shadowMatches=23; reason=" + "长".repeat(5000); + OutboundShadowObservation observation = new OutboundShadowObservation( + true, 42L, "01", SNAPSHOT.synchronizedAt(), SNAPSHOT.sourceSignature(), + "DETAIL-1", "READY", "STOCK-1", "SPACE-9", shadowDiagnostic); + + engine.compareOutbound(observation, "10"); + + ArgumentCaptor reason = ArgumentCaptor.forClass(String.class); + verify(mapper).insertComparison(any(), any(), any(), any(Long.class), + any(Instant.class), any(), any(), reason.capture()); + assertThat(reason.getValue()).hasSizeLessThanOrEqualTo(4000) + .contains("sourceSignature=ABC123", "shadowMatches=23", "legacy=10"); } @Test