--[[ 和项目关联比较紧密的一些函数 项目开发和实施人员 可以把 prj_base 改成各自项目特别的 xx_base 比如巨星项目就用 jx_base prj_base 是 WMS Basis 里的标准用法 --]] wms_base = require ("wms_base") wms_station = require( "wms_station" ) wms_wh = require( "wms_wh" ) wms_station = require( "wms_station" ) external_api = require ( "prj_api" ) local prj_base = {_version = "0.1.1"} --[[ 根据物料的长中短尺寸计算适用料箱, long 长边 middle 中边 short 短边 返回参数: (1)nRet 0 成功 非0失败 (2) box_style --]] function prj_base.GetBoxStyle( strLuaDEID, long, middle, short ) local nRet, strRetInfo -- 校验输入参数 if ( long == nil or long <= 0 or long >= 60) then return 1, "长边值不符合规范! 长边不能超过 60 " end if ( middle == nil or middle <= 0 or middle >= 40) then return 1, "中边值不符合规范! 中边不能超过 40 " end if ( short == nil or short <= 0 or short >= 30) then return 1, "短边边值不符合规范! 短边不能超 30 " end if ( middle > long or short > middle ) then return 1, "长中短边顺序不对!" end -- 计算料箱型号 if ( long < 20 ) then return 0, '["A","B","C","D","E"]' elseif ( long >= 20 and long < 30) then if ( middle < 20 ) then return 0, '["A","B","C","D","E"]' elseif ( middle >= 20 and middle < 30 ) then if ( short < 20 ) then return 0, '["A","B","C","D"]' else return 0, '["A","B"]' end end elseif ( long >= 30 and long < 40) then if ( middle < 20 ) then return 0, '["A","B","C"]' elseif ( middle >= 20 and middle < 30 ) then if ( short < 20 ) then return 0, '["A","B","C"]' else return 0, '["A","B"]' end elseif ( middle >= 30 and middle < 40 ) then return 0, '["A"]' end elseif ( long >= 40 and long < 60) then return 0, '["A"]' end return 1, "长边参数不对!" end function prj_base.Generate_Batch_No( item_code ) local nRet, strRetInfo if ( item_code == '' or item_code == nil ) then return 1, "generate_batch_no 输入参数必须有值" end local strCode = '' local strHeader = item_code..'_'..os.date("%y%m%d")..'-' nRet, strCode = mobox.getSerialNumber( "入库批次", strHeader, 3 ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '申请入库批次号失败!'..strCode ) end local seg = lua.split( strCode, "_" ) return 0, seg[2] end --[[ 获取某个库区内设备的状态(在JX项目中特指库区内的堆垛机状态) 输入参数: area_code -- 库区编码 返回参数: nRet = 0 成功 非零 失败 stacker_dev = [{"dev_no"::xxx",aisle:1,aisle_no:"A01",enable:0/1,cntr_num:0}] -- cntr_num 巷道入库接驳位容器数量 -- aisle 巷道编码 -- dev_no 堆垛机号 --]] function prj_base.Get_stacker_dev_state( strLuaDEID, area_code ) local nRet, strRetInfo if ( station == nil ) then station = '' end -- 获取 area_code 库区堆垛机设备工作状态,确定哪些巷道可以使用 local const_name = "库区"..area_code.."-堆垛机设备" nRet, strRetInfo = wms_base.Get_sConst2( strLuaDEID, const_name ) if ( nRet ~= 0 ) then return 1, "系统无法获取常量'"..const_name.."'" end if ( strRetInfo == '') then return 1, "常量'"..const_name.."' 不能为空! " end --[{"dev_no"::xxx",aisle:1,aisle_no:"A01",enable:false/true}] local stacker_dev, success success, stacker_dev = pcall( json.decode, strRetInfo) if ( success == false ) then return 1, "常量'"..const_name.."'的JSON格式非法! --> "..strRetInfo end local n, m local dev_codes = '' for n = 1, #stacker_dev do dev_codes = dev_codes..stacker_dev[n].dev_no.."," end if ( dev_codes == '') then return 1, "库区'"..area_code.."'没有定义设备!" end dev_codes = lua.trim_laster_char( dev_codes ) -- 调用WCS接口获取设备状态 下面的函数可以更新具体项目做调整 -- [{"DVC_NO":"TC21","IS_USE":0/1,"CON_NUM":1},...] nRet, dev_state = external_api.Get_DEV_State( strLuaDEID, dev_codes ) if ( nRet ~= 0 ) then return nRet, dev_state end local find for n = 1, #stacker_dev do find = false for m = 1, #dev_state do if ( stacker_dev[n].dev_no == dev_state[m].DVC_NO ) then find = true stacker_dev[n].enable = lua.Get_NumAttrValue( dev_state[m].IS_USE ) stacker_dev[n].cntr_num = lua.Get_NumAttrValue( dev_state[m].CON_NUM ) break end end if ( find == false ) then return 1, "WCS返回的设备状态中没有编码='"..stacker_dev[n].dev_no.."'的设备状态!" end end return 0, stacker_dev end -- 获取库区库可用的堆垛机巷道编码 -- 'A01', 'A02', 'A04' function prj_base.Get_Available_Lane( strLuaDEID, area_code ) local nRet, stacker_dev nRet, stacker_dev = prj_base.Get_stacker_dev_state( strLuaDEID, area_code ) if ( nRet ~= 0 ) then return nRet, stacker_dev end local n local aisle = '' for n = 1, #stacker_dev do if ( stacker_dev[n].enable == 1 ) then aisle = aisle.."'"..stacker_dev[n].aisle_no.."'," end end aisle = lua.trim_laster_char( aisle ) return 0, aisle end --[[ 创建一个预分配料箱出库作业 pac_obj 预分配料箱对象 { S_PAC_NO,N_B_STATE, S_STATION_NO, S_CNTR_CODE, S_BS_TYPE, S_BS_NO } ]] function prj_base.Create_Pre_Alloc_CNTR_OutOperation ( strLuaDEID, pac_obj ) local nRet, strRetInfo local msg local pac_no = pac_obj.S_PAC_NO local b_state = lua.Get_NumAttrValue( pac_obj.N_B_STATE ) local to_station = pac_obj.S_STATION_NO local cntr_code = lua.Get_StrAttrValue( pac_obj.S_CNTR_CODE ) local bs_type = lua.Get_StrAttrValue( pac_obj.S_BS_TYPE ) local bs_no = lua.Get_StrAttrValue( pac_obj.S_BS_NO ) -- 【组盘容器】数据对象属性判断,不合法的终止程序执行 if ( b_state ~= 0 ) then msg = "预分配号'"..pac_no.."'的状态不是未执行状态,不能启动料箱出库作业!" lua.Warning( strLuaDEID, debug.getinfo(1), msg ) return 1, msg end if ( cntr_code == '' ) then msg = "预分配号'"..pac_no.."'中的容器编码为空!" lua.Warning( strLuaDEID, debug.getinfo(1), msg ) return 1, msg end local from_loc_code = wms_wh.GetLocCodeByCNTR( strLuaDEID, cntr_code ) if ( from_loc_code == nil or from_loc_code == '' ) then msg = "预分配号'"..pac_no.."'中的容器'"..cntr_code.."'没有绑定货位!" return 1, msg end local from_loc nRet, from_loc = wms_wh.GetLocInfo( from_loc_code ) if ( nRet ~= 0 ) then return 1, '获取货位信息失败! '..loc_code end -- 创建【料箱出库】作业 -- 获取站点货位,站点货位定义在常量中 local to_loc_code nRet, to_loc_code = wms_station.Get_Station_Loc( strLuaDEID, to_station ) if ( nRet ~= 0 ) then return 1, to_loc_code end local to_loc nRet, to_loc = wms_wh.GetLocInfo( to_loc_code ) if ( nRet ~= 0 ) then return 1, '获取货位信息失败! '..to_loc end local operation = m3.AllocObject(strLuaDEID,"Operation") operation.bs_state = 8 -- 待启动前,这些作业有待后台脚本来设置为状态 0 operation.start_wh_code = from_loc.wh_code operation.start_area_code = from_loc.area_code operation.start_loc_code = from_loc_code operation.end_wh_code = to_loc.wh_code operation.end_area_code = to_loc.area_code operation.end_loc_code = to_loc_code operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-出库") operation.op_def_name = "料箱出库" -- 注意这些可能会根据项目的不同而不同,就是出库的作业类型 operation.cntr_code = cntr_code operation.carry_cb_cls = "Pre_Alloc_Container" -- 预分配容器 operation.carry_cb_no = pac_no nRet, operation = m3.CreateDataObj( strLuaDEID, operation ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '创建【作业】失败!'..operation ) end -- 更新【组盘容器】对象属性 -- N_B_STATE = 1 表示组盘容器已经安排作业进行搬运 local strUpdateSql = "S_FROM_LOC = '"..from_loc_code.."', N_B_STATE = 1, S_OUT_OP_NO = '"..operation.code.."'" strCondition = "S_PAC_NO = '"..pac_no.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Pre_Alloc_Container", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【组盘容器】信息失败!"..strRetInfo ) end -- 获取【预分配容器】的业务来源,设置业务来源的状态 if ( bs_type == "Inbound_Wave" and bs_no ~= '') then -- N_B_STATE = 2 表示入库波次已经开始作业 strUpdateSql = "N_B_STATE = 2, S_B_STATE = 'Start'" strCondition = "S_WAVE_NO = '"..bs_no.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Wave", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【入库波次】信息失败!"..strRetInfo ) end elseif ( bs_type == "Inbound_Order" and bs_no ~= '' ) then -- N_B_STATE = 1 表示分配料箱开始作业 strUpdateSql = "N_B_STATE = 2, S_B_STATE = 'Start'" strCondition = "S_NO = '"..bs_no.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Order", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【入库单】信息失败!"..strRetInfo ) end end return 0 end --////////////////////////////////////////////////////////////////////////// -- 巷道任务+空料箱排序 local function aisle_list_sort( loc1, loc2 ) if ( loc1.abc_cls < loc2.abc_cls ) then return true elseif ( loc1.abc_cls == loc2.abc_cls ) then -- 巷道空位多优先 return loc1.aisle_empty_num > loc2.aisle_empty_num end return false end local function task_num_abc_cls( aisle_list ) local max_task_num = 0 local n, nCount nCount = #aisle_list if ( 0 == nCount ) then return 0 end for n = 1, nCount do if ( aisle_list[n].task_num > max_task_num ) then max_task_num = aisle_list[n].task_num end end if ( max_task_num <= 3 ) then for n = 1, nCount do if ( aisle_list[n].task_num == 0 ) then aisle_list[n].abc_cls = "A" elseif ( aisle_list[n].task_num >= 2 ) then aisle_list[n].abc_cls = "C" else aisle_list[n].abc_cls = "B" end end else for n = 1, nCount do if ( aisle_list[n].task_num == 0 ) then aisle_list[n].abc_cls = "A" elseif ( aisle_list[n].task_num < max_task_num/2 ) then aisle_list[n].abc_cls = "B" else aisle_list[n].abc_cls = "C" end end end table.sort( aisle_list, aisle_list_sort ) end -- 计算料箱库入库区货位(任务均衡),考虑巷道货位均衡, 基本原则是: 巷道任务少优先,巷道空货位多的优先 -- 返回入库缓存区货位和巷道内存储货位(2个货位) -- V2.0 HAN 20241120 根据站台位置获取相应的 堆垛机入库缓存区,增加一个站台编码 station function prj_base.Get_StorageCache_Loc( strLuaDEID, station ) local nRet, strRetInfo local task_type = wms_base.Get_nConst( strLuaDEID, "任务类型-输送线入库搬运" ) local station_attr --[[ station_attr = {"loc_code":"S-A","entry_area_name":"A","code":"A","factory":"0001","storage_area":"K2","entry_area_code":"K4","mac":"A"} entry_area -- 入库接驳区 storage_area -- 存储区 loc_orde = 0 根据列顺序 1 -- 倒序 ]] nRet, station_attr = wms_station.Get_Station_ExtData( strLuaDEID, station ) if ( nRet ~= 0 ) then return 2, station_attr end local loc_order = lua.Get_NumAttrValue( station_attr.loc_order ) -- 站台指定的入库接驳区 local storage_cache_arae = lua.Get_StrAttrValue( station_attr.entry_area_code ) if ( storage_cache_arae == '') then return 2, "'机台-"..station.."'没有定义入库口区域编码信息!" end -- 获取入库接驳区货位的使用情况 local strCondition = "C_ENABLE = 'Y' AND S_AREA_CODE = '"..storage_cache_arae.."'" local strOrder = "S_CODE" local loc_objs local aisle_connect_loc_set = {} nRet, loc_objs = m3.QueryDataObject( strLuaDEID, "Location", strCondition, strOrder ) if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "获取【Location】信息失败! " .. loc_objs ) end for n = 1, #loc_objs do obj_attrs = m3.KeyValueAttrsToObjAttr(loc_objs[n].attrs) -- 这些货位里把这个货位对应的巷道信息保存在 S_EXT_ATTR aisle = lua.StrToNumber( obj_attrs.S_EXT_ATTR ) if ( aisle <= 0 or aisle > 4 ) then return 2, "输送线入库缓存位'"..obj_attrs.S_CODE.."'没有定义对应的巷道号或巷道号不合法" end local connect_loc = { aisle = aisle, loc_code = obj_attrs.S_CODE, --capacity = lua.StrToNumber( obj_attrs.N_CAPACITY ), --cur_num = lua.StrToNumber( obj_attrs.N_CURRENT_NUM ), } table.insert( aisle_connect_loc_set, connect_loc ) end -- 站台指定的入库存储区 local storage_area = lua.Get_StrAttrValue( station_attr.storage_area ) if ( storage_area == '') then return 2, "'机台-"..station.."'没有定义存储区编码信息!" end -- 获取库区 storage_area 内设备状态 local stacker_dev nRet, stacker_dev = prj_base.Get_stacker_dev_state( strLuaDEID, storage_area, station ) if ( nRet ~= 0 ) then return 2, stacker_dev end local n, m local storage_cache_list = {} local obj_attrs local task_num, max_task_num, empty_loc_num local loc_count = #loc_objs local loc_index local connect_loc -- 获取立库巷道口货位的基本信息,保存到 storage_cache_list max_task_num = 0 for n = 1, #stacker_dev do -- 获取设备所在巷道 aisle = stacker_dev[n].aisle if ( aisle <= 0 or aisle > 4 ) then return 2, "库区"..storage_area.."中的巷道号只能在1~4!" end -- enable = 1 表示巷道堆垛机可用 if ( stacker_dev[n].enable == 1 ) then task_num = stacker_dev[n].cntr_num if ( task_num > max_task_num ) then max_task_num = task_num end -- 查询货位启用、空货位、在本巷道、没被锁的货位数量 strCondition = "N_AISLE = "..aisle.." AND S_AREA_CODE = '"..storage_area.."' AND C_ENABLE = 'Y' AND N_CURRENT_NUM = 0 AND N_LOCK_STATE = 0" nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Location", strCondition ) if ( nRet ~= 0 ) then return nRet, strRetInfo end empty_loc_num = lua.StrToNumber( strRetInfo ) if ( empty_loc_num > 0 ) then -- 获取该巷道的 入库接驳位 loc_index = 0 for m = 1, #aisle_connect_loc_set do if ( aisle_connect_loc_set[m].aisle == aisle ) then loc_index = m break end end if ( loc_index ~= 0 ) then local cache_loc = { loc_code = aisle_connect_loc_set[loc_index].loc_code, aisle = aisle, task_num = task_num, -- 任务数量 aisle_empty_num = empty_loc_num, -- 对应巷道的空货位数量 abc_cls = "" -- ABC 分类 } table.insert( storage_cache_list, cache_loc ) end end end end -- 计算 各入库缓存区的 任务数量 ABC 分类值 没有任务的为 A,任务数大于 0 小于 max_task_num/2 的为B,其余为 C local nCount = #storage_cache_list if ( nCount == 0 ) then return 1, "系统无法分配货位!" end -- 排序 abc_cls 按ABC排序,同样等级的abc_cls 根据roadway_empty_num排序,空货位多的在前面 task_num_abc_cls( storage_cache_list ) -- 获取巷道内空货位 local storage_arae nRet, storage_arae = wms_base.Get_sConst2( strLuaDEID, "料箱库存储区" ) if ( nRet ~= 0 ) then lua.Stop( strLuaDEID, "系统无法获取常量'料箱库存储区'") return end local ret_loc -- strLuaDEID, 库区, 巷道号, 货位排序方法, 顺序/倒序, 附加条件, 取货位数量 nRet, ret_loc = wms_alg.Get_Aisle_Empty_Loc( strLuaDEID, storage_arae, storage_cache_list[1].aisle, 0, loc_order, "", 1 ) if ( nRet ~= 0 ) then return 1, "计算巷道"..storage_cache_list[1].aisle.."内货位失败!"..ret_loc end nRet, loc = wms_wh.GetLocInfo( ret_loc.loc_code ) if ( nRet ~= 0 ) then return 1, "获取货位'"..ret_loc.loc_code.."'信息失败! "..loc end -- 返回 立库巷道口入库货位,巷道内存储货位 return 0, storage_cache_list[1].loc_code, ret_loc.loc_code end --[[ 根据站台位置创建一个入库作业,处理以下事情 -- 从立库中获取一个空货位 -- 创建一个作业 -- 给获取的空货位加入库锁 输入参数: -- source_sys 来源系统 -- station 站台位置 -- cntr_code 容器号 -- op_def_name 作业定义名称 -- ext_info 扩展参数{carry_cb_cls,carry_cb_no, bs_type,bs_no,cc_no,dc_no} carry_cb_cls -- 作业携带容器的业务类型(预分配容器,配盘容器,盘点容器) 返回: nRet operation ]] function prj_base.Create_StorageOperation( strLuaDEID, source_sys, station, cntr_code, op_def_name, ext_info ) local nRet, strRetInfo local loc_code nRet, loc_code = wms_station.Get_Station_Loc( strLuaDEID, station ) if ( nRet ~= 0 ) then return 1, loc_code end local loc nRet, loc = wms_wh.GetLocInfo( loc_code ) if ( nRet ~= 0 ) then return 1, '获取货位信息失败! '..loc_code end --V2.0 创建作业前对容器进行判断,如容器已经存在 active 作业,不能创建 nRet, can_usedin_op = wms_cntr.CanUsedInOperation( strLuaDEID, cntr_code ) if ( nRet ~= 0 ) then return 2, can_usedin_op end if ( can_usedin_op == false ) then return 1, "料箱'"..cntr_code.."'存在未完成的作业,不能继续创建作业!" end local operation = m3.AllocObject(strLuaDEID,"Operation") operation.source_sys = source_sys operation.start_wh_code = loc.wh_code operation.start_area_code = loc.area_code operation.start_loc_code = loc_code -- 计算料箱入库货位,首先计算到哪个输送线入库缓存区 local str_end_loc_code, aisle_in_loc nRet, aisle_in_loc, str_end_loc_code = prj_base.Get_StorageCache_Loc( strLuaDEID, station ) if ( nRet ~= 0 ) then if ( nRet == 1 ) then return 1, "prj_base.Get_StorageCache_Loc 失败!"..aisle_in_loc end return 2, aisle_in_loc end local end_loc nRet, end_loc = wms_wh.GetLocInfo( str_end_loc_code ) if ( nRet ~= 0 ) then return 2, '获取货位信息失败! '..str_end_loc_code end operation.end_wh_code = end_loc.wh_code operation.end_area_code = end_loc.area_code operation.end_loc_code = str_end_loc_code operation.ext_data = aisle_in_loc -- 巷道口入库缓存货位 operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-入库") operation.op_def_name = op_def_name operation.cntr_code = cntr_code if ( ext_info ~= nil and ext_info ~= '') then operation.carry_cb_cls = lua.Get_StrAttrValue( ext_info.carry_cb_cls ) operation.carry_cb_no = lua.Get_StrAttrValue( ext_info.carry_cb_no ) operation.bs_type = lua.Get_StrAttrValue( ext_info.bs_type ) operation.bs_no = lua.Get_StrAttrValue( ext_info.bs_no ) end nRet, operation = m3.CreateDataObj( strLuaDEID, operation ) if ( nRet ~= 0 ) then return 2, '创建【作业】失败!'..operation end return 0, operation end --[[ 检查一下预入库容器 pac_no 下面的 detail 是否已经完成处理完成,如果完成处理 创建一个 入库作业 适合预分配料箱入库作业,station 为站台编码, cntr_code 是料箱编码 返回值: action ]] function prj_base.Pre_Alloc_CNTR_PostProcess( strLuaDEID, pac_no, station, cntr_code ) local nRet, strRetInfo if ( lua.StrIsEmpty( pac_no ) ) then return 2, "预分配料箱流水号必须有值!" end -- 检查一下当前料箱的入库任务是否已经全部完成,如果完成就创建一个【货品入库】作业 -- N_B_STATE = 1 表示科执行的入库任务 local strCondition = "S_PAC_NO = '"..pac_no.."' AND N_B_STATE = 1 " nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Pre_Alloc_CNTR_Detail", strCondition ) if ( nRet ~= 0 ) then return 2, strRetInfo end local nCount = lua.StrToNumber( strRetInfo ) local operation = {} local strUpdateSql local action = { { action_type = "refresh_master_panel", value = { sub_page = {"当前任务", "未执行任务"} } } } if ( nCount == 0 ) then -- *** -- 发现过相同有相同预分配容器的入库作业,这是严重的数据错误,这里加一个判断 N_TYPE = 1 是执行的意思 strCondition = "S_CARRY_CB_NO = '"..pac_no.."' AND N_TYPE = 1 AND S_CARRY_CB_CLS = 'Pre_Alloc_Container'" nRet, strRetInfo = mobox.existThisData( strLuaDEID, "Operation", strCondition ) if ( nRet ~= 0 ) then return 2, strRetInfo end -- 如果该车辆编码的动作已经在队列,返回,不做处理 if ( strRetInfo == "yes" ) then return 2, "容器号'"..cntr_code.."'不能重复创建货品入库作业!" end -- 创建【货品入库】作业. 【组盘容器】状态改为3, CG_Detail 加【组盘容器明细】中的内容 local ext_info = { carry_cb_cls = "Pre_Alloc_Container", carry_cb_no = pac_no } nRet, operation = prj_base.Create_StorageOperation( strLuaDEID, "WMS", station, cntr_code, "货品入库", ext_info ) if ( nRet ~= 0 ) then mobox.setInfo( strLuaDEID, "预分配料箱组盘完成后,无法创建入库作业! 错误号:100 -->"..operation ) -- 7 组盘完成入库时发现入不了库,回库出现问题, 问题编码 5100 strUpdateSql = "N_B_STATE = 7, S_B_STATE = 'Err', N_ERR_CODE = 5100, S_ERR_MSG = '"..lua.FormatSQLString(operation).."'" strCondition = "S_PAC_NO = '"..pac_no.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Pre_Alloc_Container", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then return 2, "更新【组盘容器】信息失败!"..strRetInfo end return 0, action end --【组盘容器】+ 回库作业号, 状态 = 4 (回库) local strUpdateSql = "S_BACK_OP_NO = '"..operation.code.."', N_B_STATE = 4" strCondition = "S_PAC_NO = '"..pac_no.."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Pre_Alloc_Container", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then return 2, "更新【组盘容器】信息失败!"..strRetInfo end --容器中的【CG_Detail】新增,把【组盘容器明细】中的内容加入 nRet, strRetInfo = wms_cntr.Add_CG_Detail_By_PAC_Detail( strLuaDEID, cntr_code, pac_no ) if ( nRet ~= 0 ) then return 2, 'wms_cntr.Add_CG_Detail_By_PAC_Detail!'..strRetInfo end --重置料箱信息 local container nRet, container = wms_cntr.GetInfo( strLuaDEID, cntr_code ) if (nRet ~= 0) then return 2, "获取【容器】信息失败! " .. container end nRet, strRetInfo = wms_cntr.Reset( strLuaDEID, container ) if ( nRet ~= 0 ) then return 2, strRetInfo end --入库作业产生需要对入库作业的终点获取加入库锁 nRet, strRetInfo = wms.wms_LockLocation(strLuaDEID, operation.end_loc_code, wms_base.Get_nConst( strLuaDEID, "锁类型-入库锁" ), "", operation.code, operation.op_def_name ) if (nRet ~= 0) then return 2, "wms_LockLocation 失败!"..strRetInfo end action[2] = { action_type = "set_dlg_attr", value = { { attr = "UPC", value = "", enable = true, prompt = "请扫商品条码..." }, { attr = "S_CNTR_CODE", value = "", enable = false }, { attr = "S_CELL_NO", value = "", enable = false }, { attr = "S_ITEM_CODE", F_QTY = "", enable = false }, { attr = "F_QTY", value = "", enable = false }, { attr = "F_ACT_QTY", value = "", enable = false }, { attr = "S_ITEM_NAME", value = "", enable = false } } } action[3] = { action_type = "refresh_related_panel", value = { { panel_name = "料格显示", input_parameter = { cell_no = "" } } } } action[4] = { action_type = "set_master_panel_cursor", value = { form_name = "3055 TOP VIEW", ctrl_id = "S_CNTR_CODE", value = ""} } end return 0, action end return prj_base