1
Jianw
9 天以前 70f29da38121b9a467841253e3268feb5df02902
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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
--[[
   编码: AMS-21-28
   名称: 
   作者:
   日期:2025-05-16
 
   函数: 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 nRet,attrs
    local strRetInfo
    local strCondition
    local strRetInfop
    local action = {}
    local action_arry = {}
    
    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
    
    -- 获取输入参数
    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 item_code = input_attr.S_ITEM_CODE                -- 物料编码
    local code = input_attr.S_EXT_ATTR1                     -- 货位容器号
    local loc_code = input_attr.S_EXT_ATTR2                 -- 目标货位
 
    -- local locations = {}
    -- if (code ~= '' ) then
    --     for i = 1, #code do
    --         locations[i] = code[i]
    --     end
        
    -- end
    
    local loc
    nRet, loc = wms_wh.GetLocInfo( loc_code )
    if ( nRet ~= 0 ) then 
        return 1, "获取货位'"..loc_code.."'信息失败! "..loc
    end
    -- 获取"正在码盘"数据
    local obj
    nRet, obj = m3.GetSysDataJson(strLuaDEID)
    if (nRet ~= 0) then
        mobox.setInfo(strLuaDEID, "无法获取数据包!" .. obj)
        return
    end
    
    local obj_code = obj[1].item_list
    local obj_list = m3.KeyValueAttrsToObjAttr(obj_code[1].attrs)
 
    local current_item_code = obj_list.S_ITEM_CODE
    local current_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, "当前入库数量大于可入库数量!")
        return
    end
 
    -- 查询物料信息
    local Condition = "S_ITEM_CODE = '" .. item_code .. "'"
    nRet, strRetInfo = m3.GetDataObjByCondition(strLuaDEID, "SKU", Condition)
    if nRet ~= 0 then
        mobox.setInfo(strLuaDEID,  "查询 Material 表失败: " .. strRetInfo)
        return
    end
    
    -- 处理货位容器
    local code
    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 strCondition = "S_CNTR_CODE = '" .. code .. "' and S_LOC_CODE = '" .. loc_code .. "' and S_ITEM_CODE = '" .. current_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 = '" .. current_item_code .. "'"
        local retUpdate, strInfo = mobox.updateDataAttrByCondition(strLuaDEID, "INV_Detail", strUpdateCondition, strUpdateSql)
        if retUpdate ~= 0 then
            lua.Stop(strLuaDEID, "更新 CG_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 = current_item_code
        inv_txn_log_data.S_ITEM_NAME = current_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 = current_item_code
        inv_detail_data.S_ITEM_NAME = current_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 = current_item_code
        inv_txn_log_data.S_ITEM_NAME = current_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 strCondition = "S_NO = '" .. io_no .. "' "
    local strUpdateSql = "N_B_STATE = 2"
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Order", strCondition, strUpdateSql )
    if ( nRet ~= 0 ) then  
        lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
        return 
    end
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Order", strCondition, 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
    
    -- 获取入库单的来源单号
    
    nRet, strRetInfop = m3.GetDataObjByCondition(strLuaDEID, "Inbound_Order", strCondition)
    if (nRet ~= 0) then 
        mobox.setInfo(strLuaDEID, "查询 Inbound_Order 表失败: " .. strRetInfo) 
        return
    end
    local bs_no = strRetInfop.bs_no
   
    -- 查询入库单明细(按来源单号排序)
    local container_data, nRet
    local Condition = "S_IO_NO = '" ..io_no.."' 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 details = {}
    for n = 1, #container_data do
        details[n] = m3.KeyValueAttrsToObjAttr(container_data[n].attrs)
        details[n].F_QTY = tonumber(details[n].F_QTY) or 0
        details[n].F_ACC_I_QTY = tonumber(details[n].F_ACC_I_QTY) or 0
    end
 
    -- 当前需要分配的入库数量
    local remaining_to_allocate = qty
 
    -- 遍历所有明细,按顺序分配入库数量
    for n = 1, #details do
        local detail = details[n]
        local detail_qty = detail.F_QTY
        local detail_acc_qty = detail.F_ACC_I_QTY
        -- 只处理当前操作的物料
        if detail.S_ITEM_CODE == item_code then
            -- 计算这个明细还需要入库的数量
            local detail_remaining = detail_qty - detail_acc_qty
            
            if detail_remaining > 0 and remaining_to_allocate > 0 then
                -- 本次分配的数量
                local allocate_qty = 0
                
                if remaining_to_allocate >= detail_remaining then
                    allocate_qty = detail_remaining
                else
                    allocate_qty = remaining_to_allocate
                end
                
                -- 更新累计入库数量
                local new_acc_qty = detail_acc_qty + allocate_qty
                remaining_to_allocate = remaining_to_allocate - allocate_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 = '"..detail.S_ITEM_CODE.."'"
                
                nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "ERP_Inbound_Detail", update_condition, update_data)
                if nRet ~= 0 then
                    lua.Stop(strLuaDEID, '更新入库单明细失败!' .. strRetInfo)
                    return
                end
                
                local update_obj = "F_ACC_I_QTY = " .. new_acc_qty   
                local updatecondition = "S_IO_NO = '"..io_no.."' AND S_ITEM_CODE = '"..detail.S_ITEM_CODE.."'"
                nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Detail", updatecondition, update_obj)
                if nRet ~= 0 then
                    lua.Stop(strLuaDEID, '更新入库单明细失败!' .. strRetInfo)
                    return
                end
                
                -- 回报上游ERP系统
                if allocate_qty > 0 then
                    local erp_body = {
                        no = bs_no,
                        sourceOrderNo = detail.S_BS_NO,
                        sourceLineNo = tonumber(detail.N_BS_ROW_MO),
                        itemCode = detail.S_ITEM_CODE,
                        itemName = detail.S_ITEM_NAME,
                        accumulatedQty = allocate_qty,
                        ioNo = io_no,
                        locationCode = loc_code
                    }
                    
                    lua.Debug(strLuaDEID, debug.getinfo(1), "回报ERP数据", erp_body)
                    
                end
            end
        end
    end
    
    -- 界面action各事件
    action_arry[1] = {
        action_type = "set_dlg_attr",
        value = {
                --{attr = "S_EXT_ATTR1", value = loc_code },
                {attr = "S_EXT_ATTR2", value = "" }
                }
        }
    action_arry [2]= {
                        action_type = "set_subtable_page_row",
                        value = {
                            page_name = "物料信息", 
                            row = {
                                {
                                    condition = { 
                                        {
                                            attr = "S_ITEM_CODE",  
                                            value = current_item_code    
                                        },
                                        {
                                            attr = "S_ITEM_NAME", 
                                            value = current_item_name 
                                        }
                                    },
                                    attrs = {
                                        {
                                            attr = "F_ACC_I_QTY", 
                                            operation = "", 
                                            value = act_qty
                                        },
                                        {
                                            attr = "Qty", 
                                            operation = "", 
                                            value = f_c_qty
                                        },
                                    }
                                }
                            }
                        }
                    }
 
    -- 如果当前物料已全部入库,清空物料信息页面
    if (act_qty == f_qty) then
        action_arry[3] = {
                    action_type = "clear_subpage_rows",
                    value = {
                            page_name = "物料信息"
                            }
                    }
        action_arry[4] = {
                    action_type = "set_dlg_attr",
                    value = {
                            {attr = "S_ITEM_CODE", value = "", enable = true},
                            {attr = "S_EXT_ATTR1", value = ""}
                            }
                    }
 
    end
    -- 检查是否所有明细都已入库完成
    local inbound_detail, nRet
    local Condition = "S_IO_NO = '" ..io_no.."' "
    nRet, inbound_detail = m3.QueryDataObject(strLuaDEID, "ERP_Inbound_Detail", Condition)
    if (nRet ~= 0) then
        lua.Stop(strLuaDEID, '查询入库单明细失败!!!' .. container_data)
        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 strCondition = "S_NO = '" .. io_no .. "' "
        local strUpdateSql = "N_B_STATE = 3"
        nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Inbound_Order", strCondition, strUpdateSql )
        if ( nRet ~= 0 ) then  
            lua.Stop(strLuaDEID,"更新入库单信息失败!"..strRetInfo )
            return 
        end
        nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "ERP_Inbound_Order", strCondition, strUpdateSql )
        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
    
        -- 清空"已码盘"页面
        action_arry[5] = {
                    action_type = "set_dlg_attr",
                    value = {
                            {attr = "S_IO_NO", value = "", enable = true}
                            }
                    }
    end
    
    nRet, strRetInfo = mobox.setAction(strLuaDEID, lua.table2str(action_arry))
    if (nRet ~= 0) then
        mobox.setInfo(strLuaDEID, "清空已码盘页面失败! " .. strRetInfo)
        return
    end
end