-- 四舍五入函数
|
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
|