Commit e5229a67805aaf01af7d70042c4b2fe2dfd8d2da

Authored by 易文鹏
1 parent 4806bbb2

feat:优化自动出库

src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java
... ... @@ -42,10 +42,10 @@ public class ArrivedNoticeController extends BaseController {
42 42  
43 43 @PostMapping("/arrivedNotice")
44 44 @ApiOperation("到达拣选台")
45   - @ApiLogger(apiName = "wcs到达拣选台", from="ROBOT")
  45 + @ApiLogger(apiName = "wcs到达拣选台", from = "ROBOT")
46 46 @Transactional(rollbackFor = Exception.class)
47 47 @ResponseBody
48   - public AjaxResult arrivedNotice(@RequestBody Map<String,String> map) {
  48 + public AjaxResult arrivedNotice(@RequestBody Map<String, String> map) {
49 49 //String warehouseCode = "CS0001";
50 50 String taskNo = map.get("taskNo");
51 51 //String port = map.get("port");
... ... @@ -54,18 +54,17 @@ public class ArrivedNoticeController extends BaseController {
54 54 LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
55 55 taskHeaderLambdaQueryWrapper.eq(TaskHeader::getId, taskNo);
56 56 TaskHeader taskHeader = taskHeaderService.getOne(taskHeaderLambdaQueryWrapper);
57   - if(taskHeader != null) {
  57 + if (taskHeader != null) {
  58 + int status = taskHeader.getStatus();
  59 + if (status == QuantityConstant.TASK_STATUS_COMPLETED) {
  60 + return AjaxResult.success("更新到达站台成功, 任务已经完成,不要重复更新");
  61 + }
58 62 taskHeader.setStatus(QuantityConstant.TASK_STATUS_ARRIVED_STATION);
59 63 } else {
60 64 return AjaxResult.error("没有找到任务taskNo:" + taskNo);
61 65 }
62   - //int taskType = taskHeader.getTaskType();
63   - int status = taskHeader.getStatus();
64   - if(status == QuantityConstant.TASK_STATUS_COMPLETED) {
65   - return AjaxResult.success("更新到达站台成功, 任务已经完成");
66   - }
67 66 boolean result = taskHeaderService.updateById(taskHeader);
68   - if(!result) {
  67 + if (!result) {
69 68 return AjaxResult.error("更新到达站台失败");
70 69 }
71 70 return AjaxResult.success("更新到达站台成功");
... ...
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java
... ... @@ -48,6 +48,8 @@ public interface InventoryDetailService extends IService&lt;InventoryDetail&gt; {
48 48 * @return
49 49 */
50 50 List<InventoryDetail> queryReceiptDetailById(Integer inventoryHeaderId);
  51 +
  52 + InventoryDetail getByIdForUpdate(Integer toInventoryId);
51 53 }
52 54  
53 55  
... ...
src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java
... ... @@ -286,6 +286,14 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
286 286 return this.list(lam);
287 287 }
288 288  
  289 + @Override
  290 + public InventoryDetail getByIdForUpdate(Integer toInventoryId) {
  291 + LambdaQueryWrapper<InventoryDetail> queryWrapper = new LambdaQueryWrapper<>();
  292 + return inventoryDetailMapper.selectOne(queryWrapper
  293 + .eq(InventoryDetail::getId, toInventoryId)
  294 + .last("FOR UPDATE"));
  295 + }
  296 +
289 297 }
290 298  
291 299  
... ...
src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java
... ... @@ -63,7 +63,7 @@ public interface InventoryHeaderService extends IService&lt;InventoryHeader&gt; {
63 63 */
64 64 AjaxResult getLocationForecast(String code, int type);
65 65  
66   - AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode);
  66 + //AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode);
67 67  
68 68 //判断任务
69 69 boolean getUncompleteReceiptTask(String locationCode);
... ... @@ -87,6 +87,8 @@ public interface InventoryHeaderService extends IService&lt;InventoryHeader&gt; {
87 87 List<Integer> findInventoryHeaderIdsByMaterialCode(String materialCode);
88 88  
89 89 List<InventoryHeaderVO> inventoryToDto(List<InventoryHeader> originList);
  90 +
  91 + InventoryHeader getByIdForUpdate(Integer inventoryHeaderId);
90 92 }
91 93  
92 94  
... ...
src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java
... ... @@ -35,6 +35,7 @@ import com.huaheng.pc.config.warehouse.domain.Warehouse;
35 35 import com.huaheng.pc.config.zone.domain.Zone;
36 36 import com.huaheng.pc.config.zone.service.ZoneService;
37 37 import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
  38 +import com.huaheng.pc.inventory.inventoryDetail.mapper.InventoryDetailMapper;
38 39 import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
39 40 import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader;
40 41 import com.huaheng.pc.inventory.inventoryHeader.domain.dto.InventoryHeaderVO;
... ... @@ -57,6 +58,7 @@ import lombok.extern.slf4j.Slf4j;
57 58 import org.apache.commons.collections.CollectionUtils;
58 59 import org.apache.commons.collections.Transformer;
59 60 import org.springframework.beans.BeanUtils;
  61 +import org.springframework.beans.factory.annotation.Autowired;
60 62 import org.springframework.stereotype.Service;
61 63 import org.springframework.transaction.annotation.Transactional;
62 64  
... ... @@ -113,10 +115,12 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
113 115 private ShipmentTaskService shipmentTaskService;
114 116 @Resource
115 117 private ShipmentHeaderService shipmentHeaderService;
116   -
  118 + @Autowired
  119 + private InventoryDetailMapper inventoryDetailMapper;
117 120 @Resource
118 121 private InventoryHeaderService inventoryHeaderService;
119 122  
  123 +
120 124 /**
121 125 * 生成移库任务
122 126 */
... ... @@ -432,60 +436,60 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
432 436 return AjaxResult.success(inventoryDetailList);
433 437 }
434 438  
435   - @Override
436   - @Transactional(rollbackFor = Exception.class)
437   - public AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode) {
438   - /* 查询库存*/
439   - LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery();
440   - detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materialCode)
441   - .eq(InventoryDetail::getCompanyCode, beforeCompanyCode);
442   - List<InventoryDetail> detailList = inventoryDetailService.list(detailLambdaQueryWrapper);
443   -
444   - /* 计算该物料总数量*/
445   - BigDecimal totalQty = new BigDecimal(0);
446   - for (InventoryDetail inventoryDetail : detailList) {
447   - totalQty = totalQty.add(inventoryDetail.getQty());
448   - }
449   -
450   - if (totalQty.compareTo(qty) < 1) {
451   - return AjaxResult.error("库存数量不足");
452   - } else {
453   - /**
454   - * 遍历库存,当数量大于0时,执行调拨
455   - * 库存单条记录数量小于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量
456   - * 库存单条记录数量等于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量
457   - * 库存单条记录数量大于调拨数量时,copy实体修改新实体货主编码 库存数量,原实体数量更新,更新两个实体
458   - */
459   - for (InventoryDetail inventoryDetail : detailList) {
460   - if (qty.compareTo(new BigDecimal(0)) == 1) {
461   - if (inventoryDetail.getQty().compareTo(qty) == 1) {
462   - InventoryDetail inventoryDetail1 = inventoryDetail;
463   - inventoryDetail1.setId(null);
464   - inventoryDetail1.setCompanyCode(endCompanyCode);
465   - qty = qty.subtract(inventoryDetail.getQty());
466   - inventoryDetailService.removeById(inventoryDetail.getId());
467   - inventoryDetailService.save(inventoryDetail1);
468   - } else if (inventoryDetail.getQty().compareTo(qty) == 0) {
469   - InventoryDetail inventoryDetail1 = inventoryDetail;
470   - inventoryDetail1.setId(null);
471   - inventoryDetail1.setCompanyCode(endCompanyCode);
472   - qty = qty.subtract(inventoryDetail.getQty());
473   - inventoryDetailService.removeById(inventoryDetail.getId());
474   - inventoryDetailService.save(inventoryDetail1);
475   - } else if (inventoryDetail.getQty().compareTo(qty) == -1) {
476   - InventoryDetail inventoryDetail1 = inventoryDetail;
477   - inventoryDetail1.setQty(qty);
478   - inventoryDetail1.setCompanyCode(endCompanyCode);
479   - inventoryDetail1.setId(null);
480   - inventoryDetail.setQty(inventoryDetail.getQty().subtract(qty));
481   - inventoryDetailService.updateById(inventoryDetail);
482   - inventoryDetailService.save(inventoryDetail1);
483   - }
484   - }
485   - }
486   - }
487   - return AjaxResult.success("");
488   - }
  439 + //@Override
  440 + //@Transactional(rollbackFor = Exception.class)
  441 + //public AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode) {
  442 + // /* 查询库存*/
  443 + // LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery();
  444 + // detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materialCode)
  445 + // .eq(InventoryDetail::getCompanyCode, beforeCompanyCode);
  446 + // List<InventoryDetail> detailList = inventoryDetailService.list(detailLambdaQueryWrapper);
  447 + //
  448 + // /* 计算该物料总数量*/
  449 + // BigDecimal totalQty = new BigDecimal(0);
  450 + // for (InventoryDetail inventoryDetail : detailList) {
  451 + // totalQty = totalQty.add(inventoryDetail.getQty());
  452 + // }
  453 + //
  454 + // if (totalQty.compareTo(qty) < 1) {
  455 + // return AjaxResult.error("库存数量不足");
  456 + // } else {
  457 + // /**
  458 + // * 遍历库存,当数量大于0时,执行调拨
  459 + // * 库存单条记录数量小于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量
  460 + // * 库存单条记录数量等于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量
  461 + // * 库存单条记录数量大于调拨数量时,copy实体修改新实体货主编码 库存数量,原实体数量更新,更新两个实体
  462 + // */
  463 + // for (InventoryDetail inventoryDetail : detailList) {
  464 + // if (qty.compareTo(new BigDecimal(0)) == 1) {
  465 + // if (inventoryDetail.getQty().compareTo(qty) == 1) {
  466 + // InventoryDetail inventoryDetail1 = inventoryDetail;
  467 + // inventoryDetail1.setId(null);
  468 + // inventoryDetail1.setCompanyCode(endCompanyCode);
  469 + // qty = qty.subtract(inventoryDetail.getQty());
  470 + // inventoryDetailService.removeById(inventoryDetail.getId());
  471 + // inventoryDetailService.save(inventoryDetail1);
  472 + // } else if (inventoryDetail.getQty().compareTo(qty) == 0) {
  473 + // InventoryDetail inventoryDetail1 = inventoryDetail;
  474 + // inventoryDetail1.setId(null);
  475 + // inventoryDetail1.setCompanyCode(endCompanyCode);
  476 + // qty = qty.subtract(inventoryDetail.getQty());
  477 + // inventoryDetailService.removeById(inventoryDetail.getId());
  478 + // inventoryDetailService.save(inventoryDetail1);
  479 + // } else if (inventoryDetail.getQty().compareTo(qty) == -1) {
  480 + // InventoryDetail inventoryDetail1 = inventoryDetail;
  481 + // inventoryDetail1.setQty(qty);
  482 + // inventoryDetail1.setCompanyCode(endCompanyCode);
  483 + // inventoryDetail1.setId(null);
  484 + // inventoryDetail.setQty(inventoryDetail.getQty().subtract(qty));
  485 + // inventoryDetailService.updateById(inventoryDetail);
  486 + // inventoryDetailService.save(inventoryDetail1);
  487 + // }
  488 + // }
  489 + // }
  490 + // }
  491 + // return AjaxResult.success("");
  492 + //}
489 493  
490 494 @Override
491 495 public boolean getUncompleteReceiptTask(String locationCode) {
... ... @@ -826,6 +830,15 @@ public class InventoryHeaderServiceImpl extends ServiceImpl&lt;InventoryHeaderMappe
826 830 .collect(Collectors.toList());
827 831 }
828 832  
  833 + @Override
  834 + public InventoryHeader getByIdForUpdate(Integer inventoryHeaderId) {
  835 + LambdaQueryWrapper<InventoryHeader> queryWrapper = new LambdaQueryWrapper<>();
  836 + return inventoryHeaderMapper.selectOne(queryWrapper
  837 + .eq(InventoryHeader::getId, inventoryHeaderId)
  838 + .last("FOR UPDATE"));
  839 +
  840 + }
  841 +
829 842 /**
830 843 * 找到库存对应所有的入库单
831 844 *
... ...
src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java
... ... @@ -183,7 +183,7 @@ public class RyTask extends BaseController {
183 183 //如果上一条出库单未完成,就不执行下一条
184 184 ShipmentHeader header = shipmentHeaderService.getOne(new LambdaQueryWrapper<ShipmentHeader>()
185 185 .eq(ShipmentHeader::getDeleted, 0)
186   - .in(ShipmentHeader::getAutoShipmentStatus, 2)//已自动出库
  186 + .in(ShipmentHeader::getAutoShipmentStatus, 2, 3)
187 187 .last("ORDER BY requestedStartDate asc,id asc limit 1"));
188 188 if (header != null) {
189 189 if (header.getLastStatus() < QuantityConstant.SHIPMENT_HEADER_COMPLETED) {//尾状态小于拣货完成(出库单未完成),就不继续走了
... ... @@ -781,8 +781,9 @@ public class RyTask extends BaseController {
781 781 }
782 782  
783 783  
784   - //每天计算呆滞库存
  784 + @Transactional(rollbackFor = Exception.class)
785 785 public void expiringInventoryHandle() {
  786 + // 获取库存信息
786 787 List<InventoryDetail> inventoryDetails = inventoryDetailService.list();
787 788 if (CollectionUtils.isEmpty(inventoryDetails)) {
788 789 return;
... ... @@ -796,49 +797,49 @@ public class RyTask extends BaseController {
796 797 // 获取所有物料编码
797 798 Set<String> materialCodes = inventoryDetails.stream()
798 799 .map(InventoryDetail::getMaterialCode).collect(Collectors.toSet());
799   -
800 800 List<Material> materials = materialService.list(new LambdaQueryWrapper<Material>().in(Material::getCode, materialCodes));
801 801  
802 802 // 创建物料编码和物料对象的映射关系
803   - Map<String, Material> materialMap = new HashMap<>();
804   - for (Material material : materials) {
805   - materialMap.put(material.getCode(), material);
806   - }
  803 + Map<String, Material> materialMap = materials.stream()
  804 + .collect(Collectors.toMap(Material::getCode, material -> material));
807 805  
808   - List<InventoryDetail> updatedInventoryDetails = inventoryDetails.stream()
809   - .map(inventoryDetail -> {
810   - // 计算库存的更新时间和当前时间之间的差距
811   - long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated());
  806 + for (InventoryDetail inventoryDetail : inventoryDetails) {
  807 + // 计算库存的更新时间和当前时间之间的差距
  808 + long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated());
812 809  
813   - // 从 Map 中获取物料信息
814   - Material material = materialMap.get(inventoryDetail.getMaterialCode());
815   - if (material == null) {
816   - return inventoryDetail;
817   - }
  810 + // 从 Map 中获取物料信息
  811 + Material material = materialMap.get(inventoryDetail.getMaterialCode());
  812 + if (material == null) {
  813 + continue;
  814 + }
818 815  
819   - int materialDays = days;
820   - if (Objects.equals(material.getIsFlammable(), "是")) {
821   - materialDays = Math.min(materialDays, daysFlammable);
822   - } else if (Objects.equals(material.getIsBatch(), "是")) {
823   - materialDays = Math.min(materialDays, daysBatch);
824   - }
  816 + int materialDays = days;
  817 + if (Objects.equals(material.getIsFlammable(), "是")) {
  818 + materialDays = Math.min(materialDays, daysFlammable);
  819 + } else if (Objects.equals(material.getIsBatch(), "是")) {
  820 + materialDays = Math.min(materialDays, daysBatch);
  821 + }
825 822  
826   - // 计算呆滞时长
827   - int differenceDay = DateUtils.secondToDays(difference);
828   - int deadTime = Math.max(differenceDay - materialDays, 0);
829   - if (deadTime == 0) {
830   - inventoryDetail.setDeadTime("");
831   - } else {
832   - inventoryDetail.setDeadTime(deadTime + "天");
833   - }
  823 + // 计算呆滞时长
  824 + int differenceDay = DateUtils.secondToDays(difference);
  825 + int deadTime = Math.max(differenceDay - materialDays, 0);
834 826  
835   - return inventoryDetail;
836   - })
837   - .collect(Collectors.toList());
  827 + if (deadTime == 0 && !inventoryDetail.getDeadTime().isEmpty()) {
  828 + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate();
  829 + updateWrapper
  830 + .eq(InventoryDetail::getId, inventoryDetail.getId())
  831 + .set(InventoryDetail::getDeadTime, "");
  832 + inventoryDetailService.update(updateWrapper);
  833 + }
838 834  
839   - // 保存更新后的库存信息
840   - inventoryDetailService.updateBatchById(updatedInventoryDetails);
  835 + if (deadTime > 0) {
  836 + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate();
  837 + updateWrapper
  838 + .eq(InventoryDetail::getId, inventoryDetail.getId())
  839 + .set(InventoryDetail::getDeadTime, deadTime + "天");
  840 + inventoryDetailService.update(updateWrapper);
  841 + }
  842 + }
841 843 }
842 844  
843   -
844 845 }
... ...
src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java
... ... @@ -55,6 +55,8 @@ import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerH
55 55 import com.huaheng.pc.shipment.shipmentContainerHeader.mapper.ShipmentContainerHeaderMapper;
56 56 import org.springframework.transaction.annotation.Transactional;
57 57  
  58 +import static com.huaheng.common.constant.QuantityConstant.*;
  59 +
58 60 @Service
59 61 public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentContainerHeaderMapper, ShipmentContainerHeader> implements ShipmentContainerHeaderService {
60 62  
... ... @@ -193,12 +195,15 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl&lt;ShipmentCont
193 195 } else if (i < 0) {
194 196 throw new ServiceException("出库数量不能大于单据数量!");
195 197 }
196   -
197   - //限制组盘数量
198   - AjaxResult ajaxResult = limitCombinationCount(inventoryDetail);
199   - if (ajaxResult.hasErr()) {
200   - throw new ServiceException(ajaxResult.getMsg());
  198 + //限制立库组盘数量
  199 + if (container.getFlat() == null || container.getFlat() != 1) {
  200 + AjaxResult ajaxResult = limitCombinationCount(inventoryDetail);
  201 + if (ajaxResult.hasErr()) {
  202 + throw new ServiceException(ajaxResult.getMsg());
  203 + }
201 204 }
  205 +
  206 +
202 207 shipmentDetailService.saveOrUpdate(shipmentDetail);
203 208  
204 209 //自动判定出库任务状态,根据库存数量减去预定库存相等就是整盘出--预计任务状态
... ... @@ -609,17 +614,17 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl&lt;ShipmentCont
609 614 }
610 615 inventoryList.removeAll(removeInventoryList);
611 616 if (inventoryList.isEmpty() && lock) {
612   - return AjaxResult.error("'物料名称:" + item.getMaterialName() + ",物料编码:" + item.getMaterialCode() + "' 所在托盘全部处于锁定状态,请完成或取消任务后再进行组盘");
  617 + return AjaxResult.error("'物料名称:" + item.getMaterialName() + ",物料编码:" + item.getMaterialCode() + "' 所在托盘全部处于锁定状态,请完成或取消任务或入库组盘后再进行组盘");
613 618 }
614 619  
615   - if (inventoryList.isEmpty() && item.getWaveId() != 0) {
616   - Wave wave = waveService.getById(item.getWaveId());
617   - wave.setStatus(QuantityConstant.WAVE_STATUS_ERROR);
618   - wave.setCurrentWaveStep(QuantityConstant.WAVE_STEP_ERROR);
619   - wave.setLastWaveStep(QuantityConstant.WAVE_STEP_BUILD);
620   - waveService.updateById(wave);
621   - throw new ServiceException("主单为" + item.getShipmentCode() + "子单id为" + item.getId() + "的单据没有库存,波次失败");
622   - }
  620 + //if (inventoryList.isEmpty() && item.getWaveId() != 0) {
  621 + // Wave wave = waveService.getById(item.getWaveId());
  622 + // wave.setStatus(QuantityConstant.WAVE_STATUS_ERROR);
  623 + // wave.setCurrentWaveStep(QuantityConstant.WAVE_STEP_ERROR);
  624 + // wave.setLastWaveStep(QuantityConstant.WAVE_STEP_BUILD);
  625 + // waveService.updateById(wave);
  626 + // throw new ServiceException("主单为" + item.getShipmentCode() + "子单id为" + item.getId() + "的单据没有库存,波次失败");
  627 + //}
623 628 if (inventoryList.isEmpty()) {
624 629 num = num + 1;
625 630 } else {
... ... @@ -629,12 +634,13 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl&lt;ShipmentCont
629 634 break;
630 635 }
631 636  
632   - //限制组盘数量
633   - AjaxResult ajaxResult = limitCombinationCount(inventory);
634   - if (ajaxResult.hasErr()) {
635   - throw new ServiceException(ajaxResult.getMsg());
  637 + //限制立库组盘数量
  638 + if (inventory.getIsFlatWarehouse() == 0) {
  639 + AjaxResult ajaxResult = limitCombinationCount(inventory);
  640 + if (ajaxResult.hasErr()) {
  641 + throw new ServiceException(ajaxResult.getMsg());
  642 + }
636 643 }
637   -
638 644 BigDecimal inventoryQty = inventory.getQty().subtract(inventory.getTaskQty());
639 645 ShipmentCombinationModel shipmentCombination = new ShipmentCombinationModel();
640 646 shipmentCombination.setInventoryDetailId(inventory.getId());
... ... @@ -668,25 +674,52 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl&lt;ShipmentCont
668 674 // 获取巷道信息
669 675 String roadway = location.getRoadway();
670 676  
671   - // 使用三元运算符根据巷道信息确定限制数量
672   - int limit = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ?
673   - Integer.parseInt(configService.getKey("shipmentTaskBy5RoadLimit")) :
674   - Integer.parseInt(configService.getKey("shipmentContainerTaskLimit"));
675   -
676   - // 使用三元运算符根据巷道信息确定任务数量
677   - int shipmentTaskCount = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ?
678   - taskHeaderService.getShipmentTaskBy5Road() :
679   - taskHeaderService.getShipmentContainerTask(roadway);
  677 + LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery();
  678 + wrapper.eq(Location::getRoadway, roadway)
  679 + .eq(Location::getStatus, STATUS_LOCATION_EMPTY)
  680 + .eq(Location::getHigh, location.getHigh())
  681 + .eq(Location::getContainerCode, "")
  682 + .eq(Location::getSelfCreated, NO_TSELFCREATED)
  683 + .eq(Location::getOnlyEmptyContainer, NO_EMPTY_CONTAINER_LOCATION);
  684 + List<Location> locationList = locationService.list(wrapper);
  685 +
  686 + if (locationList.size() < 3) {
  687 + return AjaxResult.error("该库存出库可能无法回库了");
  688 + }
680 689  
681   - // 检查任务数量是否超过限制
682   - if (shipmentTaskCount >= limit) {
683   - // 根据巷道信息拼接错误信息
684   - String errorMessage = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ?
685   - "5号巷道不能存在超过" + limit + "个组盘和任务" :
686   - "不能存在超过" + limit + "个组盘和任务";
687   - return AjaxResult.error(errorMessage);
  690 + List<Location> availableLocations = new ArrayList<>();
  691 + for (Location location1 : locationList) {
  692 + // 如果库位内侧没有未完成的任务,则将其添加到可用库位列表中
  693 + if (taskHeaderService.getUncompleteTaskInNear(location1) == 0) {
  694 + availableLocations.add(location1);
  695 + }
  696 + // 如果已经找到了 3 个可用库位,则直接返回成功
  697 + if (availableLocations.size() >= 3) {
  698 + return AjaxResult.success();
  699 + }
688 700 }
689   - return AjaxResult.success();
  701 +
  702 + return AjaxResult.error("该库存出库可能无法回库了,可能是空闲库位内/外测有任务了");
  703 +
  704 +
  705 + //// 使用三元运算符根据巷道信息确定限制数量
  706 + //int limit = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ?
  707 + // Integer.parseInt(configService.getKey("shipmentTaskBy5RoadLimit")) :
  708 + // Integer.parseInt(configService.getKey("shipmentContainerTaskLimit"));
  709 + //
  710 + //// 使用三元运算符根据巷道信息确定任务数量
  711 + //int shipmentTaskCount = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ?
  712 + // taskHeaderService.getShipmentTaskBy5Road() :
  713 + // taskHeaderService.getShipmentContainerTask(roadway);
  714 + //
  715 + //// 检查任务数量是否超过限制
  716 + //if (shipmentTaskCount >= limit) {
  717 + // // 根据巷道信息拼接错误信息
  718 + // String errorMessage = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ?
  719 + // "5号巷道不能存在超过" + limit + "个组盘和任务" :
  720 + // "不能存在超过" + limit + "个组盘和任务";
  721 + // return AjaxResult.error(errorMessage);
  722 + //}
690 723 }
691 724  
692 725 /**
... ...
src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java
... ... @@ -562,19 +562,19 @@ public class ShipmentHeaderController extends BaseController {
562 562 return prefix + "/addWave";
563 563 }
564 564  
565   - /**
566   - * 查询波次列表
567   - */
568   - @RequiresPermissions("shipment:bill:wave")
569   - //@Log(title = "出库-出库单", operating = "查询库区列表", action = BusinessType.GRANT)
570   - @PostMapping("/waveList")
571   - @ResponseBody
572   - public TableDataInfo waveList() {
573   - LambdaQueryWrapper<WaveMaster> lam = Wrappers.lambdaQuery();
574   - lam.eq(WaveMaster::getWarehouseCode, ShiroUtils.getWarehouseCode());
575   - List<WaveMaster> waveMasters = waveMasterService.list(lam);
576   - return getDataTable(waveMasters);
577   - }
  565 + ///**
  566 + // * 查询波次列表
  567 + // */
  568 + //@RequiresPermissions("shipment:bill:wave")
  569 + ////@Log(title = "出库-出库单", operating = "查询库区列表", action = BusinessType.GRANT)
  570 + //@PostMapping("/waveList")
  571 + //@ResponseBody
  572 + //public TableDataInfo waveList() {
  573 + // LambdaQueryWrapper<WaveMaster> lam = Wrappers.lambdaQuery();
  574 + // lam.eq(WaveMaster::getWarehouseCode, ShiroUtils.getWarehouseCode());
  575 + // List<WaveMaster> waveMasters = waveMasterService.list(lam);
  576 + // return getDataTable(waveMasters);
  577 + //}
578 578  
579 579  
580 580 /**
... ...
src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java
... ... @@ -16,6 +16,8 @@ import com.huaheng.framework.web.domain.AjaxResult;
16 16 import com.huaheng.framework.web.service.ConfigService;
17 17 import com.huaheng.pc.config.address.service.AddressService;
18 18 import com.huaheng.pc.config.company.service.CompanyService;
  19 +import com.huaheng.pc.config.container.domain.Container;
  20 +import com.huaheng.pc.config.container.service.ContainerService;
19 21 import com.huaheng.pc.config.customer.domain.Customer;
20 22 import com.huaheng.pc.config.customer.service.CustomerServiceImpl;
21 23 import com.huaheng.pc.config.location.domain.Location;
... ... @@ -25,6 +27,8 @@ import com.huaheng.pc.config.shipmentType.service.ShipmentTypeService;
25 27 import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
26 28 import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
27 29 import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
  30 +import com.huaheng.pc.shipment.shipmentContainerDetail.domain.ShipmentContainerDetail;
  31 +import com.huaheng.pc.shipment.shipmentContainerDetail.service.ShipmentContainerDetailService;
28 32 import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerHeader;
29 33 import com.huaheng.pc.shipment.shipmentContainerHeader.service.ShipmentContainerHeaderService;
30 34 import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail;
... ... @@ -62,7 +66,10 @@ import java.util.stream.Collectors;
62 66 public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, ShipmentHeader> implements ShipmentHeaderService {
63 67 @Resource
64 68 private ShipmentTaskService shipmentTaskService;
65   -
  69 + @Resource
  70 + private ShipmentContainerDetailService shipmentContainerDetailService;
  71 + @Resource
  72 + private ContainerService containerService;
66 73 @Resource
67 74 private ConfigService configService;
68 75 @Resource
... ... @@ -573,20 +580,19 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
573 580  
574 581 @Override
575 582 public void autoShipmentExecute(ShipmentHeader shipmentHeader) {
576   - shipmentHeader.setAutoShipmentStatus(4);
  583 + shipmentHeader.setAutoShipmentStatus(3);
577 584 shipmentHeader.setErrorMsg("自动组盘过程中程序错误,请手动组盘");
578 585 updateById(shipmentHeader);
579 586 //自动组盘
580 587 AjaxResult containerResult = shipmentContainerHeaderService.autoCombination(shipmentHeader.getCode(), true);
581   - //如果出库单明细全部为出库组盘,就不改状态了,找一些其他地方是不是也修改了,这个修改了应该就直接返回了呀,为什么还完成了单据呢
582 588 if (!updateShipmentErrorMsg(containerResult, shipmentHeader)) {
583 589 return;
584 590 }
585   - shipmentHeader.setAutoShipmentStatus(4);
  591 +
  592 + //生成任务
  593 + shipmentHeader.setAutoShipmentStatus(3);
586 594 shipmentHeader.setErrorMsg("自生成任务过程中程序错误,请手动生成任务");
587 595 updateById(shipmentHeader);
588   -
589   -
590 596 List<ShipmentContainerHeader> shipmentContainerHeaders = shipmentContainerHeaderService.list(new LambdaQueryWrapper<ShipmentContainerHeader>()
591 597 .eq(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_BUILD));
592 598 for (ShipmentContainerHeader item : shipmentContainerHeaders) {
... ... @@ -598,21 +604,20 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
598 604 }
599 605 }
600 606  
601   - //生成任务
602 607 //List<Integer> ids = (List<Integer>) containerResult.getData();
603 608 //AjaxResult taskResult = shipmentContainerHeaderService.createAutoTask(ids);
604 609 //if (!updateShipmentErrorMsg(taskResult, shipmentHeader)) {
605 610 // return;
606 611 //}
607   -
  612 +
608 613 //自动打印
609 614 int isPrint = Integer.parseInt(configService.getKey(QuantityConstant.AUTO_SHIPMENT_PRINT));
610 615 if (isPrint == 1) {
611   - shipmentHeader.setAutoShipmentStatus(4);
  616 + shipmentHeader.setAutoShipmentStatus(3);
612 617 shipmentHeader.setErrorMsg("自动打印过程中程序错误,请手动打印");
613 618 updateById(shipmentHeader);
614 619 AjaxResult reportResult = shipmentHeaderService.autoReportShipment(-1, shipmentHeader.getCode(), "1");
615   - if (updateShipmentErrorMsg(reportResult, shipmentHeader)) {
  620 + if (!updateShipmentErrorMsg(reportResult, shipmentHeader)) {
616 621 return;
617 622 }
618 623 }
... ... @@ -620,7 +625,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
620 625 //自动出库完成
621 626 shipmentHeader.setAutoShipmentStatus(2);
622 627 shipmentHeader.setErrorMsg("");
623   - updateById(shipmentHeader);
  628 + shipmentHeaderService.updateById(shipmentHeader);
624 629 }
625 630  
626 631  
... ... @@ -632,7 +637,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
632 637 errorMsg = errorMsg.substring(0, 500);
633 638 }
634 639 shipmentHeader.setErrorMsg(errorMsg);
635   - updateById(shipmentHeader);
  640 + shipmentHeaderService.updateById(shipmentHeader);
636 641 return false;
637 642 }
638 643 return true;
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java
... ... @@ -356,9 +356,12 @@ public class ReceiptTaskService {
356 356 List<InventoryDetail> inventoryDetails = inventoryDetailService.list(new LambdaQueryWrapper<InventoryDetail>().eq(InventoryDetail::getInventoryHeaderId, inventoryHeader.getId()));
357 357 if (inventoryDetails != null && !inventoryDetails.isEmpty()) {
358 358 for (InventoryDetail inventoryDetail : inventoryDetails) {
359   - inventoryDetail.setLocationCode(toLocation.getCode());
360   - inventoryDetail.setZoneCode(toLocation.getZoneCode());
361   - if (!inventoryDetailService.updateById(inventoryDetail)) {
  359 + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate();
  360 + updateWrapper
  361 + .eq(InventoryDetail::getId, inventoryDetail.getId())
  362 + .set(InventoryDetail::getLocationCode, toLocation.getCode())
  363 + .set(InventoryDetail::getZoneCode, toLocation.getZoneCode());
  364 + if (!inventoryDetailService.update(updateWrapper)) {
362 365 throw new ServiceException("补充入库,更新库存明细失败");
363 366 }
364 367 }
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java
... ... @@ -365,8 +365,11 @@ public class ShipmentTaskService {
365 365 List<InventoryDetail> inventoryDetails = inventoryDetailService.list(new LambdaQueryWrapper<InventoryDetail>().eq(InventoryDetail::getInventoryHeaderId, inventoryHeader.getId()));
366 366 if (inventoryDetails != null && !inventoryDetails.isEmpty()) {
367 367 for (InventoryDetail inventoryDetail : inventoryDetails) {
368   - inventoryDetail.setLocationCode(task.getToLocation());
369   - if (!inventoryDetailService.updateById(inventoryDetail)) {
  368 +
  369 + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate();
  370 + updateWrapper.eq(InventoryDetail::getId, inventoryDetail.getId())
  371 + .set(InventoryDetail::getLocationCode, task.getToLocation());
  372 + if (!inventoryDetailService.update(updateWrapper)) {
370 373 throw new ServiceException("完成出库任务,库存修改目标库位时失败" + inventoryDetail.getId());
371 374 }
372 375 }
... ... @@ -381,13 +384,14 @@ public class ShipmentTaskService {
381 384 //获取出库组盘明细
382 385 ShipmentContainerDetail shipmentContainerDetail = shipmentContainerDetailService.getById(taskDetail.getAllocationId());
383 386 //获取对应库存记录
384   - InventoryDetail inventoryDetail = inventoryDetailService.getById(taskDetail.getToInventoryId());
  387 + InventoryDetail inventoryDetail = inventoryDetailService.getByIdForUpdate(taskDetail.getToInventoryId());
385 388 if (inventoryDetail == null) {
386 389 throw new ServiceException("任务明细对应的库存ID【" + taskDetail.getToInventoryId().toString() + "】不存在!");
387 390 }
388 391 inventoryDetail.setLastUpdatedBy(taskDetail.getLastUpdatedBy());
389 392 //减扣库存单
390   - inventoryHeader = inventoryHeaderService.getById(inventoryDetail.getInventoryHeaderId());
  393 + // 使用悲观锁查询库存主表
  394 + inventoryHeader = inventoryHeaderService.getByIdForUpdate(inventoryDetail.getInventoryHeaderId());
391 395  
392 396 //扣减库存明细
393 397 inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty()));
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java
... ... @@ -191,7 +191,7 @@ public class TransferTaskService {
191 191 taskDetail.setFromInventoryId(inventoryDetail.getId());
192 192 taskDetail.setToInventoryId(inventoryDetail.getId());
193 193 taskDetail.setLastUpdatedBy(ShiroUtils.getName());
194   - if (!taskDetailService.save(taskDetail) || !inventoryDetailService.updateById(inventoryDetail)) {
  194 + if (!taskDetailService.save(taskDetail)) {
195 195 throw new ServiceException("创建任务失败");
196 196 }
197 197 }
... ...
src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java
... ... @@ -769,8 +769,7 @@ public class WorkTaskService {
769 769 taskDetail.setMaterialName(inventoryDetail.getMaterialName());
770 770 taskDetail.setMaterialSpec(inventoryDetail.getMaterialSpec());
771 771 taskDetail.setMaterialUnit(inventoryDetail.getMaterialUnit());
772   - if (!taskDetailService.save(taskDetail) ||
773   - !inventoryDetailService.updateById(inventoryDetail)) {
  772 + if (!taskDetailService.save(taskDetail)) {
774 773 throw new ServiceException("任务创建失败");
775 774 }
776 775 }
... ... @@ -843,7 +842,7 @@ public class WorkTaskService {
843 842 if (inventoryDetail.getId().equals(inventoryDetail2.getId())) {
844 843 taskDetail.setInventoryTransactionId(inventoryTransactionId);
845 844 }
846   - if (!taskDetailService.save(taskDetail) || !inventoryDetailService.updateById(inventoryDetail)) {
  845 + if (!taskDetailService.save(taskDetail)) {
847 846 throw new ServiceException("任务创建失败");
848 847 }
849 848 }
... ... @@ -919,8 +918,13 @@ public class WorkTaskService {
919 918 List<InventoryDetail> inventoryDetails = inventoryDetailService.list(lambdaQueryWrapper2);
920 919 if (inventoryDetails != null && !inventoryDetails.isEmpty()) {
921 920 for (InventoryDetail inventoryDetail : inventoryDetails) {
922   - inventoryDetail.setLocationCode(taskHeader.getToLocation());
923   - inventoryDetailService.updateById(inventoryDetail);
  921 + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate();
  922 + updateWrapper.eq(InventoryDetail::getId, inventoryDetail.getId())
  923 + .set(InventoryDetail::getLocationCode, taskHeader.getToLocation());
  924 + if (!inventoryDetailService.update(updateWrapper)) {
  925 + throw new ServiceException("库存修改目标库位时失败" + inventoryDetail.getId());
  926 + }
  927 +
924 928 }
925 929 containerService.updateStatus(containerCode, QuantityConstant.STATUS_CONTAINER_SOME, warehouseCode);
926 930 }
... ...
src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html
... ... @@ -289,10 +289,10 @@
289 289 <i class="fa fa-code-fork"></i> 自动组盘
290 290 </a>
291 291  
292   - <a class="btn btn-outline btn-primary btn-rounded auto-shipment-task" onclick="Toshipping(2)"
293   - shiro:hasPermission="shipment:shippingCombination:combination">
294   - <i class="fa fa-code-fork"></i> 自动组盘并生成任务
295   - </a>
  292 + <!-- <a class="btn btn-outline btn-primary btn-rounded auto-shipment-task" onclick="Toshipping(2)"-->
  293 + <!-- shiro:hasPermission="shipment:shippingCombination:combination">-->
  294 + <!-- <i class="fa fa-code-fork"></i> 自动组盘并生成任务-->
  295 + <!-- </a>-->
296 296 <a class="btn btn-outline btn-primary btn-rounded auto-shipment" onclick="Toshipping(3)"
297 297 shiro:hasPermission="shipment:shippingCombination:combination">
298 298 <i class="fa fa-code-fork"></i> 自动平库组盘
... ...