Jianw
2025-05-14 29f8b36ebb718d2051bf0e7e701973ec4419ee80
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
--[[
    编码: WMS-16-20
    名称: 盘点计划-盘点计划启动
    作者:HAN  
    日期:2025-1-29
 
    级别:固定 (说明本段代码在项目中不太会变化)
    
    函数: AllocPlanContainer
 
    功能:
          根据盘点计划类型生成计划盘点容器
 
    更改记录:
        V2.0 HAN 20250213
             -- 新增容器盘点类型    
 
--]]
wms_base = require( "wms_base" )
 
-- 创建 计划盘点容器
-- cp_no 盘点计划号 cntr_code 容器号 item_code 货品编码
local function create_cp_count_container( strLuaDEID, cp_no, cntr_code, item_code )
    local nRet, strRetInfo
    -- step1 盘点一下当前【计划盘点容器】里是否已经存在这个容器
    local strCondition = "S_CP_NO = '" .. cp_no .. "' AND S_CNTR_CODE = '"..cntr_code.."'"
    local cp_count_container
    if ( item_code == nil ) then item_code = '' end
 
    nRet, cp_count_container = m3.GetDataObjByCondition( strLuaDEID,"CP_Count_Container", strCondition )
    if (nRet == 1) then   
        -- 不存在要创建 【CP_Count_Container】
        cp_count_container = m3.AllocObject(strLuaDEID,"CP_Count_Container")
        cp_count_container.cp_no = cp_no
        cp_count_container.cntr_code = cntr_code
        if (item_code ~='') then
            cp_count_container.good_codes = '["'..item_code..'"]'
        end
        nRet, cp_count_container = m3.CreateDataObj( strLuaDEID, cp_count_container )
        if (nRet ~= 0) then return 1, cp_count_container end 
        return 0  
    end
    if ( nRet ~= 0 ) then return 1, cp_count_container end
    if ( item_code == '') then return 0 end
 
    -- 已经存在 更新 容器里要 盘点的货物编码
    str_good_codes = cp_count_container.good_codes
 
    local good_codes = {}
    local nIndex = 1
    if (str_good_codes ~= '') then
        good_codes = json.decode(str_good_codes)
        nIndex = #good_codes + 1
    end
    -- 判断 item_code 是否已经存在, 如果已经存就不需要加
    if ( lua.IsInTable( item_code, good_codes ) ) then return 0 end
 
    good_codes[nIndex] = item_code
 
    local id = lua.trim_guid_str( cp_count_container.id )
    strCondition = "S_ID = '"..id.."'"
    local strSetAttr = "S_GOOD_CODES = '"..lua.table2str(good_codes).."'"
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "CP_Count_Container", strCondition, strSetAttr )
    if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "updateDataAttrByCondition失败"..strRetInfo ) end     
    return 0
end
 
-- 根据 CP_Good_list 中的记录查询出这些货品所在的 容器,生成计划盘点容器
-- count_plan 盘点计划
-- data_set 需要盘点的货物 CP_Good_list
local function alloc_cntr_by_cp_good_list( strLuaDEID, count_plan, data_set )
    local n, good, nRet, strRetInfo, i
    local str_loc_condition     -- 货位条件
    local str_good_condition    -- 货物条件
    local str_condition
 
 
    str_loc_condition = "S_WH_CODE ='"..count_plan.wh_code.."' "
 
    -- MDF BY HAN 2025-2-28 考虑到根据货品盘点时,如果容器在移动中,这个时候就获取不全容器,因此把库区取消 N_PURPOSE 也不考虑
    -- N_PURPOSE = 1 表示货位是存储位
    --[[
    str_loc_condition = "S_WH_CODE ='"..count_plan.wh_code.."' AND N_PURPOSE = 1"
    if ( count_plan.area_code ~= '' and count_plan.area_code ~= nil ) then
        str_loc_condition = str_loc_condition.." AND S_AREA_CODE ='"..count_plan.area_code.."'"
    end
    ]]
 
    local success
    local queryInfo
    local queryID, nPageCount, nPage, dataSet, cntr_code, i
    local strOrder = "S_CNTR_CODE"
 
    for n = 1, #data_set do
        nRet, good = m3.ObjAttrStrToLuaObj( "CP_Good_List", lua.table2str(data_set[n].attrs) )  
        if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "m3.ObjAttrStrToLuaObj 失败! "..good ) end   
        str_good_condition = "S_ITEM_CODE = '"..good.item_code.."' "..
                             "AND S_CNTR_CODE in "..
                             "(select S_CNTR_CODE from TN_Loc_Container with (NOLOCK) where S_LOC_CODE in (select S_CODE from TN_Location with (NOLOCK) where "..str_loc_condition.."))"
 
        -- 查询有该货品的容器编号
        -- 获取货品所在容器(考虑到有比较极端情况容器数量大于1000因此采用 queryDataObjAttr2 )        
        nRet, strRetInfo = mobox.queryDataObjAttr2( strLuaDEID, "CG_Detail", str_good_condition, strOrder, 100, "S_CNTR_CODE" )
        if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2: "..strRetInfo) end  
        if  ( strRetInfo == '' ) then goto continue end 
        success, queryInfo = pcall( json.decode, strRetInfo )
        if ( success == false ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2 返回结果啊非法的JSON格式!" ) end
    
        queryID = queryInfo.queryID
        nPageCount = queryInfo.pageCount
        nPage = 1
        dataSet = queryInfo.dataSet       -- 查询出来的数据集
    
        while (nPage <= nPageCount) do
            for i = 1, #dataSet do
                cntr_code = dataSet[i].attrs[1].value
                nRet, strRetInfo = create_cp_count_container( strLuaDEID, count_plan.cp_no, cntr_code, good.item_code )
                if ( nRet ~= 0 )  then  return 1, "create_cp_count_container失败! ".. strRetInfo end
            end
 
            nPage = nPage + 1
            if ( nPage <= nPageCount ) then
                -- 取下一页
                nRet, strRetInfo = mobox.queryDataObjAttr2( queryID, nPage)
                if ( nRet ~= 0 ) then
                    lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2失败! nPage="..nPage.."  "..strRetInfo )
                end 
                queryInfo = json.decode(strRetInfo) 
                dataSet = queryInfo.dataSet 
            end
        end             
 
        ::continue::
    end
    return 0
end
 
-- 根据 CP_Location_list 中的记录查询出这些货位中存在的容器进行盘点
-- count_plan 盘点计划
-- data_set 需要盘点的货物 CP_Location_list
local function alloc_cntr_by_cp_location_list( strLuaDEID, count_plan, data_set )
    local n, nRet, strRetInfo, strCondition
    local location
    local strOrder = "N_BIND_ORDER"
    local object_attr
 
    for n = 1, #data_set do
        nRet, location = m3.ObjAttrStrToLuaObj( "CP_Location_list", lua.table2str(data_set[n].attrs) )  
        if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "m3.ObjAttrStrToLuaObj 失败! "..location ) end   
        strCondition = "S_LOC_CODE ='"..location.loc_code.."'"
        
        -- 获取货位绑定的容器号
        local data_objs, i
        nRet, data_objs = m3.QueryDataObject(strLuaDEID, "Loc_Container", strCondition, strOrder )
        if (nRet ~= 0) then return 1, data_objs end
        if ( data_objs ~= '') then
            for i = 1, #data_objs do
                object_attr = m3.KeyValueAttrsToObjAttr(data_objs[i].attrs)
                nRet, strRetInfo = create_cp_count_container( strLuaDEID, count_plan.cp_no, object_attr.S_CNTR_CODE )
                if ( nRet ~= 0 ) then return 1, strRetInfo end
            end
        end
    end
    return 0
end
 
function AllocPlanContainer ( strLuaDEID ) 
    local nRet, strRetInfo
    local count_plan
    nRet, count_plan = m3.GetSysCurEditDataObj( strLuaDEID, "Count_Plan" )
    if ( nRet ~= 0 )  then lua.Error( strLuaDEID, debug.getinfo(1), "获取当前编辑属性失败! "..count_plan ) end 
 
    local strCurEditClsID, strCurEditObjID
    nRet, strCurEditClsID, strCurEditObjID = mobox.getCurEditDataObjID( strLuaDEID )
    if ( nRet ~= 0 )  then lua.Error( strLuaDEID, debug.getinfo(1), "getCurEditDataObjID失败! " ) end
 
    -- 如果已经启动过就不要再做后面的程序
    if ( count_plan.b_state > 1 ) then
        lua.Warning( strLuaDEID, debug.getinfo(1), "盘点计划编号 = '"..count_plan.cp_no.."' 已经启动过不需要再次启动!" )
        return
    end
    local strCondition, strClsID
    local strOrder
    strCondition = "S_CP_NO = '"..count_plan.cp_no.."'"
    if ( count_plan.type == wms_base.Get_nConst(strLuaDEID,"盘点类型-货品盘点") ) then
        -- 获取 【CP_Good_List】
        strClsID = "CP_Good_List"
        strOrder = "S_ITEM_CODE"
    elseif ( count_plan.type == wms_base.Get_nConst(strLuaDEID,"盘点类型-货位盘点") ) then
        strClsID = "CP_Location_List"
        strOrder = "S_LOC_CODE"
    -- V2.0
    else
        strClsID = ""
    end
 
    -- 多页查询
    if ( strClsID ~= '') then
        nRet, strRetInfo = mobox.queryDataObjAttr2( strLuaDEID, strClsID, strCondition, strOrder, 100 )
        if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2: "..strRetInfo) end  
        if  ( strRetInfo == '' ) then return end
        local success
        local queryInfo
        success, queryInfo = pcall( json.decode, strRetInfo )
        if ( success == false ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2 返回结果啊非法的JSON格式!" ) end
 
        local queryID = queryInfo.queryID
        local nPageCount = queryInfo.pageCount
        local nPage = 1
        local dataSet = queryInfo.dataSet       -- 查询出来的数据集
 
        while (nPage <= nPageCount) do
            if ( count_plan.type == wms_base.Get_nConst(strLuaDEID,"盘点类型-货品盘点") ) then
                -- 通过计划盘点货品查找 计划盘点的容器
                nRet, strRetInfo = alloc_cntr_by_cp_good_list( strLuaDEID, count_plan, dataSet )
                if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "alloc_cntr_by_cp_good_list: "..strRetInfo) end  
            else
                nRet, strRetInfo = alloc_cntr_by_cp_location_list( strLuaDEID, count_plan, dataSet )
                if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "alloc_cntr_by_cp_location_list: "..strRetInfo) end  
            end
            nPage = nPage + 1
            if ( nPage <= nPageCount ) then
                -- 取下一页
                nRet, strRetInfo = mobox.queryDataObjAttr2( queryID, nPage)
                if ( nRet ~= 0 ) then
                    lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2失败! nPage="..nPage.."  "..strRetInfo )
                end 
                queryInfo = json.decode(strRetInfo) 
                dataSet = queryInfo.dataSet              
            end
        end
    end
 
    -- 获取 计划盘点容器【CP_Count_Container】数量
    strCondition = "S_CP_NO = '"..count_plan.cp_no.."'"
    nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "CP_Count_Container", strCondition )
    if ( nRet ~= 0 ) then return nRet, strRetInfo end 
    local nCount = lua.StrToNumber( strRetInfo )     
    
    local strSetAttr
    if ( nCount == 0 ) then
        -- 如果计划盘点容器为 0 表示没有找到盘点的容器,设置状态为错误
        strSetAttr = "N_B_STATE = 4, N_PLAN_TOTAL = 0, S_ERR = '没有找到匹配的容器!'"
    else
        strSetAttr = "N_B_STATE = 2, N_PLAN_TOTAL = "..nCount
    end
   
    nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Count_Plan", strCondition, strSetAttr )
    if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "updateDataAttrByCondition失败"..strRetInfo ) end  
    if ( nCount == 0 ) then return end
    
    -- 设置计划盘点容器表中的货位信息
    local add_wfp_paramter = {}
    add_wfp_paramter.wfp_type = 1                  -- 触发数据对象事件(指定数据对象标识)
    add_wfp_paramter.cls = strCurEditClsID
    add_wfp_paramter.obj_id = strCurEditObjID
    add_wfp_paramter.trigger_event = "刷新计划盘点容器货位信息"
    nRet, strRetInfo = m3.AddSysWFP( strLuaDEID, add_wfp_paramter )
    if ( nRet ~= 0 ) then
        lua.Error( strLuaDEID, debug.getinfo(1), strRetInfo )
    end    
  
end