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,6 +517,7 @@ public interface ErrorCodeConstants { | ||
| 517 | ErrorCode WM_RETURN_SALES_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_713_007, "销售退货单已完成或已取消,无法取消"); | 517 | ErrorCode WM_RETURN_SALES_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_713_007, "销售退货单已完成或已取消,无法取消"); |
| 518 | ErrorCode WM_RETURN_SALES_LINE_NOT_EXISTS = new ErrorCode(1_040_713_100, "销售退货单行不存在"); | 518 | ErrorCode WM_RETURN_SALES_LINE_NOT_EXISTS = new ErrorCode(1_040_713_100, "销售退货单行不存在"); |
| 519 | ErrorCode WM_RETURN_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_713_200, "销售退货单明细不存在"); | 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 | // ========== MES 仓库管理-盘点方案/任务/结果(1-040-714-100) ========== | 522 | // ========== MES 仓库管理-盘点方案/任务/结果(1-040-714-100) ========== |
| 522 | ErrorCode WM_STOCK_TAKING_PLAN_NOT_EXISTS = new ErrorCode(1_040_714_100, "盘点方案不存在"); | 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 | package cn.iocoder.yudao.module.mes.service.wm.returnsales; | 1 | package cn.iocoder.yudao.module.mes.service.wm.returnsales; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 3 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 4 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailSaveReqVO; | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailSaveReqVO; |
| 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO; | 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 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesDetailMapper; | 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 | import jakarta.annotation.Resource; | 11 | import jakarta.annotation.Resource; |
| 9 | import org.springframework.context.annotation.Lazy; | 12 | import org.springframework.context.annotation.Lazy; |
| 10 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| 11 | import org.springframework.validation.annotation.Validated; | 14 | import org.springframework.validation.annotation.Validated; |
| 12 | 15 | ||
| 16 | +import java.math.BigDecimal; | ||
| 13 | import java.util.List; | 17 | import java.util.List; |
| 14 | 18 | ||
| 15 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 16 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_SALES_DETAIL_NOT_EXISTS; | 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 | * MES 销售退货明细 Service 实现类 | 24 | * MES 销售退货明细 Service 实现类 |
| @@ -32,14 +37,15 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail | @@ -32,14 +37,15 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail | ||
| 32 | private MesWmReturnSalesLineService returnSalesLineService; | 37 | private MesWmReturnSalesLineService returnSalesLineService; |
| 33 | 38 | ||
| 34 | @Resource | 39 | @Resource |
| 35 | - private MesMdItemService itemService; | 40 | + private MesWmWarehouseAreaService warehouseAreaService; |
| 41 | + | ||
| 42 | + @Resource | ||
| 43 | + @Lazy | ||
| 44 | + private MesWmMaterialStockService materialStockService; | ||
| 36 | 45 | ||
| 37 | @Override | 46 | @Override |
| 38 | public Long createReturnSalesDetail(MesWmReturnSalesDetailSaveReqVO createReqVO) { | 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 | MesWmReturnSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmReturnSalesDetailDO.class); | 51 | MesWmReturnSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmReturnSalesDetailDO.class); |
| @@ -51,10 +57,7 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail | @@ -51,10 +57,7 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail | ||
| 51 | public void updateReturnSalesDetail(MesWmReturnSalesDetailSaveReqVO updateReqVO) { | 57 | public void updateReturnSalesDetail(MesWmReturnSalesDetailSaveReqVO updateReqVO) { |
| 52 | // 校验存在 | 58 | // 校验存在 |
| 53 | validateReturnSalesDetailExists(updateReqVO.getId()); | 59 | validateReturnSalesDetailExists(updateReqVO.getId()); |
| 54 | - // 校验父数据存在 | ||
| 55 | - returnSalesLineService.validateReturnSalesLineExists(updateReqVO.getLineId()); | ||
| 56 | - // 校验物料存在 | ||
| 57 | - itemService.validateItemExists(updateReqVO.getItemId()); | 60 | + validateReturnSalesDetailSaveData(updateReqVO); |
| 58 | 61 | ||
| 59 | // 更新 | 62 | // 更新 |
| 60 | MesWmReturnSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesDetailDO.class); | 63 | MesWmReturnSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesDetailDO.class); |
| @@ -95,4 +98,41 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail | @@ -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,10 +45,7 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ | ||
| 45 | 45 | ||
| 46 | @Override | 46 | @Override |
| 47 | public Long createReturnSalesLine(MesWmReturnSalesLineSaveReqVO createReqVO) { | 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 | MesWmReturnSalesLineDO line = BeanUtils.toBean(createReqVO, MesWmReturnSalesLineDO.class); | 51 | MesWmReturnSalesLineDO line = BeanUtils.toBean(createReqVO, MesWmReturnSalesLineDO.class); |
| @@ -62,10 +59,7 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ | @@ -62,10 +59,7 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ | ||
| 62 | public void updateReturnSalesLine(MesWmReturnSalesLineSaveReqVO updateReqVO) { | 59 | public void updateReturnSalesLine(MesWmReturnSalesLineSaveReqVO updateReqVO) { |
| 63 | // 校验存在 | 60 | // 校验存在 |
| 64 | validateReturnSalesLineExists(updateReqVO.getId()); | 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 | MesWmReturnSalesLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesLineDO.class); | 65 | MesWmReturnSalesLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesLineDO.class); |
| @@ -74,6 +68,16 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ | @@ -74,6 +68,16 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ | ||
| 74 | returnSalesLineMapper.updateById(updateObj); | 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 | @Override | 81 | @Override |
| 78 | public void deleteReturnSalesLine(Long id) { | 82 | public void deleteReturnSalesLine(Long id) { |
| 79 | // 校验存在 | 83 | // 校验存在 |