Commit 9221527d921ba9159076ee69081d931db4017e54
1 parent
5eefbfe1
✨ feat(mes): 新增退货明细数量校验逻辑
新增校验逻辑以确保退货明细总数量不超过对应退货行的数量,提升数据一致性和准确性。 同时,重构相关方法以简化数据验证过程。
Showing
3 changed files
with
63 additions
and
18 deletions
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 | // 校验存在 | ... | ... |