package com.jianshui.invoiceall.service.impl;
import java.util.Date;

import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;

import java.math.BigDecimal;


import java.util.*;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.core.domain.entity.Companyservice;
import com.jianshui.common.enums.ErrorCode;
import com.jianshui.common.utils.HutoolUtilsPro;
import com.jianshui.common.utils.StringUtils;
import com.jianshui.common.utils.ValidateUtils;
import com.jianshui.common.utils.uuid.IdUtils;
import com.jianshui.framework.manager.AsyncManager;
import com.jianshui.invoice.domain.BillDetail;
import com.jianshui.invoice.domain.BillInfo;
import com.jianshui.invoice.domain.Invoice;
import com.jianshui.invoice.mapper.BillInfoMapper;
import com.jianshui.invoice.mapper.InvoiceMapper;
import com.jianshui.common.constant.WebServiceConstant;
import com.jianshui.system.domain.InvoiceAllApiLog;
import com.jianshui.system.domain.InvoiceAllYhdj;
import com.jianshui.invoiceall.domain.dto.*;
import com.jianshui.invoiceall.domain.dto.jcsk.*;
import com.jianshui.invoiceall.domain.dto.jcsk.add.*;
import com.jianshui.invoiceall.domain.dto.jcsk.red.AddRedInvoiceDTO;
import com.jianshui.invoiceall.domain.vo.InvoiceAllKschVO;
import com.jianshui.invoiceall.domain.vo.jcsk.AddInvoiceVO;
import com.jianshui.invoiceall.domain.vo.jcsk.AddRedInvoiceVO;
import com.jianshui.invoiceall.domain.vo.jcsk.KschVO;
import com.jianshui.system.mapper.InvoiceAllApiLogMapper;
import com.jianshui.system.mapper.InvoiceAllYhdjMapper;
import com.jianshui.invoiceall.service.IInvoiceAll;
import com.jianshui.common.utils.jcsk.ApiHttp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;


/**
 * 大象进项发票认证
 *
 * @author xkng
 * @date 2022/9/9 16:03
 */
@Component(value = "elephant_invoiceall") // 这里是后台字典的服务配置键值 配置的
public class InvoiceAllImpl implements IInvoiceAll {

    private static final Logger log = LoggerFactory.getLogger(InvoiceAllImpl.class);

    @Autowired
    private BillInfoMapper billInfoMapper;

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private InvoiceAllApiLogMapper allApiLogMapper;

    @Autowired
    private InvoiceAllYhdjMapper yhdjMapper;


    /**
     * 用户登记
     *
     * @return
     */
    @Override
    public AjaxResult registration(Companyservice companyservice, InvoiceAllYhdjDTO invoiceAllYhdjDTO) {

        YhdjDTO yhdjDTO = BeanUtil.copyProperties(invoiceAllYhdjDTO, YhdjDTO.class);
        ValidateUtils.validate(yhdjDTO);
        if (BeanUtil.isEmpty(invoiceAllYhdjDTO.getJsonData())) {
            return AjaxResult.error("传入报文错误，请检查,明细不存在！");
        }
        YhdjDetailDTO yhdjDetailDTOList = BeanUtil.copyProperties(invoiceAllYhdjDTO.getJsonData(), YhdjDetailDTO.class);
        ValidateUtils.validate(yhdjDetailDTOList);
        yhdjDTO.setJsonData(yhdjDetailDTOList);

//        JSONObject result = null;
        JSONObject result = new JSONObject();

        try {
            result = ApiHttp.request(WebServiceConstant.YHDJ, WebServiceConstant.URL, yhdjDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code)) {
                InvoiceAllYhdj yhdj = BeanUtil.copyProperties(yhdjDTO.getJsonData(), InvoiceAllYhdj.class);
                yhdj.setDqbm(yhdjDTO.getDqbm());
                QueryWrapper<InvoiceAllYhdj> yhdjQueryWrapper = new QueryWrapper<>();
                yhdjQueryWrapper.eq("nsrsbh", yhdj.getNsrsbh());
                yhdjQueryWrapper.eq("identity", companyservice.getIdentity());
                InvoiceAllYhdj yhdjTemp = yhdjMapper.selectOne(yhdjQueryWrapper);

                if (BeanUtil.isNotEmpty(yhdjTemp)) {
                    BeanUtil.copyProperties(yhdj,yhdjTemp,CopyOptions.create().setIgnoreNullValue(true)) ;
                    yhdjTemp.setUpdateTime(new Date());
                    yhdjMapper.updateInvoiceAllYhdj(yhdjTemp);
                } else {
                    yhdj.setCreateTime(new Date());
                    yhdj.setIdentity(companyservice.getIdentity());
                    yhdjMapper.insertInvoiceAllYhdj(yhdj);
                }
            } else {
                return AjaxResult.error(msg);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【用户登记】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /**
     * 通用查询接口
     *
     * @return
     */
    @Override
    public AjaxResult generalQuery(Companyservice companyservice, InvoiceAllQueryDTO invoiceAllQueryDTO) {

        QueryDTO queryDTO = BeanUtil.copyProperties(invoiceAllQueryDTO, QueryDTO.class);
        ValidateUtils.validate(queryDTO);

        String requestId = queryDTO.getRequestId();
        String serviceId = "";

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.TYCXJK, WebServiceConstant.URL, queryDTO, companyservice);


            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {

                // 2022/12/13 这里所有的接口都走，需要根据具体的id判断接口来存库。

                QueryWrapper<InvoiceAllApiLog> apiLogQueryWrapper = new QueryWrapper<>();
                apiLogQueryWrapper.eq("request_id",requestId);
                InvoiceAllApiLog allApiLog = allApiLogMapper.selectOne(apiLogQueryWrapper);
                if(BeanUtil.isNotEmpty(allApiLog) && StrUtil.isNotEmpty(allApiLog.getRequestId())){
                    serviceId = allApiLog.getRequestId();
                }

                String finalServiceId = serviceId;
                AsyncManager.me().execute(
                        new TimerTask() {
                            @Override
                            public void run() {
                                if (WebServiceConstant.LZFPKJ.equals(finalServiceId)) {
                                    // 蓝字发票开具
                                    AddInvoiceVO addInvoiceVO = BeanUtil.copyProperties(data, AddInvoiceVO.class);

                                    if(BeanUtil.isNotEmpty(addInvoiceVO)){
                                        QueryWrapper<BillInfo> billInfoQueryWrapper = new QueryWrapper<>();
                                        billInfoQueryWrapper.eq("out_trade_orderno", requestId);
                                        BillInfo billInfo = billInfoMapper.selectOne(billInfoQueryWrapper);
                                        if (BeanUtil.isNotEmpty(billInfo)) {
                                            QueryWrapper<Invoice> invoiceQueryWrapper = new QueryWrapper<>();
                                            invoiceQueryWrapper.eq("out_trade_orderno", requestId);
                                            Invoice invoice = invoiceMapper.selectOne(invoiceQueryWrapper);
                                            if (BeanUtil.isNotEmpty(invoice)) {
                                                invoice = BeanUtil.copyProperties(billInfo, Invoice.class);
                                                invoice.setFphm(addInvoiceVO.getFphm());
                                                invoice.setKprq(DateUtil.parse(addInvoiceVO.getKprq()));
                                                invoice.setZzfpdm(addInvoiceVO.getZzfpdm());
                                                invoice.setZzfphm(addInvoiceVO.getZzfphm());
                                                //二维码=二维码下载地址
                                                invoice.setQrCode(addInvoiceVO.getEwmUrl());
                                                //发票 pdf 地址=PDF格式下载地址
                                                invoice.setInvoicePdfUrl(addInvoiceVO.getPdfUrl());
                                                //发票详情地址=OFD格式下载地址
                                                invoice.setInvoiceJpgUrl(addInvoiceVO.getOfdUrl());
                                                //ofdUrl=XML格式下载地址
                                                invoice.setcOfdUrl(addInvoiceVO.getXmlUrl());
                                                invoice.setState(2);
                                                invoiceMapper.updateInvoice(invoice);
                                                billInfo.setState(2);
                                                billInfoMapper.updateById(billInfo);
                                            } else {
                                                invoice = BeanUtil.copyProperties(billInfo, Invoice.class);
                                                invoice.setFphm(addInvoiceVO.getFphm());
                                                invoice.setKprq(DateUtil.parse(addInvoiceVO.getKprq()));
                                                invoice.setZzfpdm(addInvoiceVO.getZzfpdm());
                                                invoice.setZzfphm(addInvoiceVO.getZzfphm());
                                                //二维码=二维码下载地址
                                                invoice.setQrCode(addInvoiceVO.getEwmUrl());
                                                //发票 pdf 地址=PDF格式下载地址
                                                invoice.setInvoicePdfUrl(addInvoiceVO.getPdfUrl());
                                                //发票详情地址=OFD格式下载地址
                                                invoice.setInvoiceJpgUrl(addInvoiceVO.getOfdUrl());
                                                //ofdUrl=XML格式下载地址
                                                invoice.setcOfdUrl(addInvoiceVO.getXmlUrl());
                                                invoice.setState(2);
                                                invoiceMapper.insertInvoice(invoice);
                                                billInfo.setState(2);
                                                billInfoMapper.updateById(billInfo);
                                            }
                                        } else {
                                            log.error("【金四服务类】【金财数科】【通用查询接口】API请求异常，billInfo未查询到，requestId={}。", requestId);
//                            return AjaxResult.error(ErrorCode.INCOME_ERROR);
                                        }
                                    }
                                } else if (WebServiceConstant.FPEWMXZ.equals(finalServiceId)) {
                                    // 获取发票下载地址
                                    JSONObject json = JSONUtil.parseObj(data);
                                    String ewmUrl = json.getOrDefault("ewmUrl", "").toString();
                                    String pdfUrl = json.getOrDefault("pdfUrl", "").toString();
                                    String ofdUrl = json.getOrDefault("ofdUrl", "").toString();
                                    String xmlUrl = json.getOrDefault("xmlUrl", "").toString();
                                    if (StrUtil.isNotEmpty(requestId)) {
                                        QueryWrapper<Invoice> invoiceQueryWrapper = new QueryWrapper<>();
                                        invoiceQueryWrapper.eq("out_trade_orderno", requestId);
                                        Invoice invoice = invoiceMapper.selectOne(invoiceQueryWrapper);
                                        if (BeanUtil.isNotEmpty(invoice)) {
                                            invoice.setInvoicePdfUrl(pdfUrl);
                                            invoice.setcOfdUrl(ofdUrl);
                                            invoiceMapper.updateInvoice(invoice);
                                        }
                                    }

                                } else if (WebServiceConstant.ADD_RED_INVOICE.equals(finalServiceId)) {
                                    // 查找原发票信息
                                    AddRedInvoiceVO addRedInvoiceVO = BeanUtil.copyProperties(data, AddRedInvoiceVO.class);
                                    QueryWrapper<BillInfo> billInfoQueryWrapper = new QueryWrapper<>();
                                    billInfoQueryWrapper.eq("fpqqlsh", requestId);
                                    BillInfo billInfo = billInfoMapper.selectOne(billInfoQueryWrapper);
                                    if (billInfo != null) {
//                        return AjaxResult.error("未查询到原发票信息");
                                        // 根据billInfo获得原发票号码
                                        QueryWrapper<BillInfo> originBillInfoWrapper = new QueryWrapper<>();
                                        originBillInfoWrapper.eq("origin_fphm", billInfo.getOriginFphm());
                                        BillInfo originBillInfo = billInfoMapper.selectOne(originBillInfoWrapper);
                                        if (originBillInfo != null) {
//                        return AjaxResult.error("未查询到原发票信息");
                                            // 查找原发票信息
                                            Invoice originInvoice = invoiceMapper.selectInvoiceByBillInfoId(originBillInfo.getId());
                                            Invoice invoice = BeanUtil.copyProperties(originInvoice, Invoice.class);
                                            invoice.setFphm(addRedInvoiceVO.getFphm());
                                            invoice.setBillInfoId(billInfo.getId());
                                            invoice.setSystemOrderno(billInfo.getSystemOrderno());
                                            invoice.setOutTradeOrderno(billInfo.getOutTradeOrderno());
                                            invoice.setFpqqlsh(billInfo.getFpqqlsh());
                                            invoice.setKprq(DateUtil.parse(addRedInvoiceVO.getKprq()));
                                            invoice.setZzfpdm(addRedInvoiceVO.getZzfpdm());
                                            invoice.setZzfphm(addRedInvoiceVO.getZzfphm());
                                            //二维码=二维码下载地址
                                            invoice.setQrCode(addRedInvoiceVO.getEwmUrl());
                                            //发票 pdf 地址=PDF格式下载地址
                                            invoice.setInvoicePdfUrl(addRedInvoiceVO.getPdfUrl());
                                            //发票详情地址=OFD格式下载地址
                                            invoice.setInvoiceJpgUrl(addRedInvoiceVO.getOfdUrl());
                                            //ofdUrl=XML格式下载地址
                                            invoice.setcOfdUrl(addRedInvoiceVO.getXmlUrl());
                                            invoice.setState(2);
                                            invoiceMapper.insertInvoice(invoice);
                                            billInfo.setState(2);
                                            billInfoMapper.updateById(billInfo);
                                        }
                                    }
                                }else if (WebServiceConstant.KSHC.equals(finalServiceId)) {
                                    // 快速冲红
                                    // TODO: 后期存库
                                    KschVO kschVO = BeanUtil.copyProperties(data,KschVO.class);
                                    InvoiceAllKschVO invoiceAllKschVO = BeanUtil.copyProperties(kschVO,InvoiceAllKschVO.class);

                                }else if (WebServiceConstant.SQHZFPXXQRD.equals(finalServiceId)) {
                                    // 申请红字信息表
                                    // TODO: 后期存库
                                }else if (WebServiceConstant.CXHZFPXXQRD.equals(finalServiceId)) {
                                    // 查询红字信息表
                                    // TODO: 后期存库
                                }else if (WebServiceConstant.SHHZFPXXQRD.equals(finalServiceId)) {
                                    // 审核红字信息表
                                    // TODO: 后期存库
                                }else if (WebServiceConstant.QDFPWJHQ.equals(finalServiceId)) {
                                    // 审核红字信息表
                                    // TODO: 全电发票文件获取
                                }
                            }
                        }
                );

                return AjaxResult.success(JSONUtil.parseObj(data));
            } else {
                return AjaxResult.error(msg);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【通用查询接口】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);
        }
    }

    /**
     * 获取发票下载地址
     *
     * @param companyservice
     * @param invoiceAllFileAcquisitionDTO
     * @return
     */
    @Override
    public AjaxResult getFileUrl(Companyservice companyservice, InvoiceAllFileAcquisitionDTO invoiceAllFileAcquisitionDTO) {

        FileAcquisitionDTO fileAcquisitionDTO = BeanUtil.copyProperties(invoiceAllFileAcquisitionDTO, FileAcquisitionDTO.class);
        if(invoiceAllFileAcquisitionDTO.getJsonData() == null){
            return AjaxResult.error("jsonData不能为空！");
        }
        FileAcquisitionDetailDTO fileAcquisitionDetailDTO = BeanUtil.copyProperties(invoiceAllFileAcquisitionDTO.getJsonData(),FileAcquisitionDetailDTO.class);
        ValidateUtils.validate(fileAcquisitionDetailDTO);
        ValidateUtils.validate(fileAcquisitionDTO);

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.FPEWMXZ, WebServiceConstant.URL, fileAcquisitionDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.FPEWMXZ);
                allApiLog.setSendMsg(fileAcquisitionDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取发票下载地址】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }


    /**
     * 蓝字发票开具
     *
     * @param companyservice
     * @param requestBody
     * @return
     */
    @Override
    public AjaxResult addInvoice(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {

        // 请求billInfo
        Long billInfoID = 0L;

        // 开票实体转换,校验
        InvoiceAllAddDTO invoiceAllAddDTO = BeanUtil.copyProperties(requestBody, InvoiceAllAddDTO.class);
        ValidateUtils.validate(invoiceAllAddDTO);
        // JSONDATA
        InvoiceAllAddInfoDTO invoiceAllAddInfoDTO = invoiceAllAddDTO.getJsonData();
        if (BeanUtil.isEmpty(invoiceAllAddInfoDTO)) {
            return AjaxResult.error("传入报文错误，请检查！");
        }
        // TODO-kk: 2022/12/13 数科这文档写了个锤子，个别字段联调的时候维护下，文档上下不一致
        ValidateUtils.validate(invoiceAllAddInfoDTO);

            /* 暂时屏蔽，无用代码
            // 开票成功后是否返回板式下载地址
            List<InvoiceAllAddextDTO> extList = invoiceAllAddInfoDTO.getExt();
            // 附加信息
            List<InvoiceAllAddfjxxListDTO> fjxxList = invoiceAllAddInfoDTO.getFjxxList();
            //特定业务信息
            List<InvoiceAllAddtdywxxDTO> tdywxx = invoiceAllAddInfoDTO.getTdywxx();*/

        // 明细集合
        List<InvoiceAllAddmxListDTO> mxList = invoiceAllAddInfoDTO.getMxList();
        if (CollectionUtils.isEmpty(mxList)) {
            return AjaxResult.error("mxList明细集合不存在！");
        }
        for (InvoiceAllAddmxListDTO addmxListDTO : mxList) {
            ValidateUtils.validate(addmxListDTO);
        }
        // 2022/12/12 现在只是倒下手，那么就是只存一下就行，返回的也是存。不用转回去。
        // 报文转换存储
        BillInfo billInfo = beanParseBillInfo(invoiceAllAddInfoDTO);
        billInfo.setCompanyId(companyservice.getCompanyid());
        billInfo.setServiceSupplierKey("JCSK");
        try {
            int resBillInfo = billInfoMapper.insertBillInfo(billInfo);
            if (resBillInfo > 0) {
                billInfoID = billInfo.getId();
                if (BeanUtil.isEmpty(billInfo.getId())) {
                    log.error("【金四服务类】【金财数科】【蓝字发票开具】API请求异常，billInfoId返回存储错误。");
                    return AjaxResult.error(ErrorCode.INCOME_ERROR);
                }
                List<BillDetail> billDetailList = beanParseBillDetail(invoiceAllAddInfoDTO, billInfoID);
                int billDetailResult = billInfoMapper.batchBillDetail(billDetailList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【蓝字发票开具】API请求异常，billInfo存储错误。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);
        }

        JSONObject result = null;
        try {

            result = ApiHttp.request(WebServiceConstant.LZFPKJ, WebServiceConstant.URL, invoiceAllAddDTO, companyservice);

            String code   = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                BillInfo billInfoRes = billInfoMapper.selectBillInfoById(billInfoID);
                billInfoRes.setOriginSystemOrderno(requestId);
                billInfoMapper.updateBillInfo(billInfoRes);

                // 保存日志
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.LZFPKJ);
                // 记录请求报文
                allApiLog.setSendMsg(invoiceAllAddDTO.toString());
                allApiLog.setResultMsg(result.toString());
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                AsyncManager.me().execute(
                        new TimerTask() {
                            @Override
                            public void run() {
                                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);
                            }
                        }
                );

                return AjaxResult.success(json);
            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【蓝字发票开具】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);
        }
    }

    /**
     * 开票请求报文InvoiceAllAddInfoDTO转billinfo
     *
     * @param invoiceAllAddInfoDTO
     * @return
     */
    private static BillInfo beanParseBillInfo(InvoiceAllAddInfoDTO invoiceAllAddInfoDTO) {

        // 存取发票信息：记录billInfo
        BillInfo billInfo = new BillInfo();
        // 本系统订单号
        billInfo.setSystemOrderno(IdUtils.randomSystemOrderno());
        // 客户系统订单号
        billInfo.setOutTradeOrderno("");
        // 流水号
        billInfo.setFpqqlsh(invoiceAllAddInfoDTO.getFpqqlsh());
        // 发票种类
        String fplxdm = getInvoiceType(invoiceAllAddInfoDTO.getFplxdm(), true);
        billInfo.setInvoiceType(fplxdm);
        // 购方名称
        billInfo.setBuyerName(invoiceAllAddInfoDTO.getGmfmc());
        // 购方税号
        billInfo.setBuyerTaxnum(invoiceAllAddInfoDTO.getGmfnsrsbh());
        // 购方地址
        billInfo.setBuyerAddress(invoiceAllAddInfoDTO.getGmfdz());
        // 购方电话
        billInfo.setBuyerTelephone(invoiceAllAddInfoDTO.getGmflxdh());
        // 购货方开户行名称
        billInfo.setBuyerBank(invoiceAllAddInfoDTO.getGmfkhh());
        //购方开户行及账户
        billInfo.setBuyerAccount(invoiceAllAddInfoDTO.getGmfyhzh());
        //购方邮箱
        billInfo.setBuyerEmail("");
        //购方联系电话
        billInfo.setBuyerPhone(invoiceAllAddInfoDTO.getGmflxdh());
        //销方名称
        billInfo.setSellerName(invoiceAllAddInfoDTO.getXsfmc());
        //销方税号
        billInfo.setSellerTaxnum(invoiceAllAddInfoDTO.getXsfnsrsbh());
        //销方地址
        billInfo.setSellerAddress(invoiceAllAddInfoDTO.getXsfdz());
        //销方电话
        billInfo.setSellerTelephone(invoiceAllAddInfoDTO.getXsflxdh());
        //销方开户行及账户
        billInfo.setSellerAccount(invoiceAllAddInfoDTO.getXsfyhzh());
        //备注
        billInfo.setMessage(invoiceAllAddInfoDTO.getBz());
        //销方开户行名称
        billInfo.setSellerBank(invoiceAllAddInfoDTO.getXsfkhh());
        //开票人
        billInfo.setClerk("");
        //收款人
        billInfo.setPayee("");
        //复核人
        billInfo.setChecker("");
        //红字信息表编号
        billInfo.setRedInvoiceInfoCode("");
        //开票分机号
        billInfo.setFjh("");
        //开票终端号
        billInfo.setTerminalNumber("");
        //开票类型
        billInfo.setKptype("");
        //原billInfo订单号
        billInfo.setOriginSystemOrderno("");
        //编码表编号
        billInfo.setBmbbh("");
        //原发票代码
        billInfo.setOriginFpdm("");
        //原发票号码
        billInfo.setOriginFphm("");
        //推送方式
        billInfo.setTsfs("");
        //清单标志
        billInfo.setQdbz("");
        //清单项目名称
        billInfo.setQdxmmc("");
        //代开标志
        billInfo.setDkbz("");
        //成品油标志
        billInfo.setCpybz("");
        //开票状态
        /** 开票状态： 2 :开票完成（ 最终状态），其他状态分别为: 20:开票中; 21:开票成功签章中;22:开票失败;24: 开票成功签章失败;3: 发票已作废31:*/
        billInfo.setState(20);
        //订单来源
        billInfo.setSource("");
        //服务公司
        billInfo.setServiceSupplierKey("");
        //单据类型
        billInfo.setBillType("");
        //业务留存字段
        billInfo.setBusinessRemark("");
        //=含税标志判断
        if (StrUtil.isNotEmpty(invoiceAllAddInfoDTO.getHsbz())) {
            // 1含税 2不含税
            if (invoiceAllAddInfoDTO.getHsbz().equals("1")) {
                //含税金额=合计金额
                billInfo.setTaxamt(new BigDecimal(invoiceAllAddInfoDTO.getHjje()));
            } else {
                //不含税金额
                billInfo.setTaxfreeamt(new BigDecimal(invoiceAllAddInfoDTO.getHjje()));
            }
        }
        //开票时间
        billInfo.setInvoicedTime(new Date());
        //税额=合计税额
        billInfo.setTax(new BigDecimal(invoiceAllAddInfoDTO.getHjse()));
        //删除标志
        billInfo.setDeletedTime(new Date());
        //回调地址
        billInfo.setCallbackUrl("");
        billInfo.setCreateTime(new Date());
        billInfo.setUpdateTime(new Date());

        //=经办人相关
        billInfo.setJbrxm(invoiceAllAddInfoDTO.getJbrxm());
        billInfo.setJbrzjhm(invoiceAllAddInfoDTO.getJbrzjhm());
        billInfo.setJbrzjzldm(invoiceAllAddInfoDTO.getJbrzjzldm());
        billInfo.setJrznsrsbh(invoiceAllAddInfoDTO.getJrznsrsbh());
        billInfo.setJshj(invoiceAllAddInfoDTO.getJshj());
        billInfo.setTdyslxdm(invoiceAllAddInfoDTO.getTdyslxdm());
        billInfo.setTdywxx(invoiceAllAddInfoDTO.getBz());
        billInfo.setExt(invoiceAllAddInfoDTO.getBz());

        return billInfo;
    }

    /**
     * 开票请求报文InvoiceAllAddInfoDTO转List<BillDetail>
     *
     * @param invoiceAllAddInfoDTO
     * @return
     */
    private static List<BillDetail> beanParseBillDetail(InvoiceAllAddInfoDTO invoiceAllAddInfoDTO, Long billInfod) {

        List<BillDetail> billDetailList = new ArrayList<>();

        List<InvoiceAllAddmxListDTO> addmxListDTOS = invoiceAllAddInfoDTO.getMxList();

        Long index = 1L;
        for (InvoiceAllAddmxListDTO addmxListDTO : addmxListDTOS) {
            BillDetail billDetail = new BillDetail();
            //发票信息ID
            billDetail.setBillInfoId(billInfod);

            billDetail.setIndex(index);
            index++;
            //明细序号
            //billDetail.setIndex(0L);
            //商品名称
            billDetail.setGoodName(addmxListDTO.getXmmc());
            //商品数量
            billDetail.setNum(new BigDecimal(addmxListDTO.getSpsl()));
            //商品单价
            billDetail.setPrice(new BigDecimal(addmxListDTO.getDj()));
            //含税标志
            billDetail.setHsbz(0);
            //税率
            billDetail.setTaxrate(new BigDecimal(addmxListDTO.getSlv()));
            //规格型号
            billDetail.setSpec(addmxListDTO.getGgxh());
            //单位
            billDetail.setUnit(addmxListDTO.getDw());
            //税收分类编码
            billDetail.setSpbm(addmxListDTO.getSsflbm());
            //商品编码版本号
            billDetail.setBmbbh("");
            //自行编码 =特定征税方式代码
            billDetail.setZsbm(addmxListDTO.getTdzsfsdm());
            //发票行性质
            billDetail.setFphxz(Integer.valueOf(addmxListDTO.getFphxz()));
            //优惠政策标识
            billDetail.setYhzcbs(0);
            //增值税特殊管理=税收优惠政策类型代码
            billDetail.setZzstsgl(addmxListDTO.getZzstsgldm());
            //零税率标识
            billDetail.setLslbs("");
            //扣除额
            billDetail.setKce(new BigDecimal("0"));
            //不含税金额
            billDetail.setTaxfreeamt(new BigDecimal(addmxListDTO.getJe()));
            //税额
            billDetail.setTax(new BigDecimal(addmxListDTO.getSe()));
            //含税金额
            billDetail.setTaxamt(new BigDecimal(addmxListDTO.getJe()));
            //特殊票种
            billDetail.setTspz("");
            billDetail.setUpdatedTime(new Date());
            billDetail.setCreateTime(new Date());
            billDetail.setUpdateTime(new Date());
            billDetail.setRemark("");
            billDetailList.add(billDetail);
        }

        return billDetailList;
    }


    /**
     * 人脸二维码
     *
     * @param companyservice
     * @param requestBody
     * @return
     */
    @Override
    public AjaxResult qrcode(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {
        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.QRCODE, WebServiceConstant.URL, requestBody, companyservice);
            // TODO: 2022/12/11 返回处理 VO整理，数据存储。

            String code   = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            // TODO-kk: 2023/1/16 数据存储再整下
            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }

                return AjaxResult.success(json);
            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        // TODO 处理日志
//        log.info("【金四服务类】【金财数科】【获取二维码】API请求成功，外部报文返回code。返回信息:{}", result);

//        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult query(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {
        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.QUERY, WebServiceConstant.URL, requestBody, companyservice);
            // TODO: 2022/12/11 返回处理 VO整理，数据存储。
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        // TODO 处理日志

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getPrintXML(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {
        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.GET_PRINT_XML, WebServiceConstant.URL, requestBody, companyservice);
            // TODO: 2022/12/11 返回处理 VO整理，数据存储。
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        // TODO 处理日志

        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult addRedInvoice(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {
        com.alibaba.fastjson.JSONObject jsonObj = requestBody.getJSONObject("jsonData");
        if (jsonObj == null) {
            return AjaxResult.error(ErrorCode.INVOICE_NOT_EXISTS);
        }
        AddRedInvoiceDTO addRedInvoiceDTO = com.alibaba.fastjson.JSONObject.parseObject(jsonObj.toJSONString(), AddRedInvoiceDTO.class);
        ValidateUtils.validate(addRedInvoiceDTO);

        // 查找原Invoice
        QueryWrapper<Invoice> invoiceQueryWrapper = new QueryWrapper<>();
        invoiceQueryWrapper.eq("fphm", addRedInvoiceDTO.getYfphm());
        invoiceQueryWrapper.eq("invoice_type", getInvoiceType(addRedInvoiceDTO.getYfplxdm(), false));
        Invoice originInvoice = invoiceMapper.selectOne(invoiceQueryWrapper);
        if (originInvoice == null) {
            return AjaxResult.error(ErrorCode.INVOICE_NOT_EXISTS);
        }

        BillInfo billInfo = billInfoMapper.selectById(originInvoice.getBillInfoId());
        if (billInfo == null) {
            return AjaxResult.error(ErrorCode.INVOICE_NOT_EXISTS);
        }

        BillInfo redBillInfo = BeanUtil.copyProperties(billInfo, BillInfo.class);
        redBillInfo.setId(null);
        redBillInfo.setOriginFphm(addRedInvoiceDTO.getYfphm());
        redBillInfo.setOutTradeOrderno(addRedInvoiceDTO.getFpqqlsh());
        redBillInfo.setFpqqlsh("");
        String systemOrderno = IdUtils.randomSystemOrderno();
        redBillInfo.setSystemOrderno(systemOrderno);
        redBillInfo.setKptype("2");
        if (billInfoMapper.insert(redBillInfo) == 0) {
            return AjaxResult.error(ErrorCode.INVOICE_NOT_EXISTS);
        }

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.ADD_RED_INVOICE, WebServiceConstant.URL, requestBody, companyservice);
            // TODO: 2022/12/11 返回处理 VO整理，数据存储。
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.COMMON_ERROR);
        }

        // 处理请求
        if (!StringUtils.equals("0000", result.getStr("code"))) {
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。返回信息:{}", result);
            return AjaxResult.error(result.getStr("message"));
        }

        JSONObject data = result.getJSONObject("data");
        if (data == null) {
            return AjaxResult.error(ErrorCode.COMMON_ERROR);
        }

        String requestId = data.getStr("requestId");
        redBillInfo.setFpqqlsh(requestId);
        billInfoMapper.updateById(redBillInfo);

        return AjaxResult.success(result);
    }

    /**
     * 简税和金财数科 发票类型互换
     *
     * @param invoiceType 发票种类
     * @param jcsk2js     是否通过金财数科转换为简税
     * @return
     */
    private static String getInvoiceType(String invoiceType, boolean jcsk2js) {
        Map<String, String> map = new HashMap<>();
        map.put("10", "p"); //电子增值税普通发票 10
        map.put("04", "c"); //增值税普通发票 04
        map.put("01", "s"); //增值税专用发票 01
        map.put("08", "b"); //增值税电子专用发票 08
        map.put("87", "j"); //机动车发票 87
        map.put("88", "u"); //二手车发票 88

        map.put("82", "q"); //全电普票
        map.put("81", "r"); //全电专票
        if (jcsk2js) {
            String resp = map.get(invoiceType);
            return StringUtils.isNotEmpty(resp) ? resp : invoiceType;
        }

        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (entry.getValue().equals(invoiceType)) {
                return entry.getKey();
            }
        }

        return invoiceType;
    }

    @Override
    public AjaxResult invoiceStatic(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {
        // com.alibaba.fastjson.JSONObject jsonObj = requestBody.getJSONObject("jsonData");
        // if (jsonObj == null) {
        //     return AjaxResult.error(ErrorCode.INVOICE_NOT_EXISTS);
        // }

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.INVOICE_STATIC, WebServiceConstant.URL, requestBody, companyservice);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.COMMON_ERROR);
        }

        // 处理请求
        if (!StringUtils.equals("0000", result.getStr("code"))) {
            log.error("【金四服务类】【金财数科】【获取二维码】API请求异常，外部报文返回code非0000。返回信息:{}", result);
            return AjaxResult.error(result.getStr("message"));
        }

        JSONObject data = result.getJSONObject("data");
        if (data == null) {
            return AjaxResult.error(ErrorCode.COMMON_ERROR);
        }

        log.info("【金四服务类】【金财数科】【蓝字统计】API请求成功，返回信息:{}", result);

        // String requestId = data.getStr("requestId");

        return AjaxResult.success(data);
    }

    /**
     * 快速红冲
     * @param companyservice
     * @param invoiceAllKshcDTO
     * @return
     */
    @Override
    public AjaxResult issueFastRedInvoice(Companyservice companyservice, InvoiceAllKshcDTO invoiceAllKshcDTO) {

        KshcDTO kshcDTO = BeanUtil.copyProperties(invoiceAllKshcDTO, KshcDTO.class);
        ValidateUtils.validate(kshcDTO);
        ValidateUtils.validate(kshcDTO.getJsonData());

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.KSHC, WebServiceConstant.URL, kshcDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.KSHC);
                allApiLog.setSendMsg(kshcDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【快速红冲】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /**
     * 申请红字信息表
     * @param companyservice
     * @param invoiceAllKshcDTO
     * @return
     */
    @Override
    public AjaxResult uploadRedInfo(Companyservice companyservice, InvoiceAllSqhzDTO invoiceAllSqhzDTO) {

        // TODO: 2023/3/16 外部报文转数科校验

        SqhzDTO sqhzDTO = BeanUtil.copyProperties(invoiceAllSqhzDTO,SqhzDTO.class);
        ValidateUtils.validate(sqhzDTO);

        SqhzJsonDataDTO sqhzJsonDataDTO = BeanUtil.copyProperties(sqhzDTO.getJsonData(),SqhzJsonDataDTO.class);
        ValidateUtils.validate(sqhzJsonDataDTO);

        List<SqhzJsonDataDetailDTO> sqhzJsonDataDetailDTOS = BeanUtil.copyToList(sqhzJsonDataDTO.getHzqrxxmxlist(),SqhzJsonDataDetailDTO.class);
        for (SqhzJsonDataDetailDTO sqhzJsonDataDetailDTO : sqhzJsonDataDetailDTOS) {
            ValidateUtils.validate(sqhzJsonDataDetailDTO);
        }

        sqhzJsonDataDTO.setHzqrxxmxlist(sqhzJsonDataDetailDTOS);
        sqhzDTO.setJsonData(sqhzJsonDataDTO);


        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.SQHZFPXXQRD, WebServiceConstant.URL, sqhzDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.SQHZFPXXQRD);
                allApiLog.setSendMsg(sqhzDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【申请红字信息表】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /**
     * 查询红字信息表
     * @param companyservice
     * @param invoiceAllCxhzDTO
     * @return
     */
    @Override
    public AjaxResult queryRedInfo(Companyservice companyservice, InvoiceAllCxhzDTO invoiceAllCxhzDTO) {

        CxhzDTO cxhzDTO = BeanUtil.copyProperties(invoiceAllCxhzDTO,CxhzDTO.class);
        ValidateUtils.validate(cxhzDTO);

        CxhzJsonDataDTO cxhzJsonDataDTO = BeanUtil.copyProperties(cxhzDTO.getJsonData(),CxhzJsonDataDTO.class);
        ValidateUtils.validate(cxhzJsonDataDTO);

        cxhzDTO.setJsonData(cxhzJsonDataDTO);


        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.CXHZFPXXQRD, WebServiceConstant.URL, cxhzDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.CXHZFPXXQRD);
                allApiLog.setSendMsg(cxhzDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【查询红字信息表】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /**
     * 审核红字信息表
     * @param companyservice
     * @param invoiceAllShhzDTO
     * @return
     */
    @Override
    public AjaxResult auditRedInfo(Companyservice companyservice, InvoiceAllShhzDTO invoiceAllShhzDTO) {
        // TODO: 2023/3/16 外部报文转数科校验

        ShhzDTO shhzDTO = BeanUtil.copyProperties(invoiceAllShhzDTO,ShhzDTO.class);
        ValidateUtils.validate(shhzDTO);

        ShhzJsonDataDTO shhzJsonDataDTO = BeanUtil.copyProperties(shhzDTO.getJsonData(),ShhzJsonDataDTO.class);
        ValidateUtils.validate(shhzJsonDataDTO);

        shhzDTO.setJsonData(shhzJsonDataDTO);


        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.SHHZFPXXQRD, WebServiceConstant.URL, shhzDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.SHHZFPXXQRD);
                allApiLog.setSendMsg(shhzDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【审核红字信息表】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /**
     * 全电安排文件获取
     * @return
     */
    @Override
    public AjaxResult getFileAcquisitionOn(Companyservice companyservice, InvoiceAllFileAcquisitionOnDTO invoiceAllFileAcquisitionOnDTO) {

        FileAcquisitionOnDTO fileAcquisitionOnDTO = BeanUtil.copyProperties(invoiceAllFileAcquisitionOnDTO, FileAcquisitionOnDTO.class);
        FileAcquisitionOnDetailDTO fileAcquisitionOnDetailDTO = BeanUtil.copyProperties(invoiceAllFileAcquisitionOnDTO.getJsonData(),FileAcquisitionOnDetailDTO.class);
        fileAcquisitionOnDTO.setJsonData(fileAcquisitionOnDetailDTO);
        ValidateUtils.validate(fileAcquisitionOnDTO);
        ValidateUtils.validate(fileAcquisitionOnDetailDTO);

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.QDFPWJHQ, WebServiceConstant.URL, fileAcquisitionOnDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.QDFPWJHQ);
                allApiLog.setSendMsg(fileAcquisitionOnDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【全电安排文件获取】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /**
     * 查询红字申请表明细
     * @param companyservice
     * @param invoiceAllRedInvoiceDetailDTO
     * @return
     */
    @Override
    public AjaxResult queryRedInfoDetail(Companyservice companyservice, InvoiceAllRedInvoiceDetailDTO invoiceAllRedInvoiceDetailDTO) {


        RedInvoiceDetailDTO redInvoiceDetailDTO = BeanUtil.copyProperties(invoiceAllRedInvoiceDetailDTO, RedInvoiceDetailDTO.class);
        InvoiceAllRedInvoiceDetailJsonDataDTO redInvoiceDetailJsonDataDTO = BeanUtil.copyProperties(invoiceAllRedInvoiceDetailDTO.getJsonData(),InvoiceAllRedInvoiceDetailJsonDataDTO.class);
        redInvoiceDetailDTO.setJsonData(redInvoiceDetailJsonDataDTO);
        ValidateUtils.validate(redInvoiceDetailDTO);
        ValidateUtils.validate(redInvoiceDetailJsonDataDTO);

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.CXHZFPXXQRDMX, WebServiceConstant.URL, redInvoiceDetailDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.QDFPWJHQ);
                allApiLog.setSendMsg(redInvoiceDetailDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【查询红字申请表明细】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }


    /** 查询蓝字发票可红冲金额*/
    @Override
    public AjaxResult queryInvoiceBeRed(Companyservice companyservice, InvoiceAllCanRedDTO invoiceAllCanRedDTO) {

        CanRedDTO canRedDTO = BeanUtil.copyProperties(invoiceAllCanRedDTO, CanRedDTO.class);
        CanRedJsonDataDTO canRedJsonDataDTO = BeanUtil.copyProperties(invoiceAllCanRedDTO.getJsonData(), CanRedJsonDataDTO.class);
        canRedDTO.setJsonData(canRedJsonDataDTO);
        ValidateUtils.validate(canRedDTO);
        ValidateUtils.validate(canRedJsonDataDTO);

        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.CXLZFPKHCJE, WebServiceConstant.URL, canRedDTO, companyservice);

            String code = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }
                InvoiceAllApiLog allApiLog = new InvoiceAllApiLog();
                allApiLog.setUrl(WebServiceConstant.CXLZFPKHCJE);
                allApiLog.setSendMsg(canRedDTO.toString());
                allApiLog.setResultMsg(JSONUtil.toJsonStr(result));
                allApiLog.setCompany(companyservice.getSellertax());
                allApiLog.setIdentityId(companyservice.getIdentity());
                allApiLog.setRequestId(requestId);
                allApiLog.setCreateTime(new Date());
                allApiLogMapper.insertInvoiceAllApiLog(allApiLog);

            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【查询蓝字发票可红冲金额】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

        return AjaxResult.success(result);
    }

    /** 获取人脸识别结果接口 */
    @Override
    public AjaxResult qrcodeResult(Companyservice companyservice, com.alibaba.fastjson.JSONObject requestBody) {
        JSONObject result = null;
        try {
            result = ApiHttp.request(WebServiceConstant.HQRLSBJG, WebServiceConstant.URL, requestBody, companyservice);

            String code   = result.get("code") != null ? result.get("code").toString() : "";
            String msg = result.get("msg") != null ? result.get("msg").toString() : "";
            String data = result.get("data") != null ? result.get("data").toString() : "";

            if ("0000".equals(code) && StrUtil.isNotEmpty(data)) {
                JSONObject json = JSONUtil.parseObj(data);
                String requestId = json.getOrDefault("requestId", "").toString();
                if (StrUtil.isEmpty(requestId)) {
                    return AjaxResult.error(msg);
                }

                return AjaxResult.success(json);
            } else {
                return AjaxResult.error(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【金四服务类】【金财数科】【获取人脸识别结果接口】API请求异常，外部报文返回code非0000。错误信息:{}", e.getMessage());
            return AjaxResult.error(ErrorCode.INCOME_ERROR);

        }

    }


}
