fix: 收款流水认领上限改按收款金额,修复金蝶已匹配收款单无法认领

A301-1 收款单被财务核销后 unmatchamountrec 为 0,旧口径以未匹配金额为认领上限导致 704/797 条流水无法认领。
认领只登记本地并推合同合规,与金蝶匹配状态无关,故额度改为收款金额,由本地累计认领控制;未匹配金额降为参考展示。
This commit is contained in:
刘泉佳
2026-10-29 20:07:49 +08:00
parent 2eded6b20f
commit fce3f00a1e
7 changed files with 285 additions and 48 deletions
@@ -298,18 +298,11 @@ public class ReceiptClaimRecordServiceImpl extends BaseServiceImpl<ReceiptClaimM
}
/**
* 可认领上限:未匹配收款金额(A301-1 unmatchamountrec)与收款金额取较小正值(与收款流水侧口径一致)
* 可认领上限:收款金额(A301-1 actrecamt,与收款流水侧口径一致)。
* 认领只登记本地,额度由本地累计认领控制,金蝶未匹配金额不参与。
*/
private BigDecimal claimCeiling(KingdeeReceiptFlow flow) {
BigDecimal unclaimed = money(flow.getUnmatchAmountRec());
BigDecimal receipt = money(flow.getReceiptAmount());
if (receipt.compareTo(BigDecimal.ZERO) <= 0) {
return unclaimed;
}
if (unclaimed.compareTo(BigDecimal.ZERO) <= 0) {
return unclaimed;
}
return unclaimed.min(receipt);
return money(flow.getReceiptAmount());
}
private String amountStatus(BigDecimal paidAmount, BigDecimal settlementAmount) {
@@ -344,10 +344,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
allocatedTotal = allocatedTotal.add(allocated);
}
// 认领上限:未匹配收款金额(A301-1 unmatchamountrec)与收款金额取较小值(避免未匹配金额异常偏大导致无法认领完成)
if (flow.getUnmatchAmountRec() == null) {
throw new ServiceException("未匹配收款金额缺失,请先手动同步金蝶收款流水");
}
// 认领上限:收款金额(认领只登记本地,额度由本地累计认领控制,金蝶侧匹配状态不参与)
BigDecimal claimCeiling = claimCeiling(flow);
if (claimCeiling.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException("该流水可认领金额为0,无需认领");
@@ -465,7 +462,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
long start = System.currentTimeMillis();
// 同步口径:按业务日期窗口拉取金蝶收款单(收款处理),以金蝶明细流水号为幂等键 upsert 收款流水表;
// 本地已认领金额/状态(claimedAmount/claimStatus)由认领、作废驱动,不被同步顺带覆盖,
// 未匹配收款金额单独存 unclaimed_amount 作为认领上限。
// 未匹配收款金额单独存 unmatch_amount_rec,仅作金蝶参考展示,不参与认领额度。
// 按组织过滤:组织管理(blade_dept)中平台公司(是否平台公司=是)且已维护金蝶编码的组织
List<String> orgNumbers = baseMapper.selectPlatformOrgNumbers();
if (Func.isEmpty(orgNumbers)) {
@@ -814,19 +811,12 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
}
/**
* 可认领上限:未匹配收款金额(A301-1 unmatchamountrec)与收款金额取较小正值。
* 主口径为金蝶侧未匹配收款金额;与收款金额取 min,避免未匹配金额异常偏大导致无法进入「认领完成」。
* 可认领上限:收款金额(A301-1 actrecamt)。
* 认领只登记本地并推合同合规,与金蝶侧收款单匹配(核销)状态无关;
* 金蝶未匹配收款金额(unmatchamountrec)仅作参考展示,不参与额度控制。
*/
private BigDecimal claimCeiling(KingdeeReceiptFlow flow) {
BigDecimal unclaimed = money(flow.getUnmatchAmountRec());
BigDecimal receipt = money(flow.getReceiptAmount());
if (receipt.compareTo(BigDecimal.ZERO) <= 0) {
return unclaimed;
}
if (unclaimed.compareTo(BigDecimal.ZERO) <= 0) {
return unclaimed;
}
return unclaimed.min(receipt);
return money(flow.getReceiptAmount());
}
private Long toLong(Object value) {
@@ -865,7 +855,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
/**
* A301-1 收款单 → 收款流水表字段拷贝(仅覆盖金蝶侧来源字段,不覆盖本地认领金额与状态)。
* 认领上限口径:未匹配收款金额 unmatchamountrec 存 unmatch_amount_rec。
* 金蝶匹配/结算金额原样落库仅作参考,不参与认领额度控制。
*/
private void copyRecBillRow(KingdeeReceiptFlow target, BfiRecBillRow row) {
BfiRecBillVO source = row.recBill();
@@ -896,7 +886,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
target.setTransactionTime(parseDateTime(source.getBizdate()));
// 明细流水号
target.setDetailSerialNo(row.detailSerialNo());
// 未匹配收款金额(认领上限口径)
// 未匹配收款金额(金蝶参考展示,不参与认领额度)
target.setUnmatchAmountRec(money(source.getUnmatchamountrec()));
// 已匹配收款金额 / 已匹配付款金额 / 未匹配付款金额
target.setMatchAmountRec(money(source.getMatchamountrec()));
@@ -70,15 +70,10 @@ public class ReceiptFlowWrapper extends BaseEntityWrapper<KingdeeReceiptFlow, Re
case "failed" -> "处理失败";
default -> "未推送";
});
// 剩余可认领金额 = 可认领上限 − 累计认领金额(上限取未匹配收款金额与收款金额较小值)
BigDecimal unmatchAmountRec = money(entity.getUnmatchAmountRec());
// 剩余可认领金额 = 收款金额 − 累计认领金额(认领只登记本地,额度由本地累计认领控制)
BigDecimal receiptAmount = money(entity.getReceiptAmount());
BigDecimal claimCeiling = unmatchAmountRec;
if (receiptAmount.compareTo(BigDecimal.ZERO) > 0 && unmatchAmountRec.compareTo(BigDecimal.ZERO) > 0) {
claimCeiling = unmatchAmountRec.min(receiptAmount);
}
BigDecimal claimedAmount = money(entity.getClaimedAmount());
vo.setRemainingAmount(claimCeiling.subtract(claimedAmount).max(BigDecimal.ZERO));
vo.setRemainingAmount(receiptAmount.subtract(claimedAmount).max(BigDecimal.ZERO));
vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser()));
vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser()));
return vo;