fy36
2025-07-01 350eb5ec9163d3ea21416b1525bb80191e958071
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
--[[
 编码: GK-API-04
 名称: GK-WMS-Receipt_Sync
 作者: 袁峰
 入口函数:Receipt_Sync
 功能说明: 接收上游系统的XML数据,创建收货单主表(Receipt_Order)和明细记录(Receipt_Detail)。
 输入参数: xmlData(XML格式的字符串)
 返回参数: xml 格式的响应报文:
 形如:
 <response>
    <message>收货单已存在</message>
    <code>204</code>
    <flag>failure</flag>
    <error>收货单[SO2025050701]已存在</error>
 </response>
 调用示例: Receipt_Sync(xmlData)
 注意事项: 1. 输入参数xmlData为XML格式的字符串,包含了收货单主表和明细记录的数据。
          2. 函数会解析XML数据,并将其插入到数据库中。
          3. 允许xml 传入1条或者多条收货单主表数据,每条收货单主表数据可以包含多条收货
          单明细数据。
 
 变更历史: 2025-05-14 优化返回结果处理
 XML 报文示例如下;
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    </soap:Header>
    <soapenv:Body>
        <v1:InSmallPieceReq xmlns:v1="http://www.gkht.com/InReceive/INV/Ebs/Schemas/InSmallPiece/V1.0">
            <v1:SmallPiece_Input>
                <v1:RESTHeader>
                    <v1:Responsibility/>
                    <v1:RespApplication/>
                    <v1:SecurityGroup/>
                    <v1:NLSLanguage>SIMPLIFIED CHINESE</v1:NLSLanguage>
                    <v1:Org_Id>0</v1:Org_Id>
                </v1:RESTHeader>
                <v1:InputParameters>
                    <!-- 第一个收货单 -->
                    <v1:SmallPiece_TB>
                        <v1:orderNo>SO2025050701</v1:orderNo>
                        <v1:asnNo>KPD00002</v1:asnNo>
                        <v1:storerId>CGKHTY</v1:storerId>
                        <v1:ownerId>CGKHTY</v1:ownerId>
                        <v1:orderDate>2025-05-07</v1:orderDate>
                        <v1:priority>0</v1:priority>
                        <v1:memo>收货单1备注</v1:memo>
                        <v1:SmallPiece_TB_ITEM>
                            <v1:orderItemId>1</v1:orderItemId>
                            <v1:skuId>100118100</v1:skuId>
                            <v1:skuStatus>AVL</v1:skuStatus>
                            <v1:qty>3</v1:qty>
                            <v1:batchNo>PHI00000000000001310</v1:batchNo>
                            <v1:produceCode>YL201126</v1:produceCode>
                            <v1:productDate>2016-05-23</v1:productDate>
                            <v1:expiryDate>2099-12-31</v1:expiryDate>
                            <v1:registerNo>国食药监械(准)字2013</v1:registerNo>
                        </v1:SmallPiece_TB_ITEM>
                        <v1:SmallPiece_TB_ITEM>
                            <v1:orderItemId>2</v1:orderItemId>
                            <v1:skuId>100117231</v1:skuId>
                            <v1:skuStatus>AVL</v1:skuStatus>
                            <v1:qty>4</v1:qty>
                            <v1:batchNo>PHI00000000000001311</v1:batchNo>
                            <v1:produceCode>YL201127</v1:produceCode>
                            <v1:productDate>2023-05-23</v1:productDate>
                            <v1:expiryDate>2099-12-31</v1:expiryDate>
                            <v1:registerNo></v1:registerNo>
                        </v1:SmallPiece_TB_ITEM>
                    </v1:SmallPiece_TB>
                    <!-- 第二个收货单 -->
                    <v1:SmallPiece_TB>
                        <v1:orderNo>SO2025050702</v1:orderNo>
                        <v1:asnNo>KPD00003</v1:asnNo>
                        <v1:storerId>CGKHTY</v1:storerId>
                        <v1:ownerId>CGKHTY</v1:ownerId>
                        <v1:orderDate>2025-05-07</v1:orderDate>
                        <v1:priority>1</v1:priority>
                        <v1:memo>收货单2备注</v1:memo>
                        <v1:SmallPiece_TB_ITEM>
                            <v1:orderItemId>1</v1:orderItemId>
                            <v1:skuId>200000002</v1:skuId>
                            <v1:skuStatus>AVL</v1:skuStatus>
                            <v1:qty>2</v1:qty>
                            <v1:batchNo>PHI00000000000001312</v1:batchNo>
                            <v1:produceCode>YL201128</v1:produceCode>
                            <v1:productDate>2016-06-23</v1:productDate>
                            <v1:expiryDate>2099-12-31</v1:expiryDate>
                            <v1:registerNo>国食药监械(准)字2014</v1:registerNo>
                        </v1:SmallPiece_TB_ITEM>
                        <v1:SmallPiece_TB_ITEM>
                            <v1:orderItemId>2</v1:orderItemId>
                            <v1:skuId>100117238</v1:skuId>
                            <v1:skuStatus>AVL</v1:skuStatus>
                            <v1:qty>5</v1:qty>
                            <v1:batchNo>PHI00000000000001313</v1:batchNo>
                            <v1:produceCode>YL201129</v1:produceCode>
                            <v1:productDate>2023-06-23</v1:productDate>
                            <v1:expiryDate>2099-12-31</v1:expiryDate>
                            <v1:registerNo></v1:registerNo>
                        </v1:SmallPiece_TB_ITEM>
                    </v1:SmallPiece_TB>
                </v1:InputParameters>
            </v1:SmallPiece_Input>
        </v1:InSmallPieceReq>
    </soapenv:Body>
</soapenv:Envelope>
--]]
 
wms_base = require("wms_base")
xml = require("oi_base_xml")
mobox = require("OILua_JavelinExt")
 
 
-- 创建统一返回结果
local function create_result(flag, code, msg, error)
    return {
        flag = flag or "success",
        code = code or "0",
        message = msg or "",
        error = error or ""
    }
end
 
-- 创建收货单明细对象
local function create_receipt_detail(strLuaDEID, detail_item, no, header)
    local result = create_result()
    local receipt_detail = m3.AllocObject(strLuaDEID, "Receipt_Detail")
 
    -- 基本关联信息
    receipt_detail.row_no = detail_item.orderItemId
    receipt_detail.receipt_no = no
 
    -- 物料信息查询
    local material_info
    if detail_item.skuId ~= nil then
        local nRet, mat_info = m3.GetDataObjByCondition(strLuaDEID, "Material",
            "S_ITEM_CODE='" .. detail_item.skuId .. "'")
 
        if nRet ~= 0 then
            result.flag = "failure"
            result.code = "101"
            result.message = "物料数据获取失败"
            result.error = "物料[" .. detail_item.skuId .. "]查询失败: " .. mat_info
            return result
        else
            material_info = mat_info
        end
    end
 
    -- 数量相关字段
    receipt_detail.qty = lua.Get_NumAttrValue(detail_item.qty)
    receipt_detail.acc_put_qty = lua.Get_NumAttrValue("0")
    receipt_detail.acc_unq_qty = lua.Get_NumAttrValue("0")
    receipt_detail.acc_c_qty = lua.Get_NumAttrValue("0")
 
    receipt_detail.item_code = detail_item.skuId
    receipt_detail.item_state = detail_item.skuStatus
    receipt_detail.wu = "kg"
 
    -- 从物料信息获取的字段
    receipt_detail.item_name = material_info and material_info.item_name or ""
    receipt_detail.net_weight = material_info and material_info.weight or 0
    receipt_detail.gross_weight = material_info and material_info.weight or 0
    receipt_detail.uom = material_info and material_info.uom or ""
 
    -- 批次及日期信息
    receipt_detail.batch_no = detail_item.produceCode
    receipt_detail.prd_date = detail_item.productDate
    receipt_detail.exp_date = detail_item.expiryDate
 
    -- 其他业务字段
    receipt_detail.udf01 = detail_item.registerNo
    receipt_detail.storer = header.storerId
    receipt_detail.owner = header.ownerId
 
    local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt_detail)
    if nRet ~= 0 then
        result.flag = "failure"
        result.code = "102"
        result.message = "创建收货明细失败"
        result.error = "行号[" .. detail_item.orderItemId .. "]创建失败: " .. ret_info
    end
 
    return result
end
 
-- 处理单个收货单
local function process_receipt(strLuaDEID, header, CONST_FACTORY, CONST_WH, final_result)
    -- 检查收货单是否已存在
    local strCondition = string.format("S_NO = '%s'", header.orderNo)
    local nRet, id, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "Receipt_Order", strCondition)
 
    if nRet == 0 then
        final_result.flag = "failure"
        final_result.code = "204"
        final_result.message = "收货单已存在"
        final_result.error = "收货单[" .. header.orderNo .. "]已存在"
        return false
    elseif nRet > 1 then
        final_result.flag = "failure"
        final_result.code = "205"
        final_result.message = "系统错误"
        final_result.error = "检查收货单是否存在时出错: " .. strRetInfo
        return false
    end
 
    -- 创建主表记录
    local receipt = m3.AllocObject(strLuaDEID, "Receipt_Order")
    receipt.no = header.orderNo
    receipt.asn_no = header.asnNo
    receipt.op_date = header.orderDate
    receipt.priority = header.priority
    receipt.note = header.memo or ""
    receipt.bs_type = "SMALL_PIECE"
    receipt.factory = CONST_FACTORY
    receipt.wh_code = CONST_WH
 
    local nRet, result = m3.CreateDataObj(strLuaDEID, receipt)
    if nRet ~= 0 then
        final_result.flag = "failure"
        final_result.code = "206"
        final_result.message = "创建收货单失败"
        final_result.error = "创建收货单[" .. header.orderNo .. "]失败: " .. result
        return false
    end
 
    -- 处理明细数据
    local detail_items = header.SmallPiece_TB_ITEM
    if not detail_items then
        final_result.flag = "failure"
        final_result.code = "207"
        final_result.message = "缺少明细数据"
        final_result.error = "收货单[" .. header.orderNo .. "]缺少明细数据"
        return false
    end
 
    -- 判断是单个明细还是多个明细
    if detail_items.orderItemId then -- 如果是单个明细
        detail_items = {detail_items} -- 转为单元素数组
    end
 
    for _, detail_item in ipairs(detail_items) do
        local detail_result = create_receipt_detail(strLuaDEID, detail_item, receipt.no, header)
        if detail_result.flag == "failure" then
            final_result.flag = "failure"
            final_result.code = detail_result.code or "208"
            final_result.message = detail_result.message or "创建明细失败"
            final_result.error = detail_result.error or "创建明细失败"
            return false
        end
    end
 
    return true
end
 
function Receipt_Sync(strLuaDEID)
    local final_result = create_result()
    local is_stop = 0 -- 0:正常 3:需要回滚
 
    -- 1. 获取并解析XML
    local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID)
    if nRet ~= 0 then
        final_result = create_result("failure", "201", "无法获取数据包: " .. soap_xml)
        is_stop = 3
    else
        local nRet, parsed_data = xml.parse(soap_xml)
        if nRet ~= 0 then
            final_result = create_result("failure", "202", "XML格式非法")
            is_stop = 3
        else
            -- 2. 解析XML数据结构
            local receipt_data = parsed_data.Envelope.Body.InSmallPieceReq.SmallPiece_Input
            local input_params = receipt_data.InputParameters
 
            -- 判断是单个收货单还是多个收货单
            local receipt_headers = input_params.SmallPiece_TB
            if receipt_headers.orderNo then -- 如果是单个收货单
                receipt_headers = {receipt_headers} -- 转为单元素数组
            end
 
            -- 3. 获取常量
            local nRet1, CONST_FACTORY = wms_base.Get_sConst2(strLuaDEID, "GK_Default_Factory")
            local nRet2, CONST_WH = wms_base.Get_sConst2(strLuaDEID, "GK_Default_Warehouse")
            if nRet1 ~= 0 or nRet2 ~= 0 then
                final_result = create_result("failure", "203", "获取系统常量失败")
                is_stop = 3
            else
                -- 4. 处理每个收货单
                for _, header in ipairs(receipt_headers) do
                    if not process_receipt(strLuaDEID, header, CONST_FACTORY, CONST_WH, final_result) then
                        is_stop = 3
                        break
                    end
                end
            end
        end
    end
    -- 返回处理结果
    if final_result.flag == "success" then
        final_result.message = "收货单创建成功"
    end
    -- 转换为XML格式返回
    local xml_result = xml.json_to_xml(final_result, "response")
 
    lua.DebugEx(strLuaDEID, "final_result:", final_result);
    lua.DebugEx(strLuaDEID, "xml_result:", xml_result);
    -- 一律按照默认为0的 is_stop 来处理
    mobox.returnValue(strLuaDEID, 0, xml_result, 0)
end