BusinessServiceImpl.java 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. package com.ruoyi.ams.business;
  2. import cn.hutool.core.lang.Assert;
  3. import com.alibaba.fastjson.JSON;
  4. import com.ruoyi.ams.agv.ndc.common.ByteUtil;
  5. import com.ruoyi.ams.agv.ndc.common.CRC16Util;
  6. import com.ruoyi.ams.agv.ndc.domain.AmsTask;
  7. import com.ruoyi.ams.agv.ndc.service.IAmsTaskService;
  8. import com.ruoyi.ams.asn.service.IWmsDocAsnHeaderService;
  9. import com.ruoyi.ams.box.service.IWmsBoxInfoService;
  10. import com.ruoyi.ams.config.domain.AsnSoStrategy;
  11. import com.ruoyi.ams.config.domain.dto.*;
  12. import com.ruoyi.ams.config.domain.vo.FlowConfigHeaderVO;
  13. import com.ruoyi.ams.config.mapper.AsnSoStrategyMapper;
  14. import com.ruoyi.ams.config.service.IFlowConfigHeaderService;
  15. import com.ruoyi.ams.config.service.LocationAllocationStrategy;
  16. import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
  17. import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper;
  18. import com.ruoyi.ams.inv.service.IInvLotAttService;
  19. import com.ruoyi.ams.inv.service.IInvLotLocIdService;
  20. import com.ruoyi.ams.task.domain.WcsTask;
  21. import com.ruoyi.ams.task.dto.WcsTaskLocationDTO;
  22. import com.ruoyi.ams.task.mapper.WcsTaskMapper;
  23. import com.ruoyi.ams.task.service.IWcsTaskService;
  24. import com.ruoyi.base.constant.Constant;
  25. import com.ruoyi.base.domain.BaseLocationInfo;
  26. import com.ruoyi.base.domain.BaseLocationZone;
  27. import com.ruoyi.base.domain.BaseSku;
  28. import com.ruoyi.base.domain.dto.BaseLocationInfoSameColDTO;
  29. import com.ruoyi.base.domain.vo.BaseLocationLotattVO;
  30. import com.ruoyi.base.mapper.BaseLocationInfoMapper;
  31. import com.ruoyi.base.service.IBaseLocationInfoService;
  32. import com.ruoyi.base.service.IBaseSkuService;
  33. import com.ruoyi.common.core.domain.AjaxResult;
  34. import com.ruoyi.common.core.redis.RedisCache;
  35. import com.ruoyi.common.core.redis.RedisKey;
  36. import com.ruoyi.common.exception.ServiceException;
  37. import com.ruoyi.common.utils.StringUtils;
  38. import com.ruoyi.common.utils.uuid.SnowflakeIdWorker;
  39. import lombok.extern.slf4j.Slf4j;
  40. import org.springframework.beans.factory.annotation.Autowired;
  41. import org.springframework.stereotype.Service;
  42. import org.springframework.transaction.annotation.Transactional;
  43. import java.math.BigDecimal;
  44. import java.util.*;
  45. import java.util.stream.Collectors;
  46. @Slf4j
  47. @Service
  48. public class BusinessServiceImpl implements IBusinessService {
  49. @Autowired
  50. private IBusinessService businessService;
  51. @Autowired
  52. private IBaseLocationInfoService baseLocationInfoService;
  53. @Autowired
  54. private LocationAllocationStrategy locationAllocationStrategy;
  55. @Autowired
  56. private InvLotLocIdMapper invLotLocIdMapper;
  57. @Autowired
  58. private IInvLotLocIdService invLotLocIdService;
  59. @Autowired
  60. private IInvLotAttService iInvLotAttService;
  61. @Autowired
  62. private WcsTaskMapper wcsTaskMapper;
  63. @Autowired
  64. private AsnSoStrategyMapper asnSoStrategyMapper;
  65. @Autowired
  66. private BaseLocationInfoMapper baseLocationInfoMapper;
  67. @Autowired
  68. private IBaseSkuService baseSkuService;
  69. @Autowired
  70. private RedisCache redisCache;
  71. @Autowired
  72. private IWmsDocAsnHeaderService wmsDocAsnHeaderService;
  73. @Autowired
  74. private IWmsBoxInfoService wmsBoxInfoService;
  75. @Autowired
  76. private IWcsTaskService wcsTaskService;
  77. @Autowired
  78. private IAmsTaskService amsTaskService;
  79. @Autowired
  80. private IFlowConfigHeaderService flowConfigHeaderService;
  81. public static int geniKey(String taskNo) {
  82. int res = CRC16Util.calcCrc16(ByteUtil.string2byteArray(taskNo));
  83. if (res == 0) {
  84. BigDecimal t = new BigDecimal(taskNo);
  85. t = t.add(BigDecimal.ONE);
  86. return geniKey(t.toString());
  87. } else {
  88. return res;
  89. }
  90. }
  91. @Transactional
  92. @Override
  93. public AjaxResult agvCall(Long flowId, AgvCallDTO agvCallDTO) {
  94. //查询所属流程
  95. FlowConfigHeaderVO flowConfigHeaderVO = flowConfigHeaderService.selectFlowConfigHeaderById(flowId);
  96. List<AgvCallDTO> agvCallDTOList = new ArrayList<>();
  97. agvCallDTO.setWarehouseId(Constant.WAREHOUSE_ID);
  98. agvCallDTOList.add(agvCallDTO);
  99. return businessService.agvCall(flowConfigHeaderVO, agvCallDTOList);
  100. }
  101. @Transactional
  102. @Override
  103. public AjaxResult agvCall(FlowConfigHeaderVO flowConfigHeaderVO, AgvCallDTO agvCallDTO) {
  104. List<AgvCallDTO> agvCallDTOList = new ArrayList<>();
  105. List<AgvCallItemDTO> callItemDTOList = new ArrayList<>();
  106. AgvCallItemDTO callItemDTO = new AgvCallItemDTO();
  107. callItemDTO.setLotattDTO(new LotattDTO());
  108. callItemDTO.setExtParam(agvCallDTO.getExtParam());
  109. callItemDTOList.add(callItemDTO);
  110. agvCallDTO.setAgvCallItemDTOList(callItemDTOList);
  111. agvCallDTOList.add(agvCallDTO);
  112. return businessService.agvCall(flowConfigHeaderVO, agvCallDTOList);
  113. }
  114. @Transactional
  115. @Override
  116. public AjaxResult agvCall(FlowConfigHeaderVO flowConfigHeaderVO, List<AgvCallDTO> agvCallDTOList) {
  117. //唯一操作标识,用于redis标记。报错时根据该id进行删除
  118. Long token = SnowflakeIdWorker.generateId();
  119. try {
  120. //查询全局配置策略
  121. AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy();
  122. for (AgvCallDTO agvCallDTO : agvCallDTOList) {
  123. //如果是入库把起始库位相同的数据整合到一起生成库存记录
  124. BaseLocationInfo locationFrom = null;
  125. BaseLocationInfo locationTo = null;
  126. List<WcsTask> wcsTaskList = new ArrayList<>();
  127. String paramLocationFrom = agvCallDTO.getLocationFrom();
  128. String paramLocationTo = agvCallDTO.getLocationTo();
  129. List<String> zoneIdList = new ArrayList<>();
  130. if (StringUtils.isEmpty(paramLocationFrom)) {
  131. paramLocationFrom = flowConfigHeaderVO.getLocationFrom();
  132. }
  133. if (StringUtils.isEmpty(paramLocationTo)) {
  134. paramLocationTo = flowConfigHeaderVO.getLocationTo();
  135. }
  136. if (!StringUtils.isEmpty(flowConfigHeaderVO.getLocationFrom())) {
  137. zoneIdList = Arrays.stream(flowConfigHeaderVO.getLocationFrom().split(",")).collect(Collectors.toList());
  138. }
  139. if (flowConfigHeaderVO.getFlowType().equals("ASN")) {
  140. List<BaseLocationInfo> locationFromList = this.convertLocation(paramLocationFrom, agvCallDTO.getWarehouseId(), null);
  141. List<BaseLocationInfo> locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId(), null);
  142. // ASN类型的且要到仓储区的任务进行判断入库条件
  143. if (flowConfigHeaderVO.getId().equals(Long.valueOf("9")) || flowConfigHeaderVO.getId().equals(Long.valueOf("10"))
  144. || flowConfigHeaderVO.getId().equals(Long.valueOf("12"))
  145. || flowConfigHeaderVO.getId().equals(Long.valueOf("13"))){
  146. // 查询同班组的库存
  147. List<AgvCallItemDTO> agvCallItemDTOList = agvCallDTO.getAgvCallItemDTOList();
  148. if (agvCallItemDTOList != null && agvCallItemDTOList.size() >= 0){
  149. String team = agvCallItemDTOList.get(0).getLotattDTO().getLotatt09();
  150. List<BaseLocationInfo> locationInfos = new ArrayList();
  151. String currentColNo = null;// 当前列
  152. Long currentZoneId = null; // 当前库区
  153. for(BaseLocationInfo baseLocationInfo : locationToList){
  154. if (baseLocationInfo.getColNo().equals(currentColNo) && baseLocationInfo.getZoneId().equals(currentZoneId)){
  155. continue;
  156. }
  157. // 标记当前列分配
  158. Boolean columnAvailable = true;
  159. // 查询当前库位的库存包含批次属性
  160. List<InvLotLocIdLotattVO> invLotLocIdLotattVOS = invLotLocIdService.selectInvLocIdLotattByLocationId(baseLocationInfo.getId());
  161. for (InvLotLocIdLotattVO invLotLocIdLotattVO : invLotLocIdLotattVOS){
  162. // 库存当前某列有不同班组
  163. if (Objects.nonNull(invLotLocIdLotattVO) && !invLotLocIdLotattVO.getLotatt09().equals(team)){
  164. // 标记当前列不分配
  165. columnAvailable = false;
  166. currentColNo = baseLocationInfo.getColNo();
  167. currentZoneId = baseLocationInfo.getZoneId();
  168. log.info("==========当前库位有不同班组批次{}{}",baseLocationInfo,invLotLocIdLotattVO.getLotatt09());
  169. break;
  170. }
  171. }
  172. if (columnAvailable){ // 当前列同班组或者为空
  173. // 判断当前库位同列是否有不同类型任务
  174. List<BaseLocationInfo> blsList = baseLocationInfoService.selectWcsSameColumnAndTeamNotFinish(baseLocationInfo.getColNo(),
  175. team, baseLocationInfo.getZoneId(), Constant.WAREHOUSE_ID, "ASN");
  176. // 当前列有不同类型未完成任务 继续遍历下一库位
  177. if (blsList != null && blsList.size() > 0){
  178. log.info("==========当前库位同列有未完成的出库任务,库位编号{}列{}",baseLocationInfo.getId(),baseLocationInfo.getColNo());
  179. continue;
  180. }
  181. locationInfos.add(baseLocationInfo);
  182. }
  183. }
  184. locationToList = locationInfos;
  185. }
  186. }
  187. locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "ASN", asnSoStrategy, token, flowConfigHeaderVO.getId());
  188. locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "ASN", asnSoStrategy, token, flowConfigHeaderVO.getId());
  189. // 初始化库存
  190. if (agvCallDTO.getAgvCallItemDTOList().size() > 0) {
  191. iInvLotAttService.deleteInvLotAttBylocationId(locationFrom.getId());
  192. invLotLocIdService.deleteInvLotLocIdById(locationFrom.getId());
  193. invLotLocIdService.initInv(locationFrom.getId().toString(), agvCallDTO);
  194. }
  195. wcsTaskList.addAll(this.genTask(locationFrom, locationTo, flowConfigHeaderVO, agvCallDTO, token));
  196. } else if (flowConfigHeaderVO.getFlowType().equals("SO")) {
  197. List<BaseLocationInfo> locationFromListEnd = new ArrayList<>();
  198. boolean isLocation = baseLocationInfoService.checkIsLocation(paramLocationFrom, Constant.WAREHOUSE_ID);
  199. if (isLocation) {
  200. BaseLocationInfo info = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(paramLocationFrom, Constant.WAREHOUSE_ID);
  201. locationFromListEnd.add(info);
  202. }
  203. if (locationFromListEnd.size() == 0) {
  204. AgvCallItemDTO agvCall = agvCallDTO.getAgvCallItemDTOList().size() == 0
  205. ? new AgvCallItemDTO() : agvCallDTO.getAgvCallItemDTOList().get(0);
  206. HashMap<String, String> hashMap = JSON.parseObject(JSON.toJSONString(agvCall.getLotattDTO()), HashMap.class);
  207. List<BaseLocationInfo> locationFromList = baseLocationInfoMapper.selectSortedLocationLotattListByZoneIdListOrderBy(zoneIdList
  208. , agvCallDTO.getWarehouseId(), hashMap, agvCall.getSku(), "inv.create_time");
  209. locationFromListEnd = locationFromList;
  210. }
  211. List<BaseLocationInfo> locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId(), null);
  212. // 如果是从仓储区出库的任务 检查同列未完成任务类型是否相同
  213. if (flowConfigHeaderVO.getId().equals(Long.valueOf("14")) || flowConfigHeaderVO.getId().equals(Long.valueOf("15"))){
  214. Assert.isTrue(checkWcsSameColumnNotFinish(locationFromListEnd, "SO"),"同列有未完成的入库任务");
  215. }
  216. locationFrom = this.zoneLocationAllocation(locationFromListEnd, "locationFrom", "SO", asnSoStrategy, token, flowConfigHeaderVO.getId());
  217. locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "SO", asnSoStrategy, token, flowConfigHeaderVO.getId());
  218. wcsTaskList.addAll(this.genTask(locationFrom, locationTo, flowConfigHeaderVO, agvCallDTO, token));
  219. } else if (flowConfigHeaderVO.getFlowType().equals("MV")) {
  220. List<BaseLocationInfo> locationFromList = this.convertLocation(paramLocationFrom, agvCallDTO.getWarehouseId(), null);
  221. List<BaseLocationInfo> locationToList = this.convertLocation(paramLocationTo, agvCallDTO.getWarehouseId(), null);
  222. locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "MV", asnSoStrategy, token, flowConfigHeaderVO.getId());
  223. locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "MV", asnSoStrategy, token, flowConfigHeaderVO.getId());
  224. // 初始化库存
  225. if (agvCallDTO.getAgvCallItemDTOList().size() > 0) {
  226. iInvLotAttService.deleteInvLotAttBylocationId(locationFrom.getId());
  227. invLotLocIdService.deleteInvLotLocIdById(locationFrom.getId());
  228. invLotLocIdService.initInv(locationFrom.getId().toString(), agvCallDTO);
  229. }
  230. wcsTaskList.addAll(this.genTask(locationFrom, locationTo, flowConfigHeaderVO, agvCallDTO, token));
  231. }
  232. }
  233. return AjaxResult.success("任务下发成功");
  234. } catch (Exception e) {
  235. log.error("任务下发失败!", e);
  236. redisCache.unlockCacheObject(token); // 异常捕获的话就不能释放锁
  237. throw new ServiceException(e.getMessage(), token);
  238. }
  239. }
  240. /**
  241. * 检查同列的未完成任务类型是否与当前任务类型一致
  242. * @param baseLocationInfoList
  243. * @param type
  244. * @return
  245. */
  246. public Boolean checkWcsSameColumnNotFinish(List<BaseLocationInfo> baseLocationInfoList,String type){
  247. log.info("检查同列的未完成任务类型是否与当前任务类型一致============");
  248. for(BaseLocationInfo locationInfo: baseLocationInfoList){
  249. // 查询任务状态不为2(完成),6(卸货完成),7(取消)的同列任务
  250. List<BaseLocationInfo> blsList = baseLocationInfoService.selectWcsSameColumnNotFinish(locationInfo.getColNo(),
  251. locationInfo.getColIndex(), locationInfo.getZoneId(), Constant.WAREHOUSE_ID, type);
  252. // 如果同列有不同类型的未完成任务
  253. if (blsList != null && blsList.size() > 0){
  254. return false;
  255. }
  256. }
  257. return true;
  258. }
  259. /**
  260. * 检查同列的未完成任务类型及班组是否与当前任务类型一致
  261. * @param baseLocationInfoList
  262. * @param type
  263. * @return
  264. */
  265. public List<BaseLocationInfo> checkWcsSameColumnAndTeamNotFinish(List<BaseLocationInfo> baseLocationInfoList,String type,String team){
  266. log.info("检查同列的未完成任务类型及班组是否与当前任务类型一致============");
  267. List<BaseLocationInfo> resultList = new ArrayList<>();
  268. for(BaseLocationInfo locationInfo: baseLocationInfoList){
  269. // 查询任务状态不为2(完成),6(卸货完成),7(取消)的同列任务
  270. List<BaseLocationInfo> blsList = baseLocationInfoService.selectWcsSameColumnAndTeamNotFinish(locationInfo.getColNo(),
  271. team, locationInfo.getZoneId(), Constant.WAREHOUSE_ID, type);
  272. // 如果同列有不同类型的未完成任务
  273. if (blsList != null && blsList.size() > 0){
  274. resultList.addAll(blsList);
  275. }
  276. }
  277. return resultList;
  278. }
  279. @Transactional
  280. @Override
  281. public BaseLocationInfo inLocationAllocation(InWarehouseDTO inWarehouseDTO, Long token) {
  282. /**
  283. * 根据sku查询可以存放的zone
  284. * 根据每个zone的配置去分配可以存放的库位
  285. *
  286. * force
  287. * optimization
  288. * ignore
  289. */
  290. if (!StringUtils.isEmpty(inWarehouseDTO.getLocationTo())) { //指定库位则直接返回库位
  291. BaseLocationInfo baseLocationInfo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(inWarehouseDTO.getLocationTo(), inWarehouseDTO.getWarehouseId());
  292. return baseLocationInfo;
  293. } else {
  294. if (StringUtils.isEmpty(inWarehouseDTO.getLocationZoneTo()) && StringUtils.isEmpty(inWarehouseDTO.getLocationTo())) { //不指定目标库位和区域
  295. // 没有指定目标的根据sku进行匹配并进行分配
  296. // 如果可以混放的区域不匹配物料也可以选择,否则只选择可以存放的区域
  297. AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy();
  298. BaseSku baseSku = baseSkuService.selectBaseSkuByCustomerId(Constant.CUSTOMER_ID, inWarehouseDTO.getSku());
  299. //判断是否强制同物料靠近,
  300. LotattDTO lotattDTO = inWarehouseDTO.getLotattDTO();
  301. Map<String, String> lotattMap = new HashMap<>();
  302. if (asnSoStrategy.getAsnSameLotatt1Flag().equals("optimization")) {
  303. lotattMap.put(asnSoStrategy.getAsnSameLotatt1Value(), lotattDTO.getAttr(asnSoStrategy.getAsnSameLotatt1Value()));
  304. }
  305. if (asnSoStrategy.getAsnSameLotatt2Flag().equals("optimization")) {
  306. lotattMap.put(asnSoStrategy.getAsnSameLotatt2Value(), lotattDTO.getAttr(asnSoStrategy.getAsnSameLotatt2Value()));
  307. }
  308. List<BaseLocationInfo> locationInfoList = new ArrayList<>();
  309. if (asnSoStrategy.getAsnSameSku().equals("force")) {
  310. List<String> colNo = baseLocationInfoMapper.selectSameSkuColNo(baseSku.getSku(), null, lotattMap);
  311. for (String s : colNo) {
  312. List<BaseLocationInfo> locs = baseLocationInfoService.selectNeighborLocation(s, null);
  313. locationInfoList.addAll(locs);
  314. }
  315. if (colNo == null || colNo.size() == 0) {
  316. colNo = baseLocationInfoMapper.selectSameSkuTypeColNo(baseSku.getSkuType(), null);
  317. for (String s : colNo) {
  318. List<BaseLocationInfo> locs = baseLocationInfoService.selectNeighborLocation(s, null);
  319. locationInfoList.addAll(locs);
  320. }
  321. }
  322. // List<BaseLocationInfo> locs = baseLocationInfoMapper.selectLocationByColNos(colNo);
  323. } else if (asnSoStrategy.getAsnSameSku().equals("optimization") || asnSoStrategy.getAsnSameSkuType().equals("optimization")) {
  324. List<String> skuColNo = baseLocationInfoMapper.selectSameSkuColNo(baseSku.getSku(), null, lotattMap);
  325. List<String> skuTypeColNo = baseLocationInfoMapper.selectSameSkuColNo(baseSku.getSkuType(), null, lotattMap);
  326. List<String> cols = new ArrayList<>();
  327. cols.addAll(skuColNo);
  328. cols.addAll(skuTypeColNo);
  329. List<BaseLocationInfo> locs = baseLocationInfoMapper.selectLocationByColNos(cols);
  330. locationInfoList.addAll(locs);
  331. } else {
  332. locationInfoList = baseLocationInfoMapper.selectLocationBindSku(baseSku.getSkuType());
  333. }
  334. return locationAllocationStrategy.filterLockLocation(locationInfoList, inWarehouseDTO, asnSoStrategy, token);
  335. } else {
  336. // 指定区域的
  337. List<BaseLocationInfo> locationInfoList = baseLocationInfoService.selectSortedLocatinListByZoneId(Long.parseLong(inWarehouseDTO.getLocationZoneTo()), inWarehouseDTO.getWarehouseId(), null);
  338. return locationAllocationStrategy.filterLockLocation(locationInfoList, token);
  339. }
  340. }
  341. }
  342. @Transactional
  343. @Override
  344. public BaseLocationInfo outInvAllocation(OutWarehouseDTO outWarehouseDTO, Long token) {
  345. /**
  346. * 指定位置出库
  347. */
  348. if (!StringUtils.isEmpty(outWarehouseDTO.getLocationFrom())) {
  349. BaseLocationInfo baseLocationInfo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(outWarehouseDTO.getLocationFrom(), outWarehouseDTO.getWarehouseId());
  350. return baseLocationInfo;
  351. } else {
  352. //未指定明确位置出库
  353. List<Long> zoneIdList = new ArrayList<>();
  354. if (!StringUtils.isEmpty(outWarehouseDTO.getLocationZoneFrom())) {
  355. zoneIdList.add(Long.parseLong(outWarehouseDTO.getLocationZoneFrom()));
  356. } else {
  357. List<BaseLocationLotattVO> zoneList = invLotLocIdMapper.selectInvZoneBySkuLotatt(outWarehouseDTO.getSku(), outWarehouseDTO.getSkuType(), outWarehouseDTO.getLotattDTO());
  358. for (BaseLocationLotattVO vo : zoneList) {
  359. zoneIdList.add(vo.getZoneId());
  360. }
  361. }
  362. LotattDTO lotattDTO = outWarehouseDTO.getLotattDTO();
  363. List<BaseLocationLotattVO> locationInfoList = baseLocationInfoMapper.selectSortedLocationLotattListByZoneIdList(zoneIdList, outWarehouseDTO.getWarehouseId(), lotattDTO.getAttr());
  364. AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy();
  365. return locationAllocationStrategy.filterLockInv(locationInfoList, outWarehouseDTO, asnSoStrategy, token);
  366. }
  367. }
  368. @Override
  369. public BaseLocationInfo zoneLocationAllocation(List<BaseLocationInfo> locationInfoList, String locationType
  370. , String type, AsnSoStrategy asnSoStrategy, Long token, Long flowId) {
  371. BaseLocationInfo locationInfo = null;
  372. String fromMsg = "";
  373. String toMsg = "";
  374. if (type.equals("ASN")) { // 入库
  375. if (locationType.equals("locationFrom")) {
  376. } else { //目标库位
  377. }
  378. } else if (type.equals("SO")) { // 出库
  379. if (locationType.equals("locationFrom")) {
  380. } else { //目标库位
  381. }
  382. } else { //移库
  383. if (locationType.equals("locationFrom")) {
  384. } else {
  385. }
  386. }
  387. if (locationType.equals("locationFrom")) {
  388. // 如果是从仓储区出库 调用无需判断阻挡的方法
  389. if (type.equals("SO") && (flowId.equals(Long.valueOf("14")) || flowId.equals(Long.valueOf("15")))){
  390. locationInfo = checkTheSameColumnLocationSO(locationInfoList, token);
  391. }else {
  392. locationInfo = checkTheSameColumnLocation(locationInfoList, token, false);
  393. }
  394. if (locationInfo == null) {
  395. if (type.equals("ASN")) { // 入库
  396. fromMsg = "起始点没有可以分配的库存!";
  397. } else if (type.equals("SO")) { // 出库
  398. fromMsg = "起始点没有可以分配的库存!";
  399. } else { //移库
  400. fromMsg = "起始点没有可以分配的库位";
  401. }
  402. throw new ServiceException(fromMsg, token);
  403. }
  404. } else {
  405. // 是到仓储区的入库任务
  406. if (type.equals("ASN") && !flowId.equals(Long.valueOf("8")) && !flowId.equals(Long.valueOf("11"))){
  407. locationInfo = checkTheSameColumnLocationASN(locationInfoList, token, true);
  408. }else {
  409. locationInfo = checkTheSameColumnLocation(locationInfoList, token, true);
  410. }
  411. if (locationInfo == null) {
  412. if (type.equals("ASN")) { // 入库
  413. toMsg = "目标点没有可以分配的库位";
  414. } else if (type.equals("SO")) { // 出库
  415. toMsg = "目标点没有可以分配的库位";
  416. } else { //移库
  417. toMsg = "目标点没有可以分配的库位";
  418. }
  419. throw new ServiceException(toMsg, token);
  420. }
  421. }
  422. return locationInfo;
  423. }
  424. /**
  425. * 入库判断目标点位
  426. * @param locationInfoList
  427. * @param token
  428. * @param isReleaseGoods
  429. * @return
  430. */
  431. private BaseLocationInfo checkTheSameColumnLocationASN(List<BaseLocationInfo> locationInfoList, Long token, boolean isReleaseGoods) {
  432. BaseLocationInfo basLocation = null;
  433. //筛选2次 第2次去除同列占用和阻挡条件 todo 先筛选一次吧
  434. for (int i = 0; i < 1 && basLocation == null; i++) {
  435. for (BaseLocationInfo location : locationInfoList) {
  436. // 目标点位必须空闲、空且没有被锁住
  437. if (!location.getStockStatus().equals(Constant.STOCK_STATUS.STOCK00.getValue())
  438. || !location.getIsEmpty().equals(Constant.IS_YES.Y.name())
  439. || redisCache.checkIsLock(RedisKey.LOCK_LOCATION + location.getId())) {
  440. continue;
  441. }
  442. if (!redisCache.lockCacheObject(RedisKey.LOCK_LOCATION + location.getId()
  443. , location.getId().toString()
  444. , token)) {
  445. continue;
  446. }
  447. basLocation = location;
  448. break;
  449. }
  450. }
  451. return basLocation;
  452. }
  453. /**
  454. * 校验同列任务任务状态和阻挡
  455. *
  456. * @param basLocationList
  457. * @param token
  458. * @param isReleaseGoods 是否目标点位
  459. * @return
  460. */
  461. public BaseLocationInfo checkTheSameColumnLocation(List<BaseLocationInfo> basLocationList, Long token, boolean isReleaseGoods) {
  462. boolean isBlock = false; // 是否阻挡
  463. BaseLocationInfo basLocation = null;
  464. //筛选2次 第2次去除同列占用和阻挡条件 todo 先筛选一次吧
  465. for (int i = 0; i < 1 && basLocation == null; i++) {
  466. for (BaseLocationInfo location : basLocationList) {
  467. //如果库位类型不为地堆则不用判断同列占用和阻挡
  468. if (location.getLocationType().equals("2")) {
  469. isBlock = true;
  470. }
  471. //只有第一次判断同列任务占用和阻挡
  472. if (i == 0 && isBlock) {
  473. //同列是否有任务
  474. List<BaseLocationInfo> occupyByLocs = baseLocationInfoMapper.queryByListOccupyByLoc(location);
  475. if (occupyByLocs.size() > 0) {
  476. log.info("同列有任务=========={}",occupyByLocs);
  477. continue;
  478. }
  479. //同列前方是否有阻挡
  480. List<BaseLocationInfo> inStockByLocs = baseLocationInfoMapper.queryByListInStockByLoc(location);
  481. if (inStockByLocs.size() > 0) {
  482. log.info("同列有阻挡=========={}",inStockByLocs);
  483. continue;
  484. }
  485. }
  486. // 是否目标点
  487. if (!isReleaseGoods) { // 起始点位状态必须空闲且没有被锁住
  488. if (!location.getStockStatus().equals(Constant.STOCK_STATUS.STOCK00.getValue())
  489. || redisCache.checkIsLock(RedisKey.LOCK_LOCATION + location.getId())) {
  490. continue;
  491. }
  492. } else { // 目标点状态为空闲、空、且没有被锁住
  493. if (!location.getStockStatus().equals(Constant.STOCK_STATUS.STOCK00.getValue())
  494. || !location.getIsEmpty().equals(Constant.IS_YES.Y.name())
  495. || redisCache.checkIsLock(RedisKey.LOCK_LOCATION + location.getId())) {
  496. continue;
  497. }
  498. }
  499. if (!redisCache.lockCacheObject(RedisKey.LOCK_LOCATION + location.getId()
  500. , location.getId().toString()
  501. , token)) {
  502. continue;
  503. }
  504. basLocation = location;
  505. break;
  506. }
  507. }
  508. return basLocation;
  509. }
  510. /**
  511. * AGV出库任务生成时的起始位置不判断是否阻挡
  512. * @param basLocationList
  513. * @param token
  514. * @return
  515. */
  516. public BaseLocationInfo checkTheSameColumnLocationSO(List<BaseLocationInfo> basLocationList, Long token) {
  517. BaseLocationInfo basLocation = null;
  518. //筛选2次 第2次去除同列占用和阻挡条件 todo 先筛选一次吧
  519. for (int i = 0; i < 1 && basLocation == null; i++) {
  520. for (BaseLocationInfo location : basLocationList) {
  521. // 起始点位状态必须空闲且没有被锁住
  522. if (!location.getStockStatus().equals(Constant.STOCK_STATUS.STOCK00.getValue())
  523. || redisCache.checkIsLock(RedisKey.LOCK_LOCATION + location.getId())) {
  524. continue;
  525. }
  526. if (!redisCache.lockCacheObject(RedisKey.LOCK_LOCATION + location.getId()
  527. , location.getId().toString()
  528. , token)) {
  529. continue;
  530. }
  531. basLocation = location;
  532. break;
  533. }
  534. }
  535. return basLocation;
  536. }
  537. @Override
  538. public List<BaseLocationInfo> convertLocation(String locationNoOrZoneId, Long warehouseId, String orderBy) {
  539. List<BaseLocationInfo> locationInfoList = new ArrayList<>();
  540. if (!StringUtils.isEmpty(locationNoOrZoneId)) {
  541. String[] arr = locationNoOrZoneId.split(",");
  542. for (String obj : arr) {
  543. boolean isLocation = baseLocationInfoService.checkIsLocation(obj, warehouseId);
  544. if (isLocation) {
  545. BaseLocationInfo info = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(obj, warehouseId);
  546. locationInfoList.add(info);
  547. } else {
  548. List<BaseLocationInfo> infoList = baseLocationInfoService.selectSortedLocatinListByZoneId(Long.parseLong(obj), warehouseId, orderBy);
  549. locationInfoList.addAll(infoList);
  550. }
  551. }
  552. }
  553. return locationInfoList;
  554. }
  555. @Override
  556. public List<WcsTask> genTask(BaseLocationInfo locationFrom, BaseLocationInfo locationTo, FlowConfigHeaderVO flowConfigHeaderVO, AgvCallDTO agvCallDTO, Long token) {
  557. if (flowConfigHeaderVO.getLocationFromStrategyFlag().equals("N")) {
  558. if (locationFrom == null) {
  559. throw new ServiceException("起始库位不能为空", token);
  560. }
  561. }
  562. if (flowConfigHeaderVO.getLocationToStrategyFlag().equals("N")) {
  563. if (locationTo == null) {
  564. throw new ServiceException("目标库位不能为空", token);
  565. }
  566. }
  567. List<WcsTask> wcsTaskList = new ArrayList<>();
  568. if (StringUtils.isEmpty(flowConfigHeaderVO.getRootFlow())) {
  569. String taskNo = System.currentTimeMillis() + "";
  570. WcsTask wcsTask = new WcsTask();
  571. wcsTask.setTaskNo(taskNo);
  572. if (locationFrom != null) {
  573. wcsTask.setAreaFrom(locationFrom.getZoneId().toString());
  574. wcsTask.setLocationFrom(locationFrom.getId().toString());
  575. }
  576. if (locationTo != null) {
  577. wcsTask.setAreaTo(locationTo.getZoneId() + "");
  578. wcsTask.setLocationTo(locationTo.getId().toString());
  579. }
  580. wcsTask.setState(9L);
  581. wcsTask.setPriority(1L);
  582. wcsTask.setShopId(Constant.WAREHOUSE_ID.toString());
  583. wcsTask.setCreateDate(new Date());
  584. wcsTask.setCreateUser(agvCallDTO.getCreateUser());
  585. wcsTask.setBusinessType("01");
  586. wcsTask.setTaskType(Constant.TASK_TYPE.FORWARD.getValue());
  587. wcsTask.setExt8(token.toString());
  588. wcsTask.setExt7(flowConfigHeaderVO.getId().toString());
  589. // 是否复称
  590. wcsTask.setExt3(agvCallDTO.getTheWeighing() == null ? "0000"
  591. : agvCallDTO.getTheWeighing() ? "0001" : "0000");
  592. wcsTask.setExtParam(agvCallDTO.getExtParam());
  593. wcsTaskList.add(wcsTask);
  594. businessService.addTask(wcsTask);
  595. } else {
  596. /*//获取对应的流程
  597. List<FlowConfigHeader> headerVOList = flowConfigHeaderService.sortFlowConfigHeader(Long.parseLong(flowConfigHeaderVO.getRootFlow()));
  598. AsnSoStrategy asnSoStrategy = asnSoStrategyMapper.selectAsnSoStrategy();
  599. String taskNo = System.currentTimeMillis() + "";
  600. WcsTask wcsTask = new WcsTask();
  601. wcsTask.setTaskNo(taskNo);
  602. wcsTask.setAreaFrom(locationFrom.getZoneId().toString());
  603. wcsTask.setLocationFrom(locationFrom.getId().toString());
  604. wcsTask.setAreaTo(locationTo.getZoneId() + "");
  605. wcsTask.setLocationTo(locationTo.getId().toString());
  606. wcsTask.setState(9L);
  607. wcsTask.setPriority(1L);
  608. wcsTask.setCreateDate(new Date());
  609. wcsTask.setBusinessType("01");
  610. wcsTask.setTaskType("");
  611. wcsTaskList.add(wcsTask);
  612. String beforeTaskNo = taskNo;
  613. for (FlowConfigHeader flowConfigHeader : headerVOList) {
  614. if (StringUtils.isEmpty(flowConfigHeader.getRelFlow()) && flowConfigHeader.getRootFlow().equals(flowConfigHeader.getId().toString())) {
  615. continue;
  616. }
  617. List<BaseLocationInfo> locationFromList = this.convertLocation(flowConfigHeader.getLocationFrom(), 1L);
  618. List<BaseLocationInfo> locationToList = this.convertLocation(flowConfigHeader.getLocationTo(), 1L);
  619. locationFrom = this.zoneLocationAllocation(locationFromList, "locationFrom", "MV", null, null);
  620. locationTo = this.zoneLocationAllocation(locationToList, "locationTo", "MV", null, null);
  621. String currentNo = SnowflakeIdWorker.generateId().toString();
  622. WcsTask child = new WcsTask();
  623. child.setTaskNo(currentNo);
  624. child.setParentTask(taskNo);
  625. child.setBeforeTask(beforeTaskNo);
  626. child.setAreaFrom(locationFrom.getZoneId().toString());
  627. child.setLocationFrom(locationFrom.getId().toString());
  628. child.setAreaTo(locationTo.getZoneId() + "");
  629. child.setLocationTo(locationTo.getId().toString());
  630. child.setState(9L);
  631. child.setPriority(1L);
  632. child.setCreateDate(new Date());
  633. child.setBusinessType("01");
  634. child.setTaskType("");
  635. wcsTaskList.add(child);
  636. beforeTaskNo = currentNo;
  637. }*/
  638. }
  639. return wcsTaskList;
  640. }
  641. @Transactional
  642. @Override
  643. public AjaxResult addTask(WcsTask wcsTask) {
  644. //锁定库位
  645. if (!StringUtils.isEmpty(wcsTask.getLocationFrom())) {
  646. baseLocationInfoService.updateLocationStockStatus(Long.parseLong(wcsTask.getLocationFrom()), Constant.STOCK_STATUS.STOCK10.getValue());
  647. }
  648. if (!StringUtils.isEmpty(wcsTask.getLocationTo())) {
  649. baseLocationInfoService.updateLocationStockStatus(Long.parseLong(wcsTask.getLocationTo()), Constant.STOCK_STATUS.STOCK10.getValue());
  650. }
  651. Integer priority = 1;
  652. if (!wcsTask.getTaskType().equals("OB")) {
  653. if (wcsTask.getPriority() == 99) {
  654. int current = wcsTaskMapper.selectCurrentPriority();
  655. priority = current - 100;
  656. } else {
  657. int current = wcsTaskMapper.selectCurrentPriority();
  658. priority = current + 10;
  659. }
  660. } else {
  661. //倒库任务顺序由原任务中间插入不需要获取
  662. priority = wcsTask.getPriority().intValue();
  663. }
  664. wcsTask.setPriority((long) priority);
  665. int result = wcsTaskMapper.insertWcsTask(wcsTask);
  666. if (result > 0) {
  667. return AjaxResult.success("任务生成成功");
  668. } else {
  669. throw new ServiceException("任务生成失败");
  670. }
  671. }
  672. @Override
  673. public AjaxResult addTaskList(List<WcsTask> wcsTaskList) {
  674. for (WcsTask wcsTask : wcsTaskList) {
  675. //锁定库位
  676. if (!StringUtils.isEmpty(wcsTask.getLocationFrom())) {
  677. baseLocationInfoService.updateLocationStockStatus(Long.parseLong(wcsTask.getLocationFrom()), Constant.STOCK_STATUS.STOCK10.getValue());
  678. }
  679. if (!StringUtils.isEmpty(wcsTask.getLocationTo())) {
  680. baseLocationInfoService.updateLocationStockStatus(Long.parseLong(wcsTask.getLocationTo()), Constant.STOCK_STATUS.STOCK10.getValue());
  681. }
  682. Integer priority = 1;
  683. if (!wcsTask.getTaskType().equals("OB")) {
  684. if (wcsTask.getPriority() == 99) {
  685. int current = wcsTaskMapper.selectCurrentPriority();
  686. priority = current - 100;
  687. } else {
  688. int current = wcsTaskMapper.selectCurrentPriority();
  689. priority = current + 10;
  690. }
  691. } else {
  692. //倒库任务顺序由原任务中间插入不需要获取
  693. priority = wcsTask.getPriority().intValue();
  694. }
  695. wcsTask.setPriority((long) priority);
  696. int result = wcsTaskMapper.insertWcsTask(wcsTask);
  697. if (result > 0) {
  698. return AjaxResult.success("任务生成成功");
  699. } else {
  700. throw new ServiceException("任务生成失败");
  701. }
  702. }
  703. return AjaxResult.success("");
  704. }
  705. @Override
  706. public AjaxResult sendTask(WcsTask wcsTask) {
  707. BaseLocationInfo locFrom = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(wcsTask.getLocationFrom(), Constant.WAREHOUSE_ID);
  708. BaseLocationInfo locTo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(wcsTask.getLocationTo(), Constant.WAREHOUSE_ID);
  709. log.info("进入AMS任务下发=========={}",wcsTask);
  710. AmsTask amsTask = new AmsTask();
  711. amsTask.setTaskNo(wcsTask.getTaskNo());
  712. if (wcsTask.getBusinessType() == null || wcsTask.getBusinessType().equals("")) {
  713. amsTask.setBusinessType(Constant.TASK_BUSINESS_TYPE.TASK_01.getValue());
  714. } else {
  715. amsTask.setBusinessType(wcsTask.getBusinessType());
  716. }
  717. amsTask.setIsDelete(0);
  718. amsTask.setAciAccept(0);
  719. amsTask.setIkey((long) geniKey(amsTask.getTaskNo()));
  720. amsTask.setPriority(wcsTask.getPriority().intValue());
  721. amsTask.setExt1(wcsTask.getExt1());
  722. amsTask.setExt2(wcsTask.getExt2());
  723. amsTask.setExt3(wcsTask.getExt3());
  724. if(wcsTask.getBusinessType().equals(Constant.TASK_BUSINESS_TYPE.TASK_POWER.getValue())){
  725. amsTask.setStFrom(Integer.valueOf(wcsTask.getLocationFrom()));
  726. amsTask.setStTo(Integer.valueOf(wcsTask.getLocationTo()));
  727. amsTask.setDeviceName(wcsTask.getDeviceName());
  728. }else{
  729. amsTask.setStFrom(locFrom.getAgvStation().intValue());
  730. amsTask.setStTo(locTo.getAgvStation().intValue());
  731. }
  732. if (wcsTask.getBusinessType().equals("m")) {
  733. //m类消息特殊处理
  734. wcsTask.setState(2L);
  735. int result = wcsTaskService.updateWcsTask(wcsTask);
  736. if (result > 0) {
  737. //更新
  738. return AjaxResult.success("下发成功");
  739. } else {
  740. return AjaxResult.error("下发失败");
  741. }
  742. } else {
  743. int result = amsTaskService.insertAmsTask(amsTask);
  744. if (result > 0) {
  745. //更新
  746. return AjaxResult.success("下发成功");
  747. } else {
  748. return AjaxResult.error("下发失败");
  749. }
  750. }
  751. }
  752. @Override
  753. public AjaxResult sendTaskList(List<WcsTask> wcsTaskList) {
  754. return null;
  755. }
  756. @Transactional
  757. @Override
  758. public void autoSend() {
  759. List<WcsTask> wcsTaskList = wcsTaskService.selectWcsUnallocated(Constant.WAREHOUSE_ID);
  760. if (wcsTaskList != null && wcsTaskList.size() > 0) {
  761. for (WcsTask wcsTask : wcsTaskList) {
  762. //如果是充电任务直接下发
  763. if (wcsTask.getBusinessType().equals(Constant.TASK_BUSINESS_TYPE.TASK_POWER.getValue()) ||
  764. wcsTask.getBusinessType().equals(Constant.TASK_BUSINESS_TYPE.TASK_m.getValue())) {
  765. log.info("定时充电/盘点取消任务直接下发");
  766. sendTask(wcsTask);
  767. wcsTask.setState(2L);
  768. wcsTaskService.updateWcsTask(wcsTask);
  769. break;
  770. }
  771. //转发任务
  772. if (StringUtils.isNotEmpty(wcsTask.getTaskType())
  773. && wcsTask.getTaskType().equals(Constant.TASK_TYPE.FORWARD.getValue())) {
  774. log.info("进入转发任务{}=={}========", wcsTask.getTaskType(), wcsTask.getExt7());
  775. // 判断如果是出库任务
  776. if (StringUtils.isNotEmpty(wcsTask.getExt7())
  777. && (wcsTask.getExt7().equals(String.valueOf(Constant.FLOW_CONFIG_ID.FOURTEEN.getValue()))
  778. || wcsTask.getExt7().equals(String.valueOf(Constant.FLOW_CONFIG_ID.FIFTEEN.getValue())))) {
  779. log.info("出库任务下发AMS调用AGV{}", JSON.toJSONString(wcsTask));
  780. // 根据起始地查询库位信息
  781. BaseLocationInfo baseLocationInfo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(wcsTask.getLocationFrom(), Constant.WAREHOUSE_ID);
  782. //同列外方是否有任务
  783. List<BaseLocationInfo> occupyByLocs = baseLocationInfoMapper.queryByListOccupyByLoc(baseLocationInfo);
  784. if (occupyByLocs.size() > 0) {
  785. log.info("同列外面有任务=========={}", occupyByLocs);
  786. continue;
  787. }
  788. //同列前方是否有阻挡
  789. List<BaseLocationInfo> inStockByLocs = baseLocationInfoMapper.queryByListInStockByLoc(baseLocationInfo);
  790. if (inStockByLocs.size() > 0) {
  791. log.info("同列有阻挡=========={}", inStockByLocs);
  792. continue;
  793. }
  794. } else if (StringUtils.isNotEmpty(wcsTask.getExt7()) // 判断如果是入库任务
  795. && (wcsTask.getExt7().equals(String.valueOf(Constant.FLOW_CONFIG_ID.NINE.getValue()))
  796. || wcsTask.getExt7().equals(String.valueOf(Constant.FLOW_CONFIG_ID.TEN.getValue()))
  797. || wcsTask.getExt7().equals(String.valueOf(Constant.FLOW_CONFIG_ID.TWELVE.getValue()))
  798. || wcsTask.getExt7().equals(String.valueOf(Constant.FLOW_CONFIG_ID.THIRTEEN.getValue())))) {
  799. log.info("入库任务下发AMS调用AGV{}", JSON.toJSONString(wcsTask));
  800. // 根据起始地查询库位信息
  801. BaseLocationInfo baseLocationInfo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(wcsTask.getLocationFrom(), Constant.WAREHOUSE_ID);
  802. //同列里面是否有任务
  803. List<BaseLocationInfo> occupyByLocs = baseLocationInfoMapper.queryByListOccupyByLocOR(baseLocationInfo);
  804. if (occupyByLocs.size() > 0) {
  805. log.info("同列里面有任务=========={}", occupyByLocs);
  806. continue;
  807. }
  808. //同列前方是否有阻挡
  809. List<BaseLocationInfo> inStockByLocs = baseLocationInfoMapper.queryByListInStockByLoc(baseLocationInfo);
  810. if (inStockByLocs.size() > 0) {
  811. log.info("同列有阻挡=========={}", inStockByLocs);
  812. continue;
  813. }
  814. sendTask(wcsTask);
  815. wcsTask.setState(10L);
  816. wcsTaskService.updateWcsTask(wcsTask);
  817. break;
  818. }
  819. try {
  820. //任务下发判断
  821. businessService.taskDispatchStack(wcsTask);
  822. Thread.sleep(500);
  823. } catch (Exception e) {
  824. e.printStackTrace();
  825. }
  826. }
  827. }
  828. }
  829. }
  830. @Transactional
  831. @Override
  832. public void autoSendTranSit() {
  833. List<BaseLocationInfo> baseLocationInfos = baseLocationInfoService.selectSortedLocatinListByZoneId(Constant.ZONE_TYPE.TRANSIT.getValue()
  834. , Constant.WAREHOUSE_ID, null);
  835. for (BaseLocationInfo baseLocationInfo : baseLocationInfos) {
  836. // 判断是否有货并且空闲
  837. // if (baseLocationInfo.getStockStatus().equals(Constant.STOCK_STATUS.STOCK00.getValue())
  838. // && baseLocationInfo.getIsEmpty().equals(Constant.IS_YES.N.name())) {
  839. // if (baseLocationInfo.getUserdefine1().equals("ASN")) {
  840. // AgvCallDTO agvCallDTO = new AgvCallDTO();
  841. // agvCallDTO.setLocationFrom(baseLocationInfo.getLocationNo());
  842. // businessService.agvCall(Constant.TRAN_STO_FLOW_ID, agvCallDTO);
  843. // } else if (baseLocationInfo.getUserdefine1().equals("SO_HG")) {
  844. // AgvCallDTO agvCallDTO = new AgvCallDTO();
  845. // agvCallDTO.setLocationFrom(baseLocationInfo.getLocationNo());
  846. // businessService.agvCall(Constant.TRAN_OUT_FLOW_ID, agvCallDTO);
  847. // } else if (baseLocationInfo.getUserdefine1().equals("SO_BHG")) {
  848. // AgvCallDTO agvCallDTO = new AgvCallDTO();
  849. // agvCallDTO.setLocationFrom(baseLocationInfo.getLocationNo());
  850. // businessService.agvCall(Constant.TRAN_OUT_BHG_FLOW_ID, agvCallDTO);
  851. // }
  852. // }
  853. }
  854. }
  855. @Transactional
  856. @Override
  857. public boolean taskDispatchStack(WcsTask wcsTask) {
  858. /* boolean isSplit = taskService.taskSplit(wcsTask);
  859. //判断是否拆分如果拆分了直接跳过
  860. if(isSplit){
  861. return false;
  862. }*/
  863. //最后要执行的任务
  864. WcsTask currentTask = new WcsTask();
  865. //来源库位
  866. BaseLocationInfo basLocationInfoFrom = null;
  867. //目标区域
  868. BaseLocationZone basLocationZoneTo = null;
  869. //起始库位
  870. basLocationInfoFrom = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(wcsTask.getLocationFrom()));
  871. //目标库位
  872. BaseLocationInfo locationInfoTo = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(wcsTask.getLocationTo()));
  873. //TODO 前置任务未完成不进行下发
  874. if (businessService.taskDispatchCheck(wcsTask) == false) {
  875. return false;
  876. }
  877. if (basLocationInfoFrom != null) {
  878. if (basLocationInfoFrom.getIsEmpty().equals("Y")) {
  879. wcsTask.setRemark("起始库位为空无法进行任务");
  880. wcsTaskService.updateWcsTask(wcsTask);
  881. return false;
  882. }
  883. //起始库位巷道检测(起始库位检测是否同巷道)
  884. if (!StringUtils.isEmpty(basLocationInfoFrom.getColNo())) {
  885. List<BaseLocationInfo> locationInfoList = baseLocationInfoMapper.laneCheck(basLocationInfoFrom.getColNo(), "LANE_FROM", Constant.WAREHOUSE_ID);
  886. if (locationInfoList != null && locationInfoList.size() > 0) {
  887. wcsTask.setRemark("起始库位同列或同巷道有车辆在任务中,等待其他任务完成");
  888. wcsTaskService.updateWcsTask(wcsTask);
  889. return false;
  890. }
  891. }
  892. }
  893. //起始库位是地堆需要判断是否有阻挡
  894. if (basLocationInfoFrom.getLocationType().equals("2")) {
  895. //判断队列中是否有阻挡在当前任务之前
  896. List<WcsTaskLocationDTO> locationDTOS = wcsTaskService.selectTaskByColNo(basLocationInfoFrom.getColNo(), basLocationInfoFrom.getColIndex(), basLocationInfoFrom.getZoneId(), null);
  897. if (locationDTOS.size() > 0) {
  898. wcsTask.setRemark("队列中有其他任务阻挡,让其他任务先执行");
  899. wcsTaskService.updateWcsTask(wcsTask);
  900. return false;
  901. }
  902. //判断出库库位前是否有阻挡
  903. List<BaseLocationInfo> beforeLoc = baseLocationInfoService.selectBeforeLocationByColNo(basLocationInfoFrom.getColNo(), basLocationInfoFrom.getColIndex());
  904. if (beforeLoc != null) {
  905. for (BaseLocationInfo b : beforeLoc) {
  906. //如果前面库位不为空,或者状态占用
  907. //TODO 去除已经在任务中的
  908. if (b.getIsEmpty().equals("N")) {
  909. wcsTask.setRemark("有阻挡物,任务无法执行");
  910. wcsTaskService.updateWcsTask(wcsTask);
  911. return false;
  912. }
  913. }
  914. }
  915. }
  916. currentTask = wcsTask;
  917. //目标库位如果是地堆需要判断是否有阻挡
  918. if (locationInfoTo != null && locationInfoTo.getLocationType().equals("2")) {
  919. List<BaseLocationInfo> beforeLoc = baseLocationInfoService.selectBeforeLocationByColNo(locationInfoTo.getColNo(), locationInfoTo.getColIndex());
  920. if (beforeLoc != null) {
  921. for (BaseLocationInfo b : beforeLoc) {
  922. //跳过起始库位
  923. if (b.getId().equals(locationInfoTo.getId())) {
  924. continue;
  925. }
  926. //如果前面库位不为空,或者状态占用
  927. //TODO 排除已经在任务中的
  928. if (b.getIsEmpty().equals("N")) {
  929. currentTask.setRemark("目标库位前方有阻挡1");
  930. currentTask.setUpdateDate(new Date());
  931. wcsTaskService.updateWcsTask(currentTask);
  932. return false;
  933. }
  934. }
  935. }
  936. List<WcsTaskLocationDTO> dtos = wcsTaskService.selectTaskByColNoAfter(locationInfoTo.getColNo(), locationInfoTo.getColIndex(), locationInfoTo.getZoneId(), null);
  937. if (dtos != null && dtos.size() > 0) {
  938. currentTask.setRemark("目标库位同列有未完成的任务");
  939. wcsTaskService.updateWcsTask(currentTask);
  940. return false;
  941. }
  942. }
  943. //查询是否有更里面的位置可以存放
  944. if (locationInfoTo != null) {
  945. if (locationInfoTo.getZoneId() != 10) {
  946. String locationtoTmp = "";
  947. List<BaseLocationInfoSameColDTO> b = baseLocationInfoService.selectSameColCanToLoc(locationInfoTo.getColNo(), locationInfoTo.getColIndex());
  948. for (BaseLocationInfoSameColDTO bt : b) {
  949. if (bt.getIsOb() == false) {
  950. locationtoTmp = bt.getId().toString();
  951. } else {
  952. break;
  953. }
  954. }
  955. if (!StringUtils.isEmpty(locationtoTmp)) {
  956. wcsTask.setLocationTo(locationtoTmp);
  957. wcsTaskService.updateWcsTask(wcsTask);
  958. //释放原库位
  959. locationInfoTo.setStockStatus("00");
  960. baseLocationInfoService.updateBaseLocationInfo(locationInfoTo);
  961. //占用新库位
  962. BaseLocationInfo newlocationInfoTo = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(locationtoTmp));
  963. newlocationInfoTo.setStockStatus("10");
  964. baseLocationInfoService.updateBaseLocationInfo(newlocationInfoTo);
  965. }
  966. }
  967. }
  968. currentTask.setState(10L);
  969. currentTask.setRemark("");
  970. if (wcsTaskService.updateWcsTask(currentTask) > 0) {
  971. AjaxResult result = businessService.sendTask(currentTask);
  972. if ((int) result.get(AjaxResult.CODE_TAG) == 500) {
  973. throw new ServiceException("自动下发任务失败:" + result.get("msg"));
  974. }
  975. return true;
  976. } else {
  977. return false;
  978. }
  979. }
  980. @Override
  981. public boolean taskDispatchCheck(WcsTask wcsTask) {
  982. if (!StringUtils.isEmpty(wcsTask.getBeforeTask())) {
  983. List<WcsTask> taskFindBeforeRecord = wcsTaskMapper.selectBeforeTask(wcsTask.getBeforeTask());
  984. if (taskFindBeforeRecord != null && taskFindBeforeRecord.size() > 0) {
  985. //log.info("前置任务未完成主任务无法下发{}",wcsTask);
  986. wcsTask.setRemark("前置任务未完成主任务无法下发");
  987. wcsTaskService.updateWcsTask(wcsTask);
  988. return false;
  989. }
  990. }
  991. return true;
  992. }
  993. }