--[[ 版本: Version 1.0 创建日期: 2025-5-16 创建人: HAN WMS-Basis-Model-Version: V15.5 说明: 涉及数据类 INV_Detail 库存量表 INV_TXN_Log 库存交易日志 功能: 和库存量表相关的操作 更改说明: --]] --+-----------------------------------------------------------------------------+ --| 注意: wms_inv 是比较底层的业务逻辑处理层,不能再加其它和 wms_xxx 相关的 require | --+-----------------------------------------------------------------------------+ wms_base = require ("wms_base") local wms_inv = {_version = "0.2.1"} -- 对入库出库单中的明细属性进行检查,S_ITEM_CODE,S_ITEM_STATE,S_STORER 必须有值,F_QTY 必须大于 0 -- S_ITEM_STATE,S_STORER 如果没值用缺省值进行赋值 local function item_detail_data_check( item_detial_data, default_storer, default_item_state ) -- 数据检查 if lua.StrIsEmpty( item_detial_data.S_ITEM_CODE ) then return false, "创建【库存量表】前检查没通过! S_ITEM_CODE 为空" end if lua.StrIsEmpty( item_detial_data.S_ITEM_STATE ) then if default_item_state == '' then return false, "数据检查没通过! S_ITEM_STATE 为空并且没设置默认货品状态常量 WMS_Default_ItemState 没定义!" end item_detial_data.S_ITEM_STATE = default_item_state end if lua.StrIsEmpty( item_detial_data.S_STORER ) then if default_storer == '' then return false, "数据检查没通过! S_STORER 为空并且没设置默认货主常量 WMS_Default_Storer 没定义!" end item_detial_data.S_STORER = default_storer end if lua.Get_NumAttrValue( item_detial_data.F_QTY ) <= 0 then return fale, "数据检查没通过! S_ITEM_CODE ='"..item_detial_data.S_ITEM_CODE.."' 的数量属性 F_QTY 不能 <= 0!" end return true end --[[ 码盘结束后和货位进行绑定时库存量表的变化处理 --]] function wms_inv.After_CntrLoc_Binding( strLuaDEID, inb_pallet, loc_code ) local nRet, strRetInfo if (inb_pallet == nil or type(inb_pallet) ~= "table" ) then return 1, "After_CntrLoc_Binding 函数输入参数错误 inb_pallet 为空或不合规" end if ( loc_code == nil or loc_code == '' ) then return 1, "After_CntrLoc_Binding 函数输入参数错误 loc_code 不能为空!" end local loc nRet, loc = wms_wh.GetLocInfo( loc_code ) if ( nRet ~= 0 ) then return 1, "获取货位'"..loc_code.."'信息失败! "..loc end -- 查询【INB_Pallet_Detail】 local strOrder = "" local data_objects local strCondition = "S_IBP_NO = '"..inb_pallet.ibp_no.."'" nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INB_Pallet_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 2, "QueryDataObject失败!"..data_objects end if ( data_objects == '') then return 0 end local n, m, attr_count, base_attr_count local inv_detail_data local inv_txn_log_data local item_detial_data local check_is_ok -- 缺省值设置 local default_storer = '' -- 默认货主 nRet, default_storer = wms_base.Get_sConst2( "WMS_Default_Storer" ) if ( nRet ~= 0 ) then default_storer = '' end local default_item_state = '' -- 默认货品状态 nRet, default_item_state = wms_base.Get_sConst2( "WMS_Default_ItemState" ) if ( nRet ~= 0 ) then default_item_state = '' end attr_count = #INB_PALLET_DETAIL_ATTRS base_attr_count = #INV_DETAIL_BASE_ATTRS for n = 1, #data_objects do item_detial_data = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) check_is_ok, strRetInfo = item_detail_data_check( item_detial_data, default_storer, default_item_state ) if not check_is_ok then return 1, strRetInfo end -- 创建库存量表 inv_detail_data = m3.AllocObject2( strLuaDEID, "INV_Detail" ) inv_detail_data.S_WH_CODE = loc.wh_code inv_detail_data.S_AREA_CODE = loc.area_code inv_detail_data.S_LOC_CODE = loc.code inv_detail_data.S_CNTR_CODE = inb_pallet.cntr_code inv_detail_data.T_INBOUND_TIME = curTime for m = 1, attr_count do inv_detail_data[INB_PALLET_DETAIL_ATTRS[m]] = item_detial_data[INB_PALLET_DETAIL_ATTRS[m]] end nRet, inv_detail_data = m3.CreateDataObj2(strLuaDEID, inv_detail_data ) if (nRet ~= 0 ) then return 1, "创建【库存量表】失败!"..inv_detail_data end -- 创建库存交易日志 inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = loc.wh_code inv_txn_log_data.S_AREA_CODE = loc.area_code inv_txn_log_data.S_LOC_CODE = loc.code inv_txn_log_data.S_CNTR_CODE = inb_pallet.cntr_code inv_txn_log_data.S_LOG_TYPE = "IN" inv_txn_log_data.C_SYMBOL = "+" for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = item_detial_data[INV_DETAIL_BASE_ATTRS[m]] end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end end return 0 end --[[ 容器和货位解绑后,调用这个函数会删除 INV_Detail 中货品内容 输入参数: cntr_code -- 容器编码 str_note -- 备注 --]] function wms_inv.After_CntrLoc_UnBinding( strLuaDEID, cntr_code, str_note ) local nRet, strRetInfo if ( cntr_code == nil or cntr_code == '' ) then return 1, "After_CntrLoc_UnBinding 函数输入参数错误 cntr_code 不能为空!" end -- 查询【INV_Detail】 local strOrder = "" local strCondition = "S_CNTR_CODE = '"..cntr_code.."'" local data_objects nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 2, "QueryDataObject失败!"..data_objects end if ( data_objects == '') then return 0 end local n, m, attr_count, base_attr_count local inv_detail_data local inv_txn_log_data attr_count = #INB_PALLET_DETAIL_ATTRS base_attr_count = #INV_DETAIL_BASE_ATTRS for n = 1, #data_objects do inv_detail_data = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) -- 创建库存交易日志 inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_AREA_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_LOC_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_CNTR_CODE = cntr_code inv_txn_log_data.S_LOG_TYPE = "OUT" inv_txn_log_data.C_SYMBOL = "-" inv_txn_log_data.S_NOTE = str_note for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = inv_detail_data[INV_DETAIL_BASE_ATTRS[m]] end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end end -- 删除 INV_Detail strCondition = "S_CNTR_CODE = '" .. cntr_code .."'" nRet, strRetInfo = mobox.dbdeleteData(strLuaDEID, "INV_Detail", strCondition) if (nRet ~= 0) then return 2, "删除【INV_Detail】失败!"..strRetInfo end return 0 end --[[ 库存量货位编码从 loc_from 货位移动到 loc_to 货位 参数: cntr_code -- 容器编码 from -- 移库起始货位 to -- 移库终点货位 作用: 改变 INV_Detail 中的仓库库位 --]] function wms_inv.Move( strLuaDEID, cntr_code, from, to ) local nRet, strRetInfo local loc_from, loc_to if ( cntr_code == nil or cntr_code == '' ) then return 1, "wms_inv.Move 函数输入参数错误 cntr_code 不能为空!" end if ( from == nil or from == '' ) then return 1, "wms_inv.Move 函数输入参数错误 from 不能为空!" end nRet, loc_from = wms_wh.GetLocInfo( from ) if ( nRet ~= 0 ) then return 1, "获取货位'"..from.."'信息失败! "..loc_from end if ( to == nil or to == '' ) then return 1, "wms_inv.Move 函数输入参数错误 to 不能为空!" end nRet, loc_to = wms_wh.GetLocInfo( to ) if ( nRet ~= 0 ) then return 1, "获取货位'"..to.."'信息失败! "..loc_to end -- 查询【INV_Detail】 local strCondition = "S_CNTR_CODE = '"..cntr_code.."' AND S_LOC_CODE = '"..from.."'" local strOrder = "" local data_objects nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 2, "QueryDataObject失败!"..data_objects end if ( data_objects == '') then return 0 end local n, m, base_attr_count local inv_detail_data local inv_txn_log_data base_attr_count = #INV_DETAIL_BASE_ATTRS for n = 1, #data_objects do inv_detail_data = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) -- 创建库存交易日志 -- 从from库位移出 inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = loc_from.wh_code inv_txn_log_data.S_AREA_CODE = loc_from.area_code inv_txn_log_data.S_LOC_CODE = loc_from.code inv_txn_log_data.S_CNTR_CODE = cntr_code inv_txn_log_data.S_LOG_TYPE = "MOVE-OUT" inv_txn_log_data.C_SYMBOL = "-" for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = inv_detail_data[INV_DETAIL_BASE_ATTRS[m]] end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end -- 移到to库位 inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = loc_to.wh_code inv_txn_log_data.S_AREA_CODE = loc_to.area_code inv_txn_log_data.S_LOC_CODE = loc_to.code inv_txn_log_data.S_CNTR_CODE = cntr_code inv_txn_log_data.S_LOG_TYPE = "MOVE-IN" inv_txn_log_data.C_SYMBOL = "+" for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = inv_detail_data[INV_DETAIL_BASE_ATTRS[m]] end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end end --更新CG_Detail strCondition = "S_CNTR_CODE = '"..cntr_code.."' AND S_LOC_CODE = '"..from.."'" local strUpdateSql = "S_WH_CODE = '"..loc_to.wh_code.."', S_AREA_CODE = '"..loc_to.area_code.."', S_LOC_CODE = '"..loc_to.code.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "INV_Detail", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then return 2, "更新[INV_Detail]信息失败!"..strRetInfo end return 0 end --[[ 根据 条件 strCondition 来扣减 INV_detail 中货品的数量 参数: cntr_code 容器编码 strCondition 查询条件 strOrder INV_Detail 的排序 qty 扣减物料数量 note 备注 返回: nRet 非0 失败 如果没有匹配到返回 0,"none" -- ]] function wms_inv.Reduce_INV_Detail_Qty( strLuaDEID, cntr_code, strCondition, strOrder, qty, note ) local nRet, strRetInfo, m if ( cntr_code == nil or cntr_code == '' ) then return 1, "Reduce_INV_Detail_Qty 函数中 cntr_code 不能为空!" end if ( strCondition == nil or strCondition == '' ) then return 1, "Reduce_INV_Detail_Qty 函数中 strCondition 不能为空!" end if ( type(qty) ~= "number") then return 1, "Reduce_INV_Detail_Qty 函数中 qty 必须是数值类型!" end if ( qty <= 0 ) then return 1, "Reduce_INV_Detail_Qty 函数中 qty 必须大于0!" end if note == nil then note = '' end local data_objects nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 2, "QueryDataObject失败!"..data_objects end if ( data_objects == '') then return 0 end local n local obj_attr, inv_detail_data local value local inv_txn_log_data base_attr_count = #INV_DETAIL_BASE_ATTRS for n = 1, #data_objects do inv_detail_data = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) value = lua.Get_NumAttrValue( inv_detail.F_QTY ) -- 创建 INV_Log inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_AREA_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_LOC_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_CNTR_CODE = cntr_code inv_txn_log_data.S_LOG_TYPE = "ADJ-OUT" inv_txn_log_data.C_SYMBOL = "-" inv_txn_log_data.S_NOTE = note for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = inv_detail_data[INV_DETAIL_BASE_ATTRS[m]] end if ( qty >= value ) then -- 删除 INV_Detail strCondition = "S_ID = '"..data_objects[n].id.."'" nRet, strRetInfo = mobox.deleteDataObject( strLuaDEID, "INV_Detail", strCondition ) if ( nRet ~= 0) then return 1, "删除相关的【INV_Detail】失败! "..strRetInfo end inv_txn_log_data.F_QTY = inv_detail.F_QTY nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end if ( qty == value ) then goto done end else -- 减少 INV_Detail 中的数量 inv_detail.F_QTY = value - qty nRet, strRetInfo = wms_cntr.INV_Detail_Update( strLuaDEID, inv_detail ) if ( nRet ~= 0) then return 1, "wms_cntr.INV_Detail_Update 失败! "..strRetInfo end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end goto done end qty = qty - value end ::done:: return 0, "" end --[[ 根据条件加 INV_Detail 中的数量, 参数: cntr_code 容器编码 strCondition 查询条件 strOrder INV_Detail 的排序 qty 扣减物料数量 note 备注 返回: nRet 非0 失败 如果没有匹配到返回 0,"none" -- ]] function wms_inv.Add_INV_Detail_Qty( strLuaDEID, cntr_code, strCondition, strOrder, qty, note ) local m, nRet, strRetInfo if ( cntr_code == nil or cntr_code == '' ) then return 1, "Add_INV_Detail_Qty 函数中 cntr_code 不能为空!" end if ( strCondition == nil or strCondition == '' ) then return 1, "Add_INV_Detail_Qty 函数中 strCondition 不能为空!" end if ( type(qty) ~= "number") then return 1, "Add_INV_Detail_Qty 函数中 qty 必须是数值类型!" end if ( qty <= 0 ) then return 1, "Add_INV_Detail_Qty 函数中 qty 必须大于0!" end if note == nil then note = '' end local data_objects nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 2, "QueryDataObject失败!"..data_objects end if ( data_objects == '') then return 0 end local strUpdateCondition = "S_ID = '"..data_objects[n].id.."'" local strSetAttr = "F_QTY = F_QTY + "..qty nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "INV_Detail", strUpdateCondition, strSetAttr ) if ( nRet ~= 0 ) then return 2, "更新【容器货品明细】信息失败!"..strRetInfo end local inv_txn_log_data -- 创建库存交易日志 local inv_detail_data = m3.KeyValueAttrsToObjAttr(data_objects[1].attrs) -- 创建 INV_Log inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_AREA_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_LOC_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_CNTR_CODE = cntr_code inv_txn_log_data.S_LOG_TYPE = "ADJ-IN" inv_txn_log_data.C_SYMBOL = "+" inv_txn_log_data.S_NOTE = note for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = inv_detail_data[INV_DETAIL_BASE_ATTRS[m]] end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end return 0, "" end --[[ 把预分配容器明细加入 INV_Detail 适用料箱带料格的预分配料箱入库 pac_no -- 预分配容器流水号 loc_code -- 当前容器位置 ]] function wms_inv.Add_INV_Detail_By_PAC_Detail( strLuaDEID, cntr_code, pac_no, loc_code ) local nRet, strRetInfo, n if ( pac_no == nil or pac_no == '' ) then return 1, "wms_inv.Add_INV_Detail_By_PAC_Detail 函数中 pac_no 必须有值!" end if ( cntr_code == nil or cntr_code == '' ) then return 1, "wms_inv.Add_INV_Detail_By_PAC_Detail 函数中 cntr_code 必须有值!" end local loc nRet, loc = wms_wh.GetLocInfo( loc_code ) if ( nRet ~= 0 ) then return 1, "获取货位'"..loc_code.."'信息失败! "..loc end local forced_fill_cell = {} -- 强制置满的料格 local curTime = os.date("%Y-%m-%d %H:%M:%S") -- 查询【Pre_Alloc_CNTR_Detail】 local strOrder = "" local strCondition = "S_PAC_NO = '"..pac_no.."'" local data_objects nRet, data_objects = m3.QueryDataObject(strLuaDEID, "Pre_Alloc_CNTR_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 2, "QueryDataObject失败!"..data_objects end if ( data_objects == '') then return 0 end local n, m, attr_count, base_attr_count local inv_detail_data, inv_detail local inv_txn_log_data local item_detial_data local check_is_ok attr_count = #INB_PALLET_DETAIL_ATTRS base_attr_count = #INV_DETAIL_BASE_ATTRS -- 缺省值设置 local default_storer = '' -- 默认货主 nRet, default_storer = wms_base.Get_sConst2( "WMS_Default_Storer" ) if ( nRet ~= 0 ) then default_storer = '' end local default_item_state = '' -- 默认货品状态 nRet, default_item_state = wms_base.Get_sConst2( "WMS_Default_ItemState" ) if ( nRet ~= 0 ) then default_item_state = '' end for n = 1, #data_objects do item_detial_data = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) if ( item_detial_data.C_FORCED_FILL == 'Y' ) then table.insert( forced_fill_cell, item_detial_data.S_CELL_NO ) end check_is_ok, strRetInfo = item_detail_data_check( item_detial_data, default_storer, default_item_state ) if not check_is_ok then return 1, strRetInfo end if lua.Get_NumAttrValue( item_detial_data.F_ACT_QTY ) > 0 then -- 创建库存量表 inv_detail_data = m3.AllocObject2( strLuaDEID, "INV_Detail" ) inv_detail_data.S_WH_CODE = loc.wh_code inv_detail_data.S_AREA_CODE = loc.area_code inv_detail_data.S_LOC_CODE = loc.code inv_detail_data.S_CNTR_CODE = cntr_code inv_detail_data.T_INBOUND_TIME = curTime for m = 1, attr_count do inv_detail_data[INB_PALLET_DETAIL_ATTRS[m]] = item_detial_data[INB_PALLET_DETAIL_ATTRS[m]] end inv_detail_data.F_QTY = item_detial_data.F_ACT_QTY nRet, inv_detail_data = m3.CreateDataObj2(strLuaDEID, inv_detail_data ) if (nRet ~= 0 ) then return 1, "创建【库存量表】失败!"..inv_detail_data end -- 创建库存交易日志 inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = loc.wh_code inv_txn_log_data.S_AREA_CODE = loc.area_code inv_txn_log_data.S_LOC_CODE = loc.code inv_txn_log_data.S_CNTR_CODE = cntr_code inv_txn_log_data.S_LOG_TYPE = "IN" inv_txn_log_data.C_SYMBOL = "+" for m = 1, base_attr_count do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = item_detial_data[INV_DETAIL_BASE_ATTRS[m]] end nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end end end local nCount = #forced_fill_cell if ( nCount == 0 ) then return 0 end -- 设置料格强制置满属性 local str_cell_no = lua.strArray2string( forced_fill_cell ) if ( str_cell_no == '' ) then return 0 end local strCondition, srtSetAttr strCondition = " S_CELL_NO IN ("..str_cell_no..") AND S_CNTR_CODE = '"..cntr_code.."'" srtSetAttr = "C_FORCED_FILL = 'Y', N_EMPTY_FULL = 2" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Container_Cell", strCondition, srtSetAttr ) if ( nRet ~= 0 ) then lua.Warning( strLuaDEID, debug.getinfo(1), "更新【容器箱格】信息失败! condition = "..strCondition ) return 2, "更新【容器箱格】信息失败!"..strRetInfo end return 0 end --[[ 库存量加预分配量 输入参数: inv_detail_data --- 需要进行分配量增加的 INV_Detial qty -- 分配量 bs_type -- 增加分配量的业务类型 bs_no 为业务单号 --]] function wms_inv.INV_Detail_Add_AllocQty( strLuaDEID, inv_detail_data, qty, bs_type, bs_no ) local nRet, strRetInfo local strCondition local inv_detail_id = inv_detail_data.S_ID or '' if inv_detail_id == '' then return 1, "wms_inv.INV_Detail_Add_AllocQty 函数失败! inv_detail_data 中S_ID为空!" end if qty <= 0 or qty == nil then return 1, "wms_inv.INV_Detail_Add_AllocQty 函数失败! qty 必须大于 0!" end strCondition = "S_ID = '"..inv_detail_data.S_ID.."'" local strSetAttr = "F_ALLOC_QTY = F_ALLOC_QTY+"..qty nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "INV_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 2, "设置【INV_Detail】数量分配量信息失败!"..strRetInfo end -- 创建库存锁定日志 local m local inv_lock_log_data = m3.AllocObject2( strLuaDEID, "INV_Lock_Log" ) for m = 1, #INV_LOG_BASE_ATTRS do inv_lock_log_data[INV_LOG_BASE_ATTRS[m]] = inv_detail_data[INV_LOG_BASE_ATTRS[m]] end inv_lock_log_data.S_LOG_TYPE = "allocate" -- 订单分配库存量 inv_lock_log_data.F_QTY = qty inv_lock_log_data.S_BS_TYPE = bs_type inv_lock_log_data.S_BS_NO = bs_no inv_lock_log_data.G_INV_DETAIL_ID = inv_detail_data.S_ID nRet, inv_lock_log_data = m3.CreateDataObj2(strLuaDEID, inv_lock_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存锁定日志】失败!"..inv_lock_log_data end return 0 end local function create_inv_detail_allocate_out_log( strLuaDEID, inv_detail_data, qty, alloc_qty, bs_type, bs_no ) local nRet, m -- 创建库存交易日志 local inv_txn_log_data inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" ) inv_txn_log_data.S_WH_CODE = inv_detail_data.S_WH_CODE inv_txn_log_data.S_AREA_CODE = inv_detail_data.S_AREA_CODE inv_txn_log_data.S_LOC_CODE = inv_detail_data.S_LOC_CODE inv_txn_log_data.S_LOG_TYPE = "OUT" inv_txn_log_data.C_SYMBOL = "-" for m = 1, #INV_DETAIL_BASE_ATTRS do inv_txn_log_data[INV_DETAIL_BASE_ATTRS[m]] = inv_detail_data[INV_DETAIL_BASE_ATTRS[m]] end inv_txn_log_data.F_QTY = qty nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存交易日志】失败!"..inv_txn_log_data end -- 创建库存锁定日志 local inv_lock_log_data = m3.AllocObject2( strLuaDEID, "INV_Lock_Log" ) for m = 1, #INV_LOG_BASE_ATTRS do inv_lock_log_data[INV_LOG_BASE_ATTRS[m]] = inv_detail_data[INV_LOG_BASE_ATTRS[m]] end inv_lock_log_data.S_LOG_TYPE = "allocate_release" -- 订单分配库存量释放 inv_lock_log_data.F_QTY = alloc_qty inv_lock_log_data.S_BS_TYPE = bs_type inv_lock_log_data.S_BS_NO = bs_no inv_lock_log_data.G_INV_DETAIL_ID = inv_detail_data.id inv_lock_log_data.F_QTY = alloc_qty nRet, inv_lock_log_data = m3.CreateDataObj2(strLuaDEID, inv_lock_log_data ) if (nRet ~= 0 ) then return 1, "创建【库存锁定日志】失败!"..inv_lock_log_data end return 0 end --[[ INV_Detail 中分配的数量出库 -- qty 是实际出库数量 alloc_qty 是分配量 --]] function wms_inv.INV_Detail_Out( strLuaDEID, inv_detail_id, qty, alloc_qty, bs_type, bs_no ) local nRet, strRetInfo, strCondition if ( inv_detail_id == '' or inv_detail_id == nil ) then return 2, "wms_inv.Allocate_Qty_Out 函数中 参数 inv_detail_id 不能为空!" end local inv_detail_data nRet, inv_detail_data = m3.GetDataObject2( strLuaDEID, "INV_Detail", inv_detail_id ) if ( nRet ~= 0 ) then return 2, inv_detail_data end strCondition = "S_ID = '"..inv_detail_id.."'" local strSetAttr = "F_QTY = F_QTY-"..qty..", F_ALLOC_QTY = F_ALLOC_QTY-"..alloc_qty nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "INV_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 2, "设置【INV_Detail】数量分配量信息失败!"..strRetInfo end nRet, strRetInfo = create_inv_detail_allocate_out_log( strLuaDEID, inv_detail_data, qty, alloc_qty, bs_type, bs_no ) if nRet ~= 0 then return 2, strRetInfo end return 0 end -- 根据输入的 strCondition 扣减 INV_Detail 中某数量和分配量, 会有多条 INV_Detail 需要批分 -- qty 是真实际出库数量 alloc_qty 是分配量 function wms_inv.INV_Detail_SplitOut( strLuaDEID, strCondition, strOrder, qty, alloc_qty, bs_type, bs_no ) local nRet, strRetInfo if ( strCondition == '' or strCondition == nil ) then return 2, "函数 wms_inv.INV_Detail_SplitOut 里strCondition 不能为空!" end if ( strOrder == nil ) then strOrder = '' end local inv_detail_objs nRet, inv_detail_objs = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition, strOrder ) if (nRet ~= 0) then return 2, "查询CG_Detail失败! "..inv_detail_objs end if ( inv_detail_objs == '' ) then return 0 end local n, inv_detail_data local strSetAttr, inv_detail_qty, inv_detail_alloc_qty local strSetQtyAttr, strSetAllocQtyAttr local Q, AQ for n = 1, #inv_detail_objs do inv_detail_data = m3.KeyValueAttrsToObjAttr(inv_detail_objs[n].attrs) inv_detail_data.id = lua.trim_guid_str( inv_detail_objs[n].id ) inv_detail_qty = lua.Get_NumAttrValue( inv_detail_data.F_QTY ) inv_detail_alloc_qty = lua.Get_NumAttrValue( inv_detail_data.F_ALLOC_QTY ) strSetAttr = '' Q = 0 AQ = 0 if ( qty > 0 ) then if ( inv_detail_qty < qty ) then strSetQtyAttr = "F_QTY = F_QTY-"..inv_detail_qty qty = qty - inv_detail_qty Q = inv_detail_qty else strSetQtyAttr = "F_QTY = F_QTY-"..qty Q = qty qty = 0 end strSetAttr = strSetQtyAttr end if ( alloc_qty > 0 ) then if ( inv_detail_alloc_qty < alloc_qty ) then strSetAllocQtyAttr = "F_ALLOC_QTY = F_ALLOC_QTY-"..inv_detail_alloc_qty AQ = inv_detail_alloc_qty alloc_qty = alloc_qty - inv_detail_alloc_qty else strSetAllocQtyAttr = "F_ALLOC_QTY = F_ALLOC_QTY-"..alloc_qty AQ = alloc_qty alloc_qty = 0 end if ( strSetAttr ~= '' ) then strSetAttr = strSetAttr.."," end strSetAttr = strSetAttr..strSetAllocQtyAttr end if ( strSetAttr == '' ) then break end strCondition = "S_ID = '"..inv_detail_data.id.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "INV_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 2, "设置【INV_Detail】数量分配量信息失败!"..strRetInfo end -- 创建日志 nRet, strRetInfo = create_inv_detail_allocate_out_log( strLuaDEID, inv_detail_data, Q, AQ, bs_type, bs_no ) if nRet ~= 0 then return 2, strRetInfo end end return 0 end return wms_inv