From 61f1de60e6f58dd8e19f01c56f2e56e40885d65b Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 23 六月 2026 17:39:58 +0800
Subject: [PATCH] 点击发货-》发货审核-》出厂质检-》出库审核-》出库通过

---
 src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java   |   38 +++++++--
 src/main/java/com/ruoyi/quality/utils/QualityInspectHelper.java               |   65 ++++++++++++++++
 src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java     |   39 +++++++++
 src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java              |   10 ++
 src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java |   42 ++++++++++
 src/main/java/com/ruoyi/quality/pojo/QualityInspect.java                      |    5 +
 src/main/resources/mapper/quality/QualityInspectMapper.xml                    |   11 ++
 7 files changed, 201 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
index c7a80df..317ecfb 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
@@ -40,12 +40,15 @@
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.quality.utils.QualityInspectHelper;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.mapper.SalesQuotationMapper;
 import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.mapper.ShippingProductDetailMapper;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.pojo.SalesQuotation;
 import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.sales.pojo.ShippingProductDetail;
 import com.ruoyi.staff.mapper.HolidayApplicationMapper;
 import com.ruoyi.staff.pojo.HolidayApplication;
 import lombok.RequiredArgsConstructor;
@@ -94,6 +97,8 @@
     private final EnterpriseNewsMapper enterpriseNewsMapper;
     private final EnterpriseNewsScopeDeptMapper enterpriseNewsScopeDeptMapper;
     private final ApprovalTemplateNodeApproverMapper approvalTemplateNodeApproverMapper;
+    private final ShippingProductDetailMapper shippingProductDetailMapper;
+    private final SalesLedgerMapper salesLedgerMapper;
 
     @Override
     public R listPage(Page<ApprovalInstanceVo> page, ApprovalInstanceDto approvalInstanceDto) {
@@ -703,6 +708,9 @@
             shippingInfo.setStatus(ShippingStatusEnum.APPROVED.getCode());
             shippingInfo.setShippingDate(new Date());
             stockUtils.shipmentStatus(StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), shippingInfo.getId());
+
+            // 鍙戣揣瀹℃壒閫氳繃鍚庯紝鑷姩鐢熸垚鍑哄巶妫�楠屽崟
+            createFactoryInspectForShipping(shippingInfo);
         } else if ("REJECTED".equals(status)) {
             stockUtils.deleteStockOutRecord(shippingInfo.getId(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
             shippingInfo.setStatus(ShippingStatusEnum.REJECTED.getCode());
@@ -712,6 +720,40 @@
         shippingInfoMapper.updateById(shippingInfo);
     }
 
+    /**
+     * 鍙戣揣瀹℃壒閫氳繃鍚庯紝鑷姩鐢熸垚鍑哄巶妫�楠屽崟
+     */
+    private void createFactoryInspectForShipping(ShippingInfo shippingInfo) {
+        // 鏌ヨ鍙戣揣浜у搧鏄庣粏
+        List<ShippingProductDetail> detailList = shippingProductDetailMapper.selectList(
+                new LambdaQueryWrapper<ShippingProductDetail>()
+                        .eq(ShippingProductDetail::getShippingInfoId, shippingInfo.getId())
+        );
+
+        if (detailList == null || detailList.isEmpty()) {
+            return;
+        }
+
+        // 鑾峰彇瀹㈡埛鍚嶇О
+        String customerName = null;
+        if (shippingInfo.getSalesLedgerId() != null) {
+            com.ruoyi.sales.pojo.SalesLedger salesLedger = salesLedgerMapper.selectById(shippingInfo.getSalesLedgerId());
+            if (salesLedger != null) {
+                customerName = salesLedger.getCustomerName();
+            }
+        }
+
+        // 涓烘瘡涓彂璐т骇鍝佸垱寤哄嚭鍘傛楠屽崟
+        for (ShippingProductDetail detail : detailList) {
+            qualityInspectHelper.addFactoryInspect(
+                    shippingInfo,
+                    detail,
+                    customerName,
+                    shippingInfo.getSalesLedgerId()
+            );
+        }
+    }
+
     private List<ApprovalTask> createNodeAndTasks(ApprovalInstance instance, ApprovalTemplateNode templateNode) {
         List<ApprovalTemplateNodeApprover> approvers = approvalTemplateNodeApproverMapper.selectList(
                 new LambdaQueryWrapper<ApprovalTemplateNodeApprover>()
diff --git a/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java b/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
index 2b87d5e..4d2c332 100644
--- a/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
+++ b/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
@@ -52,4 +52,14 @@
      * 鑾峰彇鐑偣妫�娴嬫寚鏍� Top 4 + 鍏朵粬
      */
     List<QualityParameterStatDto> getTopParameters(@Param("modelType") Integer modelType);
+
+    /**
+     * 鏍规嵁ID鏌ヨ浜у搧瑙勬牸
+     */
+    com.ruoyi.basic.pojo.ProductModel selectProductModelById(@Param("id") Long id);
+
+    /**
+     * 鏍规嵁ID鏌ヨ浜у搧
+     */
+    com.ruoyi.basic.pojo.Product selectProductById(@Param("id") Long id);
 }
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
index c33313e..cb17247 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -153,6 +153,11 @@
     private Long salesLedgerId;
 
     /**
+     * 鍙戣揣淇℃伅id锛堝嚭鍘傛楠屽叧鑱斿彂璐э級
+     */
+    private Long shippingInfoId;
+
+    /**
      * 鎶ュ伐id
      */
     private Long productMainId;
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
index 10b156c..13c832f 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -157,14 +157,24 @@
             qualityInspect.setUnqualifiedQuantity(BigDecimal.ZERO);
         }
 
-        // 鍚堟牸鐩存帴鍏ュ簱
-        if(qualityInspect.getQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0){
+        // 鍚堟牸鍏ュ簱澶勭悊锛堟牴鎹楠岀被鍨嬪尯鍒嗭級
+        // 杩囩▼妫�楠�(inspectType=1)锛氬叆搴撳埌鎴愬搧搴�
+        // 鍑哄巶妫�楠�(inspectType=2)锛氫笉鍋氫换浣曚笟鍔″鐞�
+        // 鍘熸潗鏂欐楠�(inspectType=0)锛氭甯歌川妫�鍏ュ簱
+        Integer inspectType = qualityInspect.getInspectType();
+        boolean shouldStockIn = inspectType == null || inspectType == 0 || inspectType == 1;
+
+        if (shouldStockIn && qualityInspect.getQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) {
             //浠呮坊鍔犲叆搴撹褰�
             StockInventoryDto stockInventoryDto = new StockInventoryDto();
-            //濡傛灉鏄噰璐川妫�鍚堟牸鍏ュ簱閫夌敤CUSTOMIZATION_UNSTOCK_OUT,鍏朵綑鍚堟牸鍏ュ簱閫夌敤QUALITYINSPECT_STOCK_IN
-            stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()));
-            if (ObjectUtils.isNotEmpty(qualityInspect.getPurchaseLedgerId())){
+            //杩囩▼妫�楠屼娇鐢ㄧ敓浜ф姤宸ュ叆搴撶被鍨嬶紝鍏朵粬璐ㄦ浣跨敤璐ㄦ鍏ュ簱绫诲瀷
+            if (inspectType != null && inspectType == 1) {
+                stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()));
+            } else if (ObjectUtils.isNotEmpty(qualityInspect.getPurchaseLedgerId())) {
+                //閲囪喘璐ㄦ鍚堟牸鍏ュ簱
                 stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode()));
+            } else {
+                stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()));
             }
             stockInventoryDto.setRecordId(qualityInspect.getId());
             stockInventoryDto.setProductModelId(qualityInspect.getProductModelId());
@@ -375,12 +385,22 @@
         // 4. 鏇存柊妫�楠屽崟
         qualityInspectMapper.updateById(qualityInspect);
 
-        // 5. 鍚堟牸鍏ュ簱澶勭悊
-        if (qualified.compareTo(BigDecimal.ZERO) > 0) {
+        // 5. 鍚堟牸鍏ュ簱澶勭悊锛堟牴鎹楠岀被鍨嬪尯鍒嗭級
+        // 杩囩▼妫�楠�(inspectType=1)锛氬叆搴撳埌鎴愬搧搴�
+        // 鍑哄巶妫�楠�(inspectType=2)锛氫笉鍋氫换浣曚笟鍔″鐞�
+        // 鍘熸潗鏂欐楠�(inspectType=0)锛氭甯歌川妫�鍏ュ簱
+        Integer inspectType = qualityInspect.getInspectType();
+        boolean shouldStockIn = inspectType == null || inspectType == 0 || inspectType == 1;
+
+        if (shouldStockIn && qualified.compareTo(BigDecimal.ZERO) > 0) {
             StockInventoryDto stockInventoryDto = new StockInventoryDto();
-            stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()));
-            if (ObjectUtils.isNotEmpty(qualityInspect.getPurchaseLedgerId())) {
+            //杩囩▼妫�楠屼娇鐢ㄧ敓浜ф姤宸ュ叆搴撶被鍨嬶紝鍏朵粬璐ㄦ浣跨敤璐ㄦ鍏ュ簱绫诲瀷
+            if (inspectType != null && inspectType == 1) {
+                stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()));
+            } else if (ObjectUtils.isNotEmpty(qualityInspect.getPurchaseLedgerId())) {
                 stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode()));
+            } else {
+                stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()));
             }
             stockInventoryDto.setRecordId(qualityInspect.getId());
             stockInventoryDto.setProductModelId(qualityInspect.getProductModelId());
diff --git a/src/main/java/com/ruoyi/quality/utils/QualityInspectHelper.java b/src/main/java/com/ruoyi/quality/utils/QualityInspectHelper.java
index 050ac6f..5fc5a13 100644
--- a/src/main/java/com/ruoyi/quality/utils/QualityInspectHelper.java
+++ b/src/main/java/com/ruoyi/quality/utils/QualityInspectHelper.java
@@ -12,6 +12,8 @@
 import com.ruoyi.quality.pojo.QualityTestStandard;
 import com.ruoyi.quality.pojo.QualityTestStandardParam;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.sales.pojo.ShippingProductDetail;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 
@@ -104,4 +106,67 @@
             }
         }
     }
+
+    /**
+     * 鍒涘缓鍑哄巶妫�楠屽崟锛堝彂璐у鎵归�氳繃鍚庤嚜鍔ㄧ敓鎴愶級
+     * @param shippingInfo 鍙戣揣淇℃伅
+     * @param detail 鍙戣揣浜у搧鏄庣粏
+     * @param customerName 瀹㈡埛鍚嶇О
+     * @param salesLedgerId 閿�鍞彴璐D
+     */
+    public void addFactoryInspect(ShippingInfo shippingInfo, ShippingProductDetail detail,
+                                   String customerName, Long salesLedgerId) {
+        QualityInspect qualityInspect = new QualityInspect();
+        qualityInspect.setInspectType(2); // 鍑哄巶妫�楠�
+        qualityInspect.setCustomer(customerName);
+        qualityInspect.setSalesLedgerId(salesLedgerId);
+        qualityInspect.setShippingInfoId(shippingInfo.getId()); // 鍏宠仈鍙戣揣淇℃伅
+        qualityInspect.setProductModelId(detail.getProductModelId());
+        qualityInspect.setQuantity(detail.getQuantity());
+        qualityInspect.setInspectState(0); // 鏈彁浜�
+
+        // 閫氳繃 productModelId 鏌ヨ浜у搧淇℃伅
+        if (detail.getProductModelId() != null) {
+            com.ruoyi.basic.pojo.ProductModel productModel = qualityInspectMapper.selectProductModelById(detail.getProductModelId());
+            if (productModel != null) {
+                qualityInspect.setProductId(productModel.getProductId());
+                qualityInspect.setModel(productModel.getModel());
+                qualityInspect.setUnit(productModel.getUnit());
+                // 鏌ヨ浜у搧鍚嶇О
+                if (productModel.getProductId() != null) {
+                    com.ruoyi.basic.pojo.Product product = qualityInspectMapper.selectProductById(productModel.getProductId());
+                    if (product != null) {
+                        qualityInspect.setProductName(product.getProductName());
+                    }
+                }
+            }
+        }
+
+        qualityInspectMapper.insert(qualityInspect);
+
+        // 鏌ヨ鍑哄巶妫�楠屾爣鍑嗭紝鍒濆鍖栨楠屽弬鏁�
+        if (qualityInspect.getProductId() != null) {
+            List<QualityTestStandard> qualityTestStandardList = qualityTestStandardMapper
+                    .getQualityTestStandardByProductId(qualityInspect.getProductId(), 2, null);
+
+            if (!qualityTestStandardList.isEmpty()) {
+                QualityTestStandard firstStandard = qualityTestStandardList.get(0);
+                qualityInspect.setTestStandardId(firstStandard.getId());
+                applyInspectRuleDefaults(qualityInspect, firstStandard, detail.getQuantity());
+                qualityInspectMapper.updateById(qualityInspect);
+
+                List<QualityTestStandardParam> standardParams = qualityTestStandardParamMapper.selectList(
+                        Wrappers.<QualityTestStandardParam>lambdaQuery()
+                                .eq(QualityTestStandardParam::getTestStandardId, firstStandard.getId()));
+
+                for (QualityTestStandardParam standardParam : standardParams) {
+                    QualityInspectParam param = new QualityInspectParam();
+                    BeanUtils.copyProperties(standardParam, param);
+                    param.setId(null);
+                    param.setInspectId(qualityInspect.getId());
+                    qualityInspectParamMapper.insert(param);
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
index 43c0937..4cbd6f4 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -15,6 +15,8 @@
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
 
 import java.time.LocalDateTime;
 import com.ruoyi.stock.dto.StockInventoryDto;
@@ -52,6 +54,7 @@
     private final StockUninventoryMapper stockUninventoryMapper;
     private final AccountSalesCollectionMapper accountSalesCollectionMapper;
     private final AccountInvoiceApplicationMapper accountInvoiceApplicationMapper;
+    private final QualityInspectMapper qualityInspectMapper;
 
     @Override
     public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) {
@@ -183,6 +186,12 @@
             if (stockOutRecord.getApprovalStatus() != null && !ReviewStatusEnum.PENDING_REVIEW.getCode().equals(stockOutRecord.getApprovalStatus())) {
                 throw new BaseException("鍙湁寰呭鎵圭姸鎬佺殑璁板綍鎵嶈兘瀹℃壒,鍑哄簱鎵规:" + stockOutRecord.getOutboundBatches());
             }
+
+            // 鍑哄簱瀹℃壒閫氳繃鍓嶏紝妫�鏌ユ槸鍚﹂渶瑕佸嚭鍘傝川妫�浠ュ強璐ㄦ鏄惁瀹屾垚
+            if (ReviewStatusEnum.APPROVED.getCode().equals(approvalStatus) && StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode().equals(stockOutRecord.getRecordType())) {
+                checkFactoryInspectCompleted(stockOutRecord);
+            }
+
             stockOutRecord.setApprovalStatus(approvalStatus);
             stockOutRecordMapper.updateById(stockOutRecord);
             // 瀹℃壒閫氳繃鏃讹紝鎵e噺搴撳瓨
@@ -215,6 +224,36 @@
         return ids.size();
     }
 
+    /**
+     * 妫�鏌ラ攢鍞嚭搴撴槸鍚﹀凡瀹屾垚鍑哄巶璐ㄦ
+     */
+    private void checkFactoryInspectCompleted(StockOutRecord stockOutRecord) {
+        // 鏌ヨ璇ュ嚭搴撹褰曞搴旂殑鍑哄巶妫�楠屽崟鏄惁宸插畬鎴�
+        Long recordId = stockOutRecord.getRecordId();
+        Long productModelId = stockOutRecord.getProductModelId();
+
+        if (recordId == null || productModelId == null) {
+            return;
+        }
+
+        // 鏌ヨ鍏宠仈鐨勫嚭鍘傛楠屽崟锛坕nspectType=2, shippingInfoId=recordId, productModelId锛�
+        QualityInspect qualityInspect = qualityInspectMapper.selectOne(
+                new LambdaQueryWrapper<QualityInspect>()
+                        .eq(QualityInspect::getInspectType, 2)
+                        .eq(QualityInspect::getShippingInfoId, recordId)
+                        .eq(QualityInspect::getProductModelId, productModelId)
+                        .last("limit 1")
+        );
+
+        if (qualityInspect == null) {
+            throw new BaseException("璇ュ嚭搴撹褰曟湭鐢熸垚鍑哄巶妫�楠屽崟锛岃鍏堝畬鎴愬彂璐у鎵�");
+        }
+
+        if (qualityInspect.getInspectState() == null || qualityInspect.getInspectState() != 1) {
+            throw new BaseException("鍑哄巶妫�楠屽崟灏氭湭鎻愪氦瀹屾垚锛岃鍏堝畬鎴愬嚭鍘傝川妫�鍚庡啀杩涜鍑哄簱瀹℃壒");
+        }
+    }
+
     private StockInventory getStockInventory(Long productModelId, String batchNo) {
         LambdaQueryWrapper<StockInventory> eq = new LambdaQueryWrapper<>();
         eq.eq(StockInventory::getProductModelId, productModelId);
diff --git a/src/main/resources/mapper/quality/QualityInspectMapper.xml b/src/main/resources/mapper/quality/QualityInspectMapper.xml
index 74b3e98..a324820 100644
--- a/src/main/resources/mapper/quality/QualityInspectMapper.xml
+++ b/src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -471,5 +471,16 @@
 
     </select>
 
+    <select id="selectProductModelById" resultType="com.ruoyi.basic.pojo.ProductModel">
+        SELECT id, product_id, model, unit
+        FROM product_model
+        WHERE id = #{id}
+    </select>
+
+    <select id="selectProductById" resultType="com.ruoyi.basic.pojo.Product">
+        SELECT id, product_name
+        FROM product
+        WHERE id = #{id}
+    </select>
 
 </mapper>

--
Gitblit v1.9.3