From a0b4de611e3b1986b2713c6a161cc1613ec31a5b Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 10 十一月 2026 11:42:13 +0800
Subject: [PATCH] feat(mes): 采购入库简化为确认入库并自动生成入库单

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java |  138 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 107 insertions(+), 31 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
index c5ac05f..a8b6e3c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
@@ -2,6 +2,7 @@
 
 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;
@@ -22,6 +23,7 @@
 import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum;
+import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Lazy;
@@ -30,6 +32,7 @@
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -73,6 +76,10 @@
     @Resource
     @Lazy
     private MesQcIqcService iqcService;
+
+    @Resource
+    @Lazy
+    private MesWmItemReceiptService itemReceiptService;
 
     @Override
     public Long createArrivalNotice(MesWmArrivalNoticeSaveReqVO createReqVO) {
@@ -161,34 +168,72 @@
         }
 
         // 2. 妫�鏌ユ墍鏈夎鐨� iqcCheckFlag锛氬鏋滄湁闇�瑕佹楠岀殑琛岋紝杩涘叆寰呰川妫�鐘舵��
+        // 娉ㄦ剰锛氭潵鏂欐楠屽崟涓嶅湪鎻愪氦鏃剁敓鎴愶紝鐢卞簱绠$偣鍑汇�屾墽琛岃川妫�銆嶆椂閫氳繃 createIqcForArrivalNotice 鐢熸垚
         boolean needCheck = CollectionUtils.anyMatch(lines,
                 line -> Boolean.TRUE.equals(line.getIqcCheckFlag()));
         if (needCheck) {
-            // 2.1 闇�瑕佹楠岋紝杩涘叆寰呰川妫�
             arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
                     .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus()));
-            // 2.2 涓洪渶瑕佽川妫�鐨勮鑷姩鍒涘缓 IQC 妫�楠屽崟
-            for (MesWmArrivalNoticeLineDO line : lines) {
-                if (Boolean.TRUE.equals(line.getIqcCheckFlag()) && line.getIqcId() == null) {
-                    try {
-                        Long iqcId = iqcService.createIqcFromArrivalNotice(
-                                id, line, notice.getCode(), notice.getVendorId());
-                        // 鏇存柊琛屼笂鐨� iqcId
-                        arrivalNoticeLineService.updateArrivalNoticeLineIqcId(line.getId(), iqcId);
-                        log.info("[submitArrivalNotice][鍒拌揣閫氱煡鍗�({}) 琛�({}) 鑷姩鍒涘缓 IQC 妫�楠屽崟({})]",
-                                id, line.getId(), iqcId);
-                    } catch (Exception e) {
-                        log.warn("[submitArrivalNotice][鍒拌揣閫氱煡鍗�({}) 琛�({}) 鍒涘缓 IQC 澶辫触: {}]",
-                                id, line.getId(), e.getMessage());
-                        // 缁х画澶勭悊鍏朵粬琛岋紝涓嶄腑鏂祦绋�
-                    }
-                }
-            }
             return;
         }
-        // 涓嶉渶瑕佹楠岋紝鐩存帴杩涘叆寰呭叆搴�
+        // 涓嶉渶瑕佹楠岋紝鐩存帴杩涘叆寰呭叆搴擄紝骞惰嚜鍔ㄧ敓鎴愰噰璐叆搴撳崟浜ょ粰搴撶纭鍏ュ簱
         arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
                 .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus()));
+        autoGenerateItemReceipt(notice);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Integer createIqcForArrivalNotice(Long id) {
+        // 1. 鏍¢獙鍒拌揣閫氱煡鍗曞瓨鍦ㄤ笖涓哄緟璐ㄦ鐘舵��
+        MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);
+        if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus(), notice.getStatus())) {
+            String statusName = Arrays.stream(MesWmArrivalNoticeStatusEnum.values())
+                    .filter(item -> ObjUtil.equal(item.getStatus(), notice.getStatus()))
+                    .map(MesWmArrivalNoticeStatusEnum::getName).findFirst()
+                    .orElse(String.valueOf(notice.getStatus()));
+            throw new ServiceException(WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_QC.getCode(),
+                    "鍒拌揣閫氱煡鍗昜" + notice.getCode() + "]褰撳墠鐘舵�佷负[" + statusName + "]锛屽彧鏈夈�屽緟璐ㄦ銆嶇姸鎬佹墠鑳芥墽琛岃川妫�銆�"
+                            + "璇峰埛鏂板垪琛ㄧ‘璁ゅ崟鎹姸鎬侊紱鑻ヨ鍗曟嵁宸叉墽琛岃繃璐ㄦ锛岃鐩存帴鍒般�愯川閲忕鐞� - IQC妫�楠屻�戝綍鍏ユ娴嬬粨鏋溿��");
+        }
+        // 2. 鏍¢獙闇�妫�琛�
+        List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(id);
+        List<MesWmArrivalNoticeLineDO> needCheckLines = lines.stream()
+                .filter(line -> Boolean.TRUE.equals(line.getIqcCheckFlag()))
+                .toList();
+        if (needCheckLines.isEmpty()) {
+            throw new ServiceException(WM_ARRIVAL_NOTICE_NO_IQC_LINE.getCode(),
+                    "鍒拌揣閫氱煡鍗昜" + notice.getCode() + "]鐨勬槑缁嗚鍧囦负銆屼笉闇�妫�楠屻�嶏紝鏃犻渶鐢熸垚鏉ユ枡妫�楠屽崟銆�"
+                            + "璇风洿鎺ュ埌璇ュ崟鎹墽琛屽叆搴擄紱鑻ユ湰搴旀楠岋紝璇锋牳瀵归噰璐鍗曡鐨勬楠屾爣璇嗭紙璇ユ爣璇嗙敱閲囪喘璁㈠崟甯﹀叆锛屽埌璐ч�氱煡鍗曚笂涓嶅彲淇敼锛夈��");
+        }
+        List<MesWmArrivalNoticeLineDO> pendingLines = needCheckLines.stream()
+                .filter(line -> line.getIqcId() == null)
+                .toList();
+        if (pendingLines.isEmpty()) {
+            throw new ServiceException(WM_ARRIVAL_NOTICE_IQC_ALREADY_CREATED.getCode(),
+                    "鍒拌揣閫氱煡鍗昜" + notice.getCode() + "]鐨� " + needCheckLines.size()
+                            + " 鏉¢渶妫�琛屽潎宸茬敓鎴愭潵鏂欐楠屽崟锛屾棤闇�閲嶅鐢熸垚銆傝鐩存帴鍒般�愯川閲忕鐞� - IQC妫�楠屻�戝綍鍏ユ娴嬬粨鏋滐紱"
+                            + "濡傞渶閲嶆柊鐢熸垚锛岃鍏堝垹闄ゅ師妫�楠屽崟銆�");
+        }
+        // 3. 閫愯鐢熸垚鏉ユ枡妫�楠屽崟
+        int createdCount = 0;
+        for (MesWmArrivalNoticeLineDO line : pendingLines) {
+            Long iqcId;
+            try {
+                iqcId = iqcService.createIqcFromArrivalNotice(id, line, notice.getCode(), notice.getVendorId());
+            } catch (Exception ex) {
+                log.error("[createIqcForArrivalNotice][鍒拌揣閫氱煡鍗�({}) 琛�({}) 鍒涘缓 IQC 澶辫触]", id, line.getId(), ex);
+                throw new ServiceException(WM_ARRIVAL_NOTICE_IQC_CREATE_FAILED.getCode(),
+                        "鍒拌揣閫氱煡鍗昜" + notice.getCode() + "]鐨勬槑缁嗚锛堢墿鏂橧D=" + line.getItemId()
+                                + "锛夌敓鎴愭潵鏂欐楠屽崟澶辫触锛�" + ex.getMessage()
+                                + "銆傝绋嶅悗閲嶈瘯锛涜嫢鎸佺画澶辫触锛岃鍒般�愯川閲忕鐞� - IQC妫�楠屻�戞墜宸ユ柊寤烘楠屽崟銆�");
+            }
+            arrivalNoticeLineService.updateArrivalNoticeLineIqcId(line.getId(), iqcId);
+            createdCount++;
+            log.info("[createIqcForArrivalNotice][鍒拌揣閫氱煡鍗�({}) 琛�({}) 鐢熸垚 IQC 妫�楠屽崟({})]",
+                    id, line.getId(), iqcId);
+        }
+        return createdCount;
     }
 
     @Override
@@ -206,6 +251,47 @@
 
         // 鍚屾椂璁ゅ彲浠撳簱宸茬‘璁ょ殑鏉ユ枡閫�璐э紱淇濈暀鍘熷涓嶅悎鏍肩粨璁恒��
         arrivalDispositionService.refresh(id);
+        // 3.1 鍒ゆ柇鏄惁鎵�鏈夐渶妫�琛岄兘宸插畬鎴愯川妫�
+        List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(id);
+        boolean hasUnchecked = CollectionUtils.anyMatch(lines,
+                line -> Boolean.TRUE.equals(line.getIqcCheckFlag()) && line.getIqcCheckResult() == null);
+        if (hasUnchecked) {
+            log.info("[updateArrivalNoticeWhenIqcFinish][鍒拌揣閫氱煡鍗�({}) 杩樻湁鏈畬鎴愭楠岀殑琛岋紝鏆備笉鏇存柊鐘舵�乚", id);
+            return;
+        }
+
+        // 3.2 鍒ゆ柇鏄惁鎵�鏈夐渶妫�琛岄兘鍙互鍏ュ簱锛堝悎鏍兼垨鐗归噰锛�
+        boolean hasNonInbound = CollectionUtils.anyMatch(lines,
+                line -> Boolean.TRUE.equals(line.getIqcCheckFlag())
+                        && !MesQcCheckResultEnum.canInbound(line.getIqcCheckResult()));
+        if (hasNonInbound) {
+            log.info("[updateArrivalNoticeWhenIqcFinish][鍒拌揣閫氱煡鍗�({}) 瀛樺湪涓嶅彲鍏ュ簱鐨勮锛堥��璐�/鎶ュ簾锛夛紝鐘舵�佷繚鎸佸緟璐ㄦ]", id);
+            return;
+        }
+
+        // 3.3 鎵�鏈夎妫�楠屽畬鎴愪笖鍙叆搴擄紝鏇存柊涓昏〃鐘舵�� PENDING_QC 鈫� PENDING_RECEIPT
+        arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
+                .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus()));
+        // 3.4 璐ㄦ鍚堟牸鍚庣洿鎺ョ敓鎴愰噰璐叆搴撳崟锛堝緟鍏ュ簱锛夛紝搴撶鍙渶鏍稿鏁伴噺骞剁‘璁ゅ叆搴�
+        autoGenerateItemReceipt(notice);
+    }
+
+    /**
+     * 鍒拌揣閫氱煡鍗曡繘鍏ャ�屽緟鍏ュ簱銆嶅悗鑷姩鐢熸垚閲囪喘鍏ュ簱鍗曘��
+     * 搴撶鏃犻渶鍐嶅洖鍒板埌璐ч�氱煡鐐广�屾墽琛屽叆搴撱�嶏紝鐩存帴鍒般�愰噰璐叆搴撱�戞牳瀵规暟閲忓苟纭鍏ュ簱鍗冲彲銆�
+     */
+    private void autoGenerateItemReceipt(MesWmArrivalNoticeDO notice) {
+        try {
+            Long receiptId = itemReceiptService.generateItemReceiptFromArrivalNotice(notice.getId());
+            log.info("[autoGenerateItemReceipt][鍒拌揣閫氱煡鍗�({}) 宸茶嚜鍔ㄧ敓鎴愰噰璐叆搴撳崟({})]",
+                    notice.getId(), receiptId);
+        } catch (ServiceException ex) {
+            log.error("[autoGenerateItemReceipt][鍒拌揣閫氱煡鍗�({}) 鑷姩鐢熸垚閲囪喘鍏ュ簱鍗曞け璐",
+                    notice.getId(), ex);
+            throw new ServiceException(ex.getCode(),
+                    "鍒拌揣閫氱煡鍗昜" + notice.getCode() + "]杞叆寰呭叆搴撳悗鑷姩鐢熸垚閲囪喘鍏ュ簱鍗曞け璐ワ細" + ex.getMessage()
+                            + "銆傛湰娆℃搷浣滄湭鐢熸晥锛岃绋嶅悗閲嶈瘯锛涜嫢鎸佺画澶辫触璇疯仈绯荤鐞嗗憳銆�");
+        }
     }
 
     @Override
@@ -362,21 +448,11 @@
             arrivalNoticeLineService.createArrivalNoticeLineFromPurchaseOrderItem(line);
         }
 
-        // 7. 濡傛灉鏈夐渶瑕佽川妫�鐨勮锛屾洿鏂扮姸鎬佷负寰呰川妫�骞惰嚜鍔ㄥ垱寤� IQC 鍗�
+        // 7. 濡傛灉鏈夐渶瑕佽川妫�鐨勮锛屾洿鏂扮姸鎬佷负寰呰川妫�
+        // 娉ㄦ剰锛氭潵鏂欐楠屽崟涓嶅湪鐢熸垚鏃跺垱寤猴紝鐢卞簱绠$偣鍑汇�屾墽琛岃川妫�銆嶆椂閫氳繃 createIqcForArrivalNotice 鐢熸垚
         if (hasNeedQc) {
             arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
                     .setId(notice.getId()).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus()));
-            // 涓洪渶瑕佽川妫�鐨勮鑷姩鍒涘缓 IQC 妫�楠屽崟
-            List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(notice.getId());
-            for (MesWmArrivalNoticeLineDO line : lines) {
-                if (Boolean.TRUE.equals(line.getIqcCheckFlag())) {
-                    Long iqcId = iqcService.createIqcFromArrivalNotice(
-                            notice.getId(), line, notice.getCode(), notice.getVendorId());
-                    arrivalNoticeLineService.updateArrivalNoticeLineIqcId(line.getId(), iqcId);
-                    log.info("[generateArrivalNoticeFromPurchaseOrder][鍒拌揣閫氱煡鍗�({}) 琛�({}) 鑷姩鍒涘缓 IQC 妫�楠屽崟({})]",
-                            notice.getId(), line.getId(), iqcId);
-                }
-            }
         }
 
         return notice.getId();

--
Gitblit v1.9.3