lzh
2025-06-19 3a6436e0c88042c6ce8dca2fe8adb0109f0ad9e4
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
--[[
    版本:     Version 1.0
    创建日期: 2023-6-16
    创建人:   HAN
 
    功能:
        和盘点相关的一些标准函数
 
        -- Create_CountOrder_ByCountPlan    根据盘点计划创建盘点单
        -- Count_PostProcess                盘点后处理
 
    更改说明:
--]]
wms_base = require ("wms_base")
 
local wms_count = {_version = "0.1.1"}
 
local COUNT_PLAN_TYPE_GOODS = 1                 -- 货品盘点
local COUNT_PLAN_TYPE_LOCATION = 2              -- 货位盘点
 
 
--[[ 
    根据盘点计划 count_plan 创建一个盘点单数据对象,触发 num 个【】计划盘点容器进行"生成盘点货品明细", 
    -- method 盘点方法 1 -- 人工到货位盘点 2 -- 自动设备搬运到站台
    -- station 如果method = 2 必须有值
]]
function wms_count.Create_CountOrder_ByCountPlan( strLuaDEID, count_plan, method, station, num )
    local nRet, strRetInfo, n
 
    -- step1:输入参数合法性检查
    if ( count_plan == nil or count_plan == '') then return 1, "count_plan 必须有值!" end
    if ( method == nil or type(method) ~= "number" ) then method = 2 end
    if ( method == 2 ) then
        if ( station == nil or station == '') then return 1, "station 必须有值!" end
    end
    if  ( num == nil ) then num = 0 end
 
    -- 获取常量 盘点差异需要审核 = Y
    local diff_need_review = wms_base.Get_sConst( strLuaDEID, "盘点差异需要审核", 1 )
    local diff_hand_method = 0
    -- 1 表示有差异需要审核后才能变
    if ( diff_need_review == "Y" ) then diff_hand_method = 1 end
 
    -- step2:创建盘点单
    local count_order = m3.AllocObject(strLuaDEID,"Count_Order")
    count_order.cp_no = count_plan.cp_no
    count_order.wh_code = count_plan.wh_code
    count_order.area_code = count_plan.area_code
    count_order.method = method                      -- 1 表示是人工盘点,这是新兴项目的要求
    count_order.num = num
    count_order.station = station
    count_order.count_type = count_plan.type
    count_order.diff_hand_method = diff_hand_method
    nRet, count_order = m3.CreateDataObj( strLuaDEID, count_order )   
    if (nRet ~= 0) then return 1, "创建【盘点单】失败!"..count_order end 
 
 
    -- step3:查询盘点计划中没有盘点单的【计划盘点容器】
    --        特别注意需要 多页查询
    local strCondition = "S_CP_NO = '"..count_plan.cp_no.."' AND N_B_STATE = 0"    
    nRet, strRetInfo = mobox.queryDataObjAttr2( strLuaDEID, "CP_Count_Container", strCondition, strOrder, 100 )
    if ( nRet ~= 0 ) then return 1, "queryDataObjAttr2: "..strRetInfo end  
    if  ( strRetInfo == '' ) then return 1, "盘点计划'".. count_plan.cp_no.."'中没有待盘点的容器!" end
 
    local success
    local queryInfo
    success, queryInfo = pcall( json.decode, strRetInfo )
    if ( success == false ) then return 1, "queryDataObjAttr2 返回结果啊非法的JSON格式!" end
 
    local queryID = queryInfo.queryID
    local nPageCount = queryInfo.pageCount
    local nPage = 1
    local dataSet = queryInfo.dataSet       -- 查询出来的数据集
    local datajson = {
                        count_type = count_plan.type,             -- 盘点类型,这个在WFP的脚本里有用
                        count_order_no = count_order.count_no,    -- 盘点单号
                        count_method = method,                    -- 盘点方法
                        diff_hand_method = diff_hand_method,      -- 盘点有差异处理方法
                        station = station                         -- 盘点站台
                     }
 
    local count = 1
    while (nPage <= nPageCount) do
 
        for n = 1, #dataSet do
            -- step3.1: 后台触发【计划盘点容器】的 Create_Count_CG_Detail
            -- 考虑到生成盘点货品明细的时间会较长用 WFP 来进行处理
            local add_wfp = {
                                wfp_type = 1,                 -- 触发数据对象事件(指定数据对象标识)
                                datajson = datajson,
                                cls = "CP_Count_Container",
                                obj_id = dataSet[n].id,
                                trigger_event = "Create_Count_CG_Detail"
                            }
            nRet, strRetInfo = m3.AddSysWFP( strLuaDEID, add_wfp )
            if ( nRet ~= 0 ) then return 1, strRetInfo  end  
            if ( num > 0 ) then
                -- 如果num=0 就触发所有容器
                if ( count == num ) then  goto finish_step end 
            end    
            count = count + 1        
        end        
 
        nPage = nPage + 1
        if ( nPage <= nPageCount ) then
            -- 取下一页
            nRet, strRetInfo = mobox.queryDataObjAttr2( queryID, nPage)
            if ( nRet ~= 0 ) then
                return 1, "queryDataObjAttr2失败! nPage="..nPage.."  "..strRetInfo
            end 
            queryInfo = json.decode(strRetInfo) 
            dataSet = queryInfo.dataSet              
        end
    end
 
    -- step4:更新盘点单中盘点容器数量, 
    if  ( count < num or num == 0 ) then 
        -- 更新盘点单盘点容器数量
        strCondition = "S_COUNT_NO = '"..count_order.count_no.."'"
        local strSetSQL = "N_COUNT_NUM = "..count
        nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Count_Order", strCondition, strSetSQL)
        if (nRet ~= 0) then return 1, "设置【盘点单】信息失败!"..strRetInfo end        
    end
 
    ::finish_step::
    -- step5:更新盘点计划中的 进行盘点容器数量
    strCondition = "S_CP_NO = '"..count_plan.cp_no.."'"
    nRet, strRetInfo = mobox.incDataObjAccQty( strLuaDEID, "Count_Plan", strCondition, "N_PLAN_TOTAL", "N_ACC_COUNT", count )
    if ( nRet ~= 0 )  then return 1, "incDataObjAccQty(Count_Plan)失败! "..strRetInfo end      
    if ( strRetInfo ~= '') then
        return 1, "盘点计划号'"..count_order.count_no.."'的累计盘点容器数量异常,无法增加!"
    end 
    
    return 0
end
 
--[[ 
    根据[CP_Count_Container]cp_cntr 查询【Count_CG_Detail】如果有差异就生成【Count_Diff】 
]]
function wms_count.Count_PostProcess( strLuaDEID, cp_cntr )
    local nRet, strRetInfo
    local strCondition = "S_CC_NO = '"..cp_cntr.cc_no.."'"
 
    -- 判断盘点计划类型是否是货物盘点,如果是,需要更新货品盘点的结果 【CP_Good_List】
    local cp_no = lua.Get_StrAttrValue( cp_cntr.cp_no )
    local first_cc_no = lua.Get_StrAttrValue( cp_cntr.first_cc_no ) -- 复盘会有这个属性,表示对什么进行复盘
 
    local is_good_count = false         -- 是货品盘点
    if ( '' ~= cp_no ) then
        local count_plan
        nRet, count_plan = m3.GetDataObjectByKey( strLuaDEID, "Count_Plan", "S_CP_NO", cp_cntr.cp_no )
        if ( nRet ~= 0 ) then return 1, "GetDataObjectByKey失败"..count_plan end  
        if ( count_plan.type == COUNT_PLAN_TYPE_GOODS ) then
            is_good_count = true
        end
    end
 
    nRet, data_objs = m3.QueryDataObject(strLuaDEID, "Count_CG_Detail", strCondition )
    if (nRet ~= 0) then return 1, "QueryDataObject失败!"..data_objs end
    if ( data_objs == '' ) then return 0  end
    
    local n
    local have_diff = false
    local obj_attrs
    local count_diff
    local strCondition, strUpdateSql
 
    -- 遍历【Count_CG_Detail】
    for n = 1, #data_objs do
        obj_attrs = m3.KeyValueAttrsToObjAttr(data_objs[n].attrs)
        qty = lua.StrToNumber( obj_attrs.F_QTY )
        act_qty = lua.StrToNumber( obj_attrs.F_ACT_QTY )        -- 盘点数量
        if ( is_good_count ) then
            strCondition = "S_ITEM_CODE = '"..obj_attrs.S_ITEM_CODE.."' AND S_CP_NO = '"..cp_no.."'"
            strUpdateSql = "F_ACT_QTY = F_ACT_QTY + "..act_qty
            nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "CP_Good_List", strCondition, strUpdateSql)
            if (nRet ~= 0) then return 1, "更新【计划盘点货品】 实际数量失败!"..strRetInfo end                
        end
 
        if ( qty ~= act_qty ) then
            if ( first_cc_no == '' ) then
                count_diff = m3.AllocObject(strLuaDEID,"Count_Diff")
                count_diff.cc_no = cp_cntr.cc_no
                count_diff.cp_no = cp_no
                count_diff.cntr_code = cp_cntr.cntr_code
                count_diff.count_no = cp_cntr.count_no
                count_diff.cg_detail_id = obj_attrs.S_CG_DETAIL_ID
 
                count_diff.wh_code = cp_cntr.wh_code
                count_diff.area_code = cp_cntr.area_code
 
                count_diff.qty = qty
                count_diff.act_qty = act_qty
 
                count_diff.cell_no = obj_attrs.S_CELL_NO
                count_diff.item_code = obj_attrs.S_ITEM_CODE
                count_diff.item_name = obj_attrs.S_ITEM_NAME
 
                count_diff.item_state = lua.StrToNumber( obj_attrs.N_ITEM_STATE )
                count_diff.batch_no = obj_attrs.S_BATCH_NO  
                count_diff.serial_no = obj_attrs.S_SERIAL_NO  
                count_diff.erp_wh_code = obj_attrs.S_ERP_WH_CODE  
                count_diff.end_user = obj_attrs.S_END_USER  
                count_diff.owner = obj_attrs.S_OWNER  
                count_diff.supplier = obj_attrs.S_SUPPLIER_NO   
                
                count_diff.uom = obj_attrs.S_UOM        
                count_diff.ext_attr1 = obj_attrs.S_EXT_ATTR1      
                count_diff.ext_attr2 = obj_attrs.S_EXT_ATTR2 
                count_diff.ext_attr3 = obj_attrs.S_EXT_ATTR3 
                count_diff.ext_attr4 = obj_attrs.S_EXT_ATTR4 
                count_diff.ext_attr5 = obj_attrs.S_EXT_ATTR5                                                       
 
                nRet, count_diff = m3.CreateDataObj( strLuaDEID, count_diff )
                if ( nRet ~= 0 ) then 
                    return 1, 'mobox 创建【盘点差异表】对象失败!'..count_diff
                end 
                have_diff = true    
            else
                -- 复盘处理差异,首先获取原先最早盘点容器流水号中的差异
                strCondition = "S_CC_NO = '"..first_cc_no.."' AND S_CG_DETAIL_ID = '"..obj_attrs.S_CG_DETAIL_ID.."'"
                nRet, count_diff = m3.GetDataObjByCondition( strLuaDEID, "Count_Diff", strCondition )  
                if ( nRet ~= 0 ) then  return 1, "获取【盘点差异表】信息失败!"..count_diff end 
                -- 判断盘点次数, 如果已经是二盘
                strUpdateSql = "N_B_STATE = 1, F_ACTUAL_QTY = "..act_qty
                if ( count_diff.count_time == 2 ) then
                    -- 不允许再复盘
                    strUpdateSql = strUpdateSql..", N_COUNT_TIME = 3, C_RECOUNT = 'Y'"
                else
                    strUpdateSql = strUpdateSql..", N_COUNT_TIME = 2 "
                end
                nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Count_Diff", strCondition, strUpdateSql )
                if ( nRet ~= 0 ) then  return 1, "更新【Count_Diff】信息失败!"..strRetInfo end 
                have_diff = true
            end                     
        end
    end
 
    -- 盘点单{累计盘点数量}+1
    strCondition = "S_COUNT_NO = '"..cp_cntr.count_no.."'"
    nRet, strRetInfo = mobox.incDataObjAccQty ( strLuaDEID, "Count_Order", strCondition, "N_COUNT_NUM", "N_ACC_FINISH", 1 )
    if ( nRet ~= 0 or strRetInfo ~= '') then 
        return 1, '在增加【盘点单】中的累计盘点数量时失败!'..strRetInfo 
    end     
 
    -- 更新计划盘点容器中的 C_HAVE_DIFF = 'Y' 表示这个容器盘点有差异
    if ( have_diff ) then
        strCondition = "S_ID = '"..cp_cntr.id.."'"
        local strSetAttr = "C_HAVE_DIFF = 'Y'"
        nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "CP_Count_Container", strCondition, strSetAttr )
        if ( nRet ~= 0 ) then  return 1, "更新【CP_Count_Container】信息失败!"..strRetInfo end     
    end
    return 0
end
 
return wms_count