DocCommonServiceImpl.java 20 KB

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