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
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
--[[
        和项目关联比较紧密的一些函数
        项目开发和实施人员 可以把 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_out  = require ("wms_outbound")
prj_api = require ( "prj_api" )
wms_alg  = require ("wms_base_algorithm")
wms_inv  = require ("wms_inventory")
wms_op = require( "wms_operation" )
 
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-"..area_code.."-StackerCrane"
    nRet, strRetInfo = wms_base.Get_sConst2( 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 = prj_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_Aisle( 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, S_OUT_OP_NAME
 
    }    
]]
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 )
    local out_op_def = lua.Get_StrAttrValue( pac_obj.S_OUT_OP_NAME )
 
    -- 【预分配容器】数据对象属性判断,不合法的终止程序执行
    if ( b_state ~= PAC_STATE.InStock ) then
        msg = "预分配号'"..pac_no.."'的状态不是未执行状态,不能启动料箱出库作业!"
        lua.Warning( strLuaDEID, debug.getinfo(1), msg )
        return 1, msg
    end
    if  out_op_def == '' then
        return 1, "预分配号'"..pac_no.."'的容器预分配对象中没有定义出库作业类型!"
    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 = OPERATION_TYPE.Outbound
    operation.op_def_name = out_op_def                -- 注意这些可能会根据项目的不同而不同,就是出库的作业类型
    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/PAC_STATE.Outbound 表示预分配容器已经安排作业进行搬运
    local strUpdateSql = "S_FROM_LOC = '"..from_loc_code.."', N_B_STATE = "..PAC_STATE.Outbound..", 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/IN_WAVE_STATE.Op_Start 表示入库波次已经开始作业
        strUpdateSql = "N_B_STATE = "..IN_WAVE_STATE.Op_Start..", 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 = "..INBOUND_STATE.Op_Start..", 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
 
--[[
 
    检查一下预分配容器流水号 = pac_no 下面的预分配容器明细是否已经完成处理(码盘完成),如果完成处理 创建一个 入库作业
    适合预分配料箱入库作业,station 为站台编码, cntr_code 是料箱编码
 
    输入参数:
    pac_no -- 分配容器流水号
    station -- 站台编码
    cntr_code -- 容器编码
 
    返回值:
        nRet, 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        
 
        -- 获取【预分配容器】中定义的回库作业定义
        local pac
        nRet, pac = m3.GetDataObjectByKey(strLuaDEID, "Pre_Alloc_Container", "S_PAC_NO", pac_no )
        if nRet ~= 0 then
            return 1, "无法获取编码 = '"..pac_no.."' 的预分配容器!"
        end
        if lua.StrIsEmpty( pac.back_op_name ) then
            return 1, "【预分配容器】对象中 S_BACK_OP_NAME 必须有值!"
        end
 
        -- 容器里加入货品明细,如果容器有混箱规则,系统会在容器的扩展属性表加混箱值,通过这些值可以计算入库货位
        local container
        nRet, container = wms_cntr.GetInfo( strLuaDEID, cntr_code )
        if (nRet ~= 0) then 
            return 2, "获取【容器】信息失败! " .. container 
        end 
        -- 加库存量 INV_Detail 加【预分配容器明细】中的内容
        nRet, strRetInfo = wms_inv.Add_INV_Detail_By_PAC_Detail( strLuaDEID, cntr_code, pac_no, container.position )
        if ( nRet ~= 0 ) then return 2, 'wms_inv.Add_INV_Detail_By_PAC_Detail!'..strRetInfo end 
         
        --重置料箱信息
        nRet, strRetInfo = wms_cntr.Reset( strLuaDEID, container )
        if ( nRet ~= 0 ) then return 2, strRetInfo end 
 
        local parameter = { 
            carry_cb_cls = "Pre_Alloc_Container", 
            carry_cb_no = pac_no,
            bs_type = pac.bs_type,
            bs_no = pac.bs_no,
            factory = pac.factory,
            op_def_name = pac.back_op_name,
        }
        -- 创建作业        
        nRet, operation = wms_op.Create_Inbound_Operation( strLuaDEID, station, cntr_code, parameter )
        if ( nRet ~= 0 ) then
            mobox.setInfo( strLuaDEID, "预分配料箱组盘完成后,无法创建入库作业! 错误号:100 -->"..operation )
            -- 7 组盘完成入库时发现入不了库,回库出现问题, 问题编码 5100
            strUpdateSql = "N_B_STATE = "..PAC_STATE.Error..", 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/Inbound (回库)
        local strUpdateSql = "S_BACK_OP_NO = '"..operation.code.."', N_B_STATE = "..PAC_STATE.Inbound
        strCondition = "S_PAC_NO = '"..pac_no.."'"
        nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Pre_Alloc_Container", strCondition, strUpdateSql )
        if ( nRet ~= 0 ) then  
            return 2, "更新【预分配容器】信息失败!"..strRetInfo 
        end   
        
        -- -- 入库作业产生需要对入库作业的终点获取加入库锁
        -- -- 如果作业定义的类型 = [Station]->[Picking-AS/RS] 不需要锁定目标货位
        -- local op_def
        -- nRet, op_def = wms_base.GetOpDefInfo( factory, operation.op_def_name )
        -- if nRet ~= 0 then
        --     return 1, "系统无法获取名为'"..op_def_name.."'的作业类型! "..op_def
        -- end
        -- if op_def.hand_proc ~= "[Station]->[Picking-AS/RS]" then
        --     -- Pickingc 车不需要对最终位置加锁
        --     nRet, strRetInfo = wms.wms_LockLocation(strLuaDEID, operation.end_loc_code, LOCK_TYPE.Inbound,"", operation.code, operation.op_def_name )
        --     if (nRet ~= 0) then return 2, "wms_LockLocation 失败!"..strRetInfo end     
        -- 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 = "basis-3055 TOP VIEW", ctrl_id = "S_CNTR_CODE", value = ""}
        }                        
    end   
 
    return 0, action  
end
 
--[[
    检查一下当前正在分拣的料箱容器 dc_no (配盘容器) 下面的 detail 是否已经完成处理完成,
    如果完成处理表示该容器分拣完成,创建一个料箱入库
    输入参数:
        parameter --   分拣输入面板的参数
    返回值:
        action -- 
]]
function prj_base.Distribution_CNTR_PostProcess( strLuaDEID, parameter )
    local nRet, strRetInfo
    local strCondition, strUpdateSql
 
    -- 检查一下当前料箱的分拣出库任务是否已经全部完成,如果完成就创建一个【料箱入库】作业
    -- N_B_STATE = 1 表示科执行的入库任务
    strCondition = "S_CNTR_CODE = '"..parameter.cntr_code.."' AND N_B_STATE = 1 AND S_WAVE_NO = '"..parameter.wave_no.."'"       
    nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "Distribution_CNTR_Detail", strCondition )
    if ( nRet ~= 0 ) then return 2, strRetInfo end 
    local nCount = lua.StrToNumber( strRetInfo )  
 
    -- 容器有分拣出库后, 设置容器强制置满标记 C_FORCED_FILL = 'N'
    strCondition = "S_CODE = '"..parameter.cntr_code.."'"
    strUpdateSql = "C_FORCED_FILL = 'N'"
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Container", strCondition, strUpdateSql )
    if ( nRet ~= 0 ) then  
        return 2, "更新【Container】信息失败!"..strRetInfo 
    end 
 
    -- 当前的配盘中已经没有需要执行的出库任务
    local operation = {}   
    local action = {
        {
            action_type = "refresh_master_panel",
            value = {
                sub_page = {"当前任务", "未执行任务"}
            }
        }
    } 
 
    if ( nCount == 0 ) then
        -- 创建分拣完成后回库作业(backop_def_name). 【配盘容器】状态改为4(拣货完成)
        local dc
        nRet, dc = m3.GetDataObjectByKey(strLuaDEID, "Distribution_CNTR", "S_DC_NO", parameter.dc_no )
        if nRet ~= 0 then
            return 1, "无法获取编码 = '"..dc_no.."' 的【配盘】!"
        end
        if lua.StrIsEmpty( dc.back_op_name ) then
            return 1, "【配盘】对象中 S_BACK_OP_NAME 必须有值!"
        end
 
        --库存量表变化 并且生成下架记录
        local loc
        if parameter.loc_code == nil or parameter.loc_code == '' then
            lua.DebugEx( strLuaDEID, "Distribution_CNTR_PostProcess-->parameter 不合规!", parameter ) 
            return 2, 'prj_base.Distribution_CNTR_PostProcess 函数中的 parameter 中没定义 loc_code/拣货台货位'
        end
        nRet, loc = wms_wh.GetLocInfo( parameter.loc_code )
        if ( nRet ~= 0 ) then 
            lua.Stop( strLuaDEID, '获取货位信息失败! 货位 -->['..parameter.loc_code.."] 原因: "..loc ) 
            return
        end  
        nRet, strRetInfo = wms_out.Distribution_CNTR_Detail_PostProcess( strLuaDEID, loc.wh_code, loc.area_code, parameter.loc_code, parameter.dc_no )
        if ( nRet ~= 0 ) then 
            return 2, 'wms_out.Distribution_CNTR_Detail_PostProcess!'..strRetInfo
        end 
 
        --重置料箱信息
        local container
        nRet, container = wms_cntr.GetInfo( strLuaDEID, parameter.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 
 
        local op_parameter = { 
            carry_cb_cls = "Distribution_CNTR", 
            carry_cb_no = parameter.dc_no,
            bs_type = dc.bs_type,
            bs_no = dc.bs_no,
            factory = dc.factory,
            op_def_name = dc.back_op_name
        }
 
        nRet, operation = wms_op.Create_Inbound_Operation( strLuaDEID, parameter.station, parameter.cntr_code, op_parameter )
        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  return 2, "更新【配盘】信息失败!"..strRetInfo end   
            return 0, 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  
            return 2, "更新【配盘】信息失败!"..strRetInfo 
        end 
        local distribution_cntr  
        nRet, distribution_cntr = m3.GetDataObjByCondition( strLuaDEID, "Distribution_CNTR", strCondition )
        if ( nRet ~= 0 ) then  
            return 2, "获取【配盘】信息失败!"..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 
            return 2, "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 return 2, "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 },
                        { attr = "Remaining_Inventory", 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 = ""}
        }           
        lua.DebugEx( strLuaDEID, "action-->", action )
    end 
    
    return 0, action
end
 
return  prj_base