--[[
|
版本: Version 2.1
|
创建日期: 2025-1-28
|
创建人: HAN
|
|
WMS-Basis-Model-Version: V15.5
|
|
功能:
|
WMS 过程中一些常用功能封装
|
|
-- Get_sConst 获取常量返回字符串类型
|
-- Get_nConst 获取常量返回数值类型
|
-- GetDictItemName 获取字典项的附加值,输入的 nItemValue 必须是数值
|
-- Warning 创建一条WMS警告信息
|
-- GetFuncArea 获取功能区定义列表
|
|
--]]
|
|
require ("wms_const")
|
wms = require ("OILua_WMS")
|
|
local wms_base = {_version = "0.2.1 "}
|
--//////////////////////////////////////////////////////常量相关///////////////////////////////////////////////////////////
|
-- 获取常量返回字符串类型 (建议用这个函数)
|
function wms_base.Get_sConst2( 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( 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( 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
|
|
-- 获取字典项的附加值,输入的 nItemValue 必须是数值
|
function wms_base.GetDictItemName2( strLuaDEID, strDictName, nItemValue )
|
local str_item_name = ''
|
local nRet
|
|
if ( nItemValue == nil ) then
|
return 1, "wms_base.GetDictItemName 的输入参数 nItemValue 必须有值!请检查 wms_base.GetDictItemName 函数的输入参数!"
|
end
|
if ( type(nItemValue) ~= "number" ) then
|
return 1, "wms_base.GetDictItemName 的输入参数 nItemValue 必须要是一个数值类型!"
|
end
|
|
nRet, str_item_name = wms.wms_GetDictTypeName( strDictName, nItemValue )
|
if ( nRet ~= 0 ) then
|
return 2, strDictName.."不存在或者字典定义中不存在值 = "..nItemValue.." 的字典项!"
|
end
|
return 0, 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
|
|
|
--[[
|
入库波次完成后需要把 入库波次明细中的入库数量批分 到入库明细中的 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( ret_value.mac )
|
if ( nRet ~= 0 ) then
|
return 1, "系统无法获取常量'"..ret_value.mac.."'"
|
end
|
end
|
end
|
|
return 0, ret_value
|
|
end
|
|
--[[
|
料箱预分配配置参数检查
|
输入参数 :
|
pac_cfg = {
|
wh_code, area_code 仓库,库区编码
|
station 站台
|
bs_type 来源类型:入库单、入库波次
|
bs_no 来源单号
|
}
|
返回:
|
1--结果 true/flase
|
2--错误信息
|
]]
|
function wms_base.PreAllocCntr_CFG_Check( pac_cfg )
|
local nRet, strRetInfo
|
|
if ( pac_cfg == nil or type( pac_cfg ) ~= "table" ) then
|
return false, "料箱预分配配置参数 pac_cfg 必须有值,必须是 table 类型!"
|
end
|
if ( lua.StrIsEmpty( pac_cfg.wh_code ) ) then
|
return false, "料箱预分配配置参数 pac_cfg 中的 wh_cod 必须有值!"
|
end
|
if ( lua.StrIsEmpty( pac_cfg.bs_type ) ) then
|
return false, "料箱预分配配置参数 pac_cfg 中的 bs_type 必须有值!"
|
end
|
if ( lua.StrIsEmpty( pac_cfg.bs_no ) ) then
|
return false, "料箱预分配配置参数 pac_cfg 中的 bs_no e必须有值!"
|
end
|
return true
|
end
|
|
--[[
|
生成查询 INV_Detail 的和 SKU 相关的查询条件
|
match_rule -- 匹配规则,如果为空只是查询 S_ITEM_CODE, S_ITEM_STATE, S_STORER
|
--]]
|
function wms_base.Get_INV_Detail_MatchSql( item, match_rule )
|
local item_sql = " a.S_ITEM_CODE = '"..item.S_ITEM_CODE.."' AND a.S_ITEM_STATE = '"..item.S_ITEM_STATE.."' AND a.S_STORER = '"..item.S_STORER.."' "
|
|
if match_rule == '' then
|
return item_sql
|
end
|
|
local seg_attrs = lua.split( match_rule, ';' )
|
for _, attr in ipairs( seg_attrs ) do
|
item_sql = item_sql.." AND a."..attr.." = '"..item[attr].."' "
|
end
|
return item_sql
|
end
|
|
--[[
|
根据分拣规则生成 查询 INV_Detail 时的 order
|
picking_rule -- 拣货规则
|
FIFO -- 先进先出,查询的是 S_WMS_BN 入库批次号
|
FILO -- 先进后出,查询的是 S_WMS_BN 入库批次号
|
FMFO -- 生产日期优先, 生产日期小的先出,查询属性 D_PRD_DATE
|
FEFO -- 有效期优先, 有效期小的先出,查询属性 D_EXP_DATE
|
SMALL_QTY -- 数量小的优先 查询 F_QTY_VALID
|
BIG_QTY -- 数量大的优先,查询 F_QTY_VALID
|
--]]
|
function wms_base.Get_INV_Detail_QueryOrder( picking_rule )
|
local order = ''
|
|
if picking_rule == '' then
|
return ""
|
end
|
|
local seg_rules = lua.split( picking_rule, ';' )
|
for _, rule in ipairs( seg_rules ) do
|
if rule == "FIFO" then
|
order = order.."a.S_WMS_BN,"
|
elseif rule == "FILO" then
|
order = order.."a.S_WMS_BN Desc,"
|
elseif rule == "FMFO" then
|
order = order.."a.D_PRD_DATE,"
|
elseif rule == "FEFO" then
|
order = order.."a.D_EXP_DATE,"
|
elseif rule == "SMALL_QTY" then
|
order = order.."a.F_QTY_VALID,"
|
elseif rule == "BIG_QTY" then
|
order = order.."a.F_QTY_VALID Desc,"
|
end
|
end
|
|
return lua.trim_laster_char( order )
|
end
|
|
function wms_base.Get_LoadingLimit( item_code, sku_grid_parm, ctd_code, cell_type )
|
if item_code == nil or item_code == '' then
|
return 1, "wms_base.Get_LoadingLimit 函数中 参数 item_code 为空!"
|
end
|
if lua.isTableEmpty( sku_grid_parm ) then
|
return 1, "SKU '"..item_code.."'中没定义料格参数或参数不合规!"
|
end
|
for _, grid_parm in ipairs( sku_grid_parm ) do
|
if grid_parm.ctd_code == ctd_code then
|
for _, cell_def in ipairs( grid_parm.cell_def ) do
|
if cell_def.cell_type == cell_type then
|
loading_limit = cell_def.loading_limit or 0
|
if loading_limit <= 0 then
|
return 1, "SKU '"..item_code.."'中没定义容器类型='"..ctd_code.."' 料格类型 = '"..cell_type.."' 的装载上限设置错误!"
|
end
|
return 0, loading_limit
|
end
|
end
|
end
|
end
|
return 1, "SKU '"..item_code.."'中没定义容器类型='"..ctd_code.."' 料格类型 = '"..cell_type.."' 的装载上限设置!"
|
end
|
|
--[[
|
获取SKU在cell_type料格中最大装载数量
|
--]]
|
function wms_base.GetSKU_LoadingLimit( sku, ctd_code, cell_type )
|
if sku == nil or cell_type == nil or ctd_code == nil or ctd_code == '' then
|
return 1, "wms_base.GetSKU_LoadingLimit 输入参数不合规!"
|
end
|
local nRet, loading_limit
|
nRet, loading_limit = wms_base.Get_LoadingLimit( sku.S_ITEM_CODE, sku.sku_grid_parm, ctd_code, cell_type )
|
|
return nRet, loading_limit
|
end
|
|
function wms_base.GetOpDefInfo( factory, op_def_name )
|
local nRet, strRetInfo
|
|
if lua.StrIsEmpty( factory ) then
|
return 1, "输入参数 factory 不能为空!"
|
end
|
if lua.StrIsEmpty( op_def_name ) then
|
return 1, "输入参数 op_def_name 不能为空!"
|
end
|
nRet, strRetInfo = wms.wms_GetOpDefInfo( factory, op_def_name )
|
if nRet ~= 0 then
|
return 2, strRetInfo
|
end
|
local op_def = json.decode( strRetInfo )
|
if op_def.hand_proc == nil then
|
op_def.hand_proc = ''
|
end
|
if op_def.putaway_rule == nil then
|
op_def.putaway_rule = ''
|
end
|
return 0, op_def
|
end
|
|
-- 获取当前登录人员所属单位标识/编码
|
function wms_base.GetMyFactory( strLuaDEID )
|
local strUserLogin, strUserName, nRet
|
nRet, strUserLogin, strUserName = mobox.getCurUserInfo( strLuaDEID )
|
if ( nRet ~= 0 ) then
|
return 2, "获取当前操作人员信息失败! "..strUserLogin
|
end
|
-- 获取当前操作人员的单位编码,作为工厂标识
|
nRet, strRetInfo = mobox.getUserSectionUnit( strUserLogin )
|
if ( nRet ~= 0 ) then
|
return 2, "获取当前操作人员所属单位失败! "..strRetInfo
|
end
|
local factory = ''
|
if ( strRetInfo ~= '' ) then
|
local orgInfo = json.decode( strRetInfo )
|
factory = orgInfo.company_code
|
end
|
if factory == '' then
|
nRet, factory = wms_base.Get_sConst2( "WMS_Default_Factory")
|
if ( nRet ~= 0 ) then
|
return 2, "系统无法获取常量'WMS_Default_Factory'"
|
end
|
end
|
return 0, factory
|
end
|
|
function wms_base.GetStrategyInfo( strategy_type, strategy_code )
|
local nRet, strRetInfo
|
local strategy = {}
|
|
nRet, strRetInfo = wms.wms_GetStrategyInfo( strategy_type, strategy_code )
|
if nRet ~= 0 then
|
return 1, "在获取'"..strategy_type.."'策略时失败! "..strRetInfo
|
end
|
local success
|
success, strategy = pcall( json.decode, strRetInfo )
|
if ( success == false ) then
|
return 200, "解析 wms_GetStrategyInfo 返回的字符串错误: --> "..strategy
|
end
|
|
return 0, strategy
|
end
|
|
-- 定义一个函数用于判断字符串末尾是否包含指定子字符串
|
local function string_end_with( str, ending )
|
-- 获取原字符串的长度
|
local strLen = #str
|
-- 获取目标子字符串的长度
|
local endingLen = #ending
|
-- 如果原字符串长度小于目标子字符串长度,直接返回 false
|
if strLen < endingLen then
|
return false
|
end
|
-- 提取原字符串末尾与目标子字符串长度相同的部分
|
local endPart = string.sub(str, -endingLen)
|
-- 比较提取的部分与目标子字符串是否相等
|
return endPart == ending
|
end
|
|
--[[
|
根据策略(上架策略/空料箱呼出策略)获取仓库,库区,巷道 等存储区域
|
输入参数
|
strategy -- 策略
|
{
|
no = "", name = "",
|
enable = 1/0,
|
detail_list = {
|
{
|
title = "xx",
|
priority = 1, enable = 1/0,
|
match_attr = {...}
|
wh_code = ""
|
area_code = ""
|
aisle_code = ""
|
loc_set = {"A","B",...}
|
}
|
}
|
}
|
input_data_attr --{"S_BATCH_NO" = "",S_UDF01="xx",...}
|
返回: 存储库区
|
storage_list = {
|
{wh_code,area_code, aisle_no, colume, layer, loc}
|
}
|
--]]
|
function wms_base.Get_Storage_Area_By_Strategy( strategy, input_data_attr )
|
local nRet, strRetInfo
|
|
if strategy == nil or type( strategy ) ~= "table" then
|
return 1, "wms_base.Get_Storage_Area_By_Strategy 函数中参数 strategy 不合规! "
|
end
|
if strategy.detail_list == nil or type( strategy.detail_list ) ~= "table" then
|
return 1, "wms_base.Get_Storage_Area_By_Strategy 函数中参数 strategy.detail_list 不合规! "
|
end
|
|
if input_data_attr == nil or type( input_data_attr ) ~= "table" then
|
return 1, "wms_base.Get_Storage_Area_By_Strategy 函数中参数 input_data_attr 不合规! "
|
end
|
|
if not strategy.enable then
|
return 1, "策略'"..strategy.no.."'没有启用!"
|
end
|
|
local match
|
local str_value, n_data_attr_value, str_data_attr_value
|
local storage_list = {}
|
|
for _, strategy_detail in ipairs( strategy.detail_list ) do
|
if strategy_detail.enable then
|
match = true
|
if strategy_detail.match_attr ~= nil and not lua.isTableEmpty( strategy_detail.match_attr ) then
|
for _, match_attr in ipairs( strategy_detail.match_attr ) do
|
str_data_attr_value = input_data_attr[match_attr.attr] or ''
|
if match_attr.type == "string" then
|
str_value = match_attr.value or ''
|
-- 等于
|
if match_attr.op == CONDITION_SYMBOL.Equals then
|
if str_value ~= str_data_attr_value then
|
match = false
|
break
|
end
|
-- 不等于
|
elseif match_attr.op == CONDITION_SYMBOL.NotEquals then
|
if str_value == str_data_attr_value then
|
match = false
|
break
|
end
|
-- 为空
|
elseif match_attr.op == CONDITION_SYMBOL.IsEmpty then
|
if str_data_attr_value ~= '' then
|
match = false
|
break
|
end
|
-- 不为空
|
elseif match_attr.op == CONDITION_SYMBOL.NotEmpty then
|
if str_data_attr_value == '' then
|
match = false
|
break
|
end
|
-- 包含
|
elseif match_attr.op == CONDITION_SYMBOL.Include then
|
if not string.find( str_data_attr_value, str_value ) then
|
match = false
|
break
|
end
|
-- 不包含
|
elseif match_attr.op == CONDITION_SYMBOL.NotInclude then
|
if string.find( str_data_attr_value, str_value ) then
|
match = false
|
break
|
end
|
-- 前面有
|
elseif match_attr.op == CONDITION_SYMBOL.FrontInclude then
|
if string.sub( str_data_attr_value, 1, #str_value ) ~= str_value then
|
match = false
|
break
|
end
|
-- 后面有
|
elseif match_attr.op == CONDITION_SYMBOL.BehindInclude then
|
if not string_end_with( str_data_attr_value, str_value ) then
|
match = false
|
break
|
end
|
end
|
elseif match_attr.type == "number" then
|
n_value = lua.Get_NumAttrValue( str_value )
|
n_data_attr_value = lua.Get_NumAttrValue( str_data_attr_value )
|
-- 等于
|
if match_attr.op == CONDITION_SYMBOL.Equals then
|
if not lua.equation( n_data_attr_value, n_value ) then
|
match = false
|
break
|
end
|
-- 不等于
|
elseif match_attr.op == CONDITION_SYMBOL.NotEquals then
|
if lua.equation( n_data_attr_value, n_value ) then
|
match = false
|
break
|
end
|
-- 大于
|
elseif match_attr.op == CONDITION_SYMBOL.Greater then
|
if n_data_attr_value <= n_value then
|
match = false
|
break
|
end
|
-- 大于等于
|
elseif match_attr.op == CONDITION_SYMBOL.GreaterOrEquals then
|
if n_data_attr_value < n_value then
|
match = false
|
break
|
end
|
-- 小于
|
elseif match_attr.op == CONDITION_SYMBOL.Less then
|
if n_data_attr_value >= n_value then
|
match = false
|
break
|
end
|
-- 小于等于
|
elseif match_attr.op == CONDITION_SYMBOL.LessOrEquals then
|
if n_data_attr_value > n_value then
|
match = false
|
break
|
end
|
end
|
elseif match_attr.type == "date" then
|
-- 等于
|
if match_attr.op == CONDITION_SYMBOL.Equals then
|
if str_data_attr_value ~= str_value then
|
match = false
|
break
|
end
|
-- 不等于
|
elseif match_attr.op == CONDITION_SYMBOL.NotEquals then
|
if str_data_attr_value == str_value then
|
match = false
|
break
|
end
|
-- 大于
|
elseif match_attr.op == CONDITION_SYMBOL.Greater then
|
if str_data_attr_value <= str_value then
|
match = false
|
break
|
end
|
-- 大于等于
|
elseif match_attr.op == CONDITION_SYMBOL.GreaterOrEquals then
|
if str_data_attr_value < str_value then
|
match = false
|
break
|
end
|
-- 小于
|
elseif match_attr.op == CONDITION_SYMBOL.Less then
|
if str_data_attr_value >= str_value then
|
match = false
|
break
|
end
|
-- 小于等于
|
elseif match_attr.op == CONDITION_SYMBOL.LessOrEquals then
|
if str_data_attr_value > str_value then
|
match = false
|
break
|
end
|
end
|
end
|
end
|
end
|
|
if match then
|
local storage = {
|
wh_code = strategy_detail.wh_code,
|
area_code = strategy_detail.area_code,
|
aisle_no = strategy_detail.aisle_code,
|
colume = strategy_detail.col_set,
|
layer = strategy_detail.layer_set,
|
location = strategy_detail.loc_set,
|
priority = strategy_detail.priority
|
}
|
table.insert( storage_list, storage)
|
end
|
end
|
end
|
|
return 0, storage_list
|
end
|
|
return wms_base
|