IF COL_LENGTH('dbo.out_stockout_detail', 'status') IS NULL BEGIN ALTER TABLE dbo.out_stockout_detail ADD status nvarchar(10) NULL; END GO IF COL_LENGTH('dbo.out_stockout_detail_finish', 'status') IS NULL BEGIN ALTER TABLE dbo.out_stockout_detail_finish ADD status nvarchar(10) NULL; END GO IF COL_LENGTH('dbo.out_stockout_detail', 'stock_id') IS NULL BEGIN ALTER TABLE dbo.out_stockout_detail ADD stock_id nvarchar(80) NULL; END GO IF COL_LENGTH('dbo.out_stockout_detail_finish', 'stock_id') IS NULL BEGIN ALTER TABLE dbo.out_stockout_detail_finish ADD stock_id nvarchar(80) NULL; END GO IF COL_LENGTH('dbo.out_stockout_detail', 'stock_detail_id') IS NULL BEGIN ALTER TABLE dbo.out_stockout_detail ADD stock_detail_id nvarchar(80) NULL; END GO IF COL_LENGTH('dbo.out_stockout_detail_finish', 'stock_detail_id') IS NULL BEGIN ALTER TABLE dbo.out_stockout_detail_finish ADD stock_detail_id nvarchar(80) NULL; END GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_out_stockout_detail_stock_detail' AND object_id = OBJECT_ID(N'dbo.out_stockout_detail')) BEGIN CREATE INDEX IX_out_stockout_detail_stock_detail ON dbo.out_stockout_detail(stock_detail_id); END GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_mydo_job_detail_out_bill' AND object_id = OBJECT_ID(N'dbo.mydo_job_detail')) BEGIN CREATE INDEX IX_mydo_job_detail_out_bill ON dbo.mydo_job_detail(in_or_out_id, in_or_out_d_id); END GO IF OBJECT_ID(N'dbo.bas_stock_finish', N'U') IS NULL BEGIN CREATE TABLE dbo.bas_stock_finish ( stock_id nvarchar(32) NOT NULL, cargo_space_id nvarchar(80) NULL, stock_status nvarchar(2) NULL, product_status nvarchar(2) NULL, lot_no nvarchar(80) NULL, in_date datetime2(7) NULL, back_date datetime2(7) NULL, product_id nvarchar(80) NULL, product_name nvarchar(255) NULL, quantity decimal(18, 0) NULL, job_id nvarchar(80) NULL, job_detail_id nvarchar(255) NULL, tray_code nvarchar(225) NULL, out_quantity decimal(18, 0) NULL, stockin_detail_id nvarchar(80) NULL, stockin_id nvarchar(80) NULL, project_no nvarchar(80) NULL, in_type nvarchar(5) NULL, warehouse_id nvarchar(80) NULL, warehouse_name nvarchar(255) NULL, user_id int NULL, user_name nvarchar(255) NULL, dept_id int NULL, dept_name nvarchar(255) NULL, supplier_id nvarchar(255) NULL, supplier_name nvarchar(255) NULL, delete_time datetime2(7) NULL ); END GO IF COL_LENGTH('dbo.bas_stock_finish', 'delete_time') IS NULL BEGIN ALTER TABLE dbo.bas_stock_finish ADD delete_time datetime2(7) NULL; END GO IF COL_LENGTH('dbo.bas_stock_finish', 'project_no') IS NULL BEGIN ALTER TABLE dbo.bas_stock_finish ADD project_no nvarchar(80) NULL; END GO IF OBJECT_ID(N'dbo.bas_stock_detail_finish', N'U') IS NULL BEGIN CREATE TABLE dbo.bas_stock_detail_finish ( detail_id nvarchar(80) NOT NULL, stock_id nvarchar(32) NOT NULL, product_status nvarchar(2) NULL, lot_no nvarchar(80) NULL, product_id nvarchar(80) NULL, product_name nvarchar(255) NULL, quantity decimal(18, 0) NULL, out_quantity decimal(18, 0) NULL, job_detail_id nvarchar(255) NULL, stockin_detail_id nvarchar(80) NULL, project_no nvarchar(80) NULL, create_time datetime2(7) NULL, update_time datetime2(7) NULL, remark nvarchar(500) NULL, delete_time datetime2(7) NULL ); END GO IF COL_LENGTH('dbo.bas_stock_detail_finish', 'delete_time') IS NULL BEGIN ALTER TABLE dbo.bas_stock_detail_finish ADD delete_time datetime2(7) NULL; END GO IF COL_LENGTH('dbo.bas_stock_detail_finish', 'project_no') IS NULL BEGIN ALTER TABLE dbo.bas_stock_detail_finish ADD project_no nvarchar(80) NULL; END GO IF COL_LENGTH('dbo.bas_stock_detail_finish', 'detail_id') < 160 BEGIN ALTER TABLE dbo.bas_stock_detail_finish ALTER COLUMN detail_id nvarchar(80) NOT NULL; END GO IF OBJECT_ID(N'dbo.proc_update_outbill_status', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_update_outbill_status; GO CREATE PROCEDURE dbo.proc_update_outbill_status @v_stockout_id varchar(50), @v_status int, @v_result int OUTPUT, @v_resultString varchar(100) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @v_old_status int; DECLARE @now datetime2(7) = SYSDATETIME(); SELECT @v_old_status = TRY_CONVERT(int, status) FROM dbo.out_stockout WHERE stockout_id = @v_stockout_id; IF @v_old_status IS NULL BEGIN SET @v_result = 2; SET @v_resultString = '出库单据不存在'; RETURN; END BEGIN TRY BEGIN TRANSACTION; IF @v_status = 2 BEGIN IF @v_old_status <> 1 BEGIN SET @v_result = 2; SET @v_resultString = '只有创建状态可以审核'; ROLLBACK TRANSACTION; RETURN; END UPDATE dbo.out_stockout SET status = '2', review_dat = COALESCE(review_dat, @now) WHERE stockout_id = @v_stockout_id; END ELSE IF @v_status = 5 BEGIN IF @v_old_status >= 3 BEGIN SET @v_result = 2; SET @v_resultString = '单据已执行,不能直接作废'; ROLLBACK TRANSACTION; RETURN; END UPDATE dbo.out_stockout SET status = '5', finish_date = @now WHERE stockout_id = @v_stockout_id; INSERT INTO dbo.out_stockout_detail_finish SELECT * FROM dbo.out_stockout_detail WHERE stockout_id = @v_stockout_id; INSERT INTO dbo.out_stockout_finish SELECT * FROM dbo.out_stockout WHERE stockout_id = @v_stockout_id; DELETE FROM dbo.out_stockout_detail WHERE stockout_id = @v_stockout_id; DELETE FROM dbo.out_stockout WHERE stockout_id = @v_stockout_id; END ELSE IF @v_status = 4 BEGIN IF @v_old_status <> 3 BEGIN SET @v_result = 2; SET @v_resultString = '只有执行状态可以完成'; ROLLBACK TRANSACTION; RETURN; END IF EXISTS ( SELECT 1 FROM dbo.out_stockout_detail WHERE stockout_id = @v_stockout_id AND ISNULL(assign_num, 0) < ISNULL(quantity, 0) ) BEGIN SET @v_result = 2; SET @v_resultString = '出库明细未完成,不能完成单据'; ROLLBACK TRANSACTION; RETURN; END UPDATE dbo.out_stockout SET status = '4', finish_date = @now WHERE stockout_id = @v_stockout_id; INSERT INTO dbo.out_stockout_detail_finish SELECT * FROM dbo.out_stockout_detail WHERE stockout_id = @v_stockout_id; INSERT INTO dbo.out_stockout_finish SELECT * FROM dbo.out_stockout WHERE stockout_id = @v_stockout_id; DELETE FROM dbo.out_stockout_detail WHERE stockout_id = @v_stockout_id; DELETE FROM dbo.out_stockout WHERE stockout_id = @v_stockout_id; END ELSE BEGIN SET @v_result = 2; SET @v_resultString = '不支持的出库单据状态'; ROLLBACK TRANSACTION; RETURN; END COMMIT TRANSACTION; SET @v_result = 10; SET @v_resultString = '操作成功'; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; SET @v_result = 2; SET @v_resultString = LEFT(ERROR_MESSAGE(), 100); END CATCH END GO IF OBJECT_ID(N'dbo.proc_out_hand_allocation', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_out_hand_allocation; GO CREATE PROCEDURE dbo.proc_out_hand_allocation @v_stockout_detail_id varchar(80), @v_stock_id varchar(80), @v_exit_id varchar(80), @v_result int OUTPUT, @v_resultString varchar(100) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @stockout_id nvarchar(80), @stockout_status int, @warehouse_id nvarchar(80), @customer_id nvarchar(255), @customer_name nvarchar(255), @product_id nvarchar(255), @product_name nvarchar(255), @lot_no nvarchar(80), @locatio nvarchar(255), @preferred_stock_id nvarchar(80), @preferred_detail_id nvarchar(80), @bill_qty decimal(18, 0), @allot_qty decimal(18, 0), @remaining decimal(18, 0); DECLARE @detail_id nvarchar(80), @stock_id nvarchar(80), @available_qty decimal(18, 0), @alloc_qty decimal(18, 0), @job_id nvarchar(80), @job_type int, @task_no nvarchar(80), @job_detail_id nvarchar(80), @row_idx int, @tray_code nvarchar(255), @tray_type nvarchar(80), @cargo_space_id nvarchar(80), @cargo_space_name nvarchar(255), @roadway_id nvarchar(80), @stock_warehouse_id nvarchar(80), @stock_warehouse_name nvarchar(255), @supplier_id nvarchar(255), @supplier_name nvarchar(255), @project_no nvarchar(80), @exit_id nvarchar(80), @existing_job_id nvarchar(80), @now datetime = GETDATE(); SELECT TOP 1 @stockout_id = d.stockout_id, @product_id = d.product_id, @product_name = d.product_name, @lot_no = d.lot_no, @bill_qty = ISNULL(d.quantity, 0), @allot_qty = ISNULL(d.allot_num, 0), @locatio = NULLIF(d.locatio, ''), @preferred_stock_id = NULLIF(d.stock_id, ''), @preferred_detail_id = NULLIF(d.stock_detail_id, ''), @warehouse_id = o.warehouse_id, @customer_id = o.customer_id, @customer_name = o.customer_name, @stockout_status = TRY_CONVERT(int, o.status) FROM dbo.out_stockout_detail d WITH (UPDLOCK, HOLDLOCK) INNER JOIN dbo.out_stockout o ON d.stockout_id = o.stockout_id WHERE d.stockout_detail_id = @v_stockout_detail_id; IF @stockout_id IS NULL BEGIN SET @v_result = 2; SET @v_resultString = '出库子单不存在'; RETURN; END IF @stockout_status NOT IN (2, 3) BEGIN SET @v_result = 2; SET @v_resultString = '出库单据未审核'; RETURN; END IF @v_exit_id IS NULL OR LTRIM(RTRIM(@v_exit_id)) = '' BEGIN SET @v_result = 2; SET @v_resultString = '请选择出库口'; RETURN; END SET @remaining = @bill_qty - @allot_qty; IF @remaining <= 0 BEGIN SET @v_result = 10; SET @v_resultString = '出库子单已分配完成'; RETURN; END IF EXISTS (SELECT 1 FROM dbo.bas_stock_detail WHERE detail_id = @v_stock_id) BEGIN SET @preferred_detail_id = @v_stock_id; SET @preferred_stock_id = NULL; END ELSE IF EXISTS (SELECT 1 FROM dbo.bas_stock WHERE stock_id = @v_stock_id) BEGIN SET @preferred_stock_id = @v_stock_id; SET @preferred_detail_id = NULL; END BEGIN TRY BEGIN TRANSACTION; SELECT TOP 1 @detail_id = bsd.detail_id, @stock_id = bs.stock_id, @available_qty = ISNULL(bsd.quantity, 0) - ISNULL(bsd.out_quantity, 0), @tray_code = bs.tray_code, @cargo_space_id = bs.cargo_space_id, @cargo_space_name = bcs.cargo_space_name, @roadway_id = bcs.roadway_id, @stock_warehouse_id = bs.warehouse_id, @stock_warehouse_name = ISNULL(NULLIF(bs.warehouse_name, ''), bw.warehouse_name), @tray_type = bbf.tray_type, @supplier_id = bs.supplier_id, @supplier_name = bs.supplier_name, @project_no = bsd.project_no FROM dbo.bas_stock_detail bsd WITH (UPDLOCK, HOLDLOCK) INNER JOIN dbo.bas_stock bs WITH (UPDLOCK, HOLDLOCK) ON bsd.stock_id = bs.stock_id LEFT JOIN dbo.bas_cargo_space bcs WITH (UPDLOCK, HOLDLOCK) ON bs.cargo_space_id = bcs.cargo_space_id LEFT JOIN dbo.bas_warehouse bw ON bs.warehouse_id = bw.warehouse_id LEFT JOIN dbo.bas_cargo_area_config cac ON cac.warehouse_id = bs.warehouse_id AND cac.cargo_area_code = bcs.this_cargo_area AND cac.is_active = N'1' OUTER APPLY ( SELECT TOP 1 prefix AS tray_type FROM dbo.bas_barcode_format bbf WHERE bbf.prefix IS NOT NULL AND bbf.prefix != '' AND bs.tray_code IS NOT NULL AND LEFT(bs.tray_code, LEN(bbf.prefix)) = bbf.prefix ORDER BY LEN(bbf.prefix) DESC ) bbf OUTER APPLY ( SELECT MIN(area_space.the_column) AS area_min_column, MAX(area_space.the_column) AS area_max_column FROM dbo.bas_cargo_space area_space WHERE area_space.warehouse_id = bcs.warehouse_id AND area_space.this_cargo_area = bcs.this_cargo_area ) area_bounds WHERE bsd.product_id = @product_id AND (ISNULL(@lot_no, '') = '' OR ISNULL(bsd.lot_no, '') = ISNULL(@lot_no, '')) AND bs.stock_status = '1' AND bsd.product_status = '1' AND ISNULL(bsd.quantity, 0) - ISNULL(bsd.out_quantity, 0) > 0 AND ( bsd.job_detail_id IS NULL OR bsd.job_detail_id = '' OR NOT EXISTS ( SELECT 1 FROM dbo.mydo_job_detail lock_jd INNER JOIN dbo.mydo_job lock_j ON lock_j.job_id = lock_jd.job_id WHERE lock_jd.job_detail_id = bsd.job_detail_id AND lock_j.in_or_out >= 20 AND lock_j.status IN ('1', '2', '3') ) ) AND ( bcs.status = '2' OR EXISTS ( SELECT 1 FROM dbo.mydo_job ej INNER JOIN dbo.mydo_job_detail ejd ON ej.job_id = ejd.job_id WHERE ej.in_or_out >= 20 AND ej.status IN ('1', '2', '3') AND ej.cargo_space_id = bs.cargo_space_id AND ISNULL(ej.tray_code, '') = ISNULL(bs.tray_code, '') AND ISNULL(ej.exit_id, '') = ISNULL(@v_exit_id, '') AND ejd.in_or_out_id = @stockout_id AND ejd.stock_id = bs.stock_id ) ) AND (@warehouse_id IS NULL OR @warehouse_id = '' OR bs.warehouse_id = @warehouse_id) AND (@locatio IS NULL OR bs.cargo_space_id = @locatio OR bcs.cargo_space_name = @locatio) AND (@preferred_detail_id IS NULL OR bsd.detail_id = @preferred_detail_id) AND (@preferred_stock_id IS NULL OR bs.stock_id = @preferred_stock_id) ORDER BY CASE WHEN bsd.detail_id = @v_stock_id THEN 0 ELSE 1 END, CASE COALESCE(cac.direction_type, N'1') WHEN N'1' THEN bcs.the_column END ASC, CASE WHEN cac.direction_type = N'2' THEN bcs.the_column END DESC, CASE WHEN cac.direction_type = N'3' THEN CASE WHEN bcs.the_column - area_bounds.area_min_column <= area_bounds.area_max_column - bcs.the_column THEN bcs.the_column - area_bounds.area_min_column ELSE area_bounds.area_max_column - bcs.the_column END END ASC, CASE WHEN cac.direction_type = N'3' THEN bcs.the_column END ASC, bs.in_date ASC, bs.cargo_space_id ASC, bsd.detail_id ASC; IF @detail_id IS NULL BEGIN SET @v_result = 2; SET @v_resultString = '没有可分配库存明细'; ROLLBACK TRANSACTION; RETURN; END SET @alloc_qty = CASE WHEN @available_qty >= @remaining THEN @remaining ELSE @available_qty END; SET @job_type = CASE WHEN @alloc_qty < @available_qty THEN 21 ELSE 20 END; IF @alloc_qty <= 0 BEGIN SET @v_result = 2; SET @v_resultString = '库存可用数量不足'; ROLLBACK TRANSACTION; RETURN; END IF NOT EXISTS ( SELECT 1 FROM dbo.bas_station_point sp WHERE sp.point_id = @v_exit_id AND sp.warehouse_id = @stock_warehouse_id AND sp.point_type IN ('2', '3') AND sp.status = '0' AND ISNULL(sp.point_status, '0') = '0' ) BEGIN SET @v_result = 2; SET @v_resultString = '出库口不存在、禁用或已占用'; ROLLBACK TRANSACTION; RETURN; END IF @tray_type IS NOT NULL AND @tray_type != '' AND NOT EXISTS ( SELECT 1 FROM dbo.bas_station_point sp WHERE point_id = @v_exit_id AND warehouse_id = @stock_warehouse_id AND point_type IN ('2', '3') AND status = '0' AND ISNULL(point_status, '0') = '0' AND charindex(',' + @tray_type + ',', ',' + sp.tray_type + ',') > 0 ) BEGIN SET @v_result = 2; SET @v_resultString = '出库口不支持当前托盘类型'; ROLLBACK TRANSACTION; RETURN; END SET @exit_id = @v_exit_id; SELECT TOP 1 @existing_job_id = ej.job_id, @task_no = ej.task_no FROM dbo.mydo_job ej INNER JOIN dbo.mydo_job_detail ejd ON ej.job_id = ejd.job_id WHERE ej.in_or_out >= 20 AND ej.status IN ('1', '2', '3') AND ej.cargo_space_id = @cargo_space_id AND ISNULL(ej.tray_code, '') = ISNULL(@tray_code, '') AND ISNULL(ej.exit_id, '') = ISNULL(@exit_id, '') AND ejd.in_or_out_id = @stockout_id AND ejd.stock_id = @stock_id ORDER BY ej.create_time DESC, ej.job_id DESC; IF @existing_job_id IS NULL BEGIN EXEC dbo.util_serial_job 'CK', @job_id OUTPUT; EXEC dbo.util_serial_task '20', @task_no OUTPUT; INSERT INTO dbo.mydo_job ( job_id, status, task_no, in_or_out, execution_phase, tray_code, warehouse_id, warehouse_name, roadway_id, cargo_space_id, cargo_space_name, line_type, priority, height, weight, create_time, exit_id, customer_id, customer_name ) VALUES ( @job_id, '1', @task_no, @job_type, '4', @tray_code, @stock_warehouse_id, @stock_warehouse_name, @roadway_id, @cargo_space_id, @cargo_space_name, '1', 10, 0.00, 0.00, @now, @exit_id, @customer_id, @customer_name ); SET @row_idx = 1; END ELSE BEGIN SET @job_id = @existing_job_id; SELECT @row_idx = COUNT(1) + 1 FROM dbo.mydo_job_detail WHERE job_id = @job_id; END UPDATE dbo.mydo_job SET in_or_out = CASE WHEN @job_type = 21 THEN 21 ELSE in_or_out END WHERE job_id = @job_id; SET @job_detail_id = @job_id + '-' + CONVERT(nvarchar(10), @row_idx); INSERT INTO dbo.mydo_job_detail ( job_detail_id, job_id, stock_id, lot_no, in_date, in_or_out_id, in_or_out_d_id, product_id, product_name, stock_quantity, out_quantity, stockin_detail_id, customer_id, customer_name, supplier_id, supplier_name, project_no ) VALUES ( @job_detail_id, @job_id, @stock_id, @lot_no, CONVERT(varchar(19), @now, 120), @stockout_id, @v_stockout_detail_id, @product_id, @product_name, @available_qty, @alloc_qty, @detail_id, @customer_id, @customer_name, @supplier_id, @supplier_name, @project_no ); UPDATE dbo.bas_stock_detail SET out_quantity = ISNULL(out_quantity, 0) + @alloc_qty, job_detail_id = @job_detail_id, update_time = SYSDATETIME() WHERE detail_id = @detail_id; UPDATE bs SET quantity = ISNULL(bsa.quantity, 0), out_quantity = ISNULL(bsa.out_quantity, 0) FROM dbo.bas_stock bs INNER JOIN ( SELECT stock_id, SUM(ISNULL(quantity, 0)) AS quantity, SUM(ISNULL(out_quantity, 0)) AS out_quantity FROM dbo.bas_stock_detail WHERE stock_id = @stock_id GROUP BY stock_id ) bsa ON bsa.stock_id = bs.stock_id WHERE bs.stock_id = @stock_id; UPDATE dbo.bas_cargo_space SET status = '4', tray_code = @tray_code WHERE cargo_space_id = @cargo_space_id; UPDATE dbo.out_stockout_detail SET allot_num = ISNULL(allot_num, 0) + @alloc_qty, status = CASE WHEN ISNULL(allot_num, 0) + @alloc_qty >= ISNULL(quantity, 0) THEN '1' ELSE '0' END, stock_id = COALESCE(NULLIF(stock_id, ''), @stock_id), stock_detail_id = COALESCE(NULLIF(stock_detail_id, ''), @detail_id) WHERE stockout_detail_id = @v_stockout_detail_id; UPDATE dbo.out_stockout SET status = '3', start_date = COALESCE(start_date, SYSDATETIME()) WHERE stockout_id = @stockout_id; COMMIT TRANSACTION; SET @v_result = 10; SET @v_resultString = '成功:生成出库作业' + @job_id; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; SET @v_result = 2; SET @v_resultString = LEFT(ERROR_MESSAGE(), 100); END CATCH END GO IF OBJECT_ID(N'dbo.proc_out_auto_allocation', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_out_auto_allocation; GO CREATE PROCEDURE dbo.proc_out_auto_allocation @v_stockout_detail_id varchar(80), @v_exit_id varchar(80), @v_result int OUTPUT, @v_resultString varchar(100) OUTPUT AS BEGIN SET NOCOUNT ON; DECLARE @stockout_id nvarchar(80), @warehouse_id nvarchar(80), @product_id nvarchar(255), @lot_no nvarchar(80), @locatio nvarchar(255), @preferred_stock_id nvarchar(80), @preferred_detail_id nvarchar(80), @remaining decimal(18, 0), @detail_id nvarchar(80), @child_result int, @child_msg varchar(100), @last_error varchar(100); SELECT TOP 1 @stockout_id = d.stockout_id, @warehouse_id = o.warehouse_id, @product_id = d.product_id, @lot_no = d.lot_no, @locatio = NULLIF(d.locatio, ''), @preferred_stock_id = NULLIF(d.stock_id, ''), @preferred_detail_id = NULLIF(d.stock_detail_id, '') FROM dbo.out_stockout_detail d INNER JOIN dbo.out_stockout o ON d.stockout_id = o.stockout_id WHERE d.stockout_detail_id = @v_stockout_detail_id; IF @stockout_id IS NULL BEGIN SET @v_result = 2; SET @v_resultString = '出库子单不存在'; RETURN; END DECLARE cur_auto_stock CURSOR LOCAL FAST_FORWARD FOR SELECT bsd.detail_id FROM dbo.bas_stock_detail bsd INNER JOIN dbo.bas_stock bs ON bsd.stock_id = bs.stock_id LEFT JOIN dbo.bas_cargo_space bcs ON bs.cargo_space_id = bcs.cargo_space_id LEFT JOIN dbo.bas_cargo_area_config cac ON cac.warehouse_id = bs.warehouse_id AND cac.cargo_area_code = bcs.this_cargo_area AND cac.is_active = N'1' OUTER APPLY ( SELECT MIN(area_space.the_column) AS area_min_column, MAX(area_space.the_column) AS area_max_column FROM dbo.bas_cargo_space area_space WHERE area_space.warehouse_id = bcs.warehouse_id AND area_space.this_cargo_area = bcs.this_cargo_area ) area_bounds WHERE bsd.product_id = @product_id AND (ISNULL(@lot_no, '') = '' OR ISNULL(bsd.lot_no, '') = ISNULL(@lot_no, '')) AND bs.stock_status = '1' AND bsd.product_status = '1' AND ISNULL(bsd.quantity, 0) - ISNULL(bsd.out_quantity, 0) > 0 AND ( bsd.job_detail_id IS NULL OR bsd.job_detail_id = '' OR NOT EXISTS ( SELECT 1 FROM dbo.mydo_job_detail lock_jd INNER JOIN dbo.mydo_job lock_j ON lock_j.job_id = lock_jd.job_id WHERE lock_jd.job_detail_id = bsd.job_detail_id AND lock_j.in_or_out >= 20 AND lock_j.status IN ('1', '2', '3') ) ) AND ( bcs.status = '2' OR EXISTS ( SELECT 1 FROM dbo.mydo_job ej INNER JOIN dbo.mydo_job_detail ejd ON ej.job_id = ejd.job_id WHERE ej.in_or_out >= 20 AND ej.status IN ('1', '2', '3') AND ej.cargo_space_id = bs.cargo_space_id AND ISNULL(ej.tray_code, '') = ISNULL(bs.tray_code, '') AND ISNULL(ej.exit_id, '') = ISNULL(@v_exit_id, '') AND ejd.in_or_out_id = @stockout_id AND ejd.stock_id = bs.stock_id ) ) AND (@warehouse_id IS NULL OR @warehouse_id = '' OR bs.warehouse_id = @warehouse_id) AND (@locatio IS NULL OR bs.cargo_space_id = @locatio OR bcs.cargo_space_name = @locatio) AND (@preferred_stock_id IS NULL OR bs.stock_id = @preferred_stock_id) AND (@preferred_detail_id IS NULL OR bsd.detail_id = @preferred_detail_id) ORDER BY CASE COALESCE(cac.direction_type, N'1') WHEN N'1' THEN bcs.the_column END ASC, CASE WHEN cac.direction_type = N'2' THEN bcs.the_column END DESC, CASE WHEN cac.direction_type = N'3' THEN CASE WHEN bcs.the_column - area_bounds.area_min_column <= area_bounds.area_max_column - bcs.the_column THEN bcs.the_column - area_bounds.area_min_column ELSE area_bounds.area_max_column - bcs.the_column END END ASC, CASE WHEN cac.direction_type = N'3' THEN bcs.the_column END ASC, bs.in_date ASC, bs.cargo_space_id ASC, bsd.detail_id ASC; OPEN cur_auto_stock; FETCH NEXT FROM cur_auto_stock INTO @detail_id; WHILE @@FETCH_STATUS = 0 BEGIN SELECT @remaining = ISNULL(quantity, 0) - ISNULL(allot_num, 0) FROM dbo.out_stockout_detail WHERE stockout_detail_id = @v_stockout_detail_id; IF @remaining <= 0 BREAK; EXEC dbo.proc_out_hand_allocation @v_stockout_detail_id = @v_stockout_detail_id, @v_stock_id = @detail_id, @v_exit_id = @v_exit_id, @v_result = @child_result OUTPUT, @v_resultString = @child_msg OUTPUT; IF @child_result <> 10 SET @last_error = @child_msg; FETCH NEXT FROM cur_auto_stock INTO @detail_id; END CLOSE cur_auto_stock; DEALLOCATE cur_auto_stock; SELECT @remaining = ISNULL(quantity, 0) - ISNULL(allot_num, 0) FROM dbo.out_stockout_detail WHERE stockout_detail_id = @v_stockout_detail_id; IF @remaining <= 0 BEGIN SET @v_result = 10; SET @v_resultString = '自动分配完成'; END ELSE BEGIN SET @v_result = 2; SET @v_resultString = COALESCE(@last_error, '自动分配库存不足'); END END GO IF OBJECT_ID(N'dbo.proc_out_makesure', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_out_makesure; GO CREATE PROCEDURE dbo.proc_out_makesure @v_job_id varchar(80), @v_dept_id int, @v_user_id int, @v_result int OUTPUT, @v_resultmsg varchar(500) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @now datetime = GETDATE(), @stockout_id nvarchar(80), @job_detail_id nvarchar(80), @stock_id nvarchar(80), @stock_detail_id nvarchar(80), @stockout_detail_id nvarchar(80), @out_qty decimal(18, 0), @cargo_space_id nvarchar(80), @tray_code nvarchar(255); DECLARE @affected_stock TABLE(stock_id nvarchar(80) PRIMARY KEY); IF NOT EXISTS (SELECT 1 FROM dbo.mydo_job WHERE job_id = @v_job_id AND in_or_out >= 20) BEGIN SET @v_result = 2; SET @v_resultmsg = '未找到对应出库作业'; RETURN; END IF NOT EXISTS (SELECT 1 FROM dbo.mydo_job_detail WHERE job_id = @v_job_id) BEGIN SET @v_result = 2; SET @v_resultmsg = '出库作业无明细'; RETURN; END BEGIN TRY DECLARE cur_out_job_detail CURSOR LOCAL FAST_FORWARD FOR SELECT job_detail_id, stock_id, stockin_detail_id, in_or_out_id, in_or_out_d_id, ISNULL(out_quantity, 0) FROM dbo.mydo_job_detail WHERE job_id = @v_job_id; BEGIN TRANSACTION; OPEN cur_out_job_detail; FETCH NEXT FROM cur_out_job_detail INTO @job_detail_id, @stock_id, @stock_detail_id, @stockout_id, @stockout_detail_id, @out_qty; WHILE @@FETCH_STATUS = 0 BEGIN IF @out_qty <= 0 BEGIN SET @v_result = 2; SET @v_resultmsg = '出库作业数量异常'; ROLLBACK TRANSACTION; RETURN; END IF @stock_detail_id IS NULL OR @stock_detail_id = '' BEGIN SELECT TOP 1 @stock_detail_id = detail_id FROM dbo.bas_stock_detail WHERE job_detail_id = @job_detail_id; END IF NOT EXISTS ( SELECT 1 FROM dbo.bas_stock_detail WITH (UPDLOCK, HOLDLOCK) WHERE detail_id = @stock_detail_id AND stock_id = @stock_id AND ISNULL(quantity, 0) >= @out_qty ) BEGIN SET @v_result = 2; SET @v_resultmsg = '库存不足或库存明细不存在'; ROLLBACK TRANSACTION; RETURN; END UPDATE dbo.out_stockout_detail SET assign_num = ISNULL(assign_num, 0) + @out_qty, actual_qt = ISNULL(assign_num, 0) + @out_qty, status = CASE WHEN ISNULL(assign_num, 0) + @out_qty >= ISNULL(quantity, 0) THEN '2' ELSE status END WHERE stockout_detail_id = @stockout_detail_id; UPDATE dbo.bas_stock_detail SET quantity = ISNULL(quantity, 0) - @out_qty, out_quantity = CASE WHEN ISNULL(out_quantity, 0) - @out_qty < 0 THEN 0 ELSE ISNULL(out_quantity, 0) - @out_qty END, job_detail_id = CASE WHEN job_detail_id = @job_detail_id THEN NULL ELSE job_detail_id END, update_time = SYSDATETIME() WHERE detail_id = @stock_detail_id AND stock_id = @stock_id; INSERT INTO dbo.bas_stock_detail_finish ( detail_id, stock_id, product_status, lot_no, product_id, product_name, quantity, out_quantity, job_detail_id, stockin_detail_id, project_no, create_time, update_time, remark, delete_time ) SELECT detail_id, stock_id, product_status, lot_no, product_id, product_name, quantity, out_quantity, job_detail_id, stockin_detail_id, project_no, create_time, update_time, remark, SYSDATETIME() AS delete_time FROM dbo.bas_stock_detail WHERE detail_id = @stock_detail_id AND stock_id = @stock_id AND ISNULL(quantity, 0) <= 0; DELETE FROM dbo.bas_stock_detail WHERE detail_id = @stock_detail_id AND ISNULL(quantity, 0) <= 0; IF NOT EXISTS (SELECT 1 FROM @affected_stock WHERE stock_id = @stock_id) INSERT INTO @affected_stock(stock_id) VALUES (@stock_id); FETCH NEXT FROM cur_out_job_detail INTO @job_detail_id, @stock_id, @stock_detail_id, @stockout_id, @stockout_detail_id, @out_qty; END CLOSE cur_out_job_detail; DEALLOCATE cur_out_job_detail; DECLARE cur_stock CURSOR LOCAL FAST_FORWARD FOR SELECT stock_id FROM @affected_stock; OPEN cur_stock; FETCH NEXT FROM cur_stock INTO @stock_id; WHILE @@FETCH_STATUS = 0 BEGIN SELECT @cargo_space_id = cargo_space_id, @tray_code = tray_code FROM dbo.bas_stock WHERE stock_id = @stock_id; IF EXISTS (SELECT 1 FROM dbo.bas_stock_detail WHERE stock_id = @stock_id) BEGIN UPDATE bs SET bs.quantity = ISNULL(bsa.quantity, 0), bs.out_quantity = ISNULL(bsa.out_quantity, 0), bs.product_status = NULL, bs.lot_no = NULL, bs.product_id = NULL, bs.product_name = NULL, bs.job_detail_id = NULL, bs.stockin_detail_id = NULL FROM dbo.bas_stock bs INNER JOIN ( SELECT stock_id, SUM(ISNULL(quantity, 0)) AS quantity, SUM(ISNULL(out_quantity, 0)) AS out_quantity FROM dbo.bas_stock_detail WHERE stock_id = @stock_id GROUP BY stock_id ) bsa ON bsa.stock_id = bs.stock_id WHERE bs.stock_id = @stock_id; END ELSE BEGIN INSERT INTO dbo.bas_stock_finish ( stock_id, cargo_space_id, stock_status, product_status, lot_no, in_date, back_date, product_id, product_name, quantity, job_id, job_detail_id, tray_code, out_quantity, stockin_detail_id, stockin_id, project_no, in_type, warehouse_id, warehouse_name, user_id, user_name, dept_id, dept_name, supplier_id, supplier_name, delete_time ) SELECT stock_id, cargo_space_id, stock_status, product_status, lot_no, in_date, back_date, product_id, product_name, quantity, job_id, job_detail_id, tray_code, out_quantity, stockin_detail_id, stockin_id, project_no, in_type, warehouse_id, warehouse_name, user_id, user_name, dept_id, dept_name, supplier_id, supplier_name, SYSDATETIME() AS delete_time FROM dbo.bas_stock WHERE stock_id = @stock_id; DELETE FROM dbo.bas_stock WHERE stock_id = @stock_id; END FETCH NEXT FROM cur_stock INTO @stock_id; END CLOSE cur_stock; DEALLOCATE cur_stock; UPDATE dbo.mydo_job SET status = '4', finish_time = @now WHERE job_id = @v_job_id; INSERT INTO dbo.mydo_job_finish SELECT * FROM dbo.mydo_job WHERE job_id = @v_job_id; INSERT INTO dbo.mydo_job_detail_finish SELECT * FROM dbo.mydo_job_detail WHERE job_id = @v_job_id; DELETE FROM dbo.mydo_job_detail WHERE job_id = @v_job_id; DELETE FROM dbo.mydo_job WHERE job_id = @v_job_id; IF @stockout_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM dbo.out_stockout_detail WHERE stockout_id = @stockout_id AND ISNULL(assign_num, 0) < ISNULL(quantity, 0) ) BEGIN UPDATE dbo.out_stockout SET status = '4', finish_date = SYSDATETIME() WHERE stockout_id = @stockout_id; INSERT INTO dbo.out_stockout_detail_finish SELECT * FROM dbo.out_stockout_detail WHERE stockout_id = @stockout_id; INSERT INTO dbo.out_stockout_finish SELECT * FROM dbo.out_stockout WHERE stockout_id = @stockout_id; DELETE FROM dbo.out_stockout_detail WHERE stockout_id = @stockout_id; DELETE FROM dbo.out_stockout WHERE stockout_id = @stockout_id; END COMMIT TRANSACTION; SET @v_result = 10; SET @v_resultmsg = '出库作业完成'; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; IF CURSOR_STATUS('local','cur_out_job_detail') >= 0 BEGIN CLOSE cur_out_job_detail; DEALLOCATE cur_out_job_detail; END IF CURSOR_STATUS('local','cur_stock') >= 0 BEGIN CLOSE cur_stock; DEALLOCATE cur_stock; END SET @v_result = 2; SET @v_resultmsg = ERROR_MESSAGE(); END CATCH END GO IF OBJECT_ID(N'dbo.proc_hand_delete_out_job', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_hand_delete_out_job; GO CREATE PROCEDURE dbo.proc_hand_delete_out_job @v_job_id varchar(80), @v_result int OUTPUT, @v_resultmsg varchar(500) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @stockout_id nvarchar(80), @job_detail_id nvarchar(80), @stock_id nvarchar(80), @stock_detail_id nvarchar(80), @stockout_detail_id nvarchar(80), @out_qty decimal(18, 0), @cargo_space_id nvarchar(80), @tray_code nvarchar(255); DECLARE @affected_stock TABLE(stock_id nvarchar(80) PRIMARY KEY); IF NOT EXISTS (SELECT 1 FROM dbo.mydo_job WHERE job_id = @v_job_id AND in_or_out >= 20) BEGIN SET @v_result = 2; SET @v_resultmsg = '未找到对应出库作业'; RETURN; END BEGIN TRY DECLARE cur_cancel_out CURSOR LOCAL FAST_FORWARD FOR SELECT job_detail_id, stock_id, stockin_detail_id, in_or_out_id, in_or_out_d_id, ISNULL(out_quantity, 0) FROM dbo.mydo_job_detail WHERE job_id = @v_job_id; BEGIN TRANSACTION; OPEN cur_cancel_out; FETCH NEXT FROM cur_cancel_out INTO @job_detail_id, @stock_id, @stock_detail_id, @stockout_id, @stockout_detail_id, @out_qty; WHILE @@FETCH_STATUS = 0 BEGIN UPDATE dbo.bas_stock_detail SET out_quantity = CASE WHEN ISNULL(out_quantity, 0) - @out_qty < 0 THEN 0 ELSE ISNULL(out_quantity, 0) - @out_qty END, job_detail_id = CASE WHEN job_detail_id = @job_detail_id THEN NULL ELSE job_detail_id END, update_time = SYSDATETIME() WHERE detail_id = @stock_detail_id OR job_detail_id = @job_detail_id; UPDATE dbo.out_stockout_detail SET allot_num = CASE WHEN ISNULL(allot_num, 0) - @out_qty < 0 THEN 0 ELSE ISNULL(allot_num, 0) - @out_qty END, status = CASE WHEN ISNULL(allot_num, 0) - @out_qty <= 0 THEN '0' ELSE status END WHERE stockout_detail_id = @stockout_detail_id; IF NOT EXISTS (SELECT 1 FROM @affected_stock WHERE stock_id = @stock_id) INSERT INTO @affected_stock(stock_id) VALUES (@stock_id); FETCH NEXT FROM cur_cancel_out INTO @job_detail_id, @stock_id, @stock_detail_id, @stockout_id, @stockout_detail_id, @out_qty; END CLOSE cur_cancel_out; DEALLOCATE cur_cancel_out; DECLARE cur_cancel_stock CURSOR LOCAL FAST_FORWARD FOR SELECT stock_id FROM @affected_stock; OPEN cur_cancel_stock; FETCH NEXT FROM cur_cancel_stock INTO @stock_id; WHILE @@FETCH_STATUS = 0 BEGIN SELECT @cargo_space_id = cargo_space_id, @tray_code = tray_code FROM dbo.bas_stock WHERE stock_id = @stock_id; UPDATE bs SET quantity = ISNULL(bsa.quantity, 0), out_quantity = ISNULL(bsa.out_quantity, 0) FROM dbo.bas_stock bs INNER JOIN ( SELECT stock_id, SUM(ISNULL(quantity, 0)) AS quantity, SUM(ISNULL(out_quantity, 0)) AS out_quantity FROM dbo.bas_stock_detail WHERE stock_id = @stock_id GROUP BY stock_id ) bsa ON bsa.stock_id = bs.stock_id WHERE bs.stock_id = @stock_id; UPDATE dbo.bas_cargo_space SET status = '2', tray_code = @tray_code WHERE cargo_space_id = @cargo_space_id AND EXISTS (SELECT 1 FROM dbo.bas_stock WHERE stock_id = @stock_id); FETCH NEXT FROM cur_cancel_stock INTO @stock_id; END CLOSE cur_cancel_stock; DEALLOCATE cur_cancel_stock; DELETE FROM dbo.mydo_job_detail WHERE job_id = @v_job_id; DELETE FROM dbo.mydo_job WHERE job_id = @v_job_id; IF @stockout_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM dbo.mydo_job_detail WHERE in_or_out_id = @stockout_id ) BEGIN UPDATE dbo.out_stockout SET status = '2', start_date = NULL WHERE stockout_id = @stockout_id AND status = '3'; END COMMIT TRANSACTION; SET @v_result = 10; SET @v_resultmsg = '出库作业已作废'; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; IF CURSOR_STATUS('local','cur_cancel_out') >= 0 BEGIN CLOSE cur_cancel_out; DEALLOCATE cur_cancel_out; END IF CURSOR_STATUS('local','cur_cancel_stock') >= 0 BEGIN CLOSE cur_cancel_stock; DEALLOCATE cur_cancel_stock; END SET @v_result = 2; SET @v_resultmsg = ERROR_MESSAGE(); END CATCH END GO