refactor(wms): 优化退库操作流程
- 移除了不必要的验证逻辑,简化了代码结构 - 使用 stream API 优化了原出库明细的查找和已退库数量的计算 -调整了退库数量验证的逻辑,提高了用户体验 -优化了单位的获取逻辑,增加了默认值
This commit is contained in:
@@ -191,99 +191,100 @@ public class WmsStockIoServiceImpl implements IWmsStockIoService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean scanReturnStockByBo(WmsStockIoBo bo) {
|
||||
// 退库操作:根据明细ID查询明细,根据parent_id获取原出库单明细,验证退库数量
|
||||
// 退库操作:根据主表ID查询明细列表,验证退库数量,执行退库
|
||||
if (bo.getStockIoId() == null) {
|
||||
throw new ServiceException("退库明细ID不能为空");
|
||||
throw new ServiceException("退库单ID不能为空");
|
||||
}
|
||||
|
||||
// 1. 根据明细ID查询退库单明细
|
||||
WmsStockIoDetail returnDetail = stockIoDetailMapper.selectById(bo.getStockIoId());
|
||||
if (returnDetail == null) {
|
||||
throw new ServiceException("退库明细不存在");
|
||||
}
|
||||
|
||||
// 2. 获取退库单主表信息
|
||||
WmsStockIo returnStockIo = baseMapper.selectById(returnDetail.getStockIoId());
|
||||
// 1. 获取退库单主表信息
|
||||
WmsStockIo returnStockIo = baseMapper.selectById(bo.getStockIoId());
|
||||
if (returnStockIo == null || returnStockIo.getParentId() == null) {
|
||||
throw new ServiceException("退库单不存在或未关联原出库单");
|
||||
}
|
||||
|
||||
// 验证退库单类型必须是退库类型
|
||||
if (!"withdraw".equals(returnStockIo.getIoType())) {
|
||||
throw new ServiceException("单据类型必须是退库类型");
|
||||
}
|
||||
|
||||
// 3. 获取原出库单信息
|
||||
WmsStockIo originalOutStockIo = baseMapper.selectById(returnStockIo.getParentId());
|
||||
if (originalOutStockIo == null || !"out".equals(originalOutStockIo.getIoType())) {
|
||||
throw new ServiceException("原出库单不存在或类型错误");
|
||||
}
|
||||
|
||||
// 4. 查找对应的原出库明细
|
||||
List<WmsStockIoDetail> originalOutDetails = stockIoDetailMapper.selectList(
|
||||
Wrappers.<WmsStockIoDetail>lambdaQuery()
|
||||
.eq(WmsStockIoDetail::getStockIoId, returnStockIo.getParentId())
|
||||
// 2. 获取退库单明细列表
|
||||
List<WmsStockIoDetail> returnDetails = stockIoDetailMapper.selectList(
|
||||
Wrappers.<WmsStockIoDetail>lambdaQuery().eq(WmsStockIoDetail::getStockIoId, bo.getStockIoId())
|
||||
);
|
||||
|
||||
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("未找到对应的原出库明细");
|
||||
if (returnDetails == null || returnDetails.isEmpty()) {
|
||||
throw new ServiceException("退库单明细不能为空");
|
||||
}
|
||||
|
||||
// 5. 验证退库数量不能超过原出库数量
|
||||
BigDecimal totalReturnedQty = baseMapper.selectList(
|
||||
Wrappers.<WmsStockIo>lambdaQuery()
|
||||
.eq(WmsStockIo::getParentId, returnStockIo.getParentId())
|
||||
.eq(WmsStockIo::getIoType, "withdraw")
|
||||
.ne(WmsStockIo::getStockIoId, returnStockIo.getStockIoId())
|
||||
).stream()
|
||||
.flatMap(returnStockIoItem -> stockIoDetailMapper.selectList(
|
||||
Wrappers.<WmsStockIoDetail>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);
|
||||
// 3. 获取原出库单明细列表
|
||||
List<WmsStockIoDetail> originalOutDetails = stockIoDetailMapper.selectList(
|
||||
Wrappers.<WmsStockIoDetail>lambdaQuery().eq(WmsStockIoDetail::getStockIoId, returnStockIo.getParentId())
|
||||
);
|
||||
|
||||
BigDecimal remainingQty = originalOutDetail.getQuantity().subtract(totalReturnedQty);
|
||||
if (returnDetail.getQuantity().compareTo(remainingQty) > 0) {
|
||||
throw new ServiceException("退库数量超过原出库数量,剩余可退数量:" + remainingQty);
|
||||
if (originalOutDetails == null || originalOutDetails.isEmpty()) {
|
||||
throw new ServiceException("原出库单明细不存在");
|
||||
}
|
||||
|
||||
// 6. 执行退库操作(增加库存)
|
||||
String unit = returnDetail.getUnit();
|
||||
if (unit == null || unit.trim().isEmpty()) {
|
||||
if ("product".equals(returnDetail.getItemType())) {
|
||||
WmsProduct p = productMapper.selectById(returnDetail.getItemId());
|
||||
unit = p != null ? p.getUnit() : "个";
|
||||
} else if ("raw_material".equals(returnDetail.getItemType())) {
|
||||
WmsRawMaterial r = rawMaterialMapper.selectById(returnDetail.getItemId());
|
||||
unit = r != null ? r.getUnit() : "个";
|
||||
// 4. 遍历退库明细,验证数量并执行退库
|
||||
for (WmsStockIoDetail returnDetail : returnDetails) {
|
||||
// 查找对应的原出库明细
|
||||
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("未找到对应的原出库明细:" + returnDetail.getItemType() + "-" + returnDetail.getItemId());
|
||||
}
|
||||
|
||||
// 验证退库数量不能超过原出库数量
|
||||
BigDecimal totalReturnedQty = baseMapper.selectList(
|
||||
Wrappers.<WmsStockIo>lambdaQuery()
|
||||
.eq(WmsStockIo::getParentId, returnStockIo.getParentId())
|
||||
.eq(WmsStockIo::getIoType, "withdraw")
|
||||
.ne(WmsStockIo::getStockIoId, returnStockIo.getStockIoId())
|
||||
).stream()
|
||||
.flatMap(returnStockIoItem -> stockIoDetailMapper.selectList(
|
||||
Wrappers.<WmsStockIoDetail>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);
|
||||
|
||||
BigDecimal remainingQty = originalOutDetail.getQuantity().subtract(totalReturnedQty);
|
||||
if (returnDetail.getQuantity().compareTo(remainingQty) > 0) {
|
||||
throw new ServiceException("退库数量超过原出库数量,物品:" + returnDetail.getItemType() + "-" + returnDetail.getItemId() +
|
||||
",原出库数量:" + originalOutDetail.getQuantity() + ",已退库数量:" + totalReturnedQty +
|
||||
",剩余可退数量:" + remainingQty + ",本次退库数量:" + returnDetail.getQuantity());
|
||||
}
|
||||
|
||||
// 执行退库操作(增加库存)
|
||||
String unit = returnDetail.getUnit();
|
||||
if (unit == null || unit.trim().isEmpty()) {
|
||||
if ("product".equals(returnDetail.getItemType())) {
|
||||
WmsProduct p = productMapper.selectById(returnDetail.getItemId());
|
||||
unit = p != null ? p.getUnit() : "个";
|
||||
} else if ("raw_material".equals(returnDetail.getItemType())) {
|
||||
WmsRawMaterial r = rawMaterialMapper.selectById(returnDetail.getItemId());
|
||||
unit = r != null ? r.getUnit() : "个";
|
||||
}
|
||||
}
|
||||
|
||||
// 执行入库操作(退库就是入库)
|
||||
changeStock(returnDetail.getWarehouseId(), returnDetail.getItemType(),
|
||||
returnDetail.getItemId(), returnDetail.getQuantity(), true, unit);
|
||||
|
||||
// 记录退库操作日志
|
||||
WmsStockLog returnLog = new WmsStockLog();
|
||||
returnLog.setWarehouseId(returnDetail.getWarehouseId());
|
||||
returnLog.setItemType(returnDetail.getItemType());
|
||||
returnLog.setItemId(returnDetail.getItemId());
|
||||
returnLog.setChangeQty(returnDetail.getQuantity());
|
||||
returnLog.setChangeType("退库");
|
||||
returnLog.setChangeTime(new Date());
|
||||
stockLogMapper.insert(returnLog);
|
||||
}
|
||||
|
||||
// 执行入库操作(退库就是入库)
|
||||
changeStock(returnDetail.getWarehouseId(), returnDetail.getItemType(),
|
||||
returnDetail.getItemId(), returnDetail.getQuantity(), true, unit);
|
||||
|
||||
// 记录退库操作日志
|
||||
WmsStockLog returnLog = new WmsStockLog();
|
||||
returnLog.setWarehouseId(returnDetail.getWarehouseId());
|
||||
returnLog.setItemType(returnDetail.getItemType());
|
||||
returnLog.setItemId(returnDetail.getItemId());
|
||||
returnLog.setChangeQty(returnDetail.getQuantity());
|
||||
returnLog.setChangeType("退库");
|
||||
returnLog.setChangeTime(new Date());
|
||||
stockLogMapper.insert(returnLog);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user