From 4635770544e2d57416ad88a8983ee293919f5fec Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期一, 25 五月 2026 09:25:36 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New_pro' into dev_New_pro

---
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java |  537 ++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 271 insertions(+), 266 deletions(-)

diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index 4f4931a..d3c21a2 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3,8 +3,20 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
-import com.ruoyi.account.mapper.AccountIncomeMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.account.bean.dto.purchase.PurchaseInboundDto;
+import com.ruoyi.account.bean.dto.purchase.PurchaseReturnDto;
+import com.ruoyi.account.bean.dto.sales.SalesOutboundDto;
+import com.ruoyi.account.bean.dto.sales.SalesReturnDto;
+import com.ruoyi.account.bean.vo.purchase.PurchaseInboundVo;
+import com.ruoyi.account.bean.vo.purchase.PurchaseReturnVo;
+import com.ruoyi.account.bean.vo.sales.SalesOutboundVo;
+import com.ruoyi.account.bean.vo.sales.SalesReturnVo;
+import com.ruoyi.account.mapper.AccountStatementMapper;
 import com.ruoyi.account.mapper.purchase.AccountPurchasePaymentMapper;
+import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper;
+import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
+import com.ruoyi.account.pojo.sales.AccountSalesCollection;
 import com.ruoyi.approve.mapper.ApproveProcessMapper;
 import com.ruoyi.approve.pojo.ApproveProcess;
 import com.ruoyi.basic.mapper.CustomerMapper;
@@ -25,27 +37,27 @@
 import com.ruoyi.home.dto.*;
 import com.ruoyi.home.mapper.HomeMapper;
 import com.ruoyi.home.service.HomeService;
+import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
 import com.ruoyi.production.bean.dto.ProductionProductOutputDto;
 import com.ruoyi.production.mapper.*;
 import com.ruoyi.project.system.domain.SysDept;
 import com.ruoyi.project.system.mapper.SysDeptMapper;
-import com.ruoyi.purchase.mapper.PaymentRegistrationMapper;
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
-import com.ruoyi.purchase.pojo.PaymentRegistration;
+import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
 import com.ruoyi.quality.pojo.QualityInspect;
 import com.ruoyi.quality.pojo.QualityUnqualified;
-import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
 import com.ruoyi.sales.mapper.SalesLedgerMapper;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
-import com.ruoyi.sales.pojo.ReceiptPayment;
 import com.ruoyi.sales.pojo.SalesLedger;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.staff.mapper.StaffOnJobMapper;
 import com.ruoyi.staff.pojo.StaffOnJob;
+import com.ruoyi.stock.mapper.StockInRecordMapper;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -71,6 +83,10 @@
 public class HomeServiceImpl implements HomeService {
 
     private final SalesLedgerMapper salesLedgerMapper;
+    private final StockOutRecordMapper stockOutRecordMapper;
+    private final ReturnManagementMapper returnManagementMapper;
+    private final StockInRecordMapper stockInRecordMapper;
+    private final PurchaseReturnOrdersMapper purchaseReturnOrdersMapper;
 
     private final PurchaseLedgerMapper purchaseLedgerMapper;
 
@@ -81,10 +97,6 @@
     private final QualityInspectMapper qualityStatisticsMapper;
 
     private final ApproveProcessMapper approveProcessMapper;
-
-    private final ReceiptPaymentMapper receiptPaymentMapper;
-
-    private final PaymentRegistrationMapper paymentRegistrationMapper;
 
     private final SysDeptMapper sysDeptMapper;
 
@@ -111,7 +123,8 @@
     private final ProductionOperationTaskMapper productionOperationTaskMapper;
 
     private final AccountPurchasePaymentMapper accountPurchasePaymentMapper;
-    private final AccountIncomeMapper accountIncomeMapper;
+    private final AccountSalesCollectionMapper accountSalesCollectionMapper;
+    private final AccountStatementMapper accountStatementMapper;
 
     private final ProductionAccountMapper productionAccountMapper;
 
@@ -139,12 +152,8 @@
                             salesLedgers.stream().map(SalesLedger::getId).collect(Collectors.toList()));
             List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper
                     .selectList(salesLedgerProductMapperLambdaQueryWrapper);
-            // 鏈紑绁ㄩ噾棰�
-            BigDecimal noInvoiceAmountTotal = salesLedgerProducts.stream().map(SalesLedgerProduct::getNoInvoiceAmount)
-                    .filter(Objects::nonNull)
-                    .reduce(BigDecimal.ZERO, BigDecimal::add);
             homeBusinessDto.setMonthSaleMoney(contractAmount.setScale(2, RoundingMode.HALF_UP).toString());
-            homeBusinessDto.setMonthSaleHaveMoney(noInvoiceAmountTotal.setScale(2, RoundingMode.HALF_UP).toString());
+            homeBusinessDto.setMonthSaleHaveMoney(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString());
         }
         // 鍒涘缓LambdaQueryWrapper
         LambdaQueryWrapper<PurchaseLedger> queryWrapper = new LambdaQueryWrapper<>();
@@ -167,14 +176,8 @@
                     .filter(Objects::nonNull)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
 
-            //  寰呬粯娆炬�婚噾棰�
-            BigDecimal unReceiptPaymentAmount = salesLedgerProductsCopy.stream()
-                    .map(SalesLedgerProduct::getPendingTicketsTotal)
-                    .filter(Objects::nonNull)
-                    .reduce(BigDecimal.ZERO, BigDecimal::add);
-
             homeBusinessDto.setMonthPurchaseMoney(receiveAmount.setScale(2, RoundingMode.HALF_UP).toString());
-            homeBusinessDto.setMonthPurchaseHaveMoney(unReceiptPaymentAmount.setScale(2, RoundingMode.HALF_UP).toString());
+            homeBusinessDto.setMonthPurchaseHaveMoney(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString());
         }
         // 缁熻搴撳瓨
         BigDecimal stockQuantityTotal = stockInventoryMapper.selectTotal();
@@ -310,19 +313,35 @@
             queryWrapper.ge(QualityInspect::getCheckTime, monthStart.toString())
                     .le(QualityInspect::getCheckTime, monthEnd.toString());
             List<QualityInspect> monthInspects = qualityStatisticsMapper.selectList(queryWrapper);
+
+            // 缁熻鎬绘暟閲忥紙鍚堟牸鏁伴噺 + 涓嶅悎鏍兼暟閲忥級
             BigDecimal reduce = monthInspects.stream()
                     .filter(inspect -> inspect.getInspectType().equals(0))
-                    .map(QualityInspect::getQuantity)
+                    .map(inspect -> {
+                        BigDecimal qualified = inspect.getQualifiedQuantity() != null ? inspect.getQualifiedQuantity() : BigDecimal.ZERO;
+                        BigDecimal unqualified = inspect.getUnqualifiedQuantity() != null ? inspect.getUnqualifiedQuantity() : BigDecimal.ZERO;
+                        return qualified.add(unqualified);
+                    })
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             supplierNum = supplierNum.add(reduce);
+
             BigDecimal reduce1 = monthInspects.stream()
                     .filter(inspect -> inspect.getInspectType().equals(1))
-                    .map(QualityInspect::getQuantity)
+                    .map(inspect -> {
+                        BigDecimal qualified = inspect.getQualifiedQuantity() != null ? inspect.getQualifiedQuantity() : BigDecimal.ZERO;
+                        BigDecimal unqualified = inspect.getUnqualifiedQuantity() != null ? inspect.getUnqualifiedQuantity() : BigDecimal.ZERO;
+                        return qualified.add(unqualified);
+                    })
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             processNum = processNum.add(reduce1);
+
             BigDecimal reduce2 = monthInspects.stream()
                     .filter(inspect -> inspect.getInspectType().equals(2))
-                    .map(QualityInspect::getQuantity)
+                    .map(inspect -> {
+                        BigDecimal qualified = inspect.getQualifiedQuantity() != null ? inspect.getQualifiedQuantity() : BigDecimal.ZERO;
+                        BigDecimal unqualified = inspect.getUnqualifiedQuantity() != null ? inspect.getUnqualifiedQuantity() : BigDecimal.ZERO;
+                        return qualified.add(unqualified);
+                    })
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             factoryNum = factoryNum.add(reduce2);
 
@@ -332,25 +351,22 @@
 
             // 1. 渚涘簲鍟嗘楠岋紙绫诲瀷0锛�- 鍚堟牸鏁伴噺
             BigDecimal supplierQualified = monthInspects.stream()
-                    .filter(inspect -> inspect.getInspectType().equals(0)
-                            && "鍚堟牸".equals(inspect.getCheckResult()))
-                    .map(QualityInspect::getQuantity)
+                    .filter(inspect -> inspect.getInspectType().equals(0))
+                    .map(inspect -> inspect.getQualifiedQuantity() != null ? inspect.getQualifiedQuantity() : BigDecimal.ZERO)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             item.setSupplierNum(supplierQualified);
 
             // 2. 宸ュ簭妫�楠岋紙绫诲瀷1锛�- 鍚堟牸鏁伴噺
             BigDecimal processQualified = monthInspects.stream()
-                    .filter(inspect -> inspect.getInspectType().equals(1)
-                            && "鍚堟牸".equals(inspect.getCheckResult()))
-                    .map(QualityInspect::getQuantity)
+                    .filter(inspect -> inspect.getInspectType().equals(1))
+                    .map(inspect -> inspect.getQualifiedQuantity() != null ? inspect.getQualifiedQuantity() : BigDecimal.ZERO)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             item.setProcessNum(processQualified);
 
             // 3. 宸ュ巶妫�楠岋紙绫诲瀷2锛�- 鍚堟牸鏁伴噺
             BigDecimal factoryQualified = monthInspects.stream()
-                    .filter(inspect -> inspect.getInspectType().equals(2)
-                            && "鍚堟牸".equals(inspect.getCheckResult()))
-                    .map(QualityInspect::getQuantity)
+                    .filter(inspect -> inspect.getInspectType().equals(2))
+                    .map(inspect -> inspect.getQualifiedQuantity() != null ? inspect.getQualifiedQuantity() : BigDecimal.ZERO)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             item.setFactoryNum(factoryQualified);
 
@@ -412,76 +428,33 @@
      */
     @Override
     public StatisticsReceivablePayableDto statisticsReceivablePayable(Integer type) {
-        LocalDate today = LocalDate.now();
-        LocalDate startDate = null;
-        LocalDate endDate = null;
-        switch (type) {
-            case 1:
-                // 鑾峰彇鏈懆鍛ㄤ竴
-                startDate = today.with(DayOfWeek.MONDAY);
-                // 鑾峰彇鏈懆鍛ㄦ棩
-                endDate = today.with(DayOfWeek.SUNDAY);
-                break;
-            case 2:
-                startDate = today.with(TemporalAdjusters.firstDayOfMonth());
-                endDate = today.with(TemporalAdjusters.lastDayOfMonth());
-                break;
-            case 3:
-                Month currentMonth = today.getMonth();
-                Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
-                Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
+        StatisticsReceivablePayableDto dto = new StatisticsReceivablePayableDto();
+        LocalDate[] range = resolveFinanceRange(type);
+        LocalDate startDate = range[0];
+        LocalDate endDate = range[1];
 
-                startDate = today.withMonth(firstMonthOfQuarter.getValue())
-                        .with(TemporalAdjusters.firstDayOfMonth());
-                endDate = today.withMonth(lastMonthOfQuarter.getValue())
-                        .with(TemporalAdjusters.lastDayOfMonth());
-                break;
-        }
-        // 搴旀敹
-        List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>()
-                // .ge(SalesLedger::getEntryDate, startDate)
-                // .lt(SalesLedger::getEntryDate, endDate)
-        );
-        // BigDecimal receivableMoney =
-        // salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO,
-        // BigDecimal::add);
-        BigDecimal receivableMoney = sumAmount(salesLedgers, SalesLedger::getContractAmount);
-        // 搴斾粯
-        List<PurchaseLedger> procurementRecords = purchaseLedgerMapper
-                .selectList(new LambdaQueryWrapper<PurchaseLedger>()
-                        // .ge(PurchaseLedger::getEntryDate, startDate)
-                        // .lt(PurchaseLedger::getEntryDate, endDate)
-                );
-        // BigDecimal payableMoney =
-        // procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO,
-        // BigDecimal::add);
-        BigDecimal payableMoney = sumAmount(procurementRecords, PurchaseLedger::getContractAmount);
-        // 棰勬敹
-        List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
-                // .ge(ReceiptPayment::getReceiptPaymentDate, startDate)
-                // .lt(ReceiptPayment::getReceiptPaymentDate, endDate)
-        );
-        // BigDecimal advanceMoney =
-        // receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO,
-        // BigDecimal::add);
-        BigDecimal advanceMoney = sumAmount(receiptPayments, ReceiptPayment::getReceiptPaymentAmount);
-        // 棰勪粯
-        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper
-                .selectList(new LambdaQueryWrapper<PaymentRegistration>()
-                        // .ge(PaymentRegistration::getPaymentDate, startDate)
-                        // .lt(PaymentRegistration::getPaymentDate, endDate)
-                );
-        // BigDecimal prepayMoney =
-        // paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO,
-        // BigDecimal::add);
-        BigDecimal prepayMoney = sumAmount(paymentRegistrations, PaymentRegistration::getCurrentPaymentAmount);
-        StatisticsReceivablePayableDto statisticsReceivablePayableDto = new StatisticsReceivablePayableDto();
-        statisticsReceivablePayableDto.setPayableMoney(payableMoney.subtract(prepayMoney));
-        statisticsReceivablePayableDto.setReceivableMoney(receivableMoney.subtract(advanceMoney));
-        statisticsReceivablePayableDto.setAdvanceMoney(advanceMoney);
-        statisticsReceivablePayableDto.setPrepayMoney(prepayMoney);
+        //閿�鍞嚭搴�
+        BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate);
+        //閿�鍞��璐�
+        BigDecimal salesReturnAmount = sumSalesReturnAmount(startDate, endDate);
+        //閲囪喘鍏ュ簱
+        BigDecimal payableBase = sumPurchaseContractAmount(startDate, endDate);
+        //閲囪喘閫�璐�
+        BigDecimal purchaseReturnAmount = sumPurchaseReturnAmount(startDate, endDate);
+        //鏀舵
+        BigDecimal advanceMoney = sumCollectionAmount(startDate, endDate);
+        //浠樻
+        BigDecimal prepayMoney = sumPaymentAmount(startDate, endDate);
 
-        return statisticsReceivablePayableDto;
+        //搴旀敹閲戦=閿�鍞嚭搴�-閿�鍞��璐�
+        dto.setReceivableMoney(scaleMoney(maxZero(receivableBase.subtract(salesReturnAmount))));
+        //搴斾粯閲戦=閲囪喘鍏ュ簱-閲囪喘閫�璐�
+        dto.setPayableMoney(scaleMoney(maxZero(payableBase.subtract(purchaseReturnAmount))));
+        //鏀舵閲戦=鏀舵鍗�
+        dto.setAdvanceMoney(scaleMoney(advanceMoney));
+        //浠樻閲戦=浠樻鍗�
+        dto.setPrepayMoney(scaleMoney(prepayMoney));
+        return dto;
     }
 
     public static <T> BigDecimal sumAmount(List<T> list, java.util.function.Function<T, BigDecimal> amountExtractor) {
@@ -1162,7 +1135,7 @@
         String endStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 
         // 2. 鏌ヨ鏁版嵁
-        List<IncomeExpenseAnalysisDto> incomeList = accountIncomeMapper.selectIncomeStats(startStr, endStr, dateFormat);
+        List<IncomeExpenseAnalysisDto> incomeList = accountSalesCollectionMapper.selectIncomeStats(startStr, endStr, dateFormat);
         List<IncomeExpenseAnalysisDto> expenseList = accountPurchasePaymentMapper.selectPayment(startStr, endStr, dateFormat);
 
 
@@ -1219,7 +1192,7 @@
         String startStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         String endStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 
-        List<IncomeExpenseAnalysisDto> incomeList = accountIncomeMapper.selectIncomeStats(startStr, endStr, dateFormat);
+        List<IncomeExpenseAnalysisDto> incomeList = accountSalesCollectionMapper.selectIncomeStats(startStr, endStr, dateFormat);
         List<IncomeExpenseAnalysisDto> expenseList = accountPurchasePaymentMapper.selectPayment(startStr, endStr, dateFormat);
 
         Map<String, BigDecimal> incomeMap = incomeList.stream().collect(Collectors
@@ -1290,145 +1263,55 @@
     @Override
     public MonthlyIncomeDto monthlyIncome() {
         MonthlyIncomeDto dto = new MonthlyIncomeDto();
-        LocalDate now = LocalDate.now();
-        YearMonth currentMonth = YearMonth.from(now);
-        LocalDateTime startOfMonth = currentMonth.atDay(1).atStartOfDay();
-        LocalDateTime endOfMonth = currentMonth.atEndOfMonth().atTime(23, 59, 59);
-
-        LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(SalesLedgerProduct::getType, 1);
-        wrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
-        wrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
-
-        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(wrapper);
-
-        if (CollectionUtils.isEmpty(products)) {
-            return dto;
-        }
-
-        BigDecimal collected = products.stream()
-                .map(SalesLedgerProduct::getInvoiceTotal)
-                .filter(Objects::nonNull)
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-        dto.setMonthlyIncome(collected);
-
-        BigDecimal overdue = products.stream()
-                .map(SalesLedgerProduct::getPendingInvoiceTotal)
-                .filter(Objects::nonNull)
-                .reduce(BigDecimal.ZERO, BigDecimal::add);
-        dto.setOverdueNum(overdue);
-
-        BigDecimal total = collected.add(overdue);
-
-        if (total.compareTo(BigDecimal.ZERO) > 0) {
-            String collectionRate = collected.divide(total, 4, RoundingMode.HALF_UP)
-                    .multiply(new BigDecimal("100"))
-                    .setScale(2, RoundingMode.HALF_UP)
-                    .toString();
-            dto.setCollectionRate(collectionRate);
-
-            String overdueRate = overdue.divide(total, 4, RoundingMode.HALF_UP)
-                    .multiply(new BigDecimal("100"))
-                    .setScale(2, RoundingMode.HALF_UP)
-                    .toString();
-            dto.setOverdueRate(overdueRate);
-        }
-
+        LocalDate today = LocalDate.now();
+        YearMonth currentMonth = YearMonth.from(today);
+        LocalDate startDate = currentMonth.atDay(1);
+        LocalDate endDate = currentMonth.atEndOfMonth();
+        //鏀舵
+        BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate);
+        //閿�鍞嚭搴�
+        BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate);
+        //閿�鍞��璐�
+        BigDecimal salesReturnAmount = sumSalesReturnAmount(startDate, endDate);
+        //鍥炴鐜�=鏀舵/(閿�鍞嚭搴�-閿�鍞��璐�)搴旀敹
+        String collectionRate = toRateString(monthlyIncome, receivableBase.subtract(salesReturnAmount));
+        //閫炬湡鏁�=(閿�鍞嚭搴撻噾棰�-閿�鍞��璐ч噾棰�)搴旀敹閲戦-鏀舵閲戦
+        BigDecimal overdueAmount = receivableBase.subtract(salesReturnAmount).subtract(monthlyIncome);
+        //閫炬湡鐜�=閫炬湡鏁�/搴旀敹閲戦
+        String overdueRate = toRateString(overdueAmount, receivableBase);
+        dto.setMonthlyIncome(scaleMoney(monthlyIncome));
+        dto.setCollectionRate(collectionRate);
+        dto.setOverdueNum(overdueAmount);
+        dto.setOverdueRate(overdueRate);
         return dto;
     }
 
+    @Override
     public MonthlyExpenditureDto monthlyExpenditure() {
-
         MonthlyExpenditureDto dto = new MonthlyExpenditureDto();
+        LocalDate today = LocalDate.now();
+        YearMonth currentMonth = YearMonth.from(today);
+        LocalDate startDate = currentMonth.atDay(1);
+        LocalDate endDate = currentMonth.atEndOfMonth();
+        //鏀嚭
+        BigDecimal monthlyExpenditure = sumPaymentAmount(startDate, endDate);
+        //閲囪喘鍏ュ簱
+        BigDecimal payableBase = sumPurchaseContractAmount(startDate, endDate);
+        //閲囪喘閫�璐�
+        BigDecimal purchaseReturnAmount = sumPurchaseReturnAmount(startDate, endDate);
+        //浠樻鐜�=浠樻/(閲囪喘鍏ュ簱-閲囪喘閫�璐�)搴斾粯
+        String paymentRate = toRateString(monthlyExpenditure, payableBase.subtract(purchaseReturnAmount));
+        //鏀舵
+        BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate);
+        //姣涘埄娑�= 鏀舵-鏀嚭
+        BigDecimal grossProfit = monthlyIncome.subtract(monthlyExpenditure);
+        //鍒╂鼎鐜�=姣涘埄娑�/鏀舵
+        String profitMarginRate = toRateString(grossProfit, monthlyIncome);
 
-        // 褰撴湀鏃堕棿鑼冨洿
-        LocalDate now = LocalDate.now();
-        YearMonth currentMonth = YearMonth.from(now);
-        LocalDateTime startOfMonth = currentMonth.atDay(1).atStartOfDay();
-        LocalDateTime endOfMonth = currentMonth.atEndOfMonth().atTime(23, 59, 59);
-
-        // 閲囪喘鍙拌处锛坱ype = 2锛�
-        LambdaQueryWrapper<SalesLedgerProduct> purchaseWrapper = new LambdaQueryWrapper<>();
-        purchaseWrapper.eq(SalesLedgerProduct::getType, 2);
-        purchaseWrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
-        purchaseWrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
-
-        List<SalesLedgerProduct> purchaseProducts = salesLedgerProductMapper.selectList(purchaseWrapper);
-
-        BigDecimal rawMaterialCost = BigDecimal.ZERO; // 鍘熸潗鏂欐垚鏈�
-        BigDecimal paidAmount = BigDecimal.ZERO; // 宸蹭粯娆鹃噾棰�
-        BigDecimal pendingAmount = BigDecimal.ZERO; // 寰呬粯娆鹃噾棰�
-
-        if (!CollectionUtils.isEmpty(purchaseProducts)) {
-            for (SalesLedgerProduct p : purchaseProducts) {
-
-                if (p.getTaxInclusiveTotalPrice() != null) {
-                    rawMaterialCost = rawMaterialCost.add(p.getTaxInclusiveTotalPrice());
-                }
-
-                if (p.getTicketsTotal() != null) {
-                    paidAmount = paidAmount.add(p.getTicketsTotal());
-                }
-
-                if (p.getPendingTicketsTotal() != null) {
-                    pendingAmount = pendingAmount.add(p.getPendingTicketsTotal());
-                }
-            }
-        }
-
-        // 鍏朵粬璐圭敤
-
-
-        // 鏈堝害鎬绘敮鍑�
-        BigDecimal monthlyExpenditure = BigDecimal.ZERO;
-        dto.setMonthlyExpenditure(monthlyExpenditure);
-
-        // 宸蹭粯娆� 梅锛堝凡浠樻 + 寰呬粯娆撅級
-        BigDecimal totalPayable = paidAmount.add(pendingAmount);
-        if (totalPayable.compareTo(BigDecimal.ZERO) > 0) {
-            String paymentRate = paidAmount
-                    .divide(totalPayable, 4, RoundingMode.HALF_UP)
-                    .multiply(BigDecimal.valueOf(100))
-                    .setScale(2, RoundingMode.HALF_UP)
-                    .toString();
-            dto.setPaymentRate(paymentRate);
-        }
-
-        // 鍞彴璐︼紙type = 1锛�
-        LambdaQueryWrapper<SalesLedgerProduct> salesWrapper = new LambdaQueryWrapper<>();
-        salesWrapper.eq(SalesLedgerProduct::getType, 1);
-        salesWrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
-        salesWrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
-
-        List<SalesLedgerProduct> salesProducts = salesLedgerProductMapper.selectList(salesWrapper);
-
-        BigDecimal revenue = BigDecimal.ZERO;
-        if (!CollectionUtils.isEmpty(salesProducts)) {
-            for (SalesLedgerProduct s : salesProducts) {
-                if (s.getInvoiceAmount() != null) {
-                    revenue = revenue.add(s.getInvoiceAmount());
-                }
-            }
-        }
-
-        // 姣涘埄娑� & 鍒╂鼎鐜�
-        if (revenue.compareTo(BigDecimal.ZERO) > 0) {
-
-            // 姣涘埄娑� = 閿�鍞敹鍏� - 鍘熸潗鏂欐垚鏈�
-            BigDecimal grossProfit = revenue.subtract(rawMaterialCost);
-            dto.setGrossProfit(grossProfit);
-
-            // 鍒╂鼎鐜� = (閿�鍞敹鍏� - 鏈堝害鎬绘敮鍑�) / 閿�鍞敹鍏�
-            BigDecimal profit = revenue.subtract(monthlyExpenditure);
-            String profitMarginRate = profit
-                    .divide(revenue, 4, RoundingMode.HALF_UP)
-                    .multiply(BigDecimal.valueOf(100))
-                    .setScale(2, RoundingMode.HALF_UP)
-                    .toString();
-
-            dto.setProfitMarginRate(profitMarginRate);
-        }
-
+        dto.setMonthlyExpenditure(scaleMoney(monthlyExpenditure));
+        dto.setPaymentRate(paymentRate);
+        dto.setGrossProfit(scaleMoney(grossProfit));
+        dto.setProfitMarginRate(profitMarginRate);
         return dto;
     }
 
@@ -1867,11 +1750,8 @@
         BigDecimal unqualifiedCount = BigDecimal.ZERO;
 
         for (QualityInspect item : list) {
-            if ("鍚堟牸".equals(item.getCheckResult())) {
-                qualifiedCount = qualifiedCount.add(item.getQuantity());
-            } else {
-                unqualifiedCount = unqualifiedCount.add(item.getQuantity());
-            }
+            qualifiedCount = qualifiedCount.add(item.getQualifiedQuantity() != null ? item.getQualifiedQuantity() : BigDecimal.ZERO);
+            unqualifiedCount = unqualifiedCount.add(item.getUnqualifiedQuantity() != null ? item.getUnqualifiedQuantity() : BigDecimal.ZERO);
         }
 
         BigDecimal totalCount = qualifiedCount.add(unqualifiedCount);
@@ -2140,13 +2020,11 @@
                 continue;
             }
 
-            BigDecimal quantity = item.getQuantity();
+            BigDecimal qualifiedQty = item.getQualifiedQuantity() != null ? item.getQualifiedQuantity() : BigDecimal.ZERO;
+            BigDecimal unqualifiedQty = item.getUnqualifiedQuantity() != null ? item.getUnqualifiedQuantity() : BigDecimal.ZERO;
 
-            if ("鍚堟牸".equals(item.getCheckResult())) {
-                dto.setQualifiedCount(dto.getQualifiedCount().add(quantity));
-            } else {
-                dto.setUnqualifiedCount(dto.getUnqualifiedCount().add(quantity));
-            }
+            dto.setQualifiedCount(dto.getQualifiedCount().add(qualifiedQty));
+            dto.setUnqualifiedCount(dto.getUnqualifiedCount().add(unqualifiedQty));
         }
 
         // 璁$畻鍚堟牸鐜�
@@ -2187,14 +2065,12 @@
             BigDecimal unqualifiedCount = BigDecimal.ZERO;
 
             for (QualityInspect item : items) {
-                BigDecimal qty = item.getQuantity();
-                totalCount = totalCount.add(qty);
+                BigDecimal qualifiedQty = item.getQualifiedQuantity() != null ? item.getQualifiedQuantity() : BigDecimal.ZERO;
+                BigDecimal unqualifiedQty = item.getUnqualifiedQuantity() != null ? item.getUnqualifiedQuantity() : BigDecimal.ZERO;
 
-                if ("鍚堟牸".equals(item.getCheckResult())) {
-                    qualifiedCount = qualifiedCount.add(qty);
-                } else {
-                    unqualifiedCount = unqualifiedCount.add(qty);
-                }
+                totalCount = totalCount.add(qualifiedQty.add(unqualifiedQty));
+                qualifiedCount = qualifiedCount.add(qualifiedQty);
+                unqualifiedCount = unqualifiedCount.add(unqualifiedQty);
             }
 
             if (totalCount.compareTo(BigDecimal.ZERO) == 0) {
@@ -2323,13 +2199,17 @@
         dto.setProcessNum(sumQuantity(qualityInspectList, 1)); // 杩囩▼
         dto.setFactoryNum(sumQuantity(qualityInspectList, 2)); // 鍑哄巶
 
-        // 鍋囪 qualityInspectList 鏄竴涓� List<QualityInspect> 绫诲瀷鐨勯泦鍚�
-        Map<String, List<QualityInspect>> groupedByCheckResult = qualityInspectList.stream()
-                .collect(Collectors.groupingBy(QualityInspect::getCheckResult));
-        List<QualityInspect> qualityInspects = groupedByCheckResult.get("涓嶅悎鏍�");
-        if (ObjectUtils.isNull(qualityInspects) || qualityInspects.size() == 0) {
-            return null;
+        // 鏍规嵁 unqualifiedQuantity > 0 绛涢�変笉鍚堟牸璁板綍
+        List<QualityInspect> qualityInspects = qualityInspectList.stream()
+                .filter(i -> i.getUnqualifiedQuantity() != null && i.getUnqualifiedQuantity().compareTo(BigDecimal.ZERO) > 0)
+                .collect(Collectors.toList());
+
+        if (ObjectUtils.isEmpty(qualityInspects)) {
+            // 鍗充娇娌℃湁涓嶅悎鏍艰褰曪紝涔熷簲璇ヨ繑鍥炵粺璁℃暟鎹紝鍙槸鍥捐〃椤逛负绌�
+            dto.setItem(new ArrayList<>());
+            return dto;
         }
+
         // 4. 澶勭悊鍥捐〃椤� (Item)
         List<QualityStatisticsItem> itemList = new ArrayList<>();
 
@@ -2372,8 +2252,11 @@
     private BigDecimal sumQuantity(List<QualityInspect> list, Integer type) {
         return list.stream()
                 .filter(i -> i.getInspectType().equals(type))
-                .map(QualityInspect::getQuantity)
-                .filter(Objects::nonNull)
+                .map(i -> {
+                    BigDecimal qualified = i.getQualifiedQuantity() != null ? i.getQualifiedQuantity() : BigDecimal.ZERO;
+                    BigDecimal unqualified = i.getUnqualifiedQuantity() != null ? i.getUnqualifiedQuantity() : BigDecimal.ZERO;
+                    return qualified.add(unqualified);
+                })
                 .reduce(BigDecimal.ZERO, BigDecimal::add);
     }
 
@@ -2381,11 +2264,18 @@
         QualityStatisticsItem item = new QualityStatisticsItem();
         item.setDate(dateLabel);
 
-        item.setSupplierNum(list.stream().filter(i -> i.getInspectType() == 0).map(QualityInspect::getQuantity)
+        // 缁熻姣忕妫�楠岀被鍨嬬殑涓嶅悎鏍兼暟閲�
+        item.setSupplierNum(list.stream()
+                .filter(i -> i.getInspectType() == 0)
+                .map(i -> i.getUnqualifiedQuantity() != null ? i.getUnqualifiedQuantity() : BigDecimal.ZERO)
                 .reduce(BigDecimal.ZERO, BigDecimal::add));
-        item.setProcessNum(list.stream().filter(i -> i.getInspectType() == 1).map(QualityInspect::getQuantity)
+        item.setProcessNum(list.stream()
+                .filter(i -> i.getInspectType() == 1)
+                .map(i -> i.getUnqualifiedQuantity() != null ? i.getUnqualifiedQuantity() : BigDecimal.ZERO)
                 .reduce(BigDecimal.ZERO, BigDecimal::add));
-        item.setFactoryNum(list.stream().filter(i -> i.getInspectType() == 2).map(QualityInspect::getQuantity)
+        item.setFactoryNum(list.stream()
+                .filter(i -> i.getInspectType() == 2)
+                .map(i -> i.getUnqualifiedQuantity() != null ? i.getUnqualifiedQuantity() : BigDecimal.ZERO)
                 .reduce(BigDecimal.ZERO, BigDecimal::add));
 
         return item;
@@ -2425,6 +2315,121 @@
         return productionOperationTaskMapper.calculateProductionStatistics(startDateTime, endDateTime, userId, processIds);
     }
 
+    private LocalDate[] resolveFinanceRange(Integer type) {
+        LocalDate today = LocalDate.now();
+        int safeType = type == null ? 1 : type;
+        LocalDate startDate;
+        LocalDate endDate;
+        switch (safeType) {
+            case 1:
+                startDate = today.with(DayOfWeek.MONDAY);
+                endDate = today.with(DayOfWeek.SUNDAY);
+                break;
+            case 2:
+                startDate = today.with(TemporalAdjusters.firstDayOfMonth());
+                endDate = today.with(TemporalAdjusters.lastDayOfMonth());
+                break;
+            case 3:
+                Month firstMonthOfQuarter = today.getMonth().firstMonthOfQuarter();
+                startDate = LocalDate.of(today.getYear(), firstMonthOfQuarter, 1);
+                endDate = startDate.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
+                break;
+            default:
+                startDate = today.with(DayOfWeek.MONDAY);
+                endDate = today.with(DayOfWeek.SUNDAY);
+                break;
+        }
+        return new LocalDate[]{startDate, endDate};
+    }
+
+    //璁$畻鏃ユ湡鍐呯殑閿�鍞嚭搴撻噾棰�
+    private BigDecimal sumSalesContractAmount(LocalDate startDate, LocalDate endDate) {
+        SalesOutboundDto salesOutboundDto = new SalesOutboundDto();
+        salesOutboundDto.setStartDate(startDate);
+        salesOutboundDto.setEndDate(endDate);
+        List<SalesOutboundVo> salesOutboundVos = stockOutRecordMapper.listPageAccountSales(new Page(1, -1), salesOutboundDto).getRecords();
+        return sumAmount(salesOutboundVos, SalesOutboundVo::getOutboundAmount);
+    }
+
+    //璁$畻鏃ユ湡鍐呯殑閿�鍞��璐ч噾棰�
+    private BigDecimal sumSalesReturnAmount(LocalDate startDate, LocalDate endDate) {
+        SalesReturnDto salesReturnDto = new SalesReturnDto();
+        salesReturnDto.setStartDate(startDate);
+        salesReturnDto.setEndDate(endDate);
+        List<SalesReturnVo> salesReturnVos = returnManagementMapper.listPageAccountSalesReturn(new Page(1, -1), salesReturnDto).getRecords();
+        return sumAmount(salesReturnVos, SalesReturnVo::getRefundAmount);
+    }
+
+    //璁$畻鏃ユ湡鍐呯殑閲囪喘鍏ュ簱閲戦
+    private BigDecimal sumPurchaseContractAmount(LocalDate startDate, LocalDate endDate) {
+        PurchaseInboundDto purchaseInboundDto = new PurchaseInboundDto();
+        purchaseInboundDto.setStartDate(startDate);
+        purchaseInboundDto.setEndDate(endDate);
+        List<PurchaseInboundVo> purchaseInboundVos = stockInRecordMapper.listPageAccountPurchase(new Page(1, -1), purchaseInboundDto).getRecords();
+        return sumAmount(purchaseInboundVos, PurchaseInboundVo::getInboundAmount);
+    }
+
+    //璁$畻鏃ユ湡鍐呯殑閲囪喘閫�璐ч噾棰�
+    private BigDecimal sumPurchaseReturnAmount(LocalDate startDate, LocalDate endDate) {
+        PurchaseReturnDto purchaseReturnDto = new PurchaseReturnDto();
+        purchaseReturnDto.setStartDate(startDate);
+        purchaseReturnDto.setEndDate(endDate);
+        List<PurchaseReturnVo> purchaseReturnVos = purchaseReturnOrdersMapper.listPageAccountPurchaseReturn(new Page(1, -1), purchaseReturnDto).getRecords();
+        return sumAmount(purchaseReturnVos, PurchaseReturnVo::getTotalAmount);
+    }
+
+    //璁$畻鏃ユ湡鍐呯殑鎬绘敹娆鹃噾棰�
+    private BigDecimal sumCollectionAmount(LocalDate startDate, LocalDate endDate) {
+        List<AccountSalesCollection> collections = defaultList(accountSalesCollectionMapper.selectList(
+                new LambdaQueryWrapper<AccountSalesCollection>()
+                        .ge(AccountSalesCollection::getCollectionDate, startDate)
+                        .le(AccountSalesCollection::getCollectionDate, endDate)));
+        return sumAmount(collections, AccountSalesCollection::getCollectionAmount);
+    }
+
+    //璁$畻鏃ユ湡鍐呯殑鎬讳粯娆鹃噾棰�
+    private BigDecimal sumPaymentAmount(LocalDate startDate, LocalDate endDate) {
+        List<AccountPurchasePayment> payments = defaultList(accountPurchasePaymentMapper.selectList(
+                new LambdaQueryWrapper<AccountPurchasePayment>()
+                        .ge(AccountPurchasePayment::getPaymentDate, startDate)
+                        .le(AccountPurchasePayment::getPaymentDate, endDate)));
+        return sumAmount(payments, AccountPurchasePayment::getPaymentAmount);
+    }
+
+    private Date toDate(LocalDate localDate) {
+        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+    }
+
+    private Date toExclusiveEndDate(LocalDate localDate) {
+        return Date.from(localDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
+    }
+
+    private String toRateString(BigDecimal numerator, BigDecimal denominator) {
+        if (denominator == null || denominator.compareTo(BigDecimal.ZERO) <= 0) {
+            return "0.00";
+        }
+        return defaultDecimal(numerator)
+                .divide(denominator, 4, RoundingMode.HALF_UP)
+                .multiply(BigDecimal.valueOf(100))
+                .setScale(2, RoundingMode.HALF_UP)
+                .toString();
+    }
+
+    private BigDecimal maxZero(BigDecimal value) {
+        if (value == null) {
+            return BigDecimal.ZERO;
+        }
+        return value.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : value;
+    }
+
+    private BigDecimal scaleMoney(BigDecimal value) {
+        return defaultDecimal(value).setScale(2, RoundingMode.HALF_UP);
+    }
+
+    private <T> List<T> defaultList(List<T> list) {
+        return list == null ? List.of() : list;
+    }
+
     private BigDecimal defaultDecimal(BigDecimal value) {
         return value == null ? BigDecimal.ZERO : value;
     }

--
Gitblit v1.9.3