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

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 entryGroups 分录集合(保持行序)
* @param cargoCodeByName 货物类型名称->货物编码映射 * @param cargoCodeByName 货物类型名称->货物编码映射
@@ -398,28 +398,21 @@ public class KingdeeApBillSyncSupport {
Long formalSettlementId, String cargoType, String measureunitNumber, Long sourceRowId, Long formalSettlementId, String cargoType, String measureunitNumber, Long sourceRowId,
BigDecimal price, BigDecimal amount, BigDecimal amountNoTax, BigDecimal quantity, BigDecimal price, BigDecimal amount, BigDecimal amountNoTax, BigDecimal quantity,
String sourceDesc) { String sourceDesc) {
List<String> cargoNames = splitCargoTypes(cargoType);
if (Func.isBlank(measureunitNumber)) { if (Func.isBlank(measureunitNumber)) {
throw new ServiceException("推送金蝶财务应付单失败:" + sourceDesc + "计量单位为空,请先维护运费计算单位"); throw new ServiceException("推送金蝶财务应付单失败:" + sourceDesc + "计量单位为空,请先维护运费计算单位");
} }
// 分录唯一标识(awrp_entry_code,A103-1 要求对方系统唯一行id不能重复):雪花id天然唯一,同行多类型拆分时追加序号 // 货物类型含多种时不拆行(业务约定整行一条分录),物料编码取第一种货物类型
String rowEntryCode = String.valueOf(sourceRowId); String cargoName = splitCargoTypes(cargoType).get(0);
List<BigDecimal> amountShares = splitEqually(amount, cargoNames.size()); String materialNumber = cargoCodeByName.get(cargoName);
List<BigDecimal> amountNoTaxShares = splitEqually(amountNoTax, cargoNames.size()); if (Func.isBlank(materialNumber)) {
List<BigDecimal> quantityShares = splitEqually(quantity, cargoNames.size()); throw new ServiceException("推送金蝶财务应付单失败:" + sourceDesc + "货物类型[" + cargoName + "]未在货物类型档案中维护编码,请补充后重试");
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));
} }
// 分录唯一标识(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,用于不含税金额回链应付费用行) */ /** 付款申请关联的正式结算货物费用行(blade_formal_settlement_detail_fee,用于不含税金额回链应付费用行) */
@@ -521,7 +514,10 @@ public class KingdeeApBillSyncSupport {
return Func.isBlank(unitName) ? null : unitName.trim(); return Func.isBlank(unitName) ? null : unitName.trim();
} }
/** 货物类型支持“、/,”分隔的多类型写法,拆分为单类型名称 */ /**
* 货物类型支持“、/,”分隔的多类型写法,解析为类型名称列表;
* 分录不按类型拆行(业务约定整行一条),物料编码仅取列表第一种类型
*/
private List<String> splitCargoTypes(String cargoType) { private List<String> splitCargoTypes(String cargoType) {
if (Func.isBlank(cargoType)) { if (Func.isBlank(cargoType)) {
throw new ServiceException("推送金蝶财务应付单失败:结算明细货物类型为空,无法解析物料编码"); throw new ServiceException("推送金蝶财务应付单失败:结算明细货物类型为空,无法解析物料编码");
@@ -530,25 +526,6 @@ public class KingdeeApBillSyncSupport {
.map(String::trim).filter(Func::isNotBlank).distinct().toList(); .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 materialNumber 物料编码(货物类型档案货物编码)
* @param measureunitNumber 计量单位编码(运费计算单位,档案暂无编码字段暂传单位名称) * @param measureunitNumber 计量单位编码(运费计算单位,档案暂无编码字段暂传单位名称)
* @param entryCode 分录唯一标识(awrp_entry_code):费用明细行id,同行多货物类型拆分时追加序号 * @param entryCode 分录唯一标识(awrp_entry_code):费用明细行id,雪花id天然唯一
* @param quantity 该行运输数量 * @param quantity 该行运输数量
* @param price 该行运输单价(费用明细 unit_price) * @param price 该行运输单价(费用明细 unit_price)
* @param amount 该行金额(含税),对应明细应付金额 e_pricetaxtotal * @param amount 该行金额(含税),对应明细应付金额 e_pricetaxtotal