Преглед изворни кода

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

实现了根据行ID删除退货明细的功能,确保在删除行时能够级联删除相关的明细数据。同时,增加了对退货单状态的校验,确保只有在待上架状态下才能进行删除操作。
YunaiV пре 6 месеци
родитељ
комит
1c16ad0158

+ 5 - 0
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
                 .eq(MesWmReturnSalesDetailDO::getReturnId, returnId));
     }
 
+    default void deleteByLineId(Long lineId) {
+        delete(new LambdaQueryWrapperX<MesWmReturnSalesDetailDO>()
+                .eq(MesWmReturnSalesDetailDO::getLineId, lineId));
+    }
+
 }

+ 5 - 0
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<MesWmReturnSalesDO>
                 .orderByDesc(MesWmReturnSalesDO::getId));
     }
 
+    default MesWmReturnSalesDO selectByCode(String code) {
+        return selectOne(new LambdaQueryWrapperX<MesWmReturnSalesDO>()
+                .eq(MesWmReturnSalesDO::getCode, code));
+    }
+
 }

+ 7 - 0
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);
+
 }

+ 32 - 5
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());

+ 11 - 4
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);
     }
 

+ 8 - 0
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java

@@ -59,6 +59,14 @@ public interface MesWmReturnSalesService {
      */
     MesWmReturnSalesDO validateReturnSalesExists(Long id);
 
+    /**
+     * 校验销售退货单存在且为草稿状态
+     *
+     * @param id 编号
+     * @return 销售退货单
+     */
+    MesWmReturnSalesDO validateReturnSalesExistsAndPrepare(Long id);
+
     /**
      * 提交销售退货单(草稿 -> 待执行)
      *

+ 32 - 5
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<MesWmReturnSalesLineDO> 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());
+    }
+
 }