refactor: 抽取正式结算单收款汇总批量装载公共逻辑统一读写口径
This commit is contained in:
+62
-104
@@ -233,8 +233,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表页批量 Entity → VO:收款汇总各数据源与预结算单号按本页一次批量查询后内存分发,
|
* 列表页批量 Entity → VO:收款汇总各数据源与预结算单号按本页一次批量查询后内存分发,
|
||||||
* 计算口径与单笔版 toVO 完全一致(复用 calculatePaymentSummary 纯计算重载),
|
* 计算口径与单笔版 toVO 完全一致,且与 refreshPaymentSummaries 写回路径共用批量装载与计算(loadPaymentSummaryBatchData)。
|
||||||
* 固定约 6 次查询替代逐行 toVO 的 4~5 次/行(100 行约 500 次 SQL)。
|
|
||||||
*
|
*
|
||||||
* @param entities 本页结算单
|
* @param entities 本页结算单
|
||||||
* @return 本页 VO 列表
|
* @return 本页 VO 列表
|
||||||
@@ -243,9 +242,33 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
|||||||
if (Func.isEmpty(entities)) {
|
if (Func.isEmpty(entities)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
List<Long> ids = entities.stream().map(FormalSettlement::getId).toList();
|
PaymentSummaryBatchData batch = this.loadPaymentSummaryBatchData(
|
||||||
boolean hasPayable = entities.stream().anyMatch(item -> "payable".equals(item.getSettlementType()));
|
entities.stream().map(FormalSettlement::getId).toList());
|
||||||
boolean hasReceivable = entities.stream().anyMatch(item -> "receivable".equals(item.getSettlementType()));
|
List<FormalSettlementVO> voList = new ArrayList<>(entities.size());
|
||||||
|
for (FormalSettlement entity : entities) {
|
||||||
|
FormalSettlementVO vo = FormalSettlementWrapper.build().entityVO(entity);
|
||||||
|
vo.setInvoiceStatus(this.invoiceStatus(entity.getInvoiceAmount(), entity.getSettlementAmount()));
|
||||||
|
PaymentSummary summary = this.paymentSummaryFor(entity, batch);
|
||||||
|
vo.setAppliedPaymentAmount(summary.appliedAmount());
|
||||||
|
vo.setPaidAmount(summary.paidAmount());
|
||||||
|
vo.setRemainingPayableAmount(this.money(entity.getSettlementAmount()).subtract(summary.paidAmount())
|
||||||
|
.max(BigDecimal.ZERO));
|
||||||
|
vo.setPreSettlementNos(batch.sourcesBySettlement().getOrDefault(entity.getId(), List.of()).stream()
|
||||||
|
.map(FormalSettlementSource::getPreSettlementNo).collect(Collectors.joining(",")));
|
||||||
|
voList.add(vo);
|
||||||
|
}
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量收款汇总数据装载(列表页 toVOList 读路径与 refreshPaymentSummaries 写回路径共用):
|
||||||
|
* 固定 6 次查询取回本批结算单全部汇总数据源并按结算单id分组,替代两处各自维护的重复查询块。
|
||||||
|
*/
|
||||||
|
private PaymentSummaryBatchData loadPaymentSummaryBatchData(Collection<Long> settlementIds) {
|
||||||
|
List<Long> ids = settlementIds.stream().filter(Objects::nonNull).distinct().toList();
|
||||||
|
if (ids.isEmpty()) {
|
||||||
|
return new PaymentSummaryBatchData(Map.of(), Map.of(), Map.of(), Map.of(), Map.of(), Map.of());
|
||||||
|
}
|
||||||
// 结算-付款申请关系(全量)
|
// 结算-付款申请关系(全量)
|
||||||
Map<Long, List<PaymentApplicationSettlement>> relationsBySettlement = paymentApplicationSettlementMapper.selectList(
|
Map<Long, List<PaymentApplicationSettlement>> relationsBySettlement = paymentApplicationSettlementMapper.selectList(
|
||||||
Wrappers.<PaymentApplicationSettlement>lambdaQuery()
|
Wrappers.<PaymentApplicationSettlement>lambdaQuery()
|
||||||
@@ -275,53 +298,51 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
|||||||
Wrappers.<FormalSettlementSource>lambdaQuery()
|
Wrappers.<FormalSettlementSource>lambdaQuery()
|
||||||
.in(FormalSettlementSource::getFormalSettlementId, ids)).stream()
|
.in(FormalSettlementSource::getFormalSettlementId, ids)).stream()
|
||||||
.collect(Collectors.groupingBy(FormalSettlementSource::getFormalSettlementId));
|
.collect(Collectors.groupingBy(FormalSettlementSource::getFormalSettlementId));
|
||||||
// 收款认领分摊聚合(仅应收结算单需要)
|
// 收款认领分摊聚合(仅应收结算单消费)
|
||||||
Map<Long, BigDecimal> receiptClaimPaidBySettlement = hasReceivable
|
Map<Long, BigDecimal> receiptClaimPaidBySettlement = receiptClaimSettlementMapper.selectList(
|
||||||
? receiptClaimSettlementMapper.selectList(Wrappers.<ReceiptClaimSettlement>lambdaQuery()
|
Wrappers.<ReceiptClaimSettlement>lambdaQuery()
|
||||||
.in(ReceiptClaimSettlement::getFormalSettlementId, ids)
|
.in(ReceiptClaimSettlement::getFormalSettlementId, ids)
|
||||||
.eq(ReceiptClaimSettlement::getStatus, 1)
|
.eq(ReceiptClaimSettlement::getStatus, 1)
|
||||||
.eq(ReceiptClaimSettlement::getIsDeleted, 0)).stream()
|
.eq(ReceiptClaimSettlement::getIsDeleted, 0)).stream()
|
||||||
.collect(Collectors.groupingBy(ReceiptClaimSettlement::getFormalSettlementId,
|
.collect(Collectors.groupingBy(ReceiptClaimSettlement::getFormalSettlementId,
|
||||||
Collectors.reducing(BigDecimal.ZERO,
|
Collectors.reducing(BigDecimal.ZERO,
|
||||||
item -> this.money(item.getAllocatedReceiptAmount()), BigDecimal::add)))
|
item -> this.money(item.getAllocatedReceiptAmount()), BigDecimal::add)));
|
||||||
: Map.of();
|
// 项目预付核销合计(仅应付结算单消费,一次 group-by 避免逐单查询)
|
||||||
// 项目预付核销合计(仅应付结算单需要,一次 group-by 避免逐单查询)
|
Map<Long, BigDecimal> writeOffAmountsBySettlement = this.projectAdvanceWriteOffService.sumBySettlementIds(
|
||||||
Map<Long, BigDecimal> writeOffAmountsBySettlement = hasPayable
|
TransportBusiConstant.SETTLEMENT_BILL_FORMAL, ids);
|
||||||
? this.projectAdvanceWriteOffService.sumBySettlementIds(
|
return new PaymentSummaryBatchData(relationsBySettlement, applicationsBySettlement, relationStatuses,
|
||||||
TransportBusiConstant.SETTLEMENT_BILL_FORMAL,
|
sourcesBySettlement, receiptClaimPaidBySettlement, writeOffAmountsBySettlement);
|
||||||
entities.stream().filter(item -> "payable".equals(item.getSettlementType()))
|
}
|
||||||
.map(FormalSettlement::getId).toList())
|
|
||||||
: Map.of();
|
|
||||||
|
|
||||||
List<FormalSettlementVO> voList = new ArrayList<>(entities.size());
|
/**
|
||||||
for (FormalSettlement entity : entities) {
|
* 单张结算单收款汇总纯计算:从批量装载数据取数组装
|
||||||
FormalSettlementVO vo = FormalSettlementWrapper.build().entityVO(entity);
|
* (直挂付款申请排除该结算单关系表已引用的申请,与单笔版 notIn 语义一致)。
|
||||||
vo.setInvoiceStatus(this.invoiceStatus(entity.getInvoiceAmount(), entity.getSettlementAmount()));
|
*/
|
||||||
List<PaymentApplicationSettlement> relations = relationsBySettlement
|
private PaymentSummary paymentSummaryFor(FormalSettlement settlement, PaymentSummaryBatchData batch) {
|
||||||
.getOrDefault(entity.getId(), List.of());
|
List<PaymentApplicationSettlement> relations = batch.relationsBySettlement()
|
||||||
// 直挂付款申请需排除该结算单关系表已引用的申请(与单笔版 notIn 语义一致)
|
.getOrDefault(settlement.getId(), List.of());
|
||||||
Set<Long> ownRelationApplicationIds = relations.stream()
|
Set<Long> ownRelationApplicationIds = relations.stream()
|
||||||
.map(PaymentApplicationSettlement::getPaymentApplicationId)
|
.map(PaymentApplicationSettlement::getPaymentApplicationId)
|
||||||
.filter(Objects::nonNull).collect(Collectors.toSet());
|
.filter(Objects::nonNull).collect(Collectors.toSet());
|
||||||
List<PaymentApplication> directApplications = applicationsBySettlement
|
List<PaymentApplication> directApplications = batch.applicationsBySettlement()
|
||||||
.getOrDefault(entity.getId(), List.of()).stream()
|
.getOrDefault(settlement.getId(), List.of()).stream()
|
||||||
.filter(item -> !ownRelationApplicationIds.contains(item.getId()))
|
.filter(item -> !ownRelationApplicationIds.contains(item.getId()))
|
||||||
.toList();
|
.toList();
|
||||||
PaymentSummary summary = this.calculatePaymentSummary(entity, new PaymentSummaryData(
|
return this.calculatePaymentSummary(settlement, new PaymentSummaryData(
|
||||||
relations, directApplications, relationStatuses,
|
relations, directApplications, batch.relationStatuses(),
|
||||||
sourcesBySettlement.getOrDefault(entity.getId(), List.of()).stream()
|
batch.sourcesBySettlement().getOrDefault(settlement.getId(), List.of()).stream()
|
||||||
.filter(item -> Objects.equals(item.getIsDeleted(), 0)).toList(),
|
.filter(item -> Objects.equals(item.getIsDeleted(), 0)).toList(),
|
||||||
receiptClaimPaidBySettlement.getOrDefault(entity.getId(), BigDecimal.ZERO),
|
batch.receiptClaimPaidBySettlement().getOrDefault(settlement.getId(), BigDecimal.ZERO),
|
||||||
writeOffAmountsBySettlement));
|
batch.writeOffAmountsBySettlement()));
|
||||||
vo.setAppliedPaymentAmount(summary.appliedAmount());
|
|
||||||
vo.setPaidAmount(summary.paidAmount());
|
|
||||||
vo.setRemainingPayableAmount(this.money(entity.getSettlementAmount()).subtract(summary.paidAmount())
|
|
||||||
.max(BigDecimal.ZERO));
|
|
||||||
vo.setPreSettlementNos(sourcesBySettlement.getOrDefault(entity.getId(), List.of()).stream()
|
|
||||||
.map(FormalSettlementSource::getPreSettlementNo).collect(Collectors.joining(",")));
|
|
||||||
voList.add(vo);
|
|
||||||
}
|
}
|
||||||
return voList;
|
|
||||||
|
/**
|
||||||
|
* 批量收款汇总装载数据(结算单id → 各数据源分组)
|
||||||
|
*/
|
||||||
|
private record PaymentSummaryBatchData(Map<Long, List<PaymentApplicationSettlement>> relationsBySettlement,
|
||||||
|
Map<Long, List<PaymentApplication>> applicationsBySettlement, Map<Long, String> relationStatuses,
|
||||||
|
Map<Long, List<FormalSettlementSource>> sourcesBySettlement,
|
||||||
|
Map<Long, BigDecimal> receiptClaimPaidBySettlement, Map<Long, BigDecimal> writeOffAmountsBySettlement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2191,72 +2212,9 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Long> settledIds = settlements.stream().map(FormalSettlement::getId).toList();
|
List<Long> settledIds = settlements.stream().map(FormalSettlement::getId).toList();
|
||||||
boolean hasPayable = settlements.stream().anyMatch(item -> "payable".equals(item.getSettlementType()));
|
PaymentSummaryBatchData batch = this.loadPaymentSummaryBatchData(settledIds);
|
||||||
boolean hasReceivable = settlements.stream().anyMatch(item -> "receivable".equals(item.getSettlementType()));
|
|
||||||
|
|
||||||
// 结算-付款申请关系(全量)
|
|
||||||
Map<Long, List<PaymentApplicationSettlement>> relationsBySettlement = paymentApplicationSettlementMapper.selectList(
|
|
||||||
Wrappers.<PaymentApplicationSettlement>lambdaQuery()
|
|
||||||
.in(PaymentApplicationSettlement::getFormalSettlementId, settledIds)
|
|
||||||
.eq(PaymentApplicationSettlement::getIsDeleted, 0)).stream()
|
|
||||||
.collect(Collectors.groupingBy(PaymentApplicationSettlement::getFormalSettlementId));
|
|
||||||
// 付款申请(按结算单直挂,payment_type=结算)
|
|
||||||
Map<Long, List<PaymentApplication>> applicationsBySettlement = paymentApplicationMapper.selectList(
|
|
||||||
Wrappers.<PaymentApplication>lambdaQuery()
|
|
||||||
.in(PaymentApplication::getSettlementId, settledIds)
|
|
||||||
.eq(PaymentApplication::getPaymentType, TransportBusiConstant.PAYMENT_TYPE_SETTLEMENT)
|
|
||||||
.eq(PaymentApplication::getIsDeleted, 0)).stream()
|
|
||||||
.collect(Collectors.groupingBy(PaymentApplication::getSettlementId));
|
|
||||||
// 关系表引用的付款申请状态(全量一次)
|
|
||||||
Set<Long> relationApplicationIds = relationsBySettlement.values().stream()
|
|
||||||
.flatMap(List::stream).map(PaymentApplicationSettlement::getPaymentApplicationId)
|
|
||||||
.filter(Objects::nonNull).collect(Collectors.toSet());
|
|
||||||
Map<Long, String> relationStatuses = relationApplicationIds.isEmpty() ? Map.of()
|
|
||||||
: paymentApplicationMapper.selectList(Wrappers.<PaymentApplication>lambdaQuery()
|
|
||||||
.select(PaymentApplication::getId, PaymentApplication::getApprovalStatus)
|
|
||||||
.in(PaymentApplication::getId, relationApplicationIds)
|
|
||||||
.eq(PaymentApplication::getIsDeleted, 0)).stream()
|
|
||||||
.collect(Collectors.toMap(PaymentApplication::getId, PaymentApplication::getApprovalStatus,
|
|
||||||
(first, second) -> first));
|
|
||||||
// 预收来源(仅应付结算单需要)
|
|
||||||
Map<Long, List<FormalSettlementSource>> sourcesBySettlement = hasPayable
|
|
||||||
? sourceMapper.selectList(Wrappers.<FormalSettlementSource>lambdaQuery()
|
|
||||||
.in(FormalSettlementSource::getFormalSettlementId, settledIds)
|
|
||||||
.eq(FormalSettlementSource::getIsDeleted, 0)).stream()
|
|
||||||
.collect(Collectors.groupingBy(FormalSettlementSource::getFormalSettlementId))
|
|
||||||
: Map.of();
|
|
||||||
// 收款认领分摊聚合(仅应收结算单需要)
|
|
||||||
Map<Long, BigDecimal> receiptClaimPaidBySettlement = hasReceivable
|
|
||||||
? receiptClaimSettlementMapper.selectList(Wrappers.<ReceiptClaimSettlement>lambdaQuery()
|
|
||||||
.in(ReceiptClaimSettlement::getFormalSettlementId, settledIds)
|
|
||||||
.eq(ReceiptClaimSettlement::getStatus, 1)
|
|
||||||
.eq(ReceiptClaimSettlement::getIsDeleted, 0)).stream()
|
|
||||||
.collect(Collectors.groupingBy(ReceiptClaimSettlement::getFormalSettlementId,
|
|
||||||
Collectors.reducing(BigDecimal.ZERO,
|
|
||||||
item -> money(item.getAllocatedReceiptAmount()), BigDecimal::add)))
|
|
||||||
: Map.of();
|
|
||||||
// 项目预付核销合计(仅应付结算单需要,一次 group-by 避免逐单查询)
|
|
||||||
Map<Long, BigDecimal> writeOffAmountsBySettlement = hasPayable
|
|
||||||
? this.projectAdvanceWriteOffService.sumBySettlementIds(
|
|
||||||
TransportBusiConstant.SETTLEMENT_BILL_FORMAL, settledIds)
|
|
||||||
: Map.of();
|
|
||||||
|
|
||||||
for (FormalSettlement settlement : settlements) {
|
for (FormalSettlement settlement : settlements) {
|
||||||
List<PaymentApplicationSettlement> relations = relationsBySettlement
|
PaymentSummary summary = this.paymentSummaryFor(settlement, batch);
|
||||||
.getOrDefault(settlement.getId(), List.of());
|
|
||||||
// 直挂付款申请需排除该结算单关系表已引用的申请(与单笔版 notIn 语义一致)
|
|
||||||
Set<Long> ownRelationApplicationIds = relations.stream()
|
|
||||||
.map(PaymentApplicationSettlement::getPaymentApplicationId)
|
|
||||||
.filter(Objects::nonNull).collect(Collectors.toSet());
|
|
||||||
List<PaymentApplication> directApplications = applicationsBySettlement
|
|
||||||
.getOrDefault(settlement.getId(), List.of()).stream()
|
|
||||||
.filter(item -> !ownRelationApplicationIds.contains(item.getId()))
|
|
||||||
.toList();
|
|
||||||
PaymentSummary summary = calculatePaymentSummary(settlement, new PaymentSummaryData(
|
|
||||||
relations, directApplications, relationStatuses,
|
|
||||||
sourcesBySettlement.getOrDefault(settlement.getId(), List.of()),
|
|
||||||
receiptClaimPaidBySettlement.getOrDefault(settlement.getId(), BigDecimal.ZERO),
|
|
||||||
writeOffAmountsBySettlement));
|
|
||||||
settlement.setAppliedPaymentAmount(summary.appliedAmount());
|
settlement.setAppliedPaymentAmount(summary.appliedAmount());
|
||||||
settlement.setPaidAmount(summary.paidAmount());
|
settlement.setPaidAmount(summary.paidAmount());
|
||||||
settlement.setRemainingPayableAmount(money(settlement.getSettlementAmount())
|
settlement.setRemainingPayableAmount(money(settlement.getSettlementAmount())
|
||||||
|
|||||||
Reference in New Issue
Block a user