--[[ 版本: Version 2.1 创建日期: 2025-1-28 创建人: HAN WMS-Basis-Model-Version: V15.5 功能: WMS 过程中一些常用功能封装 -- Get_sConst 获取常量返回字符串类型 -- Get_nConst 获取常量返回数值类型 -- GetDictItemName 获取字典项的附加值,输入的 nItemValue 必须是数值 -- Warning 创建一条WMS警告信息 -- GetFuncArea 获取功能区定义列表 -- GetWHCGLocByRule 得到仓库中指定货品或空托的货位 -- Add_WHAreaQty_ByCGDetail 通过CG_Detail增加仓库量表 -- Add_WHAreaQty_By_PAC_Detail 通过 Pre_Alloc_CNTR_Detail 增加仓库量表 --]] json = require ("json") mobox = require ("OILua_JavelinExt") wms = require ("OILua_WMS") lua = require ("oi_base_func") m3 = require ("oi_base_mobox") local wms_base = {_version = "0.2.1"} -- 容器类型 WMS_CNTR_TYPE_NAME = { ["Pallet"] = "托盘", ["Normal"] = "常规", ["Cell_Box"] = "料格", ["Picking_Box"] = "拣料箱" } WMS_CNTR_TYPE = { ["托盘"] = "Pallet", ["常规"] = "Normal", ["料格"] = "Cell_Box", ["P拣料箱"] = "icking_Box" } --//////////////////////////////////////////////////////常量相关/////////////////////////////////////////////////////////// -- 获取常量返回字符串类型 (建议用这个函数) function wms_base.Get_sConst2( strLuaDEID, strConstName ) local nRet, strValue if ( strConstName == nil or strConstName == '' ) then return 1, "Get_sConst 参数必须有2个,并且第二个参数不能为空字符串!" end strConstName = lua.trim(strConstName) nRet, strValue = wms.wms_GetConst(strConstName) if (nRet ~= 0 ) then return 2, strValue end return 0, strValue end -- 如果没有返回一个巨大的值(不建议使用) function wms_base.Get_nConst( strLuaDEID, strConstName ) local nRet, strValue if ( strConstName == nil or strConstName == '' ) then return 2^53 end strConstName = lua.trim(strConstName) nRet, strValue = wms.wms_GetConst(strConstName) if (nRet ~= 0 ) then return 2^53 end return lua.StrToNumber( strValue ) end -- 获取常量返回数值类型 function wms_base.Get_nConst2( strLuaDEID, strConstName ) local nRet, strValue if ( strConstName == nil or strConstName == '' ) then return 1, "Get_nConst 参数必须有2个,并且第二个参数不能为空字符串!" end strConstName = lua.trim(strConstName) nRet, strValue = wms.wms_GetConst(strConstName) if (nRet ~= 0 ) then return 2, strValue end return 0, lua.StrToNumber( strValue ) end -- 获取常量返回bool类型 function wms_base.Get_bConst2( strLuaDEID, strConstName ) local nRet, strValue if ( strConstName == nil or strConstName == '' ) then return 1, "Get_nConst 参数必须有2个,并且第二个参数不能为空字符串!" end strConstName = lua.trim(strConstName) nRet, strValue = wms.wms_GetConst(strConstName) if (nRet ~= 0 ) then return 2, strValue end if ( strValue == '1' or strValue == 'Y' or strValue == 'y' ) then return 0, true end return 0, false end -- 获取字典项的附加值,输入的 nItemValue 必须是数值 function wms_base.GetDictItemName( strLuaDEID, strDictName, nItemValue ) local str_item_name = '' local nRet if ( nItemValue == nil ) then lua.Error( strLuaDEID, 0, "wms_base.GetDictItemName 的输入参数 nItemValue 必须有值!请检查 wms_base.GetDictItemName 函数的输入参数!" ) end if ( type(nItemValue) ~= "number" ) then lua.Warning( strLuaDEID, 0, "wms_base.GetDictItemName 的输入参数 nItemValue 必须要是一个数值类型!" ) return "" end nRet, str_item_name = wms.wms_GetDictTypeName( strDictName, nItemValue ) if ( nRet ~= 0 ) then lua.Warning( strLuaDEID, 0, strDictName.."不存在或者字典定义中不存在值 = "..nItemValue.." 的字典项!" ) return "" end return str_item_name end --[[ Warning 是未来方便使用者了解系统执行情况的 nErrCode -- 错误码 strInfo -- 错误信息 factory -- 工厂 strFrom -- 来源 nLvl -- 错误等级 strExtData -- 扩展数据 strNote -- 备注 --]] function wms_base.Warning( strLuaDEID, nLvl, nErrCode, strMsg, strExtData, strNote, strFrom, factory ) local nRet, strRetInfo, strErr if ( factory == nil or factory == "") then factory = "0000" end if ( strFrom == nil or strFrom == "") then strFrom = "Unkonw" end if ( strExtData == nil ) then strExtData = "" end if ( strNote == nil ) then strNote = "" end local warning = m3.AllocObject(strLuaDEID,"WMS_Warning") warning.factory = factory warning.msg = strMsg warning.from = strFrom warning.lvl = nLvl warning.err_code = nErrCode warning.ext_data = strExtData warning.note = strNote -- 获取创建容器时需要的属性 nRet, warning = m3.CreateDataObj( strLuaDEID, warning ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "创建 wms_base.Warning 失败! "..warning ) end end --[[ 仓库货品数量变化处理 -- strChangeOp 库存变化动作 -- strItemInfo 货品信息 --]] function wms_base.InventoryChangeAction( strLuaDEID, strChangeOp, strItemInfo ) local nRet, strRetInfo, change_op if ( type(strChangeOp) == "string" ) then change_op = wms_base.Get_nConst(strLuaDEID, strChangeOp) else change_op = strChangeOp end nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, change_op, strItemInfo ) if ( nRet ~= 0 ) then return 2, "wms_AddWHInventoryChange 失败! "..strRetInfo end return 0 end --[[ 获取位置(Postion)相关的功能区定义列表,这里的位置是一个比较宽泛的范围,库区,货位,仓库,逻辑库区 参数: strPosClsID 位置类型:Area、Zone、Warehouse、Location strPosCode 位置编码 strFuncType 功能类型 返回 -- nRet 非零失败 -- func_pos 功能区/位列表对象,是一个table类型 [{"type":0~2, "class":"Zone", "code":"xxx"}] --]] function wms_base.GetFuncArea( strLuaDEID, strPosClsID, strPosCode, strFuncType ) local nRet, strRetInfo, nFuncType if ( type(strFuncType) == "string") then nFuncType = wms_base.Get_nConst(strLuaDEID, strFuncType) else nFuncType = strFuncType end nRet, strRetInfo = wms.wms_GetFuncArea( strPosClsID, strPosCode, nFuncType ) if (nRet ~= 0) then return 1, "wms_GetFuncArea 失败!"..strRetInfo end if ( strRetInfo == '' ) then return 1, strPosClsID.."编码 = '"..strPosCode.."' 没有定义类型值 = "..nFuncType.."名称 = '"..strFuncType.."'的功能区" end local success, ret_pos success, ret_pos = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "wms_GetFuncArea返回值为非法的JSON格式!"..ret_pos end return 0, ret_pos end function wms_base.Get_Warehouse_FuncArea( strLuaDEID, strWHCode, strFuncType ) local nRet, strRetInfo nRet, strRetInfo = wms_base.GetFuncArea( strLuaDEID, "Warehouse", strWHCode, strFuncType ) if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "wms_base.GetFuncArea 失败!"..strRetInfo ) end return strRetInfo end function wms_base.Get_Area_FuncArea( strLuaDEID, strAreaCode, strFuncType ) local nRet, strRetInfo nRet, strRetInfo = wms_base.GetFuncArea( strLuaDEID, "Area", strAreaCode, strFuncType ) if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "wms_base.GetFuncArea 失败!"..strRetInfo ) end return strRetInfo end function wms_base.Get_Zone_FuncArea( strLuaDEID, strZoneCode, strFuncType ) local nRet, strRetInfo nRet, strRetInfo = wms_base.GetFuncArea( strLuaDEID, "Zone", strZoneCode, strFuncType ) if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "wms_base.GetFuncArea 失败!"..strRetInfo ) end return strRetInfo end function wms_base.Get_Loc_FuncArea( strLuaDEID, strLocCode, strFuncType ) local nRet, strRetInfo nRet, strRetInfo = wms_base.GetFuncArea( strLuaDEID, "Location", strLocCode, strFuncType ) if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "wms_base.GetFuncArea 失败!"..strRetInfo ) end return strRetInfo end --[[ 获取逻辑库区中可用的货位 参数: strZoneCode 返回 -- nRet 0 成功 -- location 货位对象,是一个table类型 {"wh_code":"XXX", "area_code":"XXX", "loc_code":"XX", "agv_site":"XXX", "agv_site_layer": X } --]] function wms_base.GetZoneAvaliableLoc( strLuaDEID, strZoneCode, strExtInfo ) local nRet, strRetInfo if (strExtInfo == nil) then strExtInfo = '' end nRet, strRetInfo = wms.wms_GetZoneAvaliableLoc( strLuaDEID, strZoneCode, strExtInfo ) if (nRet ~= 0) then return 1, "wms_GetZoneAvaliableLoc 失败!"..strRetInfo end if ( strRetInfo == '' ) then return 0, "" end local success, ret_info success, ret_info = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "wms_GetZoneAvaliableLoc 返回值为非法的JSON格式!"..ret_info end return 0, ret_info end --[[ 获取库区中可用的货位 参数: strAreaCode --]] function wms_base.GetAreaAvaliableLoc( strLuaDEID, strAreaCode, strExtInfo ) local nRet, strRetInfo if (strExtInfo == nil) then strExtInfo = '' end nRet, strRetInfo = wms.wms_GetAreaAvaliableLoc( strLuaDEID, strAreaCode, strExtInfo ) if (nRet ~= 0) then return 1, "wms_GetAreaAvaliableLoc 失败! 物理库区:'"..strAreaCode.."' "..strRetInfo end if ( strRetInfo == '' ) then return 0, "" end local success, ret_info success, ret_info = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "wms_GetAreaAvaliableLoc 返回值为非法的JSON格式!"..ret_info end return 0, ret_info end --[[ 得到仓库中指定货品或空托的货位对象 --]] function wms_base.GetWHCGLocByRule( strLuaDEID, strWHCode, strPolicyName, strExtInfo, bIsEmptyCntr ) local nRet, strRetInfo if ( bIsEmptyCntr == nil ) then bIsEmptyCntr = 0 end nRet, strRetInfo = wms.wms_GetWHCGLocByRule( strLuaDEID, strWHCode, strPolicyName, strExtInfo, bIsEmptyCntr ) if ( nRet ~= 0 ) then return nRet, "wms_GetWHCGLocByRule 失败!"..strRetInfo end if ( strRetInfo == '' ) then return 0, "" end local success, ret_info success, ret_info = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "wms_GetWHCGLocByRule 返回值为非法的JSON格式!"..ret_info end return 0, ret_info end --[[ 得到仓库库区中指定货品或空托的货位 --]] function wms_base.GetAreaCGLoc( strLuaDEID, strAreaCode, strExtInfo, bIsEmptyCntr ) local nRet, strRetInfo if ( bIsEmptyCntr == nil ) then bIsEmptyCntr = 0 end nRet, strRetInfo = wms.wms_GetAreaCGLoc( strLuaDEID, strAreaCode, strExtInfo, bIsEmptyCntr ) if ( nRet ~= 0 ) then return nRet, "wms_base.GetAreaCGLoc 失败!"..strRetInfo end if ( strRetInfo == '' ) then return 0, "" end local success, ret_info success, ret_info = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "WGetAreaCGLoc 返回值为非法的JSON格式!"..ret_info end return 0, ret_info end -- 根据CG_Detail生成量表变化信息 local function get_inventorychg_bycgdetail( strLuaDEID, wh_code, area_code, cntr_code ) local nRet, strRetInfo if ( cntr_code == nil or cntr_code == '' ) then return 1, "get_inventorychg_bycgdetail 函数中容器编码必须有值!" end if ( wh_code == '' or wh_code == nil ) then return 1, "get_inventorychg_bycgdetail 函数中仓库编码必须有值!" end if ( area_code == nil ) then area_code = '' end -- 获取 CG_Detail local strOrder = '' local strCondition = "S_CNTR_CODE = '"..cntr_code.."'" nRet, strRetInfo = mobox.queryDataObjAttr( strLuaDEID, "CG_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 1, "获取【容器货品明细】失败! "..strRetInfo end if ( strRetInfo == '' ) then return 0, "" end local retObjs = json.decode( strRetInfo ) local nObjs = #retObjs local n local cg_detail = {} local inventory_list = {} for n = 1, nObjs do nRet, cg_detail = m3.ObjAttrStrToLuaObj( "CG_Detail", lua.table2str(retObjs[n].attrs) ) if ( nRet ~= 0 ) then return 1, "m3.ObjAttrStrToLuaObj(CG_Detail) 失败! "..cg_detail end -- 生成仓库量变化输入参数 --[[ inventory_info = '{"item_code": "'..cg_detail.item_code..'",' inventory_info = inventory_info..'"item_name": "'..lua.FormatJsonString(cg_detail.item_name)..'",' inventory_info = inventory_info..'"qty": "'..cg_detail.qty..'"'..chg_target..'}' inventory_change = inventory_change .. inventory_info.."," ]] local inventory = { item_code = cg_detail.item_code, item_name = cg_detail.item_name, qty = cg_detail.qty, wh_code = wh_code, area_code = area_code } table.insert( inventory_list, inventory ) end return 0, lua.table2str(inventory_list) end -- 根据CG_Detail生成量表变化信息 local function create_on_shelves_by_cgdetail( strLuaDEID, wh_code, area_code, cntr_code, loc_code ) local nRet, strRetInfo if ( cntr_code == nil or cntr_code == '' ) then return 1, "create_on_shelves_by_cgdetail 函数中容器编码必须有值!" end if ( loc_code == nil ) then loc_code = '' end if ( wh_code == '' or wh_code == nil ) then return 1, "create_on_shelves_by_cgdetail 函数中仓库编码必须有值!" end if ( area_code == nil ) then area_code = '' end -- 获取 CG_Detail local strOrder = '' local strCondition = "S_CNTR_CODE = '"..cntr_code.."'" nRet, strRetInfo = mobox.queryDataObjAttr( strLuaDEID, "CG_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 1, "获取【容器货品明细】失败! "..strRetInfo end if ( strRetInfo == '' ) then return 0, "" end local retObjs = json.decode( strRetInfo ) local nObjs = #retObjs local n local cg_detail = {} local days = os.date("%Y%m%d") local inventory_list = {} for n = 1, nObjs do nRet, cg_detail = m3.ObjAttrStrToLuaObj( "CG_Detail", lua.table2str(retObjs[n].attrs) ) if ( nRet ~= 0 ) then return 1, "m3.ObjAttrStrToLuaObj(CG_Detail) 失败! "..cg_detail end -- 生成仓库量变化输入参数 --[[ inventory_info = '{"item_code": "'..cg_detail.item_code..'",' inventory_info = inventory_info..'"item_name": "'..lua.FormatJsonString(cg_detail.item_name)..'",' inventory_info = inventory_info..'"qty": "'..cg_detail.qty..'"'..chg_target..'}' inventory_change = inventory_change .. inventory_info.."," ]] local inventory = { item_code = cg_detail.item_code, item_name = cg_detail.item_name, qty = cg_detail.qty, wh_code = wh_code, area_code = area_code } table.insert( inventory_list, inventory ) if ( loc_code ~= '' ) then -- 生成上架记录【OnOff_Shelves】 onoff_shelves = m3.AllocObject(strLuaDEID,"OnOff_Shelves") onoff_shelves.action = "+" onoff_shelves.d_action = days onoff_shelves.wh_code = wh_code onoff_shelves.area_code = area_code onoff_shelves.loc_code = loc_code onoff_shelves.item_code = cg_detail.item_code onoff_shelves.item_name = cg_detail.item_name onoff_shelves.batch_no = cg_detail.batch_no onoff_shelves.serial_no = cg_detail.serial_no onoff_shelves.item_spec = cg_detail.item_spec onoff_shelves.item_state_name = cg_detail.item_state_name onoff_shelves.item_state = cg_detail.item_state onoff_shelves.end_user = cg_detail.end_user onoff_shelves.owner = cg_detail.owner onoff_shelves.supplier = cg_detail.supplier onoff_shelves.supplier_name = cg_detail.supplier_name onoff_shelves.cntr_code = cg_detail.cntr_code onoff_shelves.cell_no = cg_detail.cell_no onoff_shelves.qty = cg_detail.qty onoff_shelves.uom = cg_detail.uom onoff_shelves.bs_no = cg_detail.bs_no onoff_shelves.bs_type = cg_detail.bs_type nRet, onoff_shelves = m3.CreateDataObj( strLuaDEID, onoff_shelves ) if ( nRet ~= 0 ) then return 1, 'mobox 创建【上下架记录】对象失败!'..onoff_shelves end -- 根据业务来源加 F_ACC_I_QTY/累计入库数量 if ( cg_detail.bs_type == "Inbound_Order" ) then if ( cg_detail.bs_no ~= nil and cg_detail.bs_no ~= '' ) then strCondition = "S_IO_NO = '"..cg_detail.bs_no.."' AND S_ITEM_CODE = '"..cg_detail.item_code.."'" local strSetAttr = "F_ACC_I_QTY = F_ACC_I_QTY +"..cg_detail.qty nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 1, "设置【Inbound_Detail】累计入库数量失败!"..strRetInfo end end end if ( cg_detail.bs_type == 'Inbound_Wave' ) then if ( cg_detail.bs_no ~= nil and cg_detail.bs_no ~= '' ) then strCondition = "S_WAVE_NO = '"..cg_detail.bs_no.."' AND S_ITEM_CODE = '"..cg_detail.item_code.."'" local strSetAttr = "F_ACC_I_QTY = F_ACC_I_QTY +"..cg_detail.qty nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "IW_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 1, "设置【IW_Detail】累计入库数量失败!"..strRetInfo end end end end end return 0, lua.table2str( inventory_list ) end --[[ 通过CG_Detail增加仓库/库区量表 ]] function wms_base.Add_WHAreaQty_ByCGDetail( strLuaDEID, wh_code, area_code, cntr_code, loc_code ) local nRet, strRetInfo, inventory_change nRet, inventory_change = create_on_shelves_by_cgdetail( strLuaDEID, wh_code, area_code, cntr_code, loc_code ) if ( nRet ~= 0 ) then return 1, inventory_change end if ( loc_code ~= nil and loc_code ~= '' ) then -- 创建上架记录 end if ( inventory_change ~= '' ) then if ( wh_code ~= '' and wh_code ~= nil ) then -- 5 仓库量表-仓库加存储量 nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, 5, inventory_change ) if ( nRet ~= 0 ) then return 1, "wms_AddWHInventoryChange 失败! "..strRetInfo end end if ( area_code ~= '' and area_code ~= nil ) then -- 6 仓库量表-库区加存储量 nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, 6, inventory_change) if ( nRet ~= 0 ) then return 1, "wms_AddWHInventoryChange 失败! "..strRetInfo end end end return 0 end -- 从【Pre_Alloc_CNTR_Detail】获取存储量新增参数并且创建 上下架记录 -- pac_no 组盘号 local function create_on_shelves_by_pac( strLuaDEID, wh_code, area_code, loc_code, pac_no ) local nRet, strRetInfo if ( pac_no == nil or pac_no == '' ) then return 1, "get_Inventory_chg_by_orgc 函数中 pac_no 必须有值!" end local chg_target = '' -- 量表变化对象 if ( wh_code == '' or wh_code == nil ) then return 1, "get_Inventory_chg_by_orgc 函数中仓库编码必须有值!" end if ( area_code == nil ) then area_code = '' end if ( loc_code == nil ) then loc_code = '' end -- 获取 Pre_Alloc_CNTR_Detail local strOrder = '' local strCondition = "S_PAC_NO = '"..pac_no.."'" nRet, strRetInfo = mobox.queryDataObjAttr( strLuaDEID, "Pre_Alloc_CNTR_Detail", strCondition, strOrder ) if ( nRet ~= 0 ) then return 1, "获取【组盘明细】失败! "..strRetInfo end if ( strRetInfo == '' ) then lua.Warning( strLuaDEID, debug.getinfo(1), "create_on_shelves_by_pac 存在异常 组盘号'"..pac_no.."'的明细为空!" ) return 0, "" end local retObjs = json.decode( strRetInfo ) local n local inventory_change = {} local pac_detail = {} local onoff_shelves = {} -- 上下架记录 local days = os.date("%Y%m%d") for n = 1, #retObjs do nRet, pac_detail = m3.ObjAttrStrToLuaObj( "Pre_Alloc_CNTR_Detail", lua.table2str(retObjs[n].attrs) ) if ( nRet ~= 0 ) then return 1, "m3.ObjAttrStrToLuaObj(Pre_Alloc_CNTR_Detail) 失败! "..pac_detail end if ( pac_detail.act_qty > 0 ) then -- 生成仓库量变化输入参数 local inventory_info = { item_code = pac_detail.item_code, item_name = pac_detail.item_name, qty = pac_detail.act_qty, wh_code = wh_code, area_code = area_code } table.insert( inventory_change, inventory_info ) -- 生成上架记录【OnOff_Shelves】 onoff_shelves = m3.AllocObject(strLuaDEID,"OnOff_Shelves") onoff_shelves.action = "+" onoff_shelves.d_action = days onoff_shelves.wh_code = wh_code onoff_shelves.area_code = area_code onoff_shelves.loc_code = loc_code onoff_shelves.item_code = pac_detail.item_code onoff_shelves.item_name = pac_detail.item_name onoff_shelves.batch_no = pac_detail.batch_no onoff_shelves.serial_no = pac_detail.serial_no onoff_shelves.item_spec = pac_detail.item_spec onoff_shelves.item_state_name = pac_detail.item_state_name onoff_shelves.item_state = pac_detail.item_state onoff_shelves.end_user = pac_detail.end_user onoff_shelves.owner = pac_detail.owner onoff_shelves.supplier = pac_detail.supplier onoff_shelves.supplier_name = pac_detail.supplier_name onoff_shelves.cntr_code = pac_detail.cntr_code onoff_shelves.cell_no = pac_detail.cell_no onoff_shelves.qty = pac_detail.act_qty onoff_shelves.uom = pac_detail.uom onoff_shelves.bs_no = pac_detail.bs_no onoff_shelves.bs_type = pac_detail.bs_type nRet, onoff_shelves = m3.CreateDataObj( strLuaDEID, onoff_shelves ) if ( nRet ~= 0 ) then return 1, 'mobox 创建【上下架记录】对象失败!'..onoff_shelves end end -- 根据业务来源加 F_ACC_I_QTY/累计入库数量 if ( pac_detail.bs_type == "Inbound_Order" ) then if ( pac_detail.bs_no ~= nil and pac_detail.bs_no ~= '' ) then strCondition = "S_IO_NO = '"..pac_detail.bs_no.."' AND S_ITEM_CODE = '"..pac_detail.item_code.."'" local strSetAttr = "F_ACC_I_QTY = F_ACC_I_QTY +"..pac_detail.act_qty if ( lua.equation( 0, pac_detail.cancel_qty ) == false ) then strSetAttr = strSetAttr..", F_ACC_C_QTY = F_ACC_C_QTY + "..pac_detail.cancel_qty end nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 1, "设置【Inbound_Detail】累计入库数量失败!"..strRetInfo end end end if ( pac_detail.bs_type == 'Inbound_Wave' ) then if ( pac_detail.bs_no ~= nil and pac_detail.bs_no ~= '' ) then strCondition = "S_WAVE_NO = '"..pac_detail.bs_no.."' AND S_ITEM_CODE = '"..pac_detail.item_code.."'" local strSetAttr = "F_ACC_I_QTY = F_ACC_I_QTY +"..pac_detail.act_qty if ( lua.equation( 0, pac_detail.cancel_qty ) == false ) then strSetAttr = strSetAttr..", F_ACC_C_QTY = F_ACC_C_QTY + "..pac_detail.cancel_qty end nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "IW_Detail", strCondition, strSetAttr ) if (nRet ~= 0) then return 1, "设置【IW_Detail】累计入库数量失败!"..strRetInfo end end end end return 0, inventory_change end --[[ 通过 Pre_Alloc_CNTR_Detail 增加仓库/库区量表 pac_no -- 组盘号 ]] function wms_base.Add_WHAreaQty_By_PAC_Detail( strLuaDEID, wh_code, area_code, loc_code, pac_no ) local nRet, strRetInfo, inventory_change nRet, inventory_change = create_on_shelves_by_pac( strLuaDEID, wh_code, area_code, loc_code, pac_no ) if ( nRet ~= 0 ) then return nRet, inventory_change end --[[ if ( #inventory_change > 0 ) then local str_inventory_change = lua.table2str(inventory_change) if ( wh_code ~= '' and wh_code ~= nil ) then -- 5 仓库量表-仓库加存储量 nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, 5, str_inventory_change ) if ( nRet ~= 0 ) then return 1, "wms_AddWHInventoryChange 失败! "..strRetInfo end end if ( area_code ~= '' and area_code ~= nil ) then -- 6 仓库量表-库区加存储量 nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, 6, str_inventory_change ) if ( nRet ~= 0 ) then return 1, "wms_AddWHInventoryChange 失败! "..strRetInfo end end end ]] return 0 end function wms_base.Reduce_WHAreaQty_ByCGDetail( strLuaDEID, wh_code, area_code, cntr_code ) local nRet, strRetInfo, inventory_change nRet, inventory_change = get_inventorychg_bycgdetail( strLuaDEID, wh_code, area_code, cntr_code ) if ( nRet ~= 0 ) then return nRet, inventory_change end if ( inventory_change ~= '' ) then if ( wh_code ~= '' and wh_code ~= nil ) then nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, 8, inventory_change) if ( nRet ~= 0 ) then return 1, "wms_AddWHInventoryChange 失败! "..strRetInfo end end if ( area_code ~= '' and area_code ~= nil ) then nRet, strRetInfo = wms.wms_AddWHInventoryChange(strLuaDEID, 9, inventory_change) if ( nRet ~= 0 ) then return 1, "wms_AddWHInventoryChange 失败! "..strRetInfo end end end return 0 end --[[只对一个货品计算分配量,仓库量表\库区量表加分配量 ]] function wms_base.IPA_Star( wh_code, area_code, strItemInfo, strAddKey, bForceSorting ) local nRet, strRetInfo local nForceSorting = 0 if ( wh_code == nil or wh_code == '' ) then return 1, "wms_base.IPA_Star 函数中 wh_code 必须有值!" end if ( area_code == nil or area_code == '' ) then return 1, "wms_base.IPA_Star 函数中 area_code 必须有值!" end if (bForceSorting) then nForceSorting = 1 end nRet, strRetInfo = wms.wms_IPA_Start( wh_code, area_code, "", strItemInfo, strAddKey, nForceSorting ) if ( nRet ~= 0 ) then return nRet, "wms_IPA_Start失败! "..strRetInfo end local success, ret_info success, ret_info = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "wms_IPA_Start 返回值为非法的JSON格式!"..ret_info end return 0, ret_info end ----IPA_Star2 内部调用函数------------------------------------------------------------------------------------------ local function get_oos_info( item_info, oos_info_set ) local n for n = 1, #oos_info_set do if ( item_info.N_ROW_NO == oos_info_set[n].N_ROW_NO and item_info.S_ITEM_CODE == oos_info_set[n].S_ITEM_CODE ) then return oos_info_set[n].F_OOS_QTY end end return 0 end -- 把 from中的信息复制到 target local function copy_item_info( target, from ) target.N_ROW_NO = from.N_ROW_NO target.S_ITEM_CODE = from.S_ITEM_CODE target.S_ITEM_NAME = from.S_ITEM_NAME target.F_QTY = from.F_QTY end --[[ 和IPA_Star不同这个是对多个货品进行分配 仓库量表\库区量表加分配量 对一个 item_set 的物料进行批分,根据 wms_IPA_Start 的结果休整 root_item_set 的分配量 wh_code 仓库编码 area_code 库区编码 item_set 本次物料领用的全部明细 strItemInfo 等待分配存储量的物料 返回: nRet ret_result { "trans_id":"" "outbound_items":[{"item_code":"qty":"","item_name":"xx"},...] -- 在area_code 匹配到的物料,这些物料可以出库 "to_be_alloc_items": [{"item_code":"qty":"","item_name":"xx"},...] -- 等待后面再继续进行分配的物料 } --]] function wms_base.IPA_Star2( strLuaDEID, wh_code, area_code, item_set, strItemInfo ) local nRet, strRetInfo local nForceSorting = 0 if ( wh_code == nil or wh_code == '' ) then return 1, "wms_base.IPA_Star2 函数中 wh_code 必须有值!" end if ( area_code == nil or area_code == '' ) then return 1, "wms_base.IPA_Star2 函数中 area_code 必须有值!" end if ( item_set == nil or type(item_set) ~= "table" ) then return 1, "wms_base.IPA_Star2 函数中 item_set 必须是一个table对象!" end nRet, strRetInfo = wms.wms_IPA_Start( wh_code, area_code, "", strItemInfo, "", 1 ) if ( nRet ~= 0 ) then return nRet, "wms_IPA_Start失败! "..strRetInfo end local success, ret_info success, ret_info = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "wms_IPA_Start 返回值为非法的JSON格式!"..ret_info end local alloc_item_set = json.decode( strItemInfo ) -- 待分配的物料 local ret_result = {} local n local oos_qty -- 缺件数量 local n_outbound = 1 local n_to_be_alloc = 1 ret_result.trans_id = ret_info.trans_id ret_result.outbound_items_set = {} ret_result.to_be_alloc_items = {} if ( ret_info.oos_info == nil ) then -- 表示没有缺件 ret_result.outbound_items_set = alloc_item_set else -- 判断哪个item_code缺件,缺多少 for n = 1, #alloc_item_set do qty = alloc_item_set[n].F_QTY oos_qty = get_oos_info( alloc_item_set[n], ret_info.oos_info ) if ( oos_qty == 0 ) then -- 没有缺件 local items_out = {} copy_item_info( items_out, alloc_item_set[n] ) ret_result.outbound_items_set[n_outbound] = items_out n_outbound = n_outbound + 1 else -- 有缺件 if (oos_qty < alloc_item_set[n].F_QTY) then local items_out = {} copy_item_info( items_out, alloc_item_set[n] ) items_out.F_QTY = items_out.F_QTY - oos_qty ret_result.outbound_items_set[n_outbound] = items_out n_outbound = n_outbound + 1 local items_to_be_alloc = {} copy_item_info( items_to_be_alloc, alloc_item_set[n] ) items_to_be_alloc.F_QTY = oos_qty ret_result.to_be_alloc_items[n_to_be_alloc] = items_to_be_alloc n_to_be_alloc = n_to_be_alloc + 1 else local items_to_be_alloc = {} copy_item_info( items_to_be_alloc, alloc_item_set[n] ) ret_result.to_be_alloc_items[n_to_be_alloc] = items_to_be_alloc n_to_be_alloc = n_to_be_alloc + 1 end end end end -- 更新item_set 中的已分配量 if (#ret_result.outbound_items_set > 0) then for n = 1, #ret_result.outbound_items_set do local i for i = 1, #item_set do if (item_set[i].N_ROW_NO == ret_result.outbound_items_set[n].N_ROW_NO and item_set[i].S_ITEM_CODE == ret_result.outbound_items_set[n].S_ITEM_CODE ) then item_set[i].F_ALLOC_QTY = item_set[i].F_ALLOC_QTY + ret_result.outbound_items_set[n].F_QTY end end end end return 0, ret_result end -- 获取某物料的仓库量表 -- 返回 nRet, qty, alloc_qty function wms_base.GetWHInventory( strLuaDEID, wh_code, item_code ) local nRet, strRetInfo local parameter if ( wh_code == nil or wh_code == '' ) then return 1, "GetWHInventory 函数中 wh_code 必须有值!" end if ( item_code == nil or item_code == '' ) then return 1, "WGetWHInventory 函数中 item_code 必须有值!" end parameter = {} parameter.wh_code = wh_code parameter.item_list = {} local item = {} item.item_code = item_code parameter.item_list[1] = item nRet, strRetInfo = wms.wms_GetWHInventory( lua.table2str(parameter) ) if (nRet == 0) then local ret_info = json.decode( strRetInfo ) qty = ret_info[1].qty_storage alloc_qty = ret_info[1].qty_alloc return 0, qty, alloc_qty end return 1, "获取物料仓库存储量失败!"..strRetInfo end -- 获取某物料的库区量表 取消 -- 返回 nRet, qty, alloc_qty -- 获取某物料的库区量表 -- 返回 nRet, qty, alloc_qty function wms_base.GetAreaInventory( strLuaDEID, area_code, item_code, item_state, item_route ) local nRet, strRetInfo local parameter if ( area_code == nil or area_code == '' ) then return 1, "wms_base.GetAreaInventory 函数中 area_code 必须有值!" end if ( item_code == nil or item_code == '' ) then return 1, "wms_base.GetAreaInventory 函数中 item_code 必须有值!" end parameter = {} parameter.area_code = area_code parameter.item_list = {} local item = {} item.item_code = item_code parameter.item_list[1] = item nRet, strRetInfo = wms.wms_GetAreaInventory( lua.table2str(parameter) ) if (nRet == 0) then local ret_info = json.decode( strRetInfo ) qty = ret_info[1].qty_storage alloc_qty = ret_info[1].qty_alloc return 0, qty, alloc_qty end return 1, "获取物料库区存储量失败!"..strRetInfo end --[[ 入库波次完成后需要把 入库波次明细中的入库数量批分 到入库明细中的 F_ACC_I_QTY,F_ACC_C_QTY 否则以入库单进行回报时会没有入库数量 输入参数: wave_no 波次号 ]] function wms_base.InboundWave_Finish_PostProce( strLuaDEID, wave_no ) local nRet, strRetInfo, n, m --lua.Debug( strLuaDEID, debug.getinfo(1), "wms_base.InboundWave_Finish_PostProce --> begin ", wave_no ) if ( lua.StrIsEmpty( wave_no ) ) then return 1, "wms_base.InboundWave_Finish_PostProce 函数中 wave_no 不能为空!" end local iw_detail_objs local strCondition = "S_WAVE_NO = '"..wave_no.."'" nRet, iw_detail_objs = m3.QueryDataObject(strLuaDEID, "IW_Detail", strCondition, "N_ROW_NO" ) if ( nRet ~= 0 ) then return 1,"QueryDataObject失败!"..iw_detail_objs end --lua.Debug( strLuaDEID, debug.getinfo(1), "2 iw_detail_objs ", iw_detail_objs ) if ( iw_detail_objs == '' ) then return 0 end -- 获取入库单明细里的数量 local inbound_order_objs nRet, inbound_order_objs = m3.QueryDataObject(strLuaDEID, "Inbound_Order", strCondition, "S_NO" ) if ( nRet ~= 0 ) then return 1,"QueryDataObject失败!"..inbound_order_objs end --lua.Debug( strLuaDEID, debug.getinfo(1), "3 inbound_order_objs ", inbound_order_objs ) if ( inbound_order_objs == '' ) then return 0 end local io_no_set = {} -- 入库单号 local obj_attrs for n = 1, #inbound_order_objs do obj_attrs = m3.KeyValueAttrsToObjAttr(inbound_order_objs[n].attrs) table.insert( io_no_set, obj_attrs.S_NO ) end --lua.Debug( strLuaDEID, debug.getinfo(1), "4 io_no_set ", io_no_set ) local io_detail_objs strCondition = "S_IO_NO IN ("..lua.strArray2string( io_no_set )..")" nRet, io_detail_objs = m3.QueryDataObject(strLuaDEID, "Inbound_Detail", strCondition, "S_ITEM_CODE" ) if ( nRet ~= 0 ) then return 1,"QueryDataObject失败!"..io_detail_objs end --lua.Debug( strLuaDEID, debug.getinfo(1), "5 io_detail_objs ", io_detail_objs ) if ( io_detail_objs == '' ) then return 0 end local nCount = #io_detail_objs local io_detail_list = {} for n = 1, nCount do obj_attrs = m3.KeyValueAttrsToObjAttr(io_detail_objs[n].attrs) local io_detail = { id = io_detail_objs[n].id, item_code = obj_attrs.S_ITEM_CODE, qty = lua.Get_NumAttrValue( obj_attrs.F_QTY ), in_qty = 0, cancel_qty = 0, ok = false } table.insert( io_detail_list, io_detail ) end --lua.Debug( strLuaDEID, debug.getinfo(1), "6 io_detail_list ", io_detail_list ) local cancel_qty, in_qty for n = 1, #iw_detail_objs do obj_attrs = m3.KeyValueAttrsToObjAttr(iw_detail_objs[n].attrs) -- 入库数量 in_qty = lua.Get_NumAttrValue( obj_attrs.F_ACC_I_QTY ) -- 取消数量 cancel_qty = lua.Get_NumAttrValue( obj_attrs.F_ACC_C_QTY ) -- 把 in_qty, cancel_qty 批分到 Inbound_Detail for m = 1, nCount do if ( io_detail_list[m].ok == false ) then if ( io_detail_list[m].item_code == obj_attrs.S_ITEM_CODE ) then -- 批分入库数量 if ( in_qty > 0 ) then x_value = io_detail_list[m].qty - io_detail_list[m].in_qty - io_detail_list[m].cancel_qty -- 可以批分的入库数量 if ( in_qty > x_value ) then qty = x_value else qty = in_qty end in_qty = in_qty - qty io_detail_list[m].in_qty = io_detail_list[m].in_qty + qty end -- 批分取消数量 if ( cancel_qty > 0 ) then x_value = io_detail_list[m].qty - io_detail_list[m].in_qty - io_detail_list[m].cancel_qty -- 可以批分的取消数量 if ( cancel_qty > x_value ) then qty = x_value else qty = cancel_qty end cancel_qty = cancel_qty - qty io_detail_list[m].cancel_qty = io_detail_list[m].cancel_qty + qty end if ( io_detail_list[m].qty == (io_detail_list[m].in_qty+io_detail_list[m].cancel_qty) ) then io_detail_list[m].ok = true end end end if ( in_qty == 0 and cancel_qty == 0 ) then break end end end --lua.Debug( strLuaDEID, debug.getinfo(1), "7 io_detail_list ", io_detail_list ) -- 更新入库单明细中的入库数量,取消数量 local strSetAttr for n = 1, nCount do strCondition = "S_ID = '"..io_detail_list[n].id.."'" strSetAttr = "F_ACC_I_QTY = "..io_detail_list[n].in_qty..", F_ACC_C_QTY = "..io_detail_list[n].cancel_qty nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Detail", strCondition, strSetAttr ) if ( nRet ~= 0 ) then return 1, "updateDataAttrByCondition(Inbound_Detail)失败"..strRetInfo end end return 0 end --[[ 出库波次完成后需要把 出库波次明细中的出库数量批分 到出库明细中的 F_ACC_O_QTY,F_ACC_C_QTY 否则以入库单进行回报时会没有入库数量 输入参数: wave_no 波次号 ]] function wms_base.OutboundWave_Finish_PostProce( strLuaDEID, wave_no ) local nRet, strRetInfo, n, m --lua.Debug( strLuaDEID, debug.getinfo(1), "wms_base.OutboundWave_Finish_PostProce --> begin ", wave_no ) if ( lua.StrIsEmpty( wave_no ) ) then return 1, "WMS_OuboundWave_Finish_PostProce 函数中 wave_no 不能为空!" end local ow_detail_objs local strCondition = "S_WAVE_NO = '"..wave_no.."'" nRet, ow_detail_objs = m3.QueryDataObject(strLuaDEID, "OW_Detail", strCondition, "N_ROW_NO" ) if ( nRet ~= 0 ) then return 1,"QueryDataObject失败!"..ow_detail_objs end --lua.Debug( strLuaDEID, debug.getinfo(1), "2 ow_detail_objs ", ow_detail_objs ) if ( ow_detail_objs == '' ) then return 0 end -- 获取出库单明细里的数量 local outbound_order_objs nRet, outbound_order_objs = m3.QueryDataObject(strLuaDEID, "Inbound_Order", strCondition, "S_NO" ) if ( nRet ~= 0 ) then return 1,"QueryDataObject失败!"..outbound_order_objs end --lua.Debug( strLuaDEID, debug.getinfo(1), "3 outbound_order_objs ", outbound_order_objs ) if ( outbound_order_objs == '' ) then return 0 end local oo_no_set = {} -- 出库单号 local obj_attrs for n = 1, #outbound_order_objs do obj_attrs = m3.KeyValueAttrsToObjAttr(outbound_order_objs[n].attrs) table.insert( oo_no_set, obj_attrs.S_NO ) end --lua.Debug( strLuaDEID, debug.getinfo(1), "4 oo_no_set ", oo_no_set ) local oo_detail_objs strCondition = "S_IO_NO IN ("..lua.strArray2string( io_no_set )..")" nRet, oo_detail_objs = m3.QueryDataObject(strLuaDEID, "Outbound_Detail", strCondition, "S_ITEM_CODE" ) if ( nRet ~= 0 ) then return 1,"QueryDataObject失败!"..oo_detail_objs end --lua.Debug( strLuaDEID, debug.getinfo(1), "5 oo_detail_objs ", oo_detail_objs ) if ( oo_detail_objs == '' ) then return 0 end local nCount = #oo_detail_objs local oo_detail_list = {} for n = 1, nCount do obj_attrs = m3.KeyValueAttrsToObjAttr(oo_detail_objs[n].attrs) local oo_detail = { id = oo_detail_objs[n].id, item_code = obj_attrs.S_ITEM_CODE, qty = lua.Get_NumAttrValue( obj_attrs.F_QTY ), out_qty = 0, cancel_qty = 0, ok = false } table.insert( oo_detail_list, oo_detail ) end --lua.Debug( strLuaDEID, debug.getinfo(1), "6 oo_detail_list ", oo_detail_list ) local cancel_qty, out_qty for n = 1, #ow_detail_objs do obj_attrs = m3.KeyValueAttrsToObjAttr(ow_detail_objs[n].attrs) -- 出库数量 out_qty = lua.Get_NumAttrValue( obj_attrs.F_ACC_O_QTY ) -- 取消数量 cancel_qty = lua.Get_NumAttrValue( obj_attrs.F_ACC_C_QTY ) -- 把 out_qty, cancel_qty 批分到 Outbound_Detail for m = 1, nCount do if ( oo_detail_list[m].ok == false ) then if ( oo_detail_list[m].item_code == obj_attrs.S_ITEM_CODE ) then -- 批分出库数量 if ( out_qty > 0 ) then x_value = oo_detail_list[m].qty - oo_detail_list[m].out_qty - oo_detail_list[m].cancel_qty -- 可以批分的出库数量 if ( out_qty > x_value ) then qty = x_value else qty = out_qty end out_qty = out_qty - qty oo_detail_list[m].out_qty = io_detail_list[m].out_qty + qty end -- 批分取消数量 if ( cancel_qty > 0 ) then x_value = oo_detail_list[m].qty - oo_detail_list[m].out_qty - oo_detail_list[m].cancel_qty -- 可以批分的取消数量 if ( cancel_qty > x_value ) then qty = x_value else qty = cancel_qty end cancel_qty = cancel_qty - qty oo_detail_list[m].cancel_qty = oo_detail_list[m].cancel_qty + qty end if ( oo_detail_list[m].qty == (oo_detail_list[m].out_qty+oo_detail_list[m].cancel_qty) ) then oo_detail_list[m].ok = true end end end if ( out_qty == 0 and cancel_qty == 0 ) then break end end end --lua.Debug( strLuaDEID, debug.getinfo(1), "7 oo_detail_list ", oo_detail_list ) -- 更新入库单明细中得入库数量,取消数量 local strSetAttr for n = 1, nCount do strCondition = "S_ID = '"..oo_detail_list[n].id.."'" strSetAttr = "F_ACC_O_QTY = "..oo_detail_list[n].out_qty..", F_ACC_C_QTY = "..oo_detail_list[n].cancel_qty nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Outbound_Detail", strCondition, strSetAttr ) if ( nRet ~= 0 ) then return 1, "updateDataAttrByCondition(Outbound_Detail)失败"..strRetInfo end end return 0 end --[[ 得到当前登录人员的账号信息,并且获取登录人员的PC MAC地址,根据这个地址获取绑定的站台 返回一个json table nRet, ret_value { login, user_name, mac, station } ]] function wms_base.Get_CurLoginUserInfo( strLuaDEID ) local nRet, strRetInfo local ret_value = {} local strUserLogin, strUserName nRet, strUserLogin, strUserName = mobox.getCurUserInfo( strLuaDEID ) if ( nRet ~= 0 ) then return 2, "获取当前操作人员信息失败! "..strUserLogin end ret_value.login = strUserLogin ret_value.user_name = strUserName ret_value.mac = "" ret_value.station = "" -- 获取当前登录账号的电脑MAC地址(如果在MBC上登录是可以获取的) nRet, strRetInfo = mobox.getCacheValue( strUserLogin, "__user_terminal__" ) if ( nRet == 0 ) then local user_terminal = json.decode( strRetInfo ) ret_value.mac = lua.Get_StrAttrValue( user_terminal.mac ) -- 根据 MAC-站台 绑定常量获取 站台 if ( ret_value.mac ~= '' ) then nRet, ret_value.station = wms_base.Get_sConst2( strLuaDEID, ret_value.mac ) if ( nRet ~= 0 ) then return 1, "系统无法获取常量'"..ret_value.mac.."'" end end end return 0, ret_value end return wms_base