Commit 9221527d921ba9159076ee69081d931db4017e54

Authored by YunaiV
1 parent 5eefbfe1

✨ feat(mes): 新增退货明细数量校验逻辑

新增校验逻辑以确保退货明细总数量不超过对应退货行的数量,提升数据一致性和准确性。
同时,重构相关方法以简化数据验证过程。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -517,6 +517,7 @@ public interface ErrorCodeConstants {
517 517 ErrorCode WM_RETURN_SALES_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_713_007, "销售退货单已完成或已取消,无法取消");
518 518 ErrorCode WM_RETURN_SALES_LINE_NOT_EXISTS = new ErrorCode(1_040_713_100, "销售退货单行不存在");
519 519 ErrorCode WM_RETURN_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_713_200, "销售退货单明细不存在");
  520 + ErrorCode WM_RETURN_SALES_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_713_201, "上架明细总数量不能超过退货行数量");
520 521  
521 522 // ========== MES 仓库管理-盘点方案/任务/结果(1-040-714-100) ==========
522 523 ErrorCode WM_STOCK_TAKING_PLAN_NOT_EXISTS = new ErrorCode(1_040_714_100, "盘点方案不存在");
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailServiceImpl.java
1 1 package cn.iocoder.yudao.module.mes.service.wm.returnsales;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
3 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 5 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailSaveReqVO;
5 6 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO;
6 8 import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesDetailMapper;
7   -import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  9 +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
  10 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
8 11 import jakarta.annotation.Resource;
9 12 import org.springframework.context.annotation.Lazy;
10 13 import org.springframework.stereotype.Service;
11 14 import org.springframework.validation.annotation.Validated;
12 15  
  16 +import java.math.BigDecimal;
13 17 import java.util.List;
14 18  
15 19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16 20 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_SALES_DETAIL_NOT_EXISTS;
  21 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_SALES_DETAIL_QUANTITY_EXCEED;
17 22  
18 23 /**
19 24 * MES 销售退货明细 Service 实现类
... ... @@ -32,14 +37,15 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
32 37 private MesWmReturnSalesLineService returnSalesLineService;
33 38  
34 39 @Resource
35   - private MesMdItemService itemService;
  40 + private MesWmWarehouseAreaService warehouseAreaService;
  41 +
  42 + @Resource
  43 + @Lazy
  44 + private MesWmMaterialStockService materialStockService;
36 45  
37 46 @Override
38 47 public Long createReturnSalesDetail(MesWmReturnSalesDetailSaveReqVO createReqVO) {
39   - // 校验父数据存在
40   - returnSalesLineService.validateReturnSalesLineExists(createReqVO.getLineId());
41   - // 校验物料存在
42   - itemService.validateItemExists(createReqVO.getItemId());
  48 + validateReturnSalesDetailSaveData(createReqVO);
43 49  
44 50 // 插入
45 51 MesWmReturnSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmReturnSalesDetailDO.class);
... ... @@ -51,10 +57,7 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
51 57 public void updateReturnSalesDetail(MesWmReturnSalesDetailSaveReqVO updateReqVO) {
52 58 // 校验存在
53 59 validateReturnSalesDetailExists(updateReqVO.getId());
54   - // 校验父数据存在
55   - returnSalesLineService.validateReturnSalesLineExists(updateReqVO.getLineId());
56   - // 校验物料存在
57   - itemService.validateItemExists(updateReqVO.getItemId());
  60 + validateReturnSalesDetailSaveData(updateReqVO);
58 61  
59 62 // 更新
60 63 MesWmReturnSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesDetailDO.class);
... ... @@ -95,4 +98,41 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
95 98 }
96 99 }
97 100  
  101 + /**
  102 + * 校验保存时的关联数据
  103 + */
  104 + private void validateReturnSalesDetailSaveData(MesWmReturnSalesDetailSaveReqVO reqVO) {
  105 + // 校验父数据存在
  106 + MesWmReturnSalesLineDO line = returnSalesLineService.validateReturnSalesLineExists(reqVO.getLineId());
  107 + // 校验仓库、库区、库位的关联关系
  108 + warehouseAreaService.validateWarehouseAreaExists(
  109 + reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
  110 + // 校验库位物料/批次混放规则
  111 + materialStockService.checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId());
  112 + // 校验明细总数量不超过行数量(排除自身)
  113 + validateDetailQuantityNotExceed(reqVO.getLineId(), reqVO.getQuantity(), reqVO.getId(), line);
  114 + }
  115 +
  116 + /**
  117 + * 校验明细总数量不超过行数量
  118 + *
  119 + * @param lineId 行 ID
  120 + * @param newQuantity 本次新增/修改的数量
  121 + * @param excludeDetailId 排除的明细 ID(更新时排除自身,新增时传 null)
  122 + * @param line 退货单行
  123 + */
  124 + private void validateDetailQuantityNotExceed(Long lineId, BigDecimal newQuantity,
  125 + Long excludeDetailId, MesWmReturnSalesLineDO line) {
  126 + // 计算已有明细总数量(排除自身)
  127 + List<MesWmReturnSalesDetailDO> details = returnSalesDetailMapper.selectListByLineId(lineId);
  128 + BigDecimal existingTotal = CollectionUtils.getSumValue(details,
  129 + detail -> excludeDetailId != null && excludeDetailId.equals(detail.getId())
  130 + ? BigDecimal.ZERO : detail.getQuantity(),
  131 + BigDecimal::add, BigDecimal.ZERO);
  132 + // 校验:已有 + 本次 <= 行数量
  133 + if (existingTotal.add(newQuantity).compareTo(line.getQuantity()) > 0) {
  134 + throw exception(WM_RETURN_SALES_DETAIL_QUANTITY_EXCEED);
  135 + }
  136 + }
  137 +
98 138 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java
... ... @@ -45,10 +45,7 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ
45 45  
46 46 @Override
47 47 public Long createReturnSalesLine(MesWmReturnSalesLineSaveReqVO createReqVO) {
48   - // 校验父数据存在
49   - returnSalesService.validateReturnSalesExists(createReqVO.getReturnId());
50   - // 校验物料存在
51   - validateItemBatchManagement(createReqVO.getItemId(), createReqVO.getBatchId());
  48 + validateLineSaveData(createReqVO);
52 49  
53 50 // 插入
54 51 MesWmReturnSalesLineDO line = BeanUtils.toBean(createReqVO, MesWmReturnSalesLineDO.class);
... ... @@ -62,10 +59,7 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ
62 59 public void updateReturnSalesLine(MesWmReturnSalesLineSaveReqVO updateReqVO) {
63 60 // 校验存在
64 61 validateReturnSalesLineExists(updateReqVO.getId());
65   - // 校验父数据存在
66   - returnSalesService.validateReturnSalesExists(updateReqVO.getReturnId());
67   - // 校验物料存在
68   - validateItemBatchManagement(updateReqVO.getItemId(), updateReqVO.getBatchId());
  62 + validateLineSaveData(updateReqVO);
69 63  
70 64 // 更新
71 65 MesWmReturnSalesLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesLineDO.class);
... ... @@ -74,6 +68,16 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ
74 68 returnSalesLineMapper.updateById(updateObj);
75 69 }
76 70  
  71 + /**
  72 + * 校验保存时的关联数据
  73 + */
  74 + private void validateLineSaveData(MesWmReturnSalesLineSaveReqVO reqVO) {
  75 + // 校验退货单存在
  76 + returnSalesService.validateReturnSalesExists(reqVO.getReturnId());
  77 + // 校验物料存在 + 批次管理
  78 + validateItemBatchManagement(reqVO.getItemId(), reqVO.getBatchId());
  79 + }
  80 +
77 81 @Override
78 82 public void deleteReturnSalesLine(Long id) {
79 83 // 校验存在
... ...