DocCommonServiceImpl.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. package com.uas.eis.service.Impl;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import com.fasterxml.jackson.dataformat.xml.XmlMapper;
  5. import com.uas.eis.config.VwmsConfig;
  6. import com.uas.eis.dao.BaseDao;
  7. import com.uas.eis.dao.SqlRowList;
  8. import com.uas.eis.entity.vwms.entity.*;
  9. import com.uas.eis.entity.vwms.req.*;
  10. import com.uas.eis.entity.vwms.resp.BaseVastResp;
  11. import com.uas.eis.entity.vwms.resp.IOResp;
  12. import com.uas.eis.entity.vwms.resp.ProdResp;
  13. import com.uas.eis.service.DocCommonService;
  14. import com.uas.eis.service.ERPService;
  15. import com.uas.eis.utils.CollectionUtil;
  16. import com.uas.eis.utils.HttpUtil;
  17. import com.uas.eis.utils.StringUtil;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.jdbc.core.BeanPropertyRowMapper;
  22. import org.springframework.stereotype.Service;
  23. import java.io.IOException;
  24. import java.math.BigDecimal;
  25. import java.util.*;
  26. import java.util.stream.Collectors;
  27. /**
  28. * @author wuyx
  29. * @email wuyx@usoftchina.com
  30. * @date 2025-03-04
  31. */
  32. @Service
  33. public class DocCommonServiceImpl implements DocCommonService {
  34. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  35. @Autowired
  36. private BaseDao baseDao;
  37. @Autowired
  38. private VwmsConfig vwmsConfig;
  39. @Autowired
  40. private ObjectMapper objectMapper; // 注入Jackson的ObjectMapper
  41. @Override
  42. public ProdInout getIO(String master,String id,String pdIds){
  43. // 查询主表信息
  44. ProdInout prodInOut = queryMainTable(master, id);
  45. prodInOut.setOutBizCode(prodInOut.getPiOrderType()+"-"+System.currentTimeMillis());// 外部业务代码 消息ID, 用于去重, 因为网络等原因导致重复传输, 请求不会被重复处理
  46. // 构建明细查询SQL
  47. String detSql = buildDetailSql(master, prodInOut,pdIds);
  48. // 查询明细数据
  49. List<Prodiodetail> details = queryDetails(master, detSql);
  50. prodInOut.setDetails(details);
  51. // 更新WMS相关表
  52. if (!prodInOut.getPiWmsstatus().equals("已确认")) {
  53. updateWmsTables(master, prodInOut, detSql);
  54. }
  55. if("YUEJH_TEST".equals(master)){
  56. prodInOut.setCurrentMaster("YUEJH");
  57. }
  58. if("YJH_T".equals(master)){
  59. prodInOut.setCurrentMaster("AIFL");
  60. }
  61. if("YIT_T".equals(master)){
  62. prodInOut.setCurrentMaster("YJH_HK");
  63. }
  64. if(StringUtil.hasText(prodInOut.getToMasterCode())){
  65. if("YUEJH_TEST".equals(prodInOut.getToMasterCode())){
  66. prodInOut.setToMasterCode("YUEJH");
  67. }
  68. if("YJH_T".equals(prodInOut.getToMasterCode())){
  69. prodInOut.setToMasterCode("AIFL");
  70. }
  71. if("YIT_T".equals(prodInOut.getToMasterCode())){
  72. prodInOut.setToMasterCode("YJH_HK");
  73. }
  74. }
  75. return prodInOut;
  76. }
  77. private ProdInout queryMainTable(String master, String id) {
  78. String sql = new StringBuilder()
  79. .append("select pi_Wmsordertype piOrderType,pi_id piId,pi_inoutno piInoutno,pi_class piClass,pi_type piType,")
  80. .append("to_char(pi_date,'yyyy-mm-dd hh24:mi:ss') piDate,pi_Cardcode piCardcode,pi_Title piTitle,")
  81. .append("pi_Recordman piRecordman,to_char(pi_recorddate,'yyyy-mm-dd hh24:mi:ss') piRecorddate,pi_Remark piRemark,")
  82. .append("abs(nvl(pi_sendwmsflag,0)) piSendwmsflag,nvl(pi_WmsInType,'in') piWmsInType,pi_wmsstatus piWmsstatus,")
  83. .append("pi_invostatuscode piInvoStatusCode,'"+master+"' currentMaster,pi_tomaster toMasterCode,pi_purposename piLxr,pi_expresscode piLxdh,pi_address piKhdz ")
  84. .append("from ").append(master).append(".prodinout where pi_id = ").append(id)
  85. .toString();
  86. List<ProdInout> prodInOuts = baseDao.getJdbcTemplate().query(sql,
  87. new BeanPropertyRowMapper<>(ProdInout.class));
  88. return prodInOuts.get(0);
  89. }
  90. private String buildDetailSql(String master, ProdInout prodInOut,String pdIds) {
  91. StringBuilder sqlBuilder = new StringBuilder();
  92. if ("in".equals(prodInOut.getPiWmsInType())) {
  93. sqlBuilder.append("select pd_piid pdPiid,(pd_id) pdId,(pd_pdno) pdPdno,pd_prodcode pdProdcode,pr_detail pdProdname,pr_brand pdBrandName" +
  94. " ,(nvl(pd_inqty,0)+nvl(pd_outqty,0)) pdQty ,wh_code pdWhcode,wh_description pdWhname ")
  95. .append(" from ").append(master).append(".prodiodetail ").append(" left join ").append(master).append(".prodinout on pi_id = pd_piid ")
  96. .append(" left join ").append(master).append(".product on pr_code = pd_prodcode ")
  97. .append(" left join ").append(master).append(".warehouse on wh_Code = (case when pi_class='拨出单' and PI_TYPE='寄售退货' then pd_inwhcode else pd_whcode end) ")
  98. .append(" where pd_piid = "+prodInOut.getPiId()+" and nvl(pr_sendwmsflag,0) = -1 ")
  99. .append(" order by pd_pdno ");
  100. } else {
  101. if(prodInOut.getPiOrderType().equals("ZKCK")){//转库业务
  102. sqlBuilder.append("select pd_piid pdPiid,(pd_id) pdId,(pd_pdno) pdPdno,pd_prodcode pdProdcode,")
  103. .append("pr_detail pdProdname,pr_brand pdBrandName,(nvl(pd_inqty,0)+nvl(pd_outqty,0)) pdQty,")
  104. .append("pd_whcode pdWhcode,wh_description pdWhname,tsd_inwhcode pdWhcodeTo,")
  105. .append("pd_custprodcode pdCustprodcode,pd_custproddetail pdCustProdDetail,pd_custprodspec pdCustProdSpec, pd_pocode pdPocode ,pd_ordercode pdOrderCode,pd_Remark pdRemark" +
  106. ",pd_sendprice pdSendPrice,nvl(sd_purcprice,0) standardPrice ")
  107. .append("from ").append(master).append(".prodiodetail ")
  108. .append(" left join ").append(master).append(".prodinout on pi_id = pd_piid ")
  109. .append(" left join ").append(master).append(".product on pr_code = pd_prodcode ")
  110. .append(" left join ").append(master).append(".warehouse on wh_Code = pd_whcode ")
  111. .append(" left join ").append(master).append(".saledetail on sd_Code = pd_ordercode and sd_Detno = pd_orderdetno ")
  112. .append(" left join ").append(master).append(".TRANSFERSTOCK ON PI_INOUTNO = TS_CODE ")
  113. .append(" left join ").append(master).append(".TRANSFERSTOCKDETAIL ON TS_ID=TSD_TSID AND PD_PDNO = TSD_DETNO ")
  114. .append("where pd_piid = ").append(prodInOut.getPiId()).append(" and nvl(pr_sendwmsflag,0) = -1");
  115. if(StringUtil.hasText(pdIds)){
  116. sqlBuilder.append(" and pd_id in (").append(pdIds).append(")");
  117. }
  118. sqlBuilder.append(" order by pd_pdno ");
  119. }else {
  120. sqlBuilder.append("select pd_piid pdPiid,(pd_id) pdId,(pd_pdno) pdPdno,pd_prodcode pdProdcode,")
  121. .append("pr_detail pdProdname,pr_brand pdBrandName,(nvl(pd_inqty,0)+nvl(pd_outqty,0)) pdQty,")
  122. .append("pd_whcode pdWhcode,wh_description pdWhname,(case when pi_class='出货单' and pi_type='库存转移' then pd_whcode when pi_class='拨出单' then pd_inwhcode else null end) pdWhcodeTo,")
  123. .append("pd_custprodcode pdCustprodcode,pd_custproddetail pdCustProdDetail,pd_custprodspec pdCustProdSpec, pd_pocode pdPocode ,pd_ordercode pdOrderCode,pd_Remark pdRemark" +
  124. ",pd_sendprice pdSendPrice,nvl(sd_purcprice,0) standardPrice ")
  125. .append("from ").append(master).append(".prodiodetail ")
  126. .append(" left join ").append(master).append(".prodinout on pi_id = pd_piid ")
  127. .append(" left join ").append(master).append(".product on pr_code = pd_prodcode ")
  128. .append(" left join ").append(master).append(".warehouse on wh_Code = pd_whcode ")
  129. .append(" left join ").append(master).append(".saledetail on sd_Code = pd_ordercode and sd_Detno = pd_orderdetno ")
  130. .append("where pd_piid = ").append(prodInOut.getPiId()).append(" and nvl(pr_sendwmsflag,0) = -1");
  131. if(StringUtil.hasText(pdIds)){
  132. sqlBuilder.append(" and pd_id in (").append(pdIds).append(")");
  133. }
  134. sqlBuilder.append(" order by pd_pdno ");
  135. }
  136. }
  137. return sqlBuilder.toString();
  138. }
  139. private List<Prodiodetail> queryDetails(String master, String sql) {
  140. return baseDao.getJdbcTemplate().query(sql,
  141. new BeanPropertyRowMapper<>(Prodiodetail.class));
  142. }
  143. private void updateWmsTables(String master, ProdInout prodInOut, String detSql) {
  144. Long piId = prodInOut.getPiId();
  145. // 删除旧数据
  146. String deleteMainSql = "delete from " + master + ".prodiowms where PIID = " + piId;
  147. String deleteDetailSql = "delete from " + master + ".prodiowms_lines where pl_piid = " + piId;
  148. baseDao.execute(deleteMainSql);
  149. baseDao.execute(deleteDetailSql);
  150. // 插入主表数据
  151. String sql = new StringBuilder()
  152. .append("INSERT INTO ").append(master).append(".prodiowms(ITIME,PIID, PIINOUTNO, ORDERCODE, OWNERCODE, WAREHOUSECODE, WMSORDERID, WMSORDERTYPE,OUTBIZCODE,TOOWNERCODE)")
  153. .append(" select sysdate,pi_id,pi_inoutno,pi_inoutno,'")
  154. .append(prodInOut.getCurrentMaster()).append("','")
  155. .append(vwmsConfig.getWarehouseCode()).append("',PI_WMSORDERCODE,PI_WMSORDERTYPE,'").append(prodInOut.getOutBizCode()).append("','"+StringUtil.nvl(prodInOut.getToMasterCode(),"")+"'")
  156. .append(" from ").append(master).append(".prodinout where pi_id = ").append(prodInOut.getPiId())
  157. .toString();
  158. baseDao.execute(sql);
  159. // 插入明细数据 PL_PIID, ITIME, UTIME, OUTBIZCODE, LOGICWAREHOUSECODE, INLOGICWAREHOUSECODE, LINENO, ITEMCODE, PLANQTY, ACTUALQTY
  160. if ("in".equals(prodInOut.getPiWmsInType())) {
  161. String insertDetailSql = new StringBuilder()
  162. .append("INSERT INTO ").append(master).append(".prodiowms_Lines(ITIME,PL_PIID,LOGICWAREHOUSECODE,LINENO, ITEMCODE, PLANQTY)")
  163. .append(" select sysdate,pdPiid,pdWhcode,pdPdno,pdProdcode,pdQty ")
  164. .append(" from (").append(detSql).append(")")
  165. .toString();
  166. baseDao.execute(insertDetailSql);
  167. }else{
  168. String insertDetailSql = new StringBuilder()
  169. .append("INSERT INTO ").append(master).append(".prodiowms_Lines(ITIME,PL_PIID,LOGICWAREHOUSECODE,LINENO, ITEMCODE, PLANQTY" +
  170. ",custItemCode,custItemName,custItemSkuProperty,custLotNumber,custPO,contractNo,retailPrice,actualPrice)")
  171. .append(" select sysdate,pdPiid,pdWhcode,pdPdno,pdProdcode,pdQty" +
  172. ",PDCUSTPRODCODE,PDCUSTPRODDETAIL, PDCUSTPRODSPEC, PDPOCODE, PDORDERCODE, PDREMARK, PDSENDPRICE, STANDARDPRICE " +
  173. " from (").append(detSql).append(")")
  174. .toString();
  175. baseDao.execute(insertDetailSql);
  176. }
  177. }
  178. private List<? extends OrderLine> getOrderLines(ProdInout prodInOut,String masterName) {
  179. List<OrderLine> orderLineList = new ArrayList<>();
  180. String orderType = prodInOut.getPiOrderType();
  181. for (Prodiodetail detail : prodInOut.getDetails()) {
  182. OrderLine orderLine;
  183. if (!"in".equals(prodInOut.getPiWmsInType())) {
  184. orderLine = new OrderLineOut(); // 创建普通订单行对象
  185. ((OrderLineOut) orderLine).setRemark(detail.getPdRemark());
  186. ((OrderLineOut) orderLine).setCustItemCode(detail.getPdCustProdCode());
  187. ((OrderLineOut) orderLine).setCustItemName(detail.getPdCustProdDetail());
  188. ((OrderLineOut) orderLine).setCustItemSkuProperty(detail.getPdCustProdSpec());
  189. // ((OrderLineOut) orderLine).setCustLotNumber();
  190. ((OrderLineOut) orderLine).setCustPO(detail.getPdPocode());
  191. ((OrderLineOut) orderLine).setContractNo(detail.getPdOrderCode());
  192. if("transfer".equals(prodInOut.getPiWmsInType())){
  193. ((OrderLineOut) orderLine).setInLogicWarehouseCode(detail.getPdWhcodeTo());
  194. }
  195. if("out".equals(prodInOut.getPiWmsInType())){
  196. ((OrderLineOut) orderLine).setRetailPrice(detail.getStandardPrice());
  197. ((OrderLineOut) orderLine).setActualPrice(detail.getPdSendPrice());
  198. }
  199. }else {
  200. orderLine = new OrderLineIn();
  201. }
  202. // 设置通用属性
  203. orderLine.setOutBizCode(prodInOut.getOutBizCode());
  204. orderLine.setLogicWarehouseCode(detail.getPdWhcode());
  205. orderLine.setOrderLineNo(String.valueOf(detail.getPdPdno()));// 行号
  206. orderLine.setOwnerCode(prodInOut.getCurrentMaster());// 货主编码
  207. orderLine.setItemCode(detail.getPdProdcode());// 商品编码
  208. orderLine.setItemName(detail.getPdProdname());// 商品名称
  209. orderLine.setPlanQty(detail.getPdQty());// 数量
  210. orderLineList.add(orderLine);
  211. }
  212. return orderLineList;
  213. }
  214. @Override
  215. public String sendOutToWms(ProdInout prodInOut, String masterName) {
  216. StockOutAndDetRequest stockOutAndDetRequest = new StockOutAndDetRequest();
  217. DeliveryOrder deliveryOrder = new DeliveryOrder();
  218. deliveryOrder.setDeliveryOrderCode(prodInOut.getPiInoutno());// 出库单号
  219. deliveryOrder.setOrderType(prodInOut.getPiOrderType());// 订单类型
  220. deliveryOrder.setWarehouseCode(vwmsConfig.getWarehouseCode());// 仓库编码
  221. deliveryOrder.setOwnerCode(prodInOut.getCurrentMaster());// 货主编码
  222. deliveryOrder.setCreateTime(StringUtil.nvl(prodInOut.getPiRecordDate(),prodInOut.getPiDate()));
  223. //调拨业务
  224. if(prodInOut.getPiWmsInType().equals("transfer")){
  225. deliveryOrder.setInWarehouseCode(vwmsConfig.getWarehouseCode());
  226. if(prodInOut.getPiOrderType().equals("ZKCK")){//转库业务
  227. deliveryOrder.setInOwnerCode(prodInOut.getToMasterCode());
  228. }
  229. }
  230. deliveryOrder.setScheduleDate(prodInOut.getPiDeliverytime());
  231. deliveryOrder.setSupplierCode(prodInOut.getPiCardCode());// 客户编码
  232. deliveryOrder.setSupplierName(prodInOut.getPiTitle());// 客户名称
  233. deliveryOrder.setRemark(prodInOut.getPiRemark());// 备注
  234. deliveryOrder.setDocumenter(prodInOut.getPiRecordman());// 制单人
  235. //收货人信息
  236. DeliveryOrder.ReceiverInfo receiverInfo = new DeliveryOrder.ReceiverInfo();
  237. receiverInfo.setCode(prodInOut.getPiCardCode());
  238. receiverInfo.setCompany(prodInOut.getPiTitle());
  239. receiverInfo.setName(StringUtil.nvl(prodInOut.getPiLxr(),"无"));
  240. receiverInfo.setMobile(StringUtil.nvl(prodInOut.getPiLxdh(),prodInOut.getPiLxdh()));
  241. receiverInfo.setDetailAddress(StringUtil.nvl(prodInOut.getPiKhdz(),"无"));
  242. receiverInfo.setCustForshort(prodInOut.getCustShortName());
  243. deliveryOrder.setReceiverInfo(receiverInfo);
  244. //写入明细表
  245. List<OrderLineOut> orderLineOuts = (List<OrderLineOut>) getOrderLines(prodInOut, masterName);
  246. stockOutAndDetRequest.setDeliveryOrder(deliveryOrder);
  247. StockOutAndDetRequest.OutOrderLines orderLines = new StockOutAndDetRequest.OutOrderLines();
  248. orderLines.setOrderLine(orderLineOuts);
  249. stockOutAndDetRequest.setOrderLines(orderLines);
  250. String xml = null;
  251. String method = "stockout.create";
  252. try {
  253. XmlMapper xmlMapper = new XmlMapper();
  254. xml = xmlMapper.writeValueAsString(stockOutAndDetRequest);
  255. } catch (JsonProcessingException e) {
  256. e.printStackTrace();
  257. return "JSON转换失败";
  258. }
  259. //TODO 写入表:WMS_IO_RECORD_SEQ
  260. return doPostToWms(xml,method);
  261. }
  262. @Override
  263. public String sendInToWms(ProdInout prodInOut,String masterName){
  264. EntryOrder entryOrder = new EntryOrder();
  265. entryOrder.setEntryOrderCode(prodInOut.getPiInoutno());// 入库单号
  266. entryOrder.setOwnerCode(prodInOut.getCurrentMaster());// 货主编码
  267. entryOrder.setWarehouseCode(vwmsConfig.getWarehouseCode());// 仓库编码
  268. entryOrder.setOrderCreateTime(prodInOut.getPiRecordDate());// 订单创建时间
  269. entryOrder.setOrderType(prodInOut.getPiOrderType());// 订单类型
  270. entryOrder.setSupplierCode(prodInOut.getPiCardCode());// 供应商编码
  271. entryOrder.setSupplierName(prodInOut.getPiTitle());// 供应商名称
  272. entryOrder.setRemark(prodInOut.getPiRemark());// 备注
  273. List<OrderLineIn> orderList = (List<OrderLineIn>) getOrderLines(prodInOut, masterName);
  274. EntryOrderAndDetRequest entryOrderAndDetRequest = new EntryOrderAndDetRequest();
  275. EntryOrderAndDetRequest.InOrderLines orderLineIns = new EntryOrderAndDetRequest.InOrderLines();
  276. orderLineIns.setOrderLine(orderList);
  277. entryOrderAndDetRequest.setEntryOrder(entryOrder);
  278. entryOrderAndDetRequest.setOrderLines(orderLineIns);
  279. //转换为JSON字符串
  280. String xml = null;
  281. String method = "entryorder.create";
  282. try {
  283. XmlMapper xmlMapper = new XmlMapper();
  284. xml = xmlMapper.writeValueAsString(entryOrderAndDetRequest);
  285. } catch (JsonProcessingException e) {
  286. e.printStackTrace();
  287. return "JSON转换失败";
  288. }
  289. //TODO 写入表:WMS_IO_RECORD_SEQ
  290. return doPostToWms(xml,method);
  291. }
  292. @Override
  293. public String doPostToWms(String xml,String method){
  294. String eMsg = null;
  295. try {
  296. logger.info("doPostToWms method:{} XML: {}",method, xml);
  297. // HttpUtil.Response response = new HttpUtil.Response();
  298. // response.setStatusCode(404);
  299. // response.setResponseText("单据已分配。");
  300. HttpUtil.Response response = HttpUtil.postXmlToVWMS(method,xml, "UTF-8",vwmsConfig);
  301. if(!String.valueOf(response.getStatusCode()).startsWith("2")){
  302. eMsg = "("+response.getStatusCode()+")"+StringUtil.nvl(response.getResponseText(),"未知").replaceAll("'","''");
  303. }else {
  304. logger.info("doPostToWms method:{} response: {}",response.getResponseText());
  305. // 创建XmlMapper实例
  306. XmlMapper xmlMapper = new XmlMapper();
  307. IOResp ioResp = xmlMapper.readValue(response.getResponseText(), IOResp.class);
  308. if(ioResp!=null){
  309. if("success".equals(ioResp.getFlag())){
  310. String orderId = "";
  311. if("entryorder.create".equals(method)){
  312. orderId = ioResp.getEntryOrderId();
  313. eMsg = "OrderId:"+orderId;
  314. }
  315. if("stockout.create".equals(method)){
  316. orderId = ioResp.getDeliveryOrderId();
  317. eMsg = "OrderId:"+orderId;
  318. }
  319. // if("openapi.adjustmentorder.create".equals(method)){
  320. // orderId = baseVastRespResponse.getAdjustmentOrderId();
  321. // eMsg = "OrderId:"+orderId;
  322. // }
  323. logger.info("doSendInOrderToWms-resp-s code: {} method {} OrderId {} message: {}", ioResp.getCode(),method,orderId,ioResp.getMessage());
  324. }else {
  325. eMsg = "(" + ioResp.getCode() + ")";
  326. String errorMessage = ioResp.getMessage();
  327. eMsg += StringUtil.nvl(errorMessage, "未知").replaceAll("'", "''");
  328. }
  329. }else {
  330. eMsg = "Resp XML转换失败:"+response.getStatusCode()+":"+response.getResponseText();
  331. }
  332. }
  333. } catch (IOException e) {
  334. e.printStackTrace();
  335. eMsg = "xmL转换失败";
  336. } catch (Exception e) {
  337. e.printStackTrace();
  338. eMsg = StringUtil.nvl(e.getMessage(),"无").replaceAll("'","''");
  339. }
  340. return eMsg;
  341. }
  342. }