From e5229a67805aaf01af7d70042c4b2fe2dfd8d2da Mon Sep 17 00:00:00 2001 From: yiwenpeng <ywp303@163.com> Date: Tue, 20 Aug 2024 09:42:52 +0800 Subject: [PATCH] feat:优化自动出库 --- src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java | 17 ++++++++--------- src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java | 2 ++ src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java | 8 ++++++++ src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java | 4 +++- src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------- src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java | 73 +++++++++++++++++++++++++++++++++++++------------------------------------ src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------ src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java | 26 +++++++++++++------------- src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java | 29 +++++++++++++++++------------ src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java | 9 ++++++--- src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java | 12 ++++++++---- src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java | 2 +- src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java | 14 +++++++++----- src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html | 8 ++++---- 14 files changed, 253 insertions(+), 179 deletions(-) diff --git a/src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java b/src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java index 1f3ac01..8c3665c 100644 --- a/src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java +++ b/src/main/java/com/huaheng/api/wcs/controller/ArrivedNoticeController.java @@ -42,10 +42,10 @@ public class ArrivedNoticeController extends BaseController { @PostMapping("/arrivedNotice") @ApiOperation("到达拣选台") - @ApiLogger(apiName = "wcs到达拣选台", from="ROBOT") + @ApiLogger(apiName = "wcs到达拣选台", from = "ROBOT") @Transactional(rollbackFor = Exception.class) @ResponseBody - public AjaxResult arrivedNotice(@RequestBody Map<String,String> map) { + public AjaxResult arrivedNotice(@RequestBody Map<String, String> map) { //String warehouseCode = "CS0001"; String taskNo = map.get("taskNo"); //String port = map.get("port"); @@ -54,18 +54,17 @@ public class ArrivedNoticeController extends BaseController { LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(); taskHeaderLambdaQueryWrapper.eq(TaskHeader::getId, taskNo); TaskHeader taskHeader = taskHeaderService.getOne(taskHeaderLambdaQueryWrapper); - if(taskHeader != null) { + if (taskHeader != null) { + int status = taskHeader.getStatus(); + if (status == QuantityConstant.TASK_STATUS_COMPLETED) { + return AjaxResult.success("更新到达站台成功, 任务已经完成,不要重复更新"); + } taskHeader.setStatus(QuantityConstant.TASK_STATUS_ARRIVED_STATION); } else { return AjaxResult.error("没有找到任务taskNo:" + taskNo); } - //int taskType = taskHeader.getTaskType(); - int status = taskHeader.getStatus(); - if(status == QuantityConstant.TASK_STATUS_COMPLETED) { - return AjaxResult.success("更新到达站台成功, 任务已经完成"); - } boolean result = taskHeaderService.updateById(taskHeader); - if(!result) { + if (!result) { return AjaxResult.error("更新到达站台失败"); } return AjaxResult.success("更新到达站台成功"); diff --git a/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java b/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java index 742e93c..a4ca425 100644 --- a/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java +++ b/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailService.java @@ -48,6 +48,8 @@ public interface InventoryDetailService extends IService<InventoryDetail> { * @return */ List<InventoryDetail> queryReceiptDetailById(Integer inventoryHeaderId); + + InventoryDetail getByIdForUpdate(Integer toInventoryId); } diff --git a/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java b/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java index cabbfa6..1026621 100644 --- a/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java +++ b/src/main/java/com/huaheng/pc/inventory/inventoryDetail/service/InventoryDetailServiceImpl.java @@ -286,6 +286,14 @@ public class InventoryDetailServiceImpl extends ServiceImpl<InventoryDetailMappe return this.list(lam); } + @Override + public InventoryDetail getByIdForUpdate(Integer toInventoryId) { + LambdaQueryWrapper<InventoryDetail> queryWrapper = new LambdaQueryWrapper<>(); + return inventoryDetailMapper.selectOne(queryWrapper + .eq(InventoryDetail::getId, toInventoryId) + .last("FOR UPDATE")); + } + } diff --git a/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java b/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java index 7206671..94eaa8d 100644 --- a/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java +++ b/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderService.java @@ -63,7 +63,7 @@ public interface InventoryHeaderService extends IService<InventoryHeader> { */ AjaxResult getLocationForecast(String code, int type); - AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode); + //AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode); //判断任务 boolean getUncompleteReceiptTask(String locationCode); @@ -87,6 +87,8 @@ public interface InventoryHeaderService extends IService<InventoryHeader> { List<Integer> findInventoryHeaderIdsByMaterialCode(String materialCode); List<InventoryHeaderVO> inventoryToDto(List<InventoryHeader> originList); + + InventoryHeader getByIdForUpdate(Integer inventoryHeaderId); } diff --git a/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java b/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java index e0446be..1700f95 100644 --- a/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java +++ b/src/main/java/com/huaheng/pc/inventory/inventoryHeader/service/InventoryHeaderServiceImpl.java @@ -35,6 +35,7 @@ import com.huaheng.pc.config.warehouse.domain.Warehouse; import com.huaheng.pc.config.zone.domain.Zone; import com.huaheng.pc.config.zone.service.ZoneService; import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail; +import com.huaheng.pc.inventory.inventoryDetail.mapper.InventoryDetailMapper; import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService; import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader; import com.huaheng.pc.inventory.inventoryHeader.domain.dto.InventoryHeaderVO; @@ -57,6 +58,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Transformer; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -113,10 +115,12 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe private ShipmentTaskService shipmentTaskService; @Resource private ShipmentHeaderService shipmentHeaderService; - + @Autowired + private InventoryDetailMapper inventoryDetailMapper; @Resource private InventoryHeaderService inventoryHeaderService; + /** * 生成移库任务 */ @@ -432,60 +436,60 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe return AjaxResult.success(inventoryDetailList); } - @Override - @Transactional(rollbackFor = Exception.class) - public AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode) { - /* 查询库存*/ - LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery(); - detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materialCode) - .eq(InventoryDetail::getCompanyCode, beforeCompanyCode); - List<InventoryDetail> detailList = inventoryDetailService.list(detailLambdaQueryWrapper); - - /* 计算该物料总数量*/ - BigDecimal totalQty = new BigDecimal(0); - for (InventoryDetail inventoryDetail : detailList) { - totalQty = totalQty.add(inventoryDetail.getQty()); - } - - if (totalQty.compareTo(qty) < 1) { - return AjaxResult.error("库存数量不足"); - } else { - /** - * 遍历库存,当数量大于0时,执行调拨 - * 库存单条记录数量小于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 - * 库存单条记录数量等于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 - * 库存单条记录数量大于调拨数量时,copy实体修改新实体货主编码 库存数量,原实体数量更新,更新两个实体 - */ - for (InventoryDetail inventoryDetail : detailList) { - if (qty.compareTo(new BigDecimal(0)) == 1) { - if (inventoryDetail.getQty().compareTo(qty) == 1) { - InventoryDetail inventoryDetail1 = inventoryDetail; - inventoryDetail1.setId(null); - inventoryDetail1.setCompanyCode(endCompanyCode); - qty = qty.subtract(inventoryDetail.getQty()); - inventoryDetailService.removeById(inventoryDetail.getId()); - inventoryDetailService.save(inventoryDetail1); - } else if (inventoryDetail.getQty().compareTo(qty) == 0) { - InventoryDetail inventoryDetail1 = inventoryDetail; - inventoryDetail1.setId(null); - inventoryDetail1.setCompanyCode(endCompanyCode); - qty = qty.subtract(inventoryDetail.getQty()); - inventoryDetailService.removeById(inventoryDetail.getId()); - inventoryDetailService.save(inventoryDetail1); - } else if (inventoryDetail.getQty().compareTo(qty) == -1) { - InventoryDetail inventoryDetail1 = inventoryDetail; - inventoryDetail1.setQty(qty); - inventoryDetail1.setCompanyCode(endCompanyCode); - inventoryDetail1.setId(null); - inventoryDetail.setQty(inventoryDetail.getQty().subtract(qty)); - inventoryDetailService.updateById(inventoryDetail); - inventoryDetailService.save(inventoryDetail1); - } - } - } - } - return AjaxResult.success(""); - } + //@Override + //@Transactional(rollbackFor = Exception.class) + //public AjaxResult organizationalTransfers(String materialCode, BigDecimal qty, String beforeCompanyCode, String endCompanyCode) { + // /* 查询库存*/ + // LambdaQueryWrapper<InventoryDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery(); + // detailLambdaQueryWrapper.eq(InventoryDetail::getMaterialCode, materialCode) + // .eq(InventoryDetail::getCompanyCode, beforeCompanyCode); + // List<InventoryDetail> detailList = inventoryDetailService.list(detailLambdaQueryWrapper); + // + // /* 计算该物料总数量*/ + // BigDecimal totalQty = new BigDecimal(0); + // for (InventoryDetail inventoryDetail : detailList) { + // totalQty = totalQty.add(inventoryDetail.getQty()); + // } + // + // if (totalQty.compareTo(qty) < 1) { + // return AjaxResult.error("库存数量不足"); + // } else { + // /** + // * 遍历库存,当数量大于0时,执行调拨 + // * 库存单条记录数量小于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 + // * 库存单条记录数量等于调拨数量时,copy实体修改新实体货主编码 添加新库存记录删除原库存、调拨数量减去记录数量 + // * 库存单条记录数量大于调拨数量时,copy实体修改新实体货主编码 库存数量,原实体数量更新,更新两个实体 + // */ + // for (InventoryDetail inventoryDetail : detailList) { + // if (qty.compareTo(new BigDecimal(0)) == 1) { + // if (inventoryDetail.getQty().compareTo(qty) == 1) { + // InventoryDetail inventoryDetail1 = inventoryDetail; + // inventoryDetail1.setId(null); + // inventoryDetail1.setCompanyCode(endCompanyCode); + // qty = qty.subtract(inventoryDetail.getQty()); + // inventoryDetailService.removeById(inventoryDetail.getId()); + // inventoryDetailService.save(inventoryDetail1); + // } else if (inventoryDetail.getQty().compareTo(qty) == 0) { + // InventoryDetail inventoryDetail1 = inventoryDetail; + // inventoryDetail1.setId(null); + // inventoryDetail1.setCompanyCode(endCompanyCode); + // qty = qty.subtract(inventoryDetail.getQty()); + // inventoryDetailService.removeById(inventoryDetail.getId()); + // inventoryDetailService.save(inventoryDetail1); + // } else if (inventoryDetail.getQty().compareTo(qty) == -1) { + // InventoryDetail inventoryDetail1 = inventoryDetail; + // inventoryDetail1.setQty(qty); + // inventoryDetail1.setCompanyCode(endCompanyCode); + // inventoryDetail1.setId(null); + // inventoryDetail.setQty(inventoryDetail.getQty().subtract(qty)); + // inventoryDetailService.updateById(inventoryDetail); + // inventoryDetailService.save(inventoryDetail1); + // } + // } + // } + // } + // return AjaxResult.success(""); + //} @Override public boolean getUncompleteReceiptTask(String locationCode) { @@ -826,6 +830,15 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe .collect(Collectors.toList()); } + @Override + public InventoryHeader getByIdForUpdate(Integer inventoryHeaderId) { + LambdaQueryWrapper<InventoryHeader> queryWrapper = new LambdaQueryWrapper<>(); + return inventoryHeaderMapper.selectOne(queryWrapper + .eq(InventoryHeader::getId, inventoryHeaderId) + .last("FOR UPDATE")); + + } + /** * 找到库存对应所有的入库单 * diff --git a/src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java b/src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java index 05ca24d..cd7223d 100644 --- a/src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java +++ b/src/main/java/com/huaheng/pc/monitor/job/task/RyTask.java @@ -183,7 +183,7 @@ public class RyTask extends BaseController { //如果上一条出库单未完成,就不执行下一条 ShipmentHeader header = shipmentHeaderService.getOne(new LambdaQueryWrapper<ShipmentHeader>() .eq(ShipmentHeader::getDeleted, 0) - .in(ShipmentHeader::getAutoShipmentStatus, 2)//已自动出库 + .in(ShipmentHeader::getAutoShipmentStatus, 2, 3) .last("ORDER BY requestedStartDate asc,id asc limit 1")); if (header != null) { if (header.getLastStatus() < QuantityConstant.SHIPMENT_HEADER_COMPLETED) {//尾状态小于拣货完成(出库单未完成),就不继续走了 @@ -781,8 +781,9 @@ public class RyTask extends BaseController { } - //每天计算呆滞库存 + @Transactional(rollbackFor = Exception.class) public void expiringInventoryHandle() { + // 获取库存信息 List<InventoryDetail> inventoryDetails = inventoryDetailService.list(); if (CollectionUtils.isEmpty(inventoryDetails)) { return; @@ -796,49 +797,49 @@ public class RyTask extends BaseController { // 获取所有物料编码 Set<String> materialCodes = inventoryDetails.stream() .map(InventoryDetail::getMaterialCode).collect(Collectors.toSet()); - List<Material> materials = materialService.list(new LambdaQueryWrapper<Material>().in(Material::getCode, materialCodes)); // 创建物料编码和物料对象的映射关系 - Map<String, Material> materialMap = new HashMap<>(); - for (Material material : materials) { - materialMap.put(material.getCode(), material); - } + Map<String, Material> materialMap = materials.stream() + .collect(Collectors.toMap(Material::getCode, material -> material)); - List<InventoryDetail> updatedInventoryDetails = inventoryDetails.stream() - .map(inventoryDetail -> { - // 计算库存的更新时间和当前时间之间的差距 - long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated()); + for (InventoryDetail inventoryDetail : inventoryDetails) { + // 计算库存的更新时间和当前时间之间的差距 + long difference = DateUtils.difference(DateUtils.getNowDate(), inventoryDetail.getRealUpdated()); - // 从 Map 中获取物料信息 - Material material = materialMap.get(inventoryDetail.getMaterialCode()); - if (material == null) { - return inventoryDetail; - } + // 从 Map 中获取物料信息 + Material material = materialMap.get(inventoryDetail.getMaterialCode()); + if (material == null) { + continue; + } - int materialDays = days; - if (Objects.equals(material.getIsFlammable(), "是")) { - materialDays = Math.min(materialDays, daysFlammable); - } else if (Objects.equals(material.getIsBatch(), "是")) { - materialDays = Math.min(materialDays, daysBatch); - } + int materialDays = days; + if (Objects.equals(material.getIsFlammable(), "是")) { + materialDays = Math.min(materialDays, daysFlammable); + } else if (Objects.equals(material.getIsBatch(), "是")) { + materialDays = Math.min(materialDays, daysBatch); + } - // 计算呆滞时长 - int differenceDay = DateUtils.secondToDays(difference); - int deadTime = Math.max(differenceDay - materialDays, 0); - if (deadTime == 0) { - inventoryDetail.setDeadTime(""); - } else { - inventoryDetail.setDeadTime(deadTime + "天"); - } + // 计算呆滞时长 + int differenceDay = DateUtils.secondToDays(difference); + int deadTime = Math.max(differenceDay - materialDays, 0); - return inventoryDetail; - }) - .collect(Collectors.toList()); + if (deadTime == 0 && !inventoryDetail.getDeadTime().isEmpty()) { + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper + .eq(InventoryDetail::getId, inventoryDetail.getId()) + .set(InventoryDetail::getDeadTime, ""); + inventoryDetailService.update(updateWrapper); + } - // 保存更新后的库存信息 - inventoryDetailService.updateBatchById(updatedInventoryDetails); + if (deadTime > 0) { + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper + .eq(InventoryDetail::getId, inventoryDetail.getId()) + .set(InventoryDetail::getDeadTime, deadTime + "天"); + inventoryDetailService.update(updateWrapper); + } + } } - } diff --git a/src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java b/src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java index 178e445..1d1ed2a 100644 --- a/src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java +++ b/src/main/java/com/huaheng/pc/shipment/shipmentContainerHeader/service/ShipmentContainerHeaderServiceImpl.java @@ -55,6 +55,8 @@ import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerH import com.huaheng.pc.shipment.shipmentContainerHeader.mapper.ShipmentContainerHeaderMapper; import org.springframework.transaction.annotation.Transactional; +import static com.huaheng.common.constant.QuantityConstant.*; + @Service public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentContainerHeaderMapper, ShipmentContainerHeader> implements ShipmentContainerHeaderService { @@ -193,12 +195,15 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont } else if (i < 0) { throw new ServiceException("出库数量不能大于单据数量!"); } - - //限制组盘数量 - AjaxResult ajaxResult = limitCombinationCount(inventoryDetail); - if (ajaxResult.hasErr()) { - throw new ServiceException(ajaxResult.getMsg()); + //限制立库组盘数量 + if (container.getFlat() == null || container.getFlat() != 1) { + AjaxResult ajaxResult = limitCombinationCount(inventoryDetail); + if (ajaxResult.hasErr()) { + throw new ServiceException(ajaxResult.getMsg()); + } } + + shipmentDetailService.saveOrUpdate(shipmentDetail); //自动判定出库任务状态,根据库存数量减去预定库存相等就是整盘出--预计任务状态 @@ -609,17 +614,17 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont } inventoryList.removeAll(removeInventoryList); if (inventoryList.isEmpty() && lock) { - return AjaxResult.error("'物料名称:" + item.getMaterialName() + ",物料编码:" + item.getMaterialCode() + "' 所在托盘全部处于锁定状态,请完成或取消任务后再进行组盘"); + return AjaxResult.error("'物料名称:" + item.getMaterialName() + ",物料编码:" + item.getMaterialCode() + "' 所在托盘全部处于锁定状态,请完成或取消任务或入库组盘后再进行组盘"); } - if (inventoryList.isEmpty() && item.getWaveId() != 0) { - Wave wave = waveService.getById(item.getWaveId()); - wave.setStatus(QuantityConstant.WAVE_STATUS_ERROR); - wave.setCurrentWaveStep(QuantityConstant.WAVE_STEP_ERROR); - wave.setLastWaveStep(QuantityConstant.WAVE_STEP_BUILD); - waveService.updateById(wave); - throw new ServiceException("主单为" + item.getShipmentCode() + "子单id为" + item.getId() + "的单据没有库存,波次失败"); - } + //if (inventoryList.isEmpty() && item.getWaveId() != 0) { + // Wave wave = waveService.getById(item.getWaveId()); + // wave.setStatus(QuantityConstant.WAVE_STATUS_ERROR); + // wave.setCurrentWaveStep(QuantityConstant.WAVE_STEP_ERROR); + // wave.setLastWaveStep(QuantityConstant.WAVE_STEP_BUILD); + // waveService.updateById(wave); + // throw new ServiceException("主单为" + item.getShipmentCode() + "子单id为" + item.getId() + "的单据没有库存,波次失败"); + //} if (inventoryList.isEmpty()) { num = num + 1; } else { @@ -629,12 +634,13 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont break; } - //限制组盘数量 - AjaxResult ajaxResult = limitCombinationCount(inventory); - if (ajaxResult.hasErr()) { - throw new ServiceException(ajaxResult.getMsg()); + //限制立库组盘数量 + if (inventory.getIsFlatWarehouse() == 0) { + AjaxResult ajaxResult = limitCombinationCount(inventory); + if (ajaxResult.hasErr()) { + throw new ServiceException(ajaxResult.getMsg()); + } } - BigDecimal inventoryQty = inventory.getQty().subtract(inventory.getTaskQty()); ShipmentCombinationModel shipmentCombination = new ShipmentCombinationModel(); shipmentCombination.setInventoryDetailId(inventory.getId()); @@ -668,25 +674,52 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl<ShipmentCont // 获取巷道信息 String roadway = location.getRoadway(); - // 使用三元运算符根据巷道信息确定限制数量 - int limit = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? - Integer.parseInt(configService.getKey("shipmentTaskBy5RoadLimit")) : - Integer.parseInt(configService.getKey("shipmentContainerTaskLimit")); - - // 使用三元运算符根据巷道信息确定任务数量 - int shipmentTaskCount = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? - taskHeaderService.getShipmentTaskBy5Road() : - taskHeaderService.getShipmentContainerTask(roadway); + LambdaQueryWrapper<Location> wrapper = Wrappers.lambdaQuery(); + wrapper.eq(Location::getRoadway, roadway) + .eq(Location::getStatus, STATUS_LOCATION_EMPTY) + .eq(Location::getHigh, location.getHigh()) + .eq(Location::getContainerCode, "") + .eq(Location::getSelfCreated, NO_TSELFCREATED) + .eq(Location::getOnlyEmptyContainer, NO_EMPTY_CONTAINER_LOCATION); + List<Location> locationList = locationService.list(wrapper); + + if (locationList.size() < 3) { + return AjaxResult.error("该库存出库可能无法回库了"); + } - // 检查任务数量是否超过限制 - if (shipmentTaskCount >= limit) { - // 根据巷道信息拼接错误信息 - String errorMessage = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? - "5号巷道不能存在超过" + limit + "个组盘和任务" : - "不能存在超过" + limit + "个组盘和任务"; - return AjaxResult.error(errorMessage); + List<Location> availableLocations = new ArrayList<>(); + for (Location location1 : locationList) { + // 如果库位内侧没有未完成的任务,则将其添加到可用库位列表中 + if (taskHeaderService.getUncompleteTaskInNear(location1) == 0) { + availableLocations.add(location1); + } + // 如果已经找到了 3 个可用库位,则直接返回成功 + if (availableLocations.size() >= 3) { + return AjaxResult.success(); + } } - return AjaxResult.success(); + + return AjaxResult.error("该库存出库可能无法回库了,可能是空闲库位内/外测有任务了"); + + + //// 使用三元运算符根据巷道信息确定限制数量 + //int limit = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? + // Integer.parseInt(configService.getKey("shipmentTaskBy5RoadLimit")) : + // Integer.parseInt(configService.getKey("shipmentContainerTaskLimit")); + // + //// 使用三元运算符根据巷道信息确定任务数量 + //int shipmentTaskCount = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? + // taskHeaderService.getShipmentTaskBy5Road() : + // taskHeaderService.getShipmentContainerTask(roadway); + // + //// 检查任务数量是否超过限制 + //if (shipmentTaskCount >= limit) { + // // 根据巷道信息拼接错误信息 + // String errorMessage = roadway.equals(QuantityConstant.DYNAMIC_ROADWAY) ? + // "5号巷道不能存在超过" + limit + "个组盘和任务" : + // "不能存在超过" + limit + "个组盘和任务"; + // return AjaxResult.error(errorMessage); + //} } /** diff --git a/src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java b/src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java index 8f52f6c..94006b4 100644 --- a/src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java +++ b/src/main/java/com/huaheng/pc/shipment/shipmentHeader/controller/ShipmentHeaderController.java @@ -562,19 +562,19 @@ public class ShipmentHeaderController extends BaseController { return prefix + "/addWave"; } - /** - * 查询波次列表 - */ - @RequiresPermissions("shipment:bill:wave") - //@Log(title = "出库-出库单", operating = "查询库区列表", action = BusinessType.GRANT) - @PostMapping("/waveList") - @ResponseBody - public TableDataInfo waveList() { - LambdaQueryWrapper<WaveMaster> lam = Wrappers.lambdaQuery(); - lam.eq(WaveMaster::getWarehouseCode, ShiroUtils.getWarehouseCode()); - List<WaveMaster> waveMasters = waveMasterService.list(lam); - return getDataTable(waveMasters); - } + ///** + // * 查询波次列表 + // */ + //@RequiresPermissions("shipment:bill:wave") + ////@Log(title = "出库-出库单", operating = "查询库区列表", action = BusinessType.GRANT) + //@PostMapping("/waveList") + //@ResponseBody + //public TableDataInfo waveList() { + // LambdaQueryWrapper<WaveMaster> lam = Wrappers.lambdaQuery(); + // lam.eq(WaveMaster::getWarehouseCode, ShiroUtils.getWarehouseCode()); + // List<WaveMaster> waveMasters = waveMasterService.list(lam); + // return getDataTable(waveMasters); + //} /** diff --git a/src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java b/src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java index d94b624..5979988 100644 --- a/src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java +++ b/src/main/java/com/huaheng/pc/shipment/shipmentHeader/service/ShipmentHeaderServiceImpl.java @@ -16,6 +16,8 @@ import com.huaheng.framework.web.domain.AjaxResult; import com.huaheng.framework.web.service.ConfigService; import com.huaheng.pc.config.address.service.AddressService; import com.huaheng.pc.config.company.service.CompanyService; +import com.huaheng.pc.config.container.domain.Container; +import com.huaheng.pc.config.container.service.ContainerService; import com.huaheng.pc.config.customer.domain.Customer; import com.huaheng.pc.config.customer.service.CustomerServiceImpl; import com.huaheng.pc.config.location.domain.Location; @@ -25,6 +27,8 @@ import com.huaheng.pc.config.shipmentType.service.ShipmentTypeService; import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail; import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService; import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader; +import com.huaheng.pc.shipment.shipmentContainerDetail.domain.ShipmentContainerDetail; +import com.huaheng.pc.shipment.shipmentContainerDetail.service.ShipmentContainerDetailService; import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerHeader; import com.huaheng.pc.shipment.shipmentContainerHeader.service.ShipmentContainerHeaderService; import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail; @@ -62,7 +66,10 @@ import java.util.stream.Collectors; public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, ShipmentHeader> implements ShipmentHeaderService { @Resource private ShipmentTaskService shipmentTaskService; - + @Resource + private ShipmentContainerDetailService shipmentContainerDetailService; + @Resource + private ContainerService containerService; @Resource private ConfigService configService; @Resource @@ -573,20 +580,19 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, @Override public void autoShipmentExecute(ShipmentHeader shipmentHeader) { - shipmentHeader.setAutoShipmentStatus(4); + shipmentHeader.setAutoShipmentStatus(3); shipmentHeader.setErrorMsg("自动组盘过程中程序错误,请手动组盘"); updateById(shipmentHeader); //自动组盘 AjaxResult containerResult = shipmentContainerHeaderService.autoCombination(shipmentHeader.getCode(), true); - //如果出库单明细全部为出库组盘,就不改状态了,找一些其他地方是不是也修改了,这个修改了应该就直接返回了呀,为什么还完成了单据呢 if (!updateShipmentErrorMsg(containerResult, shipmentHeader)) { return; } - shipmentHeader.setAutoShipmentStatus(4); + + //生成任务 + shipmentHeader.setAutoShipmentStatus(3); shipmentHeader.setErrorMsg("自生成任务过程中程序错误,请手动生成任务"); updateById(shipmentHeader); - - List<ShipmentContainerHeader> shipmentContainerHeaders = shipmentContainerHeaderService.list(new LambdaQueryWrapper<ShipmentContainerHeader>() .eq(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_BUILD)); for (ShipmentContainerHeader item : shipmentContainerHeaders) { @@ -598,21 +604,20 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, } } - //生成任务 //List<Integer> ids = (List<Integer>) containerResult.getData(); //AjaxResult taskResult = shipmentContainerHeaderService.createAutoTask(ids); //if (!updateShipmentErrorMsg(taskResult, shipmentHeader)) { // return; //} - + //自动打印 int isPrint = Integer.parseInt(configService.getKey(QuantityConstant.AUTO_SHIPMENT_PRINT)); if (isPrint == 1) { - shipmentHeader.setAutoShipmentStatus(4); + shipmentHeader.setAutoShipmentStatus(3); shipmentHeader.setErrorMsg("自动打印过程中程序错误,请手动打印"); updateById(shipmentHeader); AjaxResult reportResult = shipmentHeaderService.autoReportShipment(-1, shipmentHeader.getCode(), "1"); - if (updateShipmentErrorMsg(reportResult, shipmentHeader)) { + if (!updateShipmentErrorMsg(reportResult, shipmentHeader)) { return; } } @@ -620,7 +625,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, //自动出库完成 shipmentHeader.setAutoShipmentStatus(2); shipmentHeader.setErrorMsg(""); - updateById(shipmentHeader); + shipmentHeaderService.updateById(shipmentHeader); } @@ -632,7 +637,7 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl<ShipmentHeaderMapper, errorMsg = errorMsg.substring(0, 500); } shipmentHeader.setErrorMsg(errorMsg); - updateById(shipmentHeader); + shipmentHeaderService.updateById(shipmentHeader); return false; } return true; diff --git a/src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java b/src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java index 653fb3d..4b8a720 100644 --- a/src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java +++ b/src/main/java/com/huaheng/pc/task/taskHeader/service/ReceiptTaskService.java @@ -356,9 +356,12 @@ public class ReceiptTaskService { List<InventoryDetail> inventoryDetails = inventoryDetailService.list(new LambdaQueryWrapper<InventoryDetail>().eq(InventoryDetail::getInventoryHeaderId, inventoryHeader.getId())); if (inventoryDetails != null && !inventoryDetails.isEmpty()) { for (InventoryDetail inventoryDetail : inventoryDetails) { - inventoryDetail.setLocationCode(toLocation.getCode()); - inventoryDetail.setZoneCode(toLocation.getZoneCode()); - if (!inventoryDetailService.updateById(inventoryDetail)) { + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper + .eq(InventoryDetail::getId, inventoryDetail.getId()) + .set(InventoryDetail::getLocationCode, toLocation.getCode()) + .set(InventoryDetail::getZoneCode, toLocation.getZoneCode()); + if (!inventoryDetailService.update(updateWrapper)) { throw new ServiceException("补充入库,更新库存明细失败"); } } diff --git a/src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java b/src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java index 670b957..c936b12 100644 --- a/src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java +++ b/src/main/java/com/huaheng/pc/task/taskHeader/service/ShipmentTaskService.java @@ -365,8 +365,11 @@ public class ShipmentTaskService { List<InventoryDetail> inventoryDetails = inventoryDetailService.list(new LambdaQueryWrapper<InventoryDetail>().eq(InventoryDetail::getInventoryHeaderId, inventoryHeader.getId())); if (inventoryDetails != null && !inventoryDetails.isEmpty()) { for (InventoryDetail inventoryDetail : inventoryDetails) { - inventoryDetail.setLocationCode(task.getToLocation()); - if (!inventoryDetailService.updateById(inventoryDetail)) { + + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper.eq(InventoryDetail::getId, inventoryDetail.getId()) + .set(InventoryDetail::getLocationCode, task.getToLocation()); + if (!inventoryDetailService.update(updateWrapper)) { throw new ServiceException("完成出库任务,库存修改目标库位时失败" + inventoryDetail.getId()); } } @@ -381,13 +384,14 @@ public class ShipmentTaskService { //获取出库组盘明细 ShipmentContainerDetail shipmentContainerDetail = shipmentContainerDetailService.getById(taskDetail.getAllocationId()); //获取对应库存记录 - InventoryDetail inventoryDetail = inventoryDetailService.getById(taskDetail.getToInventoryId()); + InventoryDetail inventoryDetail = inventoryDetailService.getByIdForUpdate(taskDetail.getToInventoryId()); if (inventoryDetail == null) { throw new ServiceException("任务明细对应的库存ID【" + taskDetail.getToInventoryId().toString() + "】不存在!"); } inventoryDetail.setLastUpdatedBy(taskDetail.getLastUpdatedBy()); //减扣库存单 - inventoryHeader = inventoryHeaderService.getById(inventoryDetail.getInventoryHeaderId()); + // 使用悲观锁查询库存主表 + inventoryHeader = inventoryHeaderService.getByIdForUpdate(inventoryDetail.getInventoryHeaderId()); //扣减库存明细 inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty())); diff --git a/src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java b/src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java index ac3c10f..281bb58 100644 --- a/src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java +++ b/src/main/java/com/huaheng/pc/task/taskHeader/service/TransferTaskService.java @@ -191,7 +191,7 @@ public class TransferTaskService { taskDetail.setFromInventoryId(inventoryDetail.getId()); taskDetail.setToInventoryId(inventoryDetail.getId()); taskDetail.setLastUpdatedBy(ShiroUtils.getName()); - if (!taskDetailService.save(taskDetail) || !inventoryDetailService.updateById(inventoryDetail)) { + if (!taskDetailService.save(taskDetail)) { throw new ServiceException("创建任务失败"); } } diff --git a/src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java b/src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java index 340d871..76f58ac 100644 --- a/src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java +++ b/src/main/java/com/huaheng/pc/task/taskHeader/service/WorkTaskService.java @@ -769,8 +769,7 @@ public class WorkTaskService { taskDetail.setMaterialName(inventoryDetail.getMaterialName()); taskDetail.setMaterialSpec(inventoryDetail.getMaterialSpec()); taskDetail.setMaterialUnit(inventoryDetail.getMaterialUnit()); - if (!taskDetailService.save(taskDetail) || - !inventoryDetailService.updateById(inventoryDetail)) { + if (!taskDetailService.save(taskDetail)) { throw new ServiceException("任务创建失败"); } } @@ -843,7 +842,7 @@ public class WorkTaskService { if (inventoryDetail.getId().equals(inventoryDetail2.getId())) { taskDetail.setInventoryTransactionId(inventoryTransactionId); } - if (!taskDetailService.save(taskDetail) || !inventoryDetailService.updateById(inventoryDetail)) { + if (!taskDetailService.save(taskDetail)) { throw new ServiceException("任务创建失败"); } } @@ -919,8 +918,13 @@ public class WorkTaskService { List<InventoryDetail> inventoryDetails = inventoryDetailService.list(lambdaQueryWrapper2); if (inventoryDetails != null && !inventoryDetails.isEmpty()) { for (InventoryDetail inventoryDetail : inventoryDetails) { - inventoryDetail.setLocationCode(taskHeader.getToLocation()); - inventoryDetailService.updateById(inventoryDetail); + LambdaUpdateWrapper<InventoryDetail> updateWrapper = Wrappers.lambdaUpdate(); + updateWrapper.eq(InventoryDetail::getId, inventoryDetail.getId()) + .set(InventoryDetail::getLocationCode, taskHeader.getToLocation()); + if (!inventoryDetailService.update(updateWrapper)) { + throw new ServiceException("库存修改目标库位时失败" + inventoryDetail.getId()); + } + } containerService.updateStatus(containerCode, QuantityConstant.STATUS_CONTAINER_SOME, warehouseCode); } diff --git a/src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html b/src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html index cb957fa..ed2cd72 100644 --- a/src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html +++ b/src/main/resources/templates/shipment/shipmentHeader/shipmentHeader.html @@ -289,10 +289,10 @@ <i class="fa fa-code-fork"></i> 自动组盘 </a> - <a class="btn btn-outline btn-primary btn-rounded auto-shipment-task" onclick="Toshipping(2)" - shiro:hasPermission="shipment:shippingCombination:combination"> - <i class="fa fa-code-fork"></i> 自动组盘并生成任务 - </a> + <!-- <a class="btn btn-outline btn-primary btn-rounded auto-shipment-task" onclick="Toshipping(2)"--> + <!-- shiro:hasPermission="shipment:shippingCombination:combination">--> + <!-- <i class="fa fa-code-fork"></i> 自动组盘并生成任务--> + <!-- </a>--> <a class="btn btn-outline btn-primary btn-rounded auto-shipment" onclick="Toshipping(3)" shiro:hasPermission="shipment:shippingCombination:combination"> <i class="fa fa-code-fork"></i> 自动平库组盘 -- libgit2 0.22.2