package com.ruoyi.purchase.service.impl;
|
|
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;
|
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.framework.security.LoginUser;
|
import com.ruoyi.purchase.dto.PaymentLedgerDto;
|
import com.ruoyi.purchase.dto.PaymentRegistrationDto;
|
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 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;
|
|
/**
|
* 付款登记Service业务层处理
|
*
|
* @author ruoyi
|
* @date 2025-05-15
|
*/
|
@Service
|
@AllArgsConstructor
|
public class PaymentRegistrationServiceImpl extends ServiceImpl<PaymentRegistrationMapper, PaymentRegistration> implements IPaymentRegistrationService {
|
private PaymentRegistrationMapper paymentRegistrationMapper;
|
|
private PurchaseLedgerMapper purchaseLedgerMapper;
|
|
private InvoicePurchaseMapper invoicePurchaseMapper;
|
|
private SalesLedgerMapper salesLedgerMapper;
|
|
private SupplierManageMapper supplierManageMapper;
|
|
private SalesLedgerProductMapper salesLedgerProductMapper;
|
|
private TicketRegistrationMapper ticketRegistrationMapper;
|
|
private ProductRecordMapper productRecordMapper;
|
|
/**
|
* 查询付款登记
|
*
|
* @param id 付款登记主键
|
* @return 付款登记
|
*/
|
@Override
|
public PaymentRegistration selectPaymentRegistrationById(Long id) {
|
return paymentRegistrationMapper.selectPaymentRegistrationById(id);
|
}
|
|
/**
|
* 查询付款登记列表
|
*
|
* @param paymentRegistrationDto 付款登记
|
* @return 付款登记
|
*/
|
@Override
|
public List<PaymentRegistrationDto> selectPaymentRegistrationList(PaymentRegistrationDto paymentRegistrationDto) {
|
List<PaymentRegistrationDto> list = paymentRegistrationMapper.selectPaymentRegistrationList(paymentRegistrationDto);
|
for (PaymentRegistrationDto registrationDto : list) {
|
List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
|
.eq("ticket_registration_id", registrationDto.getTicketRegistrationId()));
|
BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
registrationDto.setUnPaymentAmount(registrationDto.getInvoiceAmount().subtract(total));
|
}
|
return list;
|
}
|
|
/**
|
* 新增付款登记
|
*
|
* @param paymentRegistration 付款登记
|
* @return 结果
|
*/
|
@Override
|
public int insertPaymentRegistration(PaymentRegistration paymentRegistration) {
|
PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(paymentRegistration.getPurchaseLedgerId());
|
SalesLedger salesLedger = salesLedgerMapper.selectOne(new QueryWrapper<SalesLedger>().
|
eq("sales_contract_no", purchaseLedger.getSalesContractNo()));
|
if (salesLedger == null) {
|
throw new RuntimeException("关联销售合同号不存在");
|
}
|
|
paymentRegistration.setSaleLedgerId(salesLedger.getId());
|
paymentRegistration.setSupplierId(purchaseLedger.getSupplierId());
|
|
TicketRegistration tr = ticketRegistrationMapper.selectOne(new LambdaQueryWrapper<TicketRegistration>().eq(TicketRegistration::getId, paymentRegistration.getTicketRegistrationId()));
|
|
if (tr == null) {
|
throw new RuntimeException("关联发票不存在");
|
}
|
|
List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
|
.eq("ticket_registration_id", tr.getId()));
|
BigDecimal total = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
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);
|
}
|
|
/**
|
* 修改付款登记
|
*
|
* @param paymentRegistration 付款登记
|
* @return 结果
|
*/
|
@Override
|
public int updatePaymentRegistration(PaymentRegistration paymentRegistration) {
|
TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(paymentRegistration.getTicketRegistrationId());
|
|
List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new QueryWrapper<PaymentRegistration>()
|
.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(ticketRegistration.getInvoiceAmount()) > 0) {
|
throw new RuntimeException("付款金额超出发票金额");
|
}
|
|
paymentRegistration.setUpdateTime(DateUtils.getNowDate());
|
return paymentRegistrationMapper.updateById(paymentRegistration);
|
}
|
|
/**
|
* 批量删除付款登记
|
*
|
* @param ids 需要删除的付款登记主键
|
* @return 结果
|
*/
|
@Override
|
public int deletePaymentRegistrationByIds(Long[] ids) {
|
return paymentRegistrationMapper.delete(new QueryWrapper<PaymentRegistration>().in("id", ids));
|
}
|
|
@Override
|
public PaymentRegistration selectPaymentRegistrationByPurchaseId(Long id) {
|
PaymentRegistrationDto paymentRegistrationDto = new PaymentRegistrationDto();
|
PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
|
paymentRegistrationDto.setSalesContractNo(purchaseLedger.getSalesContractNo());
|
paymentRegistrationDto.setSupplierName(purchaseLedger.getSupplierName());
|
paymentRegistrationDto.setSupplierId(purchaseLedger.getSupplierId());
|
|
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 IPage<Map<String, Object>> selectPaymentLedgerList(
|
PaymentLedgerDto paymentLedgerDto,
|
Page page,
|
Integer detailPageNum,
|
Integer detailPageSize) {
|
LambdaQueryWrapper<SupplierManage> queryWrapper = new LambdaQueryWrapper<>();
|
Optional.ofNullable(paymentLedgerDto)
|
.ifPresent(dto -> {
|
if (StringUtils.hasText(dto.getSupplierName())) {
|
queryWrapper.like(SupplierManage::getSupplierName, dto.getSupplierName());
|
}
|
});
|
|
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<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);
|
|
// 付款记录及详情分页
|
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);
|
|
// 详情分页处理
|
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);
|
|
// 构建详情列表
|
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);
|
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);
|
}
|
}
|