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
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
--[[
    编码: JX-API-07
    名称: 根据出库单号新增出库单明细
    作者: kun
    日期: 2025-04-23
 
    功能:
        - 输入出库单号和ITEMS数组;
        - 校验出库单是否存在且为新建状态;
        - 校验ITEMS中每个物料的area_code是否与出库单一致;
        - 全部校验通过后逐条创建明细;
        - 中间如有失败,立即中止,报错返回。
    输入数据格式
        {
                "Name": "GetOutboundDetail",
                "Source": "ERP",
                "Data": {
                        "S_NO": "CKD001",
                        "SourceKey": "",
                        "ITEMS": [{
                                "S_BS_NO": "12",
                                "N_BS_ROW_MO": 13,
                                "S_ITEM_CODE": "A234",
                                "S_ITEM_STATE": "O",
                                "S_SUPPLIER_NO":"",
                                "S_SUPPLIER_NAME":"",
                                "F_QTY": 10,
                                "S_EXT_ATTR1":"",      
                                "S_EXT_ATTR2":"123" ,
                                "S_EXT_ATTR3":""  ,
                                "S_EXT_ATTR4":""  ,
                                "S_EXT_ATTR5":""        
                                }
                            ]
                    }
                }
--]]
 
json = require("json")
mobox = require("OILua_JavelinExt")
m3 = require("oi_base_mobox")
 
function CreateOutboundDetail(strLuaDEID)
    local nRet, inputData
    local err = {}
    
    local seen_combinations = {}
    local duplicate_found = false
    local duplicate_items = {}
 
    -- 获取接口数据
    nRet, inputData = m3.GetSysDataJson(strLuaDEID)
    if nRet ~= 0 then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "无法获取数据包!" .. inputData,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
 
    --local data = inputData.Data or {}
    local s_no = inputData.S_NO
    local items = inputData.ITEMS
    lua.Debug(strLuaDEID, debug.getinfo(1), "s_no", s_no)
    if not s_no or s_no == "" or #items == 0 then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "出库单号错误或无明细值:" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
 
    -- 查询出库单状态和库区类型
    local strCondition = " S_BS_NO = '" ..s_no.. "' "
    local nRetl, strRetInfo = mobox.existThisData(strLuaDEID, "Outbound_Order", strCondition)
    lua.Debug(strLuaDEID, debug.getinfo(1), "strRetInfo", strRetInfo)
    if (nRetl ~= 0) then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "调用方法 existThisData 出错" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
    if (strRetInfo ~= 'yes') then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "来源单号不存在" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
        
    
    local strCondition = "S_BS_NO = '"..s_no.."' AND N_B_STATE <> 0  AND S_AREA_CODE = '料箱库' "
    nRet, inbound_date = m3.QueryDataObject(strLuaDEID, "Outbound_Order", strCondition)
    if (nRet ~= 0) then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "查询对应的出库单失败" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
    if (inbound_date ~= "") then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "该来源单号对应的出库单有非新建状态,不可新增" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
    
    local container_data, nRet
    local Condition = "S_OO_NO IN (SELECT S_NO FROM TN_Outbound_Order WHERE S_BS_NO = '"..s_no.."')  AND F_ACC_O_QTY <> 0 "
    nRet, container_data = m3.QueryDataObject(strLuaDEID, "Outbound_Detail", Condition)
    if (nRet ~= 0) then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "查询对应的出库单失败" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
    if (container_data ~= "") then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "该来源单号对应的出库单明细有已出库的数据,不可新增" .. s_no,
            result = nil
        }
        mobox.returnValue(strLuaDEID, 1, lua.table2str(result))
        return
    end
 
    
    for _, item in ipairs(inputData.ITEMS) do
        local combination_key = item.S_BS_NO .. "|" .. tostring(item.N_BS_ROW_NO)
        
        if seen_combinations[combination_key] then
            duplicate_found = true
            table.insert(duplicate_items, combination_key)
        else
            seen_combinations[combination_key] = true
        end
    end
    
    if duplicate_found then
        local result = {
            SourceKey = "",
            err_code = 1,
            err_msg = "存在重复的来源单号和行号组合: " .. table.concat(duplicate_items, ", "),
            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_MO or  item.N_BS_ROW_MO == "" then
            table.insert(err, "来源行号不能为空")
        elseif (type(item.N_BS_ROW_MO) ~= "number") then
            table.insert(err, "来源行号非数字类型" )
        end
        
        local strCondition = "S_BS_NO = '" ..item.S_BS_NO.. "' and  N_BS_ROW_MO = '" ..item.N_BS_ROW_MO.. "' " -- N_BS_ROW_MO = '" ..item.N_BS_ROW_NO.. "' and 
        local nRetl, strRetInfo = mobox.existThisData(strLuaDEID, "Outbound_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)
        end
        local item_area_code = itemAttrs.udf01
        
        if (item_area_code == '' or item_area_code == nil) then
            table.insert(err, "该物料库区值不存在:" .. item.S_ITEM_CODE)
        end
        
    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
 
    -- 所有通过,开始创建明细
    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.Warning( strLuaDEID, debug.getinfo(1), "查询物料表失败: "..item.S_ITEM_CODE )
        end
        local item_area_code = itemAttrs.udf01
        
        
        local cond_item = "S_BS_NO = '"..s_no.."' AND S_AREA_CODE = '" ..item_area_code.. "' "
        local nRet, inbound_order = m3.GetDataObjByCondition(strLuaDEID, "Outbound_Order", cond_item)
        if (nRet ~= 0 or not inbound_order) then
            lua.Warning( strLuaDEID, debug.getinfo(1), "查询失败: "..item.S_ITEM_CODE )
        else
            local detail = m3.AllocObject(strLuaDEID, "Outbound_Detail")
            detail.oo_no = inbound_order.no
            detail.qty = item.F_QTY
            detail.bs_no = item.S_BS_NO
            detail.bs_row_no = item.N_BS_ROW_MO
            detail.item_code = item.S_ITEM_CODE
 
            detail.item_state = item.S_ITEM_STATE
            detail.supplier = item.S_SUPPLIER_NO 
            detail.supplier_name = item.S_SUPPLIER_NAME 
            detail.item_name = itemAttrs.item_name
            
            detail.sour_no = inputData.SourceKey 
            
            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
    
            local ret5, msg5 = m3.CreateDataObj(strLuaDEID, detail)
            lua.Debug(strLuaDEID, debug.getinfo(1), 'detail', detail)
            if ret5 ~= 0 then
                lua.Stop(strLuaDEID, "创建出库单明细失败:" .. msg5)
                return
            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