| | |
| | | --[[ |
| | | 编码: GK-API-001 |
| | | 名称: 盘点计划同步 |
| | | 作者: HAN |
| | | 作者: Yuanfeng |
| | | 日期: 2025-1-29 |
| | | |
| | | 入口函数: SKU_Sync |
| | |
| | | V2.3 移除error字段,合并到message中 |
| | | V2.4 新增SKU_GRID_PARM字段 |
| | | V2.5 2025-07-01 SKU_GRID料箱格参数优化为根据cell_type 自动同步 |
| | | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <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>BM125262</v1:skuId> |
| | | <v1:storerId>TGKHMB</v1:storerId> |
| | | <v1:skuName>Exceed ABT微孔涂层髋臼杯62mm</v1:skuName> |
| | | <v1:skuDec>Exceed ABT微孔涂层髋臼杯62mm</v1:skuDec> |
| | | <v1:spec>Acetabular Shell PC 52 x 62mm</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>501927908583</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM141234</v1:skuId> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:skuName>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuName> |
| | | <v1:skuDec>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuDec> |
| | | <v1:spec>75mm</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>.5</v1:length> |
| | | <v1:width>.5</v1:width> |
| | | <v1:height>.5</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>1</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM141234</v1:skuId> |
| | | <v1:storerId>GGKHN1</v1:storerId> |
| | | <v1:skuName>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuName> |
| | | <v1:skuDec>-</v1:skuDec> |
| | | <v1:spec>75mm</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType>C</v1:abcType> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions/> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>088030400832</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM141234</v1:skuId> |
| | | <v1:storerId>TGKHMB</v1:storerId> |
| | | <v1:skuName>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuName> |
| | | <v1:skuDec>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuDec> |
| | | <v1:spec>75mm</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>088030400832</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM141234</v1:skuId> |
| | | <v1:storerId>TGKRTH</v1:storerId> |
| | | <v1:skuName>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuName> |
| | | <v1:skuDec>-</v1:skuDec> |
| | | <v1:spec>75mm</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>088030400832</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM141234</v1:skuId> |
| | | <v1:storerId>TNMGGK</v1:storerId> |
| | | <v1:skuName>Biomet 固定十字型柄胫骨平台假体 75mm</v1:skuName> |
| | | <v1:skuDec>-</v1:skuDec> |
| | | <v1:spec>75mm</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>088030400832</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM154720</v1:skuId> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:skuName>Oxford第三代单髁膝关节骨水泥型解剖型标准胫骨底板 左膝内侧 Size B</v1:skuName> |
| | | <v1:skuDec>Oxford第三代单髁膝关节骨水泥型解剖型标准胫骨底板 左膝内侧 Size B</v1:skuDec> |
| | | <v1:spec>左膝内侧 Size B</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>501927938886</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM154720</v1:skuId> |
| | | <v1:storerId>GGKHN1</v1:storerId> |
| | | <v1:skuName>Oxford第三代单髁膝关节骨水泥型解剖型标准胫骨底板 左膝内侧 Size B</v1:skuName> |
| | | <v1:skuDec>-</v1:skuDec> |
| | | <v1:spec>左膝内侧 Size B</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType>C</v1:abcType> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions/> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>501927938886</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM154720</v1:skuId> |
| | | <v1:storerId>TGKHMB</v1:storerId> |
| | | <v1:skuName>Oxford第三代单髁膝关节骨水泥型解剖型标准胫骨底板 左膝内侧 Size B</v1:skuName> |
| | | <v1:skuDec>Oxford第三代单髁膝关节骨水泥型解剖型标准胫骨底板 左膝内侧 Size B</v1:skuDec> |
| | | <v1:spec>左膝内侧 Size B</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>501927938886</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>BM154720</v1:skuId> |
| | | <v1:storerId>TNMGGK</v1:storerId> |
| | | <v1:skuName>Oxford第三代单髁膝关节骨水泥型解剖型标准胫骨底板 左膝内侧 Size B</v1:skuName> |
| | | <v1:skuDec>-</v1:skuDec> |
| | | <v1:spec>左膝内侧 Size B</v1:spec> |
| | | <v1:packageCode>件</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>10</v1:length> |
| | | <v1:width>10</v1:width> |
| | | <v1:height>10</v1:height> |
| | | <v1:abcType/> |
| | | <v1:isBatchMgr>0</v1:isBatchMgr> |
| | | <v1:isSnMgr>0</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl/> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>BM-关节</v1:productLine> |
| | | <v1:storageConditions>是</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>120</v1:maxCount> |
| | | <v1:bMaxCount/> |
| | | <v1:cMaxCount/> |
| | | <v1:dMaxCount/> |
| | | <v1:eMaxCount/> |
| | | <v1:fMaxCount/> |
| | | <v1:upc>501927938886</v1:upc> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | </v1:COMMODITY_TB> |
| | | </v1:InputParameters> |
| | | </v1:COMMODITY_Input> |
| | | </v1:inCommodityReq> |
| | | </soapenv:Body> |
| | | </soapenv:Envelope> |
| | | |
| | | --]] wms_base = require("wms_base") |
| | | V2.6 本次更新主要针对SKU料箱格参数(SKU_GridBox_Parm)同步逻辑进行优化, |
| | | 解决了在不同cid_type变更场景下的料格处理问题,确保数据同步的准确性和完整性。 |
| | | |
| | | ]] wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | mobox = require("OILua_JavelinExt") |
| | | m3 = require("oi_base_mobox") |
| | | |
| | | -- 创建或更新SKU_UPC条码记录(重构版) |
| | | -- @param strLuaDEID: Lua数据交换ID |
| | | -- @param storer: 货主编码 |
| | | -- @param item_code: SKU编码 |
| | | -- @param upc_code: UPC条码 |
| | | -- @return: 返回两个值 (错误码, 错误信息/成功信息) |
| | | -- 创建或更新SKU_UPC条码记录(优化版) |
| | | -- @param strLuaDEID: Lua数据交换ID |
| | | -- @param storer: 货主编码 |
| | | -- @param item_code: SKU编码 |
| | | -- @param upc_code: UPC条码 |
| | | -- @return: 返回两个值 (错误码, 错误信息/成功信息) |
| | | local function create_or_update_sku_upc(strLuaDEID, storer, item_code, upc_code) |
| | | local nRet, strRetInfo |
| | | |
| | | -- 1. 检查UPC是否有效 |
| | | if not upc_code or upc_code == '' then |
| | | -- lua.debugex(strLuaDEID, "UPC为空", "货主:"..storer..", SKU:"..item_code) |
| | | return 0, "UPC为空,跳过处理" -- 修改为返回0表示跳过 |
| | | end |
| | | |
| | | -- 2. 检查该SKU的UPC记录是否已存在(三字段主键检查) |
| | | local strCondition = string.format("S_STORER = '%s' AND S_ITEM_CODE = '%s'", storer, item_code) |
| | | nRet, strRetInfo = mobox.existThisData(strLuaDEID, "SKU_UPC", strCondition) |
| | | if nRet ~= 0 then |
| | | local errMsg = "检查SKU_UPC记录失败: " .. tostring(strRetInfo) |
| | | return 1, errMsg |
| | | end |
| | | |
| | | -- 3. 处理检查结果 |
| | | if strRetInfo == 'yes' then |
| | | -- 记录已存在且完全相同,直接跳过 |
| | | local updateAttr = string.format("S_UPC_CODE='%s'", upc_code); |
| | | local nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "SKU_UPC", strCondition, updateAttr) |
| | | if (nRet ~= 0) then |
| | | return 1, "数据更新失败!" .. strRetInfo |
| | | else |
| | | lua.DebugEx(strLuaDEID, "数据更新成功....", strRetInfo) |
| | | return 0, "UPC 已更新" .. strRetInfo |
| | | end |
| | | |
| | | -- 只作为更新操作 |
| | | 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.UpdateDataObj(strLuaDEID, sku_upc) |
| | | if nRet ~= 0 then |
| | | local errMsg = "更新SKU_UPC失败: " .. tostring(strRetInfo) |
| | | return 1, errMsg |
| | | end |
| | | return 0, "SKU_UPC已存在且相同,跳过处理" |
| | | end |
| | | |
| | | -- 5. 创建新记录 |
| | | 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) |
| | | if nRet ~= 0 then |
| | | local errMsg = "创建SKU_UPC失败: " .. tostring(strRetInfo) |
| | | return 1, errMsg |
| | | end |
| | | return 0, "创建SKU_UPC成功" |
| | | end |
| | | |
| | | -- 创建/更新SKU对应的货品料箱格参数 |
| | | -- 不再依赖cell_type作为截止范围,而是检查所有maxCount~fMaxCount字段 |
| | | -- @param strLuaDEID: Lua数据交换ID |
| | | -- @param skuModel: SKU模型对象 |
| | | -- @param sku_input_data: 输入数据 |
| | | -- @return: 返回错误码和错误信息 |
| | | local function create_or_update_sku_gridbox(strLuaDEID, skuModel, sku_input_data) |
| | | local strRetInfo |
| | | |
| | | -- 1. 获取默认容器类型编码 |
| | | local nConstRet, CONST_CTD_CODE = wms_base.Get_sConst2("WMS_Default_CNTR_Type") |
| | | if nConstRet ~= 0 then |
| | | return 1, "获取默认容器类型定义编码失败: " .. CONST_CTD_CODE |
| | | end |
| | | -- 2. 定义料箱格类型与字段映射关系 |
| | | local gridbox_types = { |
| | | A = { |
| | | field = "maxCount", |
| | | value = sku_input_data.maxCount |
| | | }, |
| | | B = { |
| | | field = "bMaxCount", |
| | | value = sku_input_data.bMaxCount |
| | | }, |
| | | C = { |
| | | field = "cMaxCount", |
| | | value = sku_input_data.cMaxCount |
| | | }, |
| | | D = { |
| | | field = "dMaxCount", |
| | | value = sku_input_data.dMaxCount |
| | | }, |
| | | E = { |
| | | field = "eMaxCount", |
| | | value = sku_input_data.eMaxCount |
| | | }, |
| | | F = { |
| | | field = "fMaxCount", |
| | | value = sku_input_data.fMaxCount |
| | | } |
| | | } |
| | | -- 3. 处理所有料箱格类型 |
| | | for cell_type, type_info in pairs(gridbox_types) do |
| | | local loading_limit = lua.Get_NumAttrValue(type_info.value) or 0 |
| | | |
| | | -- 只有当限制值大于0时才处理 |
| | | if loading_limit > 0 then |
| | | -- 精确查询该类型的料箱格记录 |
| | | local strCondition = string.format( |
| | | "S_ITEM_CODE = '%s' AND S_STORER = '%s' AND S_CTD_CODE='%s' AND S_CELL_TYPE='%s'", skuModel.item_code, |
| | | skuModel.storer, CONST_CTD_CODE, cell_type) |
| | | local nRet, existing_records = m3.GetDataObjByCondition(strLuaDEID, "SKU_GridBox_Parm", strCondition) |
| | | |
| | | if nRet == 0 then |
| | | -- 记录存在,更新现有记录 |
| | | local update_gridbox_obj = {{ |
| | | id = existing_records.id, |
| | | attrs = {{ |
| | | attr = "N_LOADING_LIMIT", |
| | | value = loading_limit |
| | | }} |
| | | }} |
| | | nRet, strRetInfo = |
| | | mobox.updateDataObj(strLuaDEID, "SKU_GridBox_Parm", lua.table2str(update_gridbox_obj)) |
| | | if nRet ~= 0 then |
| | | return 1, string.format("更新%s类型料箱格属性失败: %s", cell_type, 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 = CONST_CTD_CODE |
| | | gridbox.loading_limit = loading_limit |
| | | gridbox.cell_type = cell_type |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, gridbox) |
| | | if nRet ~= 0 then |
| | | return 1, string.format("创建%s类型料箱格失败: %s", cell_type, strRetInfo) |
| | | end |
| | | else |
| | | -- 查询出错 |
| | | return 1, string.format("查询%s类型料箱格记录失败: %s", cell_type, |
| | | existing_records or "未知错误") |
| | | end |
| | | end |
| | | end |
| | | |
| | | return 0, "料箱格参数处理完成" |
| | | end |
| | | -- 创建统一返回结果(修改后版本,移除error字段) |
| | | function Create_result(flag, code, msg) |
| | | return { |
| | |
| | | |
| | | -- 创建或更新GK_PROLINE数据(生产线数据) |
| | | local function create_or_update_proline(strLuaDEID, proline_no, proline_name) |
| | | local nRet, strRetInfo |
| | | |
| | | -- 分配GK_PROLINE对象 |
| | | local proline = m3.AllocObject(strLuaDEID, "GK_PROLINE") |
| | | proline.proline_no = proline_no |
| | | proline.proline_name = proline_name |
| | | |
| | | -- 检查是否已存在 |
| | | local strCondition = string.format("S_PROLINE_NO = '%s'", proline_no) |
| | | local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "GK_PROLINE", strCondition) |
| | |
| | | value = proline_name |
| | | }} |
| | | }} |
| | | |
| | | nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, "GK_PROLINE", lua.table2str(update_proline_obj)) |
| | | if nRet ~= 0 then |
| | | return 1, "更新GK_PROLINE失败: " .. strRetInfo |
| | |
| | | return 0, strRetInfo |
| | | end |
| | | |
| | | -- 创建SKU_UPC |
| | | local function create_sku_upc(strLuaDEID, storer, item_code, upc_code) |
| | | local nRet, strRetInfo |
| | | if (upc_code == '' or upc_code == nil) then |
| | | return 0 |
| | | -- 重构后的build_sku_grid_json函数 |
| | | -- 现在完全基于数据库中的实际料格记录生成JSON |
| | | -- @param strLuaDEID: Lua数据交换ID |
| | | -- @param item_code: SKU编码 |
| | | -- @param storer: 货主编码 |
| | | -- @return: 返回两个值 (JSON字符串, 错误信息) |
| | | local function build_sku_grid_json(strLuaDEID, item_code, storer) |
| | | -- 1. 获取默认容器类型编码 |
| | | local nConstRet, CONST_CTD_CODE = wms_base.Get_sConst2("WMS_Default_CNTR_Type") |
| | | if nConstRet ~= 0 then |
| | | return "", "获取默认容器类型定义编码失败: " .. CONST_CTD_CODE |
| | | end |
| | | |
| | | 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) |
| | | -- 2. 查询该SKU所有现有的料箱格记录 |
| | | local strCondition = string.format("S_ITEM_CODE = '%s' AND S_STORER = '%s' AND S_CTD_CODE='%s'", item_code, storer, |
| | | CONST_CTD_CODE) |
| | | local nRet, grid_records = m3.QueryDataObject(strLuaDEID, "SKU_GridBox_Parm", strCondition) |
| | | |
| | | return nRet, strRetInfo |
| | | end |
| | | |
| | | |
| | | -- 新增sku_grid_parm JSON字符串,在SKU 创建的时候插入json数据 |
| | | local function build_sku_grid_parm(ctd_code, sku_input_data, cell_type) |
| | | -- 如果cell_type为空则跳过 |
| | | if not cell_type or cell_type == "" then |
| | | return "" |
| | | -- 3. 处理查询结果 |
| | | if nRet ~= 0 then |
| | | return "", "查询SKU_GridBox_Parm记录失败: " .. (grid_records or "未知错误") |
| | | end |
| | | |
| | | -- 定义基础json框架结构(放在数组中) |
| | | -- 4. 构建基础JSON结构 |
| | | local grid_def = {{ |
| | | ctd_code = ctd_code, |
| | | ctd_code = CONST_CTD_CODE, |
| | | cell_def = {} |
| | | }} |
| | | |
| | | -- 根据cell_type确定处理范围 |
| | | local types_to_process = {} |
| | | if cell_type == "A" then |
| | | types_to_process = {"A"} |
| | | elseif cell_type == "B" then |
| | | types_to_process = {"A", "B"} |
| | | elseif cell_type == "C" then |
| | | types_to_process = {"A", "B", "C"} |
| | | elseif cell_type == "D" then |
| | | types_to_process = {"A", "B", "C", "D"} |
| | | elseif cell_type == "E" then |
| | | types_to_process = {"A", "B", "C", "D", "E"} |
| | | elseif cell_type == "F" then |
| | | types_to_process = {"A", "B", "C", "D", "E", "F"} |
| | | else |
| | | -- 未知类型,默认只处理A类型 |
| | | types_to_process = {"A"} |
| | | end |
| | | -- 5. 处理查询到的记录 |
| | | if grid_records and #grid_records > 0 then |
| | | for _, record in ipairs(grid_records) do |
| | | -- 将属性数组转换为对象 |
| | | local record_obj = m3.KeyValueAttrsToObjAttr(record.attrs) |
| | | |
| | | -- 定义料箱类型与对应字段的映射 |
| | | local grid_mapping = { |
| | | A = {loading_limit = sku_input_data.maxCount}, |
| | | B = {loading_limit = sku_input_data.bMaxCount}, |
| | | C = {loading_limit = sku_input_data.cMaxCount}, |
| | | D = {loading_limit = sku_input_data.dMaxCount}, |
| | | E = {loading_limit = sku_input_data.eMaxCount}, |
| | | F = {loading_limit = sku_input_data.fMaxCount} |
| | | } |
| | | -- 提取需要的字段 |
| | | local cell_type = record_obj.S_CELL_TYPE or "" |
| | | local loading_limit = lua.Get_NumAttrValue(record_obj.N_LOADING_LIMIT) or 0 |
| | | local load_capacity = lua.Get_NumAttrValue(record_obj.F_LOAD_CAPACITY) or loading_limit -- 默认等于loading_limit |
| | | |
| | | -- 构建cell_def数组 |
| | | for _, type_key in ipairs(types_to_process) do |
| | | local grid = grid_mapping[type_key] |
| | | local limit = lua.Get_NumAttrValue(grid.loading_limit) or 0 |
| | | if limit > 0 then -- 只有当限制值大于0时才添加 |
| | | table.insert(grid_def[1].cell_def, { |
| | | cell_type = type_key, |
| | | loading_limit = limit, |
| | | load_capacity = limit |
| | | }) |
| | | end |
| | | end |
| | | |
| | | lua.DebugEx(strLuaDEID, "grid", grid_def) |
| | | return lua.table2str(grid_def) |
| | | end |
| | | |
| | | -- 创建/更新SKU对应的货品料箱格参数 |
| | | -- skuModel 是数据库定义的数据模型sku,也就是Alloc所创建的SKU对象。 |
| | | local function create_or_update_sku_gridbox(strLuaDEID, skuModel, sku_input_data) |
| | | local strRetInfo |
| | | -- 获取默认容器类型编码 |
| | | local nConstRet, CONST_CTD_CODE = wms_base.Get_sConst2("WMS_Default_CNTR_Type") |
| | | if nConstRet ~= 0 then |
| | | return 1, "获取默认容器类型定义编码失败: " .. CONST_CTD_CODE |
| | | end |
| | | |
| | | -- 如果cell_type为空则跳过 |
| | | if not skuModel.cell_type or skuModel.cell_type == "" then |
| | | return 0, "cell_type为空,跳过料箱格参数处理" |
| | | end |
| | | |
| | | -- 根据cell_type确定处理范围 |
| | | local types_to_process = {} |
| | | if skuModel.cell_type == "A" then |
| | | types_to_process = {"A"} |
| | | elseif skuModel.cell_type == "B" then |
| | | types_to_process = {"A", "B"} |
| | | elseif skuModel.cell_type == "C" then |
| | | types_to_process = {"A", "B", "C"} |
| | | elseif skuModel.cell_type == "D" then |
| | | types_to_process = {"A", "B", "C", "D"} |
| | | elseif skuModel.cell_type == "E" then |
| | | types_to_process = {"A", "B", "C", "D", "E"} |
| | | elseif skuModel.cell_type == "F" then |
| | | types_to_process = {"A", "B", "C", "D", "E", "F"} |
| | | else |
| | | -- 未知类型,默认只处理A类型 |
| | | types_to_process = {"A"} |
| | | end |
| | | |
| | | -- 定义料箱格类型与对应字段的映射 |
| | | local gridbox_types = { |
| | | A = sku_input_data.maxCount, |
| | | B = sku_input_data.bMaxCount, |
| | | C = sku_input_data.cMaxCount, |
| | | D = sku_input_data.dMaxCount, |
| | | E = sku_input_data.eMaxCount, |
| | | F = sku_input_data.fMaxCount |
| | | } |
| | | |
| | | -- 处理每种料箱格类型 |
| | | for _, type_key in ipairs(types_to_process) do |
| | | local loading_limit = lua.Get_NumAttrValue(gridbox_types[type_key]) or 0 |
| | | if loading_limit <= 0 then -- 只有当限制值大于0时才处理 |
| | | goto continue |
| | | end |
| | | |
| | | -- 精确查询该类型的料箱格记录 |
| | | local strCondition = string.format( |
| | | "S_ITEM_CODE = '%s' AND S_STORER = '%s' AND S_CTD_CODE='%s' AND S_CELL_TYPE='%s'", |
| | | skuModel.item_code, skuModel.storer, CONST_CTD_CODE, type_key) |
| | | local nRet, existing_records = m3.GetDataObjByCondition(strLuaDEID, "SKU_GridBox_Parm", strCondition) |
| | | |
| | | if nRet == 0 then |
| | | -- 更新现有记录 |
| | | local update_gridbox_obj = {{ |
| | | id = existing_records.id, |
| | | attrs = {{ |
| | | attr = "N_LOADING_LIMIT", |
| | | value = loading_limit |
| | | }} |
| | | }} |
| | | |
| | | nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, "SKU_GridBox_Parm", lua.table2str(update_gridbox_obj)) |
| | | if nRet ~= 0 then |
| | | return 1, string.format("更新%s类型料箱格属性失败: %s", type_key, strRetInfo) |
| | | -- 只有当值有效时才添加到JSON |
| | | if cell_type ~= "" and loading_limit > 0 then |
| | | table.insert(grid_def[1].cell_def, { |
| | | cell_type = cell_type, |
| | | loading_limit = loading_limit, |
| | | load_capacity = load_capacity |
| | | }) |
| | | 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 = CONST_CTD_CODE |
| | | gridbox.loading_limit = loading_limit |
| | | gridbox.cell_type = type_key |
| | | |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, gridbox) |
| | | if nRet ~= 0 then |
| | | return 1, string.format("创建%s类型料箱格失败: %s", type_key, strRetInfo) |
| | | end |
| | | else |
| | | -- 查询出错 |
| | | return 1, string.format("查询%s类型料箱格记录失败: %s", type_key, existing_records or "未知错误") |
| | | end |
| | | |
| | | ::continue:: |
| | | end |
| | | |
| | | return 0, "料箱格参数处理完成" |
| | | -- 6. 转换为JSON字符串 |
| | | local json_str = lua.table2str(grid_def) |
| | | -- -- lua.debugex(strLuaDEID, "生成的grid_json", json_str) |
| | | |
| | | return json_str |
| | | end |
| | | -- 创建或更新SKU主数据 |
| | | -- @param sku_input_data: 实际上就是报文中的:sku_data.COMMODITY_TB_ITEM 下面的字段内容 |
| | | local function create_sku(strLuaDEID, sku_input_data) |
| | | local nRet, strRetInfo |
| | | local err_msg = '' |
| | | -- 首先校验cidtype是否为空 |
| | | if not sku_input_data.cidtype or sku_input_data.cidtype == '' then |
| | | return 1, "skuId为:" .. sku_input_data.skuId .. "的适配料格cidtype不允许为空!" |
| | | end |
| | | |
| | | -- 获取系统常量 |
| | | -- 获取默认容器类型编码 |
| | | local nConstRet, CONST_CTD_CODE = wms_base.Get_sConst2("WMS_Default_CNTR_Type") |
| | | if nConstRet ~= 0 then |
| | | return 1, "获取默认容器类型定义编码失败: " .. CONST_CTD_CODE |
| | | end |
| | | -- 新增SKU_grid_param |
| | | local sku_grid_parm = build_sku_grid_parm(CONST_CTD_CODE, sku_input_data, sku_input_data.cidtype) |
| | | lua.DebugEx(strLuaDEID, "sku_grid_parm", sku_grid_parm) |
| | | if (sku_input_data.cidtype == nil or sku_input_data.cidtype == '') then |
| | | return 1, "skuId为:" .. sku_input_data.skuId .. "的适配料格cidtype不允许为空!" |
| | | end |
| | | |
| | | -- 首先检查SKU是否已存在 |
| | | local strCondition = string.format("S_ITEM_CODE = '%s' AND S_STORER = '%s'", sku_input_data.skuId, |
| | | sku_input_data.storerId) |
| | | local nRet, existing_sku = m3.GetDataObjByCondition(strLuaDEID, "SKU", strCondition) |
| | | -- lua.DebugEx(strLuaDEID, "获取条件查询:", existing_sku) |
| | | if nRet > 1 then |
| | | return 1, "检查SKU是否存在时失败: " .. (existing_sku or "未知错误") |
| | | |
| | | local existSKUnRet, existingSKU = mobox.existThisData(strLuaDEID, "SKU", strCondition) |
| | | lua.DebugEx(strLuaDEID, "检查SKU是否存在返回结果", existingSKU); |
| | | |
| | | if existSKUnRet ~= 0 then |
| | | return 1, "检查SKU是否存在时失败: " .. (existingSKU or "未知错误") |
| | | end |
| | | |
| | | -- 分配SKU对象并设置属性 |
| | | local sku = m3.AllocObject(strLuaDEID, "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.item_name = sku_input_data.skuName |
| | | sku.note = 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.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 |
| | | sku.sku_grid_parm = '[{"ctd_code":"CTD-001","cell_def":{}}]'; -- 先给个默认值 |
| | | |
| | | -- 2025-07-21 新增主表字段 |
| | | 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 |
| | | sku.sku_grid_parm = sku_grid_parm; |
| | | -- lua.DebugEx(strLuaDEID, "更新/创建数据结果:", sku) |
| | | if nRet == 1 then |
| | | -- SKU不存在,创建新记录 |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, sku) |
| | | if nRet ~= 0 then |
| | | return 1, "创建SKU失败: " .. strRetInfo .. " skuId = " .. sku_input_data.skuId |
| | | sku.udf02 = sku_input_data.registerNo or "" -- 注册证号 |
| | | sku.udf03 = sku_input_data.companyName or "" -- 生产企业 |
| | | sku.udf04 = sku_input_data.certCompanyName or "" -- 证件生产厂家 |
| | | sku.udf05 = sku_input_data.consignCompanyWTName or "" -- 委托生产厂家 |
| | | sku.udf06 = sku_input_data.sterilizationDate or "" -- 灭菌日期 |
| | | sku.udf06 = sku_input_data.ex1 or "" -- 扩展字段1 |
| | | sku.udf07 = sku_input_data.ex2 or "" -- 扩展字段2 |
| | | sku.udf08 = sku_input_data.ex3 or "" -- 扩展字段3 |
| | | -- 1. 先处理料箱格参数(确保数据库记录最新) |
| | | local nRet, strRetInfo = create_or_update_sku_gridbox(strLuaDEID, sku, sku_input_data) |
| | | if nRet ~= 0 then |
| | | return 1, "处理SKU_GridBox_Parm失败: " .. strRetInfo |
| | | end |
| | | |
| | | -- 2. 基于数据库实际记录生成JSON(不再依赖传入的cidtype) |
| | | local sku_grid_parm, err = build_sku_grid_json(strLuaDEID, sku.item_code, sku.storer) |
| | | if err then |
| | | return 1, "生成SKU_GRID_PARM失败: " .. err |
| | | end |
| | | sku.sku_grid_parm = sku_grid_parm -- 直接更新SKU对象的属性 |
| | | |
| | | -- SKU不存在,创建新记录 |
| | | if existingSKU == 'no' then |
| | | lua.DebugEx(strLuaDEID, "SKU不存在,创建新记录"); |
| | | local createnRet, strRetInfo = m3.CreateDataObj(strLuaDEID, sku) |
| | | if createnRet ~= 0 then |
| | | return 1, "创建SKU失败: 信息:" .. strRetInfo |
| | | end |
| | | else |
| | | -- SKU已存在,更新记录 |
| | | local update_sku_obj = {{ |
| | | id = existing_sku.id, |
| | | id = sku.id, |
| | | attrs = {{ |
| | | attr = "S_CTD_CODE", |
| | | value = CONST_CTD_CODE |
| | | }, { |
| | | attr = "S_ITEM_NAME", |
| | | value = sku.item_name |
| | | }, { |
| | |
| | | }, { |
| | | attr = "S_SHORT_NAME", |
| | | value = sku.short_name |
| | | }, { |
| | | attr = "S_NOTE", |
| | | value = sku.note |
| | | }, { |
| | | attr = "S_ABCTYPE", |
| | | value = sku.abc_type |
| | |
| | | attr = "S_UDF05", |
| | | value = sku.udf05 |
| | | }, { |
| | | attr = "S_UDF06", |
| | | value = sku.udf06 |
| | | }, { |
| | | attr = "S_UDF07", |
| | | value = sku.udf07 |
| | | }, { |
| | | attr = "S_UDF08", |
| | | value = sku.udf08 |
| | | }, { |
| | | attr = "S_SKU_GRID_PARM", |
| | | value = sku.sku_grid_parm |
| | | }} |
| | | }} |
| | | nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, "SKU", lua.table2str(update_sku_obj)) |
| | | -- lua.DebugEx(strLuaDEID, "更新返回值", nRet) |
| | | lua.DebugEx(strLuaDEID, "更新SKU对象结果", nRet .. " " .. strRetInfo); |
| | | 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 |
| | | -- 处理SKU_UPC条码(修改后版本) |
| | | -- 在create_sku函数中处理SKU_UPC条码的部分修改为: |
| | | local upc_code = sku_input_data.upc |
| | | if upc_code and upc_code ~= '' then |
| | | nRet, strRetInfo = create_or_update_sku_upc(strLuaDEID, sku.storer, sku.item_code, upc_code) |
| | | if nRet ~= 0 then |
| | | -- lua.debugex(strLuaDEID, "处理SKU_UPC失败", strRetInfo) |
| | | return 1, "处理SKU_UPC失败: " .. strRetInfo |
| | | end |
| | | -- lua.debugex(strLuaDEID, "处理SKU_UPC成功", upc_code) |
| | | end |
| | | |
| | | -- 处理SKU_GridBox_Parm料箱格参数 |
| | | nRet, strRetInfo = create_or_update_sku_gridbox(strLuaDEID, sku, sku_input_data) |
| | | local nRet, strRetInfo = create_or_update_sku_gridbox(strLuaDEID, sku, sku_input_data) |
| | | if nRet ~= 0 then |
| | | return 1, "处理SKU_GridBox_Parm失败: " .. strRetInfo |
| | | end |
| | | |
| | | return 0 |
| | | end |
| | | |
| | | -- Main函数 |
| | | function SKU_Sync(strLuaDEID) |
| | | m3.PrintLuaDEInfo(strLuaDEID) |
| | | -- 初始化最终结果 |
| | | local FinalRes = Create_result() |
| | | |
New file |
| | |
| | | --[[ |
| | | 编码: GK-API-01 |
| | | 名称: 货主信息同步接口 |
| | | 作者: PMN |
| | | 日期: 2025-5-20 |
| | | |
| | | 入口函数:Storer_Sync |
| | | 功能说明: |
| | | 1. 接收货主信息同步请求 |
| | | 2. 判断货主是否存在 |
| | | 3. 执行新增或修改 |
| | | 4. 返回处理结果 |
| | | |
| | | 输入XML示例: |
| | | <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:InCompanyReq |
| | | xmlns:v1="http://www.gkht.com/Information/INV/Ebs/Schemas/InCompany/V1.0"> |
| | | <v1:Company_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:COMPANY_TB> |
| | | <!--1 or more repetitions:--> |
| | | <v1:COMPANY_TB_ITEM> |
| | | <v1:companyCode>CBJJT1</v1:companyCode> |
| | | <v1:companyName>北京京泰日晟科技有限公司</v1:companyName> |
| | | <v1:contactName></v1:contactName> |
| | | <v1:contactPhone></v1:contactPhone> |
| | | <v1:contactAddress></v1:contactAddress> |
| | | <v1:memo>个</v1:memo> |
| | | </v1:COMPANY_TB_ITEM> |
| | | <v1:COMPANY_TB_ITEM> |
| | | <v1:companyCode>CBJJXK</v1:companyCode> |
| | | <v1:companyName>北京吉鑫康商贸有限公司</v1:companyName> |
| | | <v1:contactName></v1:contactName> |
| | | <v1:contactPhone></v1:contactPhone> |
| | | <v1:contactAddress></v1:contactAddress> |
| | | <v1:memo>个</v1:memo> |
| | | </v1:COMPANY_TB_ITEM> |
| | | </v1:COMPANY_TB> |
| | | </v1:InputParameters> |
| | | </v1:Company_Input> |
| | | </v1:InCompanyReq> |
| | | </soapenv:Body> |
| | | </soapenv:Envelope> |
| | | --]] |
| | | |
| | | wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | |
| | | -- 检查货主是否存在 |
| | | local function check_storer_exists(strLuaDEID, storer_item) |
| | | local storerId = storer_item.storerId |
| | | |
| | | local strCondition = string.format("S_STORER = '%s' ", storerId) |
| | | local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "STORER", strCondition) |
| | | |
| | | if nRet > 1 then |
| | | return nRet, "检查货主是否存在时出错: " .. strRetInfo |
| | | elseif nRet == 1 then |
| | | return 1, "货主不存在" -- 不存在 |
| | | else |
| | | return 0, id -- 存在 |
| | | end |
| | | end |
| | | |
| | | -- 新增货主 |
| | | local function create_storer(strLuaDEID, storer_data) |
| | | local storer = m3.AllocObject(strLuaDEID, "STORER") |
| | | local nRet1, CONST_WH = wms_base.Get_sConst2(strLuaDEID, "WMS_Default_Warehouse") |
| | | local storerCode = storer_data.storerId |
| | | -- 字段映射 |
| | | storer.storer = storerCode |
| | | storer.storer_name = storerCode |
| | | storer.company_code = storer_data.companyCode |
| | | storer.company_name = storer_data.companyName |
| | | storer.contact_name = storer_data.contactName or "" |
| | | storer.contact_phone = storer_data.contactPhone or "" |
| | | storer.contact_address = storer_data.contactAddress or "" |
| | | storer.note = storer_data.memo or "" |
| | | storer.default_wh_code = CONST_WH |
| | | |
| | | local nRet, result = m3.CreateDataObj(strLuaDEID, storer) |
| | | return nRet, result |
| | | end |
| | | |
| | | -- 更新货主信息 |
| | | local function update_storer(strLuaDEID, storer_id, storer_data) |
| | | local update_storer_obj = { |
| | | { |
| | | id = storer_id, |
| | | attrs = { |
| | | { attr = "S_COMPANY_CODE", value = storer_data.companyCode }, |
| | | { attr = "S_COMPANY_NAME", value = storer_data.companyName }, |
| | | { attr = "S_STORER_NAME", value = storer_data.companyName }, |
| | | { attr = "S_CONTACT_NAME", value = storer_data.contactName }, |
| | | { attr = "S_CONTACT_PHONE", value = storer_data.contactPhone }, |
| | | { attr = "S_CONTACT_ADDRESS", value = storer_data.contactAddress }, |
| | | { attr = "S_NOTE", value = storer_data.memo }, |
| | | } |
| | | } |
| | | } |
| | | |
| | | local nRet, result = mobox.updateDataObj( strLuaDEID, "STORER", lua.table2str(update_storer_obj) ) |
| | | return nRet, result |
| | | end |
| | | |
| | | -- 处理单个货主记录 |
| | | local function process_storer_item(strLuaDEID, storer_item) |
| | | |
| | | -- 1. 检查货主是否存在 |
| | | local nRet, result = check_storer_exists(strLuaDEID, storer_item) |
| | | if nRet > 1 then |
| | | return nRet, result |
| | | end |
| | | |
| | | -- 2. 存在则更新,不存在则新增 |
| | | if nRet == 0 then |
| | | local storer_id = result |
| | | -- 货主存在,更新信息 |
| | | nRet, result = update_storer(strLuaDEID, storer_id, storer_item) |
| | | if nRet ~= 0 then |
| | | return nRet, "更新货主信息失败: " .. tostring(result) |
| | | end |
| | | return 0, {action = "update", id = storer_id} |
| | | else |
| | | -- 货主不存在,新增 |
| | | nRet, result = create_storer(strLuaDEID, storer_item) |
| | | if nRet ~= 0 then |
| | | return nRet, "新增货主失败: " .. tostring(result) |
| | | end |
| | | return 0, {action = "create", id = result} |
| | | end |
| | | end |
| | | |
| | | function Storer_Sync(strLuaDEID) |
| | | local nRet, strRetInfo, nErr |
| | | local err_msg |
| | | nErr = 0 |
| | | local isStop = 0 |
| | | local err = {} |
| | | |
| | | -- m3.PrintLuaDEInfo(strLuaDEID) |
| | | |
| | | -- 1. 获取接口输入数据 |
| | | local soap_xml |
| | | nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if nRet ~= 0 then |
| | | lua.Stop(strLuaDEID, "无法获取数据包: " .. soap_xml) |
| | | isStop = 3 |
| | | return |
| | | end |
| | | |
| | | -- 2. 解析XML |
| | | local parsed_data |
| | | nRet, parsed_data = xml.parse(soap_xml) |
| | | if nRet ~= 0 then |
| | | lua.Stop(strLuaDEID, "接口输入的XML格式非法!") |
| | | isStop = 3 |
| | | return |
| | | end |
| | | |
| | | -- 3. 提取货主数据 |
| | | local company_data = parsed_data.Envelope.Body.InCompanyReq.Company_Input |
| | | local input_params = company_data.InputParameters |
| | | local company_tb = input_params.COMPANY_TB |
| | | |
| | | -- 处理单条或多条货主数据 |
| | | local storer_items = {} |
| | | if company_tb.COMPANY_TB_ITEM[1] ~= nil then |
| | | storer_items = company_tb.COMPANY_TB_ITEM |
| | | else |
| | | storer_items = {company_tb.COMPANY_TB_ITEM} |
| | | end |
| | | |
| | | -- 4. 处理每条货主记录 |
| | | for i, item in ipairs(storer_items) do |
| | | local storer_data = { |
| | | storerId = item.storerId, |
| | | companyCode = item.companyCode, |
| | | companyName = item.companyName, |
| | | contactName = item.contactName or "", |
| | | contactPhone = item.contactPhone or "", |
| | | contactAddress = item.contactAddress or "", |
| | | memo = item.memo or "" |
| | | } |
| | | |
| | | -- 必填字段校验 |
| | | if not storer_data.companyCode or storer_data.companyCode == "" then |
| | | err_msg = string.format("第%d条记录: companyCode不能为空", i) |
| | | wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步货主信息") |
| | | nErr = nErr + 1 |
| | | err[nErr] = err_msg |
| | | lua.Stop(strLuaDEID, err_msg) |
| | | isStop = 5 |
| | | end |
| | | |
| | | if not storer_data.companyName or storer_data.companyName == "" then |
| | | err_msg = string.format("第%d条记录: companyName不能为空", i) |
| | | wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步货主信息") |
| | | nErr = nErr + 1 |
| | | err[nErr] = err_msg |
| | | lua.Stop(strLuaDEID, err_msg) |
| | | isStop = 5 |
| | | end |
| | | |
| | | if not storer_data.storerId or storer_data.storerId == "" then |
| | | err_msg = string.format("第%d条记录: storerId不能为空", i) |
| | | wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步货主信息") |
| | | nErr = nErr + 1 |
| | | err[nErr] = err_msg |
| | | lua.Stop(strLuaDEID, err_msg) |
| | | isStop = 5 |
| | | end |
| | | |
| | | -- 处理货主记录 |
| | | nRet, result = process_storer_item(strLuaDEID, storer_data) |
| | | if nRet ~= 0 then |
| | | err_msg = result |
| | | wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步货主信息") |
| | | nErr = nErr + 1 |
| | | err[nErr] = err_msg |
| | | lua.Stop(strLuaDEID, err_msg) |
| | | isStop = 5 |
| | | end |
| | | end |
| | | |
| | | -- 5. 返回响应 |
| | | local response = { |
| | | flag = nErr > 0 and "failure" or "success", |
| | | code = nErr, |
| | | message = nErr > 0 and table.concat(err, "; ") or "处理成功", |
| | | } |
| | | |
| | | local xml_result = xml.json_to_xml(response, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, isStop) |
| | | end |
New file |
| | |
| | | --[[ |
| | | 编码: GK-API-03 |
| | | 名称: 商品批次同步接口 |
| | | 作者: yuanfeng |
| | | 日期: 2025/5/13 |
| | | 入口函数:Batch_Sync |
| | | 来源项目: 国科项目 |
| | | |
| | | 功能说明: |
| | | 1. 创建、覆盖GK_BATCH实体 |
| | | 2. 更新INV_Detail相关自定义字段 |
| | | |
| | | 变更历史: |
| | | v0.0.2 - 格式验证不通过的返回报文 |
| | | v0.0.3 - CG_Detail弃用,变更为库存表INV_Detail |
| | | v2.0 - 2025-07-16 优化代码结构,保持原有业务逻辑,统一返回格式 |
| | | v2.1 - 2025-07-16 修复SQL注入和特殊字符处理问题 |
| | | |
| | | --]] local mobox = require("OILua_JavelinExt") |
| | | local m3 = require("oi_base_mobox") |
| | | local xml = require("oi_base_xml") |
| | | local wms_base = require("wms_base") |
| | | |
| | | -- 实体标识 |
| | | local CLSID_GKbatch = "GK_BATCH" |
| | | local CLSID_INVdetail = "INV_Detail" |
| | | |
| | | -- 创建统一返回结果 |
| | | function Create_result(flag, code, msg) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "" |
| | | } |
| | | end |
| | | |
| | | -- SQL转义处理 |
| | | local function sql_escape(value) |
| | | if value == nil then |
| | | return "" |
| | | end |
| | | value = tostring(value) |
| | | -- 转义单引号、反斜杠、百分号、下划线等特殊字符 |
| | | value = string.gsub(value, "(['\\%%_])", "\\%1") |
| | | return value |
| | | end |
| | | -- 构建批次数据对象(修改consign_company_name处理) |
| | | local function buildBatchData(dataSet) |
| | | local consign_company_name = lua.Get_StrAttrValue(dataSet.consignCompanyWTName) |
| | | -- 特殊处理反斜杠 |
| | | if consign_company_name == "\\" then |
| | | consign_company_name = "\\\\" -- 将单个反斜杠转义为双反斜杠 |
| | | end |
| | | |
| | | return { |
| | | storer_no = lua.Get_StrAttrValue(dataSet.storerId), |
| | | item_code = lua.Get_StrAttrValue(dataSet.skuId), |
| | | owner_no = lua.Get_StrAttrValue(dataSet.ownerId), |
| | | wms_bn = lua.Get_StrAttrValue(dataSet.batchNo), |
| | | batch_no = lua.Get_StrAttrValue(dataSet.produceCode), |
| | | product_date = lua.Get_StrAttrValue(dataSet.productDate), |
| | | expiry_date = lua.Get_StrAttrValue(dataSet.expiryDate), |
| | | register_no = lua.Get_StrAttrValue(dataSet.registerNo), |
| | | company_name = lua.Get_StrAttrValue(dataSet.companyName), |
| | | cert_company_name = lua.Get_StrAttrValue(dataSet.certCompanyName), |
| | | consign_company_name = consign_company_name, -- 使用处理后的值 |
| | | sterilization_date = lua.Get_StrAttrValue(dataSet.sterilizationData), |
| | | note = lua.Get_StrAttrValue(dataSet.memo), |
| | | ex1 = lua.Get_StrAttrValue(dataSet.ex1), |
| | | ex2 = lua.Get_StrAttrValue(dataSet.ex2), |
| | | ex3 = lua.Get_StrAttrValue(dataSet.ex3) |
| | | } |
| | | end |
| | | |
| | | -- 创建或更新批次数据 |
| | | local function create_or_update_batch(strLuaDEID, dataSet) |
| | | -- 构建查询条件 |
| | | local strCondition = string.format("S_STORER = '%s' AND S_ITEM_CODE = '%s' AND S_OWNER = '%s' AND S_WMS_BN = '%s'", |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.storerId)), sql_escape(lua.Get_StrAttrValue(dataSet.skuId)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.ownerId)), sql_escape(lua.Get_StrAttrValue(dataSet.batchNo))) |
| | | |
| | | -- 检查批次是否存在 |
| | | local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, CLSID_GKbatch, strCondition) |
| | | |
| | | -- 构建批次数据(会调用修改后的buildBatchData) |
| | | local batch_data = buildBatchData(dataSet) |
| | | |
| | | if nRet == 0 then |
| | | -- 批次存在,更新记录 |
| | | local update_batch_obj = {{ |
| | | id = id, |
| | | attrs = {{ |
| | | attr = "S_BATCH_NO", |
| | | value = batch_data.batch_no |
| | | }, { |
| | | attr = "D_PRODUCT_DATE", |
| | | value = batch_data.product_date |
| | | }, { |
| | | attr = "D_EXPIRY_DATE", |
| | | value = batch_data.expiry_date |
| | | }, { |
| | | attr = "S_REGISTER_NO", |
| | | value = batch_data.register_no |
| | | }, { |
| | | attr = "S_COMPANY_NAME", |
| | | value = batch_data.company_name |
| | | }, { |
| | | attr = "S_CERT_COMPANY_NAME", |
| | | value = batch_data.cert_company_name |
| | | }, { |
| | | attr = "S_CONSIGN_COMPANY_NAME", |
| | | value = batch_data.consign_company_name -- 这里已经是处理过的值 |
| | | }, { |
| | | attr = "D_STERILIZATION_DATE", |
| | | value = batch_data.sterilization_date |
| | | }, { |
| | | attr = "S_NOTE", |
| | | value = batch_data.note |
| | | }, { |
| | | attr = "S_EX1", |
| | | value = batch_data.ex1 |
| | | }, { |
| | | attr = "S_EX2", |
| | | value = batch_data.ex2 |
| | | }, { |
| | | attr = "S_EX3", |
| | | value = batch_data.ex3 |
| | | }} |
| | | }} |
| | | |
| | | nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, CLSID_GKbatch, lua.table2str(update_batch_obj)) |
| | | if nRet ~= 0 then |
| | | return 1, "更新批次数据失败: " .. strRetInfo |
| | | end |
| | | elseif nRet == 1 then |
| | | -- 批次不存在,创建新记录 |
| | | local batch = m3.AllocObject(strLuaDEID, CLSID_GKbatch) |
| | | batch.storer_no = batch_data.storer_no |
| | | batch.item_code = batch_data.item_code |
| | | batch.owner_no = batch_data.owner_no |
| | | batch.wms_bn = batch_data.wms_bn |
| | | batch.batch_no = batch_data.batch_no |
| | | batch.product_date = batch_data.product_date |
| | | batch.expiry_date = batch_data.expiry_date |
| | | batch.register_no = batch_data.register_no |
| | | batch.company_name = batch_data.company_name |
| | | batch.cert_company_name = batch_data.cert_company_name |
| | | batch.consign_company_name = batch_data.consign_company_name |
| | | batch.sterilization_date = batch_data.sterilization_date |
| | | batch.note = batch_data.note |
| | | batch.ex1 = batch_data.ex1 |
| | | batch.ex2 = batch_data.ex2 |
| | | batch.ex3 = batch_data.ex3 |
| | | |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, batch) |
| | | if nRet ~= 0 then |
| | | return 1, "创建批次数据失败: " .. strRetInfo |
| | | end |
| | | else |
| | | return 1, "查询批次数据失败: " .. strRetInfo |
| | | end |
| | | |
| | | return 0 |
| | | end |
| | | |
| | | -- 更新库存明细数据 |
| | | local function update_inv_detail(strLuaDEID, dataSet) |
| | | -- 构建查询条件 |
| | | local strCondition = string.format("S_STORER = '%s' AND S_OWNER = '%s' AND S_ITEM_CODE = '%s' AND S_WMS_BN = '%s'", |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.storerId)), sql_escape(lua.Get_StrAttrValue(dataSet.ownerId)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.skuId)), sql_escape(lua.Get_StrAttrValue(dataSet.batchNo))) |
| | | |
| | | -- 构建更新字段 |
| | | local strUpdateSql = string.format("S_BATCH_NO = '%s', D_PRD_DATE = '%s', D_EXP_DATE = '%s', " .. |
| | | "S_UDF01 = '%s', S_UDF02 = '%s', S_UDF03 = '%s', " .. |
| | | "S_UDF04 = '%s', S_UDF05 = '%s', " .. |
| | | "S_UDF06 = '%s', S_UDF07 = '%s', S_UDF08 = '%s'", |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.produceCode)), sql_escape(lua.Get_StrAttrValue(dataSet.productDate)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.expiryDate)), sql_escape(lua.Get_StrAttrValue(dataSet.registerNo)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.companyName)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.certCompanyName)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.consignCompanyWTName)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.sterilizationDate)), sql_escape(lua.Get_StrAttrValue(dataSet.ex1)), |
| | | sql_escape(lua.Get_StrAttrValue(dataSet.ex2)), sql_escape(lua.Get_StrAttrValue(dataSet.ex3))) |
| | | -- 执行更新 |
| | | local nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, CLSID_INVdetail, strCondition, strUpdateSql) |
| | | if nRet ~= 0 then |
| | | return 1, "更新库存明细失败: " .. strRetInfo |
| | | end |
| | | |
| | | return 0 |
| | | end |
| | | |
| | | -- 处理单条批次数据 |
| | | local function process_batch_item(strLuaDEID, dataSet) |
| | | -- 处理批次数据 |
| | | local nRet, err_msg = create_or_update_batch(strLuaDEID, dataSet) |
| | | if nRet ~= 0 then |
| | | return 1, err_msg |
| | | end |
| | | |
| | | -- 更新库存明细 |
| | | lua.DebugEx(strLuaDEID, "准备更新的库存明细数据: ", lua.table2str(dataSet)) |
| | | nRet, err_msg = update_inv_detail(strLuaDEID, dataSet) |
| | | if nRet ~= 0 then |
| | | return 1, err_msg |
| | | end |
| | | |
| | | return 0 |
| | | end |
| | | |
| | | -- 主函数 |
| | | function Batch_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 |
| | | |
| | | -- 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. 提取批次数据 |
| | | local batch_data = parsed_data.Envelope.Body.InBatchGoodsReq.BatchGoods_Input.InputParameters.BATCHGOODS_TB |
| | | if not batch_data or not batch_data.BATCHGOODS_TB_ITEM then |
| | | FinalRes = Create_result("failure", "203", "xml数据格式错误,缺少BATCHGOODS_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. 统一处理:确保batch_items是数组 |
| | | local batch_items = batch_data.BATCHGOODS_TB_ITEM |
| | | if batch_items[1] == nil then |
| | | batch_items = {batch_items} |
| | | end |
| | | |
| | | -- 5. 遍历所有批次数据 |
| | | for i = 1, #batch_items do |
| | | local batch_item = batch_items[i] |
| | | local nRet, err_msg = process_batch_item(strLuaDEID, batch_item) |
| | | if nRet ~= 0 then |
| | | wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步批次信息") |
| | | FinalRes = Create_result("failure", "204", "批次同步失败: " .. err_msg) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "批次同步失败: " .. batch_item.batchNo, FinalRes) |
| | | return |
| | | end |
| | | end |
| | | |
| | | -- 6. 返回成功 |
| | | FinalRes = Create_result("success", "0", "批次同步成功") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | end |
New file |
| | |
| | | --[[ |
| | | 编码: GK-API-04 |
| | | 名称: GK-WMS-Receipt_Sync |
| | | 作者: 袁峰 |
| | | 入口函数:Receipt_Sync |
| | | 功能说明: 接收上游系统的XML数据,创建收货单主表(Receipt_Order)和明细记录(Receipt_Detail)。 |
| | | 输入参数: xmlData(XML格式的字符串) |
| | | 返回参数: xml 格式的响应报文: |
| | | 形如: |
| | | <response> |
| | | <message>收货单已存在</message> |
| | | <code>204</code> |
| | | <flag>failure</flag> |
| | | <error>收货单[SO2025050701]已存在</error> |
| | | </response> |
| | | |
| | | 调用示例: Receipt_Sync(xmlData) |
| | | 注意事项: 1. 输入参数xmlData为XML格式的字符串,包含了收货单主表和明细记录的数据。 |
| | | 2. 函数会解析XML数据,并将其插入到数据库中。 |
| | | 3. 允许xml 传入1条或者多条收货单主表数据,每条收货单主表数据可以包含多条收货单明细数据。 |
| | | |
| | | 变更历史: 2025-05-14 优化返回结果处理 |
| | | |
| | | XML 报文示例如下; |
| | | <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:InSmallPieceReq |
| | | xmlns:v1="http://www.gkht.com/InReceive/INV/Ebs/Schemas/InSmallPiece/V1.0"> |
| | | <v1:SmallPiece_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> |
| | | <!--1 or more repetitions:--> |
| | | <v1:SmallPiece_TB> |
| | | <v1:orderNo>SO2025050601</v1:orderNo> |
| | | <v1:asnNo>KPD00001</v1:asnNo> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:ownerId>CGKHTY</v1:ownerId> |
| | | <v1:orderDate>2025-05-06</v1:orderDate> |
| | | <v1:priority>0</v1:priority> |
| | | <v1:memo></v1:memo> |
| | | <v1:SmallPiece_TB_ITEM> |
| | | <v1:orderItemId>1</v1:orderItemId> |
| | | <v1:skuId>XR33201-2L080B</v1:skuId> |
| | | <v1:skuStatus>AVL</v1:skuStatus> |
| | | <v1:qty>2</v1:qty> |
| | | <v1:batchNo>PHI00000000000001309</v1:batchNo> |
| | | <v1:produceCode>YL201125</v1:produceCode> |
| | | <v1:productDate>2016-04-23</v1:productDate> |
| | | <v1:expiryDate>2099-12-31</v1:expiryDate> |
| | | <v1:registerNo>国食药监械(准)字2012</v1:registerNo> |
| | | </v1:SmallPiece_TB_ITEM> |
| | | <v1:SmallPiece_TB_ITEM> |
| | | <v1:orderItemId>2</v1:orderItemId> |
| | | <v1:skuId>KH32803017</v1:skuId> |
| | | <v1:skuStatus>AVL</v1:skuStatus> |
| | | <v1:qty>5</v1:qty> |
| | | <v1:batchNo>PHI00000000000001308</v1:batchNo> |
| | | <v1:produceCode>YL2011256</v1:produceCode> |
| | | <v1:productDate>2023-04-23</v1:productDate> |
| | | <v1:expiryDate>2099-12-31</v1:expiryDate> |
| | | <v1:registerNo></v1:registerNo> |
| | | </v1:SmallPiece_TB_ITEM> |
| | | </v1:SmallPiece_TB> |
| | | </v1:InputParameters> |
| | | </v1:SmallPiece_Input> |
| | | </v1:InSmallPieceReq> |
| | | </soapenv:Body> |
| | | </soapenv:Envelope> |
| | | --]] 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) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "" |
| | | } |
| | | end |
| | | function Receipt_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, "获取数据包失败", soap_xml) |
| | | 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 格式非法" .. parsed_data) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "xml格式非法", parsed_data) |
| | | return |
| | | end |
| | | |
| | | -- 3. 提取主表数据 |
| | | local receipt_data = parsed_data.Envelope.Body.InSmallPieceReq.SmallPiece_Input |
| | | local input_params = receipt_data.InputParameters |
| | | |
| | | -- 检查是否存在 SmallPiece_TB |
| | | if not input_params or not input_params.SmallPiece_TB then |
| | | FinalRes = Create_result("failure", "203", "xml 数据格式错误,缺少 SmallPiece_TB") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "xml 数据格式错误", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 4. 统一处理:确保 receipt_headers 是数组(即使只有一个主表) |
| | | local receipt_headers = input_params.SmallPiece_TB |
| | | if receipt_headers[1] == nil then |
| | | receipt_headers = {receipt_headers} |
| | | end |
| | | |
| | | -- 5. 获取系统常量 |
| | | local RetWH_COE, CONST_WH = wms_base.Get_sConst2("WMS_Default_Warehouse") |
| | | local RetFAC_COE, CONST_FACTORY = wms_base.Get_sConst2("WMS_Default_Factory") |
| | | |
| | | -- 仓库常量异常捕获 |
| | | if (RetWH_COE ~= 0) then |
| | | FinalRes = Create_result("failure", "204", "获取仓库常量失败" .. CONST_WH) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "获取系统常量:WMS_Default_Warehouse 失败", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 工厂常量异常捕获 |
| | | if (RetFAC_COE ~= 0) then |
| | | FinalRes = Create_result("failure", "204", "获取工厂常量失败" .. CONST_FACTORY) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "获取系统常量:WMS_Default_Factory", xml_result) |
| | | return |
| | | end |
| | | -- 6. 遍历所有收货单 |
| | | for i = 1, #receipt_headers do |
| | | local header = receipt_headers[i] |
| | | -- 检查收货单是否已存在 |
| | | local strCondition = string.format("S_NO = '%s'", header.orderNo) |
| | | -- lua.DEbugEx(strLuaDEID, "查询收货单条件", strCondition) |
| | | local nRet, retReceipt = m3.GetDataObjByCondition(strLuaDEID, "Receipt_Order", strCondition) |
| | | |
| | | if nRet == 0 then |
| | | -- 查询成功且找到记录,说明收货单已存在 |
| | | -- lua.DEbugEx(strLuaDEID, "查询成功,收货单已存在", retReceipt) |
| | | FinalRes = Create_result("failure", "1", "收货单[" .. header.orderNo .. "]已存在") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "收货单已存在", retReceipt) |
| | | return |
| | | elseif nRet ~= 1 then |
| | | -- 查询出错 |
| | | -- lua.DEbugEx(strLuaDEID, "查询出错", retReceipt) |
| | | FinalRes = Create_result("failure", "206", |
| | | "检查收货单[" .. header.orderNo .. "]时出错: " .. retReceipt) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "检查收货单是否存在时出错", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 创建主表数据 |
| | | local receipt = m3.AllocObject(strLuaDEID, "Receipt_Order") |
| | | receipt.no = header.orderNo |
| | | receipt.asn_no = header.asnNo |
| | | receipt.op_date = header.orderDate |
| | | receipt.priority = header.priority |
| | | receipt.note = header.memo or "" |
| | | receipt.bs_type = "SMALL_PIECE" |
| | | receipt.factory = CONST_FACTORY |
| | | receipt.wh_code = CONST_WH |
| | | |
| | | -- 检查是否已存在相同关键字的记录 |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt) |
| | | if nRet ~= 0 then |
| | | -- 再次检查是否真的存在 |
| | | local nRetCheck, retReceiptCheck = m3.GetDataObjByCondition(strLuaDEID, "Receipt_Order", strCondition) |
| | | if nRetCheck == 0 then |
| | | FinalRes = Create_result("failure", "205", "收货单[" .. header.orderNo .. "]已存在") |
| | | else |
| | | FinalRes = Create_result("failure", "207", |
| | | "收货单[" .. header.orderNo .. "]创建失败: " .. ret_info) |
| | | end |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "创建收货单主表失败", ret_info) |
| | | return |
| | | end |
| | | |
| | | -- 检查明细数据是否存在 |
| | | if header.SmallPiece_TB_ITEM == nil then |
| | | -- lua.DEbugEx(strLuaDEID, "警告:收货单 " .. header.orderNo .. " 无明细数据") |
| | | FinalRes = Create_result("failure", "208", "收货单[" .. header.orderNo .. "]无明细数据") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "收货单无明细数据", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 7. 遍历当前收货单的所有明细数据 |
| | | local details = header.SmallPiece_TB_ITEM |
| | | -- 确保 details 是数组(即使只有一个明细) |
| | | if details[1] == nil then |
| | | details = {details} |
| | | end |
| | | |
| | | for j = 1, #details do |
| | | local item = details[j] |
| | | -- 先检验skuId是否存在 |
| | | local strCondition = string.format("S_ITEM_CODE= '%s' AND S_STORER = '%s'", item.skuId, header.storerId) |
| | | -- 执行查询 |
| | | local nRet, receiptInfo = m3.GetDataObjByCondition(strLuaDEID, "SKU", strCondition) |
| | | if (nRet ~= 0) then |
| | | -- lua.DEbugEx(strLuaDEID, "SKU查询出错", |
| | | -- "ITEM_CODE: " .. item.skuId .. ", 错误信息: " .. receiptInfo) |
| | | FinalRes = Create_result("failure", "207", |
| | | "检查 SKU 是否存在时出错:SKU ID为 " .. item.skuId .. ", 错误: " .. receiptInfo) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "查询失败", xml_result) |
| | | return |
| | | elseif (receiptInfo == "") then |
| | | -- lua.DEbugEx(strLuaDEID, "查询为空", "ITEM_CODE:" .. item.skuId) |
| | | FinalRes = Create_result("failure", "208", "查询数据为空:ITEM_CODE : " .. item.skuId) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "物料数据不存在", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 创建明细数据 |
| | | local receipt_detail = m3.AllocObject(strLuaDEID, "Receipt_Detail") |
| | | receipt_detail.row_no = item.orderItemId |
| | | receipt_detail.receipt_no = header.orderNo |
| | | receipt_detail.qty = lua.Get_NumAttrValue(item.qty) or 0 |
| | | receipt_detail.acc_put_qty = lua.Get_NumAttrValue("0") |
| | | receipt_detail.acc_unq_qty = lua.Get_NumAttrValue("0") |
| | | receipt_detail.acc_c_qty = lua.Get_NumAttrValue("0") |
| | | receipt_detail.item_code = item.skuId |
| | | receipt_detail.item_state = item.skuStatus |
| | | receipt_detail.item_name = receiptInfo.item_name or "" |
| | | receipt_detail.wu = "kg" |
| | | receipt_detail.batch_no = item.produceCode |
| | | receipt_detail.wms_bn = item.batchNo |
| | | receipt_detail.prd_date = item.productDate |
| | | receipt_detail.exp_date = item.expiryDate |
| | | receipt_detail.udf01 = item.registerNo |
| | | receipt_detail.storer = header.storerId |
| | | receipt_detail.owner = header.ownerId |
| | | receipt_detail.item_name = receiptInfo.item_name or "" |
| | | receipt_detail.net_weight = receiptInfo.weight or 0 |
| | | receipt_detail.gross_weight = receiptInfo.weight or 0 |
| | | receipt_detail.uom = receiptInfo.uom or "" |
| | | |
| | | -- lua.DEbugEx(strLuaDEID, "创建明细数据:", receipt_detail) |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt_detail) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "208", "创建收货明细失败: " .. ret_info) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | -- lua.DEbugEx(strLuaDEID, "创建收货明细失败", xml_result) |
| | | lua.Stop(strLuaDEID, "创建收货明细失败", ret_info) |
| | | return |
| | | end |
| | | end |
| | | end |
| | | |
| | | -- 8. 返回成功 |
| | | FinalRes = Create_result("success", "0", "收货单创建成功") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | end |
New file |
| | |
| | | --[[ |
| | | 编码: GK-API-05 |
| | | 名称: 小件任务创建接口 |
| | | 作者: Peter fang |
| | | 日期: 2025-05-13 |
| | | |
| | | 入口函数: Inbound_Sync |
| | | 来源项目: 国科项目 |
| | | |
| | | 功能说明: |
| | | 1. 接收来自上游系统的XML格式数据,并解析该数据,创建Inbound Order及Inbound Detail |
| | | 2. 创建Inbound Palletization及Inbound Pallet Detail |
| | | ]] |
| | | |
| | | wms_base = require( "wms_base" ) |
| | | xml=require( "oi_base_xml" ) |
| | | wms_pallet = require( "wms_palletizing" ) |
| | | |
| | | -- 创建统一返回结果 |
| | | local function create_result(flag, code, msg) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "" |
| | | } |
| | | end |
| | | |
| | | local function return_value(strLuaDEID, success,err_msg) |
| | | if success==false then |
| | | lua.Stop( strLuaDEID, err_msg ) |
| | | end |
| | | local flag = "success" |
| | | local code="0" |
| | | if success==true then |
| | | flag = "success" |
| | | code="0" |
| | | else |
| | | flag = "failure" |
| | | code="1" |
| | | end |
| | | local result= create_result( flag, code, err_msg ) |
| | | local xml_result = xml.json_to_xml(result, "response") |
| | | local value=0 |
| | | if flag=="success" then |
| | | value=0 |
| | | else |
| | | value=3 |
| | | end |
| | | mobox.returnValue(strLuaDEID,1,xml_result,value) |
| | | end |
| | | |
| | | local function count_cell_list(t) |
| | | local count = 0 |
| | | for cell,group in pairs(t) do |
| | | if(cell~=nil and cell~="") then |
| | | count = count + 1 |
| | | end |
| | | end |
| | | return count |
| | | end |
| | | |
| | | local function group_by(t, key) |
| | | local result = {} |
| | | local getKey = type(key) == "function" and key or function(item) |
| | | return item[key] |
| | | end |
| | | for _, item in ipairs(t) do |
| | | local groupKey = getKey(item) |
| | | if groupKey ~= nil then |
| | | if not result[groupKey] then |
| | | result[groupKey] = {} |
| | | end |
| | | table.insert(result[groupKey], item) |
| | | end |
| | | end |
| | | return result |
| | | end |
| | | |
| | | local function goods_count(items) |
| | | local group_table = group_by(items, "skuId") |
| | | local count = 0 |
| | | for _ in pairs(group_table) do |
| | | count = count + 1 |
| | | end |
| | | return count |
| | | end |
| | | |
| | | local function sku_count(items) |
| | | local qty=0 |
| | | for _,v in ipairs(items) do |
| | | if v.qty~=nil then |
| | | qty=qty+lua.Get_NumAttrValue(v.qty) |
| | | end |
| | | end |
| | | return qty |
| | | end |
| | | |
| | | local function get_celltype(group,cid) |
| | | local spec="A" |
| | | local cellItems={} |
| | | for _,cell in ipairs(group) do |
| | | table.insert(cellItems,cell) |
| | | end |
| | | local by_cell=group_by(cellItems,"boxCode") |
| | | local cellCount=count_cell_list(by_cell) |
| | | if (cellCount==1) then |
| | | spec="A" |
| | | elseif (cellCount==2) then |
| | | spec="B" |
| | | elseif (cellCount==3) then |
| | | spec="C" |
| | | elseif (cellCount==4) then |
| | | spec="D" |
| | | elseif (cellCount==6) then |
| | | spec="E" |
| | | elseif (cellCount==8) then |
| | | spec="F" |
| | | else |
| | | return 1, "料格数量"..cellCount.. "料箱规格超出系统定义!cntr_code= "..cid |
| | | end |
| | | return 0, spec |
| | | end |
| | | |
| | | local function create_inbound_pallet(strLuaDEID,inboundData,items) |
| | | local nRet,strRetInfo |
| | | local by_pallet=group_by(items,"cid") |
| | | for cid, group in pairs(by_pallet) do |
| | | if cid~=nil and cid~="" then |
| | | if(group[1].boxCode~=nil and group[1].boxCode~="") then |
| | | local spec |
| | | nRet, spec = get_celltype(group,cid) |
| | | if nRet ~= 0 then |
| | | return 1, spec |
| | | end |
| | | local detail_item_data = {} |
| | | for _,cell in ipairs(group) do |
| | | local strTableName = "TN_SKU" |
| | | local strFieldList = '["S_UDF01"]' |
| | | local strCondition =string.format("S_STORER='%s' AND S_ITEM_CODE='%s'",inboundData.storerId,cell.skuId) |
| | | nRet, strRetInfo=mobox.queryTable(strLuaDEID,strTableName, strFieldList,1, strCondition, "") |
| | | if (nRet ~= 0) then |
| | | return 1,"查询SKU信息失败!"..strRetInfo |
| | | end |
| | | local sku_info = json.decode(strRetInfo) |
| | | if not sku_info or #sku_info == 0 then |
| | | return 1,"SKU信息不存在"..cell.skuId |
| | | end |
| | | local sudf01 = sku_info[1].S_UDF01 |
| | | |
| | | local item_detail |
| | | item_detail = m3.AllocObject2( strLuaDEID, "INB_Pallet_Detail") |
| | | item_detail.S_CNTR_CODE = cid |
| | | local seg = lua.split(cell.boxCode, '-' ) |
| | | if ( #seg ~= 2 ) then |
| | | return 1,"料格号格式错误"..cell.boxCode |
| | | end |
| | | item_detail.S_CELL_NO =spec.."-".. lua.StrToNumber(seg[2]) |
| | | item_detail.S_CELL_CODE=cell.boxCode |
| | | item_detail.S_ITEM_CODE = cell.skuId |
| | | item_detail.S_ITEM_NAME = cell.skuId |
| | | item_detail.S_ITEM_STATE=cell.skuStatus |
| | | item_detail.S_STORER=inboundData.storerId |
| | | item_detail.S_OWNER=inboundData.ownerId |
| | | item_detail.F_QTY = cell.qty |
| | | item_detail.S_UDF01=sudf01 |
| | | item_detail.S_UDF02=cell.registerNo |
| | | item_detail.S_WMS_BN = cell.batchNo |
| | | item_detail.S_BATCH_NO = cell.produceCode |
| | | item_detail.D_PRD_DATE = cell.productDate |
| | | item_detail.D_EXP_DATE = cell.expiryDate |
| | | item_detail.S_BS_TYPE="GK_IN_TASK" |
| | | item_detail.S_BS_NO=inboundData.taskId |
| | | item_detail.N_BS_ROW_NO=cell.row_no |
| | | |
| | | table.insert(detail_item_data, item_detail) |
| | | end |
| | | nRet, strRetInfo = wms_pallet.Add_INB_Pallet_Detail( strLuaDEID, cid, detail_item_data,"GK_IN_TASK",inboundData.taskId) |
| | | if nRet ~= 0 then |
| | | return 1,"生成码盘信息失败".. strRetInfo |
| | | end |
| | | end |
| | | end |
| | | end |
| | | return 0, "" |
| | | end |
| | | local function create_container(strLuaDEID,inboundData,items) |
| | | local nRet,strRetInfo |
| | | local by_pallet=group_by(items,"cid") |
| | | for cid, group in pairs(by_pallet) do |
| | | if cid~=nil and cid~="" then |
| | | if(group[1].boxCode~=nil and group[1].boxCode~="") then |
| | | local spec |
| | | nRet, spec = get_celltype(group,cid) |
| | | if nRet ~= 0 then |
| | | lua.DebugEx(strLuaDEID, "create_container", group[1].boxCode.. "cid="..cid) |
| | | return 1, spec |
| | | end |
| | | nRet, strRetInfo = wms.wms_GetConst("WMS_Default_CNTR_Type") |
| | | if (nRet ~= 0) then |
| | | return 1, "获取默认容器类型失败!"..strRetInfo |
| | | end |
| | | local container_type_info = strRetInfo |
| | | local strObjID |
| | | local strCondition =string.format("S_CODE='%s'",cid) |
| | | nRet,strObjID,strRetInfo=mobox.getDataObjAttrByKeyAttr(strLuaDEID,"Container",strCondition) |
| | | if nRet ~= 0 then |
| | | return 1,cid.."容器不存在!"..strRetInfo |
| | | end |
| | | local update_container_obj={ |
| | | { |
| | | id = strObjID, |
| | | attrs = { |
| | | { attr = "S_CTD_CODE", value =container_type_info }, -- 料箱类型 |
| | | { attr = "S_SPEC", value = spec }, -- 料箱规格 |
| | | } |
| | | }} |
| | | nRet, strRetInfo = mobox.updateDataObj( strLuaDEID, "Container", lua.table2str(update_container_obj) ) |
| | | if (nRet ~= 0 ) then |
| | | return 1,"更新【Container】属性失败!"..strRetInfo |
| | | end |
| | | end |
| | | end |
| | | end |
| | | return 0, "" |
| | | end |
| | | |
| | | local function create_inbound_detail(strLuaDEID,detail) |
| | | local nRet, strRetInfo |
| | | |
| | | local inbound_detail = m3.AllocObject( strLuaDEID,"Inbound_Detail") |
| | | inbound_detail.row_no=detail.row_no |
| | | inbound_detail.io_no=detail.io_no |
| | | inbound_detail.storer=detail.storer |
| | | inbound_detail.owner=detail.owner |
| | | inbound_detail.bs_row_no=detail.bs_row_no |
| | | inbound_detail.item_code=detail.item_code |
| | | inbound_detail.item_name=detail.item_name |
| | | inbound_detail.item_state=detail.item_state |
| | | inbound_detail.qty=detail.qty |
| | | inbound_detail.wms_bn=detail.wms_bn |
| | | inbound_detail.batch_no=detail.batch_no |
| | | inbound_detail.prd_date=detail.prd_date |
| | | inbound_detail.exp_date=detail.exp_date |
| | | inbound_detail.ext_attr1=detail.registerNo |
| | | inbound_detail.note=detail.note |
| | | |
| | | local strTableName = "TN_SKU" |
| | | local strFieldList = '["S_UDF01"]' |
| | | local strCondition =string.format("S_STORER='%s' AND S_ITEM_CODE='%s'",detail.storer,detail.item_code) |
| | | nRet, strRetInfo=mobox.queryTable(strLuaDEID,strTableName, strFieldList,1, strCondition, "") |
| | | if (nRet ~= 0) then |
| | | return 1,"查询SKU信息失败!"..strRetInfo |
| | | end |
| | | local sku_info = json.decode(strRetInfo) |
| | | if not sku_info or #sku_info == 0 then |
| | | return 1,"SKU信息不存在"..detail.item_code |
| | | end |
| | | inbound_detail.udf01 = sku_info[1].S_UDF01 |
| | | inbound_detail.udf19=detail.sn |
| | | inbound_detail.udf20=detail.cntr_code |
| | | |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, inbound_detail) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建系统入库单明细失败!"..strRetInfo.."no= "..detail.io_no |
| | | end |
| | | return 0, "" |
| | | end |
| | | |
| | | local function gk_create_inbound_detail(strLuaDEID,inboundData, inboundItem,index) |
| | | local nRet, strRetInfo |
| | | |
| | | local inbound_detail = m3.AllocObject( strLuaDEID,"GK_IN_TASK_Detail") |
| | | inbound_detail.row_no=index |
| | | inbound_detail.io_no=inboundData.taskId |
| | | inbound_detail.storer=inboundData.storerId |
| | | inbound_detail.owner=inboundData.ownerId |
| | | inbound_detail.bs_row_no=inboundItem.orderItemId |
| | | inbound_detail.item_code=inboundItem.skuId |
| | | inbound_detail.item_name=inboundItem.skuId |
| | | inbound_detail.item_state=inboundItem.skuStatus |
| | | inbound_detail.qty=lua.Get_NumAttrValue(inboundItem.qty) |
| | | inbound_detail.wms_bn=inboundItem.batchNo |
| | | inbound_detail.batch_no=inboundItem.produceCode |
| | | inbound_detail.prd_date=inboundItem.productDate |
| | | inbound_detail.exp_date=inboundItem.expiryDate |
| | | inbound_detail.register_no=inboundItem.registerNo |
| | | inbound_detail.cntr_code=inboundItem.cid |
| | | inbound_detail.cell_no=inboundItem.boxCode |
| | | inbound_detail.sn=inboundItem.sn |
| | | |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, inbound_detail) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建入库单明细失败!"..strRetInfo.."no= "..inboundData.taskId |
| | | end |
| | | |
| | | if inboundItem.boxCode==nil or inboundItem.boxCode=="" then |
| | | nRet, strRetInfo=create_inbound_detail(strLuaDEID,inbound_detail) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建系统入库单明细失败!"..strRetInfo.."no= "..inboundData.taskId |
| | | end |
| | | end |
| | | |
| | | return 0, "" |
| | | end |
| | | |
| | | local function create_inbound(strLuaDEID, gk_inbound) |
| | | local nRet, strRetInfo |
| | | |
| | | local inbound = m3.AllocObject( strLuaDEID,"Inbound_Order") |
| | | inbound.no=gk_inbound.no |
| | | inbound.b_state=0 |
| | | inbound.factory=gk_inbound.factory |
| | | inbound.wh_code=gk_inbound.wh_code |
| | | inbound.bs_type=gk_inbound.bs_type |
| | | inbound.bs_no=gk_inbound.bs_no |
| | | inbound.asn_no=gk_inbound.asn_no |
| | | inbound.op_date=gk_inbound.op_date |
| | | inbound.priority=gk_inbound.priority |
| | | inbound.note=gk_inbound.note |
| | | |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, inbound) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建系统入库单失败!"..strRetInfo.."no= "..gk_inbound.no |
| | | end |
| | | |
| | | return 0,"" |
| | | end |
| | | |
| | | local function gk_create_inbound(strLuaDEID, inboundData,emptyCellCount) |
| | | local nRet, strRetInfo |
| | | |
| | | local inbound = m3.AllocObject( strLuaDEID,"GK_IN_TASK") |
| | | inbound.no=inboundData.taskId |
| | | inbound.b_state=0 |
| | | nRet, strRetInfo = wms.wms_GetConst("WMS_Default_Factory") |
| | | if (nRet ~= 0) then |
| | | return 1, "获取默认工厂失败!"..strRetInfo |
| | | end |
| | | inbound.factory=strRetInfo |
| | | nRet, strRetInfo = wms.wms_GetConst("WMS_Default_Warehouse") |
| | | if (nRet ~= 0) then |
| | | return 1, "获取默认仓库失败!"..strRetInfo |
| | | end |
| | | inbound.wh_code=strRetInfo |
| | | inbound.bs_type=inboundData.taskType |
| | | inbound.bs_no=inboundData.orderNo |
| | | inbound.asn_no=inboundData.asnNo |
| | | inbound.op_date=inboundData.orderDate |
| | | inbound.priority=inboundData.priority |
| | | inbound.source_no=inboundData.sourceBillNo |
| | | inbound.note=inboundData.memo |
| | | |
| | | local detailItems = inboundData.TaskCreation_TB_ITEM |
| | | local items={} |
| | | if detailItems==nil then |
| | | return 1, "入库单明细为空" |
| | | end |
| | | if detailItems[1]==nil then |
| | | items={detailItems} |
| | | else |
| | | items=detailItems |
| | | end |
| | | if items==nil or items[1]==nil then |
| | | return 1, "入库单明细为空" |
| | | else |
| | | local index=1 |
| | | for index, item in ipairs(items) do |
| | | --创建入库单明细 |
| | | item.row_no=index |
| | | nRet, strRetInfo = gk_create_inbound_detail(strLuaDEID,inboundData,item,index) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建入库单明细失败!"..strRetInfo.."no= "..inboundData.taskId |
| | | end |
| | | end |
| | | end |
| | | |
| | | inbound.good_type_num=goods_count(items) |
| | | inbound.total_qty=sku_count(items) |
| | | nRet, inbound = m3.CreateDataObj(strLuaDEID, inbound) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建入库单失败!"..inbound.."no= "..inboundData.taskId |
| | | end |
| | | |
| | | --创建系统入库单 |
| | | if emptyCellCount>0 then |
| | | nRet, strRetInfo =create_inbound(strLuaDEID,inbound) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建系统入库单失败!"..strRetInfo.."no= "..inboundData.taskId |
| | | end |
| | | end |
| | | |
| | | --创建入库单码盘 |
| | | nRet, strRetInfo =create_inbound_pallet(strLuaDEID,inboundData,items) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建码盘明细失败!"..strRetInfo.."no= "..inboundData.taskId |
| | | end |
| | | |
| | | --创建容器料格信息 |
| | | nRet, strRetInfo = create_container(strLuaDEID,inboundData,items) |
| | | if (nRet==nil or nRet ~= 0 ) then |
| | | return 1, "创建容器失败!"..strRetInfo.."no= "..inboundData.taskId |
| | | end |
| | | |
| | | return 0,"" |
| | | end |
| | | |
| | | function Inbound_Sync(strLuaDEID) |
| | | local nRet, strRetInfo |
| | | local err_msg |
| | | |
| | | --m3.PrintLuaDEInfo(strLuaDEID) |
| | | |
| | | local soap_xml |
| | | nRet,soap_xml=mobox.getCurEditDataPacket(strLuaDEID) |
| | | if ( nRet ~=0 ) then |
| | | return_value(strLuaDEID, false, "无法获取数据包 !"..soap_xml) |
| | | return |
| | | end |
| | | local parsed_data |
| | | nRet, parsed_data = xml.parse(soap_xml) |
| | | if ( nRet ~= 0 ) then |
| | | return_value(strLuaDEID, false, "接口输入的XML格式非法!") |
| | | return |
| | | end |
| | | |
| | | local inboundItems=parsed_data.Envelope.Body.InTaskCreationReq.TaskCreation_Input.InputParameters.TaskCreation_TB |
| | | local inboundSet={} |
| | | if inboundItems==nil then |
| | | return_value(strLuaDEID, false, "接口输入的XML格式非法!") |
| | | return |
| | | end |
| | | if inboundItems[1]==nil then |
| | | inboundSet={inboundItems} |
| | | else |
| | | inboundSet=inboundItems |
| | | end |
| | | |
| | | for i, inboundData in ipairs(inboundSet) do |
| | | if inboundData.TaskCreation_TB_ITEM==nil then |
| | | err_msg = "入库明细为空" |
| | | return_value(strLuaDEID, false, err_msg) |
| | | return |
| | | end |
| | | |
| | | --判断InBound是否存在,取消状态后面考虑 |
| | | local id |
| | | local strCondition =string.format("S_NO='%s' AND N_B_STATE<>91",inboundData.taskId) |
| | | nRet,id,strRetInfo=mobox.getDataObjAttrByKeyAttr(strLuaDEID,"GK_IN_TASK",strCondition) |
| | | if nRet==0 then |
| | | err_msg = "入库单号已存在!"..inboundData.taskId |
| | | return_value(strLuaDEID, true, err_msg) |
| | | return |
| | | end |
| | | |
| | | --判断料箱是否存在,不存在拒绝 |
| | | local detailItems = inboundData.TaskCreation_TB_ITEM |
| | | local items={} |
| | | if detailItems==nil then |
| | | return 1, "入库单明细为空" |
| | | end |
| | | if detailItems[1]==nil then |
| | | items={detailItems} |
| | | else |
| | | items=detailItems |
| | | end |
| | | local by_pallet=group_by(items,"cid") |
| | | local emptyCellCount=0 |
| | | for cid, group in pairs(by_pallet) do |
| | | for _,cell in ipairs(group) do |
| | | if cell.boxCode==nil or cell.boxCode=="" then |
| | | emptyCellCount=emptyCellCount+1 |
| | | end |
| | | end |
| | | if cid~=nil and cid~="" then |
| | | --判断料箱是否存在 |
| | | local strCondition =string.format("S_CODE='%s'",cid) |
| | | nRet,strRetInfo=mobox.existThisData(strLuaDEID,"Container",strCondition) |
| | | if nRet~=0 then |
| | | err_msg = "查询数据出错!"..cid |
| | | return_value(strLuaDEID, false, err_msg) |
| | | return |
| | | end |
| | | if strRetInfo=="no" then |
| | | err_msg = "料箱不存在!"..cid |
| | | return_value(strLuaDEID, false, err_msg) |
| | | return |
| | | end |
| | | --判断料箱是否完成入库 |
| | | local strCondition =string.format("S_CNTR_CODE='%s' AND N_B_STATE NOT IN(30,40)",cid) |
| | | nRet,strRetInfo=mobox.existThisData(strLuaDEID,"Inbound_Palletization",strCondition) |
| | | if nRet~=0 then |
| | | err_msg = "查询数据出错!"..cid |
| | | return_value(strLuaDEID, false, err_msg) |
| | | return |
| | | end |
| | | if strRetInfo=="yes" then |
| | | err_msg = "该料箱码盘数据未完成!"..cid |
| | | return_value(strLuaDEID, false, err_msg) |
| | | return |
| | | end |
| | | --判断料箱是否存在库存 |
| | | strCondition=string.format("S_CNTR_CODE='%s' AND F_QTY>0",cid) |
| | | nRet,strRetInfo=mobox.existThisData(strLuaDEID,"INV_Detail",strCondition) |
| | | if nRet~=0 then |
| | | err_msg = "查询数据出错!"..cid |
| | | return_value(strLuaDEID, false, err_msg..strRetInfo) |
| | | return |
| | | end |
| | | if strRetInfo=="yes" then |
| | | lua.DebugEx(strLuaDEID, "料箱存在库存") |
| | | err_msg = "料箱存在库存"..cid |
| | | return_value(strLuaDEID, false, err_msg..strRetInfo) |
| | | return |
| | | end |
| | | end |
| | | end |
| | | |
| | | nRet,err_msg= gk_create_inbound(strLuaDEID, inboundData,emptyCellCount) |
| | | if (nRet==nil or nRet~=0) then |
| | | return_value(strLuaDEID, false, err_msg) |
| | | else |
| | | return_value(strLuaDEID, true, "") |
| | | end |
| | | end |
| | | end |
New file |
| | |
| | | --[[ |
| | | 编码: GK-API-06 |
| | | 名称: 出库单创建接口 |
| | | 作者: yuanfeng |
| | | 日期: 2025-7-24 |
| | | |
| | | 入口函数: Outbound_Sync |
| | | 功能说明: |
| | | 1. 接收上游系统的入库任务XML数据 |
| | | 2. 检查入库单是否已存在 |
| | | 3. 创建Outbound_Order主表和Outbound_Detail子表记录 |
| | | 4. 返回处理结果 |
| | | 更新 |
| | | 2025-07-12 V1.1 新增出库单主表,state 默认为 "定版" |
| | | |
| | | 输入XML示例: |
| | | --]] wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | xml2lua = require("xml2lua") |
| | | |
| | | -- 创建出库单主表记录 |
| | | local function create_outbound_order(strLuaDEID, order_data) |
| | | |
| | | local nRet1, CONST_FACTORY = wms_base.Get_sConst2("WMS_Default_Factory") |
| | | -- 默认工厂标识 |
| | | local nRet2, CONST_WH = wms_base.Get_sConst2("WMS_Default_Warehouse") |
| | | if nRet1 ~= 0 or nRet2 ~= 0 then |
| | | return 1, "获取工厂或仓库常量失败" |
| | | end |
| | | |
| | | local order = m3.AllocObject(strLuaDEID, "Outbound_Order") |
| | | order.no = order_data.taskId |
| | | order.bs_type = order_data.taskType |
| | | order.bs_no = order_data.orderNo |
| | | order.wave_no = order_data.waveId |
| | | order.op_date = order_data.orderDate |
| | | order.priority = order_data.priority |
| | | order.note = order_data.memo or "" |
| | | order.wh_code = CONST_WH |
| | | order.area_code = "" |
| | | order.factory = CONST_FACTORY |
| | | -- 新增出库单主表状态字段 |
| | | order.state = "定版" |
| | | -- 新增货主编码 |
| | | order.storer = order_data.storerId |
| | | -- 新增源单号 |
| | | order.source_no = order_data.sourceBillNo |
| | | -- lua.DebugEx(strLuaDEID, "预创建出库单主表", order) |
| | | local nRet, result = m3.CreateDataObj(strLuaDEID, order) |
| | | return nRet, result |
| | | end |
| | | |
| | | -- 创建出库单明细记录 |
| | | -- @param:item_date 是传入的物料明细实体数据 |
| | | -- @param:order_data 传入出库单主表实体数据 |
| | | local function create_outbound_detail(strLuaDEID, order_no, item_data, order_data) |
| | | local detail = m3.AllocObject(strLuaDEID, "Outbound_Detail") |
| | | -- 明细表字段映射 |
| | | detail.oo_no = order_no |
| | | detail.storer = order_data.storerId |
| | | detail.owner = order_data.ownerId |
| | | detail.bs_row_no = item_data.orderItemId -- 订单行号 |
| | | detail.item_code = item_data.skuId |
| | | detail.item_state = item_data.skuStatus |
| | | detail.qty = lua.Get_NumAttrValue(item_data.qty) |
| | | detail.batch_no = item_data.produceCode |
| | | detail.wms_bn = item_data.batchNo |
| | | detail.prd_date = item_data.productDate |
| | | detail.exp_date = item_data.expiryDate |
| | | detail.udf01 = item_data.registerNo or "" |
| | | detail.udf02 = item_data.cid or "" |
| | | -- lua.DebugEx(strLuaDEID, "预创建出库单明细", detail) |
| | | local nRet, result = m3.CreateDataObj(strLuaDEID, detail) |
| | | return nRet, result |
| | | end |
| | | function Outbound_Sync(strLuaDEID) |
| | | local nRet, strRetInfo, err_msg |
| | | local soap_xml, parsed_data, task_data, input_params, task_tb, order_no |
| | | local strCondition, id, task_items |
| | | local isStop = 0 |
| | | local err = {} |
| | | local items = {} |
| | | |
| | | m3.PrintLuaDEInfo(strLuaDEID) |
| | | local result = { |
| | | flag = "success", |
| | | code = "0", |
| | | message = "成功" |
| | | } |
| | | -- lua.Debug(strLuaDEID, debug.getinfo(1), "出库单数据:", result) |
| | | |
| | | -- 1. 获取接口输入数据 |
| | | |
| | | nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if nRet ~= 0 then |
| | | -- lua.Stop(strLuaDEID, "无法获取数据包: " .. soap_xml) |
| | | result.flag = "failure" |
| | | result.code = "1" |
| | | result.message = "无法获取数据包: " |
| | | goto api_call_return |
| | | |
| | | -- return |
| | | end |
| | | |
| | | -- 2. 解析XML |
| | | |
| | | nRet, parsed_data = xml.parse(soap_xml) |
| | | if nRet ~= 0 then |
| | | -- lua.Stop(strLuaDEID, "接口输入的XML格式非法!") |
| | | result.flag = "failure" |
| | | result.code = "2" |
| | | result.message = "接口输入的XML格式非法: " |
| | | goto api_call_return |
| | | -- return |
| | | end |
| | | |
| | | -- 3. 提取任务数据 |
| | | task_data = parsed_data.Envelope.Body.InTaskCreationReq.TaskCreation_Input |
| | | input_params = task_data.InputParameters |
| | | task_tb = input_params.TaskCreation_TB |
| | | |
| | | -- 4. 检查出库单是否已存在 |
| | | order_no = task_tb.taskId |
| | | strCondition = string.format("S_NO = '%s'", order_no) |
| | | nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "Outbound_Order", strCondition) |
| | | -- lua.Debug(strLuaDEID, debug.getinfo(1), "查询出来的出库单数据:", strRetInfo) |
| | | |
| | | if nRet > 1 then |
| | | result.flag = "failure" |
| | | result.code = "3" |
| | | result.message = "检查出库单是否存在时出错: " .. strRetInfo |
| | | goto api_call_return |
| | | elseif nRet == 0 then |
| | | result.flag = "failure" |
| | | result.code = "4" |
| | | result.message = "出库单已存在 " |
| | | goto api_call_return |
| | | end |
| | | -- 5. 创建出库单主表 |
| | | nRet, strRetInfo = create_outbound_order(strLuaDEID, task_tb) |
| | | if nRet ~= 0 then |
| | | -- lua.Stop(strLuaDEID, "创建出库单主表失败:" .. strRetInfo) |
| | | result.flag = "failure" |
| | | result.code = "5" |
| | | result.message = "创建出库单主表失败:" .. strRetInfo |
| | | isStop = 3 |
| | | goto api_call_return |
| | | -- return |
| | | end |
| | | |
| | | -- 6. 处理明细数据 |
| | | task_items = task_tb.TaskCreation_TB_ITEM |
| | | |
| | | -- 情况2:多条明细(数组形式) |
| | | if task_items[1] ~= nil then |
| | | items = task_items |
| | | -- 情况3:单条明细(非数组形式) |
| | | else |
| | | items = {task_items} |
| | | end |
| | | |
| | | for i, item in ipairs(items) do |
| | | nRet, strRetInfo = create_outbound_detail(strLuaDEID, order_no, item, task_tb) |
| | | if nRet ~= 0 then |
| | | err_msg = string.format("创建出库单明细失败(行号:%d): %s", item.orderItemId, strRetInfo) |
| | | result.flag = "failure" |
| | | result.code = "5" |
| | | result.message = err_msg |
| | | isStop = 3 |
| | | goto api_call_return |
| | | end |
| | | end |
| | | ::api_call_return:: |
| | | -- 7. 返回处理结果 |
| | | -- local result = { |
| | | -- flag = nErr > 0 and "failure" or "success", |
| | | -- code = nErr, |
| | | -- message = nErr > 0 and table.concat(err, "; ") or "成功", |
| | | -- } |
| | | local xml_result = xml.json_to_xml(result, "response") |
| | | |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, isStop) |
| | | |
| | | -- m3.EPI_Return(strLuaDEID, result) |
| | | -- ApiReturn(strLuaDEID, 0, result, isStop) |
| | | |
| | | end |
File was renamed from lua_code/Lua/GK-API-07.lua |
| | |
| | | --- |
| | | --- Created by wsz. |
| | | --- DateTime: 2025/5/15 下午3:31 |
| | | --- |
| | | |
| | | --[[ |
| | | 编码: GK-API-07 |
| | | 名称: 订单取消接口 |
| | | 作者: wsz |
| | | 入口函数:Order_Sync |
| | | 功能说明: 接收报文创建 Order_Hold 实体 ,对于已存在的数据无条件更新,返回报无需创建还货单 ;新增的数据设置需要创建还货单 |
| | | 功能说明: 接收报文创建 Order_Hold 实体,对于已存在的数据无条件更新,返回报无需创建还货单 ;新增的数据设置需要创建还货单 |
| | | 变更历史:v0.0.1 |
| | | |
| | | 注意: |
| | | 1、按照此报文形式,这应是单条发送 |
| | | 2、报文解析项少了来源单号、拦截类型、:存储时 来源单号不填,拦截类型填Interface |
| | | 3、needReturnOrder 仅 根据出库单的状态会涉及到 |
| | | |
| | | 订单类型: asn 入库订单 so出库订单 inventory 盘点单 |
| | | 三者单据的主键no-与报文的taskId 对应 |
| | | 入库单和盘点单已执行不允许取消,出库单订单未完成都允许取消,允许取消才插入Order_Hold |
| | | |
| | | ----------------------------------------- |
| | | |
| | | 入库单 Inbound_Order no | b_state |
New file |
| | |
| | | --- Created by w1832. |
| | | --- DateTime: 2025/5/20 上午8:57 |
| | | --- |
| | | |
| | | --[[ |
| | | 编码: GK-API-08 |
| | | 名称: Outbound_Priority_Change |
| | | 作者:wsz |
| | | 入口函数:Outbound_Priority_Change |
| | | 功能说明:更新发货单 Shipping_Order 优先级,已分配后不允许更新 |
| | | 变更历史: |
| | | v0.0.1 初始 |
| | | |
| | | v0.0.2 CLSID 为出库单 Outbound_Order,非Shipping_Order发货单 |
| | | 注意: |
| | | 1、此报文结构应是单条推送 |
| | | 2、S_BS_NO查到的数据不一定唯一,同S_BS_NO数据的N_B_STATE状态也不一定全部满足要求,仅处理满足条件的数据 |
| | | |
| | | v0.0.3 修改映射字段 S_BS_NO -> S_NO |
| | | |
| | | v0.0.4 重回映射字段 S_NO -> S_BS_NO 现逻辑保持在v0.0.2为准 |
| | | |
| | | --]] |
| | | |
| | | |
| | | json = require("json") |
| | | mobox = require("OILua_JavelinExt") |
| | | m3 = require("oi_base_mobox") |
| | | |
| | | xml = require("oi_base_xml") |
| | | |
| | | --- 实体标识-出库订单优先级调整接口 |
| | | local CLSID_OutboundOrder = "Outbound_Order" |
| | | -- 表名 |
| | | local TB_NAME_OutboundOrder = "TN_Outbound_Order" |
| | | |
| | | local CLSID_OutboundOrder_desc = "出库订单优先级调整接口" |
| | | |
| | | local luaDEID |
| | | |
| | | |
| | | |
| | | --根标签 |
| | | local RootTag = "response" |
| | | |
| | | |
| | | |
| | | |
| | | -- 简化 debug.info记录 |
| | | local function DebugInfo(desc, param) |
| | | if param == nil then |
| | | param = "" |
| | | end |
| | | lua.Debug(luaDEID, debug.getinfo(1), desc, param) |
| | | end |
| | | |
| | | |
| | | --[[ |
| | | -- 执行成功 |
| | | ]] |
| | | local function result_success(strLuaDEID) |
| | | |
| | | local result = {} |
| | | result.flag = "success" -- success|failure |
| | | result.code = 0 |
| | | result.message = "" |
| | | |
| | | do |
| | | local nRet = mobox.returnValue(strLuaDEID, 1, xml.json_to_xml(result,RootTag), result.code) |
| | | if nRet ~= 0 then |
| | | lua.Error(strLuaDEID, debug.getinfo(1), 'result_success-执行mobox.returnValue失败 ' .. nRet) |
| | | end |
| | | end |
| | | end |
| | | |
| | | --[[ |
| | | -- 事务回滚-返回信息后终止执行 |
| | | ]] |
| | | local function result_transaction_back(strLuaDEID, msg) |
| | | |
| | | -- 回滚当次处理 |
| | | lua.Stop(strLuaDEID, msg) |
| | | -- |
| | | --local result = {} |
| | | --result.flag = "failure" -- success|failure |
| | | --result.code = 5 |
| | | --result.message = msg |
| | | -- |
| | | --local xmlstr = xml.json_to_xml(result) |
| | | -- |
| | | --do |
| | | -- local nRet = mobox.returnValue(strLuaDEID, 1, xmlstr, result.code) |
| | | -- if nRet ~= 0 then |
| | | -- lua.Error(strLuaDEID, debug.getinfo(1), 'result_transaction_back-执行mobox.returnValue失败 ' .. nRet) |
| | | -- end |
| | | --end |
| | | error(msg, 0) |
| | | -- lua.Error(strLuaDEID, debug.getinfo(1), xmlstr) |
| | | end |
| | | |
| | | |
| | | --[[ |
| | | param |
| | | CLSID:目标实例calssid |
| | | id目标数据的S_ID |
| | | temp:待更新字段对象,lua属性table |
| | | |
| | | |
| | | --]] |
| | | local function butchUpdateData(strLuaDEID,CLSID,id,temp) |
| | | |
| | | local nRet, str_data_attrset = mobox.luaJsonToObjAttrs(CLSID_OutboundOrder, json.encode(temp)) |
| | | if nRet ~= 0 then |
| | | result_transaction_back(strLuaDEID, "luaJsonToObjAttrs 函数 转化格式失败" .. nRet .. str_data_attrset) |
| | | end |
| | | -- 反序列化为目标格式 |
| | | local attrValueObj = json.decode(str_data_attrset) |
| | | |
| | | -- 组装批量更新的数据格式 |
| | | local updateObj = {} |
| | | |
| | | local updateObj_item = {} |
| | | updateObj_item.id = id |
| | | updateObj_item.attrs = attrValueObj |
| | | table.insert(updateObj, updateObj_item) |
| | | |
| | | local updateStrDataJson = lua.table2str(updateObj) |
| | | lua.Debug(strLuaDEID, debug.getinfo(1), CLSID .. "update准备覆盖已有数据", updateStrDataJson) |
| | | local nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, CLSID, updateStrDataJson) |
| | | if (nRet ~= 0) then |
| | | result_transaction_back(strLuaDEID, string.format(CLSID.."更新操作失败!code:%s,msg:%s", nRet, strRetInfo)) |
| | | end |
| | | |
| | | end |
| | | |
| | | |
| | | --[[ |
| | | 业务数据处理 |
| | | 1、查询 orderNo:S_BS_NO 记录 来源单号非主键,可能存在多条数据 |
| | | 2.判断 N_B_STATE 状态 更新出库单 Outbound_Order 优先级,已分配后不允许更新(N_B_STATE>=25 AND N_B_STATE<=55) |
| | | |
| | | ]] |
| | | local function bussHandle(strLuaDEID, dataSet) |
| | | |
| | | local strCondition |
| | | do |
| | | local filters = {} |
| | | table.insert(filters, string.format([[ %s = '%s' ]], "S_BS_NO", lua.Get_StrAttrValue(dataSet.orderNo))) |
| | | strCondition = table.concat(filters, " and ") |
| | | lua.Debug(strLuaDEID, debug.getinfo(1), "filters-组装的Shipping_Order的where条件", strCondition) |
| | | end |
| | | |
| | | |
| | | -- 查找总数量 |
| | | local nRetCount |
| | | do |
| | | local nRet, nCount = mobox.getDataObjCount(strLuaDEID, CLSID_OutboundOrder, strCondition) |
| | | if nRet == 0 then |
| | | nRetCount = nCount |
| | | DebugInfo(string.format("%s-查询总数量为%s", CLSID_OutboundOrder, nCount)) |
| | | else |
| | | result_transaction_back(strLuaDEID, string.format("查询目标数据失败,code:%s,msg:%s", nRet, nCount)) |
| | | end |
| | | |
| | | if nCount == "0" then |
| | | result_transaction_back(strLuaDEID, dataSet.orderNo .. "查找不到报文对应的出库单数据!") |
| | | end |
| | | end |
| | | |
| | | |
| | | -- 查询目标数据, 存储lua数组,内部为数据库字段格式对象 |
| | | local datas = {} |
| | | do |
| | | local strFieldList = { "S_ID", "S_NO", "S_BS_NO", "N_PRIORITY", "S_NOTE", "N_PRIORITY" } |
| | | -- 返回 json型 str,格式 [ { "attr1": "xxx", "attr2": "xxx1", … }, … |
| | | local nRet, strRetInfo = mobox.queryTable(strLuaDEID, TB_NAME_OutboundOrder, json.encode(strFieldList), nRetCount, strCondition) |
| | | if nRet == 0 then |
| | | DebugInfo(string.format("%s-queryTable函数返回", CLSID_OutboundOrder), strRetInfo) |
| | | local tableData = json.decode(strRetInfo) |
| | | DebugInfo("tableData", tableData) |
| | | |
| | | datas = tableData |
| | | |
| | | --for n = 1, #tableData do |
| | | -- -- local nRet1, strObjJson = mobox.objAttrToObjJson(CLSID_ShippingOrder, tableData[n]) |
| | | -- -- local nRet1, strObjJson = mobox.objJsonToLuaJson(CLSID_ShippingOrder, tableData[n]) |
| | | -- |
| | | -- if nRet1 == 0 then |
| | | -- table.insert(datas, strObjJson) |
| | | -- else |
| | | -- result_transaction_back(strLuaDEID, string.format("queryTable-objAttrToObjJson转化失败,code:%s,msg:%s", nRet1, strObjJson)) |
| | | -- end |
| | | --end |
| | | else |
| | | result_transaction_back(strLuaDEID, string.format("queryTable查询目标数据失败,code:%s,msg:%s", nRet, strRetInfo)) |
| | | end |
| | | end |
| | | |
| | | DebugInfo(string.format("%s-queryTable-取得datas数据", CLSID_OutboundOrder), datas) |
| | | |
| | | -- 迭代更新满足条件的数据 |
| | | for n = 1, #datas do |
| | | |
| | | local b_state = lua.Get_NumAttrValue(datas[n].N_B_STATE) |
| | | local id = datas[n].S_ID |
| | | local flag = b_state >= 25 and b_state <= 55 |
| | | DebugInfo("b_state", b_state) |
| | | DebugInfo("id", id) |
| | | DebugInfo("flag", flag) |
| | | |
| | | if not flag then |
| | | -- 执行更新 |
| | | local temp = {} |
| | | temp.priority = dataSet.priority --优先级 |
| | | temp.note = dataSet.memo -- 备注 |
| | | |
| | | butchUpdateData(strLuaDEID, CLSID_OutboundOrder,id,temp) |
| | | |
| | | --local nRet, str_data_attrset = mobox.luaJsonToObjAttrs(CLSID_ShippingOrder, json.encode(temp)) |
| | | --if nRet ~= 0 then |
| | | -- result_transaction_back(strLuaDEID, "luaJsonToObjAttrs 函数 转化格式失败" .. nRet .. str_data_attrset) |
| | | --end |
| | | ---- 反序列化为目标格式 |
| | | --local attrValueObj = json.decode(str_data_attrset) |
| | | -- |
| | | ---- 组装批量更新的数据格式 |
| | | --local updateObj = {} |
| | | -- |
| | | --local updateObj_item = {} |
| | | --updateObj_item.id = id |
| | | --updateObj_item.attrs = attrValueObj |
| | | --table.insert(updateObj, updateObj_item) |
| | | -- |
| | | --local updateStrDataJson = lua.table2str(updateObj) |
| | | --lua.Debug(strLuaDEID, debug.getinfo(1), CLSID_ShippingOrder .. "update准备覆盖已有数据", updateStrDataJson) |
| | | --local nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, CLSID_ShippingOrder, updateStrDataJson) |
| | | --if (nRet ~= 0) then |
| | | -- result_transaction_back(strLuaDEID, string.format("发货单更新操作失败!code:%s,msg:%s", nRet, strRetInfo)) |
| | | --end |
| | | end |
| | | |
| | | end |
| | | |
| | | end |
| | | |
| | | |
| | | |
| | | local function Outbound_Priority_Change_main(strLuaDEID) |
| | | -- 1.1 getxml |
| | | local soap_xml |
| | | do |
| | | local nRet, data = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if (nRet ~= 0) then |
| | | result_transaction_back(strLuaDEID, "无法获取数据包 datajson !" .. data) |
| | | end |
| | | soap_xml = data |
| | | lua.Debug(strLuaDEID, debug.getinfo(1), "GK-API-08xml报文", soap_xml) |
| | | end |
| | | |
| | | -- 1.2 xml->luaobj |
| | | local parsed_data |
| | | do |
| | | local nRet, data = xml.parse(soap_xml) |
| | | if (nRet ~= 0) then |
| | | result_transaction_back(strLuaDEID, "接口输入的XML格式非法!") |
| | | end |
| | | parsed_data = data |
| | | end |
| | | |
| | | -- 1.3 取得商品批次表item的tableObj |
| | | local dataSet = parsed_data["Envelope"]["Body"] |
| | | ["OrderAdjustmentsReq"] |
| | | ["OrderAdjustments_Input"] |
| | | ["InputParameters"] |
| | | ["OrderAdjustments_TB"] |
| | | |
| | | if nil == dataSet then |
| | | -- wms_base.Warning(strLuaDEID, 2, 201, CLSID_OutboundOrder_desc .. "-未解析到soap目标节点!", json.encode(dataSet), "", CLSID_OutboundOrder_desc .. "-dataSet") |
| | | result_transaction_back(strLuaDEID, CLSID_OutboundOrder_desc .. "-未解析到soap目标节点!") |
| | | elseif #dataSet == 0 then |
| | | -- 仅单条数据 |
| | | lua.Debug(strLuaDEID, debug.getinfo(1), "单条", dataSet) |
| | | bussHandle(strLuaDEID, dataSet) |
| | | else |
| | | for i = 1, #dataSet do |
| | | lua.Debug(strLuaDEID, debug.getinfo(1), "多条", "") |
| | | bussHandle(strLuaDEID, dataSet[i]) |
| | | end |
| | | end |
| | | |
| | | result_success(strLuaDEID) |
| | | end |
| | | |
| | | |
| | | --[[ |
| | | 固定-错误捕获处理 |
| | | ]] |
| | | local ERR |
| | | local function errorHandler(err) |
| | | ERR = err |
| | | lua.Debug(luaDEID, debug.getinfo(1), "err-记录", err) |
| | | return err |
| | | end |
| | | |
| | | --[[ 入口函数 ]] |
| | | function Outbound_Priority_Change(strLuaDEID) |
| | | |
| | | m3.PrintLuaDEInfo(strLuaDEID) |
| | | |
| | | luaDEID = strLuaDEID |
| | | --Outbound_Priority_Change_main(strLuaDEID) |
| | | local success, result = xpcall(Outbound_Priority_Change_main, errorHandler, strLuaDEID) |
| | | |
| | | if not success then |
| | | |
| | | |
| | | local result = {} |
| | | result.flag = "failure" -- success|failure |
| | | result.code = 5 |
| | | result.message = ERR |
| | | |
| | | local xmlstr = xml.json_to_xml(result,RootTag) |
| | | |
| | | do |
| | | local nRet = mobox.returnValue(strLuaDEID, 1, xmlstr, result.code) |
| | | if nRet ~= 0 then |
| | | lua.Error(strLuaDEID, debug.getinfo(1), 'result_transaction_back-执行mobox.returnValue失败 ' .. nRet) |
| | | end |
| | | end |
| | | |
| | | -- lua.Error(strLuaDEID, debug.getinfo(1), ERR) |
| | | end |
| | | |
| | | end |
New file |
| | |
| | | --[[ |
| | | 编码: GK-API-09 |
| | | 名称: 盘点计划同步接口 |
| | | 作者: 袁峰 |
| | | 入口函数:Count_Pan_Sync |
| | | 功能说明: 该接口是同步接口, |
| | | 上游系统调用该接口后,WES的响应报文success说明WES已经将该报文接收成功; |
| | | 需要同步盘点任务表和盘点任务明细表xml结构。 |
| | | 变更历史: |
| | | |
| | | <soapenv:Envelope |
| | | xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" |
| | | xmlns:v1="http://www.gkht.com/Inventory/INV/Ebs/Schemas/InventoryTasks/V1.0"> |
| | | <soapenv:Header/> |
| | | <soapenv:Body> |
| | | <v1:InventoryTasksReq> |
| | | <v1:InventoryTasks_Input> |
| | | <v1:RESTHeader> |
| | | <v1:NLSLanguage>SIMPLIFIED CHINESE</v1:NLSLanguage> |
| | | <v1:Org_Id>0</v1:Org_Id> |
| | | </v1:RESTHeader> |
| | | <v1:InputParameters> |
| | | <!-- 第一个盘点任务 --> |
| | | <v1:InventoryTasks_TB> |
| | | <v1:taskId>TASK30000100</v1:taskId> |
| | | <v1:inventoryMode>01</v1:inventoryMode> |
| | | <v1:workMode>Manual</v1:workMode> |
| | | <v1:MaintenanceNumber>10</v1:MaintenanceNumber> |
| | | <v1:inventoryType>YH</v1:inventoryType> |
| | | <v1:orderNo>YH100001</v1:orderNo> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:ownerId>CGKHTY</v1:ownerId> |
| | | <v1:mtBeginDate>2025-05-06</v1:mtBeginDate> |
| | | <v1:mtEndDate>2025-05-06</v1:mtEndDate> |
| | | <!-- 第一个任务的明细数据 --> |
| | | <v1:InventoryTasks_TB_ITEM> |
| | | <v1:orderItemId>100</v1:orderItemId> |
| | | <v1:skuId>XR33201-2L080B</v1:skuId> |
| | | <v1:qty>2</v1:qty> |
| | | <v1:batchNo>PHI00000000000001309</v1:batchNo> |
| | | </v1:InventoryTasks_TB_ITEM> |
| | | </v1:InventoryTasks_TB> |
| | | |
| | | <!-- 第二个盘点任务 --> |
| | | <v1:InventoryTasks_TB> |
| | | <v1:taskId>TASK300000101</v1:taskId> |
| | | <v1:inventoryMode>02</v1:inventoryMode> |
| | | <v1:workMode>Auto</v1:workMode> |
| | | <v1:MaintenanceNumber>5</v1:MaintenanceNumber> |
| | | <v1:inventoryType>PD</v1:inventoryType> |
| | | <v1:orderNo>PD200001</v1:orderNo> |
| | | <v1:storerId>GKHT</v1:storerId> |
| | | <v1:ownerId>GKHT</v1:ownerId> |
| | | <v1:mtBeginDate>2025-05-07</v1:mtBeginDate> |
| | | <v1:mtEndDate>2025-05-07</v1:mtEndDate> |
| | | <!-- 第二个任务的明细数据 --> |
| | | <v1:InventoryTasks_TB_ITEM> |
| | | <v1:orderItemId>110</v1:orderItemId> |
| | | <v1:skuId>ABC123</v1:skuId> |
| | | <v1:qty>10</v1:qty> |
| | | <v1:batchNo>BATCH2025001</v1:batchNo> |
| | | </v1:InventoryTasks_TB_ITEM> |
| | | <v1:InventoryTasks_TB_ITEM> |
| | | <v1:orderItemId>111</v1:orderItemId> |
| | | <v1:skuId>XYZ456</v1:skuId> |
| | | <v1:qty>3</v1:qty> |
| | | <v1:batchNo>BATCH2025002</v1:batchNo> |
| | | </v1:InventoryTasks_TB_ITEM> |
| | | </v1:InventoryTasks_TB> |
| | | </v1:InputParameters> |
| | | </v1:InventoryTasks_Input> |
| | | </v1:InventoryTasksReq> |
| | | </soapenv:Body> |
| | | </soapenv:Envelope> |
| | | |
| | | 响应示例: |
| | | <response> |
| | | <flag>success</flag> |
| | | <code>0</code> |
| | | <message>成功</message> |
| | | </response> |
| | | ]] -- |
| | | wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | mobox = require("OILua_JavelinExt") |
| | | m3 = require("oi_base_mobox") |
| | | wms = require("OILua_WMS") |
| | | |
| | | local filedMapping = { |
| | | ["货品盘点"] = 1, |
| | | ["容器盘点"] = 2, |
| | | ["货位盘点"] = 3, |
| | | ["OVERALL全盘"] = 4, |
| | | ["MT动碰盘点"] = 5, |
| | | ["SPECIAL抽盘"] = 6, |
| | | ["YH"] = 7 |
| | | } |
| | | |
| | | -- 创建统一返回结果(调整为3个参数) |
| | | function Create_result(flag, code, msg) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "" |
| | | } |
| | | end |
| | | |
| | | function GK_Count_Pan_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, "获取数据包失败", soap_xml) |
| | | 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 格式非法: " .. parsed_data) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "xml格式非法", parsed_data) |
| | | return |
| | | end |
| | | |
| | | -- 3. 提取主表数据 |
| | | local receipt_data = parsed_data.Envelope.Body.InventoryTasksReq.InventoryTasks_Input |
| | | local input_params = receipt_data.InputParameters |
| | | |
| | | -- 检查是否存在 InventoryTasks_TB |
| | | if not input_params or not input_params.InventoryTasks_TB then |
| | | FinalRes = Create_result("failure", "203", "xml 数据格式错误,缺少 InventoryTasks_TB") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "xml 数据格式错误", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 4. 统一处理:确保 mainTables 是数组(即使只有一个主表) |
| | | local mainTables = input_params.InventoryTasks_TB |
| | | if mainTables[1] == nil then |
| | | mainTables = {mainTables} |
| | | end |
| | | |
| | | -- 5. 获取系统常量 |
| | | local RetWH_COE, CONST_WH = wms_base.Get_sConst2("WMS_Default_Factory") |
| | | if RetWH_COE ~= 0 then |
| | | FinalRes = Create_result("failure", "204", "获取仓库常量失败: " .. CONST_WH) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "获取系统常量失败", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 6. 遍历所有盘点任务 |
| | | for i = 1, #mainTables do |
| | | local mainData = mainTables[i] |
| | | |
| | | -- 检查盘点任务是否已存在 |
| | | local strCondition = string.format("S_CP_NO = '%s'", mainData.taskId) |
| | | lua.DebugEx(strLuaDEID, "查询盘点任务条件", strCondition) |
| | | local nRet, retCountPlan = m3.GetDataObjByCondition(strLuaDEID, "Count_Plan", strCondition) |
| | | lua.DebugEx(strLuaDEID, "查询结果", retCountPlan) |
| | | if nRet == 0 then |
| | | -- 查询成功且找到记录,说明盘点任务已存在 |
| | | FinalRes = Create_result("failure", "1", "盘点任务[" .. mainData.taskId .. "]已存在") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "盘点任务已存在", retCountPlan) |
| | | return |
| | | elseif nRet ~= 1 then |
| | | -- 查询出错 |
| | | FinalRes = Create_result("failure", "206", "检查盘点任务[" .. mainData.taskId .. |
| | | "]是否存在时出错: " .. retCountPlan) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "检查盘点任务是否存在时出错", xml_result) |
| | | return |
| | | end |
| | | |
| | | -- 创建主表数据 |
| | | local count_plan = m3.AllocObject(strLuaDEID, "Count_Plan") |
| | | count_plan.cp_no = mainData.taskId |
| | | count_plan.inventory_mode = mainData.inventoryMode |
| | | count_plan.work_mode = mainData.workMode |
| | | count_plan.count_limit = mainData.MaintenanceNumber |
| | | |
| | | -- 根据inventoryType设置type和type_desc |
| | | local panTypeValue = mainData.inventoryType or "" |
| | | local foundType = false |
| | | local typeValue = 0 |
| | | |
| | | -- 遍历字典查找匹配项 |
| | | for k, v in pairs(filedMapping) do |
| | | if string.find(panTypeValue, k) then |
| | | typeValue = v |
| | | foundType = true |
| | | break |
| | | end |
| | | end |
| | | |
| | | -- 如果没有找到匹配项,使用默认值 |
| | | if not foundType then |
| | | -- typeValue = 0 |
| | | -- typeDesc = "未知类型" |
| | | -- lua.DebugEx(strLuaDEID, "警告:未找到匹配的盘点类型", panTypeValue) |
| | | FinalRes = Create_result("failure", "1", "盘点类型[" .. panTypeValue .. "]不存在") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "盘点类型不存在", panTypeValue) |
| | | end |
| | | |
| | | count_plan.type = typeValue |
| | | |
| | | lua.DebugEx(strLuaDEID, "容器类型数值:", count_plan.type) |
| | | |
| | | count_plan.bs_no = mainData.orderNo |
| | | -- count_plan.storer = mainData.storerId |
| | | -- count_plan.owner = mainData.ownerId |
| | | count_plan.begin_time = mainData.mtBeginDate |
| | | count_plan.end_time = mainData.mtEndDate |
| | | count_plan.wh_code = CONST_WH |
| | | count_plan.plan_total = 0 |
| | | count_plan.b_state = 0 |
| | | count_plan.acc_finish = 0 |
| | | |
| | | lua.DebugEx(strLuaDEID, "获取创建数据:", count_plan) |
| | | |
| | | -- 检查是否已存在相同关键字的记录 |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, count_plan) |
| | | lua.DebugEx(strLuaDEID, "创建结果", ret_info) |
| | | if nRet ~= 0 then |
| | | -- 再次检查是否真的存在 |
| | | local nRetCheck, retCountPlanCheck = m3.GetDataObjByCondition(strLuaDEID, "Count_Plan", strCondition) |
| | | lua.DebugEx(strLuaDEID, "再次查询结果", retCountPlanCheck) |
| | | if nRetCheck == 0 then |
| | | FinalRes = Create_result("failure", "205", "盘点任务[" .. mainData.taskId .. "]已存在") |
| | | else |
| | | FinalRes = Create_result("failure", "207", |
| | | "盘点任务[" .. mainData.taskId .. "]创建失败: " .. ret_info) |
| | | end |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "创建盘点任务主表失败", ret_info) |
| | | return |
| | | end |
| | | |
| | | -- 检查明细数据是否存在 |
| | | if mainData.InventoryTasks_TB_ITEM == nil then |
| | | lua.DebugEx(strLuaDEID, "警告:盘点任务 " .. mainData.taskId .. " 无明细数据") |
| | | else |
| | | -- 7. 遍历当前盘点任务的所有明细数据 |
| | | local details = mainData.InventoryTasks_TB_ITEM |
| | | -- 确保 details 是数组(即使只有一个明细) |
| | | if details[1] == nil then |
| | | details = {details} |
| | | end |
| | | |
| | | for j = 1, #details do |
| | | local item = details[j] |
| | | |
| | | -- 创建明细数据 |
| | | local count_plan_item = m3.AllocObject(strLuaDEID, "Count_Plan_Detail") |
| | | count_plan_item.cp_no = mainData.taskId |
| | | count_plan_item.row_no = item.orderItemId |
| | | count_plan_item.qty = lua.Get_NumAttrValue(item.qty) or 0 |
| | | count_plan_item.wms_bn = item.batchNo |
| | | count_plan_item.batch_no = item.produceCode or "" |
| | | count_plan_item.prd_date = item.productDate or "" |
| | | count_plan_item.exp_date = item.expiryDate or "" |
| | | count_plan_item.reg_no = item.registerNo or "" |
| | | count_plan_item.storer = mainData.storerId |
| | | count_plan_item.owner = mainData.ownerId |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, count_plan_item) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "208", "创建盘点明细失败: " .. ret_info) |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | lua.Stop(strLuaDEID, "创建盘点明细失败", ret_info) |
| | | return |
| | | end |
| | | end |
| | | end |
| | | end |
| | | -- 8. 返回成功 |
| | | FinalRes = Create_result("success", "0", "盘点任务创建成功") |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | end |
New file |
| | |
| | | wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | mobox = require("OILua_JavelinExt") |
| | | m3 = require("oi_base_mobox") |
| | | |
| | | -- XML特殊字符转义函数 |
| | | local function xml_escape(str) |
| | | if not str then |
| | | return "" |
| | | end |
| | | return tostring(str):gsub("&", "&"):gsub("<", "<"):gsub(">", ">"):gsub("\"", """):gsub("'", "'") |
| | | end |
| | | |
| | | -- 硬编码XML生成器 |
| | | local function generate_raw_xml(result) |
| | | local xml = [[<?xml version="1.0" encoding="UTF-8"?> |
| | | <response> |
| | | <flag>]] .. xml_escape(result.flag) .. [[</flag> |
| | | <code>]] .. xml_escape(result.code) .. [[</code> |
| | | <message>]] .. xml_escape(result.message) .. [[</message>]] |
| | | |
| | | if result.data and #result.data > 0 then |
| | | xml = xml .. [[ |
| | | <data>]] |
| | | for _, item in ipairs(result.data) do |
| | | xml = xml .. [[ |
| | | <item> |
| | | <productLine>]] .. xml_escape(item.productLine) .. [[</productLine> |
| | | <storerId>]] .. xml_escape(item.storerId) .. [[</storerId> |
| | | <cid>]] .. xml_escape(item.cid) .. [[</cid> |
| | | <ownerId>]] .. xml_escape(item.ownerId) .. [[</ownerId> |
| | | <skuId>]] .. xml_escape(item.skuId) .. [[</skuId> |
| | | <boxCode>]] .. xml_escape(item.boxCode) .. [[</boxCode> |
| | | <qty>]] .. xml_escape(item.qty) .. [[</qty> |
| | | <registerNo>]] .. xml_escape(item.registerNo) .. [[</registerNo> |
| | | <skuStatus>]] .. xml_escape(item.skuStatus) .. [[</skuStatus> |
| | | <expiryDate>]] .. xml_escape(item.expiryDate) .. [[</expiryDate> |
| | | <batchNo>]] .. xml_escape(item.batchNo) .. [[</batchNo> |
| | | <productDate>]] .. xml_escape(item.productDate) .. [[</productDate> |
| | | <produceCode>]] .. xml_escape(item.produceCode) .. [[</produceCode> |
| | | <locationId>]] .. xml_escape(item.locationId) .. [[</locationId> |
| | | </item>]] |
| | | end |
| | | xml = xml .. [[ |
| | | </data>]] |
| | | else |
| | | xml = xml .. [[ |
| | | <data/>]] |
| | | end |
| | | xml = xml .. [[ |
| | | </response>]] |
| | | return xml |
| | | end |
| | | |
| | | -- 创建统一返回结果 |
| | | local function Create_result(flag, code, msg, data) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "", |
| | | data = data or {} |
| | | } |
| | | end |
| | | |
| | | -- 深度遍历查找XML节点(最稳定的方法) |
| | | local function deep_find_xml_node(data, node_names) |
| | | if type(data) ~= "table" then |
| | | return nil |
| | | end |
| | | |
| | | -- 先尝试直接路径查找 |
| | | local current = data |
| | | for _, name in ipairs(node_names) do |
| | | if type(current) ~= "table" then |
| | | break |
| | | end |
| | | |
| | | -- 尝试带v1命名空间和不带命名空间的节点 |
| | | current = current["v1:" .. name] or current[name] |
| | | if not current then |
| | | break |
| | | end |
| | | end |
| | | if current then |
| | | return current |
| | | end |
| | | |
| | | -- 深度遍历整个XML树查找 |
| | | local function deep_search(t, names, index) |
| | | if index > #names then |
| | | return t |
| | | end |
| | | local current_name = names[index] |
| | | |
| | | for k, v in pairs(t) do |
| | | if (k == current_name or k == "v1:" .. current_name) and type(v) == "table" then |
| | | local result = deep_search(v, names, index + 1) |
| | | if result then |
| | | return result |
| | | end |
| | | elseif type(v) == "table" then |
| | | local result = deep_search(v, names, index) |
| | | if result then |
| | | return result |
| | | end |
| | | end |
| | | end |
| | | return nil |
| | | end |
| | | |
| | | return deep_search(data, node_names, 1) |
| | | end |
| | | |
| | | -- 查询库存明细 |
| | | local function query_inventory_detail(strLuaDEID, query_params) |
| | | local strCondition = string.format(" S_STORER = '%s' AND S_OWNER = '%s' AND S_ITEM_CODE = '%s'", |
| | | query_params.storerId, query_params.ownerId, query_params.skuId) |
| | | |
| | | if query_params.locationId and query_params.locationId ~= "" then |
| | | strCondition = strCondition .. string.format(" AND S_LOC_CODE = '%s'", query_params.locationId) |
| | | end |
| | | |
| | | if query_params.produceCode and query_params.produceCode ~= "" then |
| | | strCondition = strCondition .. string.format(" AND S_BATCH_NO = '%s'", query_params.produceCode) |
| | | end |
| | | |
| | | local nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition) |
| | | if nRet ~= 0 then |
| | | return nRet, data_objects |
| | | end |
| | | |
| | | local formatted_result = {} |
| | | for n = 1, #data_objects do |
| | | local obj_attrs = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) |
| | | local stock = { |
| | | storerId = obj_attrs.S_STORER or "", |
| | | ownerId = obj_attrs.S_OWNER or "", |
| | | skuId = obj_attrs.S_ITEM_CODE or "", |
| | | skuStatus = obj_attrs.S_ITEM_STATE or "", |
| | | qty = lua.Get_NumAttrValue(obj_attrs.F_QTY) or 0, |
| | | locationId = obj_attrs.S_LOC_CODE or "", |
| | | cid = obj_attrs.S_CNTR_CODE or "", |
| | | boxCode = obj_attrs.S_CELL_NO or "", |
| | | batchNo = obj_attrs.S_WMS_BN or "", |
| | | produceCode = obj_attrs.S_BATCH_NO or "", |
| | | productDate = obj_attrs.D_PRD_DATE or "", |
| | | expiryDate = obj_attrs.D_EXP_DATE or "", |
| | | productLine = obj_attrs.S_UDF01 or "", |
| | | registerNo = obj_attrs.S_PROD_LINE or "" |
| | | } |
| | | table.insert(formatted_result, stock) |
| | | end |
| | | |
| | | return 0, formatted_result |
| | | end |
| | | |
| | | -- Main函数 |
| | | function Stock_Query(strLuaDEID) |
| | | m3.PrintLuaDEInfo(strLuaDEID) |
| | | local FinalRes = Create_result() |
| | | local xml_result = "" |
| | | |
| | | -- 使用pcall捕获所有可能的错误 |
| | | local status, err = pcall(function() |
| | | -- 1. 获取xml数据包 |
| | | local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "201", "无法获取数据包: " .. tostring(soap_xml)) |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | -- 2. 解析xml |
| | | local nRet, parsed_data = xml.parse(soap_xml) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "202", "xml格式非法") |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | -- 3. 使用深度遍历查找关键节点 |
| | | local inventory_input = deep_find_xml_node(parsed_data, {"Envelope", "Body", "InventoryReq", "Inventory_Input"}) |
| | | if not inventory_input then |
| | | FinalRes = Create_result("failure", "206", "XML结构错误: 缺少Inventory_Input节点") |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | local input_params = deep_find_xml_node(inventory_input, {"InputParameters"}) |
| | | if not input_params then |
| | | FinalRes = Create_result("failure", "207", "XML结构错误: 缺少InputParameters节点") |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | local inventory_tb = deep_find_xml_node(input_params, {"Inventory_TB"}) |
| | | if not inventory_tb then |
| | | FinalRes = Create_result("failure", "208", "XML结构错误: 缺少Inventory_TB节点") |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | -- 4. 提取查询参数 |
| | | local query_params = { |
| | | storerId = deep_find_xml_node(inventory_tb, {"storerId"}) or "", |
| | | ownerId = deep_find_xml_node(inventory_tb, {"ownerId"}) or "", |
| | | skuId = deep_find_xml_node(inventory_tb, {"skuId"}) or "", |
| | | productLine = deep_find_xml_node(inventory_tb, {"productLine"}) or "", |
| | | locationId = deep_find_xml_node(inventory_tb, {"locationId"}) or "", |
| | | produceCode = deep_find_xml_node(inventory_tb, {"produceCode"}) or "" |
| | | } |
| | | |
| | | -- 5. 参数校验 |
| | | if query_params.storerId == "" then |
| | | FinalRes = Create_result("failure", "203", "storerId不能为空") |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | if query_params.skuId == "" then |
| | | FinalRes = Create_result("failure", "204", "skuId不能为空") |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | -- 6. 查询库存明细 |
| | | local nRet, query_result = query_inventory_detail(strLuaDEID, query_params) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "205", "查询库存明细失败: " .. tostring(query_result)) |
| | | error(FinalRes.message) |
| | | end |
| | | |
| | | -- 7. 处理查询结果 |
| | | if not query_result or #query_result == 0 then |
| | | FinalRes = Create_result("success", "0", "未查询到符合条件的库存记录", {}) |
| | | else |
| | | FinalRes = Create_result("success", "0", "查询成功!", query_result) |
| | | end |
| | | end) |
| | | |
| | | -- 处理错误情况 |
| | | if not status then |
| | | if FinalRes.code == "0" then |
| | | FinalRes = Create_result("failure", "299", "系统内部错误: " .. tostring(err)) |
| | | end |
| | | end |
| | | |
| | | -- 生成XML结果 |
| | | xml_result = generate_raw_xml(FinalRes) |
| | | |
| | | -- 返回结果 |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | |
| | | -- 记录错误日志 |
| | | if not status then |
| | | lua.Stop(strLuaDEID, "处理过程中发生错误", FinalRes) |
| | | end |
| | | end |