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
--[[
 编码: 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")
m3 = require("oi_base_mobox")
 
-- 创建统一返回结果
function Create_result(flag, code, msg, error)
    return {
        flag = flag or "success",
        code = code or "0",
        message = msg or "",
        error = error or ""
    }
end
 
function Receipt_Sync(strLuaDEID)
    -- 1. 获取 xml 数据包
    local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID)
    if nRet ~= 0 then
        FinalRes = Create_result("failure", "201", "无法获取数据包: " .. soap_xml)
        lua.Stop(strLuaDEID, "获取数据包失败", FinalRes)
 
    end
 
    -- 2. 解析 xml
    local nRet, parsed_data = xml.parse(soap_xml)
    if nRet ~= 0 then
        FinalRes = Create_result("failure", "202", "xml 格式非法")
        lua.Stop(strLuaDEID, "xml格式非法", FinalRes)
 
    end
 
    -- 3. 提取主表数据
    local receipt_data = parsed_data.Envelope.Body.InSmallPieceReq.SmallPiece_Input
    local input_params = receipt_data.InputParameters
 
    -- 检查是否存在 SmallPiece_TB
    if not input_params or not input_params.SmallPiece_TB then
        FinalRes = Create_result("failure", "203", "xml 数据格式错误,缺少 SmallPiece_TB")
        lua.Stop(strLuaDEID, "xml 数据格式错误", FinalRes)
        return
    end
 
    -- 4. 统一处理:确保 receipt_headers 是数组(即使只有一个主表)
    local receipt_headers = input_params.SmallPiece_TB
    if receipt_headers[1] == nil then
        receipt_headers = {receipt_headers}
    end
 
    -- 5. 获取系统常量
    local RetWH_COE, CONST_WH = wms_base.Get_sConst2(strLuaDEID, "GK_Default_Warehouse")
    local RetFAC_COE, CONST_FACTORY = wms_base.Get_sConst2(strLuaDEID, "GK_Default_Factory")
    if (RetWH_COE ~= 0 or RetFAC_COE ~= 0) then
        FinalRes = Create_result("failure", "204", "获取仓库/工厂常量失败")
        lua.Stop(strLuaDEID, "获取系统常量失败", FinalRes)
        return 
    end
 
    -- 6. 遍历所有收货单
    local result = Create_result()
    for i = 1, #receipt_headers do
        local header = receipt_headers[i]
 
        -- 检查收货单是否已存在
        local strCondition = string.format("S_NO = '%s'", header.orderNo)
        lua.DebugEx(strLuaDEID, "SQL 条件", strCondition)
        local nRet, strRetInfo = mobox.getDataObjAttrByKeyAttr(strLuaDEID, "Receipt_Order", strCondition)
        if nRet == 0 then
            FinalRes = Create_result("failure", "205", "收货单已存在",
                "收货单[" .. header.orderNo .. "]已存在")
            lua.Stop(strLuaDEID, "收货单已存在", FinalRes)
 
        elseif nRet > 1 then
            FinalRes = Create_result("failure", "206", "系统错误",
                "检查收货单是否存在时出错: " .. strRetInfo)
            lua.Stop(strLuaDEID, "检查收货单是否存在时出错", FinalRes)
 
        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
        lua.DebugEx(strLuaDEID, "创建的表单:", receipt);
        local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt)
        if nRet ~= 0 then
            FinalRes = Create_result("failure", "207", "创建收货单主表失败",
                "收货单[" .. header.orderNo .. "]创建失败: " .. ret_info)
            lua.Stop(strLuaDEID, "创建收货单主表失败", FinalRes)
 
        end
 
        -- 检查明细数据是否存在
        if not header.SmallPiece_TB_ITEM then
            lua.DebugEx(strLuaDEID, "警告:收货单 " .. header.orderNo .. " 无明细数据")
        else
            -- 7. 遍历当前收货单的所有明细数据
            local details = header.SmallPiece_TB_ITEM
            -- 确保 details 是数组(即使只有一个明细)
            if details[1] == nil then
                details = {details}
            end
 
            for j = 1, #details do
                local item = details[j]
                -- 创建明细数据
                local receipt_detail = m3.AllocObject(strLuaDEID, "Receipt_Detail")
                receipt_detail.row_no = item.orderItemId
                receipt_detail.receipt_no = header.orderNo
                receipt_detail.qty = lua.Get_NumAttrValue(item.qty) or 0
                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 = item.skuId
                receipt_detail.item_state = item.skuStatus
                receipt_detail.wu = "kg"
                receipt_detail.batch_no = item.produceCode
                receipt_detail.prd_date = item.productDate
                receipt_detail.exp_date = item.expiryDate
                receipt_detail.udf01 = item.registerNo
                receipt_detail.storer = header.storerId
                receipt_detail.owner = header.ownerId
 
                -- 获取物料信息
                if item.skuId ~= nil then
                    local nRet, mat_info = m3.GetDataObjByCondition(strLuaDEID, "Material",
                        "S_ITEM_CODE='" .. item.skuId .. "'")
                    if nRet == 0 then
                        receipt_detail.item_name = mat_info.item_name or ""
                        receipt_detail.net_weight = mat_info.weight or 0
                        receipt_detail.gross_weight = mat_info.weight or 0
                        receipt_detail.uom = mat_info.uom or ""
                    end
                end
 
                local nRet, ret_info = m3.CreateDataObj(strLuaDEID, receipt_detail)
                if nRet ~= 0 then
                    FinalRes = Create_result("failure", "208", "创建收货明细失败",
                        "行号[" .. item.orderItemId .. "]创建失败: " .. ret_info)
                    lua.Stop(strLuaDEID, "创建收货明细失败", FinalRes)
 
                end
            end
        end
    end
 
    -- 8. 返回成功
    -- FinalRes = Create_result("success", "0", "收货单创建成功")
    local xml_result = xml.json_to_xml(FinalRes, "response")
    mobox.returnValue(strLuaDEID, 0, xml_result, 0)
end