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
--[[
   编码: WMS-24-18
   名称: 自动配盘
   作者:
   日期: 2025-1-29
 
   函数: AutoDistribution
   功能:
        -- 根据出库单明细计算出配盘及配盘明细
 
   备注:一个标准的针对出库单为对象的配盘算法,适合后台进程执行
        
   更改记录:
 
--]]
wms_out = require( "wms_outbound" )
wms_station = require( "wms_station" )
 
 
local function set_err_info( outbound_order_no, b_state, err_msg )
    local strCondition = "S_NO = '"..outbound_order_no.."'"
    local strSetAttr = "N_B_STATE = 5, S_ERR_MSG = '"..lua.FormatSQLString(err_msg).."', N_PRE_B_STATE = "..b_state
    mobox.addProcSQL3( "Outbound_Wave", strCondition, strSetAttr)
end
 
--[[
        执行'自动配盘算法1#' 
 
        datajson 格式:
        {
            station,
            login,
            user_name,
            outbound_order_no              -- 出库单号   
            cntr_out_op_def
            cntr_back_op_def    
        }
        -- 返回结果
        result = { d_cntr_list, d_cntr_detail_list, shortage_list }
--]]
function AutoDistribution( strLuaDEID )
    local nRet, strRetInfo
    local parameter
 
    lua.DebugEx( strLuaDEID, "AutoDistribution", "In...")
    m3.PrintLuaDEInfo( strLuaDEID )
 
    -- 获取输入参数 datajson
    nRet, parameter = m3.GetSysDataJson( strLuaDEID )
    if (nRet ~= 0) then 
        lua.Stop( strLuaDEID, parameter )
        return
    end
    local outbound_order_no = parameter.outbound_order_no or ''
 
    if outbound_order_no == '' then
        lua.Stop( strLuaDEID, "脚本的输入参数中,出库单号 outbound_order_no 不能为空!")
        return
    end
    local strCondition = "S_NO = '"..outbound_order_no.."'"
    local outbound_order  
    nRet, outbound_order = m3.GetDataObjByCondition( strLuaDEID, "Outbound_Order", strCondition )
    if ( nRet ~= 0 ) then  
        lua.Stop( strLuaDEID, "获取【出库单】信息失败!"..outbound_order )
        return
    end  
 
    -- 获取出库波次对象属性
    local b_state = lua.Get_NumAttrValue( outbound_order.b_state )  
    local wh_code = lua.Get_StrAttrValue( outbound_order.wh_code )
    local area_code = lua.Get_StrAttrValue( outbound_order.area_code ) 
    local station = lua.Get_StrAttrValue( parameter.station )  
    local err_msg = ''
    local d_cntr_list = {}              -- 配盘/Distribution_CNTR
    local d_cntr_detail_list = {}       -- 配盘明细/Distribution_CNTR_Detail   
    local shortage_list = {}            -- 缺件清单
    local result = {}
    local loc_code
    local distribution_parameter = {}
 
    local op_def
    if lua.StrIsEmpty( parameter.cntr_out_op_def ) then
        lua.Stop( strLuaDEID, "自动配盘的输入参数 parameter 中必须定义 cntr_out_op_def " )
        return
    end 
    nRet, op_def = wms_base.GetOpDefInfo( outbound_order.factory, parameter.cntr_out_op_def )
    if nRet ~= 0 then
        err_msg = "系统无法获取名为'"..parameter.cntr_out_op_def.."'的作业类型! "..op_def
        set_err_info( outbound_order_no, b_state, err_msg )
        lua.Stop( strLuaDEID, err_msg )
        return
    end
 
    -- 获取站台接驳位信息
    local to_loc_code, to_wh_code, to_area_code
    nRet, to_wh_code, to_area_code, to_loc_code = wms_station.Get_Station_TransferZone( station, op_def  )
    if nRet ~= 0 then
        err_msg = "获取站台接驳位失败! "..to_wh_code
        set_err_info( outbound_order_no, b_state, err_msg )
        lua.Stop( strLuaDEID, err_msg )
        return
    end    
 
    local exit_loc = {}
    if to_loc_code ~= '' then
        nRet, exit_loc = wms_wh.GetLocInfo( to_loc_code )
        if ( nRet ~= 0 ) then 
            err_msg = '获取站台货位信息失败! '..exit_loc 
            goto set_state_ret
        end  
    end
    
    if ( wh_code == '' ) then
        err_msg = '出库波次中仓库编码不能为空!' 
        goto set_state_ret
    end 
    
    distribution_parameter = {
        wh_code = wh_code, area_code = '', 
        exit_area_code = to_area_code,                  -- 出库要出到库区
        exit_loc = exit_loc,                            -- 出库要出到的货位
        bs_type = "Outbound_Order",
        bs_no = outbound_order_no,
        factory = outbound_order.factory or '',
        cntr_out_op_def = parameter.cntr_out_op_def or '',
        cntr_back_op_def = parameter.cntr_back_op_def or '',        
        station = station
    }    
 
    -- 【step1】 系统自动配货算法
    -- wms_out.Distribution_Procedure 是汉和WMS的一个标准的配盘算法
    nRet, strRetInfo = wms_out.Distribution_Procedure( strLuaDEID, distribution_parameter, d_cntr_list, d_cntr_detail_list, shortage_list )  
    if ( nRet ~= 0 ) then
        err_msg = "【step1】系统自动配货算法,详细信息见日志!"..strRetInfo
        goto set_state_ret
    end
    --【step2】 创建配盘及配盘明细
    nRet, strRetInfo = wms_out.Creat_Distribution_list( strLuaDEID, d_cntr_list, d_cntr_detail_list  )
    if ( nRet ~= 0 ) then
        err_msg = "wms_out.Creat_Distribution_list 发生错误,!"..strRetInfo
        goto set_state_ret      
    end
 
    -- 设置后台脚本处理结果
    result = { 
        d_cntr_list = d_cntr_list,
        d_cntr_detail_list = d_cntr_detail_list,
        shortage_list = shortage_list
    }
    mobox.returnValue( strLuaDEID, RETSTR_TYPE.Json, lua.table2str(result) )
 
    ::set_state_ret::
    if ( err_msg ~= '' ) then
        -- 5 错误
        strCondition = "S_NO = '"..outbound_order_no.."'"
        local strSetAttr = "N_B_STATE = "..OUTBOUND_ORDER_STATE.Error..", S_ERR_MSG = '"..lua.FormatSQLString(err_msg).."', N_PRE_B_STATE = "..b_state
        mobox.addProcSQL3( "Outbound_Order", strCondition, strSetAttr)
        lua.Stop( strLuaDEID, "自动配盘失败!"..err_msg )
        return
    else
        -- 触发后台脚本生成出库作业
        -- 是否需要触发后台脚本进行出库作业创建,可以根据具体项目确定
        
        -- 判断一下是否配盘完成,是否有缺件
 
        local add_wfp = {
            wfp_type = 1,
            cls = "Outbound_Order",
            obj_id = outbound_order.id,
            obj_name = "出库单'"..outbound_order_no.."'-->生成出库作业",
            trigger_event = "后台创建出库作业"
        }
        nRet, strRetInfo = m3.AddSysWFP( strLuaDEID, add_wfp )
        if ( nRet ~= 0 ) then 
            lua.Stop( strLuaDEID, "AddSysWFP失败!"..strRetInfo )  
            return
        end             
    end
end