-- 四舍五入函数 local function round(number, precision) precision = precision or 0 local mult = 10 ^ (precision or 0) return math.floor(number * mult + 0.5) / mult end -- 定义函数用于拆分字符串并转换为数字集合 local function splitAndCollectNumbers(str) local numbers = {} for num in string.gmatch(str, "%d+") do numbers[tonumber(num)] = true end return numbers end -- 定义函数用于找出两个集合中重合的数字并拼接成字符串 local function findCommonNumbers(strA, strB) local setA = splitAndCollectNumbers(strA) local setB = splitAndCollectNumbers(strB) local commonNumbers = {} for num in pairs(setA) do if setB[num] then table.insert(commonNumbers, tostring(num)) end end return table.concat(commonNumbers, ",") end --[ -- PackWorkGeneralOperation 装箱工单入库单入库通用操作 -- 1、获取目视卡信息 -- 2、新增容器货品绑定 -- 3、新增装箱记录 -- 4、更新装箱工单数量 -- 5、更新入库单数量 -- 6、判断装箱工单、入库单是否关闭 -- param: -- serial_no 条码 -- cntr_code 容器编码 -- pack_no 装箱工单号 -- order_no 入库单号 --] local function PackWorkGeneralOperation(strLuaDEID, serial_no, cntr_code, pack_no, order_no, dispersoid) local nRet, strRetInfo, label_card, strCondition --step1 获取目视卡中的信息,用这个卡中的信息创建 CG_Detail strCondition = "S_SERIAL_NO = '" .. serial_no .. "'" nRet, label_card = m3.GetDataObjByCondition(strLuaDEID, "GT_Label_Crad", strCondition) if (nRet ~= 0) then return 2, "m3.GetDataObjByCondition 失败!" .. label_card end -- 目视卡基本属性判断 if (label_card.qty <= 0) then return 1, "目视卡'" .. serial_no .. "'的数量必须有值不能是负数!" end nRet, strRetInfo = wms_cntr.EmptyContainer_Verify(strLuaDEID, cntr_code) if (nRet ~= 0) then return 2, "容器验证失败!" .. strRetInfo end --step2 新增容器货物绑定 local cg_detail = m3.AllocObject(strLuaDEID, "CG_Detail") cg_detail.cntr_code = cntr_code cg_detail.batch_no = label_card.batch_no cg_detail.item_code = label_card.item_code cg_detail.item_name = label_card.item_name cg_detail.qty = label_card.qty cg_detail.uom = 'kg' cg_detail.serial_no = label_card.serial_no lua.Debug(strLuaDEID, debug.getinfo(1), 'cg_detail', cg_detail) nRet, cg_detail = m3.CreateDataObj(strLuaDEID, cg_detail) if (nRet ~= 0) then return 2, 'mobox 创建【容器货品明细】对象失败!' .. cg_detail end --step3 新增【装箱记录】 local packing_record = m3.AllocObject(strLuaDEID, "GT_Packing_Rec") packing_record.pack_no = pack_no packing_record.qty = label_card.qty packing_record.cntr_code = cntr_code packing_record.serial_no = label_card.serial_no nRet, packing_record = m3.CreateDataObj(strLuaDEID, packing_record) if (nRet ~= 0) then return 2, '创建【装箱记录】失败!' .. packing_record end --step4 更新【装箱工单】中的累计装箱数量 -- 装箱工单表的累计数量+1 strCondition = "S_PACK_NO = '" .. pack_no .. "'" local strSetSQL_update = " N_ACC_QTY = N_ACC_QTY + 1 " nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "GT_Packing_Order", strCondition, strSetSQL_update) if (nRet ~= 0) then return 2, "updateDataAttrByCondition 失败! " .. strRetInfo end -- 如果是散装胶则单独判断入库单据行生成的总重量是否满足入库单据头的批次号总重,满足则关闭入库单和装箱工单 if (dispersoid == 'Y') then -- 获取入库单据头 local incoming_Info strCondition = "S_ORDER_NO = '" .. label_card.order_no .. "'" nRet, incoming_Info = m3.GetDataObjByCondition(strLuaDEID, "GT_Incoming_Info", strCondition) if (nRet ~= 0) then return 2, "m3.GetDataObjByCondition 失败!" .. incoming_Info end -- 获取自己生成的散装胶的数量总和 strCondition = "S_SERIAL_NO LIKE 'S%' AND S_ORDER_NO = '" .. incoming_Info.order_no .. "'" local sumQty nRet, sumQty = mobox.getDataObjAttrSum(strLuaDEID, "GT_Label_Crad", strCondition, "F_QTY") if (nRet ~= 0) then return 2, "获取已入库散装胶总数失败! " .. sumQty end lua.Debug(strLuaDEID, debug.getinfo(1), 'sumQty', sumQty) sumQty = json.decode(sumQty) if (sumQty[1] == nil or sumQty[1] == '') then sumQty = 0 else sumQty = tonumber(sumQty[1]) end -- 判断已入库数量是否达到 GTWMS下发的入库单据头的批次号总重,达到了则设置装箱工单和入库单状态为完成 if (tonumber(sumQty) >= tonumber(incoming_Info.actual_qty)) then strCondition = "S_ORDER_NO = '" .. label_card.order_no .. "'" local strSetSQL = "S_STATE = '完成'" nRet, strRetInfo = mobox.updateTableAttrByCondition(strLuaDEID, "TN_GT_Incoming_Info", strCondition, strSetSQL) if (nRet ~= 0) then return 2, strRetInfo end strCondition = "S_ORDER_NO = '" .. label_card.order_no .. "'" strSetSQL = "S_STATE = '完成'" nRet, strRetInfo = mobox.updateTableAttrByCondition(strLuaDEID, "TN_GT_Packing_Order", strCondition, strSetSQL) end else --step5 更新【入库单】中的累计装箱数量 strCondition = "S_ORDER_NO = '" .. order_no .. "'" strSetSQL_update = " N_ACC_PACK_QTY = N_ACC_PACK_QTY + 1 " nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "GT_Incoming_Info", strCondition, strSetSQL_update) if (nRet ~= 0) then return 2, "updateDataAttrByCondition 失败! " .. strRetInfo end --step6 判断装箱工单、入库单是否关闭 -- 1、判断装箱工单是否有装箱件数,如果有判断装箱工单是否完成 -- 2、判断该装箱工单上游的入库单的累计数量和托盘数量是否相同,相同则设置入库单状态以及入库单下所有启动状态的装箱工单 状态为完成 local obj_display_name = packing_record.pack_no local wfp_list_show_name = "'" .. packing_record.pack_no .. "'新增【装箱记录】后处理程序" nRet, strRetInfo = mobox.addSysWFP(strLuaDEID, 1, "", packing_record.cls, packing_record.id, obj_display_name, 0, "", "判断状态是否完成", wfp_list_show_name, "接口 WCStoreCallback", 0) if (nRet ~= 0) then return 2, "addSysWFP 失败!" .. strRetInfo end end return 0, label_card end --[ -- ManualBindGeneralOperation 人工绑定入库单入库通用操作 -- 1、验证容器货物绑定 -- 2、获取入库单号 -- 3、更新入库单状态、数量 -- 4、判断入库单是否关闭 -- param: -- cntr_code 容器编码 --] local function ManualBindGeneralOperation(strLuaDEID, cntr_code) local nRet, strRetInfo, cg_detail, strCondition --step1 验证容器货物绑定 nRet, cg_detail = wms_cntr.Get_Container_Goods(strLuaDEID, cntr_code) if (cg_detail == nil or cg_detail == '' or #cg_detail == 0) then return 1, "未进行码盘操作!" end cg_detail = cg_detail[1].attrs cg_detail = m3.KeyValueAttrsToObjAttr(cg_detail) --step2 通过流水号获取入库单号 strCondition = "S_SERIAL_NO = '" .. cg_detail.S_SERIAL_NO .. "'" local label_card nRet, label_card = m3.GetDataObjByCondition(strLuaDEID, "GT_Label_Crad", strCondition) if (nRet ~= 0) then return 2, "m3.GetDataObjByCondition 失败!" .. label_card end -- CG_Detail里面的字段 N_IS_FJ 为复检标识,如果该数据是复检则不需要更新入库单的状态 if (tonumber(cg_detail.N_IS_FJ) == 1) then return 0, label_card end --step3 更新入库单状态、数量 strCondition = "S_ORDER_NO = '" .. label_card.order_no .. "'" nRet, strRetInfo = mobox.queryOneDataObjAttr(strLuaDEID, "GT_Incoming_Info", strCondition) if (nRet ~= 0) then return 2, "queryOneDataObjAttr 失败!" .. strRetInfo end strRetInfo = json.decode(strRetInfo) local strSetSQL_update = " N_ACC_PACK_QTY = N_ACC_PACK_QTY + 1 " if (strRetInfo.state == '新建') then strSetSQL_update = strSetSQL_update .. " ,S_STATE = '启用'" end nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "GT_Incoming_Info", strCondition, strSetSQL_update) if (nRet ~= 0) then return 2, "updateDataAttrByCondition 失败! " .. strRetInfo end --step4 判断入库单是否关闭 --判断入库单据的 累计数量 = 托盘数量,如果相等则设置入库单为完成,如果超出 托盘数 系统报错 local order nRet, order = m3.GetDataObjectByKey(strLuaDEID, "GT_Incoming_Info", "S_ORDER_NO", label_card.order_no) if (nRet ~= 0) then return 2, order end if (tonumber(order.acc_pack_qty) == tonumber(order.cntr_qty)) then strCondition = "S_ORDER_NO = '" .. order.order_no .. "'" local strSetSQL = "S_STATE = '完成'" nRet, strRetInfo = mobox.updateTableAttrByCondition(strLuaDEID, "TN_GT_Incoming_Info", strCondition, strSetSQL) if (nRet ~= 0) then return 2, strRetInfo end elseif (tonumber(order.acc_pack_qty) > tonumber(order.cntr_qty)) then return 2, "入库单已完成,不允许入库!" end return 0, label_card end --[ -- PackVerification 装箱校验 -- 1、验证容器货物绑定 -- 2、验证工位与装箱工单是否一致 -- 3、获取入库单号 -- param: -- station_no 入库站点 --] local function PackVerification(strLuaDEID, station_no) local nRet, strRetInfo -- step1获取本工位最新的 【装箱检验】 local strCondition = "S_STATION = '" .. station_no .. "' AND S_STATE = '新建'" local strOrder = "T_CREATE desc" local packing_check nRet, packing_check = m3.GetDataObjByCondition(strLuaDEID, "GT_Packing_Check", strCondition, strOrder) if (nRet == 1) then return 1, "请先用PDA扫描目视卡进行检验!" end if (nRet ~= 0) then return 2, "m3.GetDataObjByCondition 失败!" .. packing_check end --step2 验证工位与装箱工单是否一致 local delivery_no = packing_check.delivery_no -- 收货单号 local delivery_row_no = packing_check.delivery_row_no -- 收货单行号 -- 检验装箱工单上的物料是否在本工位装箱 -- 通过 收货单号、收货单行号, 只要装箱工单上有 这个工位的收货单号、收货单行号获取的入库单号 就通过 -- 查询 状态=启动 的装箱工单 local sql = "SELECT S_ORDER_NO FROM TN_GT_Incoming_Info WHERE S_DELIVERY_NO = '" .. delivery_no .. "' AND N_DELIVERY_ROW_NO = '" .. delivery_row_no .. "'" strCondition = "S_STATION = '" .. station_no .. "' AND S_STATE = '启用' AND S_ORDER_NO = (" .. sql .. ")" local packing_order nRet, packing_order = m3.GetDataObjByCondition(strLuaDEID, "GT_Packing_Order", strCondition, strOrder) if (nRet == 1) then return 1, "目前的装箱工位不能对收货单号为'" .. delivery_no .. "'的物料进行装箱!" end if (nRet ~= 0) then return 2, "m3.GetDataObjByCondition 失败!" .. packing_order end --step3 更新【装箱校验】设置为"完成" strCondition = "S_SERIAL_NO = '" .. packing_check.serial_no .. "' AND S_STATION = '" .. station_no .. "' AND S_STATE = '新建'" local strUpdateSql = "S_STATE = '完成'" nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "GT_Packing_Check", strCondition, strUpdateSql) if (nRet ~= 0) then return 2, "更新【装箱校验】信息失败!" .. strRetInfo end return 0, packing_check.serial_no end --[ -- StockInquiry 库存查询 -- 1、获取巷道货位总数 -- 2、获取满货位总数 -- 3、(满货位总数 / 巷道总数)* 100 = 满货位百分比 -- 4、判断满货位库存是否达到80%,没达到则返回可入库巷道 -- param: -- str_roadway 巷到 --] local function StockInquiry(strLuaDEID) -- 获取未冻结的巷道 local strCondition = "S_AREA_CODE = 'LK' AND N_LOCK_STATE = 0" local nRet, roadway = m3.QueryDataObject(strLuaDEID, "Roadway", strCondition) if (nRet ~= 0) then return 2, '查询巷道信息失败' .. roadway end if (roadway == nil or roadway == '') then return 2, '没有可入库的巷道!' end local str = '' for i = 1, #roadway do local attrs = roadway[i].attrs attrs = m3.KeyValueAttrsToObjAttr(attrs) if (attrs == nil) then goto coroutine end -- 调用WCS接口获取巷道的状态 local data = { req_no = lua.guid(), roadway = attrs.N_ROADWAY } local url = wms_base.Get_sConst(strLuaDEID, "WCS-url") local strurl = url .. "/StackerState" local roadway_state local nRet, strRetInfo = mobox.sendHttpRequest(strurl, "", lua.table2str(data)) if (nRet ~= 0) then return 2, "调用接口失败!" .. strRetInfo end local success, resJson = pcall(json.decode, roadway_state) if(success == 0)then roadway_state = resJson.data[1].roadway_state if(tonumber(roadway_state) == 0 or tonumber(roadway_state) == 3)then goto coroutine end end local strRetInfo -- 获取巷道货位总数 strCondition = "S_AREA_CODE = 'LK' AND N_ROADWAY = " .. attrs.N_ROADWAY nRet, strRetInfo = mobox.getDataObjCount(strLuaDEID, "Location", strCondition) if (nRet ~= 0) then return 2, "getDataObjCount 失败!" .. strRetInfo end local hw_count = tonumber(strRetInfo) -- 指定巷道的货位总数 lua.Debug(strLuaDEID, debug.getinfo(1), "hw_count", hw_count) strCondition = "S_AREA_CODE = 'LK' AND N_CURRENT_NUM <> 0 AND N_ROADWAY = " .. attrs.N_ROADWAY nRet, strRetInfo = mobox.getDataObjCount(strLuaDEID, "Location", strCondition) if (nRet ~= 0) then return 2, "getDataObjCount 失败!" .. strRetInfo end local mhw_count = tonumber(strRetInfo) -- 指定巷道的满货位总数 lua.Debug(strLuaDEID, debug.getinfo(1), "mhw_count", mhw_count) local mhw_ratio = (mhw_count / hw_count) * 100 -- 满货位占比 if (mhw_ratio == nil) then return 1, "计算失败!巷道:" .. attrs.N_ROADWAY .. " 满货位数量:" .. mhw_count .. "货位总数:" .. hw_count end -- 获取字典定义的移库比例 nRet, strRetInfo = mobox.getDictItemIInfo("GT_LK_RATIO") if (nRet ~= 0) then return 2, "getDictItemIInfo 失败!" .. strRetInfo end strRetInfo = json.decode(strRetInfo) local item_ratio = tonumber(strRetInfo[1].name) -- 字典定义的巷道安全库存比例 if (mhw_ratio <= item_ratio) then str = str .. attrs.N_ROADWAY .. "," end ::coroutine:: end -- 去除最后一个, str = lua.trim_laster_char(str) lua.Debug(strLuaDEID, debug.getinfo(1), "str", str) return 0, str end --[ -- RobotBoxing 机器人装箱 -- 1、获取GTWMS同步的流水号 -- 2、GTWMS流水号多行时确定具体处理行 -- 3、获取通过物料编码散装胶组盘规则维护的物料的标准重量 -- 4、根据码盘规则计算重量 -- 5、新增入库单据行信息 -- param: -- order_no 入库单号 -- qty 装箱数量 -- palletizing 码盘规则 --] local function RobotBoxing(strLuaDEID, order_no, qty, palletizing) local nRet, strRetInfo if (qty == nil) then return 2, "散装胶数量非数字或为空!" end if (qty ~= math.floor(qty) or qty <= 0) then return 2, "散装胶数量非正整数" end lua.Debug(strLuaDEID, debug.getinfo(1), 'qty', tonumber(qty)) if (palletizing == '' or palletizing == nil) then return 2, "散装胶码盘规则不能为空!" end --step1 获取GTWMS同步的流水号(可能存在一个单据头,多个流水号的存在) local strCondition = "S_ORDER_NO = '" .. order_no .. "' AND S_SERIAL_NO NOT LIKE 'S%'" local label_crad nRet, label_crad = m3.QueryDataObject(strLuaDEID, "GT_Label_Crad", strCondition) if (nRet ~= 0) then return 2, "m3.GetDataObjByCondition 失败!" .. label_crad end local attr -- step2 GTWMS流水号多行时确定具体处理行 for i = 1, #label_crad do nRet, attr = m3.ObjAttrStrToLuaObj("GT_Label_Crad", lua.table2str(label_crad[i].attrs)) if (nRet ~= 0) then return 2, "m3.ObjAttrStrToLuaObj(GT_Label_Crad) 失败! " .. attr end lua.Debug(strLuaDEID, debug.getinfo(1), 'attr', attr) -- 根据流水号的唯一码统计我们自己返回的散装胶 S开头的编码 的数量总和 strCondition = "S_REQ_NO = '" .. attr.req_no .. "' AND S_SERIAL_NO LIKE 'S%'" local sumQty nRet, sumQty = mobox.getDataObjAttrSum(strLuaDEID, "GT_Label_Crad", strCondition, "F_QTY") if (nRet ~= 0) then return 2, "获取已入库散装胶总数失败 失败! " .. sumQty end sumQty = json.decode(sumQty) if (sumQty[1] == nil or sumQty[1] == '') then sumQty = 0 else sumQty = tonumber(sumQty[1]) end if (tonumber(attr.qty) > tonumber(sumQty)) then goto coroutine end if (i == #label_crad) then return 2, "未查找到对应的入库单据行记录! " end end ::coroutine:: -- label_crad = attr --step3 通过入库单据行的托盘重量和块数计算标准重量 local weight = tonumber(attr.qty) / tonumber(attr.number) lua.Debug(strLuaDEID, debug.getinfo(1), "qty", qty) lua.Debug(strLuaDEID, debug.getinfo(1), "attr", attr) lua.Debug(strLuaDEID, debug.getinfo(1), "weight", weight) --step4 根据码盘规则计算重量 入库单据行重量为机械臂统计的数量 * 标准重量 local all_qty = tonumber(qty) * tonumber(weight) lua.Debug(strLuaDEID, debug.getinfo(1), "all_qty", all_qty) -- 自动生成流水号(编码规则 S + 7位数字) local strCode nRet, strCode = mobox.getSerialNumber("散装胶流水号", 'S', 7) if (nRet ~= 0) then return 2, "申请散装胶入库单据行编码失败!" .. strCode end --setep5 新增入库单据行信息 创建入库单据行 -- 获取一个初始的【入库单据行】数据对象 local new_label_crad = m3.AllocObject(strLuaDEID, "GT_Label_Crad") new_label_crad.delivery_no = attr.delivery_no new_label_crad.delivery_row_no = attr.delivery_row_no new_label_crad.item_code = attr.item_code new_label_crad.item_code_9 = attr.item_code_9 new_label_crad.item_name = attr.item_name new_label_crad.product_date = attr.product_date new_label_crad.batch_no = attr.batch_no new_label_crad.item_state = attr.item_state new_label_crad.qty = all_qty new_label_crad.serial_no = strCode new_label_crad.wh_code = attr.wh_code new_label_crad.storage_loc = attr.storage_loc new_label_crad.order_no = attr.order_no new_label_crad.is_bonded = attr.is_bonded new_label_crad.wheel_type_rot = attr.wheel_type_rot new_label_crad.subpool = attr.subpool new_label_crad.req_no = attr.req_no new_label_crad.dispersoid = attr.dispersoid new_label_crad.palletizing = attr.palletizing lua.Debug(strLuaDEID, debug.getinfo(1), 'new_label_crad', new_label_crad) nRet, new_label_crad = m3.CreateDataObj(strLuaDEID, new_label_crad) if (nRet ~= 0) then return 2, "mobox 创建【入库单据行】对象失败!" .. new_label_crad end return 0, new_label_crad.serial_no end -- 创建作业 local function CreateOperation(strLuaDEID, item_code, batch_no, loc_start, inbound_policy, ext_table, cntr_code) lua.Debug(strLuaDEID, debug.getinfo(1), '进入创建作业', loc_start) lua.Debug(strLuaDEID, debug.getinfo(1), '进入创建作业', inbound_policy) lua.Debug(strLuaDEID, debug.getinfo(1), '进入创建作业', cntr_code) --获取物料类型 local nRet, item_type, material = GT_Get_ItemType(strLuaDEID, item_code) if (nRet ~= 0) then return 1, item_type end lua.Debug(strLuaDEID, debug.getinfo(1), '物料信息', material) -- 添加扩展作业 ext_table.batch_no = batch_no -- 批次号 ext_table.item_code = item_code -- 物料编码 ext_table.item_type = item_type -- 物料类型 ext_table.is_insulate = material.is_insulate -- 是否保温 -- 获取字典定义的天然胶规则 local is_trj nRet, is_trj = mobox.getDictItemIInfo("GT_TRJ_DATE") if (nRet ~= 0) then return 2, "getDictItemIInfo 失败!" .. is_trj end is_trj = json.decode(is_trj) is_trj = tonumber(is_trj[1].name) -- 天然胶规则 1 启用 2 禁用 -- 获取巷道库存未达到 80% 的可入库巷道 local strRetInfo nRet, strRetInfo = StockInquiry(strLuaDEID) if (nRet ~= 0) then return 2, strRetInfo end ext_table.roadway_inventory = strRetInfo -- 作业扩展数据存入这个巷道库存字符串,里面是库存未超过80%的巷道 lua.Debug(strLuaDEID, debug.getinfo(1), '可入库巷道', strRetInfo) -- 判断起点是否为一楼左侧回库口或三楼回库口,如果是只能使用3,4巷道 if (loc_start.code == wms_base.Get_sConst(strLuaDEID, "KL_ReturnRgvStation1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3L_InWeight1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3R_InWeight1")) then local b = wms_base.Get_sConst(strLuaDEID, "佳通-一楼左侧回库口巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then return 2, "没有可入库的3,4巷道!" end ext_table.roadway_inventory = str end --step5 创建作业 local operation = m3.AllocObject(strLuaDEID, "Operation") operation.start_wh_code = loc_start.wh_code operation.start_area_code = loc_start.area_code operation.start_loc_code = loc_start.code operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-入库") -- 判断客户指定的规则 -- 客户指定胶料入库策略 1:入7、8巷道; 2:不入7、8巷道; 3:系统巷道均衡分配; 针对天然胶物料入库的时候去进行策略的判断。 local end_loc if (tonumber(inbound_policy) == 1) then -- 获取可入库巷道 local b = wms_base.Get_sConst(strLuaDEID, "佳通-保温巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then return 2, "没有可入库的保温巷道!" end ext_table.roadway_inventory = str operation.op_def_name = "保温材料入库" -- 获取作业终点位置 nRet, end_loc = BW_StorageTactics(strLuaDEID, ext_table) if (nRet ~= 0) then return 2, "计算终点失败!" .. end_loc end if (end_loc == nil or end_loc == '') then return 2, "立库中没有满足条件的货位可以分配!" end -- 获取终点信息 nRet, end_loc = wms_wh.GetLocInfo(end_loc) if (nRet ~= 0) then return 2, 'WMS_GetLocInfo失败!' .. end_loc end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = end_loc.code ext_table.roadway = end_loc.roadway goto continue elseif (tonumber(inbound_policy) == 2) then local b = wms_base.Get_sConst(strLuaDEID, "佳通-非保温巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then return 2, "没有可入库的非保温巷道!" end ext_table.roadway_inventory = str operation.op_def_name = "立库入库" -- 获取终点信息 nRet, end_loc = JL_StorageTactics(strLuaDEID, ext_table) if (nRet ~= 0) then return 2, "计算终点失败!" .. end_loc end if (end_loc == nil or end_loc == '') then return 2, "立库中没有满足条件的货位可以分配!" end -- 获取终点信息 nRet, end_loc = wms_wh.GetLocInfo(end_loc) if (nRet ~= 0) then return 2, 'WMS_GetLocInfo失败!' .. end_loc end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = end_loc.code ext_table.roadway = end_loc.roadway goto continue end if (is_trj == 1 and material.is_insulate == 'Y') then -- 获取可入库巷道 local b = wms_base.Get_sConst(strLuaDEID, "佳通-保温巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then return 2, "没有可入库的保温巷道!" end ext_table.roadway_inventory = str operation.op_def_name = "保温材料入库" -- 获取作业终点位置 nRet, end_loc = BW_StorageTactics(strLuaDEID, ext_table) if (nRet ~= 0) then return 2, "计算终点失败!" .. end_loc end if (end_loc == nil or end_loc == '') then return 2, "立库中没有满足条件的货位可以分配!" end -- 获取终点信息 nRet, end_loc = wms_wh.GetLocInfo(end_loc) if (nRet ~= 0) then return 2, 'WMS_GetLocInfo失败!' .. end_loc end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = end_loc.code ext_table.roadway = end_loc.roadway goto continue end if (item_type == '粉料') then operation.op_def_name = "粉料入库" ext_table.isothermal = material.isothermal -- 是否恒温,用来判断粉料是否入恒温库 ext_table.area_code = material.area_code -- 库区,用来判断粉料入库口的位置 -- GT_Area_Type 字典名称 1,2,3 的附加值分别对应东粉料库、西粉料库、粉料比例维护三种 local dictItem nRet, dictItem = mobox.getDictItemIInfo("GT_Area_Type") if (nRet ~= 0) then return 2, dictItem end dictItem = json.decode(dictItem) local loc_code, d_ratio, x_ratio local strCondition, area for m = 1, #dictItem do -- 佳通WMS传的库区和字典定义的值相等则判断字典名称是哪个终点库区 if (material.area_code == dictItem[m].value) then if (tonumber(dictItem[m].name) == 1) then if (material.isothermal == 'Y') then area = "HWPFL" else area = "PFL" end elseif (tonumber(dictItem[m].name) == 2) then if (material.isothermal == 'Y') then area = "HWTFL" else area = "TFL" end else -- 佳通WMS没有指定东西出库口,则通过粉料比例维护来判断入库口 -- 默认比例为5:5 d_ratio = 5 x_ratio = 5 -- 获取东西粉料库该货品的数量 local d_count, x_count, count, d_num, x_num strCondition = "S_CNTR_CODE IN (SELECT S_CNTR_CODE FROM TN_CG_Detail WHERE S_ITEM_CODE = '" .. item_code .. "')" strCondition = strCondition .. " AND S_LOC_CODE IN (SELECT S_CODE FROM TN_Location WHERE S_AREA_CODE IN( 'PFL','HWPFL'))" nRet, d_count = mobox.getDataObjCount(strLuaDEID, "Loc_Container", strCondition) if (nRet ~= 0) then return 2, d_count end strCondition = "S_CNTR_CODE IN (SELECT S_CNTR_CODE FROM TN_CG_Detail WHERE S_ITEM_CODE = '" .. item_code .. "')" strCondition = strCondition .. " AND S_LOC_CODE IN (SELECT S_CODE FROM TN_Location WHERE S_AREA_CODE IN( 'TFL','HWTFL'))" nRet, x_count = mobox.getDataObjCount(strLuaDEID, "Loc_Container", strCondition) if (nRet ~= 0) then return 2, x_count end -- 东西粉料库所有该物料编码的总数 count = tonumber(d_count) + tonumber(x_count) -- 计算东西粉料库占比 if (count ~= 0) then d_num = round(tonumber(d_count) / tonumber(count) * 10) -- 东粉料库占比 x_num = round(tonumber(x_count) / tonumber(count) * 10) -- 西粉料库占比 else d_num = 0 x_num = 0 end if (material.isothermal == 'Y') then if (d_ratio >= d_num) then area = "HWPFL" end if (x_ratio >= x_num) then area = "HWTFL" end else if (d_ratio >= d_num) then area = "PFL" end if (x_ratio >= x_num) then area = "TFL" end end end end end -- 查询条件为库区为指定库区的空货位 strCondition = "S_AREA_CODE = '" .. area .. "' AND N_CURRENT_NUM = 0 AND N_LOCK_STATE = 0 AND C_ENABLE = 'Y'" -- 根据终点库区获取终点货位 按照排列层排序 local strOrder = "N_ROW,N_COL,N_LAYER" -- 最多获取 10 条 nRet, strRetInfo = mobox.queryDataObjAttr3(strLuaDEID, "Location", strCondition, 10, strOrder) if (nRet ~= 0) then return 2, "获取货位信息错误! " .. strRetInfo .. " SQL条件: " .. strCondition end local loc if (strRetInfo ~= '') then local retObjs = json.decode(strRetInfo) nRet, loc = m3.ObjAttrStrToLuaObj("Location", lua.table2str(retObjs[1].attrs)) if (nRet ~= 0) then return 2, "m3.ObjAttrStrToLuaObj(Location) 失败! " .. loc end else return 2, "没有查询到可入库的空货位!" end -- 获取终点信息 nRet, end_loc = wms_wh.GetLocInfo(loc.code) if (nRet ~= 0) then return 2, 'WMS_GetLocInfo失败!' .. end_loc end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = end_loc.code elseif (item_type == '钢丝') then local b = wms_base.Get_sConst(strLuaDEID, "佳通-非保温巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then return 2, "没有可入库的非保温巷道!" end ext_table.roadway_inventory = str operation.op_def_name = "立库入库" -- 获取终点信息 nRet, end_loc = GS_StorageTactics(strLuaDEID, ext_table) if (nRet ~= 0) then return 2, "计算终点失败!" .. end_loc end if (end_loc == nil or end_loc == '') then return 2, "立库中没有满足条件的货位可以分配!" end -- 获取终点信息 nRet, end_loc = wms_wh.GetLocInfo(end_loc) if (nRet ~= 0) then return 2, 'WMS_GetLocInfo失败!' .. end_loc end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = end_loc.code ext_table.roadway = end_loc.roadway else operation.op_def_name = "立库入库" -- 获取终点信息 nRet, end_loc = JL_StorageTactics(strLuaDEID, ext_table) if (nRet ~= 0) then return 2, "计算终点失败!" .. end_loc end if (end_loc == nil or end_loc == '') then return 2, "立库中没有满足条件的货位可以分配!" end -- 获取终点信息 nRet, end_loc = wms_wh.GetLocInfo(end_loc) if (nRet ~= 0) then return 2, 'WMS_GetLocInfo失败!' .. end_loc end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = end_loc.code ext_table.roadway = end_loc.roadway end ::continue:: lua.Debug(strLuaDEID, debug.getinfo(1), 'operation', operation) local strCode local strHeader = 'TA' .. os.date("%y%m%d") .. '-' nRet, strCode = mobox.getSerialNumber("任务", strHeader, 5) if (nRet ~= 0) then return 2, '申请【任务】编码失败!' .. strCode end ext_table.task_no = strCode operation.ext_data = lua.table2str(ext_table) operation.cntr_code = cntr_code lua.Debug(strLuaDEID, debug.getinfo(1), "end_loc", end_loc) nRet, operation = m3.CreateDataObj(strLuaDEID, operation) if (nRet ~= 0) then return 2, '创建【作业】失败!' .. operation end lua.Debug(strLuaDEID, debug.getinfo(1), "作业创建后信息", operation) -- 终点加锁操作(起点为站点有WCS管控) nRet, strRetInfo = wms.wms_LockLocation(strLuaDEID, operation.end_loc_code, wms_base.Get_nConst(strLuaDEID, "锁类型-入库锁"), ext_table.task_no, operation.code, operation.op_def_name) if (nRet ~= 0) then return 2, "wms_LockLocation 失败!" .. strRetInfo end return 0, '' end --[[ 编码: GT-100-01 名称: WCS入库回调 作者:LZH 入口函数: WCSCallback 功能说明: 通过传参的请求类型判断 1 = 货物入库/退库;2 = 托盘组入库;3 = RFID托盘查询 ;4 = 呼叫空托; 处理逻辑 -- step1 获取接口数据 -- step2 检验参数 -- step3 获取工位起点信息 -- step4 根据不同的类型做不同的操作 1=货物入库/退库;2=托盘组入库;3=RFID托盘查询 ;4 = 呼叫空托 输入数据: { "cntr_code": "106EGRCA1078", -- 容器号 "station_no": "A", -- 工位 "qty":0, -- 数量 "req_no": "11111111", -- GUID唯一标识 "req_type": "1", -- 请求类型 1=货物入库/退库;2=托盘组入库;3=RFID托盘查询 ;4 = 呼叫空托 "weight": "1", -- 重量 "req_time": "2024-12-11" -- 请求时间 } 变更记录: v1.1 lzh 20250421 增加接口请求处理,保证在同一个站点发送某一个请求类型,执行完或报错前不会有别的线程来处理 --]] require("WMS-Equipment") wms_cntr = require("wms_container") wms_wh = require("wms_wh") require("GT-Base") require("GT_InAndOutboundPolicies") function WCSCallback(strLuaDEID) local nRet, strRetInfo, in_date, sn_result, serialRet, label_card, pwgw_Ret, pvRet, pv_Restult, item_code, condition, msg local ext_table = {} -- 作业扩展参数 -- step1 获取接口数据 nRet, in_date = m3.GetSysDataJson(strLuaDEID) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "WCStoreCallback 无法获取数据包!" .. in_date) end lua.Debug(strLuaDEID, debug.getinfo(1), 'in_date', in_date) -- 通用变量赋值 local cntr_code = in_date.cntr_code local station_no = in_date.station_no local qty = tonumber(in_date.qty) local req_no = in_date.req_no -- 唯一码 local req_type = tonumber(in_date.req_type) -- 请求类型 1=货物入库/退库;2=托盘组入库;3=RFID托盘查询 local req_time = in_date.req_time -- 请求时间 local weight = in_date.weight -- 上报的重量 -- step2 接口参数有效性验证 if (station_no == '') then lua.Error(strLuaDEID, debug.getinfo(1), "工位不能为空!") end if (req_no == '') then lua.Error(strLuaDEID, debug.getinfo(1), "请求码不能为空!") end if (req_type > 4 or req_type < 1) then lua.Error(strLuaDEID, debug.getinfo(1), "入库类型不支持!") end -- 如果容器在作业中存在执行状态则退出 condition = "S_CNTR_CODE = '" .. cntr_code .. "' AND N_B_STATE IN( 0,1,3)" nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "Operation", condition) if (nRet == 0) then lua.Error(strLuaDEID, debug.getinfo(1), "容器已被占用!") end -- step3 获取起点信息 local loc_start = wms_base.Get_sConst(strLuaDEID, station_no) nRet, loc_start = wms_wh.GetLocInfo(loc_start) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), 'WMS_GetLocInfo失败!' .. loc_start) end lua.Debug(strLuaDEID, debug.getinfo(1), 'loc_start', loc_start) -- step4 根据不同的类型做不同的操作 1=货物入库/退库;2=托盘组入库;3=RFID托盘查询 ;4 = 呼叫空托 if (req_type == 1) then lua.Debug(strLuaDEID, debug.getinfo(1), 'in_date', in_date) -- 验证容器 if (cntr_code == '') then lua.Error(strLuaDEID, debug.getinfo(1), "容器不能为空!") end --容器有效性验证 local container nRet, container = wms_cntr.GetInfo(strLuaDEID, cntr_code) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "获取【容器】信息失败! " .. container) end if (container == '') then lua.Error(strLuaDEID, debug.getinfo(1), "【容器】" .. cntr_code .. "不存在!") end -- 查询退料单 条件:容器相同并且状态为编辑 nRet == 1则退料单为空走正常入库逻辑,存在退料单则走退料流程 local rom condition = "S_CNTR_CODE = '" .. cntr_code .. "' AND S_STATE IN( '编辑','执行')" nRet, rom = m3.GetDataObjByCondition(strLuaDEID, "GT_ROM", condition) lua.Debug(strLuaDEID, debug.getinfo(1), 'rom', rom) if (nRet == 1) then -- 判断是否是空托,空托则走空托入库流程 local is_kgz condition = "S_CNTR_CODE = '" .. cntr_code .. "' AND S_ITEM_CODE = 'KGZ'" nRet, is_kgz = m3.GetDataObjByCondition(strLuaDEID, "CG_Detail", condition) if (nRet == 1) then -- 如果不是空托继续走正常入库流程 goto KGZ elseif (nRet == 0) then nRet, strRetInfo = StockInquiry(strLuaDEID) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), strRetInfo) end ext_table.roadway_inventory = strRetInfo -- 作业扩展数据存入这个巷道库存字符串,里面是库存未超过80%的巷道 if (loc_start.code == wms_base.Get_sConst(strLuaDEID, "KL_ReturnRgvStation1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3L_InWeight1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3R_InWeight1")) then local b = wms_base.Get_sConst(strLuaDEID, "佳通-一楼左侧回库口巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then lua.Error(strLuaDEID, debug.getinfo(1), "没有可入库的3,4巷道!") end ext_table.roadway_inventory = str end -- 创建作业 local operation = m3.AllocObject(strLuaDEID, "Operation") operation.start_wh_code = loc_start.wh_code operation.start_area_code = loc_start.area_code operation.start_loc_code = loc_start.code operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-入库") operation.op_def_name = "国自空托回库" operation.cntr_code = cntr_code operation.ext_data = lua.table2str(ext_table) nRet, operation = m3.CreateDataObj(strLuaDEID, operation) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建【作业】失败!' .. operation) end goto BREAK -- 走空托入库创建作业后跳过下面的执行逻辑 end ::KGZ:: -- 获取WCS站点绑定的工位 condition = "S_START_LOC = '" .. loc_start.code .. "'" nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "GT_PDA_Station", condition) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "获取【工位】信息失败! " .. strRetInfo) end station_no = strRetInfo.station lua.Debug(strLuaDEID, debug.getinfo(1), 'station_no', station_no) --判断入库站台是否有启动状态的装箱工单 local strCondition = "S_STATION = '" .. station_no .. "' AND S_STATE = '启用'" local strOrder = "T_CREATE desc" local packing nRet, packing = m3.GetDataObjByCondition(strLuaDEID, "GT_Packing_Order", strCondition, strOrder) --没有装箱工单走人工绑定流程 if (nRet == 1) then --走人工绑定操作 pwgw_Ret, label_card = ManualBindGeneralOperation(strLuaDEID, cntr_code) if (pwgw_Ret ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '人工绑定操作失败!' .. label_card) end --走装箱工单流程 elseif (nRet == 0) then -- local palletizing = packing.palletizing --lishiming 临时用,码盘规则后续从装箱工单表里直接拿 local palletizing = "1" local dispersoid = packing.dispersoid --lishiming 临时用,散装胶标识 后续从装箱工单表中拿 --机器人装箱工位,需要自动生成流水号,不需要装箱校验 if (dispersoid == 'Y') then --获取入库流水号 serialRet, sn_result = RobotBoxing(strLuaDEID, packing.order_no, qty, palletizing) --获取失败,报错提示 if (serialRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '散装胶获取入库单行数据失败!' .. sn_result) end --走装箱工单通用操作 pwgw_Ret, label_card = PackWorkGeneralOperation(strLuaDEID, sn_result, cntr_code, packing.pack_no, packing.order_no, dispersoid) --获取失败,报错提示 if (pwgw_Ret ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '装箱工单操作失败!' .. label_card) end else -- 获取装箱校验开关是否开启 local is_zxjy = wms_base.Get_sConst(strLuaDEID, "佳通-装箱校验开关") if (is_zxjy == 'Y') then --装箱校验,成功返回流水号 pvRet, pv_Restult = PackVerification(strLuaDEID, station_no) --获取失败,报错提示 if (pvRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '装箱校验失败!' .. pv_Restult) end sn_result = pv_Restult else --非装箱校验,获取流水号 -- 获取未绑定容器的入库单的流水号进行排序,取第一个和容器绑定 local order_by = "S_SERIAL_NO" strCondition = " NOT EXISTS (SELECT S_SERIAL_NO FROM TN_CG_Detail WHERE TN_CG_Detail.S_SERIAL_NO = tn_GT_Label_Crad.S_SERIAL_NO) AND S_ORDER_NO = '" .. packing.order_no .. "'" pvRet, pv_Restult = m3.GetDataObjByCondition(strLuaDEID, "GT_Label_Crad", strCondition, order_by) if (pvRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '获取未绑定的流水号失败!' .. pv_Restult) end -- 目视卡基本属性判断 if (pv_Restult.qty <= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "目视卡'" .. pv_Restult.serial_no .. "'的数量必须有值不能是负数!") end sn_result = pv_Restult.serial_no end --走装箱工单通用操作 pwgw_Ret, label_card = PackWorkGeneralOperation(strLuaDEID, sn_result, cntr_code, packing.pack_no, packing.order_no, dispersoid) --获取失败,报错提示 if (pwgw_Ret ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '装箱工单操作失败!' .. label_card) end end --获取失败,报错提示 elseif (nRet == 2) then lua.Error(strLuaDEID, debug.getinfo(1), 'm3.GetDataObjByCondition 失败!' .. packing) end -- 根据流水号更新入库单据行的称重信息 strCondition = "S_SERIAL_NO = '" .. label_card.serial_no .. "'" local strUpdateSql = "S_WEIGHT = '" .. weight .. "'" nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "GT_Label_Crad", strCondition, strUpdateSql) if (nRet ~= 0) then return 2, "更新【入库单据行】信息失败!" .. strRetInfo end -- 创建对应的作业 nRet, strRetInfo = CreateOperation(strLuaDEID, label_card.item_code, label_card.batch_no, loc_start, label_card.inbound_policy, ext_table, cntr_code) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建作业失败!' .. strRetInfo) end elseif (nRet == 0) then -- 判断退料逻辑是否做了容器货品绑定 local cg_detail condition = "S_CNTR_CODE = '" .. cntr_code .. "'" nRet, cg_detail = m3.GetDataObjByCondition(strLuaDEID, "CG_Detail", condition) if (nRet == 1) then lua.Error(strLuaDEID, debug.getinfo(1), "托盘物料未绑定!") elseif (nRet > 1) then lua.Error(strLuaDEID, debug.getinfo(1), "GetDataObjByCondition失败!" .. cg_detail) end lua.Debug(strLuaDEID, debug.getinfo(1), 'cg_detail', cg_detail) local item_type, material nRet, item_type, material = GT_Get_ItemType(strLuaDEID, cg_detail.item_code) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), item_type) end lua.Debug(strLuaDEID, debug.getinfo(1), '物料信息', material) if (item_type == '碳黑') then lua.Error(strLuaDEID, debug.getinfo(1), "碳黑不可入立库!") end nRet, strRetInfo = CreateOperation(strLuaDEID, cg_detail.item_code, cg_detail.batch_no, loc_start, rom.inbound_policy, ext_table, cntr_code) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建作业失败!' .. strRetInfo) end -- 根据 容器+状态 更新入库单据行的称重信息和状态 local strSetAttr = "S_STATE = '执行',S_WEIGHT = '" .. weight .. "' " condition = "S_CNTR_CODE = '" .. cntr_code .. "' AND S_STATE <> '完成'" nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "GT_ROM", condition, strSetAttr) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "更新【退料单】状态失败!" .. strRetInfo) end else lua.Error(strLuaDEID, debug.getinfo(1), "GetDataObjByCondition失败!" .. rom) end ::BREAK:: -- req_type = 2 托盘组入库流程 elseif (req_type == 2) then if (cntr_code == '') then lua.Error(strLuaDEID, debug.getinfo(1), "RFID不能为空!") end -- 校验容器是否已绑定货位 condition = "S_CNTR_CODE = '" .. cntr_code .. "'" nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "Loc_Container", condition) if (nRet == 0) then lua.Error(strLuaDEID, debug.getinfo(1), '容器已绑定' .. strRetInfo.loc_code .. '货位!') end if (qty == nil or qty == 0) then strCondition = "S_CNTR_CODE = '" .. cntr_code .. "'" nRet, cg_detail = m3.QueryDataObject(strLuaDEID, "CG_Detail", strCondition) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "QueryDataObject失败!" .. cg_detail) end qty = cg_detail.qty else -- 绑定空托物料 物料编码 = KGZ 空工装 代表这个容器是空托,容器货品明细的数量的单位为托 local cg_detail = m3.AllocObject(strLuaDEID, "CG_Detail") cg_detail.cntr_code = cntr_code cg_detail.item_code = "KGZ" cg_detail.item_name = "空工装" cg_detail.qty = qty cg_detail.uom = '个' nRet, cg_detail = m3.CreateDataObj(strLuaDEID, cg_detail) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建【容器货品明细】对象失败!' .. cg_detail) end end nRet, strRetInfo = StockInquiry(strLuaDEID) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), strRetInfo) end ext_table.roadway_inventory = strRetInfo -- 作业扩展数据存入这个巷道库存字符串,里面是库存未超过80%的巷道 if (loc_start.code == wms_base.Get_sConst(strLuaDEID, "KL_ReturnRgvStation1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3L_InWeight1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3R_InWeight1")) then local b = wms_base.Get_sConst(strLuaDEID, "佳通-一楼左侧回库口巷道") local str = findCommonNumbers(ext_table.roadway_inventory, b) if (str == nil or str == '') then lua.Error(strLuaDEID, debug.getinfo(1), "没有可入库的3,4巷道!") end ext_table.roadway_inventory = str end -- 判断货位容器是否绑定,没有绑定则绑定 local loc_code = wms_wh.GetLocCodeByCNTR(strLuaDEID, cntr_code) if (loc_code == '') then nRet, strRetInfo = wms_wh.Loc_Container_Binding(strLuaDEID, loc_start.code, cntr_code, "绑定解绑方法-系统", "完成") if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '货位容器解绑失败!' .. strRetInfo) end end -- 创建托盘组入库作业 -- 创建作业 local operation = m3.AllocObject(strLuaDEID, "Operation") operation.start_wh_code = loc_start.wh_code operation.start_area_code = loc_start.area_code operation.start_loc_code = loc_start.code operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-入库") operation.op_def_name = "国自空托回库" operation.cntr_code = cntr_code operation.ext_data = lua.table2str(ext_table) nRet, operation = m3.CreateDataObj(strLuaDEID, operation) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建【作业】失败!' .. operation) end lua.Debug(strLuaDEID, debug.getinfo(1), "作业创建后信息", operation) -- req_type = 3 RFID托盘查询流程 elseif (req_type == 3) then if (cntr_code == '') then lua.Error(strLuaDEID, debug.getinfo(1), "RFID不能为空!") end -- RFID托盘查询 根据容器获取 CG_Detail -- 1 单个托盘(进码盘机) 2 托盘组(人工上料的托盘组) 3 物料(请求类型=3RFID托盘查询时需返回) local data = {} local cg_detail condition = "S_CNTR_CODE = '" .. cntr_code .. "'" nRet, cg_detail = m3.GetDataObjByCondition(strLuaDEID, "CG_Detail", condition) if (nRet ~= 0 and nRet ~= 1) then lua.Error(strLuaDEID, debug.getinfo(1), "获取【容器货品明细】信息失败! " .. cg_detail) end if (nRet == 1) then -- 拼接返回的数据 data.mat_type = 1 mobox.returnValue(strLuaDEID, 1, lua.table2str(data)) return elseif (nRet == 0) then if (cg_detail.item_code == 'KGZ') then data.mat_type = 2 mobox.returnValue(strLuaDEID, 1, lua.table2str(data)) return else data.mat_type = 3 mobox.returnValue(strLuaDEID, 1, lua.table2str(data)) return end end -- req_type = 4呼叫空托流程 elseif (req_type == 4) then -- 获取未冻结的巷道 local strCondition = "S_AREA_CODE = 'LK' AND N_LOCK_STATE = 0" local nRet, roadway_list = m3.QueryDataObject(strLuaDEID, "Roadway", strCondition) lua.Debug(strLuaDEID, debug.getinfo(1), "roadway_list", roadway_list) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '查询巷道信息失败' .. roadway_list) end if (roadway_list == nil or roadway_list == '') then lua.Error(strLuaDEID, debug.getinfo(1), '没有可出库的巷道!') end local str = '' for i = 1, #roadway_list do local attrs = roadway_list[i].attrs attrs = m3.KeyValueAttrsToObjAttr(attrs) if (attrs == nil) then goto coroutine end str = str .. attrs.N_ROADWAY .. "," ::coroutine:: end -- 去除最后一个, str = lua.trim_laster_char(str) -- 获取可出库巷道 if (loc_start.code == wms_base.Get_sConst(strLuaDEID, "KL_ReturnRgvStation1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3L_InWeight1") or loc_start.code == wms_base.Get_sConst(strLuaDEID, "F3R_InWeight1")) then local b = wms_base.Get_sConst(strLuaDEID, "佳通-一楼左侧回库口巷道") str = findCommonNumbers(str, b) end roadway_list = lua.split(str, ",") local data local loc_Container = {} local flag = 0 for i = 1, #roadway_list do local roadway = roadway_list[i] -- 巷道 -- 获取该巷道的 空货箱/托盘组 优先外深位其次内深位 local str_cntr if (station_no == 'KQ_KTPPullCache1') then str_cntr = '106EGP' else str_cntr = '106EGR' -- 胶框前6个字符 托盘是106EGP end -- 获取当前巷道信息 strCondition = "N_ROADWAY = '" .. roadway .. "'" nRet, roadway = m3.GetDataObjByCondition(strLuaDEID, "Roadway", strCondition) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "获取【巷道】信息失败! " .. roadway) end local strOrder = "T_CREATE" -- 获取外深位的空工装 strCondition = "S_LOC_CODE IN (SELECT S_CODE FROM TN_Location WHERE S_AREA_CODE = 'LK' AND N_LOCK_STATE = 0 AND C_ENABLE = 'Y' AND N_POS = 1 AND N_ROADWAY = '" .. roadway.roadway .. "')" strCondition = strCondition .. " AND S_CNTR_CODE IN (SELECT S_CNTR_CODE FROM TN_CG_Detail WHERE S_ITEM_CODE = 'KGZ' AND S_CNTR_CODE LIKE '%" .. str_cntr .. "%')" -- 最多获取 10 条 nRet, strRetInfo = mobox.queryDataObjAttr3(strLuaDEID, "Loc_Container", strCondition, 1, strOrder) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "获取货位信息错误! " .. strRetInfo .. " SQL条件: " .. strCondition) end if (strRetInfo ~= '') then local attrs local retObjs = json.decode(strRetInfo) nRet, attrs = m3.ObjAttrStrToLuaObj("Loc_Container", lua.table2str(retObjs[1].attrs)) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "m3.ObjAttrStrToLuaObj(CG_Detail) 失败! " .. attrs) end data = { loc_code = attrs.loc_code, cntr_code = attrs.cntr_code, roadway = roadway.roadway } break end -- 获取内深位的空工装 strCondition = "S_LOC_CODE IN (SELECT S_CODE FROM TN_Location WHERE S_AREA_CODE = 'LK' AND N_LOCK_STATE = 0 AND C_ENABLE = 'Y' AND N_POS = 2 AND N_ROADWAY = '" .. roadway.roadway .. "')" strCondition = strCondition .. " AND S_CNTR_CODE IN (SELECT S_CNTR_CODE FROM TN_CG_Detail WHERE S_ITEM_CODE = 'KGZ' AND S_CNTR_CODE LIKE '%" .. str_cntr .. "%')" -- 最多获取 10 条 nRet, strRetInfo = mobox.queryDataObjAttr3(strLuaDEID, "Loc_Container", strCondition, 1, strOrder) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "获取货位信息错误! " .. strRetInfo .. " SQL条件: " .. strCondition) end if (strRetInfo ~= '') then local attrs local retObjs = json.decode(strRetInfo) for j = 1, #retObjs do flag = tonumber(flag) + 1 nRet, attrs = m3.ObjAttrStrToLuaObj("Loc_Container", lua.table2str(retObjs[j].attrs)) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), "m3.ObjAttrStrToLuaObj(CG_Detail) 失败! " .. attrs) end loc_Container[flag] = attrs end end end local start_loc if (data ~= nil) then lua.Debug(strLuaDEID, debug.getinfo(1), "data", data) cntr_code = data.cntr_code start_loc = data.loc_code elseif (tonumber(#loc_Container) > tonumber(0)) then lua.Debug(strLuaDEID, debug.getinfo(1), "loc_Container", loc_Container) for i = 1, #loc_Container do -- 内深位校验 local success, loc_code = GetPosLoc(strLuaDEID, loc_Container[i].loc_code) if (success == true) then -- 判断内深位是否有货物 strCondition = "S_CODE = '" .. loc_code .. "' AND (N_LOCK_STATE = 0 OR N_CURRENT_NUM = 1)" nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "Location", strCondition) if (nRet == 2) then lua.Error(strLuaDEID, debug.getinfo(1), "m3.GetDataObjByCondition 失败!" .. strRetInfo) elseif (nRet == 1) then strCondition = "S_CODE = '" .. loc_code .. "' AND N_LOCK_STATE = 0" nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "Location", strCondition) if (nRet == 2) then lua.Error(strLuaDEID, debug.getinfo(1), "m3.GetDataObjByCondition 失败!" .. strRetInfo) elseif (nRet == 1) then goto coroutine end -- 创建移库任务 -- 获取起点信息 local start_loc_yk, end_loc_yk nRet, start_loc_yk = wms_wh.GetLocInfo(loc_code) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), 'WMS_GetLocInfo失败!' .. start_loc_yk) end -- 获取起点的物料 local cg_detail condition = "S_CNTR_CODE ='" .. loc_Container[i].cntr_code .. "'" nRet, cg_detail = m3.GetDataObjByCondition(strLuaDEID, "CG_Detail", condition) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), cg_detail) end -- 获取物料类型 local item_type, material nRet, item_type, material = GT_Get_ItemType(strLuaDEID, cg_detail.item_code) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), item_type) end -- 钢丝只能入指定层 local str_yk if (item_type == '钢丝') then str_yk = wms_base.Get_sConst(strLuaDEID, "佳通-立库钢丝货位层") nRet, end_loc_yk = GetEndLoc(strLuaDEID, start_loc_yk.roadway, str_yk) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), end_loc) end else str_yk = wms_base.Get_sConst(strLuaDEID, "佳通-立库非钢丝货位层") nRet, end_loc_yk = GetEndLoc(strLuaDEID, start_loc_yk.roadway, str_yk) if (nRet == 1) then str_yk = wms_base.Get_sConst(strLuaDEID, "佳通-立库钢丝货位层") nRet, end_loc_yk = GetEndLoc(strLuaDEID, start_loc_yk.roadway, str_yk) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), end_loc) end elseif (nRet > 1) then lua.Error(strLuaDEID, debug.getinfo(1), end_loc) end end -- 创建佳通任务 local gt_task = m3.AllocObject(strLuaDEID, "GT_Task") lua.Debug(strLuaDEID, debug.getinfo(1), 'gt_task', gt_task) -- 起点信息 gt_task.start_wh_code = start_loc_yk.wh_code gt_task.start_area_code = start_loc_yk.area_code gt_task.start_loc_code = start_loc_yk.code -- 终点信息 gt_task.end_wh_code = end_loc_yk.wh_code gt_task.end_area_code = end_loc_yk.area_code gt_task.end_loc_code = end_loc_yk.code gt_task.type = 3 -- 1 粉料调拨搬运 2 烘胶搬运 3 同巷道移库 gt_task.priority = 2 -- 大的优先 gt_task.cntr_code = loc_Container[i].cntr_code nRet, gt_task = m3.CreateDataObj(strLuaDEID, gt_task) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建【佳通任务】失败!' .. gt_task) end end lua.Debug(strLuaDEID, debug.getinfo(1), "loc_Container[i].loc_code", loc_Container[i].loc_code) cntr_code = loc_Container[i].cntr_code start_loc = loc_Container[i].loc_code break end ::coroutine:: end if (start_loc == nil or start_loc == '') then lua.Error(strLuaDEID, debug.getinfo(1), '巷道没有可出库的空工装!') end else return end nRet, start_loc = wms_wh.GetLocInfo(start_loc) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), 'WMS_GetLocInfo失败!' .. start_loc) end -- step4: 创建搬运作业 local operation = m3.AllocObject(strLuaDEID, "Operation") operation.start_wh_code = start_loc.wh_code operation.start_area_code = start_loc.area_code operation.start_loc_code = start_loc.code -- 终点是佳通WMS传过来的 operation.end_wh_code = loc_start.wh_code operation.end_area_code = loc_start.area_code operation.end_loc_code = loc_start.code operation.cntr_code = cntr_code operation.op_def_name = "呼叫空托" operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-出库") nRet, operation = m3.CreateDataObj(strLuaDEID, operation) if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '创建【作业】失败!' .. operation) end lua.Debug(strLuaDEID, debug.getinfo(1), 'operation', operation) end -- v1.1 lzh 执行完成也删除这个请求删除这个请求 end