--[[
|
巨星二期WMS项目中Lua用到的一下公共函数
|
|
更改记录:
|
V3.0 HAN 20241127 增加对设备状态的获取
|
--]]
|
|
|
|
wms_wh = require ("wms_wh")
|
wms_out = require ("wms_outbound")
|
wms_alg = require ("wms_base_algorithm")
|
jx_api = require ("jx_external_api")
|
|
local jx_base = {_version = "0.1.1"}
|
|
--[[
|
1# GetBoxStyle 根据物料的尺寸计算该物料适配的料箱规格
|
2# Generate_Batch_No 生成货品储存时用的批次号,同一个货品在一个料格要换一次批次号用顺序号解决
|
3# Get_StorageCache_Loc 获取输送线存储缓存区货位
|
|
5# Get_Usable_Lane 获取可用巷道(有些堆垛机故障后这些巷道会不可用)
|
6# Get_Station_ExtData 获取机台的扩展数据(里面有mac地址,货位,去向库区等)
|
7# Get_Usable_Lane 获取机台的货位
|
8# Get_EmptyBox_Loc ***获取指定库区内的空料箱
|
9# Organize_CNTR_PostProcess 组盘入库后处理
|
]]
|
|
--//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
-- 根据物料的长中短尺寸计算适用料箱
|
-- long 长边 middle 中边 short 短边
|
-- 返回参数:
|
-- nRet 0 成功 非0失败
|
-- box_style
|
function jx_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 jx_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
|
|
--[[
|
获取 area_code 库区里可使用的堆垛机设备所在的巷道
|
--]]
|
function jx_base.Get_Usable_Lane( strLuaDEID, area_code )
|
local nRet, strRetInfo
|
|
if ( area_code == nil or area_code == '') then
|
return 1, "jx_base.Get_Usable_Lane 输入参数 area_code不能为空!"
|
end
|
local stacker_dev = wms_base.Get_sConst( strLuaDEID, area_code.."-堆垛机设备" )
|
end
|
|
-- 获取 ‘机台-XX’ 常量并且解析成一个 站台扩展属性的 table
|
function jx_base.Get_Station_ExtData( strLuaDEID, station_code )
|
if ( station_code == nil or station_code == '') then
|
return 1, "jx_base.Get_Station_ExtData 函数中 station_code 不能为空!"
|
end
|
-- 通过盘点站台获取出库终点货位
|
local station_info = wms_base.Get_sConst( strLuaDEID, "机台-"..station_code, 1 )
|
if ( station_info == '' ) then
|
return 1, "机台-"..station_code.." 常量中没有定义信息, 或没定义这个机台常量!"
|
end
|
local staion_attr = json.decode( station_info )
|
|
return 0, staion_attr
|
end
|
|
-- 获取 ‘机台-XX’ 所在货位
|
function jx_base.Get_Station_Loc( strLuaDEID, station_code )
|
local nRet, station_data
|
nRet, station_data = jx_base.Get_Station_ExtData( strLuaDEID, station_code )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), station_data ) end
|
return station_data.loc_code
|
end
|
|
--[[
|
获取某个库区内设备的状态(在JX项目中特指库区内的堆垛机状态)
|
输入参数:
|
area_code -- 库区编码
|
station -- 入库时的扫码点,可以不输入
|
|
返回参数:
|
nRet = 0 成功 非零 失败
|
stacker_dev = [{"dev_no"::xxx",lane:1,enable:0/1,cntr_num:0}]
|
-- cntr_num 巷道入库接驳位容器数量
|
-- lane 巷道号
|
-- dev_no 堆垛机号
|
--]]
|
function jx_base.Get_stacker_dev_state( strLuaDEID, area_code, station )
|
local nRet, strRetInfo
|
if ( station == nil ) then station = '' end
|
|
-- 获取 area_code 库区堆垛机设备工作状态,确定哪些巷道可以使用
|
strRetInfo = wms_base.Get_sConst( strLuaDEID, "库区"..area_code.."-堆垛机设备" )
|
if ( strRetInfo == '') then
|
return 1, "常量'库区"..area_code.."-堆垛机设备' 不能为空! "
|
end
|
--[{"dev_no"::xxx",lane:1,enable:false/true}]
|
local stacker_dev = json.decode( strRetInfo )
|
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 = jx_api.JW_DVC_State( strLuaDEID, dev_codes, station )
|
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
|
|
-- 获取库区库可用的堆垛机巷道号 -- 1, 2, 4
|
function jx_base.Get_Available_Lane( strLuaDEID, area_code )
|
local nRet, stacker_dev
|
|
nRet, stacker_dev = jx_base.Get_stacker_dev_state( strLuaDEID, area_code )
|
if ( nRet ~= 0 ) then return nRet, stacker_dev end
|
|
local n
|
local lane = ''
|
for n = 1, #stacker_dev do
|
if ( stacker_dev[n].enable == 1 ) then
|
lane = lane..stacker_dev[n].lane..","
|
end
|
end
|
lane = lua.trim_laster_char( lane )
|
return 0, lane
|
end
|
|
--//////////////////////////////////////////////////////////////////////////
|
local function get_lane_connect_loc( lane_connect_loc_set, lane_no )
|
local n
|
|
for n = 1, #lane_connect_loc_set do
|
if ( lane_connect_loc_set[n].lane == lane_no ) then
|
return lane_connect_loc_set[n]
|
end
|
end
|
return ''
|
end
|
|
-- 排序
|
local function roadway_loc_sort( loc1, loc2 )
|
if ( loc1.abc_cls < loc2.abc_cls ) then
|
return true
|
elseif ( loc1.abc_cls == loc2.abc_cls ) then
|
-- 距离入口近的优先
|
return loc1.weight < loc2.weight
|
end
|
return false
|
end
|
|
-- 巷道任务+空料箱排序
|
local function lane_list_sort( loc1, loc2 )
|
if ( loc1.abc_cls < loc2.abc_cls ) then
|
return true
|
elseif ( loc1.abc_cls == loc2.abc_cls ) then
|
-- 巷道空位多优先
|
return loc1.roadway_empty_num > loc2.roadway_empty_num
|
end
|
return false
|
end
|
|
local function task_num_abc_cls( lane_list )
|
local max_task_num = 0
|
local n, nCount
|
|
nCount = #lane_list
|
if ( 0 == nCount ) then return 0 end
|
for n = 1, nCount do
|
if ( lane_list[n].task_num > max_task_num ) then
|
max_task_num = lane_list[n].task_num
|
end
|
end
|
if ( max_task_num <= 3 ) then
|
for n = 1, nCount do
|
if ( lane_list[n].task_num == 0 ) then
|
lane_list[n].abc_cls = "A"
|
elseif ( lane_list[n].task_num >= 2 ) then
|
lane_list[n].abc_cls = "C"
|
else
|
lane_list[n].abc_cls = "B"
|
end
|
end
|
else
|
for n = 1, nCount do
|
if ( lane_list[n].task_num == 0 ) then
|
lane_list[n].abc_cls = "A"
|
elseif ( lane_list[n].task_num < max_task_num/2 ) then
|
lane_list[n].abc_cls = "B"
|
else
|
lane_list[n].abc_cls = "C"
|
end
|
end
|
end
|
table.sort( lane_list, lane_list_sort )
|
end
|
|
-- 计算料箱库入库区货位(任务均衡),考虑巷道货位均衡, 基本原则是: 巷道任务少优先,巷道空货位多的优先
|
-- 返回入库缓存区货位和巷道内存储货位(2个货位)
|
-- V2.0 HAN 20241120 根据站台位置获取相应的 堆垛机入库缓存区,增加一个站台编码 station
|
function jx_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 = jx_base.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 lane_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
|
roadway = lua.StrToNumber( obj_attrs.S_EXT_ATTR )
|
if ( roadway <= 0 or roadway > 4 ) then
|
return 2, "输送线入库缓存位'"..obj_attrs.S_CODE.."'没有定义对应的巷道号或巷道号不合法"
|
end
|
local connect_loc = {
|
lane = roadway,
|
loc_code = obj_attrs.S_CODE,
|
--capacity = lua.StrToNumber( obj_attrs.N_CAPACITY ),
|
--cur_num = lua.StrToNumber( obj_attrs.N_CURRENT_NUM ),
|
}
|
table.insert( lane_connect_loc_set, connect_loc )
|
end
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "jx_base.Get_StorageCache_Loc-->lane_connect_loc_set", lane_connect_loc_set)
|
|
-- 站台指定的入库存储区
|
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 = jx_base.Get_stacker_dev_state( strLuaDEID, storage_area, station )
|
if ( nRet ~= 0 ) then return 2, stacker_dev end
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "jx_base.Get_StorageCache_Loc-->stacker_dev", stacker_dev)
|
|
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
|
-- 获取设备所在巷道
|
roadway = stacker_dev[n].lane
|
if ( roadway <= 0 or roadway > 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_ROADWAY = "..roadway.." 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, #lane_connect_loc_set do
|
if ( lane_connect_loc_set[m].lane == roadway ) then
|
loc_index = m
|
break
|
end
|
end
|
if ( loc_index ~= 0 ) then
|
local cache_loc = {
|
loc_code = lane_connect_loc_set[loc_index].loc_code,
|
roadway = roadway,
|
task_num = task_num, -- 任务数量
|
roadway_empty_num = empty_loc_num, -- 对应巷道的空货位数量
|
abc_cls = "" -- ABC 分类
|
}
|
table.insert( storage_cache_list, cache_loc )
|
end
|
end
|
end
|
end
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "jx_base.Get_StorageCache_Loc-->storage_cache_list1", storage_cache_list)
|
|
-- 计算 各入库缓存区的 任务数量 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 )
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "jx_base.Get_StorageCache_Loc-->storage_cache_list2", storage_cache_list)
|
|
-- 获取巷道内空货位
|
local storage_arae = wms_base.Get_sConst( strLuaDEID, "料箱库存储区" )
|
local ret_loc
|
|
-- strLuaDEID, 库区, 巷道号, 货位排序方法, 顺序/倒序, 附加条件, 取货位数量
|
nRet, ret_loc = wms_alg.Get_Roadway_Empty_Loc( strLuaDEID, storage_arae, storage_cache_list[1].roadway, 0, loc_order, "", 1 )
|
|
if ( nRet ~= 0 ) then
|
return 1, "计算巷道"..storage_cache_list[1].roadway.."内货位失败!"..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
|
|
-- 获取一个空料箱货位
|
local function get_empty_box_location( strLuaDEID, trans_id, area_code, lane_list, box_type )
|
local nRet, strRetInfo, n
|
local nCount = #lane_list
|
|
-- 对巷道内任务数量进行重新分类
|
task_num_abc_cls( lane_list )
|
-- 取排列第一的exit_loc_list 所在巷道的空料箱
|
lua.Debug( strLuaDEID, debug.getinfo(1), "jx_base.Get_EmptyBox_Loc--->lane_list1", lane_list )
|
local roadway = 0
|
for n = 1, nCount do
|
if ( lane_list[n].roadway_empty_num > 0 ) then
|
roadway = lane_list[n].roadway
|
break
|
end
|
end
|
if ( roadway == 0 ) then return 1, "库区'"..area_code.."'没有空料箱!" end
|
|
-- 要联表查询的表
|
local strTable = "TN_Container a LEFT JOIN TN_Loc_Container b ON a.S_CODE = b.S_CNTR_CODE"
|
-- 要查询的属性
|
local strAttrs = "a.S_CODE, b.S_LOC_CODE"
|
|
-- 从指定的巷道获取巷道内 巨星空料箱,根据位置进行排序
|
strCondition = "a.N_EMPTY_FULL = 0 AND a.N_TYPE = "..box_type..
|
"AND a.S_CODE IN ( select S_CNTR_CODE from TN_Loc_Container with (NOLOCK) where S_LOC_CODE IN "..
|
"(select S_CODE from TN_Location with (NOLOCK) where S_AREA_CODE = '"..area_code.."' AND N_ROADWAY = "..roadway.."))"..
|
"AND a.N_LOCK_STATE = 0 AND a.C_ENABLE = 'Y'"
|
strOrder = ""
|
nRet, strRetInfo = mobox.queryMultiTable(strLuaDEID, strAttrs, strTable, 1, strCondition, strOrder )
|
|
if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1),"QueryDataObject失败!"..strRetInfo ) end
|
if ( strRetInfo == '' ) then return 1, "库区'"..area_code.."'没有空料箱!" end
|
local ret_attr = json.decode(strRetInfo)
|
|
-- 巷道任务+1,这种批量分配的料箱还没创建任务,所以查Task是查不到巷道任务数量的
|
for n = 1, nCount do
|
if ( lane_list[n].roadway == roadway ) then
|
lane_list[n].task_num = lane_list[n].task_num + 1
|
lane_list[n].roadway_empty_num = lane_list[n].roadway_empty_num - 1
|
break
|
end
|
end
|
lua.Debug( strLuaDEID, debug.getinfo(1), "jx_base.Get_EmptyBox_Loc--->lane_list2", lane_list )
|
|
-- 返回: 巷道, 容器编码、货位编码
|
local cntr_code = ret_attr[1][1]
|
local loc_code = ret_attr[1][2]
|
nRet, strRetInfo = wms_cntr.Lock( strLuaDEID, cntr_code, 2, trans_id )
|
if ( nRet ~= 0 ) then return 2, strRetInfo end
|
return 0, roadway, cntr_code, loc_code
|
end
|
|
--[[
|
【关键函数】
|
空料箱货位计算, 基本原则是: 巷道任务少优先,巷道空料箱多的优先, 不锁容器
|
参数说明:
|
area_code -- 存储库区编码
|
trans_id -- 事务标识
|
box_type = 2 是给巨星WMS用的容器, 3 -- 是料箱给巨沃用的料箱
|
num -- 空料箱的个数缺省=1
|
返回参数:
|
nRet, roadway -- 巷道 cntr_code/料箱号, loc_code/货位号
|
]]
|
|
function jx_base.Get_EmptyBox_Loc( strLuaDEID, trans_id, area_code, box_type, num )
|
local nRet, strRetInfo
|
|
if ( area_code == nil or area_code == '') then
|
return 2, "jx_base.Get_EmptyBox_Loc 中参数 area_code 必须有值! "
|
end
|
if ( box_type == nil ) then
|
return 2, "jx_base.Get_EmptyBox_Loc 中参数 box_type 必须有值! "
|
end
|
if ( num == nil ) then num = 1 end
|
|
-- 获取库区内设备状态
|
nRet, stacker_dev = jx_base.Get_stacker_dev_state( strLuaDEID, area_code )
|
if ( nRet ~= 0 ) then return 2, stacker_dev end
|
|
local n, roadway
|
local lane_list = {} -- 巷道
|
local task_num, empty_box_num
|
|
-- 获取立库巷道口货位的基本信息,保存到 storage_cache_list
|
for n = 1, #stacker_dev do
|
-- 获取设备所在巷道
|
roadway = stacker_dev[n].lane
|
if ( roadway <= 0 or roadway > 4 ) then
|
return 2, "库区"..area_code.."中的巷道号只能在1~4!"
|
end
|
if ( stacker_dev[n].enable == 1 ) then
|
-- 获取该巷道未完成的任务数量
|
-- N_B_STATE < 3 表示任务的状态为 0等待/1已推送/2执行中, 任务的 area_code 的巷道 roadway
|
-- 任务包括进出的
|
strCondition = "N_B_STATE < 3 AND ( N_START_LANE = "..roadway.." or N_END_LANE = "..roadway..")"..
|
"AND ( S_START_AREA = '"..area_code.."' or S_END_AREA = '"..area_code.."')"
|
|
nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Task", strCondition )
|
if ( nRet ~= 0 ) then return nRet, strRetInfo end
|
task_num = lua.StrToNumber( strRetInfo )
|
|
-- 查询容器为空,满足类型条件,在某库区,某巷道
|
strCondition = "N_EMPTY_FULL = 0 AND N_TYPE = "..box_type..
|
"AND S_CODE IN ( select S_CNTR_CODE from TN_Loc_Container with (NOLOCK) where S_LOC_CODE IN "..
|
"(select S_CODE from TN_Location with (NOLOCK) where S_AREA_CODE = '"..area_code.."' AND N_ROADWAY = "..roadway.."))"..
|
"AND N_LOCK_STATE = 0 AND C_ENABLE = 'Y'"
|
|
nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Container", strCondition )
|
if ( nRet ~= 0 ) then return nRet, strRetInfo end
|
empty_box_num = lua.StrToNumber( strRetInfo )
|
|
if ( empty_box_num > 0 ) then
|
local lane = {
|
roadway = roadway,
|
task_num = task_num, -- 任务数量
|
roadway_empty_num = empty_box_num, -- 对应巷道的空料箱数量
|
abc_cls = "" -- ABC 分类
|
}
|
table.insert( lane_list, lane )
|
end
|
end
|
end
|
|
-- 计算 各入库缓存区的 任务数量 ABC 分类值 没有任务的为 A,任务数大于 0 小于 max_task_num/2 的为B,其余为 C
|
local nCount = #lane_list
|
if ( nCount == 0 ) then
|
return 1, "库区'"..area_code.."'无法出空料箱!"
|
end
|
|
local empty_box_list = {}
|
for n = 1, num do
|
nRet, roadway, cntr_code, loc_code = get_empty_box_location( strLuaDEID, trans_id, area_code, lane_list, box_type )
|
if ( nRet == 0 ) then
|
local empty_box = {
|
roadway = roadway, cntr_code = cntr_code, loc_code = loc_code
|
}
|
table.insert( empty_box_list, empty_box )
|
else
|
if ( nRet > 1 ) then return 2, roadway end
|
end
|
end
|
return 0, empty_box_list
|
|
end
|
|
|
-- 输送线入库任务完成,系统自动创建一个堆垛机入库任务
|
function jx_base.ConveyorLineStorage_Task_Finish( strLuaDEID, task, operation )
|
local nRet, strRetInfo
|
|
-- 创建堆垛机入库任务
|
local new_task = m3.AllocObject(strLuaDEID,"Task")
|
|
new_task.op_code = operation.code -- 作业编码
|
new_task.source_sys = operation.source_sys -- 来源系统
|
new_task.op_name = operation.op_def_name
|
new_task.factory = operation.factory -- 工厂
|
new_task.bs_type = operation.bs_type
|
new_task.bs_no = operation.bs_no
|
new_task.type = wms_base.Get_nConst(strLuaDEID, "任务类型-堆垛机入库搬运")
|
new_task.cntr_code = task.cntr_code
|
-- 起点
|
new_task.start_wh_code = task.end_wh_code
|
new_task.start_area_code = task.end_area_code
|
new_task.start_loc_code = task.end_loc_code
|
-- 终点
|
new_task.end_wh_code = operation.end_wh_code
|
new_task.end_area_code = operation.end_area_code
|
new_task.end_loc_code = operation.end_loc_code
|
new_task.schedule_type = wms_base.Get_nConst(strLuaDEID, "调度类型-堆垛机") -- 设置调度类型
|
|
nRet, new_task = m3.CreateDataObj(strLuaDEID, new_task)
|
if (nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1),"创建堆垛机任务失败!"..new_task) end
|
|
return 0
|
end
|
|
--[[
|
根据站台位置创建一个入库作业,处理以下事情
|
-- 从立库中获取一个空货位
|
-- 创建一个作业
|
-- 给获取的空货位加入库锁
|
|
输入参数:
|
-- source_sys 来源系统
|
-- station 站台位置
|
-- cntr_code 容器号
|
-- op_def_name 作业定义名称
|
-- ext_info 扩展参数{orgc_no,bs_type,bs_no,cc_no,dc_no}
|
orgc_no 组盘用 cc_no 盘点 dc_no 分拣
|
返回:
|
nRet
|
operation
|
]]
|
|
function jx_base.Create_StorageOperation( strLuaDEID, source_sys, station, cntr_code, op_def_name, ext_info )
|
local nRet, strRetInfo
|
local loc_code = jx_base.Get_Station_Loc( strLuaDEID, station )
|
local loc
|
nRet, loc = wms_wh.GetLocInfo( loc_code )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '获取货位信息失败! '..loc_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, roadway_in_loc
|
nRet, roadway_in_loc, str_end_loc_code = jx_base.Get_StorageCache_Loc( strLuaDEID, station )
|
if ( nRet ~= 0 ) then
|
if ( nRet == 1 ) then
|
return 1, "jx_base.Get_StorageCache_Loc 失败!"..roadway_in_loc
|
end
|
lua.Error( strLuaDEID, debug.getinfo(1), roadway_in_loc )
|
end
|
local end_loc
|
nRet, end_loc = wms_wh.GetLocInfo( str_end_loc_code )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '获取货位信息失败! '..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 = roadway_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
|
if ( ext_info.orgc_no ~= nil ) then
|
-- 有组盘的(先空料箱呼出)
|
operation.orgc_no = ext_info.orgc_no
|
end
|
if ( ext_info.cc_no ~= nil ) then
|
-- 盘点回库
|
operation.cc_no = ext_info.cc_no
|
end
|
if ( ext_info.dc_no ~= nil ) then
|
-- 盘点回库
|
operation.dc_no = ext_info.dc_no
|
end
|
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 lua.Error( strLuaDEID, debug.getinfo(1), '创建【作业】失败!'..operation ) end
|
|
return 0, operation
|
end
|
|
--[[
|
得到当前登录人员的账号信息,并且获取登录人员的PC MAC地址,根据这个地址获取绑定的站台
|
返回一个json table
|
nRet, ret_value { login, user_name, mac, station }
|
]]
|
function jx_base.Get_CurLoginUserInfo( strLuaDEID )
|
local nRet, strRetInfo
|
local ret_value = {}
|
|
local strUserLogin, strUserName
|
nRet, strUserLogin, strUserName = mobox.getCurUserInfo( strLuaDEID )
|
if ( nRet ~= 0 ) then return 2, "获取当前操作人员信息失败! "..strUserLogin end
|
|
ret_value.login = strUserLogin
|
ret_value.user_name = strUserName
|
ret_value.mac = ""
|
ret_value.station = ""
|
|
-- 获取当前登录账号的电脑MAC地址(如果在MBC上登录是可以获取的)
|
nRet, strRetInfo = mobox.getCacheValue( strUserLogin, "__user_terminal__" )
|
if ( nRet == 0 ) then
|
local user_terminal = json.decode( strRetInfo )
|
ret_value.mac = lua.Get_StrAttrValue( user_terminal.mac )
|
|
-- 根据 MAC-站台 绑定常量获取 站台
|
if ( ret_value.mac ~= '' ) then
|
ret_value.station = wms_base.Get_sConst( strLuaDEID, ret_value.mac)
|
end
|
end
|
|
return 0, ret_value
|
|
end
|
|
--[[
|
检查一下 orgc_no 下面的 detail 是否已经完成处理完成,如果完成处理 创建一个 入库作业
|
返回值:
|
action
|
]]
|
function jx_base.Organize_CNTR_PostProcess( strLuaDEID, orgc_no, station, cntr_code, bs_no )
|
local nRet, strRetInfo
|
|
-- 检查一下当前料箱的入库任务是否已经全部完成,如果完成就创建一个【货品入库】作业
|
-- N_B_STATE = 1 表示科执行的入库任务
|
local strCondition = "S_CNTR_CODE = '"..cntr_code.."' AND N_B_STATE = 1 AND S_BS_NO = '"..bs_no.."'"
|
nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Organize_CNTR_Detail", strCondition )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), 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
|
-- ***
|
-- 发现过相同有相同组盘的入库作业,这是严重的数据错误,这里加一个判断
|
strCondition = "S_ORGC_NO = '"..orgc_no.."' AND N_TYPE = 1"
|
nRet, strRetInfo = mobox.existThisData( strLuaDEID, "Operation", strCondition )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), strRetInfo ) end
|
-- 如果该车辆编码的动作已经在队列,返回,不做处理
|
if ( strRetInfo == "yes" ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "容器号'"..cntr_code.."'不能重复创建货品入库作业!" )
|
end
|
|
-- 创建【货品入库】作业. 【组盘容器】状态改为3, CG_Detail 加【组盘容器明细】中的内容
|
local ext_info = {}
|
ext_info.orgc_no = orgc_no
|
nRet, operation = jx_base.Create_StorageOperation( strLuaDEID, "巨沃", station, cntr_code, "货品入库", ext_info )
|
if ( nRet ~= 0 ) then
|
mobox.setInfo( strLuaDEID, operation )
|
-- 3 组盘完成,回库出现问题
|
strUpdateSql = "N_B_STATE = 3"
|
strCondition = "S_ORGC_NO = '"..orgc_no.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Organize_Container", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【组盘容器】信息失败!"..strRetInfo ) end
|
return action
|
end
|
|
--【组盘容器】+ 回库作业号, 状态 = 4 (回库)
|
local strUpdateSql = "S_BACK_OP_NO = '"..operation.code.."', N_B_STATE = 4"
|
strCondition = "S_ORGC_NO = '"..orgc_no.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Organize_Container", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【组盘容器】信息失败!"..strRetInfo ) end
|
|
--容器中的【CG_Detail】新增,把【组盘容器明细】中的内容加入
|
nRet, strRetInfo = wms_cntr.Add_CG_Detail_ByOrgcDetail( strLuaDEID, cntr_code, orgc_no )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), 'wms_cntr.Add_CG_Detail_ByOrgcDetail!'..strRetInfo ) end
|
|
--重置料箱信息
|
local container
|
nRet, container = wms_cntr.GetInfo( strLuaDEID, cntr_code )
|
if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "获取【容器】信息失败! " .. container) end
|
nRet, strRetInfo = wms_cntr.Reset( strLuaDEID, container )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), 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 lua.Error( strLuaDEID, debug.getinfo(1), "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 action
|
end
|
|
|
--[[
|
检查一下当前正在分拣的料箱容器 dc_no (配盘容器) 下面的 detail 是否已经完成处理完成,如果完成处理表示该容器分拣完成 创建一个 料箱入库
|
|
返回值:
|
action --
|
]]
|
function jx_base.Distribution_CNTR_PostProcess( strLuaDEID, parameter )
|
local nRet, strRetInfo
|
local strCondition
|
|
-- 检查一下当前料箱的分拣出库任务是否已经全部完成,如果完成就创建一个【料箱h入库】作业
|
-- N_B_STATE = 1 表示科执行的入库任务
|
strCondition = "S_CNTR_CODE = '"..parameter.cntr_code.."' AND N_B_STATE = 1 AND S_BS_NO = '"..parameter.bs_no.."'"
|
nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Distribution_CNTR_Detail", strCondition )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), strRetInfo ) end
|
local nCount = lua.StrToNumber( strRetInfo )
|
|
-- 当前的配盘中已经没有需要执行的出库任务
|
local operation = {}
|
local action = {
|
{
|
action_type = "refresh_master_panel",
|
value = {
|
sub_page = {"当前任务", "未执行任务"}
|
}
|
}
|
}
|
|
if ( nCount == 0 ) then
|
-- 创建【料箱入库】作业. 【配盘容器】状态改为4(拣货完成), CG_Detail 减去【配盘容器明细】中的内容
|
local ext_info = {dc_no = parameter.dc_no}
|
nRet, operation = jx_base.Create_StorageOperation( strLuaDEID, "巨沃", parameter.station, parameter.cntr_code, "料箱入库", ext_info )
|
if ( nRet ~= 0 ) then
|
mobox.setInfo( strLuaDEID, operation )
|
-- 9 分拣完成,回库出现问题
|
strUpdateSql = "N_B_STATE = 9"
|
strCondition = "S_DC_NO = '"..parameter.dc_no.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Distribution_CNTR", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【配盘】信息失败!"..strRetInfo ) end
|
return action
|
end
|
|
-- 【配盘】+ 回库作业号, 状态 = 5 (回库)
|
strUpdateSql = "S_BACK_OP_NO = '"..operation.code.."', N_B_STATE = 5"
|
strCondition = "S_DC_NO = '"..parameter.dc_no.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Distribution_CNTR", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "更新【配盘】信息失败!"..strRetInfo )
|
end
|
local distribution_cntr
|
nRet, distribution_cntr = m3.GetDataObjByCondition( strLuaDEID, "Distribution_CNTR", strCondition )
|
if ( nRet ~= 0 ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "获取【配盘】信息失败!"..strRetInfo )
|
end
|
|
--容器中的【CG_Detail】减【配盘明细】中的内容, 并且生成下架记录, 扣减量表信息
|
nRet, strRetInfo = wms_out.Distribution_CNTR_Detail_PostProcess( strLuaDEID, parameter.wh_code, parameter.area_code, parameter.loc_code, parameter.dc_no )
|
if ( nRet ~= 0 ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), 'wms_out.Distribution_CNTR_Detail_PostProcess!'..strRetInfo )
|
end
|
|
-- 增加一个后台进程对配盘进行处理,触发配盘明细中的 出库单是否可以完成
|
local add_wfp = {
|
wfp_type = 1,
|
cls = "Distribution_CNTR",
|
obj_id = distribution_cntr.id,
|
obj_name = "配盘'"..parameter.dc_no.."'-->出库后处理",
|
trigger_event = "出库后处理"
|
}
|
nRet, strRetInfo = m3.AddSysWFP( strLuaDEID, add_wfp )
|
if ( nRet ~= 0 ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "AddSysWFP失败!"..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 lua.Error( strLuaDEID, debug.getinfo(1), "wms_LockLocation 失败!"..strRetInfo ) end
|
|
action[2] = {
|
action_type = "set_dlg_attr",
|
value = {
|
{ attr = "UPC", value = "", enable = true, prompt = "请扫商品条码..." },
|
{ attr = "Prompt", value = "请扫商品条码..." },
|
{ attr = "S_CNTR_CODE", value = "", enable = false },
|
{ attr = "S_CELL_NO", value = "", enable = false },
|
{ attr = "S_ITEM_CODE", value = "", enable = false },
|
{ attr = "F_QTY", value = "", enable = false },
|
{ attr = "F_ACC_P_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 = ""
|
}
|
},
|
{
|
panel_name = "拣料箱显示",
|
input_parameter = {
|
pick_box_code = "", -- 拣料箱号
|
}
|
}
|
}
|
}
|
|
action[4] = {
|
action_type = "set_master_panel_cursor",
|
value = { form_name = "3055 TOP VIEW", ctrl_id = "S_CNTR_CODE", value = ""}
|
}
|
end
|
|
return action
|
end
|
|
--[[
|
创建一个空料箱出库作业(组盘出)
|
obj_attrs 组盘对象
|
]]
|
function jx_base.CreateEmptyBoxOutOperation ( strLuaDEID, obj_attrs )
|
local nRet, strRetInfo
|
local msg
|
local orgc_no = obj_attrs.S_ORGC_NO
|
local b_state = lua.Get_NumAttrValue( obj_attrs.N_B_STATE )
|
local to_station = obj_attrs.S_STATION_NO
|
local cntr_code = lua.Get_StrAttrValue( obj_attrs.S_CNTR_CODE )
|
local bs_type = lua.Get_StrAttrValue( obj_attrs.S_BS_TYPE )
|
local bs_no = lua.Get_StrAttrValue( obj_attrs.S_BS_NO )
|
|
-- 【组盘容器】数据对象属性判断,不合法的终止程序执行
|
if ( b_state ~= 0 ) then
|
msg = "组盘号'"..orgc_no.."'的状态不是未执行状态,不能启动料箱出库作业!"
|
lua.Warning( strLuaDEID, debug.getinfo(1), msg )
|
return 1, msg
|
end
|
if ( cntr_code == '' ) then
|
msg = "组盘号'"..orgc_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 = "组盘号'"..orgc_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 = jx_base.Get_Station_Loc( strLuaDEID, to_station )
|
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.orgc_no = orgc_no
|
operation.source_sys = "巨沃"
|
|
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_ORGC_NO = '"..orgc_no.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Organize_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"
|
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
|
end
|
|
return 0
|
end
|
|
--[[
|
创建一个配盘出库作业
|
obj_attrs 配盘数据对象 obj_attrs.S_DC_NO,...
|
--]]
|
function jx_base.Create_Distribution_OutOperation ( strLuaDEID, obj_attrs )
|
local nRet, strRetInfo
|
local msg
|
local dc_no = obj_attrs.S_DC_NO
|
local b_state = lua.Get_NumAttrValue( obj_attrs.N_B_STATE )
|
local to_station = lua.Get_StrAttrValue( obj_attrs.S_STATION_NO )
|
local cntr_code = obj_attrs.S_CNTR_CODE
|
local from_loc_code = lua.Get_StrAttrValue( obj_attrs.S_LOC_CODE )
|
local to_loc_code = lua.Get_StrAttrValue( obj_attrs.S_EXIT_LOC_CODE ) -- 出库货位
|
local bs_no = lua.Get_StrAttrValue( obj_attrs.S_BS_NO ) -- 业务来源
|
local bs_type = lua.Get_StrAttrValue( obj_attrs.S_BS_TYPE ) -- 业务来源类型
|
|
-- 【组盘容器】数据对象属性判断,不合法的终止程序执行
|
-- b_state = 1 表示配盘完成
|
if ( b_state ~= 1 ) then
|
msg = "配盘号'"..dc_no.."'的状态不是未执行状态,不能启动配盘出库作业!"
|
lua.Warning( strLuaDEID, debug.getinfo(1), msg )
|
return 1, msg
|
end
|
|
if ( from_loc_code == '') then
|
from_loc_code = wms_wh.GetLocCodeByCNTR( strLuaDEID, cntr_code )
|
if ( from_loc_code == nil or from_loc_code == '' ) then
|
return 1, "配盘号'"..orgc_no.."'中的容器'"..cntr_code.."'没有绑定货位!"
|
end
|
end
|
|
local from_loc
|
nRet, from_loc = wms_wh.GetLocInfo( from_loc_code )
|
if ( nRet ~= 0 ) then
|
return 1, '获取货位信息失败! '..loc_code
|
end
|
|
-- 创建【货品出库】作业. 【配盘】状态改为2(出库中), CG_Detail 加【组盘容器明细】中的内容
|
-- 获取站点货位,站点货位定义在常量中
|
if ( to_loc_code == '' ) then
|
if ( to_station == '') then
|
return 1, "配盘号'"..dc_no.."'的配盘没定义出库站台或货位!"
|
end
|
to_loc_code = jx_base.Get_Station_Loc( strLuaDEID, to_station )
|
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.dc_no = dc_no
|
operation.source_sys = "巨沃"
|
|
operation.bs_type = bs_type
|
operation.bs_no = bs_no
|
|
nRet, operation = m3.CreateDataObj( strLuaDEID, operation )
|
if ( nRet ~= 0 ) then return 1, '创建【作业】失败!'..operation end
|
|
-- 更新【配盘】对象属性
|
-- N_B_STATE = 2 表示配盘容器已经安排作业进行搬运
|
local strUpdateSql = "S_LOC_CODE = '"..from_loc_code.."', N_B_STATE = 2, S_OUT_OP_NO = '"..operation.code.."'"
|
strCondition = "S_DC_NO = '"..dc_no.."'"
|
nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Distribution_CNTR", strCondition, strUpdateSql )
|
if ( nRet ~= 0 ) then return 1, "更新【配盘】信息失败!"..strRetInfo end
|
|
return 0
|
end
|
|
--[[
|
从 wms_count.Get_CountPlan_QueryPanel_Condition 复制到巨星项目,大部分程序一样,只是在容器盘点时只盘点巨沃WMS的料箱
|
即 容器的类型 N_TYPE = 3 是带料格的料箱,其他和标准函数一样
|
获取新增 盘点计划 的查询面板中的查询条件, 注意这和定义的查询页面中的控件有关系,这个是标准功能里的面板获取查询条件的代码
|
|
isSetQueryCondition = true 的情况下 容器查询 需要返回 base64
|
|
返回 nRet, ret_condition_type, strCondition
|
nRet = 0 成功, nRet = 1 条件不满足 nRet = 2 错误
|
ret_condition_type = 0 返回的字符串是 纯SQL
|
]]
|
function jx_base.Get_CountPlan_QueryPanel_Condition( strLuaDEID, isSetQueryCondition )
|
local nRet, strRetInfo
|
local wh_code
|
local attrs = {}
|
local ret_condition_type = 0 -- 非base64
|
|
-- step1 获取当前查询输入面板中的 仓库编码/库区/物料编码/物料名称
|
nRet, attrs = m3.GetSysInputParameter( strLuaDEID )
|
if ( nRet ~= 0 ) then return 2, 0, "获取当前查询面板里的输入属性时失败! "..attrs end
|
|
local obj_attrs = m3.KeyValueAttrsToObjAttr(attrs)
|
if (obj_attrs == nil) then return 2, 0, "询面板里的输入属性为空" end
|
-- "N_TYPE","S_WH_CODE","Area","ItemCode", "ItemName"
|
local check_type = tonumber(obj_attrs.N_TYPE) -- 盘点类型
|
local wh_code = obj_attrs.S_WH_CODE -- 仓库编码
|
local area_code = obj_attrs.S_AREA_CODE -- 库区编码
|
if ( area_code == nil ) then area_code = '' end
|
|
local strCondition = ''
|
local strOrder = ''
|
|
if ( check_type == 0 ) then return 1, 0, "必须选择一种盘点类型" end
|
if ( wh_code == '' ) then return 1, 0, "必须选择一个仓库" end
|
|
if ( check_type == wms_base.Get_nConst(strLuaDEID, "盘点类型-货品盘点")) then
|
local item_code = obj_attrs.ItemCode -- 物料编码
|
local item_name = obj_attrs.ItemName -- 物料名称
|
local item_condition = ''
|
|
if ( item_code ~= '' and item_code ~= nil ) then
|
item_condition = " AND S_ITEM_CODE like '%%"..item_code.."%%'"
|
end
|
if ( item_name ~= '' and item_name ~= nil ) then
|
item_condition = item_condition.." AND S_ITEM_NAME like '%%"..item_name.."%%' "
|
end
|
strOrder = 'S_ITEM_CODE'
|
-- 如果是货物盘点
|
if ( area_code == '') then
|
-- 没有输入库区就直接查仓库量表
|
strCondition = "F_QTY > 0 AND S_WH_CODE = '"..wh_code.."' "..item_condition
|
else
|
-- 有库区查库区量表
|
strCondition = "F_QTY > 0 AND S_WH_CODE = '"..wh_code.."' AND S_AREA_CODE = '"..area_code.."' "..item_condition
|
end
|
else
|
-- 如果是货位盘点
|
local roadway = lua.StrToNumber(obj_attrs.Roadway) -- 巷道
|
local row = lua.StrToNumber(obj_attrs.Row) -- 排
|
local col = lua.StrToNumber(obj_attrs.Col) -- 列
|
local layer = lua.StrToNumber(obj_attrs.layer) -- 层
|
|
strCondition = "S_WH_CODE = '"..wh_code.."'"
|
if ( area_code ~= '') then
|
strCondition = strCondition .. " AND S_AREA_CODE = '"..area_code.."' "
|
end
|
if ( roadway ~= 0 ) then
|
strCondition = strCondition .. " AND N_ROADWAY = "..roadway
|
end
|
if ( row ~= 0 ) then
|
strCondition = strCondition .. " AND N_ROW = "..row
|
end
|
if ( col ~= 0 ) then
|
strCondition = strCondition .. " AND N_COL = "..col
|
end
|
if ( layer ~= 0 ) then
|
strCondition = strCondition .. " AND N_LAYER = "..layer
|
end
|
|
-- V2.0
|
if ( check_type == wms_base.Get_nConst(strLuaDEID, "盘点类型-货位盘点")) then
|
strCondition = strCondition.." AND N_CURRENT_NUM > 0"
|
else
|
-- 容器盘点
|
-- 这里的查询条件带 In 不能用简单模式
|
if ( isSetQueryCondition ) then
|
local sql_condition = {
|
{
|
{
|
field = "C_ENABLE",
|
value = "Y",
|
op = "="
|
}
|
},
|
{
|
{
|
field = "N_LOCK_STATE",
|
value = "0",
|
op = "="
|
}
|
},
|
{
|
{
|
field = "N_TYPE",
|
value = "3",
|
op = "="
|
}
|
},
|
{
|
{
|
field = "S_CODE",
|
value = "(select S_CNTR_CODE from TN_Loc_Container with (NOLOCK) where S_LOC_CODE in (select S_CODE from TN_Location with (NOLOCK) where "..strCondition.."))",
|
op = "in"
|
}
|
}
|
}
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "sql_condition", sql_condition )
|
|
nRet, strCondition = mobox.strToBase64( lua.table2str(sql_condition) )
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "base64", strCondition )
|
|
if ( nRet ~= 0 ) then return 2, 0, "strToBase64 失败: "..strCondition end
|
ret_condition_type = 1
|
else
|
strCondition = "C_ENABLE = 'Y' AND N_LOCK_STATE = 0 AND N_TYPE = 3 AND "..
|
"S_CODE in (select S_CNTR_CODE from TN_Loc_Container with (NOLOCK) where S_LOC_CODE in (select S_CODE from TN_Location with (NOLOCK) where "..strCondition.."))"
|
end
|
end
|
end
|
return 0, ret_condition_type, strCondition
|
end
|
|
return jx_base
|