refactor: 收款流水同步改为主单粒度一单一流水不再展开流水分录
This commit is contained in:
+1
-1
@@ -113,7 +113,7 @@ public class KingdeeReceiptFlow extends TenantEntity {
|
||||
*/
|
||||
private LocalDateTime transactionTime;
|
||||
/**
|
||||
* 明细流水号(A301-1 流水分录 bei_detailid,兜底 bei_bankdetailno,幂等键)
|
||||
* 明细流水号(收款单号 billno,幂等键;C104-2 按此定位合规侧收款流水)
|
||||
*/
|
||||
private String detailSerialNo;
|
||||
/**
|
||||
|
||||
+18
-49
@@ -40,7 +40,6 @@ import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.system.pojo.entity.Dept;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiRecBillQueryDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillFlowVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiRecBillVO;
|
||||
import org.springblade.thirdparty.bfi.service.IBfiService;
|
||||
import org.springblade.thirdparty.bfi.util.BfiUtil;
|
||||
@@ -483,7 +482,24 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
}
|
||||
pullCount += rows.size();
|
||||
for (BfiRecBillVO recBill : rows) {
|
||||
skippedCount += expandRecBillRows(recBill, pending, batchSerials);
|
||||
// 主单粒度:一张收款单一条流水,不展开流水分录;明细流水号取收款单号(幂等键,C104-2 按此定位合规流水)
|
||||
String detailSerialNo = trimToEmpty(recBill.getBillno());
|
||||
if (Func.isEmpty(detailSerialNo)) {
|
||||
log.warn("收款流水同步跳过:收款单缺少单号");
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
if (!batchSerials.add(detailSerialNo)) {
|
||||
throw new ServiceException("收款单号" + detailSerialNo + "重复");
|
||||
}
|
||||
// 收款金额取主单入账金额 inneraccountamount(金蝶口径,非流水分录 bei_creditamount)
|
||||
BigDecimal receiptAmount = money(recBill.getInneraccountAmount());
|
||||
if (receiptAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
log.warn("收款流水同步跳过:收款单[{}]收款金额(inneraccountamount)为空或小于0", recBill.getBillno());
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
pending.add(new BfiRecBillRow(recBill, detailSerialNo, receiptAmount));
|
||||
if (pending.size() >= SYNC_BATCH_SIZE) {
|
||||
batchNo++;
|
||||
totalCount += syncBatch(batchNo, pending);
|
||||
@@ -515,44 +531,6 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单张收款单展开为流水行并做批内校验(金额非法跳过,批内流水号重复拦截)。
|
||||
* 明细流水号优先级:bei_detailid > bei_bankdetailno > 收款单号 billno 兜底
|
||||
* (无流水分录的单如手工收款单也入库,但认领后 C104-2 将定位不到合规流水,C107-1 落失败标记)。
|
||||
*
|
||||
* @return 跳过条数
|
||||
*/
|
||||
private int expandRecBillRows(BfiRecBillVO recBill, List<BfiRecBillRow> pending, Set<String> batchSerials) {
|
||||
int skipped = 0;
|
||||
List<BfiRecBillFlowVO> flowEntries = recBill.getInfoentry();
|
||||
if (Func.isEmpty(flowEntries)) {
|
||||
flowEntries = List.of(new BfiRecBillFlowVO());
|
||||
}
|
||||
for (BfiRecBillFlowVO flowEntry : flowEntries) {
|
||||
// 明细流水号优先级:bei_detailid > bei_bankdetailno > 收款单号兜底
|
||||
String detailSerialNo = firstNonBlank(flowEntry.getBeiDetailid(), flowEntry.getBeiBankdetailno(),
|
||||
recBill.getBillno());
|
||||
if (Func.isEmpty(detailSerialNo)) {
|
||||
log.warn("收款流水同步跳过:收款单[{}]缺少明细流水号", recBill.getBillno());
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
detailSerialNo = detailSerialNo.trim();
|
||||
if (!batchSerials.add(detailSerialNo)) {
|
||||
throw new ServiceException("明细流水号" + detailSerialNo + "重复");
|
||||
}
|
||||
// 收款金额取主单入账金额 inneraccountamount(金蝶口径,非流水分录 bei_creditamount)
|
||||
BigDecimal receiptAmount = money(recBill.getInneraccountAmount());
|
||||
if (receiptAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
log.warn("收款流水同步跳过:收款单[{}]收款金额(inneraccountamount)为空或小于0", recBill.getBillno());
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
pending.add(new BfiRecBillRow(recBill, detailSerialNo, receiptAmount));
|
||||
}
|
||||
return skipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单批入库(独立事务):批内 FOR UPDATE 防并发,按明细流水号 upsert,操作日志批量落库
|
||||
*
|
||||
@@ -877,15 +855,6 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
return KingdeeBfiConstant.KINGDEE_STATUS_FAILED;
|
||||
}
|
||||
|
||||
private String firstNonBlank(String... values) {
|
||||
for (String value : values) {
|
||||
if (Func.isNotEmpty(value)) {
|
||||
return value.trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private LocalDateTime parseDateTime(String value) {
|
||||
if (Func.isEmpty(value)) {
|
||||
return null;
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ A301-1 收款单查询(业务日期窗口取 `thirdParty.bfi.recBillSync.days`
|
||||
| --- | --- | --- |
|
||||
| receipt_notice_no / kingdee_bill_no | `billno` | 金蝶收款单号(两处同值) |
|
||||
| kingdee_bill_status | `billstatus` 映射 | A/B已提交→pushed、C已审核→approved、D已收款→received、其余(含G退单)→failed |
|
||||
| detail_serial_no | `infoentry[].bei_detailid`,兜底 `bei_bankdetailno` | **幂等键**;每条流水分录展开为一行流水 |
|
||||
| detail_serial_no | 主单 `billno` | 明细流水号=收款单号,**幂等键**;主单粒度,一张收款单一条流水,不展开流水分录 |
|
||||
| receipt_amount | 主单 `inneraccountamount` | 收款金额(入账金额口径,非流水分录 bei_creditamount) |
|
||||
| unclaimed_amount | `unmatchamountrec` | 未匹配收款金额,**认领上限口径** |
|
||||
| payer_name / counterparty_name | `payername` | 付款人名称 |
|
||||
|
||||
Reference in New Issue
Block a user