WcsToWmsApiService.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. package com.ruoyi.ams.xuankuang.service;
  2. import cn.hutool.core.comparator.CompareUtil;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import com.ruoyi.ams.asn.domain.WmsDocAsnDetails;
  5. import com.ruoyi.ams.asn.domain.WmsDocAsnHeader;
  6. import com.ruoyi.ams.asn.mapper.WmsDocAsnDetailsMapper;
  7. import com.ruoyi.ams.asn.mapper.WmsDocAsnHeaderMapper;
  8. import com.ruoyi.ams.asn.service.IWmsDocAsnDetailsService;
  9. import com.ruoyi.ams.config.domain.dto.LotattDTO;
  10. import com.ruoyi.ams.task.domain.WcsTask;
  11. import com.ruoyi.ams.task.service.IWcsTaskService;
  12. import com.ruoyi.ams.xuankuang.domain.form.*;
  13. import com.ruoyi.ams.xuankuang.domain.vo.LocationCoordinateVo;
  14. import com.ruoyi.ams.xuankuang.facade.IUnpackingMachineFacade;
  15. import com.ruoyi.base.constant.Constant;
  16. import com.ruoyi.base.domain.BaseLocationInfo;
  17. import com.ruoyi.base.domain.vo.BaseLocationLotattVO;
  18. import com.ruoyi.base.service.IBaseLocationInfoService;
  19. import com.ruoyi.base.service.IBaseSkuService;
  20. import com.ruoyi.base.utils.IdSequenceUtils;
  21. import com.ruoyi.common.core.domain.AjaxResult;
  22. import com.ruoyi.common.utils.StringUtils;
  23. import com.ruoyi.hard.xuankang.StirringTankClient;
  24. import com.ruoyi.hard.xuankang.UnpackingMachineSubClient;
  25. import io.jsonwebtoken.lang.Assert;
  26. import lombok.extern.slf4j.Slf4j;
  27. import org.springframework.beans.factory.annotation.Autowired;
  28. import org.springframework.stereotype.Service;
  29. import org.springframework.transaction.annotation.Transactional;
  30. import java.math.BigDecimal;
  31. import java.util.Date;
  32. import java.util.List;
  33. import static com.ruoyi.ams.xuankuang.service.BaseLocationInfoSubService.OUT_ZONES;
  34. /**
  35. * @author HuKang
  36. * @version 1.0
  37. * @date 2023/3/30 15:42
  38. */
  39. @Slf4j
  40. @Service
  41. public class WcsToWmsApiService {
  42. @Autowired
  43. private IBaseSkuService iBaseSkuService;
  44. @Autowired
  45. private IBaseLocationInfoService iBaseLocationInfoService;
  46. @Autowired
  47. private BaseLocationInfoSubService baseLocationInfoSubService;
  48. @Autowired
  49. private InvLotLocIdSubService InvLotLocIdSubService;
  50. @Autowired
  51. private WcsTaskSubService wcsTaskSubService;
  52. @Autowired
  53. private IWcsTaskService iWcsTaskService;
  54. @Autowired
  55. private WmsDocAsnHeaderMapper wmsDocAsnHeaderMapper;
  56. @Autowired
  57. private WmsDocAsnDetailsMapper wmsDocAsnDetailsMapper;
  58. @Autowired
  59. private IdSequenceUtils idSequenceUtils;
  60. @Autowired
  61. private StirringTankClient stirringTankClient;
  62. @Autowired
  63. private UnpackingMachineSubClient unpackingMachineSubClient;
  64. @Autowired
  65. private IUnpackingMachineFacade unpackingMachineFacade;
  66. @Autowired
  67. private IWcsTaskService wcsTaskService;
  68. @Autowired
  69. private IWmsDocAsnDetailsService wmsDocAsnDetailsService;
  70. @Autowired
  71. private WmsDocAsnSubService wmsDocAsnSubService;
  72. @Autowired
  73. private AgvCallProxyService agvCallProxyService;
  74. /**
  75. * 组盘上报
  76. *
  77. * @param stackingCompletion
  78. * @return
  79. */
  80. @Transactional
  81. public AjaxResult stackingCompletion(StackingCompletionForm stackingCompletion) {
  82. // 上报类型
  83. int reportType = stackingCompletion.getReportType();
  84. // 托盘号
  85. String palletNo = stackingCompletion.getPalletNo();
  86. // Wcs物料类型
  87. String materialType = stackingCompletion.getMaterialType();
  88. // wms物料编码
  89. String sku = iBaseSkuService.selectBaseSkuByMaterialType(materialType).getSku();
  90. // 数量
  91. Double qty = (double) stackingCompletion.getQty();
  92. // 入库单号
  93. String asnNo = stackingCompletion.getRelatedWmsNo();
  94. // 任务号
  95. String wcsNo = stackingCompletion.getWcsNo();
  96. if (StringUtils.isBlank(asnNo)) {
  97. AjaxResult ajaxResult1 = generateAShippingOrder(sku, new BigDecimal(qty));
  98. asnNo = ajaxResult1.getData().toString();
  99. }
  100. return insertTaskAndInvLotLocId(asnNo, palletNo, wcsNo, sku, qty);
  101. }
  102. private AjaxResult insertTaskAndInvLotLocId(String asnNo, String palletNo, String wcsNo, String sku, Double qty){
  103. WcsTask wcsTaskQuery = new WcsTask();
  104. wcsTaskQuery.setExt1(asnNo);
  105. wcsTaskQuery.setExt2(palletNo);
  106. wcsTaskQuery.setExt3(wcsNo);
  107. wcsTaskQuery.setState(Long.parseLong(Constant.TASK_STS.TASK10.getValue().toString()));
  108. WcsTask wcsTask = iWcsTaskService.selectWcsTaskByModel(wcsTaskQuery);
  109. if (wcsTask != null) {
  110. BaseLocationInfo baseLocationInfo = iBaseLocationInfoService.selectBaseLocationInfoByIdOrNo(wcsTask.getLocationTo(), Constant.WAREHOUSE_ID);
  111. return AjaxResult.success("仓位获取成功!", buildLocationCoordinateVo(wcsTask.getTaskNo(), baseLocationInfo.getLocationNo(), baseLocationInfo.getShiftNo(), baseLocationInfo.getRowNo(), baseLocationInfo.getRowIndex(), baseLocationInfo.getUserdefine4()));
  112. }
  113. // 推荐目标库位
  114. BaseLocationLotattVO baseLocationLotattVO = baseLocationInfoSubService.recommendAReceiptLocation(sku);
  115. if (baseLocationLotattVO == null) {
  116. return AjaxResult.error("没有可以推荐的目标库位!");
  117. }
  118. // 生成任务
  119. AjaxResult ajaxResult = wcsTaskSubService.addWcsTask(Constant.LOC_STAGE_CACHE.toString()
  120. , baseLocationLotattVO.getId().toString()
  121. , asnNo
  122. , palletNo
  123. , wcsNo);
  124. if (!ajaxResult.isSuccess()) {
  125. return ajaxResult;
  126. }
  127. String taskNo = ajaxResult.get("data").toString();
  128. // 入库缓存位生成库存
  129. InvLotLocIdSubService.initInv(Constant.LOC_STAGE_CACHE.toString(), sku, palletNo, asnNo, taskNo, qty);
  130. // 反馈
  131. return AjaxResult.success("仓位获取成功!", buildLocationCoordinateVo(taskNo, baseLocationLotattVO.getLocationNo(), baseLocationLotattVO.getShiftNo(), baseLocationLotattVO.getRowNo(), baseLocationLotattVO.getRowIndex(), baseLocationLotattVO.getUserdefine4()));
  132. }
  133. private LocationCoordinateVo buildLocationCoordinateVo(String taskNo, String locationId, String floor, String col, String row, String wcsLocation){
  134. LocationCoordinateVo locationCoordinateVo = new LocationCoordinateVo();
  135. locationCoordinateVo.setTaskNo(taskNo);
  136. locationCoordinateVo.setLocationId(locationId);
  137. locationCoordinateVo.setFloor(Integer.valueOf(floor));
  138. locationCoordinateVo.setCol(Integer.valueOf(col));
  139. locationCoordinateVo.setRow(Integer.valueOf(row));
  140. locationCoordinateVo.setWcsLocation(wcsLocation);
  141. return locationCoordinateVo;
  142. }
  143. /**
  144. * 空托仓位请求
  145. *
  146. * @param emptyPalletLocForm
  147. * @return
  148. */
  149. @Transactional
  150. public AjaxResult EmptyPalletLoc(EmptyPalletLocForm emptyPalletLocForm) {
  151. // 空托仓位请求类型
  152. int taskType = emptyPalletLocForm.getTaskType();
  153. // 任务号
  154. String wcsNo = emptyPalletLocForm.getWcsNo();
  155. if (taskType == 0) {
  156. return AjaxResult.error("未传入空托仓位请求类型");
  157. }
  158. if (taskType == 1) {
  159. return insertTaskAndInvLotLocId(StringUtils.EMPTY, StringUtils.EMPTY, wcsNo, Constant.PALLET_TYPE, 1.0);
  160. }
  161. //出库仓位
  162. List<BaseLocationLotattVO> baseLocationLotattVOS = baseLocationInfoSubService.selectAllocatingInventoryAccordingConditionsOrderBy(OUT_ZONES, new LotattDTO(), Constant.PALLET_TYPE, StringUtils.EMPTY);
  163. if (baseLocationLotattVOS.size() == 0) {
  164. return AjaxResult.error("仓库中无库存");
  165. }
  166. BaseLocationLotattVO baseLocationLotattVO = filterInv1(baseLocationLotattVOS);
  167. Assert.isTrue(ObjectUtil.isNotNull(baseLocationLotattVO), "仓库中无库存");
  168. String pallentNo = ObjectUtil.isNotNull(baseLocationLotattVO.getLotattVO())
  169. ? baseLocationLotattVO.getLotattVO().getLotatt07() : StringUtils.EMPTY;
  170. String locationFrom = baseLocationLotattVO.getLocationNo();
  171. // 生成四向车出库任务
  172. AjaxResult ajaxResult = wcsTaskSubService.addWcsOutTask(locationFrom, Constant.LOC_SORTATION_CACHE.toString(), "", pallentNo, wcsNo);
  173. return AjaxResult.success("仓位获取成功", buildLocationCoordinateVo(ajaxResult.get("data").toString(), baseLocationLotattVO.getLocationNo(), baseLocationLotattVO.getShiftNo(), baseLocationLotattVO.getRowNo(), baseLocationLotattVO.getRowIndex(), baseLocationLotattVO.getUserdefine4()));
  174. }
  175. /**
  176. * 任务状态反馈
  177. *
  178. * @param taskStatusForm
  179. * @return
  180. */
  181. public AjaxResult taskStatusResponse(TaskStatusForm taskStatusForm) {
  182. String taskNo = taskStatusForm.getTaskNo();
  183. int status = taskStatusForm.getStatus();
  184. wcsTaskSubService.callBack(taskNo, status, null);
  185. return AjaxResult.success();
  186. }
  187. /**
  188. * 匹配库存
  189. *
  190. * @param locationLotattList
  191. * @return
  192. */
  193. public synchronized BaseLocationLotattVO filterInv1(List<BaseLocationLotattVO> locationLotattList) {
  194. return locationLotattList.parallelStream()
  195. .filter(item -> ObjectUtil.isNotNull(item)
  196. && StringUtils.equals(Constant.PALLET_TYPE, item.getSku())
  197. && CompareUtil.compare(item.getQty(), 1F) == 0).findFirst().orElse(null);
  198. }
  199. /**
  200. * 生成入库单
  201. *
  202. * @param sku
  203. * @param qty
  204. * @return
  205. */
  206. public AjaxResult generateAShippingOrder(String sku, BigDecimal qty) {
  207. WmsDocAsnHeader wmsDocAsnHeader = new WmsDocAsnHeader();
  208. //生成单头
  209. String asnNo = idSequenceUtils.generateId("ASNNO");
  210. wmsDocAsnHeader.setAsnNo(asnNo);
  211. wmsDocAsnHeader.setEdiSendFlag("N");
  212. wmsDocAsnHeader.setAsnType(Constant.ASN_TYP.HK.getValue());
  213. wmsDocAsnHeader.setCreateTime(new Date());
  214. wmsDocAsnHeader.setAsnStatus(Constant.ASN_STS.STS10.getValue());
  215. wmsDocAsnHeader.setCreateBy("Wms");
  216. wmsDocAsnHeaderMapper.insertWmsDocAsnHeader(wmsDocAsnHeader);
  217. //生成明细
  218. WmsDocAsnDetails wmsDocAsnDetails = new WmsDocAsnDetails();
  219. wmsDocAsnDetails.setAsnNo(asnNo);
  220. wmsDocAsnDetails.setAsnLineNo(1l);
  221. wmsDocAsnDetails.setSku(sku);
  222. wmsDocAsnDetails.setCreateTime(new Date());
  223. wmsDocAsnDetails.setExpectedQty(qty);
  224. wmsDocAsnDetails.setExpectedQtyEach(qty);
  225. wmsDocAsnDetails.setReceivedQty(new BigDecimal(0));
  226. wmsDocAsnDetails.setReceivedQtyEach(new BigDecimal(0));
  227. wmsDocAsnDetails.setLineStatus(Constant.ASN_STS.STS10.getValue());
  228. wmsDocAsnDetails.setCreateTime(new Date());
  229. wmsDocAsnDetails.setCreateBy("Wms");
  230. wmsDocAsnDetailsMapper.insertWmsDocAsnDetails(wmsDocAsnDetails);
  231. return AjaxResult.success("操作成功!", asnNo);
  232. }
  233. /**
  234. * 拆包机开启接口
  235. *
  236. * @param lineOpenNotificationForm
  237. * @return
  238. */
  239. public AjaxResult lineOpenNotification(LineOpenNotificationForm lineOpenNotificationForm) {
  240. String lineId = lineOpenNotificationForm.getLineId();
  241. boolean[] booleans = stirringTankClient.readTank14();
  242. return unpackingMachineFacade.unpackingMachineOpen(lineId, booleans) ? AjaxResult.success() : AjaxResult.error();
  243. }
  244. /**
  245. * 正常关闭1号拆包机
  246. *
  247. * @return
  248. */
  249. public AjaxResult turnOffTheUnpacker() {
  250. new Thread(() -> {
  251. try {
  252. Thread.sleep(300000);
  253. //写关闭拆包机信号
  254. unpackingMachineSubClient.writeV141_2();
  255. //写仓库注入碳酸钠完成
  256. stirringTankClient.writeTank05();
  257. } catch (InterruptedException e) {
  258. e.printStackTrace();
  259. }
  260. }).start();
  261. return AjaxResult.success();
  262. }
  263. /**
  264. * 正常关闭2号拆包机
  265. *
  266. * @return
  267. */
  268. public AjaxResult turnOffTheUnpacker1() {
  269. new Thread(() -> {
  270. try {
  271. Thread.sleep(300000);
  272. //写关闭拆包机信号
  273. unpackingMachineSubClient.writeV141_3();
  274. //写仓库注入丁黄药完成
  275. stirringTankClient.writeTank05_1();
  276. } catch (InterruptedException e) {
  277. e.printStackTrace();
  278. }
  279. }).start();
  280. return AjaxResult.success();
  281. }
  282. /**
  283. * 正常关闭3号拆包机
  284. *
  285. * @return
  286. */
  287. public AjaxResult turnOffTheUnpacker2() {
  288. new Thread(() -> {
  289. try {
  290. Thread.sleep(300000);
  291. //写关闭拆包机信号
  292. unpackingMachineSubClient.writeV141_4();
  293. //写仓库注入六偏磷酸钠完成
  294. stirringTankClient.writeTank05_3();
  295. } catch (InterruptedException e) {
  296. e.printStackTrace();
  297. }
  298. }).start();
  299. return AjaxResult.success();
  300. }
  301. /**
  302. * 正常关闭4号拆包机
  303. *
  304. * @return
  305. */
  306. public AjaxResult turnOffTheUnpacker3() {
  307. new Thread(() -> {
  308. try {
  309. Thread.sleep(300000);
  310. //写关闭拆包机信号
  311. unpackingMachineSubClient.writeV141_5();
  312. //写仓库注入硫酸铵完成
  313. stirringTankClient.writeTank05_4();
  314. } catch (InterruptedException e) {
  315. e.printStackTrace();
  316. }
  317. }).start();
  318. return AjaxResult.success();
  319. }
  320. /**
  321. * 正常关闭5号拆包机
  322. *
  323. * @return
  324. */
  325. public AjaxResult turnOffTheUnpacker4() {
  326. new Thread(() -> {
  327. try {
  328. Thread.sleep(300000);
  329. //写关闭拆包机信号
  330. unpackingMachineSubClient.writeV141_6();
  331. //写仓库注入乙黄药完成
  332. stirringTankClient.writeTank05_5();
  333. } catch (InterruptedException e) {
  334. e.printStackTrace();
  335. }
  336. }).start();
  337. return AjaxResult.success();
  338. }
  339. /**
  340. * 异常关闭1号拆包机
  341. *
  342. * @return
  343. */
  344. public AjaxResult turnOffTheUnpackererror() {
  345. //写仓库注入碳酸钠失败
  346. stirringTankClient.writeTank04();
  347. stirringTankClient.writeTank05f();
  348. //写关闭拆包机信号
  349. unpackingMachineSubClient.writeV141_2();
  350. return AjaxResult.success();
  351. }
  352. /**
  353. * 异常关闭2号拆包机
  354. *
  355. * @return
  356. */
  357. public AjaxResult turnOffTheUnpackererror1() {
  358. //写仓库注入丁黄药失败
  359. stirringTankClient.writeTank04_1();
  360. stirringTankClient.writeTank05_1f();
  361. unpackingMachineSubClient.writeV141_3();
  362. return AjaxResult.success();
  363. }
  364. /**
  365. * 异常关闭3号拆包机
  366. *
  367. * @return
  368. */
  369. public AjaxResult turnOffTheUnpackererror2() {
  370. //写仓库注入六偏磷酸钠失败
  371. stirringTankClient.writeTank04_3();
  372. stirringTankClient.writeTank05_3f();
  373. unpackingMachineSubClient.writeV141_4();
  374. return AjaxResult.success();
  375. }
  376. /**
  377. * 异常关闭4号拆包机
  378. *
  379. * @return
  380. */
  381. public AjaxResult turnOffTheUnpackererror3() {
  382. //写仓库注入硫酸铵失败
  383. stirringTankClient.writeTank04_4();
  384. stirringTankClient.writeTank05_4f();
  385. unpackingMachineSubClient.writeV141_5();
  386. return AjaxResult.success();
  387. }
  388. /**
  389. * 异常关闭5号拆包机
  390. *
  391. * @return
  392. */
  393. public AjaxResult turnOffTheUnpackererror4() {
  394. //写仓库注入乙黄药失败
  395. stirringTankClient.writeTank04_5();
  396. stirringTankClient.writeTank05_5f();
  397. unpackingMachineSubClient.writeV141_6();
  398. return AjaxResult.success();
  399. }
  400. /**
  401. * 更新数据接口
  402. *
  403. * @param updateForm
  404. * @return
  405. */
  406. public AjaxResult updateAsnData(UpdateForm updateForm) {
  407. String asnNo = updateForm.getDocNo();
  408. String asnLineNo = updateForm.getLineNo();
  409. Integer num = updateForm.getNum();
  410. WmsDocAsnDetails wmsDocAsnDetails = wmsDocAsnDetailsMapper.selectWmsDocAsnDetailsByAsnLineNo(asnNo, asnLineNo);
  411. wmsDocAsnDetails.setExpectedQty(new BigDecimal(num));
  412. wmsDocAsnDetails.setExpectedQtyEach(new BigDecimal(num));
  413. wmsDocAsnDetailsMapper.updateWmsDocAsnDetails(wmsDocAsnDetails);
  414. return AjaxResult.success();
  415. }
  416. /**
  417. * 桶装入库
  418. * @return
  419. */
  420. @Transactional
  421. public synchronized AjaxResult theBucketIsLoadedIntoTheLibrary(String sku, String asnNo, String palletNo, BigDecimal num) {
  422. // 数量
  423. Double qty = num.doubleValue();
  424. return insertTaskAndInvLotLocId(asnNo, palletNo, StringUtils.EMPTY, sku, qty);
  425. }
  426. /**
  427. * 安全交握
  428. * @param callbackTaskFrom
  429. * @return
  430. */
  431. public AjaxResult secureHandover(CallbackTaskFrom callbackTaskFrom) {
  432. if (callbackTaskFrom.getSafeCode().equals("1")){
  433. WcsTask wcsTask = new WcsTask();
  434. wcsTask.setState(new Long(13));
  435. WcsTask wcsTask1 = wcsTaskService.selectWcsTaskByModel(wcsTask);
  436. wcsTask1.setState(new Long(9));
  437. int i = wcsTaskService.updateWcsTask(wcsTask1);
  438. if (i>0){
  439. return AjaxResult.success();
  440. }
  441. }else if (callbackTaskFrom.getSafeCode().equals("0")){
  442. log.error(callbackTaskFrom.getMessage());
  443. return AjaxResult.success("未执行");
  444. }
  445. return AjaxResult.success();
  446. }
  447. /**
  448. * 出库任务下发
  449. * @return
  450. */
  451. public AjaxResult outboundRequest(OutboundForm outboundForm) {
  452. String locationFrom = "100733";
  453. String locationTo = "";
  454. String palletNo = outboundForm.getPalletNo();
  455. String wcsId = outboundForm.getWcsId();
  456. AjaxResult ajaxResult = agvCallProxyService.barrelsOutOfStorage(locationFrom, locationTo, palletNo,wcsId);
  457. if (ajaxResult.isSuccess()){
  458. return AjaxResult.success("任务创建成功");
  459. }
  460. return AjaxResult.error("任务创建失败");
  461. }
  462. /**
  463. * 回调卸货完成前
  464. * @return
  465. */
  466. public AjaxResult agvCallbackWCSBeforeUnloadingIsCompleted() {
  467. // 查询出状态为10,包含物料信息为丁铵黑药的入库单
  468. WmsDocAsnDetails wmsDocAsnDetails = new WmsDocAsnDetails();
  469. wmsDocAsnDetails.setSku("C4H9O2PSSNH4");
  470. wmsDocAsnDetails.setLineStatus(Constant.ASN_STS.STS10.getValue());
  471. WmsDocAsnDetails wmsDocAsnDetails1 = wmsDocAsnDetailsService.selectWmsDocAsnDetailsByModel(wmsDocAsnDetails);
  472. String asnNo = wmsDocAsnDetails1.getAsnNo();
  473. // 根据入库单号(Ext1)查询出所对应的任务
  474. WcsTask wcsTask = new WcsTask();
  475. wcsTask.setExt1(asnNo);
  476. WcsTask wcsTask1 = wcsTaskService.selectWcsTaskByModel(wcsTask);
  477. // 根据查出来的任务编号反馈wcs卸货完成
  478. String taskNo = wcsTask1.getTaskNo();
  479. wmsDocAsnSubService.wmsAgvCallbackIntask(taskNo);
  480. return AjaxResult.success();
  481. }
  482. }