WMS核心分配是件拣货位先进先出,系统在分配之前预留一个客户自定的方法,我们进行干预,实现全仓先进先出。
具体实现如下:
1、核心分配主逻辑:SPSO_HardAllocation_Process
---------------------------------------------------------------------------------------------------
--v372 增加一个可以让实施顾问自己定义逻辑的处理过程
---------------------------------------------------------------------------------------------------
/* v372 */ Set @Return_Code='*_*'
/* v372 */ Declare @Param4 Varchar(200)
/* V408 */ Declare @Param2 varchar(40)
/* V408 */ if @Process_By = 'By WaveNO'
/* V408 */ set @Param2 = @WaveNO
/* V408 */ else
/* V408 */ set @Param2 = @OrderNo
/* v372 */ Set @Param4=@Process_By+'%'+@WaveNO+'%'+@OrderNo+'%'+Cast(@OrderLineNo as char(4))
/* v372 *//* V408 */ Exec SPUDF_ProcessA @WareHouseID_R, 'ALLOCATION_BEFORE'/*V431*/,@Param2,''/*V431*/,@Param4,@Language,@UserID,@Return_Code Output
/* v372 */ if substring(@Return_Code,1,3)<>'000'
/* v372 */ begin
/* v372 */ If @Trans_Control='Y' select @Return_Code
/* v372 */ goto ErrorReturn
/* v372 */ end
----------------------------------------------------------------------------------
2、客户自定义存储过程:SPUDF_ProcessA
----分配前判断是否已过出库效期
if(@Parameter1 = 'ALLOCATION_BEFORE')
begin
if exists (select 1 from DOC_Order_Details(nolock) d
left join Bas_sku(nolock) u on d.CustomerID = u.CustomerID and d.SKU = u.SKU
where 1 = 1
and d.OrderNo = @Parameter2
and d.LineStatus < 40
)
begin
EXEC SPUDF_AllocationAvlDate4 @WarehouseID_R,@Parameter2,@Return_Code output
if substring(@Return_Code,1,3)<>'000'
begin
set @Return_Code = '999#指定效期最小批次错误'
select @Return_Code
return
end
end
end
3、我们进行干预的存储过程:SPUDF_AllocationAvlDate4
USE [wmsa]
GO
/****** Object: Table [dbo].[temp_min_lot_INV_LOT_LOC_ID] Script Date: 08/30/2018 10:09:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[temp_min_lot_INV_LOT_LOC_ID](
[WarehouseID] [varchar](30) NULL,
[CustomerID] [varchar](30) NOT NULL,
[SKU] [varchar](50) NOT NULL,
[LotAtt02] [varchar](20) NULL,
[LotAtt03] [varchar](20) NULL,
[lotnum] [char](10) NOT NULL,
[RotationID] [varchar](10) NULL,
[locationid] [varchar](20) NOT NULL,
[LocationUsage] [char](2) NULL,
[LocationAttribute] [char](2) NULL,
[QtyAvailed] [numeric](22, 0) NULL,
[Addtime] [datetime] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [wmsa]
GO
/****** Object: StoredProcedure [dbo].[SPUDF_AllocationAvlDate4] Script Date: 09/04/2018 15:47:50 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER proc [dbo].[SPUDF_AllocationAvlDate4]
@WarehouseID varchar(30),
@OrderNO varchar(30),
@return_code varchar(100) output
as
set @return_code = '000'
begin try
declare @CustomerID varchar(20),@SKU varchar(50) ,@LotAtt02 varchar(20),@LotAtt03 varchar(20),@LotAtt08 varchar(20)
,@LotID varchar(20),@RotationID varchar(20),@LotNum varchar(20),@oper_flag varchar(2) = 'Y',@lotCount int = 0
select @WarehouseID = WarehouseID from DOC_Order_Header(nolock) where Orderno = @OrderNO
--N:拣货区先进先出控制 Y:全仓库先进先出控制
--select @oper_flag = Value_String from SYS_Configuration where Config_ID = 'CUS_XQCONTROL'
--20180904 YANGXUN 增加按客户指定批次分配逻辑
declare @DetailsEditWho varchar(20),@EditLotNum varchar(20)
declare Cur_OrderNOList cursor
for
select d.CustomerID,d.SKU,d.LotAtt02,d.LotAtt03,d.LotAtt08,u.LotID,u.RotationID
from DOC_Order_Details(nolock) d
left join doc_order_header(nolock) h on d.orderno = h.orderno
left join Bas_sku(nolock) u on d.CustomerID = u.CustomerID and d.SKU = u.SKU
where 1 = 1
and h.ordertime between dateadd(d,-30,getdate()) and getdate()
and h.sostatus < 40
--and u.LotID = 'FOOD'
--and u.RotationID = 'FOOD'
and d.OrderNo = @OrderNO
--and d.OrderNo = 'SO150705003454'
and d.LineStatus < 40
open Cur_OrderNOList
Fetch Next From Cur_OrderNOList Into @CustomerID,@SKU,@LotAtt02,@LotAtt03,@LotAtt08,@LotID,@RotationID
While @@FETCH_STATUS=0
Begin
/*
drop table temp_min_lot_INV_LOT_LOC_ID
select k.WarehouseID,k.CustomerID,k.SKU,k.LotAtt02,k.LotAtt03,k.lotnum,u.RotationID,k.locationid,l.LocationUsage,l.LocationAttribute,k.QtyAvailed
into temp_min_lot_INV_LOT_LOC_ID
from V_SelectINV_LOT_LOC_ID(nolock) k
left join BAS_SKU(nolock) u on k.CustomerID = u.CustomerID and k.SKU = u.SKU
left join bas_location(nolock) l on k.locationid = l.locationid
where 1 = 1
and k.WarehouseID = @WarehouseID
and k.CustomerID = @CustomerID
and k.SKU = @SKU
and k.LotAtt08 = @LotAtt08
--and DATEDIFF(D,GETDATE(),k.LotAtt02) > u.OutboundLifeDays --取产品档案失效日期预警天数
and DATEDIFF(D,GETDATE(),k.LotAtt02) > case isnull(u.OutboundLifeDays,0) when 0 then 60 else u.OutboundLifeDays end --2016.06.12 黄久洲修改,默认效期低于60天不能出库
and QtyAvailed > 0
and k.LocationID not like 'STAGE%'
and k.LocationID not like 'SORTATION%'
and k.LocationID not like 'LOST%'
and k.LocationID not like 'DYNAMIC%'
and l.LocationAttribute in('OK')
*/
--2180424 YANGXUN 改成delete 避免drop表不存在报错 后续涉及所有 temp_min_lot_INV_LOT_LOC_ID 都要加上仓库、客户、SKU
delete from temp_min_lot_INV_LOT_LOC_ID
where WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
--20180522 YANGXUN 分成食品批次属性和标准批次属性插入,标准属性不考虑效期低于60天预警情况
if(isnull(@LotID,'') = 'FOOD')
begin
insert into temp_min_lot_INV_LOT_LOC_ID
select k.WarehouseID,k.CustomerID,k.SKU,k.LotAtt02,k.LotAtt03,k.lotnum,u.RotationID,
k.locationid,l.LocationUsage,l.LocationAttribute,k.QtyAvailed,getdate()
from V_SelectINV_LOT_LOC_ID(nolock) k
left join BAS_SKU(nolock) u on k.CustomerID = u.CustomerID and k.SKU = u.SKU
left join bas_location(nolock) l on k.locationid = l.locationid
where 1 = 1
and k.WarehouseID = @WarehouseID
and k.CustomerID = @CustomerID
and k.SKU = @SKU
and k.LotAtt08 = @LotAtt08
--and DATEDIFF(D,GETDATE(),k.LotAtt02) > u.OutboundLifeDays --取产品档案失效日期预警天数
and DATEDIFF(D,GETDATE(),k.LotAtt02) > case isnull(u.OutboundLifeDays,0) when 0 then 60 else u.OutboundLifeDays end --2016.06.12 黄久洲修改,默认效期低于60天不能出库
and QtyAvailed > 0
and k.LocationID not like 'STAGE%'
and k.LocationID not like 'SORTATION%'
and k.LocationID not like '%LOST%'
and k.LocationID not like 'DYNAMIC%'
and l.LocationAttribute in('OK')
end
else if(isnull(@LotID,'') = 'STANDARD')
begin
insert into temp_min_lot_INV_LOT_LOC_ID
select k.WarehouseID,k.CustomerID,k.SKU,k.LotAtt02,k.LotAtt03,k.lotnum,u.RotationID,
k.locationid,l.LocationUsage,l.LocationAttribute,k.QtyAvailed,getdate()
from V_SelectINV_LOT_LOC_ID(nolock) k
left join BAS_SKU(nolock) u on k.CustomerID = u.CustomerID and k.SKU = u.SKU
left join bas_location(nolock) l on k.locationid = l.locationid
where 1 = 1
and k.WarehouseID = @WarehouseID
and k.CustomerID = @CustomerID
and k.SKU = @SKU
and k.LotAtt08 = @LotAtt08
and QtyAvailed > 0
and k.LocationID not like 'STAGE%'
and k.LocationID not like 'SORTATION%'
and k.LocationID not like '%LOST%'
and k.LocationID not like 'DYNAMIC%'
and l.LocationAttribute in('OK')
end
if(isnull(@LotID,'') = 'FOOD')
begin
set @LotAtt02 = '9999-12-31'
set @RotationID = 'FOOD' --2016.06.12 黄久洲修改
update d
set d.LotAtt02 = @LotAtt02,RotationID = @RotationID,d.D_EDI_20= '按食品批次分配1'
from Doc_order_Details(nolock) d
where 1 = 1
and d.OrderNo = @OrderNO
and d.CustomerID = @CustomerID
and d.SKU = @SKU
and d.LineStatus < 40
select @LotAtt02 = LotAtt02,@lotCount = COUNT(LotAtt02)
from temp_min_lot_INV_LOT_LOC_ID
where WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU --20180625 YANGXUN 剔除干扰库存
group by WarehouseID,CustomerID,SKU,LotAtt02
having LotAtt02 = (select MIN(LotAtt02) from temp_min_lot_INV_LOT_LOC_ID
where WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU )
if(@lotCount > 1)
begin
if exists(select 1 from temp_min_lot_INV_LOT_LOC_ID where LocationUsage = 'EA' and LotAtt02 = @LotAtt02
and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU )
select top 1 @lotnum = lotnum,@LotAtt02 = LotAtt02,@LotAtt03 = LotAtt03 from temp_min_lot_INV_LOT_LOC_ID
where LocationUsage = 'EA' and LotAtt02 = @LotAtt02 and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
order by LotAtt02,LotAtt03
else
select top 1 @lotnum = lotnum,@LotAtt02 = LotAtt02,@LotAtt03 = LotAtt03 from temp_min_lot_INV_LOT_LOC_ID
where LotAtt02 = @LotAtt02 and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
order by LotAtt02,LotAtt03
end
else
select top 1 @lotnum = lotnum,@LotAtt02 = LotAtt02,@LotAtt03 = LotAtt03 from temp_min_lot_INV_LOT_LOC_ID
where LotAtt02 = @LotAtt02 and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
if(@@ROWCOUNT > 0)
begin
--20180904 YANGXUN 增加按客户指定批次分配逻辑
select @DetailsEditWho = EditWho,@EditLotNum = LotNum from DOC_Order_Details
where OrderNo=@OrderNO and CustomerID = @CustomerID and SKU = @SKU
if(@DetailsEditWho not in('EDI','system'))
begin
select '按客户指定食品批次分配'
insert into WTD_EditLotNum_Log(ID,WarehouseID,CustomerID,SKU,OrderNo,EditWho,EditTime,EditLotNum,NOTES)
values (NEWID(),@WarehouseID,@CustomerID,@SKU,@OrderNO,@DetailsEditWho,GETDATE(),@EditLotNum,'按客户指定食品批次分配')
update d
set d.D_EDI_20= '按客户指定食品批次分配'
from Doc_order_Details(nolock) d
where 1 = 1
and d.OrderNo = @OrderNO
and d.CustomerID = @CustomerID
and d.SKU = @SKU
and d.LineStatus < 40
end
else
begin
select '按系统指定最优食品次分配'
update d
set d.LotAtt02 = @LotAtt02,d.LotAtt03 = @LotAtt03,RotationID = @RotationID,LotNum= @LotNum,
d.D_EDI_19=CONVERT(varchar(20),GETDATE(),120),d.D_EDI_20= '按食品批次分配2'
from Doc_order_Details(nolock) d
where 1 = 1
and d.OrderNo = @OrderNO
and d.CustomerID = @CustomerID
and d.SKU = @SKU
and d.LineStatus < 40
end
end
end
else if(isnull(@LotID,'') = 'STANDARD')
begin
set @LotAtt03 = '1999-01-01'
set @RotationID = 'STANDARD' --2016.06.12 黄久洲修改
update d
set d.LotAtt03 = @LotAtt03,RotationID = @RotationID,d.D_EDI_20= '按标准批次分配1'
from Doc_order_Details(nolock) d
where 1 = 1
and d.OrderNo = @OrderNO
and d.CustomerID = @CustomerID
and d.SKU = @SKU
and d.LineStatus < 40
select @LotAtt03 = LotAtt03,@lotCount = COUNT(LotAtt03)
from temp_min_lot_INV_LOT_LOC_ID
where WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU --20180625 YANGXUN 剔除干扰库存
group by WarehouseID,CustomerID,SKU,LotAtt03
having LotAtt03 = (select MIN(LotAtt03) from temp_min_lot_INV_LOT_LOC_ID
where WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU )
if(@lotCount > 1)
begin
if exists(select 1 from temp_min_lot_INV_LOT_LOC_ID where LocationUsage = 'EA' and LotAtt03 = @LotAtt03
and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU)
select top 1 @lotnum = lotnum,@LotAtt03 = LotAtt03 from temp_min_lot_INV_LOT_LOC_ID
where LocationUsage = 'EA' and LotAtt03 = @LotAtt03 and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
order by LotAtt03
else
select top 1 @lotnum = lotnum,@LotAtt03 = LotAtt03 from temp_min_lot_INV_LOT_LOC_ID
where LotAtt03 = @LotAtt03 and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
order by LotAtt03
end
else
select top 1 @lotnum = lotnum,@LotAtt03 = LotAtt03 from temp_min_lot_INV_LOT_LOC_ID
where LotAtt03 = @LotAtt03 and WarehouseID = @WarehouseID and CustomerID = @CustomerID and SKU = @SKU
if(@@ROWCOUNT > 0)
begin
--20180904 YANGXUN 增加按客户指定批次分配逻辑
select @DetailsEditWho = EditWho,@EditLotNum = LotNum from DOC_Order_Details
where OrderNo=@OrderNO and CustomerID = @CustomerID and SKU = @SKU
if(@DetailsEditWho not in('EDI','system'))
begin
select '按客户指定标准批次分配'
insert into WTD_EditLotNum_Log(ID,WarehouseID,CustomerID,SKU,OrderNo,EditWho,EditTime,EditLotNum,NOTES)
values (NEWID(),@WarehouseID,@CustomerID,@SKU,@OrderNO,@DetailsEditWho,GETDATE(),@EditLotNum,'按客户指定标准批次分配')
update d
set d.D_EDI_20= '按客户指定标准批次分配'
from Doc_order_Details(nolock) d
where 1 = 1
and d.OrderNo = @OrderNO
and d.CustomerID = @CustomerID
and d.SKU = @SKU
and d.LineStatus < 40
end
else
begin
select '按系统指定最优标准批次分配'
update d
set d.LotAtt03 = @LotAtt03,RotationID = @RotationID,LotNum = @LotNum,
d.D_EDI_19=CONVERT(varchar(20),GETDATE(),120),d.D_EDI_20= '按标准批次分配2'
from Doc_order_Details(nolock) d
where 1 = 1
and d.OrderNo = @OrderNO
and d.CustomerID = @CustomerID
and d.SKU = @SKU
and d.LineStatus < 40
end
end
end
Fetch Next From Cur_OrderNOList Into @CustomerID,@SKU,@LotAtt02,@LotAtt03,@LotAtt08,@LotID,@RotationID
end
Close Cur_OrderNOList
DeAllocate Cur_OrderNOList
end try
begin catch
set @return_code=ERROR_MESSAGE()
+'('+ERROR_PROCEDURE()+')'
+',ERROR_NUMBER='+cast(ERROR_NUMBER()as varchar(10))
+',行号='+cast(ERROR_LINE() as varchar(10))
+',ERROR_STATE='+cast(ERROR_STATE() as varchar(10))
+',ERROR_SEVERITY='+cast(ERROR_SEVERITY() as varchar(10))
Close Cur_OrderNOList
DeAllocate Cur_OrderNOList
end catch