OUTConfirm.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. package com.uas.eis.entity.vwms.req;
  2. import com.fasterxml.jackson.annotation.JsonProperty;
  3. import com.uas.eis.utils.StringUtil;
  4. import lombok.Data;
  5. import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. @Data
  9. @JsonIgnoreProperties(ignoreUnknown = true)
  10. public class OUTConfirm {
  11. private DeliveryOrder deliveryOrder;
  12. private Packages packages;
  13. private OrderLines orderLines;
  14. private OrderDetails orderDetails;
  15. @Data
  16. @JsonIgnoreProperties(ignoreUnknown = true)
  17. public static class DeliveryOrder {
  18. /** 出库单号 长度:50 */
  19. private String deliveryOrderCode;
  20. /** 仓储系统出库单号 长度:50 条件必填 */
  21. private String deliveryOrderId;
  22. /** 仓库代码 长度:50 */
  23. private String warehouseCode;
  24. /** 货主代码 长度:50 */
  25. private String ownerCode;
  26. /** 出库单类型 长度:50 例如: XSDD=销售订单, DBCK=调拨出库、CGTH=采购退货, QTCK=其他出库 */
  27. private String orderType;
  28. /** 出库单状态 长度:50 NEW-未开始处理, ACCEPT=仓库接单, PARTDELIVERED=部分发货完成, DELIVERED=发货完成, CANCELED=取消, CLOSED=关闭, CANCELEDFAIL=取消失败(只传英文编码) */
  29. private String status;
  30. /** 外部业务编码 长度:50 消息ID, 用于去重, 因为网络等原因导致重复传输, 请求不会被重复处理 */
  31. private String outBizCode;
  32. /** 支持出库单多次发货 多次发货确认时 0=发货单最终状态确认: 1=发货单中间状态确认 */
  33. private String confirmType;
  34. /** 物流公司编码 长度:50 SF=顺丰、EMS=标准快递、EYB=经济快件、ZJS=宅急送、YTO=圆通、ZTO=中通、HTKY=百世汇通、UC=优速、STO=申通、TTKDEX=天天快递、QFKD=全峰、FAST=快捷、POSTB=邮政小包、GTO=国通、YUNDA=韵达、JD=京东配送、DD=当当宅配、AMAZON=亚马逊物流、OTHER=其他(只传英文编码) */
  35. private String logisticsCode;
  36. /** 运单号 长度:50 */
  37. private String expressCode;
  38. /** 制单人 长度:50 */
  39. private String documentMaker;
  40. /** 发货人 长度:50 */
  41. private String shipper;
  42. /** 收货人 长度:50 */
  43. private String receiverName;
  44. /** 订单发运时间 长度:19 YYYY-MM-DD HH:MM:SS */
  45. private String deliveryTime;
  46. /** 用户自定义1 长度:50 */
  47. private String userDefined1;
  48. /** 用户自定义2 长度:50 */
  49. private String userDefined2;
  50. /** 用户自定义3 长度:50 */
  51. private String userDefined3;
  52. /** 用户自定义4 长度:50 */
  53. private String userDefined4;
  54. /** 客户 长度:50 */
  55. private String customer;
  56. /** 序列号 长度:50 */
  57. private String serialNos;
  58. /** 序列号数量 长度:50 */
  59. private String serialNoQty;
  60. /** 订单来源平台代码 长度:50 */
  61. private String sourcePlatformCode;
  62. /** 备注 长度:100 */
  63. private String remark;
  64. /** 文件信息 */
  65. private Files files;
  66. }
  67. @Data
  68. @JsonIgnoreProperties(ignoreUnknown = true)
  69. public static class Files {
  70. private List<File> file;
  71. @Data
  72. @JsonIgnoreProperties(ignoreUnknown = true)
  73. public static class File {
  74. /** 文件url,仅出库单关闭状态时回传,文件url有效时间24小时内*/
  75. private String url;
  76. }
  77. }
  78. @Data
  79. @JsonIgnoreProperties(ignoreUnknown = true)
  80. public static class Packages {
  81. @JsonProperty("package")
  82. // private List<Pkg> pkg;
  83. private Pkg pkg;
  84. @Data
  85. @JsonIgnoreProperties(ignoreUnknown = true)
  86. public static class Pkg {
  87. /** 物流公司编码 长度:50 SF=顺丰、EMS=标准快递、EYB=经济快件、ZJS=宅急送、YTO=圆通、ZTO=中通、HTKY=百世汇通、UC=优速、STO=申通、TTKDEX=天天快递、QFKD=全峰、FAST=快捷、POSTB=邮政小包、GTO=国通、YUNDA=韵达、JD=京东配送、DD=当当宅配、AMAZON=亚马逊物流、OTHER=其他(只传英文编码) */
  88. private String logisticsCode;
  89. /** 运单号 长度:50 */
  90. private String expressCode;
  91. /** 箱号 长度:50 */
  92. private String packageCode;
  93. /** 商品信息 */
  94. private Items items;
  95. /** 耗材信息 */
  96. private ConsumableDetails consumableDetails;
  97. /** 箱重量 类型:double(18,3) */
  98. private Double weight;
  99. /** 箱体积 类型:double(18,3) */
  100. private Double volume;
  101. /** 耗材体积 类型:double(18,3) */
  102. private Double consumableVolume;
  103. /** 耗材代码 长度:50 */
  104. private String consumableCode;
  105. /** 货品体积 double (18,3)*/
  106. private String productVolume;
  107. /** 货品重量 */
  108. private String productWeight;
  109. /** 箱自定义1 */
  110. private String userDefined1;
  111. /** 箱自定义2 */
  112. private String userDefined2;
  113. /** 箱自定义3 */
  114. private String userDefined3;
  115. /** 箱自定义4 */
  116. private String userDefined4;
  117. }
  118. }
  119. @Data
  120. @JsonIgnoreProperties(ignoreUnknown = true)
  121. public static class Items {
  122. private List<Item> item;
  123. @Data
  124. @JsonIgnoreProperties(ignoreUnknown = true)
  125. public static class Item {
  126. /** 货品代码 */
  127. private String itemCode;
  128. /** 箱内该货品的数量 */
  129. private String quantity;
  130. }
  131. }
  132. @Data
  133. @JsonIgnoreProperties(ignoreUnknown = true)
  134. public static class ConsumableDetails {
  135. private List<ConsumableDetail> consumableDetail;
  136. @Data
  137. @JsonIgnoreProperties(ignoreUnknown = true)
  138. public static class ConsumableDetail {
  139. /** 耗材代码 */
  140. private String consumableCode;
  141. /** 箱内该耗材的数量 */
  142. private String quantity;
  143. }
  144. }
  145. @Data
  146. @JsonIgnoreProperties(ignoreUnknown = true)
  147. public static class OrderLines {
  148. private List<OrderLine> orderLine;
  149. @Data
  150. @JsonIgnoreProperties(ignoreUnknown = true)
  151. public static class OrderLine {
  152. /** 行号 */
  153. private Integer lineNo;
  154. /** 货品代码 长度:50 */
  155. private String itemCode;
  156. /** 包装单位 长度:50 */
  157. private String packUom;
  158. /** 预期货品数量 类型:float */
  159. private Float planQty;
  160. /** 实发货品数量 类型:float */
  161. private Float actualQty;
  162. /** 实发包装数量 类型:float */
  163. private Float actualPackUomQty;
  164. /** 质量状态 长度:50 ZP=正品, CC=残次, 默认为ZP */
  165. private String inventoryType;
  166. /** 序列号,多个序列号用英文逗号隔开 长度:500 */
  167. private String serialNo;
  168. /** 自定义字段1 长度:50 */
  169. private String customField1;
  170. /** 自定义字段2 长度:50 */
  171. private String customField2;
  172. /** 自定义字段3 长度:50 */
  173. private String customField3;
  174. /** 自定义字段4 长度:50 */
  175. private String customField4;
  176. /** 自定义字段5 长度:50 */
  177. private String customField5;
  178. /** 自定义字段6 长度:50 */
  179. private String customField6;
  180. /** 自定义字段7 长度:50 */
  181. private String customField7;
  182. /** 自定义字段8 长度:50 */
  183. private String customField8;
  184. /** 批次信息 */
  185. private Batchs batchs;
  186. @Data
  187. @JsonIgnoreProperties(ignoreUnknown = true)
  188. public static class Batchs {
  189. private List<Batch> batch;
  190. @Data
  191. @JsonIgnoreProperties(ignoreUnknown = true)
  192. public static class Batch {
  193. /** 实发货品数量 类型:float */
  194. private Float actualQty;
  195. /** 实收包装数量 类型:float */
  196. private Float actualPackUomQty;
  197. /** 库存类型 长度:50 ZP=正品, CC=残次, 默认ZP */
  198. private String inventoryType;
  199. /** 虚拟仓库 长度:50 条件必填, 条件为使用虚拟仓库 */
  200. private String virtualWarehouse;
  201. /** 生产日期 长度:10 YYYY-MM-DD */
  202. private String productDate;
  203. /** 失效日期 长度:10 YYYY-MM-DD */
  204. private String expireDate;
  205. /** 批次号 长度:50 */
  206. private String batchCode;
  207. /** 入库日期 长度:10 YYYY-MM-DD */
  208. private String stockinDate;
  209. /** 自定义批次1 长度:50 */
  210. private String userDefined1;
  211. /** 自定义批次2 长度:50 */
  212. private String userDefined2;
  213. /** 自定义批次3 长度:50 */
  214. private String userDefined3;
  215. /** 自定义批次4 长度:50 */
  216. private String userDefined4;
  217. /** 拣货容器号 长度:50 */
  218. private String lpn;
  219. }
  220. }
  221. }
  222. }
  223. @Data
  224. @JsonIgnoreProperties(ignoreUnknown = true)
  225. public static class OrderDetails {
  226. private List<Detail> detail;
  227. @Data
  228. @JsonIgnoreProperties(ignoreUnknown = true)
  229. public static class Detail {
  230. /** 容器号 */
  231. private String boxNo;
  232. /** epc码 RFID场景适用 */
  233. private String epc;
  234. }
  235. }
  236. public String getMasterName() {
  237. if (orderLines.getOrderLine() != null) {//账套名称
  238. return orderLines.getOrderLine().get(0).getBatchs().getBatch().get(0).getUserDefined4();
  239. } else {
  240. return null;
  241. }
  242. }
  243. public String getGenerateMainSql() {
  244. StringBuilder sql = new StringBuilder("MERGE INTO @MASTERCODE.prodiowms wmsl USING (")
  245. .append("SELECT ")
  246. .append("@PIID").append(" PIID, ")
  247. .append("'").append("@INOUTNO").append("' PIINOUTNO, ")
  248. .append("'").append(StringUtil.nvl(deliveryOrder.getDeliveryOrderCode(), "")).append("' ORDERCODE, ")
  249. .append("'").append(StringUtil.nvl(deliveryOrder.getOwnerCode(), "")).append("' OWNERCODE, ")
  250. .append("'").append(StringUtil.nvl(deliveryOrder.getWarehouseCode(), "")).append("' WAREHOUSECODE, ")
  251. .append("'").append(StringUtil.nvl(deliveryOrder.getDeliveryOrderId(), "")).append("' WMSORDERID, ")
  252. .append("'").append(StringUtil.nvl(deliveryOrder.getOrderType(), "")).append("' WMSORDERTYPE, ")
  253. .append("'").append(StringUtil.nvl(deliveryOrder.getOutBizCode(), "")).append("' OUTBIZCODE, ")
  254. .append(StringUtil.nvl(deliveryOrder.getConfirmType(), "0")).append(" CONFIRMTYPE, ")
  255. .append("'").append(StringUtil.nvl(deliveryOrder.getStatus(), "")).append("' STATUS, ")
  256. .append((StringUtil.hasText(deliveryOrder.getDeliveryTime()) ? "to_date('" + deliveryOrder.getDeliveryTime() + "','yyyy-mm-dd hh24:mi:ss')" : "null")).append(" deliveryTime, ")
  257. .append("'").append(StringUtil.nvl(deliveryOrder.getShipper(), "")).append("' shipper, ")
  258. .append("'").append(StringUtil.nvl(deliveryOrder.getRemark(), "")).append("' REMARK, ")
  259. .append("'").append(StringUtil.nvl(deliveryOrder.getUserDefined1(), "")).append("' USERDEFINED1, ")
  260. .append("'").append(StringUtil.nvl(deliveryOrder.getUserDefined2(), "")).append("' USERDEFINED2, ")
  261. .append("'").append(StringUtil.nvl(deliveryOrder.getUserDefined3(), "")).append("' USERDEFINED3, ")
  262. .append("'").append(StringUtil.nvl(deliveryOrder.getUserDefined4(), "")).append("' USERDEFINED4 ")
  263. .append("FROM dual) doc ON (wmsl.PIID = doc.PIID AND wmsl.PIINOUTNO = doc.PIINOUTNO) ")
  264. .append("WHEN MATCHED THEN UPDATE SET ")
  265. .append("wmsl.ORDERCODE = doc.ORDERCODE, ")
  266. .append("wmsl.OWNERCODE = doc.OWNERCODE, ")
  267. .append("wmsl.WAREHOUSECODE = doc.WAREHOUSECODE, ")
  268. .append("wmsl.WMSORDERID = doc.WMSORDERID, ")
  269. .append("wmsl.WMSORDERTYPE = doc.WMSORDERTYPE, ")
  270. .append("wmsl.OUTBIZCODE = doc.OUTBIZCODE, ")
  271. .append("wmsl.CONFIRMTYPE = doc.CONFIRMTYPE, ")
  272. .append("wmsl.STATUS = doc.STATUS, ")
  273. .append("wmsl.deliveryTime = doc.deliveryTime, ")
  274. .append("wmsl.shipper = doc.shipper, ")
  275. .append("wmsl.REMARK = doc.REMARK, ")
  276. .append("wmsl.USERDEFINED1 = doc.USERDEFINED1, ")
  277. .append("wmsl.USERDEFINED2 = doc.USERDEFINED2, ")
  278. .append("wmsl.USERDEFINED3 = doc.USERDEFINED3, ")
  279. .append("wmsl.USERDEFINED4 = doc.USERDEFINED4, ")
  280. .append("wmsl.UTIME = SYSDATE ")
  281. .append("WHEN NOT MATCHED THEN INSERT (ITIME,PIID, PIINOUTNO, ORDERCODE, OWNERCODE, WAREHOUSECODE, WMSORDERID, WMSORDERTYPE, OUTBIZCODE, CONFIRMTYPE, STATUS, deliveryTime, shipper, REMARK, USERDEFINED1, USERDEFINED2, USERDEFINED3, USERDEFINED4) ")
  282. .append("VALUES (SYSDATE,doc.PIID, doc.PIINOUTNO, doc.ORDERCODE, doc.OWNERCODE, doc.WAREHOUSECODE, doc.WMSORDERID, doc.WMSORDERTYPE, doc.OUTBIZCODE, doc.CONFIRMTYPE, doc.STATUS, doc.deliveryTime, doc.shipper, doc.REMARK, doc.USERDEFINED1, doc.USERDEFINED2, doc.USERDEFINED3, doc.USERDEFINED4)");
  283. return sql.toString();
  284. }
  285. public List<String> getGenerateLinesSql() {
  286. List<String> sqls = new ArrayList<>();
  287. for (OUTConfirm.OrderLines.OrderLine line : orderLines.getOrderLine()) {
  288. sqls.add(getGenerateLinesSql(line));
  289. for (int i = 0; i < line.getBatchs().getBatch().size(); i++) {
  290. OUTConfirm.OrderLines.OrderLine.Batchs.Batch batch = line.getBatchs().getBatch().get(i);
  291. sqls.add(getGenerateBatchsSql(line,line.getLineNo(), (i + 1), batch));
  292. }
  293. }
  294. return sqls;
  295. }
  296. public String getGenerateLinesSql(OUTConfirm.OrderLines.OrderLine line) {
  297. StringBuilder sql = new StringBuilder();
  298. sql.append("MERGE INTO ").append("@MASTERCODE").append(".prodiowms_Lines wmsl USING (")
  299. .append("SELECT ")
  300. .append("@PIID").append(" PIID, ")
  301. .append(line.getLineNo()).append(" LINENO, ")
  302. .append("'").append(line.getItemCode()).append("' ITEMCODE, ")
  303. .append("'").append(StringUtil.nvl(line.getPlanQty(), "")).append("' PLANQTY, ")
  304. .append(StringUtil.nvl(line.getActualQty(), "0")).append(" ACTUALQTY, ")
  305. .append(StringUtil.nvl(line.getActualPackUomQty(), "0")).append(" ACTUALPACKUOMQTY, ")
  306. .append("'").append(StringUtil.nvl(line.getSerialNo(), "")).append("' SERIALNO, ")
  307. .append("'").append(StringUtil.nvl(line.getCustomField1(), "")).append("' CUSTOMFIELD1, ")
  308. .append("'").append(StringUtil.nvl(line.getCustomField2(), "")).append("' CUSTOMFIELD2, ")
  309. .append("'").append(StringUtil.nvl(line.getCustomField3(), "")).append("' CUSTOMFIELD3, ")
  310. .append("'").append(StringUtil.nvl(line.getCustomField4(), "")).append("' CUSTOMFIELD4, ")
  311. .append("'").append(StringUtil.nvl(line.getCustomField5(), "")).append("' CUSTOMFIELD5, ")
  312. .append("'").append(StringUtil.nvl(line.getCustomField6(), "")).append("' CUSTOMFIELD6, ")
  313. .append("'").append(StringUtil.nvl(line.getCustomField7(), "")).append("' CUSTOMFIELD7, ")
  314. .append("'").append(StringUtil.nvl(line.getCustomField8(), "")).append("' CUSTOMFIELD8 ")
  315. .append("FROM dual) doc ON (wmsl.PL_PIID = doc.PIID AND wmsl.LINENO = doc.LINENO AND wmsl.ITEMCODE = doc.ITEMCODE) ")
  316. .append("WHEN MATCHED THEN UPDATE SET ")
  317. .append("wmsl.ACTUALQTY = doc.ACTUALQTY, ")
  318. .append("wmsl.ACTUALPACKUOMQTY = doc.ACTUALPACKUOMQTY, ")
  319. .append("wmsl.SERIALNO = doc.SERIALNO, ")
  320. .append("wmsl.CUSTOMFIELD1 = doc.CUSTOMFIELD1, ")
  321. .append("wmsl.CUSTOMFIELD2 = doc.CUSTOMFIELD2, ")
  322. .append("wmsl.CUSTOMFIELD3 = doc.CUSTOMFIELD3, ")
  323. .append("wmsl.CUSTOMFIELD4 = doc.CUSTOMFIELD4, ")
  324. .append("wmsl.CUSTOMFIELD5 = doc.CUSTOMFIELD5, ")
  325. .append("wmsl.CUSTOMFIELD6 = doc.CUSTOMFIELD6, ")
  326. .append("wmsl.CUSTOMFIELD7 = doc.CUSTOMFIELD7, ")
  327. .append("wmsl.CUSTOMFIELD8 = doc.CUSTOMFIELD8, ")
  328. .append("wmsl.UTIME = SYSDATE ")
  329. .append("WHEN NOT MATCHED THEN INSERT (ITIME,PL_PIID, LINENO, ITEMCODE, PLANQTY, ACTUALQTY, ACTUALPACKUOMQTY, SERIALNO, ")
  330. .append("CUSTOMFIELD1, CUSTOMFIELD2, CUSTOMFIELD3, CUSTOMFIELD4, CUSTOMFIELD5, CUSTOMFIELD6, CUSTOMFIELD7, CUSTOMFIELD8) ")
  331. .append("VALUES (SYSDATE,doc.PIID, doc.LINENO, doc.ITEMCODE, doc.PLANQTY, doc.ACTUALQTY,doc.ACTUALPACKUOMQTY, ")
  332. .append(" doc.SERIALNO, doc.CUSTOMFIELD1, doc.CUSTOMFIELD2, doc.CUSTOMFIELD3, doc.CUSTOMFIELD4, doc.CUSTOMFIELD5, ")
  333. .append("doc.CUSTOMFIELD6, doc.CUSTOMFIELD7, doc.CUSTOMFIELD8)");
  334. return sql.toString();
  335. }
  336. public String getGenerateBatchsSql(OUTConfirm.OrderLines.OrderLine line,Integer lineNo, Integer detno, OUTConfirm.OrderLines.OrderLine.Batchs.Batch batch) {
  337. StringBuilder sql = new StringBuilder();
  338. sql.append("INSERT INTO ").append("@MASTERCODE")
  339. .append(".prodiowms_batchs(ITIME,PB_PIID, PD_DETNO, LINENO, ACTUALQTY, ACTUALPACKUOMQTY, INVENTORYTYPE, VIRTUALWAREHOUSE, PRODUCTDATE, EXPIREDATE, BATCHCODE, STOCKINDATE, USERDEFINED1, USERDEFINED2, USERDEFINED3, USERDEFINED4, LPN) VALUES(");
  340. // 添加字段值
  341. sql.append("SYSDATE, ");
  342. sql.append("@PIID").append(", ");
  343. sql.append(detno).append(", "); // PD_DETNO
  344. sql.append(lineNo).append(", "); // LINENO
  345. sql.append(StringUtil.nvl(batch.getActualQty(), "0")).append(", ");
  346. sql.append(StringUtil.nvl(batch.getActualPackUomQty(), "0")).append(", ");
  347. sql.append("'").append(StringUtil.nvl(line.getInventoryType(), "")).append("', ");
  348. sql.append("'").append(StringUtil.nvl(batch.getVirtualWarehouse(), "")).append("', ");
  349. if (StringUtil.hasText(batch.getProductDate())) {
  350. sql.append("to_date('").append(batch.getProductDate()).append("','yyyy-mm-dd hh24:mi:ss'), ");
  351. } else {
  352. sql.append("null, ");
  353. }
  354. if (StringUtil.hasText(batch.getExpireDate())) {
  355. sql.append("to_date('").append(batch.getExpireDate()).append("','yyyy-mm-dd hh24:mi:ss'), ");
  356. } else {
  357. sql.append("null, ");
  358. }
  359. sql.append("'").append(StringUtil.nvl(batch.getBatchCode(), "")).append("', ");
  360. if (StringUtil.hasText(batch.getStockinDate())) {
  361. sql.append("to_date('").append(batch.getStockinDate()).append("','yyyy-mm-dd hh24:mi:ss'), ");
  362. } else {
  363. sql.append("null, ");
  364. }
  365. sql.append("'").append(StringUtil.nvl(batch.getUserDefined1(), "")).append("', ");
  366. sql.append("'").append(StringUtil.nvl(batch.getUserDefined2(), "")).append("', ");
  367. sql.append("'").append(StringUtil.nvl(batch.getUserDefined3(), "")).append("', ");
  368. sql.append("'").append(StringUtil.nvl(batch.getUserDefined4(), "")).append("', ");
  369. sql.append("'").append(StringUtil.nvl(batch.getLpn(), "")).append("'");
  370. sql.append(")");
  371. return sql.toString();
  372. }
  373. }