--[[
|
编码: GK-API-001
|
名称: 盘点计划同步
|
作者: HAN
|
日期: 2025-1-29
|
|
入口函数: SKU_Sync
|
来源项目: 国科项目
|
|
功能说明:
|
1. 接收来自上游系统的 XML 格式数据,并解析该数据, 创建SKU及SKU_UPC
|
更新:
|
2025/06/09 更新了udf01~udf04的属性变更
|
<soapenv:Envelope
|
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
<soap:Header
|
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
</soap:Header>
|
<soapenv:Body>
|
<v1:inCommodityReq
|
xmlns:v1="http://www.gkht.com/Information/INV/Ebs/Schemas/InCommodity/V1.0">
|
<v1:COMMODITY_Input>
|
<v1:RESTHeader>
|
<v1:Responsibility/>
|
<v1:RespApplication/>
|
<v1:SecurityGroup/>
|
<v1:NLSLanguage>SIMPLIFIED CHINESE</v1:NLSLanguage>
|
<v1:Org_Id>0</v1:Org_Id>
|
</v1:RESTHeader>
|
<v1:InputParameters>
|
<v1:COMMODITY_TB>
|
<!--1 or more repetitions:-->
|
<v1:COMMODITY_TB_ITEM>
|
<v1:skuId>KH32803017</v1:skuId>
|
<v1:storerId>CGKHTY</v1:storerId>
|
<v1:skuName>螺旋刀片式髓内钉</v1:skuName>
|
<v1:skuDec>螺旋刀片式股骨近端髓内钉10×170</v1:skuDec>
|
<v1:spec>JGDⅥ φ10×170</v1:spec>
|
<v1:packageCode>个</v1:packageCode>
|
<v1:packageQty>1</v1:packageQty>
|
<v1:goodsUnit>件</v1:goodsUnit>
|
<v1:length>1</v1:length>
|
<v1:width>2</v1:width>
|
<v1:height>3</v1:height>
|
<v1:abcType></v1:abcType>
|
<v1:isBatchMgr>1</v1:isBatchMgr>
|
<v1:isSnMgr>1</v1:isSnMgr>
|
<v1:isSnStorageMgr>0</v1:isSnStorageMgr>
|
<v1:imgUrl></v1:imgUrl>
|
<v1:cidtype>A</v1:cidtype>
|
<v1:productLine>KH-创伤</v1:productLine>
|
<v1:storageConditions>常温</v1:storageConditions>
|
<v1:skuType>small</v1:skuType>
|
<v1:maxCount>50</v1:maxCount>
|
<v1:sptm></v1:sptm>
|
<v1:barcode1></v1:barcode1>
|
<v1:barcode2></v1:barcode2>
|
<v1:barcode3></v1:barcode3>
|
<v1:barcode_pk></v1:barcode_pk>
|
</v1:COMMODITY_TB_ITEM>
|
</v1:COMMODITY_TB>
|
</v1:InputParameters>
|
</v1:COMMODITY_Input>
|
</v1:inCommodityReq>
|
</soapenv:Body>
|
</soapenv:Envelope>
|
|
更改记录:
|
V2.0 HAN 20250402 代码规范
|
|
V2.1 Yuanfeng
|
1. 统一了返回结果格式,使用Create_result函数创建标准化的返回结构
|
2. 优化了代码结构
|
--]] --[[
|
编码: GK-API-001
|
名称: 盘点计划同步
|
作者: HAN
|
日期: 2025-1-29
|
|
入口函数: SKU_Sync
|
来源项目: 国科项目
|
|
功能说明:
|
1. 接收来自上游系统的 XML 格式数据,并解析该数据, 创建SKU及SKU_UPC
|
|
更改记录:
|
V2.0 HAN 20250402 代码规范
|
V2.1 Yuanfeng 优化返回结果处理
|
V2.2 优化错误处理和返回逻辑
|
]] wms_base = require("wms_base")
|
xml = require("oi_base_xml")
|
mobox = require("OILua_JavelinExt")
|
m3 = require("oi_base_mobox")
|
|
-- 创建统一返回结果
|
function Create_result(flag, code, msg, error)
|
return {
|
flag = flag or "success",
|
code = code or "0",
|
message = msg or "",
|
error = error or ""
|
}
|
end
|
|
local function create_sku_upc(strLuaDEID, storer, item_code, upc_code)
|
local nRet, strRetInfo
|
if (upc_code == '' or upc_code == nil) then
|
return 0
|
end
|
|
-- 创建SKU_UPC
|
local sku_upc = m3.AllocObject(strLuaDEID, "SKU_UPC")
|
sku_upc.storer = storer
|
sku_upc.item_code = item_code
|
sku_upc.upc_code = upc_code
|
nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, sku_upc)
|
|
return nRet, strRetInfo
|
end
|
|
-- 创建/更新SKU对应的货品料箱格参数
|
-- 输入参数:strLuaDEID - 执行环境ID
|
-- skuModel - SKU数据模型(包含料格参数)
|
local function create_or_update_sku_gridbox(strLuaDEID, skuModel)
|
local nRet, strRetInfo
|
local err_msg = ''
|
|
-- 获取默认容器类型定义编码
|
local nConstRet, CONST_CTD_CODE = wms_base.Get_sConst2("WMS_Default_CNTR_Type")
|
if nConstRet ~= 0 then
|
return 1, "获取默认容器类型定义编码失败: " .. CONST_CTD_CODE
|
end
|
|
-- 检查必填字段
|
if not skuModel.item_code or not skuModel.storer then
|
return 1, "缺少必要参数: item_code或storer"
|
end
|
|
-- 设置默认料格类型
|
skuModel.ctd_code = CONST_CTD_CODE
|
skuModel.cell_type = skuModel.cell_type -- 料格类型
|
|
-- 根据商品编码(item_code)和货主(storer)以及容器类型定义编码(ctd_code)关联查询货品料箱格参数
|
local strCondition = string.format("S_ITEM_CODE = '%s' AND S_STORER = '%s' AND S_CTD_CODE='%s'", skuModel.item_code,
|
skuModel.storer, skuModel.ctd_code)
|
lua.DebugEx(strLuaDEID, "查询SKU_GridBox_Parm条件", strCondition)
|
|
local nRet, gridBoxParams = m3.GetDataObjByCondition(strLuaDEID, "SKU_GridBox_Parm", strCondition)
|
lua.DebugEx(strLuaDEID, "查询SKU_GridBox_Parm结果", gridBoxParams)
|
|
if nRet == 0 then
|
-- 记录已存在,执行更新操作
|
local update_gridbox_obj = {{
|
id = gridBoxParams.id,
|
attrs = {{
|
attr = "N_LOADING_LIMIT",
|
value = skuModel.loading_limit -- 更新容器装载上限
|
}, {
|
attr = "S_CELL_TYPE",
|
value = skuModel.cell_type -- 更新料格类型
|
}}
|
}}
|
lua.DebugEx(strLuaDEID, "准备更新SKU_GridBox_Parm属性", update_gridbox_obj)
|
nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, "SKU_GridBox_Parm", lua.table2str(update_gridbox_obj))
|
lua.DebugEx(strLuaDEID, "更新SKU_GridBox_Parm结果", nRet .. " 返回值" .. strRetInfo)
|
if nRet ~= 0 then
|
return 1, "更新SKU_GridBox_Parm属性失败: " .. strRetInfo
|
end
|
elseif nRet == 1 then
|
-- 记录不存在,创建新的料箱格参数
|
local gridbox = m3.AllocObject(strLuaDEID, "SKU_GridBox_Parm")
|
gridbox.item_code = skuModel.item_code -- 商品编码
|
gridbox.storer = skuModel.storer -- 货主
|
gridbox.ctd_code = skuModel.ctd_code -- 容器类型定义编码
|
gridbox.loading_limit = skuModel.loading_limit -- 设置容器装载上限
|
gridbox.cell_type = skuModel.cell_type -- 格类型
|
lua.DebugEx(strLuaDEID, "准备创建SKU_GridBox_Parm", gridbox)
|
nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, gridbox)
|
if nRet ~= 0 then
|
return 1, "创建SKU_GridBox_Parm失败: " .. strRetInfo
|
end
|
else
|
-- 查询出错
|
return 1, "查询SKU_GridBox_Parm时出错: " .. strRetInfo
|
end
|
return 0, strRetInfo
|
end
|
|
local function create_sku(strLuaDEID, sku_input_data)
|
local nRet, strRetInfo
|
local err_msg = ''
|
|
-- 分配SKU对象
|
local sku = m3.AllocObject(strLuaDEID, "SKU")
|
lua.DebugEx(strLuaDEID, "SKU分配对象", sku)
|
sku.item_code = sku_input_data.skuId
|
sku.storer = sku_input_data.storerId
|
sku.short_name = sku_input_data.skuName
|
sku.item_name = sku_input_data.skuDec
|
sku.spec = sku_input_data.spec
|
sku.unit = sku_input_data.goodsUnit
|
sku.long = lua.Get_NumAttrValue(sku_input_data.length) or 0
|
sku.middle = lua.Get_NumAttrValue(sku_input_data.width) or 0
|
sku.short = lua.Get_NumAttrValue(sku_input_data.height) or 0
|
sku.count_method = "Limit";
|
sku.abc_type = sku_input_data.abcType or ""
|
sku.is_life_mgt = (sku_input_data.isBatchMgr == "1" and 'Y') or 'N'
|
sku.is_sn_mgt = (sku_input_data.isSnMgr == "1" and 'Y') or 'N'
|
sku.img_url = sku_input_data.imgUrl or ""
|
sku.cell_type = sku_input_data.cidtype
|
sku.item_type = sku_input_data.skuType
|
sku.loading_limit = lua.Get_NumAttrValue(sku_input_data.maxCount) or 0
|
--- 2025/6/9 新增/更改字段
|
sku.udf01 = sku_input_data.productLine or "";
|
sku.udf03 = sku_input_data.isSnStorageMgr or ""
|
sku.udf02 = sku_input_data.storageConditions or ""
|
sku.udf04 = sku_input_data.packageCode or "";
|
sku.udf05 = lua.Get_NumAttrValue(sku_input_data.packageQty) or 0;
|
lua.DebugEx(strLuaDEID, "SKU赋值后", sku)
|
|
-- 检查SKU是否已存在
|
local id
|
local strCondition = string.format("S_ITEM_CODE = '%s' AND S_STORER = '%s'", sku.item_code, sku.storer)
|
nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "SKU", strCondition)
|
|
if nRet > 1 then
|
return 1, "检查SKU是否存在时失败: " .. strRetInfo
|
end
|
|
if nRet == 1 then
|
-- SKU不存在,创建新SKU
|
nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, sku)
|
if nRet ~= 0 then
|
return 1, "创建SKU失败: " .. strRetInfo .. " skuId = " .. sku_input_data.skuId
|
end
|
else
|
-- SKU已存在,更新属性
|
local update_sku_obj = {{
|
id = id,
|
attrs = {{
|
attr = "S_ITEM_NAME",
|
value = sku.item_name
|
}, {
|
attr = "S_SPEC",
|
value = sku.spec
|
}, {
|
attr = "S_ITEM_TYPE",
|
value = sku.item_type
|
}, {
|
attr = "S_UNIT",
|
value = sku.unit
|
}, {
|
attr = "S_SHORT_NAME",
|
value = sku.short_name
|
}, {
|
attr = "S_ABCTYPE",
|
value = sku.abc_type
|
}, {
|
attr = "C_ISSNMGT",
|
value = sku.is_sn_mgt
|
}, {
|
attr = "C_ISLIFEMGT",
|
value = sku.is_life_mgt
|
}, {
|
attr = "S_IMG_URL",
|
value = sku.img_url
|
}, {
|
attr = "S_CELL_TYPE",
|
value = sku.cell_type
|
}, {
|
attr = "N_LOADING_LIMIT",
|
value = sku.loading_limit
|
}, {
|
attr = "F_LONG",
|
value = sku.long
|
}, {
|
attr = "F_MIDDLE",
|
value = sku.middle
|
}, {
|
attr = "F_SHORT",
|
value = sku.short
|
}, {
|
attr = "S_UDF01",
|
value = sku.udf01
|
}, {
|
attr = "S_UDF02",
|
value = sku.udf02
|
}, {
|
attr = "S_UDF03",
|
value = sku.udf03
|
}, {
|
attr = "S_UDF04",
|
value = sku.udf04
|
}, {
|
attr = "S_UDF05",
|
value = sku.udf05
|
}}
|
}}
|
|
nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, "SKU", lua.table2str(update_sku_obj))
|
if nRet ~= 0 then
|
return 1, "更新SKU属性失败: " .. strRetInfo
|
end
|
end
|
|
-- 处理SKU_UPC
|
local upc_codes = {sku_input_data.sptm, sku_input_data.barcode1, sku_input_data.barcode2, sku_input_data.barcode3,
|
sku_input_data.barcode_pk, sku_input_data.upc}
|
|
for _, upc_code in ipairs(upc_codes) do
|
if upc_code and upc_code ~= '' then
|
nRet, strRetInfo = create_sku_upc(strLuaDEID, sku.storer, sku.item_code, upc_code)
|
if nRet ~= 0 then
|
return 1, "创建SKU_UPC失败: " .. strRetInfo .. " UPC: " .. upc_code
|
end
|
end
|
end
|
|
-- 处理SKU_GridBox_Parm
|
nRet, strRetInfo = create_or_update_sku_gridbox(strLuaDEID, sku)
|
if nRet ~= 0 then
|
return 1, "处理SKU_GridBox_Parm失败: " .. strRetInfo
|
end
|
|
return 0
|
end
|
|
-- Main函数
|
function SKU_Sync(strLuaDEID)
|
-- 初始化最终结果
|
local FinalRes = Create_result()
|
|
-- 1. 获取xml数据包
|
local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID)
|
if nRet ~= 0 then
|
FinalRes = Create_result("failure", "201", "无法获取数据包: " .. soap_xml)
|
local xml_result = xml.json_to_xml(FinalRes, "response")
|
mobox.returnValue(strLuaDEID, 0, xml_result, 0)
|
lua.Stop(strLuaDEID, "获取数据包失败", FinalRes)
|
return
|
end
|
|
lua.DebugEx(strLuaDEID, "获取到的数据包", soap_xml)
|
|
-- 2. 解析xml
|
local nRet, parsed_data = xml.parse(soap_xml)
|
if nRet ~= 0 then
|
FinalRes = Create_result("failure", "202", "xml格式非法")
|
local xml_result = xml.json_to_xml(FinalRes, "response")
|
mobox.returnValue(strLuaDEID, 0, xml_result, 0)
|
lua.Stop(strLuaDEID, "xml格式非法", FinalRes)
|
return
|
end
|
|
-- 3. 提取SKU数据
|
local sku_data = parsed_data.Envelope.Body.inCommodityReq.COMMODITY_Input.InputParameters.COMMODITY_TB
|
if not sku_data or not sku_data.COMMODITY_TB_ITEM then
|
FinalRes = Create_result("failure", "203", "xml数据格式错误,缺少COMMODITY_TB_ITEM")
|
local xml_result = xml.json_to_xml(FinalRes, "response")
|
mobox.returnValue(strLuaDEID, 0, xml_result, 0)
|
lua.Stop(strLuaDEID, "xml数据格式错误", FinalRes)
|
return
|
end
|
|
-- 4. 统一处理:确保sku_items是数组(即使只有一个SKU)
|
local sku_items = sku_data.COMMODITY_TB_ITEM
|
if sku_items[1] == nil then
|
sku_items = {sku_items}
|
end
|
|
-- 5. 遍历所有SKU数据
|
for i = 1, #sku_items do
|
local sku_item = sku_items[i]
|
|
-- 创建SKU及其UPC
|
local nRet, err_msg = create_sku(strLuaDEID, sku_item)
|
if nRet ~= 0 then
|
-- 记录警告日志
|
wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步SKU信息")
|
|
-- 设置错误结果并停止处理
|
FinalRes = Create_result("failure", "204", "SKU同步失败", err_msg)
|
local xml_result = xml.json_to_xml(FinalRes, "response")
|
mobox.returnValue(strLuaDEID, 0, xml_result, 0)
|
lua.Stop(strLuaDEID, "SKU同步失败: " .. sku_item.skuId, FinalRes)
|
return
|
end
|
end
|
|
-- 6. 返回成功
|
FinalRes = Create_result("success", "0", "SKU同步成功")
|
local xml_result = xml.json_to_xml(FinalRes, "response")
|
mobox.returnValue(strLuaDEID, 0, xml_result, 0)
|
end
|