package cn.iocoder.yudao.module.erp.service.purchase;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.statement.ErpSupplierStatementReqVO;
|
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.statement.ErpSupplierStatementRespVO;
|
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO;
|
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO;
|
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
|
import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinancePaymentMapper;
|
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseInvoiceMapper;
|
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderMapper;
|
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
|
import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.SUPPLIER_NOT_EXISTS;
|
|
/**
|
* ERP 供应商往来 Service 实现
|
*/
|
@Service
|
@Validated
|
public class ErpSupplierStatementServiceImpl implements ErpSupplierStatementService {
|
|
@Resource
|
private ErpPurchaseOrderMapper purchaseOrderMapper;
|
@Resource
|
private ErpPurchaseInvoiceMapper purchaseInvoiceMapper;
|
@Resource
|
private ErpFinancePaymentMapper financePaymentMapper;
|
@Resource
|
private ErpPurchaseInvoiceService purchaseInvoiceService;
|
@Resource
|
private SrmSupplierApi srmSupplierApi;
|
|
@Override
|
public ErpSupplierStatementRespVO getSupplierStatement(ErpSupplierStatementReqVO reqVO) {
|
// 1. 校验供应商
|
SrmSupplierRespDTO supplier = srmSupplierApi.getSupplier(reqVO.getSupplierId()).getCheckedData();
|
if (supplier == null) {
|
throw ServiceExceptionUtil.exception(SUPPLIER_NOT_EXISTS);
|
}
|
|
// 2. 查询订单 / 来票 / 付款
|
List<Integer> orderStatuses = Boolean.TRUE.equals(reqVO.getIncludeUnapprovedOrder())
|
? List.of(ErpAuditStatus.PROCESS.getStatus(), ErpAuditStatus.APPROVING.getStatus(),
|
ErpAuditStatus.APPROVE.getStatus())
|
: List.of(ErpAuditStatus.APPROVE.getStatus());
|
List<ErpPurchaseOrderDO> orders = purchaseOrderMapper.selectListBySupplierIdAndOrderTimeBetween(
|
reqVO.getSupplierId(), reqVO.getBeginTime(), reqVO.getEndTime(), orderStatuses);
|
List<ErpPurchaseInvoiceDO> invoices = purchaseInvoiceMapper.selectListBySupplierIdAndInvoiceTimeBetween(
|
reqVO.getSupplierId(), reqVO.getBeginTime(), reqVO.getEndTime());
|
List<Integer> paymentStatuses = List.of(ErpAuditStatus.PROCESS.getStatus(),
|
ErpAuditStatus.APPROVING.getStatus(), ErpAuditStatus.APPROVE.getStatus());
|
List<ErpFinancePaymentDO> payments = financePaymentMapper.selectListBySupplierIdAndPaymentTimeBetween(
|
reqVO.getSupplierId(), reqVO.getBeginTime(), reqVO.getEndTime(), paymentStatuses);
|
|
// 3. 订单已开票金额(不按开票日期过滤,保证未开票金额准确)
|
Map<Long, BigDecimal> invoicedMap = CollUtil.isEmpty(orders) ? Collections.emptyMap()
|
: purchaseInvoiceService.getPurchaseInvoicePriceSumMapByOrderIds(
|
orders.stream().map(ErpPurchaseOrderDO::getId).toList());
|
// 4. 来票已付金额(按所有有效付款单汇总)
|
Map<Long, BigDecimal> paidMap = CollUtil.isEmpty(invoices) ? Collections.emptyMap()
|
: financePaymentMapper.selectPaymentPriceMapByInvoiceId(
|
invoices.stream().map(ErpPurchaseInvoiceDO::getId).toList());
|
// 5. 来票关联订单号
|
Set<Long> invoiceOrderIds = invoices.stream().map(ErpPurchaseInvoiceDO::getPurchaseOrderId)
|
.filter(Objects::nonNull).collect(Collectors.toSet());
|
Map<Long, ErpPurchaseOrderDO> invoiceOrderMap = invoiceOrderIds.isEmpty() ? Collections.emptyMap()
|
: purchaseOrderMapper.selectBatchIds(invoiceOrderIds).stream()
|
.collect(Collectors.toMap(ErpPurchaseOrderDO::getId, Function.identity()));
|
// 6. 付款关联来票号
|
Set<Long> paymentInvoiceIds = payments.stream().map(ErpFinancePaymentDO::getInvoiceId)
|
.filter(Objects::nonNull).collect(Collectors.toSet());
|
Map<Long, ErpPurchaseInvoiceDO> paymentInvoiceMap = paymentInvoiceIds.isEmpty() ? Collections.emptyMap()
|
: purchaseInvoiceMapper.selectBatchIds(paymentInvoiceIds).stream()
|
.collect(Collectors.toMap(ErpPurchaseInvoiceDO::getId, Function.identity()));
|
|
// 7. 组装
|
ErpSupplierStatementRespVO respVO = new ErpSupplierStatementRespVO();
|
respVO.setSupplierId(reqVO.getSupplierId());
|
respVO.setSupplierName(supplier.getName());
|
|
List<ErpSupplierStatementRespVO.OrderRow> orderRows = new ArrayList<>();
|
for (ErpPurchaseOrderDO order : orders) {
|
BigDecimal orderAmount = zero(order.getTotalPrice());
|
BigDecimal invoicedAmount = zero(invoicedMap.get(order.getId()));
|
ErpSupplierStatementRespVO.OrderRow row = new ErpSupplierStatementRespVO.OrderRow();
|
row.setId(order.getId());
|
row.setNo(order.getNo());
|
row.setOrderTime(order.getOrderTime());
|
row.setOrderAmount(orderAmount);
|
row.setInvoicedAmount(invoicedAmount);
|
row.setUninvoicedAmount(orderAmount.subtract(invoicedAmount));
|
row.setStatus(order.getStatus());
|
row.setInStatus(order.getInStatus());
|
orderRows.add(row);
|
}
|
respVO.setOrders(orderRows);
|
|
List<ErpSupplierStatementRespVO.InvoiceRow> invoiceRows = new ArrayList<>();
|
for (ErpPurchaseInvoiceDO invoice : invoices) {
|
BigDecimal invoiceAmount = zero(invoice.getPrice());
|
BigDecimal paidAmount = zero(paidMap.get(invoice.getId()));
|
ErpSupplierStatementRespVO.InvoiceRow row = new ErpSupplierStatementRespVO.InvoiceRow();
|
row.setId(invoice.getId());
|
row.setNo(invoice.getNo());
|
row.setInvoiceNo(invoice.getInvoiceNo());
|
row.setInvoiceTime(invoice.getInvoiceTime());
|
row.setInvoiceAmount(invoiceAmount);
|
row.setPaidAmount(paidAmount);
|
row.setRemainingPayable(invoiceAmount.subtract(paidAmount));
|
row.setPaymentStatus(paidAmount.compareTo(BigDecimal.ZERO) <= 0 ? 0
|
: paidAmount.compareTo(invoiceAmount) >= 0 ? 2 : 1);
|
row.setPurchaseOrderId(invoice.getPurchaseOrderId());
|
ErpPurchaseOrderDO order = invoiceOrderMap.get(invoice.getPurchaseOrderId());
|
row.setPurchaseOrderNo(order != null ? order.getNo() : null);
|
invoiceRows.add(row);
|
}
|
respVO.setInvoices(invoiceRows);
|
|
List<ErpSupplierStatementRespVO.PaymentRow> paymentRows = new ArrayList<>();
|
for (ErpFinancePaymentDO payment : payments) {
|
ErpSupplierStatementRespVO.PaymentRow row = new ErpSupplierStatementRespVO.PaymentRow();
|
row.setId(payment.getId());
|
row.setNo(payment.getNo());
|
row.setPaymentTime(payment.getPaymentTime());
|
row.setPaymentAmount(zero(payment.getPaymentPrice()));
|
row.setStatus(payment.getStatus());
|
row.setInvoiceId(payment.getInvoiceId());
|
ErpPurchaseInvoiceDO invoice = paymentInvoiceMap.get(payment.getInvoiceId());
|
row.setInvoiceNo(invoice != null ? invoice.getNo() : null);
|
paymentRows.add(row);
|
}
|
respVO.setPayments(paymentRows);
|
|
// 8. 汇总
|
ErpSupplierStatementRespVO.Summary summary = new ErpSupplierStatementRespVO.Summary();
|
summary.setTotalPurchaseAmount(orderRows.stream().map(ErpSupplierStatementRespVO.OrderRow::getOrderAmount)
|
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
summary.setTotalInvoiceAmount(invoiceRows.stream().map(ErpSupplierStatementRespVO.InvoiceRow::getInvoiceAmount)
|
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
summary.setTotalPaymentAmount(paymentRows.stream().map(ErpSupplierStatementRespVO.PaymentRow::getPaymentAmount)
|
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
summary.setUnpaidAmount(summary.getTotalInvoiceAmount().subtract(summary.getTotalPaymentAmount()));
|
respVO.setSummary(summary);
|
return respVO;
|
}
|
|
private BigDecimal zero(BigDecimal value) {
|
return value != null ? value : BigDecimal.ZERO;
|
}
|
|
}
|