From a387092945a0fe25ead4809eb1392fcfddfdcf6c Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期三, 22 四月 2026 14:16:06 +0800
Subject: [PATCH] feat(invoiceLedger): 同一销售产品回款两次(一次回款500,一次回款100),客户往来合同金额、应收金额变化了

---
 src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java |  271 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 262 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
index a624661..6ccf2a6 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -27,8 +27,14 @@
 import com.ruoyi.project.system.service.ISysNoticeService;
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
 import com.ruoyi.sales.mapper.CommonFileMapper;
+import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.pojo.CommonFile;
 import com.ruoyi.sales.pojo.ShippingInfo;
 import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
@@ -50,8 +56,12 @@
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 @Service
@@ -80,6 +90,9 @@
     @Autowired
     private  ISysNoticeService sysNoticeService;
 
+    @Autowired
+    private SalesLedgerMapper salesLedgerMapper;
+
     @Override
     public void addApprove(ApproveProcessVO approveProcessVO) throws Exception {
         SysUser sysUser = sysUserMapper.selectUserById(approveProcessVO.getApproveUser());
@@ -107,6 +120,7 @@
         approveProcess.setApproveUserNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(",")));
         approveProcess.setApproveTime(StringUtils.isEmpty(approveProcessVO.getApproveTime()) ? null : dateFormat.parse(approveProcessVO.getApproveTime()));
         approveProcess.setApproveReason(approveProcessVO.getApproveReason());
+        approveProcess.setApproveRemark(approveProcessVO.getApproveRemark());
         approveProcess.setDeviceRepairId(approveProcessVO.getDeviceRepairId());
         approveProcess.setMaintenancePrice(approveProcessVO.getMaintenancePrice());
         approveProcess.setPrice(approveProcessVO.getPrice());
@@ -167,6 +181,12 @@
     @Autowired
     private ShippingInfoMapper shippingInfoMapper;
 
+    @Autowired
+    private SalesLedgerProductMapper salesLedgerProductMapper;
+
+    @Autowired
+    private QualityInspectMapper qualityInspectMapper;
+
     @Override
     public IPage<ApproveProcess> listAll(Page page, ApproveProcess approveProcess) {
         IPage<ApproveProcess> approveProcessIPage = approveProcessMapper.listPage(page, approveProcess);
@@ -191,19 +211,28 @@
 
             //  鍙戣揣瀹℃壒鏌ヨ
             else if (record.getApproveType() == 7) {
-                String reason = record.getApproveReason(); // 鏍煎紡涓� "xx:...-..."
+                String reason = record.getApproveReason(); // 鏍煎紡涓� "xx:CONTRACT_NO"
                 if (StringUtils.hasText(reason) && reason.contains(":")) {
-                    // 鎻愬彇鍐掑彿鍚庨潰鐨勫彂璐у崟鍙�
-                    String shippingNo = reason.split(":")[1];
-                    // 鏍规嵁鍙戣揣鍗曞彿鏌ヨ鍙戣揣鍙拌处璁板綍
-                    ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
-                            .eq(ShippingInfo::getShippingNo, shippingNo)
+                    // 鎻愬彇鍐掑彿鍚庨潰鐨勬爣璇嗙 (鍙兘鏄悎鍚屽彿鎴栧彂璐у崟鍙�)
+                    String identifier = reason.split(":")[1];
+                    // 1. 浼樺厛灏濊瘯鎵鹃攢鍞彴璐� (鏂伴�昏緫锛氬悎鍚屽彿鍚屾瀹℃壒)
+                    SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
+                            .eq(SalesLedger::getSalesContractNo, identifier)
                             .last("limit 1"));
-                    if (shippingInfo != null) {
-                        // 浣跨敤鍙戣揣鍙拌处鐨� 閿�鍞彴璐D 鍘绘煡闄勪欢
+                    if (ledger != null) {
                         allFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
-                                .eq(CommonFile::getCommonId, shippingInfo.getSalesLedgerId())
+                                .eq(CommonFile::getCommonId, ledger.getId())
                                 .eq(CommonFile::getType, FileNameType.SALE.getValue()));
+                    } else {
+                        // 2. 鍥為��鍒版棫閫昏緫锛氬彂璐у崟鍙�
+                        ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
+                                .eq(ShippingInfo::getShippingNo, identifier)
+                                .last("limit 1"));
+                        if (shippingInfo != null) {
+                            allFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
+                                    .eq(CommonFile::getCommonId, shippingInfo.getSalesLedgerId())
+                                    .eq(CommonFile::getType, FileNameType.SALE.getValue()));
+                        }
                     }
                 }
             }
@@ -302,6 +331,228 @@
                 .eq(CommonFile::getCommonId, one.getId())
                 .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue())));
         return one;
+    }
+
+    @Override
+    public Map<String, Object> getStockInOrderInfo(String approveId) {
+        ApproveProcess approveProcess = getStockInApproveProcess(approveId);
+        StockInBusinessContext context = parseStockInContext(approveProcess);
+        if (context == null) {
+            throw new RuntimeException("褰撳墠瀹℃壒鍗曟湭缁戝畾鍏ュ簱涓氬姟鏁版嵁");
+        }
+        Map<String, Object> result = new HashMap<>();
+        result.put("approveId", approveProcess.getApproveId());
+        result.put("approveType", approveProcess.getApproveType());
+        result.put("businessType", context.businessType);
+        if (context.purchaseLedgerId != null) {
+            PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(context.purchaseLedgerId);
+            if (purchaseLedger == null) {
+                throw new RuntimeException("鍏宠仈閲囪喘璁㈠崟涓嶅瓨鍦�");
+            }
+            result.put("orderInfo", purchaseLedger);
+            return result;
+        }
+        if (context.salesLedgerId != null) {
+            SalesLedger salesLedger = salesLedgerMapper.selectById(context.salesLedgerId);
+            if (salesLedger == null) {
+                throw new RuntimeException("鍏宠仈閿�鍞鍗曚笉瀛樺湪");
+            }
+            result.put("orderInfo", salesLedger);
+            return result;
+        }
+        throw new RuntimeException("鏈В鏋愬埌璁㈠崟淇℃伅");
+    }
+
+    @Override
+    public List<?> getStockInProductList(String approveId) {
+        ApproveProcess approveProcess = getStockInApproveProcess(approveId);
+        StockInBusinessContext context = parseStockInContext(approveProcess);
+        if (context == null) {
+            throw new RuntimeException("褰撳墠瀹℃壒鍗曟湭缁戝畾鍏ュ簱浜у搧鏁版嵁");
+        }
+        List<SalesLedgerProduct> matchedProducts;
+        if (context.purchaseLedgerId != null) {
+            matchedProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .eq(SalesLedgerProduct::getSalesLedgerId, context.purchaseLedgerId)
+                    .eq(SalesLedgerProduct::getType, 2)
+                    .orderByAsc(SalesLedgerProduct::getId));
+            return matchedProducts;
+        }
+        if (context.salesLedgerId != null) {
+            LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .eq(SalesLedgerProduct::getSalesLedgerId, context.salesLedgerId)
+                    .eq(SalesLedgerProduct::getType, 1)
+                    .orderByAsc(SalesLedgerProduct::getId);
+            if (!context.productIds.isEmpty()) {
+                wrapper.in(SalesLedgerProduct::getId, context.productIds);
+            }
+            matchedProducts = salesLedgerProductMapper.selectList(wrapper);
+            attachRequestedQty(matchedProducts, context);
+            return matchedProducts;
+        }
+        if (!context.productIds.isEmpty()) {
+            matchedProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .in(SalesLedgerProduct::getId, context.productIds)
+                    .orderByAsc(SalesLedgerProduct::getId));
+            attachRequestedQty(matchedProducts, context);
+            return matchedProducts;
+        }
+        return Collections.emptyList();
+    }
+
+    private ApproveProcess getStockInApproveProcess(String approveId) {
+        if (!StringUtils.hasText(approveId)) {
+            throw new RuntimeException("瀹℃壒缂栧彿涓嶈兘涓虹┖");
+        }
+        ApproveProcess approveProcess = approveProcessMapper.selectOne(new LambdaQueryWrapper<ApproveProcess>()
+                .eq(ApproveProcess::getApproveId, approveId)
+                .eq(ApproveProcess::getApproveDelete, 0)
+                .orderByDesc(ApproveProcess::getCreateTime)
+                .last("limit 1"));
+        if (approveProcess == null) {
+            throw new RuntimeException("瀹℃壒鍗曚笉瀛樺湪");
+        }
+        if (!Objects.equals(approveProcess.getApproveType(), 9)) {
+            throw new RuntimeException("褰撳墠瀹℃壒鍗曚笉鏄叆搴撳鎵�");
+        }
+        return approveProcess;
+    }
+
+    private StockInBusinessContext parseStockInContext(ApproveProcess approveProcess) {
+        if (approveProcess == null) {
+            return null;
+        }
+        String remark = approveProcess.getApproveRemark();
+        if (StringUtils.hasText(remark) && remark.startsWith("qualityQualifiedInbound:")) {
+            String[] split = remark.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "PURCHASE_QUALITY";
+                context.purchaseLedgerId = parseLongSafely(split[2]);
+                return context;
+            }
+        }
+        if (StringUtils.hasText(remark) && remark.startsWith("salesStock:")) {
+            String[] split = remark.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "SALES_STOCK";
+                context.salesLedgerId = parseLongSafely(split[1]);
+                context.productIds = Arrays.stream(split[2].split(","))
+                        .filter(StringUtils::hasText)
+                        .map(this::parseLongSafely)
+                        .filter(Objects::nonNull)
+                        .collect(Collectors.toList());
+                return context;
+            }
+        }
+        if (StringUtils.hasText(remark) && (remark.startsWith("scanQualified:") || remark.startsWith("scanUnqualified:"))) {
+            String[] split = remark.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = remark.startsWith("scanQualified:") ? "SALES_SCAN_QUALIFIED" : "SALES_SCAN_UNQUALIFIED";
+                context.salesLedgerId = parseLongSafely(split[1]);
+                parseProductLineQty(split[2], context);
+                return context;
+            }
+        }
+        String reason = approveProcess.getApproveReason();
+        if (!StringUtils.hasText(reason)) {
+            return null;
+        }
+        if (reason.startsWith("鍘熸潗鏂欒川妫�鍏ュ簱瀹℃壒:")) {
+            String[] split = reason.split(":");
+            if (split.length >= 3) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "PURCHASE_QUALITY";
+                context.purchaseLedgerId = parseLongSafely(split[2]);
+                return context;
+            }
+            if (split.length >= 2) {
+                Long inspectId = parseLongSafely(split[1]);
+                if (inspectId != null) {
+                    QualityInspect inspect = qualityInspectMapper.selectById(inspectId);
+                    if (inspect != null) {
+                        StockInBusinessContext context = new StockInBusinessContext();
+                        context.businessType = "PURCHASE_QUALITY";
+                        context.purchaseLedgerId = inspect.getPurchaseLedgerId();
+                        return context;
+                    }
+                }
+            }
+        }
+        if (reason.startsWith("鍏ュ簱瀹℃壒:")) {
+            String[] split = reason.split(":");
+            if (split.length >= 4) {
+                StockInBusinessContext context = new StockInBusinessContext();
+                context.businessType = "SALES_STOCK";
+                context.salesLedgerId = parseLongSafely(split[2]);
+                context.productIds = Arrays.stream(split[3].split(","))
+                        .filter(StringUtils::hasText)
+                        .map(this::parseLongSafely)
+                        .filter(Objects::nonNull)
+                        .collect(Collectors.toList());
+                return context;
+            }
+        }
+        return null;
+    }
+
+    private void parseProductLineQty(String lines, StockInBusinessContext context) {
+        if (!StringUtils.hasText(lines) || context == null) {
+            return;
+        }
+        String[] items = lines.split(",");
+        for (String item : items) {
+            if (!StringUtils.hasText(item)) {
+                continue;
+            }
+            String[] pair = item.split("@");
+            Long lineId = parseLongSafely(pair[0]);
+            if (lineId == null) {
+                continue;
+            }
+            context.productIds.add(lineId);
+            if (pair.length >= 2 && StringUtils.hasText(pair[1])) {
+                context.requestedQtyByProductId.put(lineId, pair[1]);
+            }
+        }
+    }
+
+    private void attachRequestedQty(List<SalesLedgerProduct> products, StockInBusinessContext context) {
+        if (products == null || products.isEmpty() || context == null || context.requestedQtyByProductId.isEmpty()) {
+            return;
+        }
+        for (SalesLedgerProduct product : products) {
+            if (product == null || product.getId() == null) {
+                continue;
+            }
+            String requestedQty = context.requestedQtyByProductId.get(product.getId());
+            if (requestedQty != null) {
+                product.setRemark(StringUtils.hasText(product.getRemark())
+                        ? product.getRemark() + "锛涘鎵圭敵璇锋暟閲�:" + requestedQty
+                        : "瀹℃壒鐢宠鏁伴噺:" + requestedQty);
+            }
+        }
+    }
+
+    private Long parseLongSafely(String value) {
+        if (!StringUtils.hasText(value)) {
+            return null;
+        }
+        try {
+            return Long.valueOf(value);
+        } catch (Exception ignored) {
+            return null;
+        }
+    }
+
+    private static class StockInBusinessContext {
+        private String businessType;
+        private Long purchaseLedgerId;
+        private Long salesLedgerId;
+        private List<Long> productIds = new ArrayList<>();
+        private final Map<Long, String> requestedQtyByProductId = new HashMap<>();
     }
 
     @Autowired
@@ -441,6 +692,8 @@
                 return "鍙戣揣瀹℃壒";
             case 8:
                 return "鍗遍櫓浣滀笟瀹℃壒";
+            case 9:
+                return "鍏ュ簱瀹℃壒";
         }
         return null;
     }

--
Gitblit v1.9.3