--[[
|
编码: AMS-21-28
|
名称:
|
作者:
|
日期:2025-05-16
|
|
函数: ClickOK
|
功能: 处理入库确认操作,按来源单号顺序分配入库数量
|
|
更改记录:
|
|
--]]
|
|
json = require ("json")
|
mobox = require ("OILua_JavelinExt")
|
m3 = require ("oi_base_mobox")
|
wms_base = require( "wms_base" )
|
wms_cntr= require( "wms_container" )
|
wms_wh = require( "wms_wh" )
|
|
function ClickOK( strLuaDEID )
|
local nRet,attrs
|
local strRetInfo
|
local strCondition
|
local strRetInfop
|
local action = {}
|
local action_arry = {}
|
|
local curTime = os.date("%Y-%m-%d %H:%M:%S")
|
local default_storer = '' -- 默认货主
|
nRet, default_storer = wms_base.Get_sConst2( "WMS_Default_Storer" )
|
if ( nRet ~= 0 ) then
|
default_storer = ''
|
end
|
|
-- 获取输入参数
|
nRet, attrs = m3.GetSysInputParameter(strLuaDEID)
|
if (nRet ~= 0) then
|
mobox.setInfo(strLuaDEID, "获取当前输入面板里的属性失败! " .. attrs)
|
return
|
end
|
|
local input_attr = m3.KeyValueAttrsToObjAttr(attrs)
|
|
local io_no = input_attr.S_IO_NO -- 入库单号
|
local item_code = input_attr.S_ITEM_CODE -- 物料编码
|
local code = input_attr.S_EXT_ATTR1 -- 货位容器号
|
local loc_code = input_attr.S_EXT_ATTR2 -- 目标货位
|
|
-- local locations = {}
|
-- if (code ~= '' ) then
|
-- for i = 1, #code do
|
-- locations[i] = code[i]
|
-- end
|
|
-- end
|
|
local loc
|
nRet, loc = wms_wh.GetLocInfo( loc_code )
|
if ( nRet ~= 0 ) then
|
return 1, "获取货位'"..loc_code.."'信息失败! "..loc
|
end
|
-- 获取"正在码盘"数据
|
local obj
|
nRet, obj = m3.GetSysDataJson(strLuaDEID)
|
if (nRet ~= 0) then
|
mobox.setInfo(strLuaDEID, "无法获取数据包!" .. obj)
|
return
|
end
|
|
local obj_code = obj[1].item_list
|
local obj_list = m3.KeyValueAttrsToObjAttr(obj_code[1].attrs)
|
|
local current_item_code = obj_list.S_ITEM_CODE
|
local current_item_name = obj_list.S_ITEM_NAME
|
|
local f_qty = tonumber(obj_list.F_QTY) or 0 -- 入库数量
|
local acc_i_qty = tonumber(lua.Get_NumAttrValue(obj_list.F_ACC_I_QTY)) or 0 -- 累计入库数量
|
local qty = tonumber(obj_list.Qty) or 0 -- 当前入库数量
|
|
local act_qty = acc_i_qty + qty -- 累计入库数量+当前入库数量
|
local f_c_qty = f_qty - act_qty -- 入库数量-累计入库数量+当前入库数量
|
|
|
if (act_qty > f_qty) then
|
lua.Stop(strLuaDEID, "当前入库数量大于可入库数量!")
|
return
|
end
|
|
-- 查询物料信息
|
local Condition = "S_ITEM_CODE = '" .. item_code .. "'"
|
nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "SKU", Condition)
|
if nRet ~= 0 then
|
mobox.setInfo(strLuaDEID, "查询 Material 表失败: " .. strRetInfo)
|
return
|
end
|
|
-- 处理货位容器
|
local code
|
strCondition = "S_LOC_CODE = '" .. loc_code .. "'"
|
local loc_Container
|
nRet, loc_Container = m3.GetDataObjByCondition(strLuaDEID, "Loc_Container", strCondition)
|
if (nRet == 0) then
|
code = loc_Container.cntr_code
|
elseif (nRet == 1) then
|
|
local Condition = "S_NAME = '虚拟容器'"
|
nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "Container_Type_Def", Condition)
|
if nRet ~= 0 then
|
mobox.setInfo(strLuaDEID, "查询 Material 表失败: " .. strRetInfo)
|
return
|
end
|
|
local ctd_code = strRetInfo.ctd_code
|
|
local container = m3.AllocObject(strLuaDEID, "Container")
|
container.virtual = 'Y'
|
container.ctd_code = ctd_code
|
local nRetl, strRetInfo = wms_cntr.CreateVirtual( strLuaDEID, container )
|
if (nRetl ~= 0) then
|
lua.Stop(strLuaDEID,"申请虚拟容器失败!!")
|
return
|
end
|
code = strRetInfo.code
|
nRet, strRetInfo = wms_wh.Loc_Container_Binding(strLuaDEID, loc_code, code, "绑定解绑方法-系统", "系统绑定")
|
if (nRet ~= 0) then
|
lua.Error(strLuaDEID, debug.getinfo(1), '货位容器绑定失败!' .. strRetInfo)
|
end
|
elseif (nRet > 1) then
|
lua.Error(strLuaDEID, debug.getinfo(1), loc_Container)
|
end
|
|
-- 构造查询条件:判断是否存在相同容器号、货位号、物料编码的记录
|
local strCondition = "S_CNTR_CODE = '" .. code .. "' and S_LOC_CODE = '" .. loc_code .. "' and S_ITEM_CODE = '" .. current_item_code .. "'"
|
local nRet, exist_detail = m3.GetDataObjByCondition(strLuaDEID, "INV_Detail", strCondition)
|
if nRet == 0 and exist_detail ~= nil then
|
-- 已存在,更新数量
|
local old_qty = tonumber(exist_detail.qty or 0)
|
local new_qty = old_qty + tonumber(qty)
|
|
local strUpdateSql = "F_QTY = " .. new_qty
|
local strUpdateCondition = "S_CNTR_CODE = '" .. code .. "' and S_LOC_CODE = '" .. loc_code .. "' and S_ITEM_CODE = '" .. current_item_code .. "'"
|
local retUpdate, strInfo = mobox.updateDataAttrByCondition(strLuaDEID, "INV_Detail", strUpdateCondition, strUpdateSql)
|
if retUpdate ~= 0 then
|
lua.Stop(strLuaDEID, "更新 CG_Detail 失败:" .. strInfo)
|
return
|
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 = code
|
inv_txn_log_data.S_LOG_TYPE = "IN"
|
inv_txn_log_data.C_SYMBOL = "+"
|
inv_txn_log_data.F_QTY = qty
|
|
inv_txn_log_data.S_ITEM_CODE = current_item_code
|
inv_txn_log_data.S_ITEM_NAME = current_item_name
|
inv_txn_log_data.S_ITEM_STATE = 'O'
|
inv_txn_log_data.S_STORER = default_storer
|
nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data )
|
if (nRet ~= 0 ) then
|
lua.Stop(strLuaDEID, "创建【库存交易日志】失败!:" .. inv_txn_log_data)
|
return
|
end
|
else
|
-- 不存在,创建新记录
|
local nRet,inv_detail_data
|
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 = code
|
inv_detail_data.T_INBOUND_TIME = curTime
|
inv_detail_data.F_QTY = qty
|
inv_detail_data.S_ITEM_CODE = current_item_code
|
inv_detail_data.S_ITEM_NAME = current_item_name
|
|
nRet, inv_detail_data = m3.CreateDataObj2(strLuaDEID, inv_detail_data )
|
if nRet ~= 0 then
|
lua.Stop(strLuaDEID, "创建 INV_Detail 失败:" .. inv_detail_data)
|
return
|
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 = code
|
inv_txn_log_data.S_LOG_TYPE = "IN"
|
inv_txn_log_data.C_SYMBOL = "+"
|
inv_txn_log_data.F_QTY = qty
|
|
inv_txn_log_data.S_ITEM_CODE = current_item_code
|
inv_txn_log_data.S_ITEM_NAME = current_item_name
|
inv_txn_log_data.S_ITEM_STATE = 'O'
|
inv_txn_log_data.S_STORER = default_storer
|
nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data )
|
if (nRet ~= 0 ) then
|
lua.Stop(strLuaDEID, "创建【库存交易日志】失败!:" .. inv_txn_log_data)
|
return
|
end
|
|
end
|
|
-- 更新入库单的状态
|
local strCondition = "S_NO = '" .. io_no .. "' "
|
local strUpdateSql = "N_B_STATE = 2"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Order", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Order", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
|
-- 更新入库单明细的状态
|
local SQLstrCondition = "S_IO_NO = '" .. io_no .. "' "
|
local strUpdateSql = "N_B_STATE = 2"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Detail", SQLstrCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Detail", SQLstrCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
|
-- 获取入库单的来源单号
|
|
nRet, strRetInfop = m3.GetDataObjByCondition(strLuaDEID, "Inbound_Order", strCondition)
|
if (nRet ~= 0) then
|
mobox.setInfo(strLuaDEID, "查询 Inbound_Order 表失败: " .. strRetInfo)
|
return
|
end
|
local bs_no = strRetInfop.bs_no
|
|
-- 查询入库单明细(按来源单号排序)
|
local container_data, nRet
|
local Condition = "S_IO_NO = '" ..io_no.."' ORDER BY S_BS_NO"
|
nRet, container_data = m3.QueryDataObject(strLuaDEID, "ERP_Inbound_Detail", Condition)
|
if (nRet ~= 0) then
|
lua.Stop(strLuaDEID, '查询入库单明细失败!!!' .. container_data)
|
return
|
end
|
|
-- 保存明细数据用于后续处理
|
local details = {}
|
for n = 1, #container_data do
|
details[n] = m3.KeyValueAttrsToObjAttr(container_data[n].attrs)
|
details[n].F_QTY = tonumber(details[n].F_QTY) or 0
|
details[n].F_ACC_I_QTY = tonumber(details[n].F_ACC_I_QTY) or 0
|
end
|
|
-- 当前需要分配的入库数量
|
local remaining_to_allocate = qty
|
|
-- 遍历所有明细,按顺序分配入库数量
|
for n = 1, #details do
|
local detail = details[n]
|
local detail_qty = detail.F_QTY
|
local detail_acc_qty = detail.F_ACC_I_QTY
|
-- 只处理当前操作的物料
|
if detail.S_ITEM_CODE == item_code then
|
-- 计算这个明细还需要入库的数量
|
local detail_remaining = detail_qty - detail_acc_qty
|
|
if detail_remaining > 0 and remaining_to_allocate > 0 then
|
-- 本次分配的数量
|
local allocate_qty = 0
|
|
if remaining_to_allocate >= detail_remaining then
|
allocate_qty = detail_remaining
|
else
|
allocate_qty = remaining_to_allocate
|
end
|
|
-- 更新累计入库数量
|
local new_acc_qty = detail_acc_qty + allocate_qty
|
remaining_to_allocate = remaining_to_allocate - allocate_qty
|
|
-- 更新条件:入库单号+来源单号+物料编码
|
local update_data = "F_ACC_I_QTY = " .. new_acc_qty
|
local update_condition = "S_IO_NO = '"..io_no.."' AND S_BS_NO = '"..detail.S_BS_NO.."' AND S_ITEM_CODE = '"..detail.S_ITEM_CODE.."'"
|
|
nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "ERP_Inbound_Detail", update_condition, update_data)
|
if nRet ~= 0 then
|
lua.Stop(strLuaDEID, '更新入库单明细失败!' .. strRetInfo)
|
return
|
end
|
|
local update_obj = "F_ACC_I_QTY = " .. new_acc_qty
|
local updatecondition = "S_IO_NO = '"..io_no.."' AND S_ITEM_CODE = '"..detail.S_ITEM_CODE.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Detail", updatecondition, update_obj)
|
if nRet ~= 0 then
|
lua.Stop(strLuaDEID, '更新入库单明细失败!' .. strRetInfo)
|
return
|
end
|
|
-- 回报上游ERP系统
|
if allocate_qty > 0 then
|
local erp_body = {
|
no = bs_no,
|
sourceOrderNo = detail.S_BS_NO,
|
sourceLineNo = tonumber(detail.N_BS_ROW_MO),
|
itemCode = detail.S_ITEM_CODE,
|
itemName = detail.S_ITEM_NAME,
|
accumulatedQty = allocate_qty,
|
ioNo = io_no,
|
locationCode = loc_code
|
}
|
|
lua.Debug(strLuaDEID, debug.getinfo(1), "回报ERP数据", erp_body)
|
|
end
|
end
|
end
|
end
|
|
-- 界面action各事件
|
action_arry[1] = {
|
action_type = "set_dlg_attr",
|
value = {
|
--{attr = "S_EXT_ATTR1", value = loc_code },
|
{attr = "S_EXT_ATTR2", value = "" }
|
}
|
}
|
action_arry [2]= {
|
action_type = "set_subtable_page_row",
|
value = {
|
page_name = "物料信息",
|
row = {
|
{
|
condition = {
|
{
|
attr = "S_ITEM_CODE",
|
value = current_item_code
|
},
|
{
|
attr = "S_ITEM_NAME",
|
value = current_item_name
|
}
|
},
|
attrs = {
|
{
|
attr = "F_ACC_I_QTY",
|
operation = "",
|
value = act_qty
|
},
|
{
|
attr = "Qty",
|
operation = "",
|
value = f_c_qty
|
},
|
}
|
}
|
}
|
}
|
}
|
|
-- 如果当前物料已全部入库,清空物料信息页面
|
if (act_qty == f_qty) then
|
action_arry[3] = {
|
action_type = "clear_subpage_rows",
|
value = {
|
page_name = "物料信息"
|
}
|
}
|
action_arry[4] = {
|
action_type = "set_dlg_attr",
|
value = {
|
{attr = "S_ITEM_CODE", value = "", enable = true},
|
{attr = "S_EXT_ATTR1", value = ""}
|
}
|
}
|
|
end
|
-- 检查是否所有明细都已入库完成
|
local inbound_detail, nRet
|
local Condition = "S_IO_NO = '" ..io_no.."' "
|
nRet, inbound_detail = m3.QueryDataObject(strLuaDEID, "ERP_Inbound_Detail", Condition)
|
if (nRet ~= 0) then
|
lua.Stop(strLuaDEID, '查询入库单明细失败!!!' .. container_data)
|
return
|
end
|
-- 检查是否所有明细都已入库完成
|
local allEqual = true
|
for n = 1, #inbound_detail do
|
local cntr_detail = m3.KeyValueAttrsToObjAttr(inbound_detail[n].attrs)
|
if lua.Get_NumAttrValue(cntr_detail.F_QTY) ~= lua.Get_NumAttrValue(cntr_detail.F_ACC_I_QTY) then
|
allEqual = false
|
break
|
end
|
end
|
|
-- 只有当所有明细的数量和累计入库数量都相等时才执行清空操作
|
if allEqual then
|
local strCondition = "S_NO = '" .. io_no .. "' "
|
local strUpdateSql = "N_B_STATE = 3"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Order", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Order", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
|
-- 更新入库单明细的状态
|
local strCondition = "S_IO_NO = '" .. io_no .. "' "
|
local strUpdateSql = "N_B_STATE = 3"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Detail", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Detail", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
|
return
|
end
|
|
-- 清空"已码盘"页面
|
action_arry[5] = {
|
action_type = "set_dlg_attr",
|
value = {
|
{attr = "S_IO_NO", value = "", enable = true}
|
}
|
}
|
end
|
|
nRet, strRetInfo = mobox.setAction(strLuaDEID, lua.table2str(action_arry))
|
if (nRet ~= 0) then
|
mobox.setInfo(strLuaDEID, "清空已码盘页面失败! " .. strRetInfo)
|
return
|
end
|
end
|