1. SKU数据同步代码更新返回格式,修复返回非xml报文格式问题
2. 盘点数据同步代码优化
3. 小件收货品信息同步代码优化
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> |
| | | |
| | | 响应示例: |
| | | <flag>sucess</flag> |
| | | <code>0</code> |
| | | <message>成功</message> |
| | | ]] --[[ |
| | | 功能:盘点计划同步接口(支持多主表+多明细) |
| | | 作者:袁峰 |
| | | 入口函数:Count_Pan_Sync |
| | | 说明:解析 xml,支持多个 InventoryTasks_TB(主表),每个主表下可包含多个明细(InventoryTasks_TB_ITEM) |
| | | ]] -- |
| | | -- 引入依赖库 |
| | | wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | mobox = require("OILua_JavelinExt") |
| | | m3 = require("oi_base_mobox") |
| | | -- 创建统一返回结果 |
| | | function Create_result(flag, code, msg, error) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "", |
| | | error = error or "" |
| | | } |
| | | end |
| | | |
| | | function Count_Pan_Sync(strLuaDEID) |
| | | -- 1. 获取 xml 数据包 |
| | | local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "201", "无法获取数据包: " .. soap_xml) |
| | | 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 格式非法") |
| | | lua.Stop(strLuaDEID, "xml格式非法", FinalRes) |
| | | return |
| | | end |
| | | |
| | | -- 3. 提取主表数据(可能多个 InventoryTasks_TB) |
| | | 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") |
| | | lua.Stop(strLuaDEID, "xml 数据格式错误", FinalRes) |
| | | return |
| | | end |
| | | |
| | | -- 4. 判断 InventoryTasks_TB 是单个对象还是数组 |
| | | -- xml 解析后,如果只有一个 InventoryTasks_TB,可能返回 table;多个则可能是数组 |
| | | local mainTables = input_params.InventoryTasks_TB |
| | | if not mainTables then |
| | | FinalRes = Create_result("failure", "204", "xml 数据格式错误,InventoryTasks_TB 为空") |
| | | lua.Stop(strLuaDEID, "xml 数据格式错误", FinalRes) |
| | | return |
| | | end |
| | | -- 5. 统一处理:确保 mainTables 是数组(即使只有一个主表) |
| | | if mainTables[1] == nil then |
| | | -- 如果 mainTables 不是数组(单个主表),则包装成数组 |
| | | mainTables = {mainTables} |
| | | end |
| | | -- 6. 遍历所有主表数据 |
| | | local result = Create_result() |
| | | for i = 1, #mainTables do |
| | | local mainData = mainTables[i] |
| | | -- lua.DebugEx(strLuaDEID, "主表任务ID:", mainData.taskId) |
| | | -- 创建主表数据 |
| | | local count_plan = m3.AllocObject(strLuaDEID, "Count_Plan") |
| | | count_plan.cp_no = mainData.taskId; -- 盘点计划号 |
| | | count_plan.inventory_mode = mainTables[i].inventoryMode; -- 盘点方式 |
| | | count_plan.work_mode = mainData.workMode; -- 作业方式 |
| | | count_plan.count_limit = mainData.MaintenanceNumber; -- 盘点数量限制 |
| | | count_plan.type = mainTables[i].inventoryType; -- 盘点类型 |
| | | count_plan.bs_no = mainData.orderNo; -- 来源单号 |
| | | count_plan.storeId = mainData.storer; -- 货主编码 |
| | | count_plan.ownerId = mainData.owner; -- 物权 |
| | | count_plan.begin_time = mainData.mtBeginDate; -- 动碰开始时间 |
| | | count_plan.end_time = mainData.mtEndDate; -- 动碰结束时间 |
| | | count_plan.prod_line = mainData.productLine; -- 产品线 |
| | | count_plan.begin_location = mainData.beginLocation; -- 开始库位 |
| | | count_plan.end_location = mainData.endLocation; -- 结束库位 |
| | | count_plan.area_code = mainData.areaCode; -- 库区 |
| | | count_plan.op_date = mainData.orderDate; -- 订单日期 |
| | | count_plan.priority = mainData.priority; -- 优先级 |
| | | count_plan.note = mainData.memo; -- 备注 |
| | | -- count_plan.type = wms_base.Get_nConst2(strLuaDEID, "WMS_CountType") |
| | | count_plan.plan_total = 0; -- 计划盘点数 |
| | | count_plan.b_state = 0; |
| | | local RetWH_COE, CONST_WH = wms_base.Get_sConst2(strLuaDEID, "GK_Default_Warehouse") |
| | | if (RetWH_COE ~= 0) then |
| | | FinalRes = Create_result("failure", "201", "获取仓库常量失败", CONST_WH) |
| | | lua.Stop(strLuaDEID, "获取仓库常量失败", CONST_WH) |
| | | else |
| | | count_plan.wh_code = CONST_WH; -- 仓库 |
| | | count_plan.acc_finish = 0; |
| | | end |
| | | lua.DebugEx(strLuaDEID, "创建的表单:", count_plan); |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, count_plan) |
| | | if nRet ~= 0 then |
| | | result.flag = "failure" |
| | | result.code = "102" |
| | | result.message = "创建主表数据失败" |
| | | result.error = "行号[" .. count_plan.cp_no .. "]创建失败: " .. ret_info |
| | | lua.DebugEx(strLuaDEID, "主表数据创建失败: ", ret_info) |
| | | FinalRes = Create_result("failure", "205", "主表数据创建失败: ", ret_info) |
| | | lua.Stop(strLuaDEID, "创建主表数据失败" .. count_plan.cp_no, ret_info) |
| | | end |
| | | -- 检查明细数据是否存在 |
| | | if not mainData.InventoryTasks_TB_ITEM 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 = item.qty; -- 计划数量 |
| | | count_plan_item.wms_bn = item.batchNo; -- WMS批次编号 |
| | | count_plan_item.batch_no = item.produceCode; -- 生产批次 |
| | | count_plan_item.prd_date = item.productDate; -- 生产日期 |
| | | count_plan_item.exp_date = item.expiryDate; -- 有效期 |
| | | count_plan_item.reg_no = item.registerNo; -- 商品编码 |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, count_plan_item) |
| | | if nRet ~= 0 then |
| | | result.flag = "failure" |
| | | result.code = "102" |
| | | result.message = "创建明细数据失败" |
| | | result.error = "行号[" .. count_plan_item.row_no .. "]创建失败: " .. ret_info |
| | | FinalRes = Create_result("failure", "206", "明细表数据创建失败: ", ret_info) |
| | | lua.DebugEx(strLuaDEID, "明细表数据创建失败: ", ret_info) |
| | | lua.Stop(strLuaDEID, "创建明细表数据失败" .. count_plan.cp_no, ret_info) |
| | | else |
| | | lua.DebugEx(strLuaDEID, "明细数据创建成功!", count_plan_item) |
| | | end |
| | | end |
| | | end |
| | | end |
| | | |
| | | -- 8. 返回成功 |
| | | 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> |
| | | <!-- 第一个收货单 --> |
| | | <v1:SmallPiece_TB> |
| | | <v1:orderNo>SO2025050701</v1:orderNo> |
| | | <v1:asnNo>KPD00002</v1:asnNo> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:ownerId>CGKHTY</v1:ownerId> |
| | | <v1:orderDate>2025-05-07</v1:orderDate> |
| | | <v1:priority>0</v1:priority> |
| | | <v1:memo>收货单1备注</v1:memo> |
| | | <v1:SmallPiece_TB_ITEM> |
| | | <v1:orderItemId>1</v1:orderItemId> |
| | | <v1:skuId>100118100</v1:skuId> |
| | | <v1:skuStatus>AVL</v1:skuStatus> |
| | | <v1:qty>3</v1:qty> |
| | | <v1:batchNo>PHI00000000000001310</v1:batchNo> |
| | | <v1:produceCode>YL201126</v1:produceCode> |
| | | <v1:productDate>2016-05-23</v1:productDate> |
| | | <v1:expiryDate>2099-12-31</v1:expiryDate> |
| | | <v1:registerNo>国食药监械(准)字2013</v1:registerNo> |
| | | </v1:SmallPiece_TB_ITEM> |
| | | <v1:SmallPiece_TB_ITEM> |
| | | <v1:orderItemId>2</v1:orderItemId> |
| | | <v1:skuId>100117231</v1:skuId> |
| | | <v1:skuStatus>AVL</v1:skuStatus> |
| | | <v1:qty>4</v1:qty> |
| | | <v1:batchNo>PHI00000000000001311</v1:batchNo> |
| | | <v1:produceCode>YL201127</v1:produceCode> |
| | | <v1:productDate>2023-05-23</v1:productDate> |
| | | <v1:expiryDate>2099-12-31</v1:expiryDate> |
| | | <v1:registerNo></v1:registerNo> |
| | | </v1:SmallPiece_TB_ITEM> |
| | | </v1:SmallPiece_TB> |
| | | <!-- 第二个收货单 --> |
| | | <v1:SmallPiece_TB> |
| | | <v1:orderNo>SO2025050702</v1:orderNo> |
| | | <v1:asnNo>KPD00003</v1:asnNo> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:ownerId>CGKHTY</v1:ownerId> |
| | | <v1:orderDate>2025-05-07</v1:orderDate> |
| | | <v1:priority>1</v1:priority> |
| | | <v1:memo>收货单2备注</v1:memo> |
| | | <v1:SmallPiece_TB_ITEM> |
| | | <v1:orderItemId>1</v1:orderItemId> |
| | | <v1:skuId>200000002</v1:skuId> |
| | | <v1:skuStatus>AVL</v1:skuStatus> |
| | | <v1:qty>2</v1:qty> |
| | | <v1:batchNo>PHI00000000000001312</v1:batchNo> |
| | | <v1:produceCode>YL201128</v1:produceCode> |
| | | <v1:productDate>2016-06-23</v1:productDate> |
| | | <v1:expiryDate>2099-12-31</v1:expiryDate> |
| | | <v1:registerNo>国食药监械(准)字2014</v1:registerNo> |
| | | </v1:SmallPiece_TB_ITEM> |
| | | <v1:SmallPiece_TB_ITEM> |
| | | <v1:orderItemId>2</v1:orderItemId> |
| | | <v1:skuId>100117238</v1:skuId> |
| | | <v1:skuStatus>AVL</v1:skuStatus> |
| | | <v1:qty>5</v1:qty> |
| | | <v1:batchNo>PHI00000000000001313</v1:batchNo> |
| | | <v1:produceCode>YL201129</v1:produceCode> |
| | | <v1:productDate>2023-06-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, error) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "", |
| | | error = error or "" |
| | | } |
| | | end |
| | | |
| | | function Receipt_Sync(strLuaDEID) |
| | | -- 1. 获取 xml 数据包 |
| | | local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "201", "无法获取数据包: " .. soap_xml) |
| | | lua.Stop(strLuaDEID, "获取数据包失败", FinalRes) |
| | | |
| | | end |
| | | |
| | | -- 2. 解析 xml |
| | | local nRet, parsed_data = xml.parse(soap_xml) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "202", "xml 格式非法") |
| | | lua.Stop(strLuaDEID, "xml格式非法", FinalRes) |
| | | |
| | | 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") |
| | | lua.Stop(strLuaDEID, "xml 数据格式错误", FinalRes) |
| | | 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(strLuaDEID, "GK_Default_Warehouse") |
| | | local RetFAC_COE, CONST_FACTORY = wms_base.Get_sConst2(strLuaDEID, "GK_Default_Factory") |
| | | if (RetWH_COE ~= 0 or RetFAC_COE ~= 0) then |
| | | FinalRes = Create_result("failure", "204", "获取仓库/工厂常量失败") |
| | | lua.Stop(strLuaDEID, "获取系统常量失败", FinalRes) |
| | | return |
| | | end |
| | | |
| | | -- 6. 遍历所有收货单 |
| | | local result = Create_result() |
| | | for i = 1, #receipt_headers do |
| | | local header = receipt_headers[i] |
| | | |
| | | -- 检查收货单是否已存在 |
| | | local strCondition = string.format("S_NO = '%s'", header.orderNo) |
| | | lua.DebugEx(strLuaDEID, "SQL 条件", strCondition) |
| | | local nRet, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "Receipt_Order", strCondition) |
| | | if nRet == 0 then |
| | | FinalRes = Create_result("failure", "205", "收货单已存在", |
| | | "收货单[" .. header.orderNo .. "]已存在") |
| | | lua.Stop(strLuaDEID, "收货单已存在", FinalRes) |
| | | |
| | | elseif nRet > 1 then |
| | | FinalRes = Create_result("failure", "206", "系统错误", |
| | | "检查收货单是否存在时出错: " .. strRetInfo) |
| | | lua.Stop(strLuaDEID, "检查收货单是否存在时出错", FinalRes) |
| | | |
| | | 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 |
| | | lua.DebugEx(strLuaDEID, "创建的表单:", receipt); |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "207", "创建收货单主表失败", |
| | | "收货单[" .. header.orderNo .. "]创建失败: " .. ret_info) |
| | | lua.Stop(strLuaDEID, "创建收货单主表失败", FinalRes) |
| | | |
| | | end |
| | | |
| | | -- 检查明细数据是否存在 |
| | | if not header.SmallPiece_TB_ITEM then |
| | | lua.DebugEx(strLuaDEID, "警告:收货单 " .. header.orderNo .. " 无明细数据") |
| | | else |
| | | -- 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] |
| | | -- 创建明细数据 |
| | | 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.wu = "kg" |
| | | receipt_detail.batch_no = item.produceCode |
| | | 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 |
| | | |
| | | -- 获取物料信息 |
| | | if item.skuId ~= nil then |
| | | local nRet, mat_info = m3.GetDataObjByCondition(strLuaDEID, "Material", |
| | | "S_ITEM_CODE='" .. item.skuId .. "'") |
| | | if nRet == 0 then |
| | | receipt_detail.item_name = mat_info.item_name or "" |
| | | receipt_detail.net_weight = mat_info.weight or 0 |
| | | receipt_detail.gross_weight = mat_info.weight or 0 |
| | | receipt_detail.uom = mat_info.uom or "" |
| | | end |
| | | end |
| | | |
| | | local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt_detail) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "208", "创建收货明细失败", |
| | | "行号[" .. item.orderItemId .. "]创建失败: " .. ret_info) |
| | | lua.Stop(strLuaDEID, "创建收货明细失败", FinalRes) |
| | | |
| | | 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 |
| | |
| | | --[[ |
| | | 编码: GK-API-001 |
| | | 名称: 盘点计划同步 |
| | | 作者: HAN |
| | | 日期: 2025-1-29 |
| | | |
| | | 入口函数: SKU_Sync |
| | | 来源项目: 国科项目 |
| | | |
| | | 功能说明: |
| | | 1. 接收来自上游系统的 XML 格式数据,并解析该数据, 创建SKU及SKU_UPC |
| | | |
| | | <soapenv:Envelope |
| | | xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> |
| | | <soap:Header |
| | | xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> |
| | | </soap:Header> |
| | | <soapenv:Body> |
| | | <v1:inCommodityReq |
| | | xmlns:v1="http://www.gkht.com/Information/INV/Ebs/Schemas/InCommodity/V1.0"> |
| | | <v1:COMMODITY_Input> |
| | | <v1:RESTHeader> |
| | | <v1:Responsibility/> |
| | | <v1:RespApplication/> |
| | | <v1:SecurityGroup/> |
| | | <v1:NLSLanguage>SIMPLIFIED CHINESE</v1:NLSLanguage> |
| | | <v1:Org_Id>0</v1:Org_Id> |
| | | </v1:RESTHeader> |
| | | <v1:InputParameters> |
| | | <v1:COMMODITY_TB> |
| | | <!--1 or more repetitions:--> |
| | | <v1:COMMODITY_TB_ITEM> |
| | | <v1:skuId>KH32803017</v1:skuId> |
| | | <v1:storerId>CGKHTY</v1:storerId> |
| | | <v1:skuName>螺旋刀片式髓内钉</v1:skuName> |
| | | <v1:skuDec>螺旋刀片式股骨近端髓内钉10×170</v1:skuDec> |
| | | <v1:spec>JGDⅥ φ10×170</v1:spec> |
| | | <v1:packageCode>个</v1:packageCode> |
| | | <v1:packageQty>1</v1:packageQty> |
| | | <v1:goodsUnit>件</v1:goodsUnit> |
| | | <v1:length>1</v1:length> |
| | | <v1:width>2</v1:width> |
| | | <v1:height>3</v1:height> |
| | | <v1:abcType></v1:abcType> |
| | | <v1:isBatchMgr>1</v1:isBatchMgr> |
| | | <v1:isSnMgr>1</v1:isSnMgr> |
| | | <v1:isSnStorageMgr>0</v1:isSnStorageMgr> |
| | | <v1:imgUrl></v1:imgUrl> |
| | | <v1:cidtype>A</v1:cidtype> |
| | | <v1:productLine>KH-创伤</v1:productLine> |
| | | <v1:storageConditions>常温</v1:storageConditions> |
| | | <v1:skuType>small</v1:skuType> |
| | | <v1:maxCount>50</v1:maxCount> |
| | | <v1:sptm></v1:sptm> |
| | | <v1:barcode1></v1:barcode1> |
| | | <v1:barcode2></v1:barcode2> |
| | | <v1:barcode3></v1:barcode3> |
| | | <v1:barcode_pk></v1:barcode_pk> |
| | | </v1:COMMODITY_TB_ITEM> |
| | | </v1:COMMODITY_TB> |
| | | </v1:InputParameters> |
| | | </v1:COMMODITY_Input> |
| | | </v1:inCommodityReq> |
| | | </soapenv:Body> |
| | | </soapenv:Envelope> |
| | | |
| | | 更改记录: |
| | | V2.0 HAN 20250402 代码规范 |
| | | |
| | | V2.1 Yuanfeng |
| | | 1. 统一了返回结果格式,使用Create_result函数创建标准化的返回结构 |
| | | 2. 优化了代码结构 |
| | | --]] wms_base = require("wms_base") |
| | | xml = require("oi_base_xml") |
| | | mobox = require("OILua_JavelinExt") |
| | | m3 = require("oi_base_mobox") |
| | | |
| | | -- 创建统一返回结果 |
| | | function Create_result(flag, code, msg, error) |
| | | return { |
| | | flag = flag or "success", |
| | | code = code or "0", |
| | | message = msg or "", |
| | | error = error or "" |
| | | } |
| | | end |
| | | |
| | | local function create_sku_upc(strLuaDEID, storer, item_code, upc_code) |
| | | local nRet, strRetInfo |
| | | |
| | | if (upc_code == '' or upc_code == nil) then |
| | | return 0 |
| | | end |
| | | |
| | | -- 创建SKU_UPC |
| | | local sku_upc = m3.AllocObject(strLuaDEID, "SKU_UPC") |
| | | sku_upc.storer = storer |
| | | sku_upc.item_code = item_code |
| | | sku_upc.upc_code = upc_code |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, sku_upc) |
| | | |
| | | return nRet, strRetInfo |
| | | end |
| | | |
| | | local function create_sku(strLuaDEID, sku_input_data) |
| | | local nRet, strRetInfo |
| | | local err_msg = '' |
| | | |
| | | -- 分配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.spec = sku_input_data.spec |
| | | sku.udf01 = sku_input_data.packageCode |
| | | sku.udf02 = sku_input_data.packageQty |
| | | sku.unit = sku_input_data.goodsUnit |
| | | sku.long = lua.Get_NumAttrValue(sku_input_data.length) |
| | | sku.middle = lua.Get_NumAttrValue(sku_input_data.width) |
| | | sku.short = lua.Get_NumAttrValue(sku_input_data.height) |
| | | sku.abc_type = sku_input_data.abcType |
| | | sku.is_life_mgt = (sku_input_data.isBatchMgr == "1" and 'Y') or 'N' |
| | | sku.is_sn_mgt = (sku_input_data.isSnMgr == "1" and 'Y') or 'N' |
| | | sku.udf03 = sku_input_data.isSnStorageMgr |
| | | sku.img_url = sku_input_data.imgUrl |
| | | sku.cell_type = sku_input_data.cidtype |
| | | sku.prod_line = sku_input_data.productLine |
| | | sku.udf04 = sku_input_data.storageConditions |
| | | sku.item_type = sku_input_data.skuType |
| | | sku.loading_limit = lua.Get_NumAttrValue(sku_input_data.maxCount) |
| | | |
| | | -- 检查SKU是否已存在 |
| | | local id |
| | | local strCondition = "S_ITEM_CODE = '" .. sku.item_code .. "' AND S_STORER = '" .. sku.storer .. "'" |
| | | nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "SKU", strCondition) |
| | | |
| | | if nRet > 1 then |
| | | return 1, "检查SKU是否存在时失败: " .. strRetInfo |
| | | end |
| | | |
| | | if nRet == 1 then |
| | | -- SKU不存在,创建新SKU |
| | | nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, sku) |
| | | if nRet ~= 0 then |
| | | return 1, "创建SKU失败: " .. strRetInfo .. " skuId = " .. sku_input_data.skuId |
| | | end |
| | | else |
| | | -- SKU已存在,更新属性 |
| | | local update_sku_obj = {{ |
| | | id = id, |
| | | attrs = {{ |
| | | attr = "S_ITEM_NAME", |
| | | value = sku.item_name |
| | | }, { |
| | | attr = "S_SPEC", |
| | | value = sku.spec |
| | | }, { |
| | | attr = "S_ITEM_TYPE", |
| | | value = sku.item_type |
| | | }, { |
| | | attr = "S_UNIT", |
| | | value = sku.unit |
| | | }, { |
| | | attr = "S_SHORT_NAME", |
| | | value = sku.short_name |
| | | }, { |
| | | attr = "S_ABCTYPE", |
| | | value = sku.abc_type |
| | | }, { |
| | | attr = "C_ISSNMGT", |
| | | value = sku.is_sn_mgt |
| | | }, { |
| | | attr = "C_ISLIFEMGT", |
| | | value = sku.is_life_mgt |
| | | }, { |
| | | attr = "S_IMG_URL", |
| | | value = sku.img_url |
| | | }, { |
| | | attr = "S_CELL_TYPE", |
| | | value = sku.cell_type |
| | | }, { |
| | | attr = "S_PROD_LINE", |
| | | value = sku.prod_line |
| | | }, { |
| | | attr = "N_LOADING_LIMIT", |
| | | value = sku.loading_limit |
| | | }, { |
| | | attr = "F_LONG", |
| | | value = sku.long |
| | | }, { |
| | | attr = "F_MIDDLE", |
| | | value = sku.middle |
| | | }, { |
| | | attr = "F_SHORT", |
| | | value = sku.short |
| | | }, { |
| | | attr = "S_UDF01", |
| | | value = sku.udf01 |
| | | }, { |
| | | attr = "S_UDF02", |
| | | value = sku.udf02 |
| | | }, { |
| | | attr = "S_UDF03", |
| | | value = sku.udf03 |
| | | }, { |
| | | attr = "S_UDF04", |
| | | value = sku.udf04 |
| | | }} |
| | | }} |
| | | |
| | | nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, "SKU", lua.table2str(update_sku_obj)) |
| | | if nRet ~= 0 then |
| | | return 1, "更新SKU属性失败: " .. strRetInfo |
| | | end |
| | | end |
| | | |
| | | -- 处理SKU_UPC |
| | | local upc_codes = {sku_input_data.sptm, sku_input_data.barcode1, sku_input_data.barcode2, sku_input_data.barcode3, |
| | | sku_input_data.barcode_pk} |
| | | |
| | | for _, upc_code in ipairs(upc_codes) do |
| | | if upc_code and upc_code ~= '' then |
| | | nRet, strRetInfo = create_sku_upc(strLuaDEID, sku.storer, sku.item_code, upc_code) |
| | | if nRet ~= 0 then |
| | | return 1, "创建SKU_UPC失败: " .. strRetInfo .. " UPC: " .. upc_code |
| | | end |
| | | end |
| | | end |
| | | |
| | | return 0 |
| | | end |
| | | |
| | | function SKU_Sync(strLuaDEID) |
| | | -- 1. 获取xml数据包 |
| | | local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) |
| | | if nRet ~= 0 then |
| | | FinalRes = Create_result("failure", "201", "无法获取数据包: " .. soap_xml) |
| | | 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格式非法") |
| | | lua.Stop(strLuaDEID, "xml格式非法", FinalRes) |
| | | return |
| | | end |
| | | |
| | | -- 3. 提取SKU数据 |
| | | local sku_data = parsed_data.Envelope.Body.inCommodityReq.COMMODITY_Input.InputParameters.COMMODITY_TB |
| | | if not sku_data or not sku_data.COMMODITY_TB_ITEM then |
| | | FinalRes = Create_result("failure", "203", "xml数据格式错误,缺少COMMODITY_TB_ITEM") |
| | | lua.Stop(strLuaDEID, "xml数据格式错误", FinalRes) |
| | | return |
| | | end |
| | | |
| | | -- 4. 统一处理:确保sku_items是数组(即使只有一个SKU) |
| | | local sku_items = sku_data.COMMODITY_TB_ITEM |
| | | if sku_items[1] == nil then |
| | | sku_items = {sku_items} |
| | | end |
| | | |
| | | -- 5. 遍历所有SKU数据 |
| | | local FinalRes = Create_result() |
| | | for i = 1, #sku_items do |
| | | local sku_item = sku_items[i] |
| | | |
| | | -- 创建SKU及其UPC |
| | | local nRet, err_msg = create_sku(strLuaDEID, sku_item) |
| | | if nRet ~= 0 then |
| | | -- 记录警告日志 |
| | | wms_base.Warning(strLuaDEID, 1, 601, err_msg, "从GK-WMS系统同步SKU信息") |
| | | |
| | | -- 设置错误结果并停止处理 |
| | | FinalRes = Create_result("failure", "204", "SKU同步失败", err_msg) |
| | | lua.Stop(strLuaDEID, "SKU同步失败: " .. sku_item.skuId, FinalRes) |
| | | return |
| | | end |
| | | end |
| | | |
| | | -- 6. 返回成功 |
| | | local xml_result = xml.json_to_xml(FinalRes, "response") |
| | | mobox.returnValue(strLuaDEID, 0, xml_result, 0) |
| | | end |