Jianw
2025-05-13 3b39fe3810c3ee2ec9ec97236c1769c5c85e062c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
--[[
    编码: JX-67-10
    名称: 站台货品明细-呼出空料箱
    作者:HAN  
    日期:2025-3-10
 
    级别:项目
    
    函数: RunEmptyBoxOutProcess
 
    功能:
        -- 后台脚本计算入库需要呼出多少空料箱
 
    更改记录:
        V3.0 HAN 20241231 改成后台线程来处理空料箱呼出计算,因为这个过程是一个比较长的事务,有并发锁表的风险
                          本次改进的目的就是将这些长事务统一交给后台一个线程排队处理
--]]
 
require ("jx_emptyboxoutplan")
 
--[[ 
 
datajson 格式: 
    paramter = {
        station = station,
        login = strUserLogin,
        user_name = strUserName,
        bs_type = "".
        bs_no = ""
    } 
]]
 
function RunEmptyBoxOutProcess ( strLuaDEID ) 
    local nRet, strRetInfo, n
    local paramter, data_json
    local result = { cntr_count = 0 }
    
    nRet, paramter = m3.GetSysDataJson( strLuaDEID )
    if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), data_json ) end
       
    -- 从入库单这里获取 仓库、库区编码,如果不一样报错
    local station = lua.Get_StrAttrValue( paramter.station )
    local bs_type = lua.Get_StrAttrValue( paramter.bs_type )
    local bs_no = lua.Get_StrAttrValue( paramter.bs_no )
 
    if ( bs_type ~= "Inbound_Wave" ) then
        mobox.stopProgram( strLuaDEID,  "站台货品明细的来源目前只支持入库波次!")
        return 1
    end        
    if ( bs_no == "" ) then
        mobox.stopProgram( strLuaDEID,  "入库波次号不能为空!")
        return 1
    end 
 
    local in_wave
    nRet, in_wave = m3.GetDataObjectByKey(strLuaDEID, "Inbound_Wave", "S_WAVE_NO", bs_no )
    if ( nRet ~= 0 or in_wave == "") then 
        mobox.stopProgram( strLuaDEID,  "无效的入库波次编码'"..bs_no.."'" )
        return 1
    end 
 
    local wh_code = lua.Get_StrAttrValue( in_wave.wh_code )
    local area_code = lua.Get_StrAttrValue( in_wave.area_code )
    if ( wh_code == '' ) then
        mobox.stopProgram( strLuaDEID, "入库波次对象中仓库属性不能为空!" )
        return  1
    end 
    if ( area_code == '' ) then
        mobox.stopProgram( strLuaDEID, "入库波次对象中库区属性不能为空!" )
        return  1
    end    
 
    -- 获取需要入库的货品明细,合并相同货品编码
    local strCondition
    local data_objs
 
    -- 要联表查询的表
    local strTable = "TN_Station_Goods_Detail a LEFT JOIN TN_Material b ON a.S_ITEM_CODE = b.S_ITEM_CODE" 
    -- 要查询的属性
    local strAttrs = "a.S_ITEM_CODE, a.S_ITEM_NAME, a.F_QTY, b.F_WEIGHT, b.F_VOLUME, b.S_CELL_TYPE" 
 
    strCondition = "a.S_STATION_NO = '"..station.."' AND a.N_B_STATE = 0 AND a.S_BS_TYPE = '"..bs_type.."' AND a.S_BS_NO = '"..bs_no.."'"
    nRet, strRetInfo = mobox.queryMultiTable(strLuaDEID, strAttrs, strTable, 1000, strCondition )
    if ( nRet ~= 0 ) then return 2, "queryMultiTable 失败!"..strRetInfo end
    if ( strRetInfo == '' ) then 
        mobox.stopProgram( strLuaDEID, "没找到需要入库的站台货品!" )
        return  1
    end
    
    local n, item_code, qty, weight, volume, cell_type
    local detail_attrs
    local bFind
    local sg_detail_list = {}       -- 站台货品明细
    local ret_data = json.decode(strRetInfo)
 
    for n = 1, #ret_data do
        item_code = lua.Get_StrAttrValue( ret_data[n][1] )
        item_name = lua.Get_StrAttrValue( ret_data[n][2] )        
        qty = lua.Get_NumAttrValue( ret_data[n][3] )    
        weight = lua.Get_NumAttrValue( ret_data[n][4] ) 
        volume = lua.Get_NumAttrValue( ret_data[n][5] )         
        cell_type = lua.Get_StrAttrValue( ret_data[n][6] )  
 
        if ( item_code ~= '' and qty > 0 ) then
            bFind = false
            for m = 1, #sg_detail_list do
                if (sg_detail_list[m].item_code == item_code) then
                    bFind = true
                    sg_detail_list[m].qty = sg_detail_list[m].qty + qty
                    break
                end
            end
            if ( bFind == false ) then
                local sg_detail = {
                    item_code = item_code,
                    item_name = item_name,
                    qty = qty,
                    weight = weight,
                    volume = volume,
                    cell_type = cell_type
                }
                table.insert( sg_detail_list, sg_detail )
            end
        end
    end    
    
    -- 计算货品件数,种类
    local total_qty = 0
    local good_type_num = #sg_detail_list
 
    if ( good_type_num == 0 ) then
        result = { cntr_count = 0 }
        mobox.returnValue( strLuaDEID, 1, lua.table2str(result) )
        return 0
    end
 
    for n = 1, good_type_num do
        total_qty = total_qty + sg_detail_list[n].qty
    end
 
    local item_list = {}    -- 需要入库的货品
    local obj_attrs
 
    -- 生成要入库的货品链表 item_list
    for n = 1, good_type_num do
        local item = {
            item_code = sg_detail_list[n].item_code,
            item_name = sg_detail_list[n].item_name,
            row = n,
            volume = sg_detail_list[n].volume,
            weight = sg_detail_list[n].weight,
            cell_type = sg_detail_list[n].cell_type,
            qty = sg_detail_list[n].qty,
            alloc_qty = 0,
            cntr_cell_list = {},
            empty_cell_type = "",
            upgrad_cell_index = 0,          -- 标记货品开始升格的料格 A = 1, B = 2 ,如果到A还没有合适料格,要从这个料格开始降格
            Q = 0,
            ok = false                      -- true 表示这个货品已经分配好入库料箱
        }
        table.insert( item_list, item )
    end
  
    lua.Debug( strLuaDEID, debug.getinfo(1), "超重货品 item_list-->", item_list )
 
    -- 呼出空料箱算法
    local ps_cntr_list = {}
    local ps_detail_list = {}    
    local lane = ""             -- 可用巷道
 
    nRet, lane = jx_base.Get_Available_Lane( strLuaDEID, area_code )
    if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), 'jx_base.Get_Available_Lane!'..lane ) end
    if ( lane == '' ) then
        mobox.stopProgram( strLuaDEID,  "库区里的所有堆垛机状态都是不可用,无法继续呼出料箱!")
        return 1
    end       
 
    nRet, strRetInfo = JX_EmptyBoxCellOutPlan( strLuaDEID, item_list, wh_code, area_code, lane, station, bs_type, bs_no, ps_cntr_list, ps_detail_list )  
    if ( nRet ~= 0 ) then
        if (nRet == 1) then
            mobox.stopProgram( strLuaDEID,  strRetInfo)
            return 1
        else
            lua.Error( strLuaDEID, debug.getinfo(1), "JX_EmptyBoxCellOutPlan错误: "..strRetInfo)
        end
    end    
 
    -- 站台货品明细 的状态改成 处理中
    strCondition = "S_STATION_NO = '"..station.."' AND S_BS_TYPE = '"..bs_type.."' AND S_BS_NO = '"..bs_no.."'"
    local strSetAttr = "N_B_STATE = 1"        -- 1  处理中
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Station_Goods_Detail", strCondition, strSetAttr )
    if ( nRet ~= 0 ) then  lua.Error( strLuaDEID, debug.getinfo(1), "更新【站台货品明细】信息失败!"..strRetInfo ) end 
 
 
    result = { 
        cntr_count = #ps_cntr_list,
        cntr_cell_list = ps_detail_list,
        wave_obj_id = in_wave.id
    }
    mobox.returnValue( strLuaDEID, 1, lua.table2str(result) )
 
    return 0
end