diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java index 7f853c1b..114c3c88 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsStockIoServiceImpl.java @@ -191,170 +191,84 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService { @Override @Transactional(rollbackFor = Exception.class) public boolean scanReturnStockByBo(WmsStockIoBo bo) { - // 退库操作:根据id查询明细表,根据parent_id获取原出库单明细,验证退库数量 + // 退库操作:根据明细ID查询明细,根据parent_id获取原出库单明细,验证退库数量 if (bo.getStockIoId() == null) { - throw new ServiceException("退库单ID不能为空"); + throw new ServiceException("退库明细ID不能为空"); } - // 1. 根据id查询退库单明细 + // 1. 根据明细ID查询退库单明细 WmsStockIoDetail returnDetail = stockIoDetailMapper.selectById(bo.getStockIoId()); if (returnDetail == null) { throw new ServiceException("退库明细不存在"); } - // 验证退库数量必须大于0 - if (returnDetail.getQuantity() == null || returnDetail.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { - throw new ServiceException("退库数量必须大于0"); - } - - // 验证物品类型和物品ID的有效性 - if (returnDetail.getItemType() == null || returnDetail.getItemId() == null) { - throw new ServiceException("物品类型和物品ID不能为空"); - } - - if (!"product".equals(returnDetail.getItemType()) && !"raw_material".equals(returnDetail.getItemType())) { - throw new ServiceException("物品类型必须是product或raw_material"); - } - - // 验证库位ID的有效性 - if (returnDetail.getWarehouseId() == null) { - throw new ServiceException("库位ID不能为空"); - } - - // 验证物品是否存在 - if ("product".equals(returnDetail.getItemType())) { - WmsProduct product = productMapper.selectById(returnDetail.getItemId()); - if (product == null) { - throw new ServiceException("产品不存在"); - } - } else if ("raw_material".equals(returnDetail.getItemType())) { - WmsRawMaterial rawMaterial = rawMaterialMapper.selectById(returnDetail.getItemId()); - if (rawMaterial == null) { - throw new ServiceException("原材料不存在"); - } - } - - // 验证库位是否存在 - WmsWarehouse warehouse = warehouseMapper.selectById(returnDetail.getWarehouseId()); - if (warehouse == null) { - throw new ServiceException("库位不存在"); - } - - // 验证库位是否启用 - if (warehouse.getIsEnabled() == null || warehouse.getIsEnabled() != 1) { - throw new ServiceException("库位未启用,无法进行退库操作"); - } - // 2. 获取退库单主表信息 WmsStockIo returnStockIo = baseMapper.selectById(returnDetail.getStockIoId()); - if (returnStockIo == null) { - throw new ServiceException("退库单不存在"); + if (returnStockIo == null || returnStockIo.getParentId() == null) { + throw new ServiceException("退库单不存在或未关联原出库单"); } - // 验证退库单类型必须是入库类型 - if (!"in".equals(returnStockIo.getIoType())) { - throw new ServiceException("退库单类型必须是入库类型"); - } - - // 验证退库单状态必须是已提交或已审核状态 - if (returnStockIo.getStatus() == null || (returnStockIo.getStatus() != 1 && returnStockIo.getStatus() != 2)) { - throw new ServiceException("退库单必须是已提交或已审核状态才能执行退库操作"); - } - - // 3. 根据parent_id获取原出库单的所有明细 - if (returnStockIo.getParentId() == null) { - throw new ServiceException("退库单未关联原出库单"); + // 验证退库单类型必须是退库类型 + if (!"withdraw".equals(returnStockIo.getIoType())) { + throw new ServiceException("单据类型必须是退库类型"); } + // 3. 获取原出库单信息 WmsStockIo originalOutStockIo = baseMapper.selectById(returnStockIo.getParentId()); - if (originalOutStockIo == null) { - throw new ServiceException("原出库单不存在"); + if (originalOutStockIo == null || !"out".equals(originalOutStockIo.getIoType())) { + throw new ServiceException("原出库单不存在或类型错误"); } - if (!"out".equals(originalOutStockIo.getIoType())) { - throw new ServiceException("原单据不是出库单"); - } - - // 验证原出库单状态必须是已审核状态 - if (originalOutStockIo.getStatus() == null || originalOutStockIo.getStatus() != 2) { - throw new ServiceException("原出库单必须是已审核状态才能进行退库操作"); - } - - // 4. 获取原出库单的所有明细 + // 4. 查找对应的原出库明细 List originalOutDetails = stockIoDetailMapper.selectList( Wrappers.lambdaQuery() .eq(WmsStockIoDetail::getStockIoId, returnStockIo.getParentId()) ); - if (originalOutDetails == null || originalOutDetails.isEmpty()) { - throw new ServiceException("原出库单明细不存在"); - } - - // 5. 查找对应的原出库明细(根据物品类型、物品ID、库位ID匹配) - WmsStockIoDetail originalOutDetail = null; - for (WmsStockIoDetail detail : originalOutDetails) { - if (detail.getItemType().equals(returnDetail.getItemType()) && - detail.getItemId().equals(returnDetail.getItemId()) && - detail.getWarehouseId().equals(returnDetail.getWarehouseId())) { - originalOutDetail = detail; - break; - } - } - + WmsStockIoDetail originalOutDetail = originalOutDetails.stream() + .filter(detail -> detail.getItemType().equals(returnDetail.getItemType()) && + detail.getItemId().equals(returnDetail.getItemId()) && + detail.getWarehouseId().equals(returnDetail.getWarehouseId())) + .findFirst() + .orElse(null); + if (originalOutDetail == null) { throw new ServiceException("未找到对应的原出库明细"); } - // 6. 查询该物品已退库的总数量 - BigDecimal totalReturnedQty = BigDecimal.ZERO; - List returnStockIos = baseMapper.selectList( + // 5. 验证退库数量不能超过原出库数量 + BigDecimal totalReturnedQty = baseMapper.selectList( Wrappers.lambdaQuery() .eq(WmsStockIo::getParentId, returnStockIo.getParentId()) - .eq(WmsStockIo::getIoType, "in") // 退库单类型为入库 - ); + .eq(WmsStockIo::getIoType, "withdraw") + .ne(WmsStockIo::getStockIoId, returnStockIo.getStockIoId()) + ).stream() + .flatMap(returnStockIoItem -> stockIoDetailMapper.selectList( + Wrappers.lambdaQuery() + .eq(WmsStockIoDetail::getStockIoId, returnStockIoItem.getStockIoId()) + .eq(WmsStockIoDetail::getItemType, returnDetail.getItemType()) + .eq(WmsStockIoDetail::getItemId, returnDetail.getItemId()) + .eq(WmsStockIoDetail::getWarehouseId, returnDetail.getWarehouseId()) + ).stream()) + .map(WmsStockIoDetail::getQuantity) + .reduce(BigDecimal.ZERO, BigDecimal::add); - for (WmsStockIo returnStockIoItem : returnStockIos) { - // 排除当前正在处理的退库单 - if (returnStockIoItem.getStockIoId().equals(returnStockIo.getStockIoId())) { - continue; - } - - List returnDetails = stockIoDetailMapper.selectList( - Wrappers.lambdaQuery() - .eq(WmsStockIoDetail::getStockIoId, returnStockIoItem.getStockIoId()) - .eq(WmsStockIoDetail::getItemType, returnDetail.getItemType()) - .eq(WmsStockIoDetail::getItemId, returnDetail.getItemId()) - .eq(WmsStockIoDetail::getWarehouseId, returnDetail.getWarehouseId()) - ); - - for (WmsStockIoDetail detail : returnDetails) { - totalReturnedQty = totalReturnedQty.add(detail.getQuantity()); - } - } - - // 7. 验证退库数量不能超过原出库数量 BigDecimal remainingQty = originalOutDetail.getQuantity().subtract(totalReturnedQty); if (returnDetail.getQuantity().compareTo(remainingQty) > 0) { - throw new ServiceException("退库数量超过原出库数量,原出库数量:" + originalOutDetail.getQuantity() + - ",已退库数量:" + totalReturnedQty + ",剩余可退数量:" + remainingQty + - ",本次退库数量:" + returnDetail.getQuantity()); + throw new ServiceException("退库数量超过原出库数量,剩余可退数量:" + remainingQty); } - // 8. 执行退库操作(增加库存) + // 6. 执行退库操作(增加库存) String unit = returnDetail.getUnit(); - // 如果unit为空,自动查item表补全 if (unit == null || unit.trim().isEmpty()) { if ("product".equals(returnDetail.getItemType())) { WmsProduct p = productMapper.selectById(returnDetail.getItemId()); - unit = p != null ? p.getUnit() : null; + unit = p != null ? p.getUnit() : "个"; } else if ("raw_material".equals(returnDetail.getItemType())) { WmsRawMaterial r = rawMaterialMapper.selectById(returnDetail.getItemId()); - unit = r != null ? r.getUnit() : null; + unit = r != null ? r.getUnit() : "个"; } } - if (unit == null || unit.trim().isEmpty()) { - throw new ServiceException("未能获取到单位"); - } // 执行入库操作(退库就是入库) changeStock(returnDetail.getWarehouseId(), returnDetail.getItemType(),