From 1c16ad0158d2a391e7f32ca3852db57a4df37fdf Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 30 Mar 2026 19:32:58 +0800 Subject: [PATCH] ✨ feat(mes): 新增根据行ID删除退货明细功能 --- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesDetailMapper.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesMapper.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailService.java | 7 +++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailServiceImpl.java | 37 ++++++++++++++++++++++++++++++++----- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java | 15 +++++++++++---- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java | 37 ++++++++++++++++++++++++++++++++----- 7 files changed, 100 insertions(+), 14 deletions(-) diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesDetailMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesDetailMapper.java index 93cca0c..2fc1189 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesDetailMapper.java +++ b/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() + .eq(MesWmReturnSalesDetailDO::getLineId, lineId)); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesMapper.java index 26a3d02..8b3942b 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnsales/MesWmReturnSalesMapper.java +++ b/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 .orderByDesc(MesWmReturnSalesDO::getId)); } + default MesWmReturnSalesDO selectByCode(String code) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesWmReturnSalesDO::getCode, code)); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailService.java index dd83a5b..83d923a 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailService.java @@ -66,4 +66,11 @@ public interface MesWmReturnSalesDetailService { */ void deleteReturnSalesDetailByReturnId(Long returnId); + /** + * 根据行ID删除明细(行删除时级联) + * + * @param lineId 行ID + */ + void deleteReturnSalesDetailByLineId(Long lineId); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailServiceImpl.java index 3333dce..cce3063 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesDetailServiceImpl.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.mes.service.wm.returnsales; +import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.detail.MesWmReturnSalesDetailSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesDetailMapper; +import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum; import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; import jakarta.annotation.Resource; @@ -17,8 +20,7 @@ import java.math.BigDecimal; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_SALES_DETAIL_NOT_EXISTS; -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_SALES_DETAIL_QUANTITY_EXCEED; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; /** * MES 销售退货明细 Service 实现类 @@ -35,6 +37,9 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail @Resource @Lazy private MesWmReturnSalesLineService returnSalesLineService; + @Resource + @Lazy + private MesWmReturnSalesService returnSalesService; @Resource private MesWmWarehouseAreaService warehouseAreaService; @@ -67,7 +72,10 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail @Override public void deleteReturnSalesDetail(Long id) { // 校验存在 - validateReturnSalesDetailExists(id); + MesWmReturnSalesDetailDO detail = validateReturnSalesDetailExists(id); + // 校验退货单为待上架状态才允许删除明细 + validateReturnSalesStatusApproved(detail.getReturnId()); + // 删除 returnSalesDetailMapper.deleteById(id); } @@ -92,10 +100,27 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail returnSalesDetailMapper.deleteByReturnId(returnId); } - private void validateReturnSalesDetailExists(Long id) { - if (returnSalesDetailMapper.selectById(id) == null) { + @Override + public void deleteReturnSalesDetailByLineId(Long lineId) { + returnSalesDetailMapper.deleteByLineId(lineId); + } + + private MesWmReturnSalesDetailDO validateReturnSalesDetailExists(Long id) { + MesWmReturnSalesDetailDO detail = returnSalesDetailMapper.selectById(id); + if (detail == null) { throw exception(WM_RETURN_SALES_DETAIL_NOT_EXISTS); } + return detail; + } + + /** + * 校验退货单为待上架状态(明细操作仅允许在待上架状态) + */ + private void validateReturnSalesStatusApproved(Long returnId) { + MesWmReturnSalesDO returnSales = returnSalesService.validateReturnSalesExists(returnId); + if (ObjUtil.notEqual(MesWmReturnSalesStatusEnum.APPROVED.getStatus(), returnSales.getStatus())) { + throw exception(WM_RETURN_SALES_STATUS_NOT_APPROVED); + } } /** @@ -104,6 +129,8 @@ public class MesWmReturnSalesDetailServiceImpl implements MesWmReturnSalesDetail private void validateReturnSalesDetailSaveData(MesWmReturnSalesDetailSaveReqVO reqVO) { // 校验父数据存在 MesWmReturnSalesLineDO line = returnSalesLineService.validateReturnSalesLineExists(reqVO.getLineId()); + // 校验退货单为待上架状态 + validateReturnSalesStatusApproved(line.getReturnId()); // 校验仓库、库区、库位的关联关系 warehouseAreaService.validateWarehouseAreaExists( reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java index d56c9f3..634b168 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java +++ b/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 private MesWmReturnSalesService returnSalesService; @Resource private MesMdItemService itemService; + @Resource + @Lazy + private MesWmReturnSalesDetailService returnSalesDetailService; @Override public Long createReturnSalesLine(MesWmReturnSalesLineSaveReqVO createReqVO) { @@ -72,8 +75,8 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ * 校验保存时的关联数据 */ private void validateLineSaveData(MesWmReturnSalesLineSaveReqVO reqVO) { - // 校验退货单存在 - returnSalesService.validateReturnSalesExists(reqVO.getReturnId()); + // 校验退货单存在 + 草稿状态 + returnSalesService.validateReturnSalesExistsAndPrepare(reqVO.getReturnId()); // 校验物料存在 + 批次管理 validateItemBatchManagement(reqVO.getItemId(), reqVO.getBatchId()); } @@ -81,8 +84,12 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ @Override public void deleteReturnSalesLine(Long id) { // 校验存在 - validateReturnSalesLineExists(id); - // 删除 + MesWmReturnSalesLineDO line = validateReturnSalesLineExists(id); + // 校验主单为草稿状态才允许删除行 + returnSalesService.validateReturnSalesExistsAndPrepare(line.getReturnId()); + // 级联删除该行的明细 + returnSalesDetailService.deleteReturnSalesDetailByLineId(id); + // 删除行 returnSalesLineMapper.deleteById(id); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java index ccba7c3..1c06437 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java @@ -60,6 +60,14 @@ public interface MesWmReturnSalesService { MesWmReturnSalesDO validateReturnSalesExists(Long id); /** + * 校验销售退货单存在且为草稿状态 + * + * @param id 编号 + * @return 销售退货单 + */ + MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id); + + /** * 提交销售退货单(草稿 -> 待执行) * * @param id 编号 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java index 8df9d6c..2347dfd 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java +++ b/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 { @Transactional(rollbackFor = Exception.class) public Long createReturnSales(MesWmReturnSalesSaveReqVO createReqVO) { // 1. 校验关联数据 - clientService.validateClientExists(createReqVO.getClientId()); + validateSaveData(createReqVO); // 2. 插入主表 MesWmReturnSalesDO returnSales = BeanUtils.toBean(createReqVO, MesWmReturnSalesDO.class); @@ -76,7 +76,7 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService { // 1.1 校验存在 + 准备中状态 validateReturnSalesExistsAndPrepare(updateReqVO.getId()); // 1.2 校验关联数据 - clientService.validateClientExists(updateReqVO.getClientId()); + validateSaveData(updateReqVO); // 2. 更新主表 MesWmReturnSalesDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnSalesDO.class); @@ -131,12 +131,17 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService { @Override @Transactional(rollbackFor = Exception.class) public void finishReturnSales(Long id) { - // 校验存在 + // 1.1 校验存在 + 待执行状态 MesWmReturnSalesDO returnSales = validateReturnSalesExists(id); if (ObjUtil.notEqual(MesWmReturnSalesStatusEnum.APPROVING.getStatus(), returnSales.getStatus())) { throw exception(WM_RETURN_SALES_STATUS_NOT_APPROVING); } - // 执行退货(待执行 -> 待上架) + // 1.2 校验至少有一条行 + List lines = returnSalesLineService.getReturnSalesLineListByReturnId(id); + if (CollUtil.isEmpty(lines)) { + throw exception(WM_RETURN_SALES_NO_LINE); + } + // 2. 执行退货(待执行 -> 待上架) returnSalesMapper.updateById(new MesWmReturnSalesDO() .setId(id).setStatus(MesWmReturnSalesStatusEnum.APPROVED.getStatus())); } @@ -232,7 +237,8 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService { /** * 校验销售退货单存在且为准备中状态 */ - private MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id) { + @Override + public MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id) { MesWmReturnSalesDO returnSales = validateReturnSalesExists(id); if (ObjUtil.notEqual(MesWmReturnSalesStatusEnum.PREPARE.getStatus(), returnSales.getStatus())) { throw exception(WM_RETURN_SALES_STATUS_NOT_PREPARE); @@ -246,4 +252,25 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService { returnSalesMapper.updateById(new MesWmReturnSalesDO().setId(id).setStatus(status)); } + /** + * 校验编码唯一性 + */ + private void validateCodeUnique(Long id, String code) { + MesWmReturnSalesDO returnSales = returnSalesMapper.selectByCode(code); + if (returnSales == null) { + return; + } + if (ObjUtil.notEqual(id, returnSales.getId())) { + throw exception(WM_RETURN_SALES_CODE_DUPLICATE); + } + } + + /** + * 校验保存时的关联数据 + */ + private void validateSaveData(MesWmReturnSalesSaveReqVO reqVO) { + validateCodeUnique(reqVO.getId(), reqVO.getCode()); + clientService.validateClientExists(reqVO.getClientId()); + } + } -- libgit2 0.21.4