✨ A303-5开票结果回写支持Base64解码响应并补充关键日志
This commit is contained in:
+37
-20
@@ -44,6 +44,8 @@ import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplyQueryDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplySaveDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoiceApplySaveEntryDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoiceApplyOpenApiBillVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoiceApplyOpenApiInvoiceVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoiceApplyVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiOpenApiResultVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
|
||||
@@ -738,6 +740,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
if (Func.isEmpty(applications)) {
|
||||
return "金蝶开票结果回写:无待回写开票申请";
|
||||
}
|
||||
log.info("金蝶开票结果回写开始:待回写开票申请{}笔", applications.size());
|
||||
// 按 serialNo(金蝶开票申请单编号)分批(≤50/批)调 A303-5,销方税号与 A303-1 同源(开票单位→客商档案),按税号分组查询
|
||||
Map<String, InvoiceApplication> applicationBySerialNo = new LinkedHashMap<>();
|
||||
applications.forEach(application -> {
|
||||
@@ -766,6 +769,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
}
|
||||
serialNosBySellerTaxNo.computeIfAbsent(sellerTaxNo, key -> new ArrayList<>()).add(entry.getKey());
|
||||
}
|
||||
log.info("金蝶开票结果回写:按销方税号分组完成,共{}组,销方税号无法解析跳过{}笔", serialNosBySellerTaxNo.size(), unresolved);
|
||||
int invoiceWritten = 0;
|
||||
int failed = 0;
|
||||
int invoicedCount = 0;
|
||||
@@ -773,34 +777,28 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
List<String> groupSerialNos = group.getValue();
|
||||
for (int from = 0; from < groupSerialNos.size(); from += INVOICE_RESULT_QUERY_BATCH) {
|
||||
List<String> batch = groupSerialNos.subList(from, Math.min(from + INVOICE_RESULT_QUERY_BATCH, groupSerialNos.size()));
|
||||
String batchSerialNos = String.join(",", batch);
|
||||
log.info("金蝶开票结果回写批次查询:销方税号=[{}],单据编号=[{}],数量={}", group.getKey(), batchSerialNos, batch.size());
|
||||
try {
|
||||
BfiInvoiceApplyOpenApiQueryDTO param = new BfiInvoiceApplyOpenApiQueryDTO();
|
||||
param.setSerialNo(String.join(",", batch));
|
||||
param.setSerialNo(batchSerialNos);
|
||||
param.setSellerTaxpayerId(group.getKey());
|
||||
BfiOpenApiResultVO<List<Object>> result = bfiService.queryInvoiceApplyInvoice(param);
|
||||
BfiOpenApiResultVO<List<BfiInvoiceApplyOpenApiBillVO>> result = bfiService.queryInvoiceApplyInvoice(param);
|
||||
if (result == null || !result.isSuccess() || result.getData() == null) {
|
||||
failed++;
|
||||
log.warn("金蝶开票结果回写批次查询未成功:serialNo=[{}]", String.join(",", batch));
|
||||
log.warn("金蝶开票结果回写批次查询未成功:serialNo=[{}]", batchSerialNos);
|
||||
continue;
|
||||
}
|
||||
for (Object billItem : result.getData()) {
|
||||
if (!(billItem instanceof Map)) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> billMap = (Map<?, ?>) billItem;
|
||||
String billNo = firstText(billMap, "billNo", "billno");
|
||||
log.info("金蝶开票结果回写批次查询成功:serialNo=[{}],返回单据数={}", batchSerialNos, result.getData().size());
|
||||
for (BfiInvoiceApplyOpenApiBillVO bill : result.getData()) {
|
||||
String billNo = bill.getBillNo();
|
||||
InvoiceApplication application = applicationBySerialNo.get(billNo);
|
||||
if (application == null || !(billMap.get("invoiceList") instanceof List)) {
|
||||
if (application == null || bill.getInvoiceList() == null) {
|
||||
continue;
|
||||
}
|
||||
int inserted = 0;
|
||||
for (Object invoiceItem : (List<?>) billMap.get("invoiceList")) {
|
||||
if (!(invoiceItem instanceof Map)) {
|
||||
continue;
|
||||
}
|
||||
Map<?, ?> invoice = (Map<?, ?>) invoiceItem;
|
||||
// 宽松提取关键字段(票易通原文,字段名联调校准后收敛),原文整体 JSON 留档
|
||||
String invoiceNo = firstText(invoice, "invoiceNo", "invoice_no", "invoiceNumber");
|
||||
for (BfiInvoiceApplyOpenApiInvoiceVO invoice : bill.getInvoiceList()) {
|
||||
String invoiceNo = invoice.getInvoiceNumber();
|
||||
if (Func.isBlank(invoiceNo)) {
|
||||
continue;
|
||||
}
|
||||
@@ -809,17 +807,20 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
.eq(InvoiceApplicationInvoice::getInvoiceApplicationId, application.getId())
|
||||
.eq(InvoiceApplicationInvoice::getInvoiceNo, invoiceNo));
|
||||
if (exists != null && exists > 0) {
|
||||
log.debug("金蝶开票结果回写:发票号码[{}]已存在,跳过", invoiceNo);
|
||||
continue;
|
||||
}
|
||||
InvoiceApplicationInvoice record = new InvoiceApplicationInvoice();
|
||||
record.setInvoiceApplicationId(application.getId());
|
||||
record.setSerialNo(billNo);
|
||||
record.setInvoiceNo(invoiceNo);
|
||||
record.setInvoiceDate(parseInvoiceDate(firstText(invoice, "invoiceDate", "invoice_date", "issueDate", "billingDate")));
|
||||
record.setInvoiceAmount(parseDecimal(firstText(invoice, "amountWithTax", "totalAmount", "invoiceAmount", "priceTaxTotal")));
|
||||
record.setInvoiceDate(parseInvoiceDateTimestamp(invoice.getInvoiceDate()));
|
||||
record.setInvoiceAmount(invoice.getIncludeTaxAmount());
|
||||
record.setRawJson(JsonUtil.toJson(invoice));
|
||||
invoiceApplicationInvoiceMapper.insert(record);
|
||||
inserted++;
|
||||
log.info("金蝶开票结果回写:写入发票,申请单号=[{}],单据编号=[{}],发票号码=[{}],含税金额=[{}]",
|
||||
application.getApplicationNo(), billNo, invoiceNo, invoice.getIncludeTaxAmount());
|
||||
}
|
||||
if (inserted > 0) {
|
||||
invoiceWritten += inserted;
|
||||
@@ -827,14 +828,17 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
application.setKingdeeStatus(KingdeeBfiConstant.KINGDEE_STATUS_INVOICED);
|
||||
updateById(application);
|
||||
invoicedCount++;
|
||||
log.info("金蝶开票结果回写:开票申请[{}]状态推进为invoiced,本次写入发票{}张", application.getApplicationNo(), inserted);
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
failed++;
|
||||
log.error("金蝶开票结果回写批次异常:serialNo=[{}]", String.join(",", batch), exception);
|
||||
log.error("金蝶开票结果回写批次异常:serialNo=[{}]", batchSerialNos, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("金蝶开票结果回写完成:待查开票申请{}笔(销方税号无法解析跳过{}笔),回写发票{}张(开票完成{}笔,失败批次{}个)",
|
||||
applications.size(), unresolved, invoiceWritten, invoicedCount, failed);
|
||||
return "金蝶开票结果回写完成:待查开票申请" + applications.size() + "笔(销方税号无法解析跳过" + unresolved
|
||||
+ "笔),回写发票" + invoiceWritten + "张(开票完成" + invoicedCount + "笔,失败批次" + failed + "个)";
|
||||
}
|
||||
@@ -877,6 +881,19 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 解析时间戳格式的开票日期(毫秒时间戳),无法解析返回 null */
|
||||
private LocalDateTime parseInvoiceDateTimestamp(Long timestamp) {
|
||||
if (timestamp == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return LocalDateTime.ofInstant(java.time.Instant.ofEpochMilli(timestamp), java.time.ZoneId.systemDefault());
|
||||
} catch (Exception exception) {
|
||||
log.warn("金蝶开票结果开票日期时间戳解析失败:[{}]", timestamp);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** 宽松解析金额文本,无法解析返回 null */
|
||||
private BigDecimal parseDecimal(String text) {
|
||||
if (Func.isBlank(text)) {
|
||||
|
||||
Reference in New Issue
Block a user