feat: 金蝶收票单A303-2分录不送税收分类编码/税率/税额并去物料编码尾部0
This commit is contained in:
+13
-34
@@ -261,8 +261,8 @@ public class KingdeeReceivedInvoiceSyncSupport {
|
||||
/**
|
||||
* 分录组装:逐行取发票明细行(镜像 items_json 反序列化为 {@link BfiInvoicePoolItemVO}),一条明细行一条分录:
|
||||
* 价税合计=明细金额+税额(合计为 0 拦截);数量取 num(≤0/空/不可解析兜底 1);单价取 unitPrice(空按价税合计/数量反算);
|
||||
* 物料编码与税收分类编码取行商品编码 goodsCode(缺失拦截);税率表编码="V"+整数税率(13/13%/0.13→V13,
|
||||
* 缺失、0/免税行拦截提示人工);不含税金额/税额取明细金额/税额(空不送);分录标识=发票号码_seq(重推幂等候选键)
|
||||
* 物料编码取行商品编码 goodsCode(缺失拦截,去尾部 0);不含税金额取明细金额(空不送);
|
||||
* 税收分类编码/税率表编码/税额不送;分录标识=发票号码_seq(重推幂等候选键)
|
||||
*
|
||||
* @param receipt 收票登记(发票号码,分录标识前缀)
|
||||
* @param mirror 票池镜像(明细行 items_json)
|
||||
@@ -291,7 +291,7 @@ public class KingdeeReceivedInvoiceSyncSupport {
|
||||
throw new ServiceException("推送金蝶收票单失败:发票[" + receipt.getInvoiceNo() + "]分录[" + seq + "]价税合计为 0,无法推送");
|
||||
}
|
||||
if (Func.isBlank(item.getGoodsCode())) {
|
||||
throw new ServiceException("推送金蝶收票单失败:发票[" + receipt.getInvoiceNo() + "]分录[" + seq + "]缺少行商品编码,无法确定物料与税收分类编码");
|
||||
throw new ServiceException("推送金蝶收票单失败:发票[" + receipt.getInvoiceNo() + "]分录[" + seq + "]缺少行商品编码,无法确定物料编码");
|
||||
}
|
||||
BfiReceivedInvoiceSaveEntryDTO entry = new BfiReceivedInvoiceSaveEntryDTO();
|
||||
entry.setEPricetaxtotal(priceTaxTotal);
|
||||
@@ -299,19 +299,13 @@ public class KingdeeReceivedInvoiceSyncSupport {
|
||||
entry.setQuantity(this.mirrorQuantity(item.getNum()));
|
||||
// 【必填】单价:明细行单价(空按价税合计/数量反算;单据头 isincludetax=true,单价仅作参考)
|
||||
entry.setPrice(this.mirrorPrice(item.getUnitPrice(), priceTaxTotal, entry.getQuantity()));
|
||||
// 【必填】物料编码.编码:行商品编码
|
||||
entry.setMaterialNumber(item.getGoodsCode().trim());
|
||||
// 税收分类编码.编码:数电票行商品编码即税收分类编码
|
||||
entry.setETaxclassNumber(item.getGoodsCode().trim());
|
||||
// 【必填】税率表.编码:"V"+整数税率(缺失、0/免税行拦截提示人工)
|
||||
entry.setTaxrateidNumber(this.taxRateCode(receipt.getInvoiceNo(), seq, item.getTaxRate()));
|
||||
// 金额(不含税)/税额:明细金额/税额(空不送)
|
||||
// 【必填】物料编码.编码:行商品编码(金蝶档案不含末尾补零,去掉尾部 0)
|
||||
String goodsCode = this.stripTrailingZeros(item.getGoodsCode().trim());
|
||||
entry.setMaterialNumber(goodsCode);
|
||||
// 金额(不含税):明细金额(空不送);税收分类编码/税率表编码/税额不送,税额仅参与价税合计
|
||||
if (detailAmount != null) {
|
||||
entry.setEAmount(kingdeeApBillSyncSupport.money(detailAmount));
|
||||
}
|
||||
if (taxAmount != null) {
|
||||
entry.setETax(kingdeeApBillSyncSupport.money(taxAmount));
|
||||
}
|
||||
// 【必填】外部系统来源分录标识(候选键):发票号码_seq,重推同键幂等
|
||||
entry.setAwrpEntryCode(receipt.getInvoiceNo() + "_" + seq);
|
||||
entries.add(entry);
|
||||
@@ -319,6 +313,12 @@ public class KingdeeReceivedInvoiceSyncSupport {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/** 商品编码去尾部 0:金蝶物料编码档案不含末尾补零(如 3010102020100000000→30101020201);全 0 兜底保留原值 */
|
||||
private String stripTrailingZeros(String code) {
|
||||
String stripped = code.replaceAll("0+$", "");
|
||||
return stripped.isEmpty() ? code : stripped;
|
||||
}
|
||||
|
||||
/** 镜像明细行反序列化:items_json 解析异常按脏数据拦截(A801-1 原样落库,理论上可解析) */
|
||||
private List<BfiInvoicePoolItemVO> parseMirrorItems(String invoiceNo, String itemsJson) {
|
||||
try {
|
||||
@@ -347,27 +347,6 @@ public class KingdeeReceivedInvoiceSyncSupport {
|
||||
return result.setScale(4, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/** 镜像税率转税率表编码:"V"+整数税率(13/13%/0.13→V13);缺失、零/免税行拦截提示人工 */
|
||||
private String taxRateCode(String invoiceNo, String seq, String taxRateText) {
|
||||
if (Func.isBlank(taxRateText)) {
|
||||
throw new ServiceException("推送金蝶收票单失败:发票[" + invoiceNo + "]分录[" + seq + "]税率缺失,无法映射税率表,请人工核实");
|
||||
}
|
||||
BigDecimal rate;
|
||||
try {
|
||||
rate = new BigDecimal(taxRateText.trim().replace("%", ""));
|
||||
} catch (NumberFormatException exception) {
|
||||
throw new ServiceException("推送金蝶收票单失败:发票[" + invoiceNo + "]分录[" + seq + "]税率[" + taxRateText.trim() + "]无法识别,请人工核实");
|
||||
}
|
||||
if (rate.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException("推送金蝶收票单失败:发票[" + invoiceNo + "]分录[" + seq + "]为免税/零税率行,无法映射税率表,请人工核实");
|
||||
}
|
||||
// 小于 1 的小数按比率换算百分比(0.13→13),"1" 按百分比(1%→V1)
|
||||
if (rate.compareTo(BigDecimal.ONE) < 0) {
|
||||
rate = rate.multiply(BigDecimal.valueOf(100));
|
||||
}
|
||||
return "V" + rate.stripTrailingZeros().toPlainString();
|
||||
}
|
||||
|
||||
/** 镜像明细数值解析:空返回 null,不可解析返回 null(数量/单价有兜底,金额空不送) */
|
||||
private BigDecimal parseMirrorAmountQuietly(String value) {
|
||||
if (Func.isBlank(value)) {
|
||||
|
||||
Reference in New Issue
Block a user