1
Jianw
2025-07-09 88e26a2a960dbbc148332772448b79b9877102d8
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
--[[
   编码: AMS-21-32
   名称: 
   作者:
   日期:2025-05-17
 
   函数: ClickOK
   功能:
 
   更改记录:
 
--]]
json  = require ("json")
mobox = require ("OILua_JavelinExt")
m3 = require ("oi_base_mobox")
wms_base = require( "wms_base" )
wms_cntr= require( "wms_container" )
wms_wh = require( "wms_wh" )
 
function ClickOK(strLuaDEID)
    
    local curTime = os.date("%Y-%m-%d %H:%M:%S")
    local default_storer = ''                    -- 默认货主
    nRet, default_storer = wms_base.Get_sConst2( "WMS_Default_Storer" )
    if ( nRet ~= 0 ) then
        default_storer = ''
    end
    
    -- 获取当前输入面板里的属性
    local nRet, attrs = m3.GetSysInputParameter(strLuaDEID)
    if nRet ~= 0 then
        mobox.setInfo(strLuaDEID, "获取当前输入面板里的属性失败! "..attrs)
        return
    end
 
    local input_attr = m3.KeyValueAttrsToObjAttr(attrs)
    local io_no = input_attr.S_IO_NO                                    -- 入库单号
    local loc_code = input_attr.S_EXT_ATTR1                             -- 货位号   
    
    
    local loc
    nRet, loc = wms_wh.GetLocInfo( loc_code )
    if ( nRet ~= 0 ) then 
        mobox.setInfo(strLuaDEID, "获取货位'"..loc_code.."'信息失败! "..loc)
        return
    end
    -- 获取已码盘数据包
    local obj
    nRet, obj = m3.GetSysDataJson(strLuaDEID)
    if nRet ~= 0 then
        mobox.setInfo(strLuaDEID, "无法获取数据包!"..obj)
        return
    end
 
    -- 获取或创建容器
    local code
    local strCondition = "S_LOC_CODE = '"..loc_code.."'"
    local loc_Container
    nRet, loc_Container = m3.GetDataObjByCondition(strLuaDEID, "Loc_Container", strCondition)
    if nRet == 0 then
        code = loc_Container.cntr_code
    elseif nRet == 1 then
        local Condition = "S_NAME = '虚拟容器'"
        nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "Container_Type_Def", Condition)
        if nRet ~= 0 then
            mobox.setInfo(strLuaDEID,  "查询 Material 表失败: " .. strRetInfo)
            return
        end
        
        local ctd_code = strRetInfo.ctd_code 
    
        local container = m3.AllocObject(strLuaDEID, "Container")
        container.virtual = 'Y'
        container.ctd_code = ctd_code
        local nRetl, strRetInfo = wms_cntr.CreateVirtual(strLuaDEID, container)
        if nRetl ~= 0 then
            lua.Stop(strLuaDEID, "申请虚拟容器失败!!")
            return
        end
        code = strRetInfo.code
        nRet, strRetInfo = wms_wh.Loc_Container_Binding(strLuaDEID, loc_code, code, "绑定解绑方法-系统", "系统绑定")
        if nRet ~= 0 then 
            lua.Error(strLuaDEID, debug.getinfo(1), '货位容器绑定失败!'..strRetInfo) 
        end
    elseif nRet > 1 then
        lua.Error(strLuaDEID, debug.getinfo(1), loc_Container)
    end
 
    -- 更新入库单状态为处理中
    local strUpdateSql = "N_B_STATE = 2"
    nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Order", "S_NO = '"..io_no.."'", strUpdateSql)
    if nRet ~= 0 then  
        lua.Stop(strLuaDEID, "更新入库单信息失败!"..strRetInfo)
        return 
    end
    
    nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "ERP_Inbound_Order", "S_NO = '"..io_no.."'", strUpdateSql)
    if nRet ~= 0 then  
        lua.Stop(strLuaDEID, "更新入库单信息失败!"..strRetInfo)
        return 
    end
    
    -- 更新入库单明细的状态
    local SQLstrCondition = "S_IO_NO = '" .. io_no .. "' "
    local strUpdateSql = "N_B_STATE = 2"
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Detail", SQLstrCondition, strUpdateSql )
    if ( nRet ~= 0 ) then  
        lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
        return 
    end
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Detail", SQLstrCondition, strUpdateSql )
    if ( nRet ~= 0 ) then  
        lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
        return 
    end
    
    -- 获取入库单基本信息
    local bs_no
    local nRet, strRetInfop = m3.GetDataObjByCondition(strLuaDEID, "Inbound_Order", "S_NO = '"..io_no.."'")
    if nRet == 0 then
        bs_no = strRetInfop.bs_no
    else
        mobox.setInfo(strLuaDEID, "查询 Inbound_Order 表失败: "..strRetInfo)
        return
    end
 
    -- 初始化物料信息更新列表
    local rows_to_update = {}
    local item_list = obj[1].item_list
    for i = 1, #item_list do
        local obj_list = m3.KeyValueAttrsToObjAttr(item_list[i].attrs)
        local item_code = obj_list.S_ITEM_CODE
        local item_name = obj_list.S_ITEM_NAME
        local f_qty = tonumber(obj_list.F_QTY) or 0
        local acc_i_qty = tonumber(lua.Get_NumAttrValue(obj_list.F_ACC_I_QTY)) or 0
        local qty = tonumber(obj_list.Qty) or 0
        local act_qty = acc_i_qty + qty
        local f_c_qty = f_qty - act_qty
 
        if act_qty > f_qty then
            lua.Stop(strLuaDEID, "物料["..item_code.."]当前入库数量大于可入库数量!")
            return
        end
 
        -- 判断是否存在相同容器号、货位号、物料编码的记录
        local strCondition = "S_CNTR_CODE = '" .. code .. "' and S_LOC_CODE = '" .. loc_code .. "' and S_ITEM_CODE = '" .. item_code .. "'"
        local nRet, exist_detail = m3.GetDataObjByCondition(strLuaDEID, "INV_Detail", strCondition)
        if nRet == 0 and exist_detail ~= nil then
            -- 已存在,更新数量
            local old_qty = tonumber(exist_detail.qty or 0)
            local new_qty = old_qty + tonumber(qty)
        
            local strUpdateSql = "F_QTY = " .. new_qty
            local strUpdateCondition = "S_CNTR_CODE = '" .. code .. "' and S_LOC_CODE = '" .. loc_code .. "' and S_ITEM_CODE = '" .. item_code .. "'"
            local retUpdate, strInfo = mobox.updateDataAttrByCondition(strLuaDEID, "INV_Detail", strUpdateCondition, strUpdateSql)
            if retUpdate ~= 0 then
                lua.Stop(strLuaDEID, "更新 INV_Detail 失败:" .. strInfo)
                return
            end
            
            -- 创建库存交易日志
            inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" )
            inv_txn_log_data.S_WH_CODE = loc.wh_code
            inv_txn_log_data.S_AREA_CODE = loc.area_code
            inv_txn_log_data.S_LOC_CODE = loc_code
            inv_txn_log_data.S_CNTR_CODE = code
            inv_txn_log_data.S_LOG_TYPE = "IN"
            inv_txn_log_data.C_SYMBOL = "+"
            inv_txn_log_data.F_QTY = qty
            
            inv_txn_log_data.S_ITEM_CODE = item_code
            inv_txn_log_data.S_ITEM_NAME = item_name
            inv_txn_log_data.S_ITEM_STATE = 'O'                     -- 注意,这个地方需要修改!
            inv_txn_log_data.S_STORER = default_storer
            nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data )
            if (nRet ~= 0 ) then 
                lua.Stop(strLuaDEID, "创建【库存交易日志】失败!:" .. inv_txn_log_data)
                return
            end 
        else
            -- 不存在,创建新记录
            local nRet,inv_detail_data
            inv_detail_data = m3.AllocObject2( strLuaDEID, "INV_Detail" )
            inv_detail_data.S_WH_CODE = loc.wh_code
            inv_detail_data.S_AREA_CODE = loc.area_code
            inv_detail_data.S_LOC_CODE = loc_code
            inv_detail_data.S_CNTR_CODE = code
            inv_detail_data.T_INBOUND_TIME = curTime
            inv_detail_data.F_QTY = qty
            inv_detail_data.S_ITEM_CODE = item_code
            inv_detail_data.S_ITEM_NAME = item_name
            
            nRet, inv_detail_data = m3.CreateDataObj2(strLuaDEID, inv_detail_data )
            if nRet ~= 0 then
                lua.Stop(strLuaDEID, "创建 INV_Detail 失败:" .. inv_detail_data)
                return
            end
            
            -- 创建库存交易日志
            inv_txn_log_data = m3.AllocObject2( strLuaDEID, "INV_TXN_Log" )
            inv_txn_log_data.S_WH_CODE = loc.wh_code
            inv_txn_log_data.S_AREA_CODE = loc.area_code
            inv_txn_log_data.S_LOC_CODE = loc_code
            inv_txn_log_data.S_CNTR_CODE = code
            inv_txn_log_data.S_LOG_TYPE = "IN"
            inv_txn_log_data.C_SYMBOL = "+"
            inv_txn_log_data.F_QTY = qty
            
            inv_txn_log_data.S_ITEM_CODE = item_code
            inv_txn_log_data.S_ITEM_NAME = item_name
            inv_txn_log_data.S_ITEM_STATE = 'O'
            inv_txn_log_data.S_STORER = default_storer
            nRet, inv_txn_log_data = m3.CreateDataObj2(strLuaDEID, inv_txn_log_data )
            if (nRet ~= 0 ) then 
                lua.Stop(strLuaDEID, "创建【库存交易日志】失败!:" .. inv_txn_log_data)
                return
            end 
        end
 
        -- 分配入库数量
        local container_data
        local Condition = "S_IO_NO = '"..io_no.."' AND S_ITEM_CODE = '"..item_code.."' ORDER BY S_BS_NO"
        nRet, container_data = m3.QueryDataObject(strLuaDEID, "ERP_Inbound_Detail", Condition)
        if nRet ~= 0 then
            lua.Stop(strLuaDEID, '查询入库单明细失败!!!'..container_data)
            return
        end
 
        local remaining_to_allocate = qty
        for n = 1, #container_data do
            local detail = m3.KeyValueAttrsToObjAttr(container_data[n].attrs)
            local detail_qty = tonumber(detail.F_QTY) or 0
            local detail_acc_qty = tonumber(detail.F_ACC_I_QTY) or 0
            local detail_remaining = detail_qty - detail_acc_qty
 
            if detail_remaining > 0 and remaining_to_allocate > 0 then
                local allocate_qty = math.min(remaining_to_allocate, detail_remaining)
                local new_acc_qty = detail_acc_qty + allocate_qty
                remaining_to_allocate = remaining_to_allocate - allocate_qty
                
                lua.Debug( strLuaDEID, debug.getinfo(1), "detail_remaining --> ", detail_remaining )  
                lua.Debug( strLuaDEID, debug.getinfo(1), "allocate_qty --> ", allocate_qty )    
                lua.Debug( strLuaDEID, debug.getinfo(1), "new_acc_qty --> ", new_acc_qty )    
                -- 更新累计入库数量
                local update_data = "F_ACC_I_QTY = "..new_acc_qty
                local update_condition = "S_IO_NO = '"..io_no.."' AND S_BS_NO = '"..detail.S_BS_NO.."' AND S_ITEM_CODE = '"..item_code.."'"
                local nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "ERP_Inbound_Detail", update_condition, update_data)
                if nRet ~= 0 then
                    lua.Stop(strLuaDEID, '更新入库单明细失败!'..strRetInfo)
                    return
                end
                
                local updatedata = "F_ACC_I_QTY = "..new_acc_qty
                local updatecondition = "S_IO_NO = '"..io_no.."' AND S_ITEM_CODE = '"..item_code.."'"
                local nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Detail", updatecondition, updatedata)
                if nRet ~= 0 then
                    lua.Stop(strLuaDEID, '更新入库单明细失败!'..strRetInfo)
                    return
                end
 
                -- 回报ERP
                local erp_body = {
                    no = bs_no,
                    sourceOrderNo = detail.S_BS_NO,
                    sourceLineNo = tonumber(detail.N_BS_ROW_MO),
                    itemCode = item_code,
                    itemName = item_name,
                    accumulatedQty = allocate_qty,
                    ioNo = io_no,
                    locationCode = loc_code
                }
                lua.Debug(strLuaDEID, debug.getinfo(1), "回报ERP数据", erp_body)
            end
        end
 
        -- 添加当前物料更新到 rows_to_update
        table.insert(rows_to_update, {
            condition = {
                { attr = "S_ITEM_CODE", value = item_code },
                { attr = "S_ITEM_NAME", value = item_name }
            },
            attrs = {
                { attr = "F_ACC_I_QTY", operation = "", value = act_qty },
                { attr = "Qty", operation = "", value = f_c_qty }
            }
        })
    end
 
    -- 页面更新动作
    local action_arry = {}
 
    table.insert(action_arry, {
        action_type = "set_subtable_page_row",
        value = {
            page_name = "物料信息",
            row = rows_to_update
        }
    })
 
    table.insert(action_arry, {
                    action_type = "set_dlg_attr",
                    value = {
                            {attr = "S_ITEM_CODE", value = "", enable = true},
                            {attr = "S_EXT_ATTR1", value = ""}
                            }
    })
    -- 检查是否所有入库明细已完成
    local inbound_detail
    nRet, inbound_detail = m3.QueryDataObject(strLuaDEID, "Inbound_Detail", "S_IO_NO = '" ..io_no.."'")
    if nRet ~= 0 then
        lua.Stop(strLuaDEID, '查询入库单明细失败!!!' .. inbound_detail)
        return
    end
 
    local allEqual = true
    for n = 1, #inbound_detail do
        local cntr_detail = m3.KeyValueAttrsToObjAttr(inbound_detail[n].attrs)
        if lua.Get_NumAttrValue(cntr_detail.F_QTY) ~= lua.Get_NumAttrValue(cntr_detail.F_ACC_I_QTY) then
            allEqual = false
            break
        end
    end
 
    if allEqual then
        local nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Order", "S_NO = '" .. io_no .. "'", "N_B_STATE = 3")
        if nRet ~= 0 then  
            lua.Stop(strLuaDEID, "更新入库单信息失败!"..strRetInfo)
            return 
        end
        
        local nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "ERP_Inbound_Order", "S_NO = '" .. io_no .. "'", "N_B_STATE = 3")
        if nRet ~= 0 then  
            lua.Stop(strLuaDEID, "更新入库单信息失败!"..strRetInfo)
            return 
        end
        
        -- 更新入库单明细的状态
        local strCondition = "S_IO_NO = '" .. io_no .. "' "
        local strUpdateSql = "N_B_STATE = 3"
        nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Detail", strCondition, strUpdateSql )
        if ( nRet ~= 0 ) then  
            lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
            return 
        end
        nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Detail", strCondition, strUpdateSql )
        if ( nRet ~= 0 ) then  
            lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
            return 
        end
        -- 清空主界面
        table.insert(action_arry, {
            action_type = "clear_subpage_rows",
            value = { page_name = "物料信息" }
        })
 
        table.insert(action_arry, {
            action_type = "set_dlg_attr",
            value = {
                { attr = "S_IO_NO", value = "" },
                { attr = "S_ITEM_CODE", value = "" },
                { attr = "S_EXT_ATTR1", value = "" }
            }
        })
    end
 
    local nRet, strRetInfo = mobox.setAction(strLuaDEID, lua.table2str(action_arry))
    if nRet ~= 0 then
        mobox.setInfo(strLuaDEID, "设置界面数据失败! " .. strRetInfo)
        return
    end
end