liding
8 天以前 0050395dfb05425f0a929bc1587b971d78f1e95e
src/main/java/com/ruoyi/purchase/service/impl/PaymentRegistrationServiceImpl.java
@@ -2,6 +2,9 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.mapper.SupplierManageMapper;
import com.ruoyi.basic.pojo.SupplierManage;
@@ -10,23 +13,24 @@
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.purchase.dto.PaymentLedgerDto;
import com.ruoyi.purchase.dto.PaymentRegistrationDto;
import com.ruoyi.purchase.mapper.InvoicePurchaseMapper;
import com.ruoyi.purchase.mapper.PaymentRegistrationMapper;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.InvoicePurchase;
import com.ruoyi.purchase.mapper.*;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import com.ruoyi.purchase.pojo.ProductRecord;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.pojo.TicketRegistration;
import com.ruoyi.purchase.service.IPaymentRegistrationService;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.*;
import java.util.stream.Collectors;
@@ -37,24 +41,23 @@
 * @date 2025-05-15
 */
@Service
@AllArgsConstructor
public class PaymentRegistrationServiceImpl extends ServiceImpl<PaymentRegistrationMapper, PaymentRegistration> implements IPaymentRegistrationService {
    @Autowired
    private PaymentRegistrationMapper paymentRegistrationMapper;
    @Autowired
    private PurchaseLedgerMapper purchaseLedgerMapper;
    @Autowired
    private InvoicePurchaseMapper invoicePurchaseMapper;
    @Autowired
    private SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private SupplierManageMapper supplierManageMapper;
    @Autowired
    private SalesLedgerProductMapper salesLedgerProductMapper;
    private TicketRegistrationMapper ticketRegistrationMapper;
    private ProductRecordMapper productRecordMapper;
    /**
     * 查询付款登记
@@ -78,7 +81,7 @@
        List<PaymentRegistrationDto> list = paymentRegistrationMapper.selectPaymentRegistrationList(paymentRegistrationDto);
        for (PaymentRegistrationDto registrationDto : list) {
            List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                    .eq("invoice_purchase_id", registrationDto.getInvoicePurchaseId()));
                    .eq("ticket_registration_id", registrationDto.getTicketRegistrationId()));
            BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            registrationDto.setUnPaymentAmount(registrationDto.getInvoiceAmount().subtract(total));
        }
@@ -103,25 +106,24 @@
        paymentRegistration.setSaleLedgerId(salesLedger.getId());
        paymentRegistration.setSupplierId(purchaseLedger.getSupplierId());
        List<InvoicePurchase> invoicePurchases = invoicePurchaseMapper.selectList(new QueryWrapper<InvoicePurchase>().
                eq("purchase_contract_no", purchaseLedger.getPurchaseContractNumber()));
        if (invoicePurchases == null || invoicePurchases.size() == 0) {
        TicketRegistration tr = ticketRegistrationMapper.selectOne(new LambdaQueryWrapper<TicketRegistration>().eq(TicketRegistration::getId, paymentRegistration.getTicketRegistrationId()));
        if (tr == null) {
            throw new RuntimeException("关联发票不存在");
        }
        paymentRegistration.setInvoicePurchaseId(invoicePurchases.get(0).getId());
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                .eq("invoice_purchase_id", invoicePurchases.get(0).getId()));
                .eq("ticket_registration_id", tr.getId()));
        BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (total.add(paymentRegistration.getCurrentPaymentAmount()).compareTo(invoicePurchases.get(0).getInvoiceAmount()) > 0) {
        if (total.add(paymentRegistration.getCurrentPaymentAmount()).compareTo(tr.getInvoiceAmount()) > 0) {
            throw new RuntimeException("付款金额超出发票金额");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Integer tenantId = loginUser.getTenantId();
        paymentRegistration.setTenantId(tenantId.longValue());
        paymentRegistration.setRegistrantId(loginUser.getUserId());
        paymentRegistration.setCreateTime(DateUtils.getNowDate());
        paymentRegistration.setUpdateTime(DateUtils.getNowDate());
        return paymentRegistrationMapper.insert(paymentRegistration);
@@ -135,13 +137,13 @@
     */
    @Override
    public int updatePaymentRegistration(PaymentRegistration paymentRegistration) {
        InvoicePurchase invoicePurchase = invoicePurchaseMapper.selectById(paymentRegistration.getInvoicePurchaseId());
        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(paymentRegistration.getTicketRegistrationId());
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                .eq("invoice_purchase_id", paymentRegistration.getInvoicePurchaseId()).ne("id", paymentRegistration.getId()));
                .eq("ticket_registration_id", paymentRegistration.getTicketRegistrationId()).ne("id", paymentRegistration.getId()));
        BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (total.add(paymentRegistration.getCurrentPaymentAmount()).compareTo(invoicePurchase.getInvoiceAmount()) > 0) {
        if (total.add(paymentRegistration.getCurrentPaymentAmount()).compareTo(ticketRegistration.getInvoiceAmount()) > 0) {
            throw new RuntimeException("付款金额超出发票金额");
        }
@@ -168,19 +170,21 @@
        paymentRegistrationDto.setSupplierName(purchaseLedger.getSupplierName());
        paymentRegistrationDto.setSupplierId(purchaseLedger.getSupplierId());
        List<InvoicePurchase> invoicePurchaseList = invoicePurchaseMapper.selectList(new QueryWrapper<InvoicePurchase>()
                .eq("purchase_contract_no", purchaseLedger.getPurchaseContractNumber()));
        if (invoicePurchaseList != null && invoicePurchaseList.size() > 0) {
            paymentRegistrationDto.setInvoiceNumber(invoicePurchaseList.get(0).getInvoiceNumber());
            paymentRegistrationDto.setInvoiceAmount(invoicePurchaseList.get(0).getInvoiceAmount());
            paymentRegistrationDto.setTaxRate(invoicePurchaseList.get(0).getTaxRate());
        List<TicketRegistration> ticketRegistrations = ticketRegistrationMapper.selectList(new QueryWrapper<TicketRegistration>()
                .eq("purchase_contract_number", purchaseLedger.getPurchaseContractNumber()));
        if (ticketRegistrations != null && ticketRegistrations.size() > 0) {
            paymentRegistrationDto.setInvoiceNumber(ticketRegistrations.get(0).getInvoiceNumber());
            paymentRegistrationDto.setInvoiceAmount(ticketRegistrations.get(0).getInvoiceAmount());
        }
        return paymentRegistrationDto;
    }
    @Override
    public List<Map<String, Object>> selectPaymentLedgerList(PaymentLedgerDto paymentLedgerDto) {
        List<Map<String, Object>> result = new ArrayList<>();
    public IPage<Map<String, Object>> selectPaymentLedgerList(
            PaymentLedgerDto paymentLedgerDto,
            Page page,
            Integer detailPageNum,
            Integer detailPageSize) {
        LambdaQueryWrapper<SupplierManage> queryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(paymentLedgerDto)
                .ifPresent(dto -> {
@@ -189,58 +193,223 @@
                    }
                });
        List<SupplierManage> supplierManages = supplierManageMapper.selectList(queryWrapper);
        IPage<SupplierManage> supplierPage = supplierManageMapper.selectPage(page, queryWrapper);
        List<SupplierManage> supplierManages = supplierPage.getRecords();
        IPage<Map<String, Object>> resultPage = new Page<>(page.getCurrent(), page.getSize(), supplierPage.getTotal());
        List<Map<String, Object>> result = new ArrayList<>();
        for (SupplierManage supplierManage : supplierManages) {
            Map<String, Object> res = new HashMap<>();
            res.put("supplierName", supplierManage.getSupplierName());
            // 应付金额
            // 应付金额计算
            BigDecimal payableAmount = BigDecimal.ZERO;
            List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(new QueryWrapper<SalesLedger>().eq("customer_id", supplierManage.getId()));
            if (salesLedgers != null && salesLedgers.size() > 0) {
                List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new QueryWrapper<SalesLedgerProduct>()
                        .in("sales_ledger_id", salesLedgers.stream().map(SalesLedger::getId).collect(Collectors.toList())));
                // 应付金额
                payableAmount = salesLedgerProducts.stream().map(SalesLedgerProduct::getTaxInclusiveTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            List<PurchaseLedger> purchaseLedgers = purchaseLedgerMapper.selectList(
                    new QueryWrapper<PurchaseLedger>().eq("supplier_id", supplierManage.getId())
            );
            List<SalesLedgerProduct> salesLedgerProducts = purchaseLedgers.stream()
                    .filter(Objects::nonNull)
                    .map(PurchaseLedger::getId)
                    .filter(Objects::nonNull)
                    .flatMap(id -> salesLedgerProductMapper.selectList(
                            new QueryWrapper<SalesLedgerProduct>().eq("sales_ledger_id", id)
                    ).stream())
                    .collect(Collectors.toList());
            payableAmount = salesLedgerProducts.stream()
                    .map(SalesLedgerProduct::getTaxInclusiveTotalPrice)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            // 来票金额计算
            List<TicketRegistration> ticketRegistrations = purchaseLedgers.stream()
                    .map(PurchaseLedger::getId)
                    .filter(Objects::nonNull)
                    .map(id -> ticketRegistrationMapper.selectList(
                            new LambdaQueryWrapper<TicketRegistration>().eq(TicketRegistration::getPurchaseLedgerId, id)
                    ))
                    .flatMap(Collection::stream)
                    .collect(Collectors.toList());
            BigDecimal invoiceAmount = ticketRegistrations.stream()
                    .map(TicketRegistration::getInvoiceAmount)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            // 开票金额
            BigDecimal invoiceAmount = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            // 付款记录及详情分页
            List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(
                    new QueryWrapper<PaymentRegistration>().eq("supplier_id", supplierManage.getId())
            );
            BigDecimal paymentAmount = paymentRegistrations.stream()
                    .map(PaymentRegistration::getCurrentPaymentAmount)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            // 付款金额
            List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
                    .eq("supplier_id", supplierManage.getId()));
            // 详情分页处理
            detailPageNum = detailPageNum != null ? detailPageNum : 1;
            detailPageSize = detailPageSize != null ? detailPageSize : paymentRegistrations.size(); // 默认显示全部
            int totalDetails = paymentRegistrations.size();
            int start = (detailPageNum - 1) * detailPageSize;
            int end = Math.min(start + detailPageSize, totalDetails);
            List<PaymentRegistration> pagedDetails = paymentRegistrations.subList(start, end);
            BigDecimal paymentAmount = BigDecimal.ZERO;
            if (paymentRegistrations != null && paymentRegistrations.size() > 0) {
                paymentAmount = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            // 构建详情列表
            List<Map<String, Object>> details = pagedDetails.stream()
                    .filter(Objects::nonNull)
                    .map(pr -> {
                        Map<String, Object> detail = new HashMap<>();
                        detail.put("paymentAmount", pr.getCurrentPaymentAmount());
                        // 批量查询 TicketRegistration(避免 N+1)
                        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(pr.getTicketRegistrationId());
                        if (ticketRegistration != null) {
                            detail.put("payableAmount", ticketRegistration.getInvoiceAmount());
                            BigDecimal voteCount = productRecordMapper.selectList(
                                            new LambdaQueryWrapper<ProductRecord>().eq(ProductRecord::getTicketRegistrationId, ticketRegistration.getId())
                                    ).stream()
                                    .map(ProductRecord::getTicketsNum)
                                    .map(BigDecimal::new)
                                    .filter(Objects::nonNull)
                                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                            detail.put("voteCount", voteCount);
                        }
                        // 日期格式化(建议使用 LocalDateTime)
                        if (pr.getPaymentDate() != null) {
                            detail.put("paymentDate", new SimpleDateFormat("yyyy-MM-dd").format(pr.getPaymentDate()));
                        }
                        return detail;
                    })
                    .collect(Collectors.toList());
            // 封装详情分页元数据
            Map<String, Object> detailPagination = new HashMap<>();
            detailPagination.put("total", totalDetails);
            detailPagination.put("pageNum", detailPageNum);
            detailPagination.put("pageSize", detailPageSize);
            detailPagination.put("pages", (int) Math.ceil((double) totalDetails / detailPageSize));
            res.put("invoiceAmount", invoiceAmount);
            res.put("payableAmount", payableAmount);
            res.put("paymentAmount", paymentAmount);
            // 详情
            List<Map<String, Object>> details = new ArrayList<>();
            for (PaymentRegistration paymentRegistration : paymentRegistrations) {
                Map<String, Object> detail = new HashMap<>();
                detail.put("voteCount", 1); // 票数,未知数据源,暂时用1
                detail.put("paymentAmount", paymentRegistration.getCurrentPaymentAmount()); // 付款金额
                InvoicePurchase  invoicePurchase = invoicePurchaseMapper.selectById(paymentRegistration.getInvoicePurchaseId());
                detail.put("payableAmount", invoicePurchase.getInvoiceAmount()); // 应付金额
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String formattedDate = sdf.format(paymentRegistration.getPaymentDate());
                detail.put("createTime", formattedDate); // 发生时间
                details.add(detail);
            }
            res.put("details", paymentRegistrations);
            res.put("details", details);
            res.put("detailPagination", detailPagination); // 添加详情分页信息
            result.add(res);
        }
        resultPage.setRecords(result);
        return resultPage;
    }
    @Override
    public Map<String, BigDecimal> paymentMonthList() {
        // 查询供应商列表
        List<SupplierManage> suppliers = supplierManageMapper.selectList(null);
        if (CollectionUtils.isEmpty(suppliers)) {
            Map<String, BigDecimal> result = new HashMap<>();
            result.put("payableAmount", BigDecimal.ZERO);
            result.put("paymentAmount", BigDecimal.ZERO);
            return result;
        }
        // 提取所有供应商ID
        List<Long> supplierIds = suppliers.stream()
                .map(SupplierManage::getId) // 先获取Integer类型的ID
                .filter(Objects::nonNull)    // 过滤掉可能的null值
                .map(Integer::longValue)    // 将Integer转换为Long
                .collect(Collectors.toList());
        // 获取当月的开始和结束日期
        YearMonth currentMonth = YearMonth.now();
        LocalDate startDate = currentMonth.atDay(1);
        LocalDate endDate = currentMonth.atEndOfMonth();
        // 批量查询采购台账(当月)
        Map<Long, List<PurchaseLedger>> purchaseLedgerMap = batchQueryPurchaseLedgers(supplierIds, startDate, endDate);
        // 批量查询销售台账产品
        Map<Long, List<SalesLedgerProduct>> salesLedgerProductMap = batchQuerySalesLedgerProducts(purchaseLedgerMap);
        // 批量查询付款记录(当月)
        Map<Long, List<PaymentRegistration>> paymentRegistrationMap = batchQueryPaymentRegistrations(supplierIds, startDate, endDate);
        // 计算应付金额和付款金额
        BigDecimal totalPayableAmount = calculateTotalPayableAmount(purchaseLedgerMap, salesLedgerProductMap);
        BigDecimal totalPaymentAmount = calculateTotalPaymentAmount(paymentRegistrationMap);
        // 构建结果
        Map<String, BigDecimal> result = new HashMap<>();
        result.put("payableAmount", totalPayableAmount);
        result.put("paymentAmount", totalPaymentAmount);
        return result;
    }
    // 批量查询采购台账(当月)
    private Map<Long, List<PurchaseLedger>> batchQueryPurchaseLedgers(List<Long> supplierIds, LocalDate startDate, LocalDate endDate) {
        LambdaQueryWrapper<PurchaseLedger> query = new LambdaQueryWrapper<>();
        query.in(PurchaseLedger::getSupplierId, supplierIds)
                .ge(PurchaseLedger::getCreatedAt, startDate)
                .le(PurchaseLedger::getCreatedAt, endDate);
        List<PurchaseLedger> purchaseLedgers = purchaseLedgerMapper.selectList(query);
        return purchaseLedgers.stream()
                .filter(pl -> pl.getSupplierId() != null)
                .collect(Collectors.groupingBy(PurchaseLedger::getSupplierId));
    }
    // 批量查询销售台账产品
    private Map<Long, List<SalesLedgerProduct>> batchQuerySalesLedgerProducts(Map<Long, List<PurchaseLedger>> purchaseLedgerMap) {
        // 提取所有采购台账ID
        List<Long> purchaseLedgerIds = purchaseLedgerMap.values().stream()
                .flatMap(Collection::stream)
                .map(PurchaseLedger::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (purchaseLedgerIds.isEmpty()) {
            return Collections.emptyMap();
        }
        LambdaQueryWrapper<SalesLedgerProduct> query = new LambdaQueryWrapper<>();
        query.in(SalesLedgerProduct::getSalesLedgerId, purchaseLedgerIds);
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(query);
        return products.stream()
                .filter(slp -> slp.getSalesLedgerId() != null)
                .collect(Collectors.groupingBy(SalesLedgerProduct::getSalesLedgerId));
    }
    // 批量查询付款记录(当月)
    private Map<Long, List<PaymentRegistration>> batchQueryPaymentRegistrations(List<Long> supplierIds, LocalDate startDate, LocalDate endDate) {
        LambdaQueryWrapper<PaymentRegistration> query = new LambdaQueryWrapper<>();
        query.in(PaymentRegistration::getSupplierId, supplierIds)
                .ge(PaymentRegistration::getPaymentDate, startDate)
                .le(PaymentRegistration::getPaymentDate, endDate);
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(query);
        return paymentRegistrations.stream()
                .filter(pr -> pr.getSupplierId() != null)
                .collect(Collectors.groupingBy(PaymentRegistration::getSupplierId));
    }
    // 计算总应付金额
    private BigDecimal calculateTotalPayableAmount(Map<Long, List<PurchaseLedger>> purchaseLedgerMap,
                                                   Map<Long, List<SalesLedgerProduct>> salesLedgerProductMap) {
        return purchaseLedgerMap.values().stream()
                .flatMap(Collection::stream)
                .map(pl -> salesLedgerProductMap.getOrDefault(pl.getId(), Collections.emptyList()))
                .flatMap(Collection::stream)
                .map(SalesLedgerProduct::getTaxInclusiveTotalPrice)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    // 计算总付款金额
    private BigDecimal calculateTotalPaymentAmount(Map<Long, List<PaymentRegistration>> paymentRegistrationMap) {
        return paymentRegistrationMap.values().stream()
                .flatMap(Collection::stream)
                .map(PaymentRegistration::getCurrentPaymentAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}