chore: 补充收票单推送金蝶方法注释与批量推送关键环节日志
This commit is contained in:
+24
@@ -491,6 +491,16 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
|
||||
// ==================== 图05 环节②③:A303-2 收票单批量保存 + A302-6 收票指定应付 ====================
|
||||
|
||||
/**
|
||||
* 批量推送收票登记至金蝶(图05 环节②③:A303-2 收票单保存 + A302-6 指定应付)
|
||||
* <p>
|
||||
* 编排流程:参数去重校验 → 批量组装推送计划(分摊/镜像/结算单/结算明细一次取回防 N+1)→
|
||||
* A102-4 应付单已生成预检 → A801-3 幂等预检(金蝶已有收票单则跳过保存续推指定)→
|
||||
* 逐单推送(单笔失败不中断整批)→ 汇总成功/失败笔数返回
|
||||
*
|
||||
* @param ids 收票登记主键集合
|
||||
* @return 推送结果汇总(本批笔数、成功/失败笔数及失败原因明细)
|
||||
*/
|
||||
@Override
|
||||
public String pushKingdeeReceivedInvoice(List<Long> ids) {
|
||||
if (Func.isEmpty(ids)) {
|
||||
@@ -500,26 +510,31 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
if (distinctIds.isEmpty()) {
|
||||
throw new ServiceException("请选择需要推送金蝶的收票登记");
|
||||
}
|
||||
log.info("推送金蝶收票单开始:入参 {} 笔,去重后 {} 笔,收票登记id={}", ids.size(), distinctIds.size(), distinctIds);
|
||||
List<InvoiceReceipt> receipts = listByIds(distinctIds);
|
||||
if (receipts.size() != distinctIds.size()) {
|
||||
throw new ServiceException("部分收票登记不存在或已删除");
|
||||
}
|
||||
// 批量组装推送计划:分摊关系/镜像/结算单/结算明细一次取回,避免逐单查库 N+1
|
||||
// 1) 收票登记与正式结算单的分摊关系(按登记id分组),用于"一票一应付"校验及防重键取数来源
|
||||
Map<Long, List<InvoiceReceiptSettlement>> relationsByReceipt = settlementRelationMapper.selectList(
|
||||
Wrappers.<InvoiceReceiptSettlement>lambdaQuery()
|
||||
.in(InvoiceReceiptSettlement::getInvoiceReceiptId, distinctIds)
|
||||
.orderByAsc(InvoiceReceiptSettlement::getCreateTime)).stream()
|
||||
.collect(Collectors.groupingBy(InvoiceReceiptSettlement::getInvoiceReceiptId));
|
||||
// 2) 票池镜像(A801-1 同步落库的发票数据),提供明细行 itemsJson、票种编码、购方单位等推送必填字段
|
||||
List<Long> mirrorIds = receipts.stream().map(InvoiceReceipt::getKingdeeInvoicePoolId)
|
||||
.filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, KingdeeInvoicePool> mirrorById = mirrorIds.isEmpty() ? Map.of()
|
||||
: invoicePoolMapper.selectBatchIds(mirrorIds).stream()
|
||||
.collect(Collectors.toMap(KingdeeInvoicePool::getId, Function.identity(), (first, second) -> first));
|
||||
// 3) 分摊关系指向的正式结算单,后续校验须为审批通过的应付类型结算单
|
||||
List<Long> settlementIds = relationsByReceipt.values().stream().flatMap(List::stream)
|
||||
.map(InvoiceReceiptSettlement::getFormalSettlementId).filter(Objects::nonNull).distinct().toList();
|
||||
Map<Long, FormalSettlement> settlementById = settlementIds.isEmpty() ? Map.of()
|
||||
: formalSettlementMapper.selectBatchIds(settlementIds).stream()
|
||||
.collect(Collectors.toMap(FormalSettlement::getId, Function.identity(), (first, second) -> first));
|
||||
// 4) 应付结算单的明细行(按行号升序),用于组装 A302-6 指定应付的防重键 apBillSrcCode
|
||||
List<Long> payableSettlementIds = settlementById.values().stream()
|
||||
.filter(settlement -> "payable".equals(settlement.getSettlementType()))
|
||||
.map(FormalSettlement::getId).toList();
|
||||
@@ -529,19 +544,27 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
.eq(FormalSettlementDetail::getIsDeleted, 0)
|
||||
.orderByAsc(FormalSettlementDetail::getLineNo)).stream()
|
||||
.collect(Collectors.groupingBy(FormalSettlementDetail::getFormalSettlementId));
|
||||
log.info("推送金蝶收票单批量取数完成:分摊关系 {} 条,票池镜像 {} 个,结算单 {} 张(应付 {} 张),结算明细 {} 行",
|
||||
relationsByReceipt.size(), mirrorById.size(), settlementById.size(), payableSettlementIds.size(),
|
||||
detailsBySettlement.values().stream().mapToInt(List::size).sum());
|
||||
// 5) 逐单组装推送计划:状态机/绑定/查验/一票一应付/防重键校验,不满足项写入 blockedReason 不抛异常(逐单报因)
|
||||
Map<Long, ReceivedInvoicePushPlan> planByReceipt = new LinkedHashMap<>();
|
||||
for (InvoiceReceipt receipt : receipts) {
|
||||
planByReceipt.put(receipt.getId(), buildReceivedInvoicePushPlan(receipt,
|
||||
relationsByReceipt.getOrDefault(receipt.getId(), List.of()), mirrorById, settlementById, detailsBySettlement));
|
||||
}
|
||||
long blockedCount = planByReceipt.values().stream().filter(plan -> plan.blockedReason() != null).count();
|
||||
log.info("推送金蝶收票单计划组装完成:本批 {} 笔,前置校验拦截 {} 笔", planByReceipt.size(), blockedCount);
|
||||
// A102-4 应付单已生成预检:本批防重键一次批量查询,缺单的登记逐单提示先完成付款侧同步
|
||||
List<String> apSrcCodes = planByReceipt.values().stream()
|
||||
.filter(plan -> plan.blockedReason() == null)
|
||||
.map(ReceivedInvoicePushPlan::apBillSrcCode).filter(Func::isNotBlank).distinct().toList();
|
||||
Map<String, String> apBillNoBySrcCode = apSrcCodes.isEmpty() ? Map.of()
|
||||
: kingdeeApBillSyncSupport.queryApBillExistNos(apSrcCodes);
|
||||
log.info("推送金蝶收票单 A102-4 预检:待校验防重键 {} 个,已生成财务应付单 {} 个", apSrcCodes.size(), apBillNoBySrcCode.size());
|
||||
// A801-3 幂等预检:按购方单位(接口必填)分组回看窗口翻页,本地按防重键匹配(金蝶已存在则跳过保存续推指定)
|
||||
Map<String, BfiReceivedInvoiceVO> kingdeeRowByInvoiceNo = queryKingdeeReceivedInvoiceRows(planByReceipt);
|
||||
log.info("推送金蝶收票单 A801-3 预检:金蝶已存在收票单 {} 笔,命中单据将跳过保存续推指定", kingdeeRowByInvoiceNo.size());
|
||||
KingdeeSyncContext context = KingdeeSyncContext.empty();
|
||||
int success = 0;
|
||||
List<String> failures = new ArrayList<>();
|
||||
@@ -559,6 +582,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
if (!failures.isEmpty()) {
|
||||
summary = summary + ",失败 " + failures.size() + " 笔:" + String.join(";", failures);
|
||||
}
|
||||
log.info("{}", summary);
|
||||
return summary;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user