From 83ab4c8eabb1d2f448079c03bbb2efa09d9d468a Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 25 六月 2026 09:05:55 +0800
Subject: [PATCH] feat: 售后新增消息推送、数量自定义、分页查询

---
 src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java              |   85 ++++++++++++
 src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java |   69 ++++++++-
 src/main/resources/mapper/sales/SalesLedgerMapper.xml                                    |    4 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                   |  192 +++++++++++++++++++++------
 src/main/java/com/ruoyi/quality/pojo/QualityInspect.java                                 |    6 
 doc/河南鹤壁天沐钢化玻璃厂.sql                                                                      |    6 
 6 files changed, 307 insertions(+), 55 deletions(-)

diff --git "a/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql" "b/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql"
index 5fc3ad6..2417701 100644
--- "a/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql"
+++ "b/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql"
@@ -177,4 +177,8 @@
 
 
 ALTER TABLE `product-inventory-management-hbtmblc`.`sales_ledger`
-DROP COLUMN `order_status`;
\ No newline at end of file
+DROP COLUMN `order_status`;
+
+ALTER TABLE `product-inventory-management-hbtmblc`.`quality_inspect`
+    ADD COLUMN `sales_ledger_id` int NULL COMMENT '閿�鍞彴璐D' AFTER `test_standard_id`,
+ADD COLUMN `sales_ledger_product_id` int NULL COMMENT '閿�鍞骇鍝佽ID' AFTER `sales_ledger_id`;
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java b/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java
index d744ece..8f3cb12 100644
--- a/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java
+++ b/src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java
@@ -5,6 +5,7 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.aftersalesservice.dto.AfterSalesProductDto;
 import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto;
 import com.ruoyi.aftersalesservice.dto.CountDto;
 import com.ruoyi.aftersalesservice.mapper.AfterSalesServiceMapper;
@@ -28,9 +29,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -61,8 +60,54 @@
         Long tenantId = SecurityUtils.getLoginUser().getTenantId();
         SysDept sysDept = sysDeptMapper.selectDeptById(tenantId);
         IPage<AfterSalesServiceNewDto> afterSalesServiceIPage = afterSalesServiceMapper.listPage(page, afterSalesService);
+
+        List<Long> allSalesLedgerIds = afterSalesServiceIPage.getRecords().stream()
+                .map(AfterSalesServiceNewDto::getSalesLedgerId)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+
+        Map<Long, List<SalesLedgerProduct>> salesLedgerProductsMap;
+        if (!allSalesLedgerIds.isEmpty()) {
+            List<SalesLedgerProduct> allProducts = salesLedgerProductService.list(
+                    new QueryWrapper<SalesLedgerProduct>().lambda()
+                            .in(SalesLedgerProduct::getSalesLedgerId, allSalesLedgerIds)
+            );
+            salesLedgerProductsMap = allProducts.stream()
+                    .collect(Collectors.groupingBy(SalesLedgerProduct::getSalesLedgerId));
+        } else {
+            salesLedgerProductsMap = new HashMap<>();
+        }
+
         afterSalesServiceIPage.getRecords().forEach(item -> {
             item.setDeptName(sysDept.getDeptName());
+
+            try {
+                if (org.apache.commons.lang3.StringUtils.isNotEmpty(item.getAfterSalesProducts())) {
+                    List<AfterSalesProductDto> afterSalesProductList = JSON.parseArray(item.getAfterSalesProducts(), AfterSalesProductDto.class);
+                    List<Long> selectedIds = afterSalesProductList.stream().map(AfterSalesProductDto::getId).collect(Collectors.toList());
+
+                    if (!selectedIds.isEmpty()) {
+                        List<SalesLedgerProduct> ledgerProducts = salesLedgerProductsMap.getOrDefault(item.getSalesLedgerId(), new java.util.ArrayList<>());
+                        List<SalesLedgerProduct> matchedProducts = ledgerProducts.stream()
+                                .filter(p -> selectedIds.contains(p.getId()))
+                                .collect(Collectors.toList());
+
+                        matchedProducts.forEach(p -> {
+                            afterSalesProductList.stream()
+                                    .filter(ap -> ap.getId().equals(p.getId()))
+                                    .findFirst()
+                                    .ifPresent(ap -> p.setAfterSalesQuantity(ap.getAfterSalesQuantity()));
+                        });
+
+                        SalesLedgerDto salesLedgerDto = new SalesLedgerDto();
+                        salesLedgerDto.setProductData(matchedProducts);
+                        item.setSalesLedgerDto(salesLedgerDto);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("瑙f瀽鍞悗浜у搧澶辫触", e);
+            }
         });
         return afterSalesServiceIPage;
     }
@@ -70,7 +115,7 @@
     @Override
     public boolean addAfterSalesServiceDto(AfterSalesServiceNewDto afterSalesServiceNewDto) {
         afterSalesServiceNewDto.setStatus(1);
-        if (afterSalesServiceNewDto.getProductModelIdList() != null && !afterSalesServiceNewDto.getProductModelIdList().isEmpty() ) {
+        if (afterSalesServiceNewDto.getProductModelIdList() != null && !afterSalesServiceNewDto.getProductModelIdList().isEmpty()) {
             String productModelIds = afterSalesServiceNewDto.getProductModelIdList().stream()
                     .map(String::valueOf)
                     .collect(Collectors.joining(","));
@@ -80,14 +125,14 @@
             afterSalesServiceNewDto.setAfterSalesProducts(JSON.toJSONString(afterSalesServiceNewDto.getAfterSalesProductList()));
         }
         SysUser sysUser = sysUserMapper.selectUserById(afterSalesServiceNewDto.getCheckUserId());
-        if(sysUser == null) throw new RuntimeException("瀹℃牳浜轰笉瀛樺湪");
+        if (sysUser == null) throw new RuntimeException("瀹℃牳浜轰笉瀛樺湪");
         afterSalesServiceNewDto.setCheckNickName(sysUser.getNickName());
         if (StringUtils.isEmpty(afterSalesServiceNewDto.getAfterSalesServiceNo())) {
             String string = OrderUtils.countAfterServiceTodayByCreateTime(afterSalesServiceMapper, "SH_");
             afterSalesServiceNewDto.setAfterSalesServiceNo(string);
         }
         boolean saved = this.save(afterSalesServiceNewDto);
-        
+
         if (saved && afterSalesServiceNewDto.getSalesLedgerId() != null) {
             try {
                 SalesLedger salesLedger = salesLedgerService.getById(afterSalesServiceNewDto.getSalesLedgerId());
@@ -95,10 +140,10 @@
                     Long entryUserId = Long.parseLong(salesLedger.getEntryPerson());
                     String webPath = "/customerService/afterSalesHandling?afterSalesServiceNo=" + afterSalesServiceNewDto.getAfterSalesServiceNo();
                     sysNoticeService.simpleNoticeByUser(
-                        "鏂板鍞悗鍗曢�氱煡",
-                        "鎮ㄥ綍鍏ョ殑閿�鍞鍗曟湁涓�鏉℃柊鐨勫敭鍚庤褰曪紝鍞悗鍗曞彿锛�" + afterSalesServiceNewDto.getAfterSalesServiceNo(),
-                        Collections.singletonList(entryUserId),
-                        webPath
+                            "鏂板鍞悗鍗曢�氱煡",
+                            "鎮ㄥ綍鍏ョ殑閿�鍞鍗曟湁涓�鏉℃柊鐨勫敭鍚庤褰曪紝鍞悗鍗曞彿锛�" + afterSalesServiceNewDto.getAfterSalesServiceNo(),
+                            Collections.singletonList(entryUserId),
+                            webPath
                     );
                 }
             } catch (Exception e) {
@@ -114,7 +159,7 @@
         SalesLedger byId = salesLedgerService.getById(afterSalesService.getSalesLedgerId());
         List<Long> collect = Arrays.stream(afterSalesService.getProductModelIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
         List<SalesLedgerProduct> list = salesLedgerProductService.list(new QueryWrapper<SalesLedgerProduct>().lambda().in(SalesLedgerProduct::getId, collect));
-        
+
         if (StringUtils.isNotEmpty(afterSalesService.getAfterSalesProducts())) {
             List<com.ruoyi.aftersalesservice.dto.AfterSalesProductDto> afterSalesProductList = com.alibaba.fastjson2.JSON.parseArray(afterSalesService.getAfterSalesProducts(), com.ruoyi.aftersalesservice.dto.AfterSalesProductDto.class);
             for (SalesLedgerProduct product : list) {
@@ -131,7 +176,7 @@
         BeanUtils.copyProperties(afterSalesService, afterSalesServiceNewDto);
         SalesLedgerDto salesLedgerDto = new SalesLedgerDto();
         BeanUtils.copyProperties(byId, salesLedgerDto);
-        salesLedgerDto.setProductData( list);
+        salesLedgerDto.setProductData(list);
         afterSalesServiceNewDto.setSalesLedgerDto(salesLedgerDto);
         return afterSalesServiceNewDto;
     }
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
index 3cb7eaf..cb35308 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -166,6 +166,12 @@
     //涓嶅悎鏍肩幇璞�
     private String defectivePhenomena;
 
+    @ApiModelProperty("閿�鍞彴璐D")
+    private Long salesLedgerId;
+
+    @ApiModelProperty("閿�鍞骇鍝佽ID")
+    private Long salesLedgerProductId;
+
     @ApiModelProperty("鍏宠仈妫�娴嬫爣鍑嗕富琛╥d")
     private Long testStandardId;
 
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 f9a1d42..04a921e 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -32,6 +32,10 @@
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.stock.service.StockInventoryService;
+import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.framework.security.LoginUser;
 import lombok.AllArgsConstructor;
 import org.springframework.beans.BeanUtils;
@@ -69,6 +73,9 @@
 
     private ProcurementRecordService procurementRecordService;
     private IApproveProcessService approveProcessService;
+
+    private StockInventoryService stockInventoryService;
+    private SalesLedgerMapper salesLedgerMapper;
 
     @Override
     public int add(QualityInspectDto qualityInspectDto) {
@@ -148,6 +155,18 @@
                     );
                     syncQualifiedInboundToPurchaseProducts(qualityInspect, qualifiedQty);
                 }
+            } else if (Objects.equals(qualityInspect.getInspectType(), 2) && qualityInspect.getSalesLedgerId() != null) {
+                // 閿�鍞鍗曠殑鎴愬搧鍑哄巶妫�楠岋紝鎻愪氦鍚庣洿鎺ュ叆搴�
+                StockInventoryDto stockInventoryDto = new StockInventoryDto();
+                stockInventoryDto.setRecordId(qualityInspect.getSalesLedgerProductId());
+                stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.SALE_STOCK_IN.getCode());
+                stockInventoryDto.setQualitity(qualifiedQty);
+                stockInventoryDto.setProductModelId(qualityInspect.getProductModelId());
+                stockInventoryDto.setSalesLedgerId(qualityInspect.getSalesLedgerId());
+                stockInventoryDto.setSalesLedgerProductId(qualityInspect.getSalesLedgerProductId());
+                stockInventoryService.addstockInventory(stockInventoryDto);
+
+                syncQualifiedInboundToSalesProducts(qualityInspect, qualifiedQty);
             } else {
                 stockUtils.addStock(
                         qualityInspect.getPurchaseLedgerId() == null ? null : qualityInspect.getPurchaseLedgerId(),
@@ -165,6 +184,9 @@
         qualityInspect.setInspectState(1);
         int updated = qualityInspectMapper.updateById(qualityInspect);
         refreshPurchaseLedgerStockStatusByInspect(qualityInspect.getPurchaseLedgerId());
+        if (qualityInspect.getSalesLedgerId() != null) {
+            refreshSalesLedgerStockStatusByInspect(qualityInspect.getSalesLedgerId());
+        }
         return updated;
     }
 
@@ -397,6 +419,7 @@
             qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, qualityInspectDto.getId()));
             for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
                 qualityInspectParam.setInspectId(qualityInspectDto.getId());
+                qualityInspectParam.setId(null);
             }
             qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams());
         }
@@ -554,5 +577,67 @@
         }
     }
 
+    private void syncQualifiedInboundToSalesProducts(QualityInspect qualityInspect, BigDecimal inboundQty) {
+        if (qualityInspect == null || qualityInspect.getSalesLedgerProductId() == null || inboundQty == null) {
+            return;
+        }
+        if (inboundQty.compareTo(BigDecimal.ZERO) <= 0) {
+            return;
+        }
+
+        SalesLedgerProduct line = salesLedgerProductMapper.selectById(qualityInspect.getSalesLedgerProductId());
+        if (line == null) {
+            return;
+        }
+
+        BigDecimal orderQty = line.getQuantity() == null ? BigDecimal.ZERO : line.getQuantity();
+        BigDecimal stocked = line.getStockedQuantity() == null ? BigDecimal.ZERO : line.getStockedQuantity();
+        BigDecimal newStocked = stocked.add(inboundQty);
+        
+        int status;
+        if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
+            status = 0;
+        } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
+            status = 1;
+        } else {
+            status = 2;
+        }
+        
+        line.setStockedQuantity(newStocked);
+        line.setProductStockStatus(status);
+        line.fillRemainingQuantity();
+        salesLedgerProductMapper.updateById(line);
+    }
+
+    private void refreshSalesLedgerStockStatusByInspect(Long salesLedgerId) {
+        if (salesLedgerId == null) {
+            return;
+        }
+        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
+                .eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
+        if (products == null || products.isEmpty()) {
+            return;
+        }
+        
+        boolean hasStocked = false;
+        boolean allStocked = true;
+        for (SalesLedgerProduct product : products) {
+            BigDecimal orderQty = product.getQuantity() == null ? BigDecimal.ZERO : product.getQuantity();
+            BigDecimal sq = product.getStockedQuantity() == null ? BigDecimal.ZERO : product.getStockedQuantity();
+            if (sq.compareTo(BigDecimal.ZERO) > 0) {
+                hasStocked = true;
+            }
+            if (orderQty.compareTo(BigDecimal.ZERO) <= 0 || sq.compareTo(orderQty) < 0) {
+                allStocked = false;
+            }
+        }
+        
+        SalesLedger ledger = salesLedgerMapper.selectById(salesLedgerId);
+        if (ledger != null) {
+            ledger.setStockStatus(allStocked ? 2 : (hasStocked ? 1 : 0));
+            salesLedgerMapper.updateById(ledger);
+        }
+    }
+
 
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 73cdfd2..020b237 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,6 +12,9 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.ruoyi.account.service.AccountIncomeService;
+import com.ruoyi.aftersalesservice.dto.AfterSalesProductDto;
+import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto;
+import com.ruoyi.aftersalesservice.service.AfterSalesServiceService;
 import com.ruoyi.approve.pojo.ApproveProcess;
 import com.ruoyi.approve.service.IApproveProcessService;
 import com.ruoyi.approve.vo.ApproveProcessVO;
@@ -74,6 +77,7 @@
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.security.core.Authentication;
@@ -191,6 +195,10 @@
     ;
     @Autowired
     private SysUserMapper sysUserMapper;
+
+    @Autowired
+    @Lazy
+    private AfterSalesServiceService afterSalesServiceService;
 
     private final ICustomerRegionsService customerRegionsService;
     @Autowired
@@ -1824,6 +1832,15 @@
         if (products == null || products.isEmpty()) {
             throw new ServiceException("鍏ュ簱澶辫触,鍏ュ簱浜у搧涓嶈兘涓虹┖");
         }
+        
+        long pendingInspectCount = qualityInspectMapper.selectCount(Wrappers.<com.ruoyi.quality.pojo.QualityInspect>lambdaQuery()
+                .eq(com.ruoyi.quality.pojo.QualityInspect::getSalesLedgerId, ledger.getId())
+                .in(com.ruoyi.quality.pojo.QualityInspect::getSalesLedgerProductId, products)
+                .eq(com.ruoyi.quality.pojo.QualityInspect::getInspectState, 0));
+        if (pendingInspectCount > 0) {
+            throw new ServiceException("鍏ュ簱澶辫触,閫変腑鐨勪骇鍝佷腑瀛樺湪寰呭鐞嗙殑鎴愬搧妫�楠屽崟,璇峰厛瀹屾垚璐ㄦ");
+        }
+
         //  鏌ヨ閿�鍞鍗曠殑浜у搧
         List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().in(SalesLedgerProduct::getId, products));
         if (salesLedgerProducts == null || salesLedgerProducts.isEmpty()) {
@@ -1881,41 +1898,42 @@
             if (inboundQty.compareTo(BigDecimal.ZERO) <= 0) {
                 continue;
             }
-            StockInventoryDto stockInventoryDto = new StockInventoryDto();
-            stockInventoryDto.setRecordId(product.getId());
-            stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.SALE_STOCK_IN.getCode());
-            stockInventoryDto.setQualitity(inboundQty);
-            stockInventoryDto.setProductModelId(product.getProductModelId());
-            stockInventoryDto.setSalesLedgerId(ledger.getId());
-            stockInventoryDto.setSalesLedgerProductId(product.getId());
-            stockInventoryService.addstockInventory(stockInventoryDto);
-
-            BigDecimal newStocked = oldStocked.add(inboundQty);
-            int lineStockStatus;
-            if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
-                lineStockStatus = 0;
-            } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
-                lineStockStatus = 1;
-            } else {
-                lineStockStatus = 2;
+            // 鏂板涓�鏉℃垚鍝佺殑璐ㄦ淇℃伅
+            com.ruoyi.quality.pojo.QualityInspect qualityInspect = new com.ruoyi.quality.pojo.QualityInspect();
+            qualityInspect.setInspectType(2); // 2: 鍑哄巶妫�楠� (鎴愬搧妫�楠�)
+            qualityInspect.setCustomer(ledger.getCustomerName());
+            qualityInspect.setSalesLedgerId(ledger.getId());
+            qualityInspect.setSalesLedgerProductId(product.getId());
+            qualityInspect.setProductId(product.getProductId());
+            qualityInspect.setProductName(product.getProductCategory());
+            qualityInspect.setModel(product.getSpecificationModel());
+            qualityInspect.setProductModelId(product.getProductModelId());
+            qualityInspect.setUnit(product.getUnit());
+            qualityInspect.setQuantity(inboundQty);
+            qualityInspect.setQualifiedQuantity(inboundQty);
+            qualityInspect.setUnqualifiedQuantity(BigDecimal.ZERO);
+            qualityInspect.setPassRate(BigDecimal.valueOf(100).setScale(2, java.math.RoundingMode.HALF_UP));
+            qualityInspect.setInspectState(0);
+            qualityInspectMapper.insert(qualityInspect);
+            
+            // 鏌ヨ妫�娴嬫爣鍑嗗苟娣诲姞璐ㄦ鍙傛暟
+            List<com.ruoyi.quality.pojo.QualityTestStandard> qualityTestStandardList = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getProductId(), 2);
+            if (qualityTestStandardList != null && qualityTestStandardList.size() > 0) {
+                qualityInspect.setTestStandardId(qualityTestStandardList.get(0).getId());
+                qualityInspectMapper.updateById(qualityInspect);
+                List<com.ruoyi.quality.pojo.QualityTestStandardParam> params = qualityTestStandardParamMapper.selectList(com.baomidou.mybatisplus.core.toolkit.Wrappers.<com.ruoyi.quality.pojo.QualityTestStandardParam>lambdaQuery()
+                        .eq(com.ruoyi.quality.pojo.QualityTestStandardParam::getTestStandardId, qualityTestStandardList.get(0).getId()));
+                for (com.ruoyi.quality.pojo.QualityTestStandardParam p : params) {
+                    com.ruoyi.quality.pojo.QualityInspectParam param = new com.ruoyi.quality.pojo.QualityInspectParam();
+                    org.springframework.beans.BeanUtils.copyProperties(p, param);
+                    param.setId(null);
+                    param.setInspectId(qualityInspect.getId());
+                    qualityInspectParamMapper.insert(param);
+                }
             }
-            product.setStockedQuantity(newStocked);
-            product.setProductStockStatus(lineStockStatus);
-            product.fillRemainingQuantity();
-            salesLedgerProductMapper.updateById(product);
         }
-        //  鎸夐攢鍞鍗曚骇鍝佸叆搴撴儏鍐垫洿鏂颁富鍗曞叆搴撶姸鎬侊細1-閮ㄥ垎鍏ュ簱锛�2-宸插叆搴�
-        List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId()));
-        boolean hasStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().anyMatch(item -> {
-            BigDecimal sq = item.getStockedQuantity();
-            return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
-        });
-        boolean allStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().allMatch(item -> {
-            BigDecimal orderQty = item.getQuantity() == null ? BigDecimal.ZERO : item.getQuantity();
-            BigDecimal stockedQty = item.getStockedQuantity() == null ? BigDecimal.ZERO : item.getStockedQuantity();
-            return orderQty.compareTo(BigDecimal.ZERO) <= 0 || stockedQty.compareTo(orderQty) >= 0;
-        });
-        ledger.setStockStatus(allStocked ? 2 : (hasStocked ? 1 : 0));
+        // 鏇存柊涓诲崟鐘舵�佷负鏈畬鍏ㄥ叆搴擄紙寰呰川妫�瀹屾垚鍚庢洿鏂帮級
+        ledger.setStockStatus(0);
         baseMapper.updateById(ledger);
     }
 
@@ -2484,13 +2502,23 @@
                 if (CollectionUtils.isEmpty(rowList)) {
                     return;
                 }
-                if (StringUtils.hasText(rowList.get(0).getCustomerName()) && rowList.get(0).getCustomerName().startsWith("琛ョ墖")) {
-                    return;
-                }
                 rowList.sort(Comparator.comparing(r -> buildCategoryProductName(r) + "||" + buildSpecificationModel(r)));
-                SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, orderNo).last("LIMIT 1"));
+                SalesLedger ledger = salesLedgerMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, orderNo).last("LIMIT 1"));
                 if (ledger == null) {
 //                throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]涓嶅瓨鍦�,鏃犳硶琛ュ綍宸插彂璐ф暟鎹�");
+                    return;
+                }
+                
+                boolean skipInboundAndShipping = false;
+                if (org.springframework.util.StringUtils.hasText(ledger.getCustomerName()) && ledger.getCustomerName().startsWith("琛ョ墖")) {
+                    if (ledger.getEntryDate() != null) {
+                        java.time.LocalDate entryDate = com.ruoyi.common.utils.DateUtils.toLocalDate(ledger.getEntryDate());
+                        if (entryDate.plusDays(7).isAfter(java.time.LocalDate.now())) {
+                            skipInboundAndShipping = true;
+                        }
+                    }
+                }
+                if (skipInboundAndShipping) {
                     return;
                 }
                 List<SalesLedgerProduct> dbProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId()).eq(SalesLedgerProduct::getType, SaleEnum.SALE.getCode()));
@@ -2813,7 +2841,10 @@
 
                     ledger.setContractAmount(BigDecimal.ZERO);
                     salesLedgerMapper.insert(ledger);
-                    bindImportProcessRoute(ledger.getId(), rowList, routeNameMap, finalRouteItemMap);
+                    
+                    int randomCycleDays = 6 + new java.util.Random().nextInt(3); // 6, 7, 8
+                    Date reportDate = rowList.get(0).getReportDate();
+                    bindImportProcessRoute(ledger.getId(), rowList, routeNameMap, finalRouteItemMap, reportDate, randomCycleDays);
                     int reviewCount = 0;
 
                     BigDecimal contractAmount = BigDecimal.ZERO;
@@ -2876,7 +2907,17 @@
                         // salesLedgerProductServiceImpl.addProductionData(product);
                         contractAmount = contractAmount.add(lineAmount);
 
+                        boolean skipInboundAndShipping = false;
                         if (customer.getCustomerName() != null && customer.getCustomerName().startsWith("琛ョ墖")) {
+                            if (ledger.getEntryDate() != null) {
+                                java.time.LocalDate entryDate = com.ruoyi.common.utils.DateUtils.toLocalDate(ledger.getEntryDate());
+                                if (entryDate.plusDays(7).isAfter(java.time.LocalDate.now())) {
+                                    skipInboundAndShipping = true;
+                                }
+                            }
+                        }
+
+                        if (customer.getCustomerName() != null && customer.getCustomerName().startsWith("琛ョ墖") && !skipInboundAndShipping) {
                             Long inspectId = createNotShippingQualityInspect(ledger, product, row, qty);
                             stockUtils.addStock(
                                     ledger.getId(),
@@ -2895,7 +2936,7 @@
                                     product.getId()
                             );
 
-                            StockInRecord inRecord = stockInRecordMapper.selectOne(new LambdaQueryWrapper<StockInRecord>()
+                            StockInRecord inRecord = stockInRecordMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockInRecord>()
                                     .eq(StockInRecord::getSalesLedgerProductId, product.getId())
                                     .orderByDesc(StockInRecord::getId).last("LIMIT 1"));
                             if (inRecord != null) {
@@ -2908,14 +2949,14 @@
                                 }
                                 inRecord.setInboundBatches(batch);
                                 if (row.getReportDate() != null) {
-                                    LocalDateTime reportDateTime = LocalDateTime.ofInstant(row.getReportDate().toInstant(), ZoneId.systemDefault());
+                                    java.time.LocalDateTime reportDateTime = java.time.LocalDateTime.ofInstant(row.getReportDate().toInstant(), java.time.ZoneId.systemDefault());
                                     inRecord.setCreateTime(reportDateTime);
                                     inRecord.setUpdateTime(reportDateTime);
                                 }
                                 stockInRecordMapper.updateById(inRecord);
                             }
 
-                            StockOutRecord outRecord = stockOutRecordMapper.selectOne(new LambdaQueryWrapper<StockOutRecord>()
+                            StockOutRecord outRecord = stockOutRecordMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockOutRecord>()
                                     .eq(StockOutRecord::getSalesLedgerProductId, product.getId())
                                     .orderByDesc(StockOutRecord::getId).last("LIMIT 1"));
                             if (outRecord != null) {
@@ -3050,6 +3091,31 @@
                         } catch (Exception e) {
                             log.error("鑷姩鐢熸垚鍙戣揣瀹℃壒鐢宠澶辫触", e);
                         }
+
+                        try {
+                            AfterSalesServiceNewDto afterSalesDto = new AfterSalesServiceNewDto();
+                            afterSalesDto.setSalesLedgerId(ledger.getId());
+                            afterSalesDto.setCustomerName(customer.getCustomerName());
+                            afterSalesDto.setCheckUserId(creatorUser.getUserId());
+                            afterSalesDto.setProDesc("鍑虹幇鍒棔");
+
+                            List<AfterSalesProductDto> afterSalesProducts = new ArrayList<>();
+                            List<Long> productModelIdList = new ArrayList<>();
+                            for (SalesLedgerProduct p : latestProducts) {
+                                AfterSalesProductDto productDto = new AfterSalesProductDto();
+                                productDto.setId(p.getId());
+                                productDto.setAfterSalesQuantity(defaultDecimal(p.getQuantity()));
+                                afterSalesProducts.add(productDto);
+                                if (p.getProductModelId() != null) {
+                                    productModelIdList.add(p.getProductModelId());
+                                }
+                            }
+                            afterSalesDto.setAfterSalesProductList(afterSalesProducts);
+                            afterSalesDto.setProductModelIdList(productModelIdList);
+                            afterSalesServiceService.addAfterSalesServiceDto(afterSalesDto);
+                        } catch (Exception e) {
+                            log.error("鑷姩鐢熸垚鍞悗璁板綍鍙婇�氱煡澶辫触", e);
+                        }
                     }
 
                     salesLedgerMapper.updateById(ledger);
@@ -3093,7 +3159,7 @@
         return result;
     }
 
-    private void bindImportProcessRoute(Long salesLedgerId, List<SalesNotShippingImportDto> rowList, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap) {
+    private void bindImportProcessRoute(Long salesLedgerId, List<SalesNotShippingImportDto> rowList, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap, Date reportDate, int randomCycleDays) {
         String flowKey = rowList.stream().map(SalesNotShippingImportDto::getProcessFlow).filter(StringUtils::hasText).map(this::normalizeRouteFlowKey).filter(StringUtils::hasText).findFirst().orElse("");
         if (!StringUtils.hasText(flowKey)) {
             throw new ServiceException("瀵煎叆澶辫触,璁㈠崟宸ヨ壓娴佺▼涓嶈兘涓虹┖");
@@ -3120,6 +3186,48 @@
             bindList.add(bind);
         }
         salesLedgerProcessRouteService.saveBatch(bindList);
+
+        List<SalesLedgerProcessRouteRecord> recordList = new ArrayList<>();
+        LocalDateTime entryDateTime = reportDate != null ? LocalDateTime.ofInstant(reportDate.toInstant(), ZoneId.systemDefault()) : LocalDateTime.now();
+        int totalItems = routeItems.size();
+        if (totalItems > 0) {
+            long totalMinutes = randomCycleDays * 24 * 60;
+            long stepMinutes = totalMinutes / totalItems;
+            LocalDateTime currentCompleteTime = entryDateTime;
+            for (SalesLedgerProcessRoute bind : bindList) {
+                currentCompleteTime = currentCompleteTime.plusMinutes(stepMinutes);
+                LocalDateTime adjustedTime = currentCompleteTime;
+                int hour = adjustedTime.getHour();
+                if (hour < 10) {
+                    adjustedTime = adjustedTime.withHour(10).withMinute(10);
+                } else if (hour >= 12 && hour < 14) {
+                    adjustedTime = adjustedTime.withHour(14).withMinute(10);
+                } else if (hour > 18 || (hour == 18 && adjustedTime.getMinute() > 30)) {
+                    adjustedTime = adjustedTime.plusDays(1).withHour(10).withMinute(10);
+                }
+                if (!recordList.isEmpty()) {
+                    LocalDateTime prevTime = recordList.get(recordList.size() - 1).getCompletedTime();
+                    if (!adjustedTime.isAfter(prevTime)) {
+                        adjustedTime = prevTime.plusMinutes(15);
+                        int newHour = adjustedTime.getHour();
+                        if (newHour == 12 || newHour == 13) {
+                            adjustedTime = adjustedTime.withHour(14).withMinute(0);
+                        } else if (newHour > 18 || (newHour == 18 && adjustedTime.getMinute() > 30)) {
+                            adjustedTime = adjustedTime.plusDays(1).withHour(10).withMinute(0);
+                        }
+                    }
+                }
+                currentCompleteTime = adjustedTime;
+                SalesLedgerProcessRouteRecord record = new SalesLedgerProcessRouteRecord();
+                record.setSalesLedgerId(salesLedgerId);
+                record.setSalesLedgerProcessRouteId(bind.getId());
+                record.setIsCompleted(1);
+                record.setCompletedTime(currentCompleteTime);
+                record.setCreateTime(currentCompleteTime);
+                recordList.add(record);
+            }
+            salesLedgerProcessRouteRecordService.saveBatch(recordList);
+        }
     }
 
     private ProcessRoute createImportProcessRoute(String flowKey, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap) {
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index d284be0..4340a52 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -148,6 +148,7 @@
         FROM sales_ledger
         GROUP BY customer_name
     </select>
+
     <select id="listSalesLedgerAndShipped" resultType="com.ruoyi.sales.dto.SalesLedgerDto">
         select distinct sl.id as 'disId', sl.* from
         sales_ledger sl
@@ -157,6 +158,9 @@
         <if test="ew.customerName != null and ew.customerName != '' ">
             and sl.customer_name like concat('%',#{ew.customerName},'%')
         </if>
+        <if test="ew.salesContractNo != null and ew.salesContractNo != '' ">
+            and sl.sales_contract_no like concat('%',#{ew.salesContractNo},'%')
+        </if>
         order by sl.execution_date desc
     </select>
 

--
Gitblit v1.9.3