--- --- Created by wsz. --- DateTime: 2025/5/15 下午3:31 --- --[[ 编码: GK-API-07 名称: 订单取消接口 作者: wsz 入口函数:Order_Sync 功能说明: 接收报文创建 Order_Hold 实体 ,对于已存在的数据无条件更新,返回报无需创建还货单 ;新增的数据设置需要创建还货单 变更历史:v0.0.1 注意: 1、按照此报文形式,这应是单条发送 2、报文解析项少了来源单号、拦截类型、:存储时 来源单号不填,拦截类型填Interface 3、needReturnOrder 仅 根据出库单的状态会涉及到 订单类型: asn 入库订单 so出库订单 inventory 盘点单 三者单据的主键no-与报文的taskId 对应 入库单和盘点单已执行不允许取消,出库单订单未完成都允许取消,允许取消才插入Order_Hold ----------------------------------------- 入库单 Inbound_Order no | b_state 状态为N_B_STATE>=20 AND N_B_STATE<=55 不允许取消 取消插入Order_Hold 表 同时更新N_BSTATE=91 盘点单 Count_Order count_no | b_state 状态为N_B_STATE>=20 AND N_B_STATE<=50不允许取消, 取消插入Order_Hold 表 同时更新N_BSTATE=91 出库单 Outbound_Order no | b_state 状态为N_B_STATE IN(50,55,90,91)不允许取消, ,取消插入Order_Hold 表, 如果状态N_B_STATE>=25 AND N_B_STATE<=55,出参needReturnOrder=1 --]] local json = require("json") local mobox = require("OILua_JavelinExt") local m3 = require("oi_base_mobox") local xml = require("oi_base_xml") --- 实体标识-订单取消同步 TN_ORDER_CANCEL local CLSID_OrderHold = "Order_Hold" local CLSID_OrderHold_desc = "订单取消接口" --- 实体标识-入库单 local CLSID_InboundOrder = "Inbound_Order" --- 实体标识-出库单 local CLSID_OutboundOrder = "Outbound_Order" --- 实体标识-盘点单 local CLSID_CountOrder = "Count_Order" --根标签 local RootTag = "response" ----- 出库单 -状态列表 --local STATUS_array_OutboundOrder = {"0"} ----- 入库单 - 状态列表 --local STATUS_array_Inbound_Order = {"0"} ----- 盘点单 - 状态列表 --local STATUS_array_Count_Order = {"0"} -- local luaDEID local ERR -- 返回部分----------------------------------------- --[[ -- 事务回滚-返回信息后终止执行 ]] local function result_transaction_back(strLuaDEID, msg) -- 回滚当次处理 lua.Stop(strLuaDEID, msg) lua.Debug(strLuaDEID, debug.getinfo(1), "result_transaction_back-Stop 执行完毕", "") local result = {} result.flag = "failure" -- success|failure result.code = 5 result.message = msg 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 error(msg,0) -- lua.Error(strLuaDEID, debug.getinfo(1), xmlstr) end --[[ -- 执行成功 ]] local function result_success(strLuaDEID,needReturnOrder,msg) local result = {} result.flag = "success" -- success|failure result.code = 0 result.message = msg if needReturnOrder then -- nil false result.needReturnOrder = needReturnOrder end 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_failure(strLuaDEID,msg) local result = {} result.flag = "failure" -- success|failure result.code = 0 result.message = msg 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_failure-执行mobox.returnValue失败 ' .. nRet) end end end ------------------------------------------- -- util-------------------- ------------------------ -- mergeTablesDeep辅助-递归 local function deepCopy(original) if type(original) ~= 'table' then return original end local copy = {} for key, value in pairs(original) do copy[key] = deepCopy(value) end return copy end -- 将tableb合并到tablea local function mergeTablesDeep(tablea, tableb) local bCopy = deepCopy(tableb) for key, value in pairs(bCopy) do tablea[key] = value end return tablea end --[[ strClsID: 数据类id dataObj:待创建的数据对象 --]] local function create_obj(strLuaDEID, strClsID, dataObj) -- 基础验证 if (nil == strClsID or strClsID == '') then result_transaction_back(strLuaDEID, CLSID_OrderHold_desc .. "-创建对象失败,strClsID不可为空") end if type(dataObj) ~= 'table' then result_transaction_back(strLuaDEID, CLSID_OrderHold_desc .. "-创建对象失败,dataObj必须为table类型") end -- local creatobj = m3.AllocObject(strLuaDEID, strClsID) mergeTablesDeep(creatobj, dataObj) local nRet, resultData = m3.CreateDataObj(strLuaDEID, creatobj) if (nRet ~= 0) then result_transaction_back(strLuaDEID, string.format("创建对象[%s]失败,msg:%s", strClsID, resultData)) end end --[[ param table:字符串数组 value:要判断是否存在的值 return true:存在 false:不存在 ]] local function contains(table, value) for _, v in ipairs(table) do if v == value then return true end end return false end --[[ 组装临时对象 ]] local function buildTemp(dataSet) local temp = {} -- 放置待创建数据 -- 任务编号 temp.no = lua.Get_StrAttrValue(dataSet.taskId) -- 订单类型 temp.no_type = lua.Get_StrAttrValue(dataSet.taskType) -- 来源单号 temp.bs_no = "" -- 货主编码 temp.storer = lua.Get_StrAttrValue(dataSet.storerId) -- 物权 temp.owner = lua.Get_StrAttrValue(dataSet.ownerId) -- 拦截类型 temp.hold_type = "Interface" -- 状态 temp.state = "10" -- 取消原因 temp.note = lua.Get_StrAttrValue(dataSet.reason) return temp end --[[ desc:更新目标数据 ]] local function updateBussData(strLuaDEID, dataSet, id) local temp = buildTemp(dataSet) local attrValueObj do -- 取得 可用来更新数据库的 attr-value 的 table 类型 [attrValueObj] -- luaJsonToObjAttrs 执行后返回的str_data_attrset 是字符串,且attr 是数据库字符串 需反序列化处理为table local nRet, str_data_attrset = mobox.luaJsonToObjAttrs(CLSID_OrderHold, json.encode(temp)) if nRet ~= 0 then result_transaction_back(strLuaDEID, CLSID_OrderHold ..' 更新时luaJsonToObjAttrs执行失败,详细:' .. str_data_attrset) end -- 反序列化为目标格式 attrValueObj = json.decode(str_data_attrset) end -- 当程序可以运行以下时 - 认为 if nRet == 0 --- 执行upd逻辑 lua.Debug(strLuaDEID, debug.getinfo(1), "attrValueObj", attrValueObj) -- 组装批量更新的数据格式 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_OrderHold .."-update准备覆盖已有数据", updateStrDataJson) local nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, CLSID_OrderHold, updateStrDataJson) if (nRet ~= 0) then result_transaction_back(strLuaDEID, string.format(CLSID_OrderHold .."更新操作失败。code:%s,msg:%s", nRet, strRetInfo)) end end --[[ desc:创建目标数据 ]] local function creatBussData(strLuaDEID, dataSet) -- 前置判断 if dataSet.taskType == nil and lua.trim(dataSet.taskType) == "" then result_transaction_back(strLuaDEID, string.format([[ %s 数据验证-操作失败。%s ]], CLSID_OrderHold, "报文‘订单类型(taskType)’-字段,不可为空")) end -- 允许创建‘订单取消实体’标记 - 暂留 local FLAG = false -- 仅用于出库单组装返回报文用 nil、 0、 1 local needReturnOrder -- 1. 出库订单判断-Outbound_Order if dataSet.taskType == "so" then lua.Debug(strLuaDEID, debug.getinfo(1), "订单类型-出库订单", dataSet.taskType) local strCondition do local filters = {} table.insert(filters, string.format([[ %s = '%s' ]], "S_NO", lua.Get_StrAttrValue(dataSet.taskId))) strCondition = table.concat(filters, " and ") lua.Debug(strLuaDEID, debug.getinfo(1), "filters-组装 出库订单 的where条件", strCondition) end -- strRetInfo:str attr-value 型的数据 local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, CLSID_OutboundOrder, strCondition) if nRet == 0 then local luaDataArray = json.decode(strRetInfo) lua.Debug(strLuaDEID, debug.getinfo(1), "出库单-luaDataArray", luaDataArray) local luaData = m3.KeyValueAttrsToObjAttr(luaDataArray) lua.Debug(strLuaDEID, debug.getinfo(1), "出库单-luaData", luaData) --local state = lua.Get_StrAttrValue( luaData.b_state) local state = lua.Get_StrAttrValue( luaData.N_B_STATE) lua.Debug(strLuaDEID, debug.getinfo(1), "出库订单 b_state", state) FLAG = not contains( { "50","55","90","91" },state ) --包含状态不准取消 if FLAG then local state_toNum = lua.Get_NumAttrValue(state) needReturnOrder = (state_toNum >=25 and state_toNum <= 55 ) and 1 or 0 end elseif nRet == 1 then --目标单据不存在 result_transaction_back(strLuaDEID, string.format([[出库订单-出库单号:%s,不存在!]],lua.Get_StrAttrValue(dataSet.taskId))) else result_transaction_back(strLuaDEID, string.format([[异常:查询出库订单-出库单号:%s,时失败:%s]],lua.Get_StrAttrValue(dataSet.taskId),strRetInfo)) end end -- 2. 入库单-Inbound_Order if dataSet.taskType == "asn" then lua.Debug(strLuaDEID, debug.getinfo(1), "订单类型-入库单", dataSet.taskType) local strCondition do local filters = {} table.insert(filters, string.format([[ %s = '%s' ]], "S_NO", lua.Get_StrAttrValue(dataSet.taskId))) strCondition = table.concat(filters, " and ") lua.Debug(strLuaDEID, debug.getinfo(1), "filters-组装 入库单 的where条件", strCondition) end -- strRetInfo:str attr-value 型的数据 local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, CLSID_InboundOrder, strCondition) --local nRet, id, strRetInfo = mobox.GetDataObjByCondition(strLuaDEID, CLSID_InboundOrder, strCondition) if nRet == 0 then local luaDataArray = json.decode(strRetInfo) --lua.Debug(strLuaDEID, debug.getinfo(1), "入库单 strRetInfo 类型", type(strRetInfo)) --lua.Debug(strLuaDEID, debug.getinfo(1), "入库单 strRetInfo", strRetInfo) --local luaJson = m3.objAttrsToLuaJson(CLSID_InboundOrder,strRetInfo) --lua.Debug(strLuaDEID, debug.getinfo(1), "入库单 luaJson", luaJson) local luaData = m3.KeyValueAttrsToObjAttr(luaDataArray) lua.Debug(strLuaDEID, debug.getinfo(1), "入库单 luaData", luaData) --FLAG = contains( STATUS_array_OutboundOrder, lua.Get_StrAttrValue( luaData.b_state)) --local state = lua.Get_StrAttrValue( luaData.b_state) local state = lua.Get_StrAttrValue( luaData.N_B_STATE) lua.Debug(strLuaDEID, debug.getinfo(1), "入库单 b_state", state) local state_toNum = lua.Get_NumAttrValue(state) FLAG = not (state_toNum >=20 and state_toNum <= 55 ) if FLAG then -- 需要更新 入库单 N_BSTATE=91 local temp = {} temp.b_state = 91 local nRet, str_data_attrset = mobox.luaJsonToObjAttrs(CLSID_InboundOrder, json.encode(temp)) if nRet ~= 0 then result_transaction_back(strLuaDEID, '更新入库单状态b_state时 luaJsonToObjAttrs 函数执行失败!msg:' .. 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), "入库单-update准备覆盖已有数据", updateStrDataJson) local nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, CLSID_InboundOrder, updateStrDataJson) if (nRet ~= 0) then result_transaction_back(strLuaDEID, string.format("入库单更新操作失败!code:%s,msg:%s", nRet, strRetInfo)) end end elseif nRet == 1 then --目标单据不存在 result_transaction_back(strLuaDEID, string.format([[入库单-入库单号:%s,不存在!]],lua.Get_StrAttrValue(dataSet.taskId))) else result_transaction_back(strLuaDEID, string.format([[异常:查询入库单-入库单号:%s,时失败:%s]],lua.Get_StrAttrValue(dataSet.taskId),strRetInfo)) end end -- 3. 盘点单-Count_Order if dataSet.taskType == "inventory" then lua.Debug(strLuaDEID, debug.getinfo(1), "订单类型-盘点单", dataSet.taskType) local strCondition do local filters = {} table.insert(filters, string.format([[ %s = '%s' ]], "S_COUNT_NO", lua.Get_StrAttrValue(dataSet.taskId))) strCondition = table.concat(filters, " and ") lua.Debug(strLuaDEID, debug.getinfo(1), "filters-组装 盘点单 的where条件", strCondition) end -- strRetInfo:str attr-value 型的数据 local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, CLSID_CountOrder, strCondition) if nRet == 0 then local luaDataArray = json.decode(strRetInfo) lua.Debug(strLuaDEID, debug.getinfo(1), "盘点单-luaDataArray", luaDataArray) local luaData = m3.KeyValueAttrsToObjAttr(luaDataArray) local state = lua.Get_StrAttrValue( luaData.N_B_STATE) lua.Debug(strLuaDEID, debug.getinfo(1), "盘点单 b_state", state) local state_toNum = lua.Get_NumAttrValue(state) FLAG = not (state_toNum >=20 and state_toNum <= 50 ) if FLAG then -- 需要更新 盘点单 N_BSTATE=91 local temp = {} temp.b_state = 91 local nRet, str_data_attrset = mobox.luaJsonToObjAttrs(CLSID_CountOrder, json.encode(temp)) if nRet ~= 0 then result_transaction_back(strLuaDEID, '更新盘点单状态b_state时 luaJsonToObjAttrs 函数执行失败!msg:' .. 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), "盘点单-update准备覆盖已有数据", updateStrDataJson) local nRet, strRetInfo = mobox.updateDataObj(strLuaDEID, CLSID_CountOrder, updateStrDataJson) if (nRet ~= 0) then result_transaction_back(strLuaDEID, string.format("盘点单更新操作失败!code:%s,msg:%s", nRet, strRetInfo)) end end elseif nRet == 1 then --目标单据不存在 result_transaction_back(strLuaDEID, string.format([[盘点单-盘点单号:%s,不存在!]],lua.Get_StrAttrValue(dataSet.taskId))) else result_transaction_back(strLuaDEID, string.format([[异常:查询盘点单-盘点单号:%s,时失败:%s]],lua.Get_StrAttrValue(dataSet.taskId),strRetInfo)) end end ------ if not FLAG then result_failure(strLuaDEID, "目标单据状态不满足取消条件!不会生成‘单据取消’记录!") return -- 结束后续执行 end -- 创建取消单记录 local temp = buildTemp(dataSet) lua.Debug(strLuaDEID, debug.getinfo(1), "OrderHold待新增数据-temp", temp) create_obj(strLuaDEID, CLSID_OrderHold, temp) -- 返回数据 result_success(strLuaDEID,needReturnOrder) end --[[ 业务数据处理 ]] local function bussHandle(strLuaDEID, dataSet) -- 组装sql过滤条件 local strCondition do local filters = {} table.insert(filters, string.format([[ %s = '%s' ]], "S_NO", lua.Get_StrAttrValue(dataSet.taskId))) strCondition = table.concat(filters, " and ") lua.Debug(strLuaDEID, debug.getinfo(1), "filters-组装的ordercancel的where条件", strCondition) end local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, CLSID_OrderHold, strCondition) if nRet == 0 then -- key已存在 lua.Debug(strLuaDEID, debug.getinfo(1), "add", "数据更新:" .. strRetInfo) -- updateBussData(strLuaDEID, dataSet, id) --result_failure(strLuaDEID, string.format("任务id:%s 已存在",id)) result_success(strLuaDEID, nil,string.format("任务id:%s 已存在",id)) elseif nRet == 1 then -- key不存在 lua.Debug(strLuaDEID, debug.getinfo(1), "upd", "数据新增") creatBussData(strLuaDEID, dataSet) else result_transaction_back(strLuaDEID, string.format("查询目标数据失败,code:%s,msg:%s", nRet, strRetInfo)) end -- result_success(strLuaDEID,1) -- 更新的数据不需要创建 WMS还货入库单 end local function Order_Cancel_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-07xml报文", 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"] ["OrderCancellationReq"] ["OrderCancellation_Input"] ["InputParameters"] ["OrderCancellation_TB"] if nil == dataSet then -- wms_base.Warning(strLuaDEID, 2, 201, CLSID_OrderHold_desc .."-未解析到soap目标节点!", json.encode(dataSet), "", CLSID_OrderHold_desc .."-dataSet") result_transaction_back(strLuaDEID, CLSID_OrderHold_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 end --[[ 固定-错误捕获处理 ]] local function errorHandler(err) ERR = err lua.Debug(luaDEID, debug.getinfo(1), "err-记录", err) --lua.Error(strLuaDEID, debug.getinfo(1), "err-记录:" .. err) return err end --[[ 入口函数 ]] function Order_Cancel(strLuaDEID) luaDEID = strLuaDEID local success, result = xpcall(Order_Cancel_main, errorHandler,strLuaDEID) if not success then -- lua.Error(strLuaDEID, debug.getinfo(1), ERR) end end