liyong
2 天以前 4635770544e2d57416ad88a8983ee293919f5fec
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3,10 +3,18 @@
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.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.AccountStatement;
import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
import com.ruoyi.account.pojo.sales.AccountSalesCollection;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
@@ -29,11 +37,13 @@
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.PurchaseLedgerMapper;
import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
@@ -45,7 +55,9 @@
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;
@@ -297,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);
@@ -319,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);
@@ -404,14 +433,26 @@
        LocalDate startDate = range[0];
        LocalDate endDate = range[1];
        //销售出库
        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);
        dto.setReceivableMoney(scaleMoney(maxZero(receivableBase.subtract(advanceMoney))));
        dto.setPayableMoney(scaleMoney(maxZero(payableBase.subtract(prepayMoney))));
        //应收金额=销售出库-销售退货
        dto.setReceivableMoney(scaleMoney(maxZero(receivableBase.subtract(salesReturnAmount))));
        //应付金额=采购入库-采购退货
        dto.setPayableMoney(scaleMoney(maxZero(payableBase.subtract(purchaseReturnAmount))));
        //收款金额=收款单
        dto.setAdvanceMoney(scaleMoney(advanceMoney));
        //付款金额=付款单
        dto.setPrepayMoney(scaleMoney(prepayMoney));
        return dto;
    }
@@ -1226,33 +1267,21 @@
        YearMonth currentMonth = YearMonth.from(today);
        LocalDate startDate = currentMonth.atDay(1);
        LocalDate endDate = currentMonth.atEndOfMonth();
        //收款
        BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate);
        //销售出库
        BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate);
        String collectionRate = toRateString(monthlyIncome, receivableBase);
        String currentMonthText = currentMonth.toString();
        List<AccountStatement> receivableStatements = defaultList(accountStatementMapper.selectList(
                new LambdaQueryWrapper<AccountStatement>()
                        .eq(AccountStatement::getAccountType, 1)
                        .le(AccountStatement::getStatementMonth, currentMonthText)));
        long overdueNum = receivableStatements.stream()
                .filter(item -> item.getStatementMonth() != null && item.getStatementMonth().compareTo(currentMonthText) < 0)
                .filter(item -> defaultDecimal(item.getClosingBalance()).compareTo(BigDecimal.ZERO) > 0)
                .count();
        long totalReceivableCount = receivableStatements.size();
        String overdueRate = totalReceivableCount == 0
                ? "0.00"
                : BigDecimal.valueOf(overdueNum)
                .multiply(BigDecimal.valueOf(100))
                .divide(BigDecimal.valueOf(totalReceivableCount), 2, RoundingMode.HALF_UP)
                .toString();
        //销售退货
        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(BigDecimal.valueOf(overdueNum));
        dto.setOverdueNum(overdueAmount);
        dto.setOverdueRate(overdueRate);
        return dto;
    }
@@ -1264,16 +1293,25 @@
        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);
        dto.setMonthlyExpenditure(scaleMoney(monthlyExpenditure));
        dto.setPaymentRate(toRateString(monthlyExpenditure, payableBase));
        dto.setPaymentRate(paymentRate);
        dto.setGrossProfit(scaleMoney(grossProfit));
        dto.setProfitMarginRate(toRateString(grossProfit, monthlyIncome));
        dto.setProfitMarginRate(profitMarginRate);
        return dto;
    }
@@ -1712,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);
@@ -1985,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));
        }
        // 计算合格率
@@ -2032,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) {
@@ -2168,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<>();
@@ -2217,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);
    }
@@ -2226,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;
@@ -2297,20 +2342,43 @@
        return new LocalDate[]{startDate, endDate};
    }
    //计算日期内的销售出库金额
    private BigDecimal sumSalesContractAmount(LocalDate startDate, LocalDate endDate) {
        List<SalesLedger> salesLedgers = defaultList(salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>()
                .ge(SalesLedger::getEntryDate, toDate(startDate))
                .lt(SalesLedger::getEntryDate, toExclusiveEndDate(endDate))));
        return sumAmount(salesLedgers, SalesLedger::getContractAmount);
        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) {
        List<PurchaseLedger> purchaseLedgers = defaultList(purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
                .ge(PurchaseLedger::getEntryDate, toDate(startDate))
                .lt(PurchaseLedger::getEntryDate, toExclusiveEndDate(endDate))));
        return sumAmount(purchaseLedgers, PurchaseLedger::getContractAmount);
        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>()
@@ -2319,6 +2387,7 @@
        return sumAmount(collections, AccountSalesCollection::getCollectionAmount);
    }
    //计算日期内的总付款金额
    private BigDecimal sumPaymentAmount(LocalDate startDate, LocalDate endDate) {
        List<AccountPurchasePayment> payments = defaultList(accountPurchasePaymentMapper.selectList(
                new LambdaQueryWrapper<AccountPurchasePayment>()