这两天看到系统里面在做库位库存事务的时候采用了增量算法来做,这种方法很有用,与大家分享一下:美的仓库结构为计划仓->财务仓->物流仓->虚拟物流仓->库位;不论是新增,修改,删除库位单的时候都需要做库位库存事务,修改库位现有量,虚拟物流仓现有量和在库位历史表中进行记录。增量算法就是每次做库存事务的时候,不论之前的库存事务正确与否,每次做库存事务的数量都取库位单上应该做库存事务的数量减去库存历史中已经记录的数量,这样就保证了每次做库存事务的时候都争取把整张单据做正确的库存事务。
CURSOR C_KW_TRANSACTION_CREATION IS
SELECT DUMMY_MF_INVENTORY_ID
,MF_INVENTORY_ID
,CUSTOMER_ID
,KW_INVENTORY_ID
,ORDER_LINE_ID
,MTL_BATCH_NUMBER
,MTL_STATUS
,MATERIAL_ID
,UOM_CODE
--Add By HYJ At [2005-12-14]
,INOUT_TYPE
,SOURCE_ORDER_INV_SRC_TYPE_ID
,SOURCE_ORDER_TYPE_ID
,SOURCE_ORDER_NUMBER
,SOURCE_ORDER_DATE
,ORIGIN_ORDER_NUMBER
,ORIGIN_ORDER_DATE
,SUM(ORDER_QUANTITY) AS TRAN_QUANTITY
FROM (
--1、分库位出库单据行数据
SELECT ikoah.DUMMY_MF_INVENTORY_ID
,ikoah.MF_INVENTORY_ID
,ikoah.CUSTOMER_ID
,ikoal.KW_INVENTORY_ID
,ikoal.LINE_ID AS ORDER_LINE_ID
,ikoal.MTL_BATCH_NUMBER
,ikoal.MTL_STATUS
,ikoal.MATERIAL_ID
,ikoah.INOUT_TYPE
,ikoah.SOURCE_ORDER_INV_SRC_TYPE_ID
,ikoah.SOURCE_ORDER_TYPE_ID
,ikoah.SOURCE_ORDER_NUMBER
,ikoah.SOURCE_ORDER_DATE
,ikoal.ORIGIN_ORDER_NUMBER
,ikoal.ORIGIN_ORDER_DATE
/*
根据事务类型和单据确认标记来决定数量:
1、如果是帐面库存事务,则数量取库位出入库单据的单据数量;
2、如果是结存库存事务,则分为是否已经确认两种情况:
2_1、如果已确认,则数量取库位出入库单据的确认数量;
2_2、如果未确认,则数量取0,目的是要冲平该单据的结存库位库存事务。
*/
,NVL(DECODE(sTRAN_TYPE,'帐面',ikoal.QUANTITY,
DECODE(NVL(ikoah.SEND_CONFIRM_FLAG,'Y'),'Y',ikoal.AFFIRM_QUANTITY,0)),0)
*DECODE(iot.TRAN_SOURCE_TYPE_ID,2,-1,+1) AS ORDER_QUANTITY
FROM sales.T_INV_KW_ORDER_ALLOT_LINES ikoal,--分库位单行
sales.T_INV_KW_ORDER_ALLOT_HEADERS ikoah,--分库位单头
sales.T_SO_ORDER_TYPES sot,--单据类型表
sales.V_INV_ORDER_TYPES iot--库存单据类型
WHERE ikoal.HEADER_ID=ikoah.HEADER_ID
AND ikoah.ORDER_TYPE_ID=sot.ORDER_TYPE_ID
AND sot.INV_ORDER_TYPE_ID=iot.INV_ORDER_TYPE_ID
AND sot.INV_ORDER_SOURCE_TYPE_ID=iot.INV_ORDER_SOURCE_TYPE_ID
AND ikoah.FINANCE_MAIN_ENTITY_ID=sot.ENTITY_ID
AND ikoal.KW_INVENTORY_ID IS NOT NULL--出库操作
AND ikoah.FINANCE_MAIN_ENTITY_ID=V_FINANCE_MAIN_ENTITY_ID
AND ikoah.HEADER_ID=V_KW_ORDER_ID
UNION ALL
--2、分库位入库单据行数据
SELECT ikoah.DUMMY_MF_INVENTORY_ID
,ikoah.MF_INVENTORY_ID
,ikoah.CUSTOMER_ID
,ikoal.REV_KW_INVENTORY_ID
,ikoal.LINE_ID
,ikoal.REV_MTL_BATCH_NUMBER
,ikoal.REV_MTL_STATUS
,ikoal.MATERIAL_ID
,ikoal.UOM_CODE
,ikoah.INOUT_TYPE
,ikoah.SOURCE_ORDER_INV_SRC_TYPE_ID
,ikoah.SOURCE_ORDER_TYPE_ID
,ikoah.SOURCE_ORDER_NUMBER
,ikoah.SOURCE_ORDER_DATE
,ikoal.ORIGIN_ORDER_NUMBER
,ikoal.ORIGIN_ORDER_DATE
/*
根据事务类型和单据确认标记来决定数量:
1、如果是帐面库存事务,则数量取库位出入库单据的单据数量;
2、如果是结存库存事务,则分为是否已经确认两种情况:
2_1、如果已确认,则数量取库位出入库单据的确认数量;
2_2、如果未确认,则取0,目的是要冲平该单据的结存库位库存事务。
*/
,NVL(DECODE(sTRAN_TYPE,'帐面',ikoal.QUANTITY,
DECODE(NVL(ikoah.SEND_CONFIRM_FLAG,'Y'),'Y',ikoal.AFFIRM_QUANTITY,0)),0)
*DECODE(iot.TRANSFER_TRAN_SOURCE_TYPE_ID,2,-1,+1) AS ORDER_QUANTITY
FROM sales.T_INV_KW_ORDER_ALLOT_LINES ikoal,--分库位单行
sales.T_INV_KW_ORDER_ALLOT_HEADERS ikoah,--分库位单头
sales.T_SO_ORDER_TYPES sot,--单据类型表
sales.V_INV_ORDER_TYPES iot--库存单据类型
WHERE ikoal.HEADER_ID=ikoah.HEADER_ID
AND ikoah.ORDER_TYPE_ID=sot.ORDER_TYPE_ID
AND sot.INV_ORDER_TYPE_ID=iot.INV_ORDER_TYPE_ID
AND sot.INV_ORDER_SOURCE_TYPE_ID=iot.INV_ORDER_SOURCE_TYPE_ID
AND ikoah.FINANCE_MAIN_ENTITY_ID=sot.ENTITY_ID
AND ikoal.REV_KW_INVENTORY_ID IS NOT NULL--入库操作
AND ikoah.FINANCE_MAIN_ENTITY_ID=V_FINANCE_MAIN_ENTITY_ID
AND ikoah.HEADER_ID=V_KW_ORDER_ID
UNION ALL
--3、已执行库位库存事务历史数据
SELECT ikth.DUMMY_MF_INVENTORY_ID
,ikth.MF_INVENTORY_ID
,ikth.CUSG_ID
,ikth.KW_INVENTORY_ID
,ikth.OPERATION_ORDER_LINE_ID
,ikth.MTL_BATCH_NUMBER
,ikth.MTL_STATUS
,ikth.MATERIAL_ID
,ikth.PRIMARY_UOM
--Add By HYJ At [2005-12-14]
,ikth.INOUT_TYPE
,ikth.SOURCE_ORDER_INV_SRC_TYPE_ID
,ikth.SOURCE_ORDER_TYPE_ID
,ikth.SOURCE_ORDER_NUMBER
,ikth.SOURCE_ORDER_DATE
,ikth.ORIGIN_ORDER_NUMBER
,ikth.ORIGIN_ORDER_DATE
,-NVL(ikth.PRIMARY_QUANTITY,0) AS ORDER_QUANTITY
FROM sales.T_INV_KW_TRAN_HIS ikth--库位库存事务历史表
WHERE ikth.FINANCE_MAIN_ENTITY_ID=V_FINANCE_MAIN_ENTITY_ID
AND ikth.OPERATION_ORDER_ID=V_KW_ORDER_ID
AND ikth.TRAN_TYPE=sTRAN_TYPE
)
GROUP BY DUMMY_MF_INVENTORY_ID
,MF_INVENTORY_ID
,CUSTOMER_ID
,KW_INVENTORY_ID
,ORDER_LINE_ID
,MTL_BATCH_NUMBER
,MTL_STATUS
,MATERIAL_ID
,UOM_CODE
,INOUT_TYPE
,SOURCE_ORDER_INV_SRC_TYPE_ID
,SOURCE_ORDER_TYPE_ID
,SOURCE_ORDER_NUMBER
,SOURCE_ORDER_DATE
,ORIGIN_ORDER_NUMBER
,ORIGIN_ORDER_DATE
HAVING SUM(ORDER_QUANTITY)!=0;