From 06c312e584b99df613728d5ea8b32df4e156f3cc Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期一, 07 九月 2026 17:40:09 +0800
Subject: [PATCH] feat(mes): 采购退货关联采购订单后自动带入物料并锁定选料

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java |  143 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 136 insertions(+), 7 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
index 34ca27b..18296c8 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
@@ -2,12 +2,14 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorSaveReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.line.MesWmReturnVendorLineSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDetailDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorLineDO;
@@ -15,7 +17,10 @@
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnVendorStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
-import cn.iocoder.yudao.module.erp.api.purchase.ErpSupplierApi;
+import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi;
+import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO;
+import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO;
+import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
 import jakarta.annotation.Resource;
@@ -24,7 +29,9 @@
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -45,32 +52,71 @@
     @Resource
     private MesWmReturnVendorDetailService returnVendorDetailService;
     @Resource
-    private ErpSupplierApi supplierApi;
+    private SrmSupplierApi srmSupplierApi;
     @Resource
     private MesWmTransactionService wmTransactionService;
+    @Resource
+    private ErpPurchaseOrderApi purchaseOrderApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createReturnVendor(MesWmReturnVendorSaveReqVO createReqVO) {
         // 1. 鏍¢獙鏁版嵁
         validateReturnVendorSaveData(createReqVO);
+        // 1.1. 鑻ラ噰璐鍗曞彿涓虹┖浣嗗叧鑱斾簡閲囪喘璁㈠崟锛屽垯浠� ERP 閲囪喘璁㈠崟琛ラ綈璁㈠崟鍙�
+        fillPurchaseOrderCode(createReqVO);
 
         // 2. 鎻掑叆涓昏〃
         MesWmReturnVendorDO returnVendor = BeanUtils.toBean(createReqVO, MesWmReturnVendorDO.class);
         returnVendor.setStatus(MesWmReturnVendorStatusEnum.PREPARE.getStatus());
         returnVendorMapper.insert(returnVendor);
+
+        // 2.1. 鍏宠仈浜嗛噰璐鍗曪細鑷姩鎶婅鍗曠墿鏂欏甫鍏ラ��璐ц锛堟棤鍙��鐗╂枡鏃堕潤榛橈紝涓嶅奖鍝嶅崟鎹垱寤猴級
+        if (returnVendor.getPurchaseOrderId() != null) {
+            autoImportLinesFromLinkedOrder(returnVendor.getId(), false);
+        }
         return returnVendor.getId();
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateReturnVendor(MesWmReturnVendorSaveReqVO updateReqVO) {
-        // 1. 鏍¢獙鏁版嵁
-        validateReturnVendorSaveData(updateReqVO);
+        // 1. 鏍¢獙鏁版嵁锛堝惈瀛樺湪 + 鑽夌鐘舵�侊級
+        MesWmReturnVendorDO oldReturnVendor = validateReturnVendorSaveData(updateReqVO);
+        // 1.1. 鑻ラ噰璐鍗曞彿涓虹┖浣嗗叧鑱斾簡閲囪喘璁㈠崟锛屽垯浠� ERP 閲囪喘璁㈠崟琛ラ綈璁㈠崟鍙�
+        fillPurchaseOrderCode(updateReqVO);
+
+        Long oldPurchaseOrderId = oldReturnVendor != null ? oldReturnVendor.getPurchaseOrderId() : null;
+        Long newPurchaseOrderId = updateReqVO.getPurchaseOrderId();
+        boolean purchaseOrderChanged = !ObjUtil.equal(oldPurchaseOrderId, newPurchaseOrderId);
 
         // 2. 鏇存柊涓昏〃
         MesWmReturnVendorDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnVendorDO.class);
         returnVendorMapper.updateById(updateObj);
+
+        // 3. 鍏宠仈浜嗛噰璐鍗曪細鑷姩鍚屾鐗╂枡琛岋紝淇濊瘉琛岀墿鏂欎笌璇ラ噰璐鍗曚竴鑷�
+        //    3.1 鏇存崲浜嗛噰璐鍗� 鈫� 鍏堟竻绌烘棫璁㈠崟甯﹀叆鐨勮锛屽啀鎸夋柊璁㈠崟閲嶆柊甯﹀叆
+        //    3.2 閲囪喘璁㈠崟鏈彉浣嗗綋鍓嶆棤琛� 鈫� 鍏滃簳鑷姩甯﹀叆锛堝巻鍙叉暟鎹垨甯︽枡琚腑鏂殑鍦烘櫙锛�
+        if (newPurchaseOrderId != null) {
+            autoImportLinesFromLinkedOrder(updateReqVO.getId(), purchaseOrderChanged);
+        }
+    }
+
+    /**
+     * 褰撻噰璐鍗曞彿涓虹┖銆佷絾鍏宠仈浜嗛噰璐鍗曟椂锛屼粠 ERP 閲囪喘璁㈠崟琛ラ綈閲囪喘璁㈠崟鍙�
+     */
+    private void fillPurchaseOrderCode(MesWmReturnVendorSaveReqVO reqVO) {
+        if (reqVO == null || reqVO.getPurchaseOrderId() == null) {
+            return;
+        }
+        if (cn.hutool.core.util.StrUtil.isNotBlank(reqVO.getPurchaseOrderCode())) {
+            return;
+        }
+        ErpPurchaseOrderRespDTO purchaseOrder =
+                purchaseOrderApi.getPurchaseOrder(reqVO.getPurchaseOrderId()).getCheckedData();
+        if (purchaseOrder != null) {
+            reqVO.setPurchaseOrderCode(purchaseOrder.getNo());
+        }
     }
 
     @Override
@@ -210,16 +256,50 @@
 
     /**
      * 鏍¢獙閫�璐у崟鍒涘缓/淇敼鐨勫叕鍏辨暟鎹�
+     *
+     * @return 淇敼鏃惰繑鍥炴棫鍗曟嵁锛堢敤浜庢瘮杈冮噰璐鍗曟槸鍚﹀彉鏇达級锛涘垱寤烘椂杩斿洖 null
      */
-    private void validateReturnVendorSaveData(MesWmReturnVendorSaveReqVO reqVO) {
+    private MesWmReturnVendorDO validateReturnVendorSaveData(MesWmReturnVendorSaveReqVO reqVO) {
         // 鏍¢獙瀛樺湪 + 鑽夌鐘舵�侊紙浠呬慨鏀规椂锛�
+        MesWmReturnVendorDO oldReturnVendor = null;
         if (reqVO.getId() != null) {
-            validateReturnVendorExistsAndPrepare(reqVO.getId());
+            oldReturnVendor = validateReturnVendorExistsAndPrepare(reqVO.getId());
         }
         // 鏍¢獙渚涘簲鍟嗗瓨鍦�
-        supplierApi.validateSupplier(reqVO.getVendorId());
+        srmSupplierApi.getSupplier(reqVO.getVendorId());
         // 鏍¢獙缂栫爜鍞竴
         validateCodeUnique(reqVO.getId(), reqVO.getCode());
+        return oldReturnVendor;
+    }
+
+    /**
+     * 鎶婂叧鑱旈噰璐鍗曠殑鐗╂枡鑷姩甯﹀叆閫�璐у崟琛岋紙浠呰崏绋跨姸鎬佷笖宸插叧鑱旈噰璐鍗曟椂鐢熸晥锛夈��
+     *
+     * @param id         閫�璐у崟缂栧彿
+     * @param clearFirst 鏄惁鍏堟竻绌哄凡鏈夎鍐嶅甫鍏ワ紱鏇存崲閲囪喘璁㈠崟鏃朵紶 true
+     */
+    private void autoImportLinesFromLinkedOrder(Long id, boolean clearFirst) {
+        MesWmReturnVendorDO returnVendor = returnVendorMapper.selectById(id);
+        if (returnVendor == null || returnVendor.getPurchaseOrderId() == null) {
+            return;
+        }
+        List<MesWmReturnVendorLineDO> existingLines =
+                returnVendorLineService.getReturnVendorLineListByReturnId(id);
+        if (clearFirst) {
+            if (CollUtil.isNotEmpty(existingLines)) {
+                // 绾ц仈鍒犻櫎鏃ф槑缁嗕笌琛�
+                returnVendorDetailService.deleteReturnVendorDetailByReturnId(id);
+                returnVendorLineService.deleteReturnVendorLineByReturnId(id);
+            }
+        } else if (CollUtil.isNotEmpty(existingLines)) {
+            // 宸叉湁琛屼笖鏈洿鎹㈤噰璐鍗曪細涓嶉噸澶嶅甫鍏ワ紝閬垮厤瑕嗙洊鐢ㄦ埛宸茶皟鏁寸殑鏁伴噺
+            return;
+        }
+        try {
+            importPurchaseOrderItems(id);
+        } catch (ServiceException ignore) {
+            // 閲囪喘璁㈠崟鏃犳槑缁� / 鏃犲彲閫�鐗╂枡绛変笟鍔″紓甯革細鍗曟嵁涓讳綋浠嶆甯镐繚瀛橈紝鍙湪鐗╂枡鍖哄彟琛屽鐞�
+        }
     }
 
     /**
@@ -240,4 +320,53 @@
         return returnVendorMapper.selectCountByVendorId(vendorId);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int importPurchaseOrderItems(Long id) {
+        // 1. 鏍¢獙閫�璐у崟瀛樺湪涓斾负鑽夌鐘舵��
+        MesWmReturnVendorDO returnVendor = validateReturnVendorExistsAndPrepare(id);
+        if (returnVendor.getPurchaseOrderId() == null) {
+            throw exception(WM_RETURN_VENDOR_PURCHASE_ORDER_REQUIRED);
+        }
+
+        // 2. 鑾峰彇閲囪喘璁㈠崟鍙婃槑缁�
+        ErpPurchaseOrderRespDTO purchaseOrder = purchaseOrderApi.getPurchaseOrder(returnVendor.getPurchaseOrderId()).getCheckedData();
+        if (purchaseOrder == null) {
+            throw exception(WM_PURCHASE_ORDER_NOT_EXISTS);
+        }
+        List<ErpPurchaseOrderItemRespDTO> items = purchaseOrderApi.getPurchaseOrderItemList(returnVendor.getPurchaseOrderId()).getCheckedData();
+        if (CollUtil.isEmpty(items)) {
+            throw exception(WM_RETURN_VENDOR_PURCHASE_ORDER_NO_ITEM);
+        }
+
+        // 3. 宸插瓨鍦ㄧ殑琛岀墿鏂欓泦鍚堬紙鎸夌墿鏂欏幓閲嶏紝閬垮厤閲嶅甯﹀叆锛�
+        Set<Long> existsItemIds = new HashSet<>();
+        List<MesWmReturnVendorLineDO> existingLines = returnVendorLineService.getReturnVendorLineListByReturnId(id);
+        if (CollUtil.isNotEmpty(existingLines)) {
+            existsItemIds.addAll(convertList(existingLines, MesWmReturnVendorLineDO::getItemId));
+        }
+
+        // 4. 閬嶅巻閲囪喘璁㈠崟鏄庣粏锛岀敓鎴愰��璐ц锛堝彲閫�鏁伴噺 = 宸插叆搴� - 宸查��璐э級
+        int importedCount = 0;
+        for (ErpPurchaseOrderItemRespDTO item : items) {
+            if (item.getProductId() == null || existsItemIds.contains(item.getProductId())) {
+                continue;
+            }
+            BigDecimal inCount = item.getInCount() != null ? item.getInCount() : BigDecimal.ZERO;
+            BigDecimal returnCount = item.getReturnCount() != null ? item.getReturnCount() : BigDecimal.ZERO;
+            BigDecimal quantity = inCount.subtract(returnCount);
+            if (quantity.compareTo(BigDecimal.ZERO) <= 0) {
+                continue;
+            }
+            MesWmReturnVendorLineSaveReqVO lineReqVO = new MesWmReturnVendorLineSaveReqVO();
+            lineReqVO.setReturnId(id);
+            lineReqVO.setItemId(item.getProductId());
+            lineReqVO.setQuantity(quantity);
+            lineReqVO.setRemark(item.getRemark());
+            returnVendorLineService.createReturnVendorLine(lineReqVO);
+            importedCount++;
+        }
+        return importedCount;
+    }
+
 }

--
Gitblit v1.9.3