--[[
|
编码: JX-API-07
|
名称: 根据出库单号新增出库单明细
|
作者: kun
|
日期: 2025-04-23
|
|
功能:
|
- 输入出库单号和ITEMS数组;
|
- 校验出库单是否存在且为新建状态;
|
- 校验ITEMS中每个物料的area_code是否与出库单一致;
|
- 全部校验通过后逐条创建明细;
|
- 中间如有失败,立即中止,报错返回。
|
输入数据格式
|
{
|
"Name": "GetOutboundDetail",
|
"Source": "ERP",
|
"Data": {
|
"S_NO": "CKD001",
|
"SourceKey": "",
|
"ITEMS": [{
|
"S_BS_NO": "12",
|
"N_BS_ROW_MO": 13,
|
"S_ITEM_CODE": "A234",
|
"S_ITEM_STATE": "O",
|
"S_SUPPLIER_NO":"",
|
"S_SUPPLIER_NAME":"",
|
"F_QTY": 10,
|
"S_EXT_ATTR1":"",
|
"S_EXT_ATTR2":"123" ,
|
"S_EXT_ATTR3":"" ,
|
"S_EXT_ATTR4":"" ,
|
"S_EXT_ATTR5":""
|
}
|
]
|
}
|
}
|
--]]
|
|
json = require("json")
|
mobox = require("OILua_JavelinExt")
|
m3 = require("oi_base_mobox")
|
|
function CreateOutboundDetail(strLuaDEID)
|
local nRet, inputData
|
local err = {}
|
|
local seen_combinations = {}
|
local duplicate_found = false
|
local duplicate_items = {}
|
|
-- 获取接口数据
|
nRet, inputData = m3.GetSysDataJson(strLuaDEID)
|
if nRet ~= 0 then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "无法获取数据包!" .. inputData,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
--local data = inputData.Data or {}
|
local s_no = inputData.S_NO
|
local items = inputData.ITEMS
|
lua.Debug(strLuaDEID, debug.getinfo(1), "s_no", s_no)
|
if not s_no or s_no == "" or #items == 0 then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "出库单号错误或无明细值:" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
-- 查询出库单状态和库区类型
|
local strCondition = " S_BS_NO = '" ..s_no.. "' "
|
local nRetl, strRetInfo = mobox.existThisData(strLuaDEID, "Outbound_Order", strCondition)
|
lua.Debug(strLuaDEID, debug.getinfo(1), "strRetInfo", strRetInfo)
|
if (nRetl ~= 0) then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "调用方法 existThisData 出错" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
if (strRetInfo ~= 'yes') then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "来源单号不存在" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
|
local strCondition = "S_BS_NO = '"..s_no.."' AND N_B_STATE <> 0 AND S_AREA_CODE = '料箱库' "
|
nRet, inbound_date = m3.QueryDataObject(strLuaDEID, "Outbound_Order", strCondition)
|
if (nRet ~= 0) then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "查询对应的出库单失败" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
if (inbound_date ~= "") then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "该来源单号对应的出库单有非新建状态,不可新增" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
local container_data, nRet
|
local Condition = "S_OO_NO IN (SELECT S_NO FROM TN_Outbound_Order WHERE S_BS_NO = '"..s_no.."') AND F_ACC_O_QTY <> 0 "
|
nRet, container_data = m3.QueryDataObject(strLuaDEID, "Outbound_Detail", Condition)
|
if (nRet ~= 0) then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "查询对应的出库单失败" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
if (container_data ~= "") then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "该来源单号对应的出库单明细有已出库的数据,不可新增" .. s_no,
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
|
for _, item in ipairs(inputData.ITEMS) do
|
local combination_key = item.S_BS_NO .. "|" .. tostring(item.N_BS_ROW_NO)
|
|
if seen_combinations[combination_key] then
|
duplicate_found = true
|
table.insert(duplicate_items, combination_key)
|
else
|
seen_combinations[combination_key] = true
|
end
|
end
|
|
if duplicate_found then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "存在重复的来源单号和行号组合: " .. table.concat(duplicate_items, ", "),
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
-- 校验ITEMS物料库区是否一致
|
for _, item in ipairs(items) do
|
|
if not item.S_ITEM_CODE or item.S_ITEM_CODE == "" then
|
table.insert(err, "商品编码不能为空")
|
elseif not item.F_QTY or item.F_QTY == 0 then
|
table.insert(err, "商品数量不能为0")
|
elseif not item.S_BS_NO or item.S_BS_NO == "" then
|
table.insert(err, "来源单号不能为空")
|
elseif not item.N_BS_ROW_MO or item.N_BS_ROW_MO == "" then
|
table.insert(err, "来源行号不能为空")
|
elseif (type(item.N_BS_ROW_MO) ~= "number") then
|
table.insert(err, "来源行号非数字类型" )
|
end
|
|
local strCondition = "S_BS_NO = '" ..item.S_BS_NO.. "' and N_BS_ROW_MO = '" ..item.N_BS_ROW_MO.. "' " -- N_BS_ROW_MO = '" ..item.N_BS_ROW_NO.. "' and
|
local nRetl, strRetInfo = mobox.existThisData(strLuaDEID, "Outbound_Detail", strCondition)
|
if (nRetl ~= 0) then
|
table.insert(err, "调用方法 existThisData 出错: " .. strRetInfo)
|
end
|
if (strRetInfo == 'yes') then
|
table.insert(err, "该物料的来源单行号已存在:" .. item.S_ITEM_CODE)
|
end
|
|
local cond_item = "S_ITEM_CODE = '" .. item.S_ITEM_CODE .. "'"
|
local nRet, itemAttrs = m3.GetDataObjByCondition(strLuaDEID, "SKU", cond_item)
|
if (nRet ~= 0 or not itemAttrs) then
|
table.insert(err, "物料不存在:" .. item.S_ITEM_CODE)
|
end
|
local item_area_code = itemAttrs.udf01
|
|
if (item_area_code == '' or item_area_code == nil) then
|
table.insert(err, "该物料库区值不存在:" .. item.S_ITEM_CODE)
|
end
|
|
end
|
|
if #err > 0 then
|
local result = {
|
SourceKey = "",
|
err_code = 1,
|
err_msg = "明细校验失败:" .. table.concat(err, ","),
|
result = nil
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
return
|
end
|
|
-- 所有通过,开始创建明细
|
for _, item in ipairs(items) do
|
|
local cond_item = "S_ITEM_CODE = '" .. item.S_ITEM_CODE .. "'"
|
local nRet, itemAttrs = m3.GetDataObjByCondition(strLuaDEID, "SKU", cond_item)
|
if (nRet ~= 0 or not itemAttrs) then
|
lua.Warning( strLuaDEID, debug.getinfo(1), "查询物料表失败: "..item.S_ITEM_CODE )
|
end
|
local item_area_code = itemAttrs.udf01
|
|
|
local cond_item = "S_BS_NO = '"..s_no.."' AND S_AREA_CODE = '" ..item_area_code.. "' "
|
local nRet, inbound_order = m3.GetDataObjByCondition(strLuaDEID, "Outbound_Order", cond_item)
|
if (nRet ~= 0 or not inbound_order) then
|
lua.Warning( strLuaDEID, debug.getinfo(1), "查询失败: "..item.S_ITEM_CODE )
|
else
|
local detail = m3.AllocObject(strLuaDEID, "Outbound_Detail")
|
detail.oo_no = inbound_order.no
|
detail.qty = item.F_QTY
|
detail.bs_no = item.S_BS_NO
|
detail.bs_row_no = item.N_BS_ROW_MO
|
detail.item_code = item.S_ITEM_CODE
|
|
detail.item_state = item.S_ITEM_STATE
|
detail.supplier = item.S_SUPPLIER_NO
|
detail.supplier_name = item.S_SUPPLIER_NAME
|
detail.item_name = itemAttrs.item_name
|
|
detail.sour_no = inputData.SourceKey
|
|
detail.ext_attr1 = item.S_EXT_ATTR1
|
detail.ext_attr2 = item.S_EXT_ATTR2
|
detail.ext_attr3 = item.S_EXT_ATTR3
|
detail.ext_attr4 = item.S_EXT_ATTR4
|
detail.ext_attr5 = item.S_EXT_ATTR5
|
|
local ret5, msg5 = m3.CreateDataObj(strLuaDEID, detail)
|
lua.Debug(strLuaDEID, debug.getinfo(1), 'detail', detail)
|
if ret5 ~= 0 then
|
lua.Stop(strLuaDEID, "创建出库单明细失败:" .. msg5)
|
return
|
end
|
end
|
end
|
|
local result = {
|
SourceKey = inputData.SourceKey or "",
|
err_code = 0,
|
err_msg = "出库单明细新增成功!",
|
result = {
|
S_NO = s_no,
|
}
|
}
|
mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
|
end
|