|
@@ -150,7 +150,72 @@ public class IVController {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 混票识别 [旧版]
|
|
|
+ * 混票识别 [新版本]
|
|
|
+ */
|
|
|
+ @PostMapping("invoice-iv2")
|
|
|
+ McR invoice_iv2(@RequestBody Map<String, String> data) throws TencentCloudSDKException {
|
|
|
+
|
|
|
+ McException.assertParamException_Null(data, "url");
|
|
|
+ String image = ydClient.convertTemporaryUrl(data.get("url"));
|
|
|
+ log.info("混票识别, 免登地址, {}", image);
|
|
|
+ // 非PDF, 且内存大于3M, 压缩后上传
|
|
|
+ if (UtilMap.getFloat(data, "size") > 3.0f && !UtilMap.getBoolean(data, "isPdf")) {
|
|
|
+ image = imageUrlConvertBase64(image);
|
|
|
+ }
|
|
|
+ if (UtilMap.getFloat(data, "size") > 6.0f && UtilMap.getBoolean(data, "isPdf")) {
|
|
|
+ image = pdfUrlConvertBase64(image);
|
|
|
+ }
|
|
|
+ List<Map> invoices = (List<Map>) txyInvoice.doRecognizeGeneralInvoice(image).get("MixedInvoiceItems");
|
|
|
+ List<McInvoiceDto> result = invoices.stream().map(item -> {
|
|
|
+ Map prop = UtilMap.getMap(UtilMap.getMap(item, "SingleInvoiceInfos"), UtilMap.getString(item, "SubType"));
|
|
|
+ // ppExt: 通用字段定义
|
|
|
+ McInvoiceDto invoiceDto = McInvoiceDto.builder()
|
|
|
+ .name(UtilMap.getString(item, "SubTypeDescription"))
|
|
|
+ .kindName(UtilMap.getString(item, "TypeDescription"))
|
|
|
+ .kind(UtilMap.getInt(item, "Type"))
|
|
|
+ .code(UtilMap.getString(prop, "Code"))
|
|
|
+ .serial(UtilMap.getString(prop, "Number"))
|
|
|
+ .date(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "Date")))
|
|
|
+ .checkCode(UtilMap.getString(prop, "CheckCode"))
|
|
|
+ // ppExt: 多明细行时, 优先取值合计 [全电票返回了subTotal字段, 但值为空]
|
|
|
+ .amount(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "SubTotal", "Total")))
|
|
|
+ .tax(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "SubTax", "Tax")))
|
|
|
+ .excludingTax(UtilNumber.setBigDecimal(UtilMap.getString(prop, "PretaxAmount")))
|
|
|
+ .buyerName(guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))
|
|
|
+ // ppExt: 中央非税未返回税号官方说明: 非税发票理论是没有税号的,图片中属于信用代码
|
|
|
+ .buyerTaxId(UtilMap.getString(prop, "BuyerTaxID"))
|
|
|
+ .sellerName(guyuanNameRepalce(UtilMap.getString_first(prop, "Seller", "Issuer"))) // 行程单: 填开单位
|
|
|
+ .sellerTaxId(UtilMap.getString_first(prop, "SellerTaxID", "AgentCode")) // 行程单: 销售单位代号
|
|
|
+ .passengerName(UtilMap.getString_first(prop, "Name", "UserName")) // 火车票, 行程单
|
|
|
+ // 交通出行
|
|
|
+ .seatType(UtilMap.getString(prop, "Seat"))
|
|
|
+ .departureTime(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"))
|
|
|
+ .departurePort(UtilMap.getString_first(prop, "StationGetOn", "Entrance", "Place")) // 火车票: 出发车站, 过路过桥费: 入口, 出租车: 发票所在地
|
|
|
+ .arrivePort(UtilMap.getString_first(prop, "StationGetOff", "Exit")) // 行程单, 火车票: 到达车站, 过路过桥费: 出口
|
|
|
+ .trainNo(UtilMap.getString_first(prop, "TrainNumber", "LicensePlate")) // 火车票: 车次, 出租车: 车牌号
|
|
|
+ .insuranceCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "Insurance")))) // 行程单: 保险费
|
|
|
+ .fuelCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "FuelSurcharge")))) // 行程单: 燃油附加费
|
|
|
+ .constructionCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "AirDevelopmentFund")))) // 行程单: 民航发展基金
|
|
|
+ .build();
|
|
|
+ // ppExt: 机票行程单, 行程与座位信息在明细内
|
|
|
+ if ("机票行程单".equals(item.get("TypeDescription"))) {
|
|
|
+ Map flight = (Map) UtilMap.getList(prop, "FlightItems").get(0);
|
|
|
+ invoiceDto.setDepartureTime(UtilString.replaceDateZH_cn(UtilMap.getString(item, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"));
|
|
|
+ invoiceDto.setDeparturePort(UtilMap.getString(flight, "StationGetOn"));
|
|
|
+ invoiceDto.setArrivePort(UtilMap.getString(flight, "StationGetOff"));
|
|
|
+ invoiceDto.setSeatType(UtilMap.getString(flight, "Seat"));
|
|
|
+ }
|
|
|
+ if ("出租车发票".equals(item.get("TypeDescription"))) {
|
|
|
+ // 上下车时间
|
|
|
+ invoiceDto.setDepartureTime(UtilMap.getString(prop, "TimeGetOn") + " ~ " + UtilMap.getString(prop, "TimeGetOff"));
|
|
|
+ }
|
|
|
+ return invoiceDto;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ return McR.success(McInvoiceDto.formatResponse(result));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 混票识别 [旧版本, 已废弃]
|
|
|
*/
|
|
|
@PostMapping("invoice-iv")
|
|
|
McR invoice_iv(@RequestBody Map<String, String> data) throws TencentCloudSDKException {
|
|
@@ -207,6 +272,10 @@ public class IVController {
|
|
|
.fuelCosts(UtilNumber.setBigDecimal((findValue(infos, "燃油附加费")))) // 行程单
|
|
|
.constructionCosts(UtilNumber.setBigDecimal((findValue(infos, "民航发展基金")))) // 行程单
|
|
|
.build();
|
|
|
+ // 价格不一致情况下, 通过合计返回
|
|
|
+ if (!UtilNumber.equalBigDecimal(invoiceDto.getAmount(), invoiceDto.getExcludingTax().add(invoiceDto.getTax()))) {
|
|
|
+ invoiceDto.setAmount(invoiceDto.getExcludingTax().add(invoiceDto.getTax()));
|
|
|
+ }
|
|
|
// 机票行程单
|
|
|
if (kind.equals(McInvoiceKind.JP.getDesc())) {
|
|
|
String date = findValue(infos, "日期").replace("年", "-").replace("月", "-").replace("日", " ");
|
|
@@ -252,11 +321,11 @@ public class IVController {
|
|
|
McException.exceptionAccess(serial + "已存在, 请勿重复提交!");
|
|
|
}
|
|
|
// prd 仅仅识别增值税普通发票
|
|
|
- if (dto.getKindName().contains("普通发票")) {
|
|
|
+ if (dto.getName().contains("普通发票")) {
|
|
|
String serialTips = serial + "有疑问";
|
|
|
try {
|
|
|
// ppExt: 识别与验真后抬头对比
|
|
|
- Map rsp = txyInvoice.doVatInvoiceVerifyNew(dto.getKindName(), dto.getCode(), invoiceNo, dto.getDate(), String.valueOf(dto.getAmount()), dto.getCheckCode(), String.valueOf(dto.getExcludingTax()), serialTips);
|
|
|
+ Map rsp = txyInvoice.doVatInvoiceVerifyNew(dto.getName(), dto.getCode(), invoiceNo, dto.getDate(), String.valueOf(dto.getAmount()), dto.getCheckCode(), String.valueOf(dto.getExcludingTax()), serialTips);
|
|
|
Map invoice = (Map) rsp.get("Invoice");
|
|
|
McException.assertAccessException(!dto.getBuyerName().equals(guyuanNameRepalce(invoice.get("BuyerName").toString())), serialTips + ", 购买方名称不匹配!");
|
|
|
McException.assertAccessException(!dto.getBuyerTaxId().equals(invoice.get("BuyerTaxCode")), serialTips + ", 购买方税号不匹配!");
|
|
@@ -266,6 +335,10 @@ public class IVController {
|
|
|
log.error(e.getMessage(), e);
|
|
|
// prd: 上传发票为假发票时,提示:该发票有疑问,请联系财务人员
|
|
|
String message = e.getMessage();
|
|
|
+ // ppExt: 已经是新版本接口, 过滤提示
|
|
|
+ if (message.contains("温馨提示")) {
|
|
|
+ message = message.split("温馨提示")[0];
|
|
|
+ }
|
|
|
if (message.contains("发票不存在")) {
|
|
|
message = "有疑问,请联系财务人员";
|
|
|
}
|
|
@@ -273,8 +346,7 @@ public class IVController {
|
|
|
}
|
|
|
}
|
|
|
}));
|
|
|
-
|
|
|
- return McR.success("发票查重, 验真响应");
|
|
|
+ return McR.success();
|
|
|
}
|
|
|
|
|
|
|
|
@@ -282,7 +354,7 @@ public class IVController {
|
|
|
private YDService ydService;
|
|
|
|
|
|
/**
|
|
|
- * 发票状态更新: 服务注册 // todo 通用服务, { 组件Id: 值, 组件id: 值 }
|
|
|
+ * 发票状态更新: 服务注册
|
|
|
*/
|
|
|
@PostMapping("invoice-up")
|
|
|
McR invoice_va(HttpServletRequest request) {
|
|
@@ -306,7 +378,7 @@ public class IVController {
|
|
|
update.put("radioField_liw7rb2q", "否"); // 提交后, 更新是否退回标识为否
|
|
|
}
|
|
|
|
|
|
- // prd 9.10 更新报销单, 关联到发票:: todo 宜搭服务注册拿不到系统默认字段, 先查询解决:::: 可能是提交校验的原因
|
|
|
+ // prd 9.10 更新报销单, 关联到发票:: ppExt 宜搭服务注册, 提交规则系统默认字段 [详见 YDService]
|
|
|
ydService.operateData2(data, update, YDParam.builder()
|
|
|
.formUuid("FORM-W2A66Z910O9B3LP9C6IYUDPRVWY62DO0YHIILY")
|
|
|
.formInstanceIdList(formInstanceIds)
|