⚡ 金蝶应付单分录不再按多货物类型拆行:整行一条分录,物料编码取第一种货物类型

This commit is contained in:
刘泉佳
2026-09-18 21:07:12 +08:00
parent e79c4ce888
commit 0e1334be23
@@ -379,8 +379,8 @@ public class KingdeeApBillSyncSupport {
}
/**
* 单条应付货物费用行生成不聚合分录(每行一条);
* 一行含多种货物类型时按类型拆为多条,金额与数量按份数均分(尾差计入最后一份)
* 单条应付货物费用行生成一条分录;
* 货物类型含多种(“、/,”分隔)时不拆行,物料编码取第一种货物类型,金额数量整行直送
*
* @param entryGroups 分录集合(保持行序)
* @param cargoCodeByName 货物类型名称->货物编码映射
@@ -398,28 +398,21 @@ public class KingdeeApBillSyncSupport {
Long formalSettlementId, 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)) {
throw new ServiceException("推送金蝶财务应付单失败:" + sourceDesc + "计量单位为空,请先维护运费计算单位");
}
// 分录唯一标识(awrp_entry_code,A103-1 要求对方系统唯一行id不能重复):雪花id天然唯一,同行多类型拆分时追加序号
String rowEntryCode = String.valueOf(sourceRowId);
List<BigDecimal> amountShares = splitEqually(amount, cargoNames.size());
List<BigDecimal> amountNoTaxShares = splitEqually(amountNoTax, cargoNames.size());
List<BigDecimal> quantityShares = splitEqually(quantity, cargoNames.size());
for (int index = 0; index < cargoNames.size(); index++) {
String cargoName = cargoNames.get(index);
String materialNumber = cargoCodeByName.get(cargoName);
if (Func.isBlank(materialNumber)) {
throw new ServiceException("推送金蝶财务应付单失败:" + sourceDesc + "货物类型[" + cargoName + "]未在货物类型档案中维护编码,请补充后重试");
}
String entryCode = cargoNames.size() > 1 ? rowEntryCode + "-" + (index + 1) : rowEntryCode;
entryGroups.add(new BfiEntryGroup(materialNumber, measureunitNumber, entryCode,
quantityShares.get(index), price, amountShares.get(index), amountNoTaxShares.get(index), formalSettlementId));
log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],计量单位[{}],数量[{}],单价[{}],含税金额[{}],不含税金额[{}]",
sourceDesc, entryCode, materialNumber, measureunitNumber,
quantityShares.get(index), price, amountShares.get(index), amountNoTaxShares.get(index));
// 货物类型含多种时不拆行(业务约定整行一条分录),物料编码取第一种货物类型
String cargoName = splitCargoTypes(cargoType).get(0);
String materialNumber = cargoCodeByName.get(cargoName);
if (Func.isBlank(materialNumber)) {
throw new ServiceException("推送金蝶财务应付单失败:" + sourceDesc + "货物类型[" + cargoName + "]未在货物类型档案中维护编码,请补充后重试");
}
// 分录唯一标识(awrp_entry_code,A103-1 要求对方系统唯一行id不能重复):应付货物费用行id,雪花id天然唯一
String entryCode = String.valueOf(sourceRowId);
entryGroups.add(new BfiEntryGroup(materialNumber, measureunitNumber, entryCode,
quantity, price, amount, amountNoTax, formalSettlementId));
log.info("金蝶应付单分录生成:来源[{}],分录标识[{}],物料编码[{}],计量单位[{}],数量[{}],单价[{}],含税金额[{}],不含税金额[{}]",
sourceDesc, entryCode, materialNumber, measureunitNumber, quantity, price, amount, amountNoTax);
}
/** 付款申请关联的正式结算货物费用行(blade_formal_settlement_detail_fee,用于不含税金额回链应付费用行) */
@@ -521,7 +514,10 @@ public class KingdeeApBillSyncSupport {
return Func.isBlank(unitName) ? null : unitName.trim();
}
/** 货物类型支持“、/,”分隔的多类型写法,拆分为单类型名称 */
/**
* 货物类型支持“、/,”分隔的多类型写法,解析为类型名称列表;
* 分录不按类型拆行(业务约定整行一条),物料编码仅取列表第一种类型
*/
private List<String> splitCargoTypes(String cargoType) {
if (Func.isBlank(cargoType)) {
throw new ServiceException("推送金蝶财务应付单失败:结算明细货物类型为空,无法解析物料编码");
@@ -530,25 +526,6 @@ public class KingdeeApBillSyncSupport {
.map(String::trim).filter(Func::isNotBlank).distinct().toList();
}
/** 数值按份数均分(保留 2 位小数、向下取整,尾差计入最后一份) */
private List<BigDecimal> splitEqually(BigDecimal total, int parts) {
if (parts <= 1) {
return List.of(total);
}
List<BigDecimal> shares = new ArrayList<>(parts);
BigDecimal remaining = total;
for (int index = 0; index < parts; index++) {
if (index == parts - 1) {
shares.add(remaining);
} else {
BigDecimal share = total.divide(BigDecimal.valueOf(parts), 2, RoundingMode.DOWN);
shares.add(share);
remaining = remaining.subtract(share);
}
}
return shares;
}
// ==================== 金蝶公共校验与档案取数 ====================
/**
@@ -685,7 +662,7 @@ public class KingdeeApBillSyncSupport {
*
* @param materialNumber 物料编码(货物类型档案货物编码)
* @param measureunitNumber 计量单位编码(运费计算单位,档案暂无编码字段暂传单位名称)
* @param entryCode 分录唯一标识(awrp_entry_code):费用明细行id,同行多货物类型拆分时追加序号
* @param entryCode 分录唯一标识(awrp_entry_code):费用明细行id,雪花id天然唯一
* @param quantity 该行运输数量
* @param price 该行运输单价(费用明细 unit_price)
* @param amount 该行金额(含税),对应明细应付金额 e_pricetaxtotal