⚡ 金蝶应付单分录新增明细单价推送,取数去掉结算明细行兜底改为缺失即报错

This commit is contained in:
刘泉佳
2026-09-18 19:37:27 +08:00
parent 17b8da0a65
commit 63b2e89cb6
@@ -1134,6 +1134,8 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
entry.setMeasureunitNumber(entryGroup.measureunitNumber());
// 【必填】数量:该行运输数量,无吨位数据时兜底 1
entry.setQuantity(entryGroup.quantity().compareTo(BigDecimal.ZERO) > 0 ? entryGroup.quantity() : BigDecimal.ONE);
// 明细.单价:该行运输单价(费用明细 unit_price;单据头 ispricetotal=true 录入总价,单价仅作参考)
entry.setPrice(entryGroup.price());
// 应付金额(含税):该行应付货物费用行调整后总金额(含税)
entry.setEPricetaxtotal(entryGroup.amount());
// 金额(不含税):该行结算金额(不含税)(应付费用行无不含税字段,经结算货物费用行回链)
@@ -1275,13 +1277,14 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
*
* @param materialNumber 物料编码(货物类型档案货物编码)
* @param measureunitNumber 计量单位编码(运费计算单位,档案暂无编码字段暂传单位名称)
* @param entryCode 分录唯一标识(awrp_entry_code):费用明细行id(兜底结算明细行id),同行多货物类型拆分时追加序号
* @param entryCode 分录唯一标识(awrp_entry_code):费用明细行id,同行多货物类型拆分时追加序号
* @param quantity 该行运输数量
* @param price 该行运输单价(费用明细 unit_price)
* @param amount 该行金额(含税),对应明细应付金额 e_pricetaxtotal
* @param amountNoTax 该行金额(不含税),对应明细金额 e_amount
*/
private record BfiEntryGroup(String materialNumber, String measureunitNumber, String entryCode,
BigDecimal quantity, BigDecimal amount, BigDecimal amountNoTax) {
BigDecimal quantity, BigDecimal price, BigDecimal amount, BigDecimal amountNoTax) {
}
/**
@@ -1310,7 +1313,7 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
* 每货物一条)——货物类型/计量单位/运输数量/含税金额直接取应付费用行(含税金额取调整后总金额 after_amount);
* 应付费用行无不含税字段,不含税金额经结算货物费用行 sourceFeeId 回链(直接选明细路径 sourceFeeId=应付费用行id,
* 预结算合并路径 sourceFeeId=预结算费用行id,经预结算费用行 sourceFeeId 回溯应付费用行id);
* 结算明细无应付费用行时兜底结算明细行(金额取结算金额)。物料编码:货物类型(支持“、”分隔多类型)
* 结算明细对应应付明细无货物费用行时直接报错拦截(取数必须来自应付费用明细,无兜底)。物料编码:货物类型(支持“、”分隔多类型)
* 匹配货物类型档案货物编码;分录唯一标识(awrp_entry_code)取费用明细行id(雪花id天然唯一,满足 A103-1
* 对方系统唯一行id不能重复;A103-1 与应付单的勾稽关联走 awrp_finapbill_entryid=付款计划
* awrp_entry_code_p,与本标识无关);分录金额不按申请付款金额分摊。</p>
@@ -1326,7 +1329,7 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
// 去重收集结算明细单据号(保持行序),用于拼接财务应付单外部系统来源单据号
List<String> documentNos = settlementDocumentNos(settlementDetails);
Map<String, String> cargoCodeByName = cargoCodeByName(context);
// 应付明细id->应付货物费用行(分录主取数来源)
// 应付明细id->应付货物费用行(分录取数来源,无兜底)
Map<Long, List<ReceivablePayableCargoFee>> payableFeesByDetailId = payableCargoFeesByDetailId(settlementDetails);
// 应付费用行id->结算金额(不含税):应付费用行无不含税字段,经结算货物费用行 sourceFeeId 回链
Map<Long, BigDecimal> noTaxByPayableFeeId = settlementNoTaxByPayableFeeId(settlementDetails);
@@ -1334,27 +1337,19 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
for (FormalSettlementDetail settlementDetail : settlementDetails) {
List<ReceivablePayableCargoFee> payableFees =
payableFeesByDetailId.getOrDefault(settlementDetail.getSourceDetailId(), List.of());
if (Func.isNotEmpty(payableFees)) {
for (ReceivablePayableCargoFee payableFee : payableFees) {
appendEntryGroups(entryGroups, cargoCodeByName, payableFee.getCargoType(),
resolveMeasureunitNumber(payableFee.getPriceUnit(), payableFee.getQuantityUnit()),
payableFee.getId(),
money(payableFee.getAfterAmount()),
noTaxByPayableFeeId.getOrDefault(payableFee.getId(), BigDecimal.ZERO),
money(payableFee.getTransportQuantity()),
"应付货物费用[" + Func.toStr(payableFee.getCargoName()) + " 第" + Func.toStr(payableFee.getLineNo()) + "行]");
}
} else {
appendEntryGroups(entryGroups, cargoCodeByName, settlementDetail.getCargoType(),
resolveMeasureunitNumber(null, settlementDetail.getQuantityUnit()),
settlementDetail.getId(),
money(settlementDetail.getSettlementAmountTax()), money(settlementDetail.getSettlementAmountNoTax()),
money(settlementDetail.getTransportQuantity()),
"结算明细[" + Func.toStr(settlementDetail.getDocumentNo()) + " 第" + Func.toStr(settlementDetail.getLineNo()) + "行]");
if (Func.isEmpty(payableFees)) {
throw new ServiceException("推送金蝶财务应付单失败:结算明细[" + Func.toStr(settlementDetail.getDocumentNo())
+ "]对应应付明细无货物费用行,分录取数必须来自应付费用明细,请先维护费用数据");
}
for (ReceivablePayableCargoFee payableFee : payableFees) {
appendEntryGroups(entryGroups, cargoCodeByName, payableFee.getCargoType(),
resolveMeasureunitNumber(payableFee.getPriceUnit(), payableFee.getQuantityUnit()),
payableFee.getId(), money(payableFee.getUnitPrice()),
money(payableFee.getAfterAmount()),
noTaxByPayableFeeId.getOrDefault(payableFee.getId(), BigDecimal.ZERO),
money(payableFee.getTransportQuantity()),
"应付货物费用[" + Func.toStr(payableFee.getCargoName()) + " 第" + Func.toStr(payableFee.getLineNo()) + "行]");
}
}
if (entryGroups.isEmpty()) {
throw new ServiceException("推送金蝶财务应付单失败:结算明细未解析出任何分录,请检查货物类型维护");
}
return new BfiEntryGroupResult(entryGroups, documentNos);
}
@@ -1431,21 +1426,22 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
}
/**
* 单条来源行(应付货物费用行或结算明细行)生成不聚合分录(每行一条);
* 单条应付货物费用行生成不聚合分录(每行一条);
* 一行含多种货物类型时按类型拆为多条,金额与数量按份数均分(尾差计入最后一份)
*
* @param entryGroups 分录集合(保持行序)
* @param cargoCodeByName 货物类型名称->货物编码映射
* @param cargoType 货物类型(支持“、”分隔多类型)
* @param measureunitNumber 计量单位编码(运费计算单位,档案暂无编码字段暂传单位名称)
* @param sourceRowId 来源行id(应付货物费用行id,兜底结算明细行id),雪花id天然唯一
* @param sourceRowId 应付货物费用行id,雪花id天然唯一
* @param price 该行运输单价(费用明细 unit_price)
* @param amount 该行金额(含税)
* @param amountNoTax 该行金额(不含税)
* @param quantity 该行运输数量
* @param sourceDesc 来源行描述,用于异常提示
*/
private void appendEntryGroups(List<BfiEntryGroup> entryGroups, Map<String, String> cargoCodeByName,
String cargoType, String measureunitNumber, Long sourceRowId,
String cargoType, String measureunitNumber, Long sourceRowId, BigDecimal price,
BigDecimal amount, BigDecimal amountNoTax, BigDecimal quantity, String sourceDesc) {
List<String> cargoNames = splitCargoTypes(cargoType);
if (Func.isBlank(measureunitNumber)) {
@@ -1464,10 +1460,10 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
}
String entryCode = cargoNames.size() > 1 ? rowEntryCode + "-" + (index + 1) : rowEntryCode;
entryGroups.add(new BfiEntryGroup(materialNumber, measureunitNumber, entryCode,
quantityShares.get(index), amountShares.get(index), amountNoTaxShares.get(index)));
log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],计量单位[{}],数量[{}],含税金额[{}],不含税金额[{}]",
quantityShares.get(index), price, amountShares.get(index), amountNoTaxShares.get(index)));
log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],计量单位[{}],数量[{}],单价[{}],含税金额[{}],不含税金额[{}]",
sourceDesc, entryCode, materialNumber, measureunitNumber,
quantityShares.get(index), amountShares.get(index), amountNoTaxShares.get(index));
quantityShares.get(index), price, amountShares.get(index), amountNoTaxShares.get(index));
}
}