diff --git a/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java b/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java index f2e8697..380130b 100644 --- a/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java +++ b/jianshui-admin/src/main/java/com/jianshui/api/controller/http/invoice/v1/InvoiceController.java @@ -1,6 +1,8 @@ package com.jianshui.api.controller.http.invoice.v1; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; @@ -11,13 +13,16 @@ import com.jianshui.common.exception.jianshui.JianshuiParamErrorException; import com.jianshui.common.exception.jianshui.JianshuiServiceException; import com.jianshui.common.utils.StringUtils; import com.jianshui.common.utils.http.HttpHelper; +import com.jianshui.common.utils.uuid.IdUtils; import com.jianshui.invoice.constant.elephant.ElephantConstants; import com.jianshui.invoice.domain.BillInfo; import com.jianshui.invoice.domain.FindRedInfo; +import com.jianshui.invoice.domain.InvoiceBack; import com.jianshui.invoice.domain.ele.EleNewMessage; import com.jianshui.invoice.domain.ele.EleOuterMessage; import com.jianshui.invoice.domain.ele.FindRedInfoDTO; import com.jianshui.invoice.domain.ele.HZSQDMessage; +import com.jianshui.invoice.mapper.InvoiceBackMapper; import com.jianshui.invoice.task.InvoiceBackTask; import com.jianshui.invoice.utils.elephant.ElephantUtils; import com.jianshui.platform.dto.InvoiceAdd.BillInfoPDTO; @@ -44,6 +49,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.util.Date; import java.util.List; /** @@ -75,6 +81,9 @@ public class InvoiceController { @Autowired private InvoiceAddPService addService; + @Autowired + private InvoiceBackMapper invoiceBackMapper; + /** @@ -1752,61 +1761,149 @@ public class InvoiceController { * @throws Exception */ @Validated - @ApiOperation("开票请求接口-(蓝字发票开具,红字发票开具)") + @ApiOperation("开票请求接口-(蓝字发票开具,红字发票开具)-异步接口") @ApiImplicitParams({ @ApiImplicitParam(name = "identity", value = "身份认证", dataType = "java.lang.Void", example = "1130", required = true), @ApiImplicitParam(name = "order", value = "请求体", dataType = "java.lang.Void", required = true)}) @PostMapping({"/api/invoice/v1/addInvoiceBatch", "/api/invoice/v1/addInvoiceBatch/{identity}", "/invoice/addInvoiceBatch"}) - public Object addInvoiceBatch(HttpServletRequest request, String identity) throws Exception { - - // TODO: 2023/11/2 批量开票接口 - - - // 摘成异步逻辑,状态码过来所有的错误记录数据库,记录请求过来的数据先 - - + public void addInvoiceBatch(HttpServletRequest request, String identity) throws Exception { + + // 1-前置条件判断 + InvoiceBack invoiceBack = new InvoiceBack(); + invoiceBack.setUpdateTime(new Date()); + invoiceBack.setCreateTime(new Date()); + invoiceBack.setId(IdUtil.randomUUID()); + invoiceBack.setSystemOrderno(IdUtil.randomUUID()); + invoiceBack.setStatus("1"); + invoiceBack.setIdentity(identity); + invoiceBack.setBackMsg(""); + invoiceBack.setBackUrl(""); + + // 1-1 identity校验 if (StringUtils.isEmpty(identity)) { - return AjaxResult.error(ErrorCode.EMPTY_IDENTITY); + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("身份认证参数为空!"); + log.info("[重汽批量开票接口]身份认证参数为空!"); + return; } - Companyservice companyservice = iCompanyserviceService.selectCompanyserviceByIdentity(identity); + // 1-2 企业信息校验 + Companyservice companyservice = null; + try { + companyservice = iCompanyserviceService.selectCompanyserviceByIdentity(identity); + } catch (Exception e) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("企业信息不存在!"); + log.info("[重汽批量开票接口]获取企业信息异常!identity={},e={}",identity,e); + return; + } if (companyservice == null) { - return AjaxResult.error(ErrorCode.COMPANY_NOT_FOUND); + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("企业信息不存在!"); + log.info("[重汽批量开票接口]企业信息不存在!identity={}",identity); + return; } - // 获得入口报文适配器 - String requestAdapterKey = serviceManageService.getRequestAdapterKey("invoice", companyservice.getCompanyid()); - IInvoiceRequestService invoiceRequestService = invoiceRequestFactory.getService(requestAdapterKey); - JSONObject decryptResult = invoiceRequestService.decrypt(request, companyservice, "add"); - - // 报文处理 - BillInfo billInfo = decryptResult.toJavaObject(BillInfo.class); - if (billInfo == null) { - throw new JianshuiParamErrorException(ErrorCode.ERROR_PARAMS, companyservice, "invoice"); + // 1-3 获得入口报文适配器 + JSONObject decryptResult = null; + try { + String requestAdapterKey = serviceManageService.getRequestAdapterKey("invoice", companyservice.getCompanyid()); + IInvoiceRequestService invoiceRequestService = invoiceRequestFactory.getService(requestAdapterKey); + decryptResult = invoiceRequestService.decrypt(request, companyservice, "add"); + } catch (Exception e) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("请求解密失败!"); + log.info("[重汽批量开票接口]请求解密失败!identity={}",identity); + return; + } + + // 2-报文处理 + cn.hutool.json.JSONObject billJson = null; + try { + billJson = JSONUtil.parseObj(decryptResult); + } catch (Exception e) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("未匹配到发票报文!"); + log.info("[重汽批量开票接口]报文格式化异常!identity={},e={}",identity,e); + return; + } + if(billJson.get("billInfo") == null ){ + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("未匹配到发票报文!"); + log.info("[重汽批量开票接口]未匹配到发票报文!identity={}",identity); + return; } - billInfo.setSource("2"); - // 获得请求实例,并且进行扣费 - String serviceKey = serviceManageService.getCompanyServiceSupplier("invoice", companyservice.getCompanyid()); - serviceManageService.companyConsume("invoice", companyservice.getCompanyid()); - billInfo.setServiceSupplierKey(serviceKey); - IInvoiceApiService invoiceService = invoiceServiceFactory.getService(serviceKey); - HXResponse result = invoiceService.addInvoice(billInfo, companyservice); - -// HXResponse result = preHandleDecryptResult(decryptResult, "add", companyservice); - - String responseAdapterKey = serviceManageService.getResponseAdapterKey("invoice", companyservice.getCompanyid()); - IInvoiceResponseService invoiceResponseService = invoiceResponseFactory.getService(responseAdapterKey); - - return invoiceResponseService.response(result, companyservice, "add"); - } - - + JSONArray billJsonArray = null; + try { + billJsonArray = JSONUtil.parseArray(billJson.get("billInfo")); + } catch (Exception e) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("发票报文为空!"); + log.info("[重汽批量开票接口]发票报文获取异常!identity={},e={}",identity,e); + return; + } + if(billJsonArray.size() == 0){ + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("发票报文为空!"); + log.info("[重汽批量开票接口]发票报文为空!identity={}",identity); + return; + } + // 3-报文递交开票 + for (Object billInfoObj : billJsonArray) { + BillInfo billInfo = BeanUtil.copyProperties(billInfoObj,BillInfo.class); + if (billInfo == null) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("报文格式错误!"); + log.info("[重汽批量开票接口]报文格式错误!identity={}",identity); + continue; + } + billInfo.setSource("2"); + // 4-获得请求实例,并且进行扣费 + IInvoiceApiService invoiceService = null; + try { + String serviceKey = serviceManageService.getCompanyServiceSupplier("invoice", companyservice.getCompanyid()); + serviceManageService.companyConsume("invoice", companyservice.getCompanyid()); + billInfo.setServiceSupplierKey(serviceKey); + invoiceService = invoiceServiceFactory.getService(serviceKey); + } catch (Exception e) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("扣费失败!"); + log.info("[重汽批量开票接口]扣费失败!identity={},e={}",identity,e); + continue; + } + // 5-开票 + try { + HXResponse resultHx = invoiceService.addInvoice(billInfo, companyservice); + log.info("[重汽批量开票接口]开票identity={},返回结果result={}",identity,resultHx); + + if(!resultHx.isSuccess()){ + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg(resultHx.getMessage()); + invoiceBack.setSystemOrderno(billInfo.getSystemOrderno()); + invoiceBack.setStatus("0"); + invoiceBackMapper.insertInvoiceBack(invoiceBack); + log.info("[重汽批量开票接口]提交开票异常,开票失败!identity={},msg={}",identity,resultHx.getMessage()); + continue; + } + + } catch (Exception e) { + invoiceBack.setResultCode("9999"); + invoiceBack.setResultMsg("开票失败!"); + invoiceBack.setSystemOrderno(billInfo.getSystemOrderno()); + invoiceBack.setStatus("0"); + invoiceBackMapper.insertInvoiceBack(invoiceBack); + log.info("[重汽批量开票接口]提交开票异常,开票失败!identity={},e={}",identity,e); + continue; + } + } + log.info("[重汽批量开票接口]{},执行完成!",identity); + } diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceBack.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceBack.java index f9b8a12..7ccce4a 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceBack.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/domain/InvoiceBack.java @@ -51,15 +51,16 @@ public class InvoiceBack private String resultCode; /** 更新时间*/ - private String updateTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; - public String getUpdateTime() { + public Date getUpdateTime() { return updateTime; } - public void setUpdateTime(String updateTime) { + public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/BillInfoMapper.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/BillInfoMapper.java index 1cba555..88e7604 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/BillInfoMapper.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/mapper/BillInfoMapper.java @@ -100,4 +100,6 @@ public interface BillInfoMapper extends BaseMapper { public BillInfo selectByOutTradeOrderno(@Param(("companyId")) Long companyId, @Param("out_trade_orderno") String outTradeOrderno); + public BillInfo selectByOutTradeOrdernoNotDel(@Param(("companyId")) Long companyId, @Param("out_trade_orderno") String outTradeOrderno, @Param("updateBy") String updateBy); + } diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java index 95bffaa..69504ac 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java @@ -103,7 +103,7 @@ public class AisinoInvoiceRequestAdapterImpl implements IInvoiceRequestService { // 平台解密 try { // TODO: 2023/9/20 -// order = AisinoInvoiceDecryptUtil.decrypt(order, JKey); + order = AisinoInvoiceDecryptUtil.decrypt(order, JKey); } catch (Exception e) { e.printStackTrace(); throw new JianshuiParamErrorException(ErrorCode.DECRYPT_ERROR, companyservice, "invoice"); diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/AisinoConsoleInvoiceApiZhongQiServiceImpl.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/AisinoConsoleInvoiceApiZhongQiServiceImpl.java index 202b4c3..a488e24 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/AisinoConsoleInvoiceApiZhongQiServiceImpl.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/api/AisinoConsoleInvoiceApiZhongQiServiceImpl.java @@ -115,22 +115,22 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer @Override public HXResponse addInvoice(BillInfo billInfo, Companyservice companyservice) throws IllegalAccessException, InstantiationException { - String outNO = billInfo.getOutTradeOrderno() != null ? billInfo.getOutTradeOrderno() : ""; - if (StrUtil.isEmpty(outNO)) { - return new HXResponse("订单号为空,请检查报文!"); - } + // TODO: 2023/11/6 错误先抛出到这里,后面整理到controller统一管理 + + // 1.订单唯一校验。新增历史订单部分(删除)。 // 订单号唯一校验 start - /*String outNO = billInfo.getOutTradeOrderno() != null ? billInfo.getOutTradeOrderno() : ""; + String outNO = billInfo.getOutTradeOrderno() != null ? billInfo.getOutTradeOrderno() : ""; if (StrUtil.isEmpty(outNO)) { return new HXResponse("订单号为空,请检查报文!"); } - BillInfo billInfoValidate = billInfoMapper.selectByOutTradeOrderno(companyservice.getCompanyid(), outNO); + // update_by 0未删除 1已删除 + BillInfo billInfoValidate = billInfoMapper.selectByOutTradeOrdernoNotDel(companyservice.getCompanyid(), outNO,"0"); if (BeanUtil.isNotEmpty(billInfoValidate)) { return new HXResponse("订单号不允许重复!!!"); - }*/ + } // end - // 预处理:处理billinfo,计算税额等 + // 2.预处理:处理billinfo,计算税额等 try { billInfo = BillInfoUtils.processBillInfo(billInfo, companyservice); } catch (JianshuiParamErrorException e) { @@ -235,7 +235,11 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer } //明细处理前条件校验 - ValidateUtils.validate(aisinoConsoleInvoiceAddDTO, companyservice, null); + try { + ValidateUtils.validate(aisinoConsoleInvoiceAddDTO, companyservice, null); + } catch (RuntimeException e) { + return new HXResponse("订单必填字段校验失败!{}",e.getMessage() != null ? e.getMessage().substring(0,100):""); + } //发票明细处理 List invoiceItems = new ArrayList<>(); @@ -314,7 +318,7 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer //返回报文解析 if (ajaxResult.isError()) { - throw new JianshuiServiceException(ajaxResult.getMsg()); + return new HXResponse(ajaxResult.getMsg()); } cn.hutool.json.JSONObject resultJSON = JSONUtil.parseObj(ajaxResult.get("data")); @@ -327,7 +331,7 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer } AisinoConsoleInvoiceAddVO aisinoConsoleInvoiceAddVO = BeanUtil.copyProperties(resultJSON, AisinoConsoleInvoiceAddVO.class); if (StrUtil.isEmpty(aisinoConsoleInvoiceAddVO.getInfoNumber())) { - throw new JianshuiServiceException("开具的发票号码不存在!"); + return new HXResponse("开具的发票号码不存在!"); } //更新发票状态 billInfo.setState(2); @@ -373,7 +377,6 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer // TODO: 2023/9/26 增加主动回调方式,可配置 - // TODO: 2023/10/25 回调改成异步的,执行10次,直到获取到结果 ICompanyservicePropService companyserviceProp = SpringUtils.getBean(ICompanyservicePropService.class); CompanyserviceProp secretIdProp = companyserviceProp.selectPropByKey(companyservice.getCompanyid(), "aisino_callback_url"); if (BeanUtil.isNotEmpty(secretIdProp) && secretIdProp.getValue() != null && !"".equals(secretIdProp.getValue())) { @@ -923,7 +926,7 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer throw new JianshuiServiceException(ajaxResult.getMsg()); } - /** sb控制台和文档不一样*/ + /** 控制台和文档不一样*/ String retdata = ajaxResult.get("data") != null ? ajaxResult.get("data").toString() : ""; if (StrUtil.isEmpty(retdata)) { return new HXResponse("9999", "下载失败"); @@ -943,14 +946,14 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer // Map map = new HashMap<>(); data = Base64.decodeStr(data, "GB2312"); - if (data.indexOf("") != -1 && data.indexOf("") != -1) { + if (data.contains("") && data.contains("")) { String dataChild = data.substring(data.indexOf("") + 6, data.indexOf("")); cn.hutool.json.JSONObject dataChildJson = JSONUtil.parseObj(dataChild); String RedInvReqBill = dataChildJson.get("RedInvReqBill").toString(); - // TODO: 2023/11/4 这里处理 + // TODO: 2023/11/4 多条明细的这里和单条的不一样,重汽只用多条的 // cn.hutool.json.JSONArray jsonArray = JSONUtil.parseArray(RedInvReqBill); cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(RedInvReqBill); @@ -970,7 +973,7 @@ public class AisinoConsoleInvoiceApiZhongQiServiceImpl implements IInvoiceApiSer return new HXResponse("9999", "系统异常!!!"); } - return new HXResponse("0000", red); + return new HXResponse("0000", "查询成功!",red,true); } } diff --git a/jianshui-invoice/src/main/resources/mapper/invoice/BillInfoMapper.xml b/jianshui-invoice/src/main/resources/mapper/invoice/BillInfoMapper.xml index f514bbb..845ff3a 100644 --- a/jianshui-invoice/src/main/resources/mapper/invoice/BillInfoMapper.xml +++ b/jianshui-invoice/src/main/resources/mapper/invoice/BillInfoMapper.xml @@ -478,6 +478,94 @@ limit 1 + + insert into bill_info