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
--[[
    编码: JX-API-03
    名称: 根据入库单号新增入库单明细
    作者: kun
    日期: 2025-04-23
 
    功能:
        - 输入入库单号和ITEMS数组;
        - 校验入库单是否存在且为新建状态;
        - 校验ITEMS中每个物料的area_code是否与入库单一致;
        - 全部校验通过后逐条创建明细;
        - 中间如有失败,立即中止,报错返回。
    输入数据格式
                {
        "Name": "GetInboundOrderDetail",
        "Source": "ERP",
        "Data": 
                {"S_NO":"CS001",
                "SourceKey": "",
                "ITEMS": [{
            "S_ITEM_CODE":"A234",
            "F_QTY":12,
            "S_EXT_ATTR1":"",
            "D_PRD_DATE":"",
            "S_SUPPLIER_NO":"",
            "S_SUPPLIER_NAME":"",
            "S_BS_NO":"CS003",
            "N_BS_ROW_NO":2,
            "N_ITEM_STATE":"O",
            "S_EXT_ATTR2":"",
            "F_WEIGHT": 0.5,
            "S_EXT_ATTR3":"",
            "S_EXT_ATTR4":"",
            "S_EXT_ATTR5":""
            }
        ]}
            
--]]
 
json = require("json")
mobox = require("OILua_JavelinExt")
m3 = require("oi_base_mobox")
wms_base = require( "wms_base" )
 
function CreateInboundDetail(strLuaDEID)
    local nRet, inputData
    local errcode = {}
    local err = {}
    local err_msg
    local inbound_date
    local data
    local items, s_no
    local strCondition,nRetl, strRetInfo
    local strConditioninfo
    local container_data, nRet
    local Condition
    
    local seen_combinations = {}
    local duplicate_found = false
    local duplicate_items = {}
    
    -- 获取接口数据
    nRet, inputData = m3.GetSysDataJson(strLuaDEID)
    if nRet ~= 0 then
        table.insert(errcode, "无法获取数据包!")
        goto continue
    end
 
    data = inputData.Data       --数据
    items = inputData.ITEMS     --明细数据
    s_no = inputData.S_NO       --来源单号
    
    
    if (s_no == nil or s_no == "" or #items == 0) then
        table.insert(errcode, "入库单号错误或无明细值".. s_no)
        goto continue
    end
 
    -- 校验入库单号是否存在
    strCondition = " S_BS_NO = '" ..s_no.. "' "
    nRetl, strRetInfo = mobox.existThisData(strLuaDEID, "Inbound_Order", strCondition)
    if (nRetl ~= 0) then
        table.insert(errcode, "调用方法 existThisData 出错".. s_no)
        goto continue
    end
    if (strRetInfo ~= 'yes') then
        table.insert(errcode, "来源单号不存在".. s_no)
        goto continue
    end
        
    -- 校验入库单是否为新建状态
    strConditioninfo = "S_BS_NO = '"..s_no.."' AND N_B_STATE <> 0  AND S_AREA_CODE = '料箱库' "
    nRet, inbound_date = m3.QueryDataObject(strLuaDEID, "Inbound_Order", strConditioninfo)
    if (nRet ~= 0) then
        table.insert(errcode, "查询对应的入库单失败".. s_no)
        goto continue
    end
    if (inbound_date ~= "") then
        table.insert(errcode, "该来源单号对应的入库单有非新建状态,不可新增".. s_no)
        goto continue
    end
    
    -- 校验入库单明细是否有已入库的数据
    Condition = "S_IO_NO IN (SELECT S_NO FROM TN_Inbound_Order WHERE S_BS_NO = '"..s_no.."')  AND F_ACC_I_QTY <> 0 "
    nRet, container_data = m3.QueryDataObject(strLuaDEID, "Inbound_Detail", Condition)
    if (nRet ~= 0) then
        table.insert(errcode, "查询对应的入库单失败".. s_no)
        goto continue
    end
    if (container_data ~= "") then
        table.insert(errcode, "该来源单号对应的入库单明细有已入库的数据,不可新增".. s_no)
        goto continue
    end
    
    ::continue::
 
    if #errcode > 0 then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "入库单明细校验失败:" .. table.concat(errcode, ","),
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
 
    
    -- 校验ITEMS物料库区是否一致
    for _, item in ipairs(items) do
        if not item.S_ITEM_CODE or item.S_ITEM_CODE == "" then
            table.insert(err, "商品编码不能为空")
        elseif not item.F_QTY or item.F_QTY == 0 then
            table.insert(err, "商品数量不能为0")
        elseif not item.S_BS_NO or  item.S_BS_NO == "" then
            table.insert(err, "来源单号不能为空")
        elseif not item.N_BS_ROW_NO or  item.N_BS_ROW_NO == "" then
            table.insert(err, "来源行号不能为空")
        elseif (type(item.N_BS_ROW_NO) ~= "number") then
            table.insert(err, "来源行号非数字类型" )
        end
        -- 校验是否存在相同的来源单号和来源单行号的数据
        local strCondition = " N_BS_ROW_MO = '" ..item.N_BS_ROW_NO.. "' and S_BS_NO = '" ..item.S_BS_NO.. "' "
        local nRetl, strRetInfo = mobox.existThisData(strLuaDEID, "ERP_Inbound_Detail", strCondition)
        if (nRetl ~= 0) then
            table.insert(err, "调用方法 existThisData 出错: " .. strRetInfo)
        end
        if (strRetInfo == 'yes') then
            table.insert(err, "该物料的来源单行号已存在:" .. item.S_ITEM_CODE)
        end
        -- 查询物料
        local cond_item = "S_ITEM_CODE = '" .. item.S_ITEM_CODE .. "'"
        local nRet, itemAttrs = m3.GetDataObjByCondition(strLuaDEID, "SKU", cond_item)
        if (nRet ~= 0 or not itemAttrs) then
            table.insert(err, "物料不存在:" .. item.S_ITEM_CODE)
            goto done
        end
        
        local item_area_code = itemAttrs.udf01
        
        if (item_area_code == '' or item_area_code == nil) then
            table.insert(err, "该物料库区值不存在:" .. item.S_ITEM_CODE)
            goto done
        end
        local strCondition = "S_BS_NO = '"..s_no.."' AND S_AREA_CODE = '" ..item_area_code.. "' "
        local nRet, inbound_order = m3.GetDataObjByCondition(strLuaDEID, "Inbound_Order", strCondition)
        if (nRet ~= 0 or not inbound_order) then
            table.insert(err,  "该来源单号的库区值和物料的库区对不上: "..item.S_ITEM_CODE )
        end
        
        ::done::
    end
    
    if #err > 0 then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "明细校验失败:" .. table.concat(err, ","),
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
 
    -- 合并相同物料编码的总数量
    local merged_items = {}
 
    for _, item in ipairs(items) do
        local key = item.S_ITEM_CODE
        if merged_items[key] == nil then
            merged_items[key] = {
                S_ITEM_CODE = item.S_ITEM_CODE,                 -- 物料编码
                S_BS_NO = item.S_BS_NO,                         -- 来源单号
                F_QTY = item.F_QTY,                             -- 数量
                D_PRD_DATE = item.D_PRD_DATE,                   -- 生产日期
                N_ITEM_STATE = item.N_ITEM_STATE,           -- 物料状态
                S_SUPPLIER_NO = item.S_SUPPLIER_NO,         -- 供应商编码
                S_SUPPLIER_NAME = item.S_SUPPLIER_NAME,     -- 供应商名称
                N_BS_ROW_NO = item.N_BS_ROW_NO,             -- 来源单行号
                F_WEIGHT = item.F_WEIGHT,                   -- 重量
 
                S_EXT_ATTR1 = item.S_EXT_ATTR1,             -- 扩展属性1
                S_EXT_ATTR2 = item.S_EXT_ATTR2,         -- 扩展属性2
                S_EXT_ATTR3 = item.S_EXT_ATTR3,         -- 扩展属性3
                S_EXT_ATTR4 = item.S_EXT_ATTR4,         -- 扩展属性4
                S_EXT_ATTR5 = item.S_EXT_ATTR5,         -- 扩展属性5
 
            }
        else
            merged_items[key].F_QTY = merged_items[key].F_QTY + item.F_QTY
        end
    end
 
    -- 创建 Inbound_Detail(原有逻辑)
    for _, item in ipairs(items) do
        local cond_item = "S_ITEM_CODE = '" .. item.S_ITEM_CODE .. "'"
        local nRet, itemAttrs = m3.GetDataObjByCondition(strLuaDEID, "SKU", cond_item)
        if (nRet ~= 0 or not itemAttrs) then
            lua.Stop(strLuaDEID,  "查询物料表失败: "..item.S_ITEM_CODE )
            return
        end
        local item_area_code = itemAttrs.udf01
        
        
        local inbound_cond = "S_BS_NO = '"..s_no.."' AND S_AREA_CODE = '" ..item_area_code.. "' "
        local nRet, inbound_order = m3.GetDataObjByCondition(strLuaDEID, "ERP_Inbound_Order", inbound_cond)
        if (nRet ~= 0 or not inbound_order) then
            lua.Stop(strLuaDEID, "查询失败: "..item.S_ITEM_CODE )
            return
        else
            local detail = m3.AllocObject(strLuaDEID, "ERP_Inbound_Detail")
            detail.io_no = inbound_order.no
            detail.qty = item.F_QTY
            detail.bs_no = item.S_BS_NO
            detail.bs_row_no = item.N_BS_ROW_NO
            detail.item_code = item.S_ITEM_CODE
            detail.prd_date = item.D_PRD_DATE
            detail.sour_no = inputData.SourceKey or ""
            detail.weight = item.F_WEIGHT or 0                                      -- 重量
 
            detail.item_state = item.N_ITEM_STATE
            detail.ext_attr1 = item.S_EXT_ATTR1
            detail.ext_attr2 = item.S_EXT_ATTR2
            detail.ext_attr3 = item.S_EXT_ATTR3
            detail.ext_attr4 = item.S_EXT_ATTR4
            detail.ext_attr5 = item.S_EXT_ATTR5
 
 
 
            
            detail.supplier = item.S_SUPPLIER_NO
            detail.supplier_name = item.S_SUPPLIER_NAME
            
            detail.item_name = itemAttrs.item_name
            detail.s_material = itemAttrs.udf02                                        -- 物料材质
            
    
            local ret5, msg5 = m3.CreateDataObj(strLuaDEID, detail)
            if ret5 ~= 0 then
                lua.Stop(strLuaDEID, "创建入库单明细失败:" .. msg5)
                return
            end
        end
    end
    -- 创建或更新 ERP_Inbound_Detail(新逻辑)
    for _, merge_item in pairs(merged_items) do
 
        local cond_item = "S_ITEM_CODE = '" .. merge_item.S_ITEM_CODE .. "'"
        local nRet, itemAttrs = m3.GetDataObjByCondition(strLuaDEID, "SKU", cond_item)
        if (nRet ~= 0 or not itemAttrs) then
            lua.Stop(strLuaDEID,  "查询物料表失败: "..merge_item.S_ITEM_CODE )
            return
        end
        local item_area_code = itemAttrs.udf01
        
        
        local inbound_cond = "S_BS_NO = '"..s_no.."' AND S_AREA_CODE = '" ..item_area_code.. "' "
        local nRet, inbound_order = m3.GetDataObjByCondition(strLuaDEID, "Inbound_Order", inbound_cond)
        
        lua.Debug(strLuaDEID, debug.getinfo(1), "inbound_order", inbound_order)
 
        if (nRet ~= 0 or not inbound_order) then
            lua.Stop(strLuaDEID, "查询失败: "..itemAttrs.S_ITEM_CODE )
            return
        else
            local strCondition = "S_IO_NO = '" .. inbound_order.no .. "' and S_ITEM_CODE = '" .. merge_item.S_ITEM_CODE .. "' "
            local nRet, strRetInfo = mobox.existThisData(strLuaDEID, "Inbound_Detail", strCondition)
            if nRet ~= 0 then
                lua.Stop(strLuaDEID, "查询 Inbound_Detail 出错:" .. merge_item.S_ITEM_CODE)
                return
            end
 
            if strRetInfo == 'yes'then
                local strConditionData = "S_IO_NO = '" .. inbound_order.no .. "' and S_ITEM_CODE = '" .. merge_item.S_ITEM_CODE .. "' "
                local nRet, exist_data = m3.GetDataObjByCondition(strLuaDEID, "Inbound_Detail", strCondition)
                if nRet ~= 0 then
                    lua.Stop(strLuaDEID, "查询 Inbound_Detail 出错:" .. merge_item.S_ITEM_CODE)
                    return
                end
                -- 存在则更新数量
                exist_data.qty = (exist_data.qty or 0) + merge_item.F_QTY
                local strUpdateSql = "F_QTY = " .. exist_data.qty
                local retUpdate, strInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Inbound_Detail", strConditionData, strUpdateSql)
                if retUpdate ~= 0 then
                    lua.Stop(strLuaDEID, "更新 CG_Detail 失败:" .. strInfo)
                    return
                end
 
            else
                -- 不存在则新增
                local erp_detail = m3.AllocObject(strLuaDEID, "Inbound_Detail")
                erp_detail.io_no = inbound_order.no
                erp_detail.item_code = merge_item.S_ITEM_CODE
                erp_detail.qty = merge_item.F_QTY
                erp_detail.item_state = merge_item.N_ITEM_STATE
                erp_detail.prd_date = merge_item.D_PRD_DATE
                erp_detail.supplier = merge_item.S_SUPPLIER_NO
                erp_detail.supplier_name = merge_item.S_SUPPLIER_NAME
                erp_detail.item_name = itemAttrs.item_name  
 
                erp_detail.s_material = itemAttrs.udf02        -- 物料材质
                erp_detail.ext_attr1 = merge_item.S_EXT_ATTR1
                erp_detail.ext_attr2 = merge_item.S_EXT_ATTR2
                erp_detail.ext_attr3 = merge_item.S_EXT_ATTR3
                erp_detail.ext_attr4 = merge_item.S_EXT_ATTR4
                erp_detail.ext_attr5 = merge_item.S_EXT_ATTR5
 
                erp_detail.sour_no = inputData.SourceKey or ""
                erp_detail.weight = merge_item.F_WEIGHT or 0                                      -- 重量
 
 
                local ret_add, msg_add = m3.CreateDataObj(strLuaDEID, erp_detail)
                if ret_add ~= 0 then
                    lua.Stop(strLuaDEID, "创建 Inbound_Detail 失败:" .. msg_add)
                    return
                end
            end
        end
    end
 
 
    -- 创建入库单明细成功,返回结果
    local result = {
        SourceKey = inputData.SourceKey or "",
        err_code = 0,
        err_msg = "入库单明细新增成功!",
        result = {
            S_NO = s_no,
        }
    }
    mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
    
end