发票验真功能小结

 

1. 在项目中,如果需要将发票导入到发票行中,在导入前会有对增值税专用发票进行验真操作,一般调用公用的外围接口来实现验真发票的头行信息是否准确,是否一致,如果不一致,那么该发票就不允许使用。本项目主要通过HTTP请求来调用大象的发票验真接口,然后将返回的结果存入到表中。

 发票验真功能小结_第1张图片

2. 发票验真的三方地址最好能够配置,增强系统的可配置性:

     */
    private InvoiceHeadCODTO invoiceCheck(Long tenantId,
                                        Long setOfBooksId,
                                        Long invoiceTypeId,
                                        String invoiceType,
                                        String invoiceNo,
                                        String invoiceCode,
                                        String invoiceDate,
                                        String taxNo,
                                        String invoiceAmount,
                                        String checkCode,
                                        String remark,
                                        String invoiceCheckService) {

        //  构造待校验发票的JSON信息
        JSONArray waitCheckInvoiceJson = genInvoiceInfoJson(invoiceType, invoiceNo, invoiceCode, invoiceDate, taxNo, invoiceAmount, checkCode);

        //  构造请求内容
        String postBody = genHxInvoiceCheckPostBody(waitCheckInvoiceJson);

        //  发送HTTP请求
        JSONObject responeJson = null;
        try{
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Content-Type", "application/json;charset=UTF-8");
            httpHeaders.add("Accept", "application/json, text/plain, */*");
            HttpEntity httpEntity;
            httpEntity = new HttpEntity(postBody, httpHeaders);
            String invoiceCheckUrl = hcfOrganizationInterface.getParameterValue(null,OrgInformationUtil.getCurrentSetOfBookId(),"INVOICE_CHECK_URL");
            String responseData = hangxinGeneralService.sendPost(invoiceCheckService + invoiceCheckUrl, httpEntity);
            logger.info("responseData : " + responseData);
            responeJson = JSONObject.fromObject(responseData);
        }catch (Exception e){
            throw new BizException(RespCode.INVOICE_CHECK_HTTP_SEND_ERROR);
        }

        JSONObject returnStateInfo = responeJson.getJSONObject("returnStateInfo");
        if(!"0000".equals(returnStateInfo.getString("returnCode"))){

            //失败也会有详细的信息
            String errorResultCode = "- ";
            String errorResultTip = "; ";

            String data = responeJson.getString("data");
            if(StringUtils.isNotBlank(data)){
                JSONObject errorDataJson = HangxinInvoiceUtils.base64DecodeJson(data);
                JSONArray errorInvoiceList = errorDataJson.getJSONArray("invoiceList");
                if(errorInvoiceList.size() > 0){
                    errorResultCode = errorResultCode + errorInvoiceList.getJSONObject(0).getString("resultCode");
                    errorResultTip = errorResultTip + errorInvoiceList.getJSONObject(0).getString("resultTip");
                }
            }

            throw new BizException(RespCode.INVOICE_CHECK_HX_CHECK_ERROR, new String[]{returnStateInfo.getString("returnCode") + errorResultCode + errorResultTip});
        }

        //  返回数据解密
        String data = responeJson.getString("data");
        JSONObject postResultDataJson = HangxinInvoiceUtils.base64DecodeJson(data);


        //  解析返回内容
        JSONArray invoiceListJsonArr = postResultDataJson.getJSONArray("invoiceList");
        if(invoiceListJsonArr.isEmpty()){
            throw new BizException(RespCode.INVOICE_CHECK_HX_RESULT_ISNULL);
        }
        JSONObject invoiceInfoJson = invoiceListJsonArr.getJSONObject(0).getJSONObject("invoiceInfo");

        //  保存发票验真结果到发票验真日志表
        InvoiceCheckData checkLog = new InvoiceCheckData();
        checkLog.setResultCode(invoiceInfoJson.getString("resultCode"));
        checkLog.setResultTip(invoiceInfoJson.getString("resultTip"));
        checkLog.setInvoiceCode(invoiceInfoJson.getString("invoiceCode"));
        checkLog.setInvoiceNo(invoiceInfoJson.getString("invoiceNo"));
        checkLog.setCheckCount(invoiceInfoJson.getString("checkCount"));
        this.insert(checkLog);

        //  Json对象转Co
        InvoiceCheckHeadDTO invoiceCheckHeadDTO = new InvoiceCheckHeadDTO();

        // 处理发票行信息
        JSONArray invoiceLineJsonArr = invoiceInfoJson.getJSONArray("detailList");
        invoiceLineJsonArr = filterInvoiceLine(invoiceLineJsonArr);
        List invoiceCheckLineDTOList = JSONArray.toList(invoiceLineJsonArr, new InvoiceCheckLineDTO(), new JsonConfig());
        invoiceInfoJson.remove("detailList");
        InvoiceHeadCODTO invoiceHeadCODTO = new InvoiceHeadCODTO();
        invoiceCheckHeadDTO = (InvoiceCheckHeadDTO) JSONObject.toBean(invoiceInfoJson, InvoiceCheckHeadDTO.class);
        invoiceCheckHeadDTO.setDetailList(invoiceCheckLineDTOList);
        invoiceCheckHeadDTO.setRemark(remark);
        invoiceHeadCODTO.setReturnTip(invoiceCheckHeadDTO.getResultTip());
        invoiceHeadCODTO.setReturnCode(invoiceCheckHeadDTO.getResultCode());
        invoiceHeadCODTO.setTaxRate(invoiceCheckHeadDTO.getTaxRate());

        //调用接口成功页可能会有其他错误,要抛出
        if(!"0001".equals(invoiceCheckHeadDTO.getResultCode())){
             return  invoiceHeadCODTO;
        }

        return invoiceResultToInvoiceHeaderCO(invoiceCheckHeadDTO, tenantId, setOfBooksId, invoiceTypeId);
    }

 

3. 验真完后,需要校验发票的信息是否准确,可以通过本地接口再去查验,确保验真的信息是否与客户手上的信息是否一致。确保发票的完整性和准确性。

        在费用行,填单时,手工录入发票前端需要调一个三方接口去查验该发票信息,拿到接口返回的信息后,再在本地接口查验,查验完毕后,录入到票库中(invoice_head),然后前端根据后端返回的查验字段(check_result)的值来判断是否查验成功。

 手工录入的先调用三方接口,然后再调用本地接口校验
 三方接口:
 Request URL: /api/invoice/check/query?roleType=TENANT
Request Method: POST
 
 本地接口校验 ,调用本地接口时,需要将三方接口的返回作为参数使用
 Request URL: /api/invoice/head/check/invoice?roleType=TENANT
Request Method: POST

发票验真功能小结_第2张图片

另外如果票夹中已经存在,那么应该从票夹中导入,在票夹中经过校验的发票才能够被拿来使用:

发票验真功能小结_第3张图片

 

你可能感兴趣的:(项目总结)