Commit 1c16ad0158d2a391e7f32ca3852db57a4df37fdf

Authored by YunaiV
1 parent 9221527d

✨ feat(mes): 新增根据行ID删除退货明细功能

实现了根据行ID删除退货明细的功能,确保在删除行时能够级联删除相关的明细数据。同时,增加了对退货单状态的校验,确保只有在待上架状态下才能进行删除操作。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesDetailMapper.java
... ... @@ -40,4 +40,9 @@ public interface MesWmReturnSalesDetailMapper extends BaseMapperX<MesWmReturnSal
40 40 .eq(MesWmReturnSalesDetailDO::getReturnId, returnId));
41 41 }
42 42  
  43 + default void deleteByLineId(Long lineId) {
  44 + delete(new LambdaQueryWrapperX<MesWmReturnSalesDetailDO>()
  45 + .eq(MesWmReturnSalesDetailDO::getLineId, lineId));
  46 + }
  47 +
43 48 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesMapper.java
... ... @@ -26,4 +26,9 @@ public interface MesWmReturnSalesMapper extends BaseMapperX&lt;MesWmReturnSalesDO&gt;
26 26 .orderByDesc(MesWmReturnSalesDO::getId));
27 27 }
28 28  
  29 + default MesWmReturnSalesDO selectByCode(String code) {
  30 + return selectOne(new LambdaQueryWrapperX<MesWmReturnSalesDO>()
  31 + .eq(MesWmReturnSalesDO::getCode, code));
  32 + }
  33 +
29 34 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailService.java
... ... @@ -66,4 +66,11 @@ public interface MesWmReturnSalesDetailService {
66 66 */
67 67 void deleteReturnSalesDetailByReturnId(Long returnId);
68 68  
  69 + /**
  70 + * 根据行ID删除明细(行删除时级联)
  71 + *
  72 + * @param lineId 行ID
  73 + */
  74 + void deleteReturnSalesDetailByLineId(Long lineId);
  75 +
69 76 }
... ...
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.hutool.core.util.ObjUtil;
3 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 6 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO;
6 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO;
7 9 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO;
8 10 import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesDetailMapper;
  11 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum;
9 12 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
10 13 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
11 14 import jakarta.annotation.Resource;
... ... @@ -17,8 +20,7 @@ import java.math.BigDecimal;
17 20 import java.util.List;
18 21  
19 22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
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;
  23 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
22 24  
23 25 /**
24 26 * MES 销售退货明细 Service 实现类
... ... @@ -35,6 +37,9 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
35 37 @Resource
36 38 @Lazy
37 39 private MesWmReturnSalesLineService returnSalesLineService;
  40 + @Resource
  41 + @Lazy
  42 + private MesWmReturnSalesService returnSalesService;
38 43  
39 44 @Resource
40 45 private MesWmWarehouseAreaService warehouseAreaService;
... ... @@ -67,7 +72,10 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
67 72 @Override
68 73 public void deleteReturnSalesDetail(Long id) {
69 74 // 校验存在
70   - validateReturnSalesDetailExists(id);
  75 + MesWmReturnSalesDetailDO detail = validateReturnSalesDetailExists(id);
  76 + // 校验退货单为待上架状态才允许删除明细
  77 + validateReturnSalesStatusApproved(detail.getReturnId());
  78 +
71 79 // 删除
72 80 returnSalesDetailMapper.deleteById(id);
73 81 }
... ... @@ -92,10 +100,27 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
92 100 returnSalesDetailMapper.deleteByReturnId(returnId);
93 101 }
94 102  
95   - private void validateReturnSalesDetailExists(Long id) {
96   - if (returnSalesDetailMapper.selectById(id) == null) {
  103 + @Override
  104 + public void deleteReturnSalesDetailByLineId(Long lineId) {
  105 + returnSalesDetailMapper.deleteByLineId(lineId);
  106 + }
  107 +
  108 + private MesWmReturnSalesDetailDO validateReturnSalesDetailExists(Long id) {
  109 + MesWmReturnSalesDetailDO detail = returnSalesDetailMapper.selectById(id);
  110 + if (detail == null) {
97 111 throw exception(WM_RETURN_SALES_DETAIL_NOT_EXISTS);
98 112 }
  113 + return detail;
  114 + }
  115 +
  116 + /**
  117 + * 校验退货单为待上架状态(明细操作仅允许在待上架状态)
  118 + */
  119 + private void validateReturnSalesStatusApproved(Long returnId) {
  120 + MesWmReturnSalesDO returnSales = returnSalesService.validateReturnSalesExists(returnId);
  121 + if (ObjUtil.notEqual(MesWmReturnSalesStatusEnum.APPROVED.getStatus(), returnSales.getStatus())) {
  122 + throw exception(WM_RETURN_SALES_STATUS_NOT_APPROVED);
  123 + }
99 124 }
100 125  
101 126 /**
... ... @@ -104,6 +129,8 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail
104 129 private void validateReturnSalesDetailSaveData(MesWmReturnSalesDetailSaveReqVO reqVO) {
105 130 // 校验父数据存在
106 131 MesWmReturnSalesLineDO line = returnSalesLineService.validateReturnSalesLineExists(reqVO.getLineId());
  132 + // 校验退货单为待上架状态
  133 + validateReturnSalesStatusApproved(line.getReturnId());
107 134 // 校验仓库、库区、库位的关联关系
108 135 warehouseAreaService.validateWarehouseAreaExists(
109 136 reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java
... ... @@ -42,6 +42,9 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ
42 42 private MesWmReturnSalesService returnSalesService;
43 43 @Resource
44 44 private MesMdItemService itemService;
  45 + @Resource
  46 + @Lazy
  47 + private MesWmReturnSalesDetailService returnSalesDetailService;
45 48  
46 49 @Override
47 50 public Long createReturnSalesLine(MesWmReturnSalesLineSaveReqVO createReqVO) {
... ... @@ -72,8 +75,8 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ
72 75 * 校验保存时的关联数据
73 76 */
74 77 private void validateLineSaveData(MesWmReturnSalesLineSaveReqVO reqVO) {
75   - // 校验退货单存在
76   - returnSalesService.validateReturnSalesExists(reqVO.getReturnId());
  78 + // 校验退货单存在 + 草稿状态
  79 + returnSalesService.validateReturnSalesExistsAndPrepare(reqVO.getReturnId());
77 80 // 校验物料存在 + 批次管理
78 81 validateItemBatchManagement(reqVO.getItemId(), reqVO.getBatchId());
79 82 }
... ... @@ -81,8 +84,12 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ
81 84 @Override
82 85 public void deleteReturnSalesLine(Long id) {
83 86 // 校验存在
84   - validateReturnSalesLineExists(id);
85   - // 删除
  87 + MesWmReturnSalesLineDO line = validateReturnSalesLineExists(id);
  88 + // 校验主单为草稿状态才允许删除行
  89 + returnSalesService.validateReturnSalesExistsAndPrepare(line.getReturnId());
  90 + // 级联删除该行的明细
  91 + returnSalesDetailService.deleteReturnSalesDetailByLineId(id);
  92 + // 删除行
86 93 returnSalesLineMapper.deleteById(id);
87 94 }
88 95  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java
... ... @@ -60,6 +60,14 @@ public interface MesWmReturnSalesService {
60 60 MesWmReturnSalesDO validateReturnSalesExists(Long id);
61 61  
62 62 /**
  63 + * 校验销售退货单存在且为草稿状态
  64 + *
  65 + * @param id 编号
  66 + * @return 销售退货单
  67 + */
  68 + MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id);
  69 +
  70 + /**
63 71 * 提交销售退货单(草稿 -> 待执行)
64 72 *
65 73 * @param id 编号
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java
... ... @@ -61,7 +61,7 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
61 61 @Transactional(rollbackFor = Exception.class)
62 62 public Long createReturnSales(MesWmReturnSalesSaveReqVO createReqVO) {
63 63 // 1. 校验关联数据
64   - clientService.validateClientExists(createReqVO.getClientId());
  64 + validateSaveData(createReqVO);
65 65  
66 66 // 2. 插入主表
67 67 MesWmReturnSalesDO returnSales = BeanUtils.toBean(createReqVO, MesWmReturnSalesDO.class);
... ... @@ -76,7 +76,7 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
76 76 // 1.1 校验存在 + 准备中状态
77 77 validateReturnSalesExistsAndPrepare(updateReqVO.getId());
78 78 // 1.2 校验关联数据
79   - clientService.validateClientExists(updateReqVO.getClientId());
  79 + validateSaveData(updateReqVO);
80 80  
81 81 // 2. 更新主表
82 82 MesWmReturnSalesDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesDO.class);
... ... @@ -131,12 +131,17 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
131 131 @Override
132 132 @Transactional(rollbackFor = Exception.class)
133 133 public void finishReturnSales(Long id) {
134   - // 校验存在
  134 + // 1.1 校验存在 + 待执行状态
135 135 MesWmReturnSalesDO returnSales = validateReturnSalesExists(id);
136 136 if (ObjUtil.notEqual(MesWmReturnSalesStatusEnum.APPROVING.getStatus(), returnSales.getStatus())) {
137 137 throw exception(WM_RETURN_SALES_STATUS_NOT_APPROVING);
138 138 }
139   - // 执行退货(待执行 -> 待上架)
  139 + // 1.2 校验至少有一条行
  140 + List<MesWmReturnSalesLineDO> lines = returnSalesLineService.getReturnSalesLineListByReturnId(id);
  141 + if (CollUtil.isEmpty(lines)) {
  142 + throw exception(WM_RETURN_SALES_NO_LINE);
  143 + }
  144 + // 2. 执行退货(待执行 -> 待上架)
140 145 returnSalesMapper.updateById(new MesWmReturnSalesDO()
141 146 .setId(id).setStatus(MesWmReturnSalesStatusEnum.APPROVED.getStatus()));
142 147 }
... ... @@ -232,7 +237,8 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
232 237 /**
233 238 * 校验销售退货单存在且为准备中状态
234 239 */
235   - private MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id) {
  240 + @Override
  241 + public MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id) {
236 242 MesWmReturnSalesDO returnSales = validateReturnSalesExists(id);
237 243 if (ObjUtil.notEqual(MesWmReturnSalesStatusEnum.PREPARE.getStatus(), returnSales.getStatus())) {
238 244 throw exception(WM_RETURN_SALES_STATUS_NOT_PREPARE);
... ... @@ -246,4 +252,25 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService {
246 252 returnSalesMapper.updateById(new MesWmReturnSalesDO().setId(id).setStatus(status));
247 253 }
248 254  
  255 + /**
  256 + * 校验编码唯一性
  257 + */
  258 + private void validateCodeUnique(Long id, String code) {
  259 + MesWmReturnSalesDO returnSales = returnSalesMapper.selectByCode(code);
  260 + if (returnSales == null) {
  261 + return;
  262 + }
  263 + if (ObjUtil.notEqual(id, returnSales.getId())) {
  264 + throw exception(WM_RETURN_SALES_CODE_DUPLICATE);
  265 + }
  266 + }
  267 +
  268 + /**
  269 + * 校验保存时的关联数据
  270 + */
  271 + private void validateSaveData(MesWmReturnSalesSaveReqVO reqVO) {
  272 + validateCodeUnique(reqVO.getId(), reqVO.getCode());
  273 + clientService.validateClientExists(reqVO.getClientId());
  274 + }
  275 +
249 276 }
... ...