package com.jianshui.invoice.service.impl.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jianshui.common.config.JianshuiConfig;
import com.jianshui.common.constant.Constants;
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.exception.jianshui.JianshiSystemErrorException;
import com.jianshui.common.exception.jianshui.JianshuiParamErrorException;
import com.jianshui.common.exception.jianshui.JianshuiServiceException;
import com.jianshui.common.utils.*;
import com.jianshui.common.utils.http.HttpHelper;
import com.jianshui.common.utils.uuid.IdUtils;
import com.jianshui.framework.manager.AsyncManager;
import com.jianshui.invoice.constant.elephant.ElephantConstants;
import com.jianshui.invoice.domain.*;
import com.jianshui.invoice.domain.dto.*;
import com.jianshui.invoice.domain.dto.adapter.request.nuonuo2.QueryInvoiceDTO;
import com.jianshui.invoice.domain.dto.adapter.response.RedInfoDTO;
import com.jianshui.invoice.domain.dto.adapter.response.RedInfoDetailDTO;
import com.jianshui.invoice.domain.dto.api.*;
import com.jianshui.invoice.domain.dto.api.elephant.*;
import com.jianshui.invoice.mapper.BillInfoMapper;
import com.jianshui.invoice.mapper.InvoiceMapper;
import com.jianshui.invoice.mapper.RedinfoMapper;
import com.jianshui.invoice.service.IBillInfoService;
import com.jianshui.invoice.service.IInvoiceApiService;
import com.jianshui.invoice.task.QueryInvoiceTask;
import com.jianshui.invoice.utils.BillInfoUtils;
import com.jianshui.invoice.utils.elephant.ElephantUtils;

import com.jianshui.queue.utils.RedisQueueUtil;
import com.jianshui.storage.domain.StorageUrlDTO;
import com.jianshui.storage.factory.StorageFactory;
import com.jianshui.storage.service.IStorageService;
import com.jianshui.system.mapper.CompanyserviceMapper;
import com.jianshui.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author 巩权林
 * @Date 2022-03-18 9:53
 **/
@Component("elephant_invoice")
@Slf4j
public class ElephantInvoiceApiServiceImpl implements IInvoiceApiService {

    @Autowired
    private BillInfoMapper billInfoMapper;

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private RedinfoMapper redinfoMapper;

    @Autowired
    private CompanyserviceMapper companyserviceMapper;

    @Autowired
    private StorageFactory storageFactory;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IBillInfoService billInfoService;

    /**
     * 发票开具
     *
     * @param billInfo
     * @return
     * @description TODO 没有处理机动车的情况，需要处理机动车，冲红和蓝票都要处理
     */
    @Override
    public HXResponse addInvoice(BillInfo billInfo, Companyservice companyservice) throws IllegalAccessException, InstantiationException {

        // 预处理
        try {
            billInfo = BillInfoUtils.processBillInfo(billInfo, companyservice);
        } catch (JianshuiParamErrorException e) {
            return new HXResponse(e.getMessage());
        } catch (Exception e) {
            log.error("【销项】【大象发票】开票接口校验异常", e);
            return new HXResponse("格式校验失败，请检查报文");
        }

        // 订单头信息
        DDTXX ddtxx = new DDTXX(billInfo);

        // 订单票面信息
        DDPCXX ddpcxx = new DDPCXX();
        // ddpcxx.setKPFS("1"); // 设置开票方式为手动开票
        ddpcxx.setDDQQPCH(billInfo.getSystemOrderno());
        ddpcxx.setNSRSBH(billInfo.getSellerTaxnum());
        ddpcxx.setKPZD(billInfo.getTerminalNumber());
        // 大象发票类型代码说明
        // 增值税专用发票： 004   1
        // 增值税普通发票： 007   1
        // 增值税电子专用发票：028  1
        // 机动车销售统一发票：005 1
        // 二手车销售统一发票：006 1
        // 增值税普通发票（电子）： 026  1
        String invioceType = billInfo.getInvoiceType();
        String fplxdm = ElephantUtils.transElephantType(invioceType, 1);
        ddpcxx.setFPLXDM(fplxdm);
        // switch (invioceType) {
        //     case "p":
        //         ddpcxx.setFPLXDM("026");
        //         break;
        //     case "c":
        //         ddpcxx.setFPLXDM("007");
        //         break;
        //     case "s":
        //         ddpcxx.setFPLXDM("004");
        //         break;
        //     case "b":
        //         ddpcxx.setFPLXDM("028");
        //         break;
        //     case "j":
        //         ddpcxx.setFPLXDM("005");
        //         throw new JianshuiParamErrorException("暂不支持的开票类型，请联系管理员！", companyservice, "invoice");
        //     case "u":
        //         ddpcxx.setFPLXDM("006");
        //         throw new JianshuiParamErrorException("暂不支持的开票类型，请联系管理员！", companyservice, "invoice");
        //     case "r":
        //     default:
        //         throw new JianshuiParamErrorException("暂不支持的开票类型，请联系管理员！", companyservice, "invoice");
        // }

        // 开始处理详情
        List<BillDetail> details = billInfo.getBillDetailList();
        List<DDMXXX> ddmxxxList = new ArrayList<>();
        for (int i = 0; i < details.size(); i++) {
            BillDetail detail = details.get(i);
            DDMXXX ddmxxx = new DDMXXX(billInfo, detail);
            ddmxxxList.add(ddmxxx);
        }

        // 开始封装请求报文
        ElephantInvoiceAddDTO elephantInvoiceAddDTO = new ElephantInvoiceAddDTO();
        elephantInvoiceAddDTO.setDDPCXX(ddpcxx);
        DDZXX ddzxx = new DDZXX();
        ddzxx.setDDTXX(ddtxx);
        ddzxx.setDDMXXX(ddmxxxList);
        List<DDZXX> ddzxxes = new ArrayList<>();
        ddzxxes.add(ddzxx);
        elephantInvoiceAddDTO.setDDZXX(ddzxxes);

        // JSONObject result = JSONObject.parseObject("{\"zipCode\":\"0\",\"entCode\":\"91370102MA3UD2FG21\",\"dataExchangeId\":\"20220328140706911955546286280593\",\"encryptCode\":\"0\",\"returnStateInfo\":{\"returnCode\":\"0000\",\"returnMessage\":\"5aSE55CG5oiQ5YqfIQ==\"},\"content\":\"eyJERFFRUENIIjoiODgyOWNmNWUtNDAyYS00NWZkLWFiYmEtMzlkMjlhOWMzMjMzIiwiWlRETSI6IjAwOTk5OSIsIlpUWFgiOiLkvIHkuJrmnKrphY3nva7nqI7mjqforr7lpIcifQ==\"}");
        // if (!CommonUtils.isDevMode()) {
        //     result = ElephantUtils.sendRequest(ElephantConstants.ADD_INVOICE, (JSONObject) JSONObject.toJSON(elephantInvoiceAddDTO));
        // }
        // AjaxResult queryResult = ElephantUtils.sendRequest(ElephantConstants.ADD_INVOICE, JSONUtil.parse(elephantInvoiceAddDTO));
        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.ADD_INVOICE_LOCALHOST, ElephantConstants.ADD_INVOICE_METHOD, JSONUtil.parse(elephantInvoiceAddDTO), companyservice);
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
            log.error("【销项发票】【大象接口】【发票开具】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(elephantInvoiceAddDTO).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】发票开具请求结果{}", queryResult.toString());

        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }

        JSONObject result = queryResult.getJsonData();
        JSONObject contentJson = result;

        // 如果content不为空，判断状态代码
        if (contentJson != null) {
            String ztdm = contentJson.getString("ZTDM");
            if (!StringUtils.equals("0000", ztdm) && !StringUtils.equals("010000", ztdm)) {
                return new HXResponse(contentJson.getString("ZTXX"));
            }
        }

        billInfo.setState(20);
        billInfoMapper.updateBillInfo(billInfo);

        // 还需要单独调用下发票结果获取接口，获取订单结果
        JSONObject queryBody = new JSONObject();
        queryBody.put("NSRSBH", companyservice.getSellertax());
        queryBody.put("DDQQPCH", billInfo.getSystemOrderno());
        queryBody.put("FPLXDM", fplxdm);
        queryBody.put("SFFHSBSJ", "0");
        // queryResult = ElephantUtils.sendRequest(ElephantConstants.ADD_INVOICE_RESULT, JSONUtil.parse(queryBody));
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.ADD_INVOICE_RESULT_LOCALHOST, ElephantConstants.ADD_INVOICE_RESULT_METHOD, JSONUtil.parse(queryBody), companyservice);
        } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
            log.error("【销项发票】【大象接口】【发票开具】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(elephantInvoiceAddDTO).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }

        log.info("【销项发票】【大象发票】发票开具请求拉取结果{}", queryResult.toString());
        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }

        // 如果content不为空，判断状态代码
        contentJson = queryResult.getJsonData();
        if (contentJson != null) {
            String ztdm = contentJson.getString("ZTDM");
            if (!StringUtils.equalsAny(ztdm, "020111", "020000", "010000")) {
                // 开票失败
                if (StringUtils.equals("020002", ztdm)) {
                    billInfo.setState(22);
                    billInfoMapper.updateBillInfo(billInfo);
                }

                return new HXResponse(contentJson.getString("ZTXX"));
            }

            // 如果全部开具成功
            if (StringUtils.equals("020000", ztdm)) {
                billInfo.setState(2);
                billInfoMapper.updateBillInfo(billInfo);
            }
        }

        // // 处理报文保存
        // JSONObject DDJGXX = contentJson.getJSONObject("DDJGXX");
        // if (StringUtils.isNotEmpty(DDJGXX.getString("DDQQLSH"))) {
        //     billInfo.setFpqqlsh(DDJGXX.getString("DDQQLSH"));
        // }

        // 定时拉取保存发票， TODO 处理开票中的问题
        AsyncManager.me().execute(new QueryInvoiceTask(billInfo, companyservice, this));

        HXResponse response = new HXResponse("0000", "同步成功");
        response.put("fpqqlsh", billInfo.getSystemOrderno());
        return response;

    }


    /**
     * 发票失败重开接口
     *
     * @param
     */
    @Override
    public AjaxResult reInvoice(BillInfo billInfo, Companyservice companyservice) {
        return AjaxResult.error("系统维护中");
    }

    private static void debugLog(String msg, String uuid, Long timestamp) {
        Long now = System.currentTimeMillis();
        log.debug("【DebugLog:{}】耗时：{}，断点信息：{}", uuid, now - timestamp, msg);
    }

    /**
     * 单个发票查询接口
     *
     * @param billInfo
     * @return
     */
    @Override
    public HXResponse queryInvoice(QueryBillInfoDTO billInfo, Companyservice companyservice) {
        // String fpqqlsh = billInfo.getFpqqlsh();
        // if (StringUtils.isEmpty(fpqqlsh)) {
        //     HXResponse response = new HXResponse("9999", "发票请求流水号不能为空！");
        //     return response;
        // }
        // 获得当前时间戳
        Long timestamp = System.currentTimeMillis();
        String uuid = UUID.randomUUID().toString();
        debugLog("断点1", uuid, timestamp);
        QueryWrapper<BillInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id", companyservice.getCompanyid());
        if (StringUtils.isNotEmpty(billInfo.getFpqqlsh())) {
            queryWrapper.eq("fpqqlsh", billInfo.getFpqqlsh());
        } else if (StringUtils.isNotEmpty(billInfo.getOutTradeOrderno())) {
            queryWrapper.eq("out_trade_orderno", billInfo.getOutTradeOrderno());
        } else {
            HXResponse response = new HXResponse("9997", "订单号或流水号不能同时为空");
            return response;
        }

        queryWrapper.orderByDesc("id");
        queryWrapper.last(" limit 1");
        BillInfo originBillInfo = billInfoMapper.selectOne(queryWrapper);
        debugLog("断点2", uuid, timestamp);
        if (originBillInfo == null) {
            Invoice tempInvoice = new Invoice();
            tempInvoice.setInvoiceMsg("发票信息不存在");
            if (billInfo.getSystemOrderno() != null) {
                tempInvoice.setSystemOrderno(billInfo.getSystemOrderno());
            }
            if (billInfo.getOutTradeOrderno() != null) {
                tempInvoice.setOutTradeOrderno(billInfo.getOutTradeOrderno());
            }
            if (billInfo.getFpqqlsh() != null) {
                tempInvoice.setFpqqlsh(billInfo.getFpqqlsh());
            }
            HXResponse response = new HXResponse("9998", "发票信息不存在", tempInvoice);
            return response;
        }
        debugLog("断点3", uuid, timestamp);

        JSONObject queryBody = new JSONObject();
        queryBody.put("NSRSBH", companyservice.getSellertax());
        queryBody.put("DDQQLSH", originBillInfo.getSystemOrderno());
        queryBody.put("BSWJ", "0");
        debugLog("断点4", uuid, timestamp);

        // AjaxResult queryResult = ElephantUtils.sendRequest(ElephantConstants.QUERY_INVOICE, JSONUtil.parse(queryBody));
        // queryResult = ElephantUtils.sendRequest(ElephantConstants.ADD_INVOICE_RESULT, JSONUtil.parse(queryBody));
        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.QUERY_INVOICE_LOCALHOST, ElephantConstants.QUERY_INVOICE_METHOD, JSONUtil.parse(queryBody), companyservice);
        } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
            log.error("【销项发票】【大象接口】【发票开具】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(queryBody).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        debugLog("断点5", uuid, timestamp);

        // 判断外层报文是否成功
        if (queryResult.isError()) {
            // String base64Result = returnStateInfo.getString("returnMessage");
            // String errorMsg = new String(Base64.decodeBase64(base64Result));
            // Invoice tempInvoice = new Invoice();
            // tempInvoice.setInvoiceMsg(errorMsg);
            // if (billInfo.getSystemOrderno() != null) {
            //     tempInvoice.setSystemOrderno(billInfo.getSystemOrderno());
            // }
            // if (billInfo.getOutTradeOrderno() != null) {
            //     tempInvoice.setOutTradeOrderno(billInfo.getOutTradeOrderno());
            // }
            // if (billInfo.getFpqqlsh() != null) {
            //     tempInvoice.setFpqqlsh(billInfo.getFpqqlsh());
            // }
            throw new JianshuiServiceException(queryResult.getMsg());
        }
        debugLog("断点6", uuid, timestamp);

        // TODO 保存订单信息
        JSONObject contentJson = queryResult.getJsonData();
        debugLog("断点7", uuid, timestamp);

        ElephantInvoiceQueryResultDTO queryResultDTO = contentJson.toJavaObject(ElephantInvoiceQueryResultDTO.class);
        debugLog("断点8", uuid, timestamp);
        String ztdm = queryResultDTO.getZTDM();
        if (!StringUtils.equals("000000", ztdm) && !StringUtils.equals("002000", ztdm)) {
            Invoice tempInvoice = new Invoice();
            tempInvoice.setInvoiceMsg(queryResultDTO.getZTXX());
            if (billInfo.getSystemOrderno() != null) {
                tempInvoice.setSystemOrderno(billInfo.getSystemOrderno());
            }
            if (billInfo.getOutTradeOrderno() != null) {
                tempInvoice.setOutTradeOrderno(billInfo.getOutTradeOrderno());
            }
            if (billInfo.getFpqqlsh() != null) {
                tempInvoice.setFpqqlsh(billInfo.getFpqqlsh());
            }
            return new HXResponse(queryResultDTO.getZTXX(), tempInvoice);
        }
        debugLog("断点9", uuid, timestamp);
        List<DDFPZXX> ddfpzxxes = queryResultDTO.getDDFPZXX();
        if (ddfpzxxes.size() > 1) {
            HXResponse response = new HXResponse("9996", "一次只能查询一张发票");
            return response;
        }
        DDFPZXX ddfpzxx = ddfpzxxes.get(0);
        DDFPXX ddfpxx = ddfpzxx.getDDFPXX(); // 发票头信息
        // 查一下原来的发票
        debugLog("断点10", uuid, timestamp);
        Invoice invoice = invoiceMapper.selectBySystemOrderNo(companyservice.getCompanyid(), originBillInfo.getSystemOrderno());
        if (invoice == null) {
            invoice = new Invoice();
        }
        debugLog("断点11", uuid, timestamp);
        // invoice.setId(); // 主键ID */
        invoice.setBillInfoId(originBillInfo.getId()); //  bill_info表的bill_id */
        invoice.setCompanyId(companyservice.getCompanyid()); // "销方ID"
        invoice.setSystemOrderno(originBillInfo.getSystemOrderno()); // "系统订单号"
        invoice.setOutTradeOrderno(originBillInfo.getOutTradeOrderno()); // "客户订单号"
        invoice.setFpqqlsh(originBillInfo.getFpqqlsh()); // "流水号"
        invoice.setInvoiceType(originBillInfo.getInvoiceType()); // "发票种类"

        // 处理开票信息
        String ddzt = ddfpxx.getDDZT(); // 000000 成功，001000 订单处理成功 001999开票失败
        if (StringUtils.equals(ddzt, "000000")) {
            invoice.setState(2); // "开票状态"
        } else if (StringUtils.equals(ddzt, "001999")) {
            invoice.setState(22); // "开票状态"
        } else if (StringUtils.equals(ddzt, "002000")) {
            if (StringUtils.equals(ztdm, "002000")) {
                invoice.setState(22); // "开票状态" 辣鸡大象，订单开票异常的外层报文也是002000，内层报文也是这个
            } else {
                invoice.setState(20); // "开票状态"
            }
        } else if (StringUtils.equals(ddzt, "003000")) {
            invoice.setState(3); // "开票状态"
        } else if (StringUtils.equals(ddzt, "004000")) {
            invoice.setState(99); // "开票状态"
        } else if (StringUtils.equals(ddzt, "005000")) {
            invoice.setState(25); // "开票状态"
        } else if (StringUtils.equals(ddzt, "001999")) {
            invoice.setState(22); // "开票状态"
        } else {
            invoice.setState(20); // "开票状态"
        }

        // invoice.setState(); // "开票状态" TODO 处理开票状态
        invoice.setcInvoiceid("not used"); // 发票c_invoiceid */
        invoice.setFpdm(ddfpxx.getFPDM()); // "发票代码"
        invoice.setFphm(ddfpxx.getFPHM()); // "发票号码"
        try {
            String kprq = ddfpxx.getKPRQ();
            if (StringUtils.isNotEmpty(kprq)) {
                invoice.setKprq(DateUtils.parseDate(kprq, "yyyy-MM-dd HH:mm:ss")); // "开票日期", width = 30, dateFormat = "yyyy-MM-dd"
            }
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("【销项发票】【大象接口】【订单查询】 发票格式化日期错误。请求报文{}，大象返回报文{}，原始报文{}", queryBody.toJSONString(), queryResult.toString(), JSONObject.toJSONString(billInfo));
            throw new JianshuiServiceException("日期处理错误，请联系管理员！");
        }
        invoice.setBuyerName(ddfpxx.getGMFMC()); // "购方名称"
        invoice.setBuyerTaxnum(ddfpxx.getGMFSBH()); // "购方税号"
        invoice.setBuyerAddress(ddfpxx.getGMFDZ()); // "购方地址"
        invoice.setBuyerTelephone(ddfpxx.getGMFDH()); // "购方电话"
        invoice.setBuyerAccount(ddfpxx.getGMFYH() + ddfpxx.getGMFZH()); // "购方开户行及账户"
        invoice.setBuyerEmail(originBillInfo.getBuyerEmail()); // "购方邮箱"
        invoice.setBuyerPhone(originBillInfo.getBuyerPhone()); // "购方联系电话，可空"
        invoice.setSellerName(ddfpxx.getXHFMC()); // "销方名称"
        invoice.setSellerTaxnum(ddfpxx.getXHFSBH()); // "销方税号"
        invoice.setSellerAddress(ddfpxx.getXHFDZ()); // "销方地址"
        invoice.setSellerTelephone(ddfpxx.getXHFDH()); // "销方电话"
        invoice.setSellerAccount(ddfpxx.getXHFYH() + ddfpxx.getXHFZH()); // "销方开户行及账户"
        invoice.setMessage(ddfpxx.getBZ()); // "备注"
        invoice.setClerk(ddfpxx.getKPR()); // "开票人"
        invoice.setPayee(ddfpxx.getSKR()); // "收款人"
        invoice.setChecker(ddfpxx.getFHR()); // "复核人"
        invoice.setTaxfreeamt(new BigDecimal(ddfpxx.getHJJE())); // "不含税金额"
        invoice.setTax(new BigDecimal(ddfpxx.getHJSE())); // "税额"
        invoice.setTaxamt(new BigDecimal(ddfpxx.getJSHJ())); // "含税金额"
        invoice.setOriginFpdm(ddfpxx.getYFPDM()); // "原发票代码"
        invoice.setOriginFphm(ddfpxx.getYFPHM()); // "原发票号码"
        invoice.setJym(ddfpxx.getJYM()); // "校验码"
        invoice.setQrCode(ddfpxx.getDTM()); // "二维码" 动态码是二维码吗？
        invoice.setMachineCode(ddfpxx.getJQBH()); //  "税控设备号"
        // invoice.setCipherText(); // "发票密文"
        // invoice.setInvoicePdfUrl(); // "发票 pdf 地址"
        // invoice.setInvoiceJpgUrl(); // "发票详情地址"
        invoice.setInvoiceMsg(ddfpxx.getDDZTXX()); // "开票信息，成功或者失败的信息"
        invoice.setInvoiceResultMsg(ddfpxx.getDDZTXX()); // "结果信息"
        String oilFlag = "0";
        String qdbz = "0";
        if (StringUtils.equals(ddfpxx.getQDBZ(), "4")) {
            oilFlag = "1";
        }
        if (StringUtils.equals(ddfpxx.getQDBZ(), "1")) {
            qdbz = "1";
        }
        invoice.setProductOilFlag(oilFlag); // "成品油标志"
        invoice.setQdbz(qdbz); // "清单标志"
        // invoice.setcOfdUrl(); // "ofdUrl"
        invoice.setFjh(ddfpxx.getKPJH()); // "分机号"
        invoice.setTerminalNumber(ddfpxx.getKPZD()); // "终端号"
        debugLog("断点12", uuid, timestamp);
        // 上传文件到oss
        String defaultStorage = configService.selectConfigByKey("default_storage");
        if (StringUtils.isNotEmpty(defaultStorage) && StringUtils.isEmpty(invoice.getInvoicePdfUrl())) {
            try {
                IStorageService service = storageFactory.getStorageInstance(defaultStorage);
                String pdfzjl = ddfpxx.getPDFZJL();
                String zjllx = ddfpxx.getZJLLX();
                String pdfName = IdUtils.fastSimpleUUID() + "." + (StringUtils.equals(zjllx, "PDF") ? "pdf" : "ofd");
                if (StringUtils.isNotEmpty(pdfzjl)) {
                    byte[] pdfBytes = Base64.decode(pdfzjl);
                    String invoicePath = Constants.RESOURCE_PREFIX + "/invoice/" + pdfName;
                    AjaxResult uploadResult = service.upload(pdfBytes, invoicePath);
                    if (uploadResult.isSuccess()) {
                        StorageUrlDTO uploadResultDTO = (StorageUrlDTO) uploadResult.get("data");
                        String fileUrl = configService.selectConfigByKey("file_url");
                        if (StringUtils.isNotEmpty(fileUrl)) {
                            uploadResultDTO.setContentType(zjllx.toLowerCase());
                            String pdfUrl = fileUrl + "/" + Base64.encode(JSONObject.toJSONString(uploadResultDTO));
                            invoice.setInvoicePdfUrl(pdfUrl);
                            invoice.setInvoiceFileStorage(uploadResultDTO.getServiceProvider());
                            if (StringUtils.equals(zjllx, "OFD")) {
                                invoice.setcOfdUrl(pdfUrl);
                            }
                        }
                    }
                }
            } catch (JianshiSystemErrorException e) {
                e.printStackTrace();
            }
        }
        debugLog("断点13", uuid, timestamp);

        if (invoice.getId() != null) {
            invoiceMapper.updateInvoice(invoice);
        } else {
            invoiceMapper.insertInvoice(invoice);
        }
        debugLog("断点14", uuid, timestamp);
        // TODO 处理发票详情
        invoiceMapper.deleteInvoiceDetailByInvoiceId(invoice.getId()); // 删除发票明细
        List<InvoiceDetail> invoiceDetailList = new ArrayList<>();
        List<DDMXXX> ddmxxxList = ddfpzxx.getDDMXXX();
        for (int i = 0; i < ddmxxxList.size(); i++) {
            DDMXXX ddmxxx = ddmxxxList.get(i);
            InvoiceDetail tempDetail = new InvoiceDetail();
            // tempDetail.setId(); // id
            tempDetail.setInvoiceId(invoice.getId()); // 发票主键
            tempDetail.setIndex(Long.parseLong(StringUtils.isEmpty(ddmxxx.getXH()) ? "" : ddmxxx.getXH())); // 顺序
            tempDetail.setGoodName(StringUtils.isEmpty(ddmxxx.getXMMC()) ? "" : ddmxxx.getXMMC()); // 商品名称
            tempDetail.setNum(ddmxxx.getSPSL()); // 商品数量
            tempDetail.setPrice(new BigDecimal(StringUtils.isEmpty(ddmxxx.getDJ()) ? "0" : ddmxxx.getDJ())); // 商品单价
            tempDetail.setHsbz(Integer.parseInt(StringUtils.isEmpty(ddmxxx.getHSBZ()) ? "0" : ddmxxx.getHSBZ())); // 含税标志
            tempDetail.setTaxrate(new BigDecimal(StringUtils.isEmpty(ddmxxx.getSL()) ? "0" : ddmxxx.getSL())); // 税率
            tempDetail.setSpec(StringUtils.isEmpty(ddmxxx.getGGXH()) ? "" : ddmxxx.getGGXH()); // 规格型号
            tempDetail.setUnit(StringUtils.isEmpty(ddmxxx.getDW()) ? "" : ddmxxx.getDW()); // 单位
            tempDetail.setSpbm(StringUtils.isEmpty(ddmxxx.getSPBM()) ? "" : ddmxxx.getSPBM()); // 税收分类编码
            tempDetail.setBmbbh(ddfpxx.getBMBBBH()); // 商品编码版本号
            tempDetail.setZsbm(StringUtils.isEmpty(ddmxxx.getZXBM()) ? "" : ddmxxx.getZXBM()); // 自行编码
            tempDetail.setFphxz(Integer.parseInt(StringUtils.isEmpty(ddmxxx.getFPHXZ()) ? "0" : ddmxxx.getFPHXZ())); // 发票行性质
            tempDetail.setYhzcbs(Integer.parseInt(StringUtils.isEmpty(ddmxxx.getYHZCBS()) ? "0" : ddmxxx.getYHZCBS())); // 优惠政策标识
            tempDetail.setZzstsgl(StringUtils.isEmpty(ddmxxx.getZZSTSGL()) ? "" : ddmxxx.getZZSTSGL()); // 增值税特殊管理
            tempDetail.setLslbs(StringUtils.isEmpty(ddmxxx.getLSLBS()) ? "" : ddmxxx.getLSLBS()); // 零税率标识
            if (ddmxxx.getKCE() != null) {
                tempDetail.setKce(new BigDecimal(ddmxxx.getKCE())); // 扣除额
            }
            tempDetail.setTax(new BigDecimal(ddmxxx.getSE())); // 税额
            if (tempDetail.getHsbz() == 0) {
                tempDetail.setTaxfreeamt(new BigDecimal(ddmxxx.getJE())); // 不含税金额
                // 计算含税金额
                tempDetail.setTaxamt(tempDetail.getTaxfreeamt().add(tempDetail.getTax()));
            } else {
                tempDetail.setTaxamt(new BigDecimal(ddmxxx.getJE())); // 含税金额
                tempDetail.setTaxfreeamt(tempDetail.getTaxamt().subtract(tempDetail.getTax())); // 计算不含税金额
            }
            // tempDetail.setTspz(ddmxxx.getts); // 特殊票种

            invoiceDetailList.add(tempDetail);
        }

        invoice.setInvoiceDetailList(invoiceDetailList);
        invoiceMapper.batchInvoiceDetail(invoiceDetailList);
        debugLog("断点15", uuid, timestamp);
        // 更新原来的billInfo
        originBillInfo.setState(invoice.getState());
        if (StringUtils.equals(originBillInfo.getKptype(), "2")) {
            originBillInfo.setOriginFpdm(invoice.getOriginFpdm());
            originBillInfo.setOriginFphm(invoice.getOriginFphm());
            // 如果是红票，开票状态为成功，还需要对原来的蓝票进行状态修改
            if (invoice.getState() == 2) {
                Invoice originInvoice = invoiceMapper.selectByFpdmFphm(companyservice.getCompanyid(), invoice.getOriginFpdm(), invoice.getOriginFphm());
                if (originInvoice != null) {
                    originBillInfo.setOriginSystemOrderno(originInvoice.getSystemOrderno());
                    QueryWrapper<BillInfo> myQueryWrapper = new QueryWrapper<>();
                    myQueryWrapper.eq("company_id", companyservice.getCompanyid());
                    myQueryWrapper.eq("system_orderno", originInvoice.getSystemOrderno());
                    BillInfo originBlueBillInfo = billInfoMapper.selectOne(myQueryWrapper);
                    if (originBlueBillInfo != null) {
                        originBlueBillInfo.setState(99);
                        billInfoMapper.updateBillInfo(originBlueBillInfo);
                    }
                    originInvoice.setState(99);
                    invoiceMapper.updateInvoice(originInvoice);
                }
            }
        }
        debugLog("断点16", uuid, timestamp);
        billInfoMapper.updateBillInfo(originBillInfo);
        debugLog("断点17", uuid, timestamp);
        try {
            if (billInfo != null && billInfo.getPushBillInfo() != null && billInfo.getPushBillInfo()) {
                log.info("推送订单信息,id:{}", originBillInfo.getId());
                billInfoService.pushBillInfo(originBillInfo.getId());
            }
        } catch (Exception e) {
            log.error("推送订单信息失败,id:{}", originBillInfo.getId(), e);
            e.printStackTrace();
        }
        debugLog("断点18", uuid, timestamp);
        HXResponse response = new HXResponse("0000", "查询成功", invoice);
        return response;
    }

    /**
     * 批量发票查询接口
     *
     * @param billInfo
     * @return
     */
    @Override
    public HXResponse batchQueryInvoices(BillInfo billInfo, String byWhat, Companyservice companyservice) {
        String fpqqlsh = billInfo.getFpqqlsh();
        String orderNo = billInfo.getOutTradeOrderno();
        List<Object> result = new ArrayList<>();
        List<BillInfo> queryBillInfo = new ArrayList<>();
        if (StringUtils.equals("fpqqlsh", byWhat)) {
            JSONArray fpqqlshs = JSONArray.parseArray(fpqqlsh);
            if (fpqqlshs == null) {
                fpqqlshs = new JSONArray();
                fpqqlshs.add(fpqqlsh);
            }
            fpqqlshs.forEach(i -> {
                BillInfo tempBillInfo = new BillInfo();
                tempBillInfo.setCompanyId(companyservice.getCompanyid());
                tempBillInfo.setFpqqlsh((String) i);
                queryBillInfo.add(tempBillInfo);
            });
        }

        if (StringUtils.equals("orderno", byWhat)) {
            JSONArray fpqqlshs = JSONArray.parseArray(orderNo);
            if (fpqqlshs == null) {
                fpqqlshs = new JSONArray();
                fpqqlshs.add(orderNo);
            }
            fpqqlshs.forEach(i -> {
                BillInfo tempBillInfo = new BillInfo();
                tempBillInfo.setCompanyId(companyservice.getCompanyid());
                tempBillInfo.setOutTradeOrderno((String) i);
                queryBillInfo.add(tempBillInfo);
            });
        }

        queryBillInfo.forEach(i -> {
            QueryBillInfoDTO queryBillInfoDTO = new QueryBillInfoDTO();
            BeanUtils.copyProperties(i, queryBillInfoDTO);
            HXResponse tempResult = this.queryInvoice(queryBillInfoDTO, companyservice);
            // if (tempResult.isSuccess()) {
            //     result.add(tempResult.getData());
            // }
            result.add(tempResult.getData());
        });

        return new HXResponse("0000", "查询成功", result);

    }


    /**
     * 范围查询接口
     *
     * @param queryJson
     * @param companyservice
     * @return
     */
    public HXResponse scopeQueryInvoices(JSONObject queryJson, Companyservice companyservice) {
        // 获取基本参数
        QueryWrapper<Invoice> queryWrapper = new QueryWrapper<>();
        String period = queryJson.getString("period"); // 开始结束时间，用&间隔
        if (StringUtils.isNotEmpty(period)) {
            List<String> periodSplit = Arrays.asList(period.split("&"));
            if (periodSplit != null && periodSplit.size() > 0) {
                // 订单开始日期
                if (periodSplit.get(0) != null) {
                    queryWrapper.ge("kprq", periodSplit.get(0));
                }
                // 订单截止日期
                if (periodSplit.get(1) != null) {
                    queryWrapper.le("kprq", periodSplit.get(0));
                }
            }
        }
        String buyername = queryJson.getString("buyername"); // 购方名称
        if (StringUtils.isNotEmpty(buyername)) {
            // buyername
            queryWrapper.eq("buyer_name", buyername);
        }
        String buyertaxno = queryJson.getString("buyertaxno"); // 购方taxno
        if (StringUtils.isNotEmpty(buyertaxno)) {
            queryWrapper.eq("buyer_taxnum", buyertaxno);
        }
        String fpdm = queryJson.getString("fpdm"); // 发票代码
        if (StringUtils.isNotEmpty(fpdm)) {
            queryWrapper.eq("fpdm", fpdm);
        }
        String fphm = queryJson.getString("fphm"); // 发票号码
        if (StringUtils.isNotEmpty(fphm)) {
            queryWrapper.eq("fphm", fphm);
        }

        // 开始查询数据库，invoice
        List<Invoice> invoices = invoiceMapper.selectList(queryWrapper);
        List<Object> result = new ArrayList<>();
        for (Invoice tempInvoice : invoices) {
            QueryBillInfoDTO tempBillInfo = new QueryBillInfoDTO();
            tempBillInfo.setFpqqlsh(tempInvoice.getFpqqlsh());
            HXResponse tempResult = this.queryInvoice(tempBillInfo, companyservice);
            result.add(tempResult.getData());
        }

        return new HXResponse("0000", "查询成功", result);

    }

    /**
     * 申请/上传 红字发票
     *
     * @param redinfo
     */
    @Override
    public HXResponse uploadRedInfo(Redinfo redinfo, Companyservice companyservice) {

        // 处理redinfo
        redinfo.setCompanyId(companyservice.getCompanyid());
        redinfo.setSystemOrderno(IdUtils.randomSystemOrderno());
        if (StringUtils.isEmpty(redinfo.getOutTradeOrderno())) {  // 把 outTradeOrderno作为用户的申请单号
            throw new JianshuiParamErrorException(ErrorCode.EMPTY_REDINFO_NO, companyservice, "invoice");
        }
        redinfo.setOutTradeOrderno(redinfo.getOutTradeOrderno());
        redinfo.setFpqqlsh(redinfo.getSystemOrderno());
        redinfo.setRedInfoStatus("0");
        redinfo.setSellerName(companyservice.getSellername());
        redinfo.setSellerTaxnum(companyservice.getSellertax());
        redinfo.setBillInputTime(TimeUtil.dateFormat(new Date(), "yyyyMMddHHmmss"));
        List<Redinfodetail> redinfodetailList = redinfo.getRedinfodetailList();
        BigDecimal taxfreeamt = new BigDecimal(0); // 不含税金额
        BigDecimal tax = new BigDecimal(0); // 税额
        for (Redinfodetail detail : redinfodetailList) {
            taxfreeamt = taxfreeamt.add(detail.getTaxfreeamt());
            tax = tax.add(detail.getTax());
        }
        redinfo.setTax(tax);
        redinfo.setTaxfreeamt(taxfreeamt);
        redinfo.setTaxamt(tax.add(taxfreeamt));
        redinfoMapper.insertRedinfo(redinfo);
        int index = 0;
        for (Redinfodetail detail : redinfodetailList) {
            detail.setBillno(redinfo.getRedInfoNo());
            detail.setRedinfoId(redinfo.getId());
            detail.setIndex(++index);
            detail.setBillno(redinfo.getRedInfoNo());
            taxfreeamt = taxfreeamt.add(detail.getTaxfreeamt());
            tax = tax.add(detail.getTax());
        }
        redinfoMapper.batchRedinfodetail(redinfodetailList);

        String fplxdm = "";
        String invioceType = redinfo.getInvoiceType();
        fplxdm = ElephantUtils.transElephantType(invioceType, 1);
        // switch (invioceType) {
        //     case "p":
        //         fplxdm = "026";
        //         break;
        //     case "c":
        //         fplxdm = "007";
        //         break;
        //     case "s":
        //         fplxdm = "004";
        //         break;
        //     case "b":
        //         fplxdm = "028";
        //         break;
        //     case "j":
        //         fplxdm = "005";
        //         throw new JianshuiParamErrorException("暂不支持的开票类型，请联系管理员！", companyservice, "invoice");
        //     case "u":
        //         fplxdm = "006";
        //         throw new JianshuiParamErrorException("暂不支持的开票类型，请联系管理员！", companyservice, "invoice");
        //     case "r":
        //     default:
        //         throw new JianshuiParamErrorException("暂不支持的开票类型，请联系管理员！", companyservice, "invoice");
        // }

        ElephatRedInfoDTO elephatRedInfoDTO = new ElephatRedInfoDTO();

        // 配置头信息
        HZSQDSCPC HZSQDSCPC = new HZSQDSCPC();
        // HZSQDSCPC.setSQBSCQQPCH(IdUtils.randomSystemOrderno());  // "申请表上传请求批次号",
        HZSQDSCPC.setSQBSCQQPCH(redinfo.getOutTradeOrderno());  // "申请表上传请求批次号", // 大象要求如果只有一条申请信息，上传批次号必须和上传流水号一直，就是上传单号
        HZSQDSCPC.setNSRSBH(redinfo.getSellerTaxnum());  // "申请方纳税人识别号",
        HZSQDSCPC.setKPZD(redinfo.getTerminalNumber());  // "开票终端",
        HZSQDSCPC.setFPLXDM(fplxdm);  // "发票类型代码",
        HZSQDSCPC.setSQLB(Integer.toString(redinfo.getSqlb()));  // "申请类别,0 为销方申请,1 为购方申请",
        // HZSQDSCPC.setKZZD();  // "扩展字段"
        elephatRedInfoDTO.setHZSQDSCPC(HZSQDSCPC);

        // TODO 处理税额、不含税金额、含税金额

        // 配置订单头信息
        HZSQDTXX HZSQDTXX = new HZSQDTXX(redinfo);

        // 配置订单明细
        List<Redinfodetail> myRedinfodetailList = redinfo.getRedinfodetailList();
        List<DDMXXX> ddmxxxList = new ArrayList<>();
        for (int i = 0; i < myRedinfodetailList.size(); i++) {
            Redinfodetail temp = myRedinfodetailList.get(i);
            DDMXXX DDMXXX = new DDMXXX(temp);
            ddmxxxList.add(DDMXXX);
        }

        elephatRedInfoDTO.setHZSQDSCPC(HZSQDSCPC);

        List<HZSQDSCZXX> HZSQDSCZXXList = new ArrayList<>();
        HZSQDSCZXX HZSQDSCZXX = new HZSQDSCZXX();
        HZSQDSCZXX.setHZSQDTXX(HZSQDTXX);
        HZSQDSCZXX.setDDMXXX(ddmxxxList);
        HZSQDSCZXXList.add(HZSQDSCZXX);
        elephatRedInfoDTO.setHZSQDSCZXX(HZSQDSCZXXList);

        // AjaxResult queryResult = ElephantUtils.sendRequest(ElephantConstants.REDINFO_UPLOAD, JSONUtil.parse(elephatRedInfoDTO));
        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.REDINFO_UPLOAD_LOCALHOST, ElephantConstants.REDINFO_UPLOAD_METHOD, JSONUtil.parse(elephatRedInfoDTO), companyservice);
        } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
            log.error("【销项发票】【大象接口】【红字信息表上传】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(elephatRedInfoDTO).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】红字信息表上传请求结果{}", queryResult.toString());

        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }

        Object contentObject = queryResult.getData();
        JSONObject contentJson = new JSONObject();
        // 如果是json array
        if (contentObject.getClass().getName().equals("com.alibaba.fastjson.JSONArray")) {
            JSONArray contentArray = (JSONArray) contentObject;
            contentJson = contentArray.getJSONObject(0);
        } else {
            contentJson = queryResult.getJsonData();
        }

        // 外部状态代码
        String ztdm = contentJson.getString("ZTDM");
        if (!StringUtils.equals("0000", ztdm)) {
            redinfo.setRedInfoStatus("2");
            redinfo.setRedInfoMessage(contentJson.getString("ZTXX"));
            redinfoMapper.updateRedinfo(redinfo);
            return new HXResponse(contentJson.getString("ZTXX"));
        }

        // if (!StringUtils.equals("060000", ztdm) && !StringUtils.equals("060001", ztdm)) {
        //     redinfo.setRedInfoStatus("2");
        //     redinfo.setRedInfoMessage(contentJson.getString("ZTXX"));
        //     redinfoMapper.updateRedinfo(redinfo);
        //     return new HXResponse(contentJson.getString("ZTXX"));
        // }

        // 红字信息表成功报文
        /**
         * {
         *     "msg": "操作成功",
         *     "code": 200,
         *     "data": {
         *         "ZTXX": "成功",
         *         "SQBSCQQPCH": "d899831373174d9a8bf71e76f0dd030c",
         *         "ZTDM": "0000",
         *         "HZSQDSCJG": [{
         *             "ZTXX": "审核通过",
         *             "SQBSCQQLSH": "fce79f2be4c143438eb5e095bfbd5f81",
         *             "SQDH": "661505060963220417171834",
         *             "XXBBH": "5001012204024900",
         *             "ZTDM": "TZD0000"
         *         }]
         *     }
         * }
         */

        // HZSQDSCJG内部状态diamante
        JSONArray hzsqdscjg = contentJson.getJSONArray("HZSQDSCJG");
        String ztxx = "同步成功";
        ztdm = "0000";
        for (int i = 0; i < hzsqdscjg.size(); i++) {
            JSONObject temp = hzsqdscjg.getJSONObject(i);
            QueryWrapper<Redinfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("system_orderno", temp.getString("SQBSCQQLSH"));
            queryWrapper.orderByDesc("id");
            queryWrapper.last(" limit 1");
            Redinfo myRedinfo = redinfoMapper.selectOne(queryWrapper);
            if (myRedinfo != null) {
                String tempZtdm = temp.getString("ZTDM");
                if (StringUtils.equals(tempZtdm, "060000")) {
                    myRedinfo.setRedInfoStatus("1");
                    myRedinfo.setRedInfoMessage(temp.getString("ZTXX"));
                    ztxx = temp.getString("ZTXX");
                    ztdm = "0000";
                } else if (StringUtils.equals(tempZtdm, "060001")) {
                    myRedinfo.setRedInfoStatus("0");
                    myRedinfo.setRedInfoMessage(temp.getString("ZTXX"));
                    ztxx = temp.getString("ZTXX");
                    ztdm = "0000";
                } else {
                    myRedinfo.setRedInfoStatus("2");
                    myRedinfo.setRedInfoMessage(temp.getString("ZTXX"));
                    ztxx = temp.getString("ZTXX");
                    ztdm = "9999";
                }
                redinfoMapper.updateRedinfo(myRedinfo);
            }
        }


        return new HXResponse(ztdm, ztxx);
    }


    /**
     * 红字信息申请查询
     *
     * @param redinfo
     */
    @Override
    public AjaxResult queryRedInfo(Redinfo redinfo, Companyservice companyservice) {
        return AjaxResult.error("系统维护中");
    }

    /**
     * 红字信息表下载
     */
    @Override
    public HXResponse downloadRedInfo(DownloadRedInfoDTO downloadRedInfoDTO, Companyservice companyservice) {
        // 先去查之前的红票
        Redinfo redinfo = new Redinfo();
        redinfo.setRedInfoNo(downloadRedInfoDTO.getBillInfoNo());
        redinfo.setCompanyId(companyservice.getCompanyid());
        QueryWrapper<Redinfo> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getInvoiceLine())) {
            queryWrapper.eq("invoice_type", downloadRedInfoDTO.getInvoiceLine());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBuyerTaxNo())) {
            queryWrapper.eq("buyer_taxnum", downloadRedInfoDTO.getBuyerTaxNo());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getExtensionNumber())) {
            queryWrapper.eq("fjh", downloadRedInfoDTO.getExtensionNumber());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getTerminalNumber())) {
            queryWrapper.eq("terminal_number", downloadRedInfoDTO.getTerminalNumber());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillTimeBegin())) {
            queryWrapper.ge("bill_input_time", downloadRedInfoDTO.getBillTimeBegin());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillTimeEnd())) {
            queryWrapper.le("bill_input_time", downloadRedInfoDTO.getBillTimeEnd());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillNo())) {
            queryWrapper.le("out_trade_orderno", downloadRedInfoDTO.getBillNo());
        }
        queryWrapper.orderByDesc("id");
        queryWrapper.last(" limit 1 ");
        Redinfo redInfoResult = redinfoMapper.selectOne(queryWrapper);
        if (redInfoResult == null) {
            HXResponse response = new HXResponse("9999", "未查到指定红字信息");
            return response;
        }

        JSONObject queryJson = new JSONObject();
        String taxno = redInfoResult.getReqnsrsbh() == null ? companyservice.getSellertax() : redInfoResult.getReqnsrsbh();
        queryJson.put("SQBXZQQPCH", redInfoResult.getSystemOrderno()); // 申请表审核结果下载请求批次号",
        queryJson.put("NSRSBH", taxno); // 申请方纳税人识别号",
        String fplxdm = ElephantUtils.transElephantType(redInfoResult.getInvoiceType(), 1);
        queryJson.put("FPLXDM", fplxdm); // 发票类型代码",
        // 查询一个月之前的
        // Date tkrqq = DateUtil.offsetDay(new Date(), -5);
        // queryJson.put("TKRQQ", DateUtil.format(tkrqq,"yyyyMMdd")); // 填开日期起，可空",
        // queryJson.put("TKRQZ", DateUtil.format(new Date(),"yyyyMMdd")); // 填开日期止，可空",
        queryJson.put("TKRQQ", downloadRedInfoDTO.getBillTimeBegin()); // 填开日期起，可空",
        queryJson.put("TKRQZ",  downloadRedInfoDTO.getBillTimeEnd()); // 填开日期止，可空",
        queryJson.put("GMFSBH", redInfoResult.getBuyerTaxnum()); // 购买方税号，可空",
        queryJson.put("XHFSBH", redInfoResult.getSellerTaxnum()); // 销货方税号，可空",
        queryJson.put("XXBBH", ""); // 信息表编号，可空",
        // if (StringUtils.isNotEmpty(redInfoResult.getRedInfoNo())) {
        //     queryJson.put("XXBBH", redInfoResult.getRedInfoNo()); // 信息表编号，可空",
        // }
        queryJson.put("XXBFW", 0); // 信息表下载范围：0 全部；1 本企业申请；2 其它企业申请",
        int page = 1;
        queryJson.put("GS", 10); // 个数"
        List<RedInfoDTO> resultDTO = new ArrayList<>();

        for (; page < 11; page++) {
            queryJson.put("YS", page); // 页数",

            // AjaxResult queryResult = ElephantUtils.sendRequest(ElephantConstants.DEPRECATE_INVOICE, JSONUtil.parse(queryJson));
            AjaxResult queryResult = null;
            try {
                queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.REDINFO_DOWNLOAD_LOCALHOST, ElephantConstants.REDINFO_DOWNLOAD_METHOD, JSONUtil.parse(queryJson), companyservice);
            } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
                log.error("【销项发票】【大象接口】【红字信息表下载】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(queryJson).toString(), JSONObject.toJSONString(companyservice));
                break;
                // e.printStackTrace();
                // throw new JianshuiServiceException("系统异常！");
            }
            log.info("【销项发票】【大象发票】发票红字信息表下载请求结果{}", queryResult.toString());

            // 判断外层报文是否成功
            if (queryResult.isError()) {
                // 不是第一页之后的9999都给扔出去
                if(page > 1){
                    break;
                }
                throw new JianshuiServiceException(queryResult.getMsg());
            }

            // 处理返回报文
            JSONObject content = queryResult.getJsonData();
            String ztdm = content.getString("ZTDM");
            if (!StringUtils.equalsAny(ztdm, "060000", "0000")) {
                return new HXResponse(content.getString("ZTXX"));
            }

            List<Redinfo> result = new ArrayList<>();
            // 解析json
            ElephantDownloadRedinfoDTO downloadRedinfoDTO = content.toJavaObject(ElephantDownloadRedinfoDTO.class);
            List<HZSQDXZZXX> hzsqdxzzxxes = downloadRedinfoDTO.getHZSQDXZZXX(); // 获取返回结果
            for (int i = 0; i < hzsqdxzzxxes.size(); i++) {
                HZSQDXZZXX HZSQDXZZXX = hzsqdxzzxxes.get(i);
                HZSQDXZTXX HZSQDXZTXX = HZSQDXZZXX.getHZSQDXZTXX(); // 头信息
                // Redinfo queryRedinfo = new Redinfo();
                // queryRedinfo.setRedInfoNo(downloadRedInfoDTO.getBillInfoNo());
                // queryRedinfo.setCompanyId(companyservice.getCompanyid());
                QueryWrapper<Redinfo> tempQueryWrapper = new QueryWrapper<>();
                // tempQueryWrapper.eq("out_trade_orderno", HZSQDXZTXX.getSQDH());
                tempQueryWrapper.eq("origin_fpdm", HZSQDXZTXX.getYFPDM());
                tempQueryWrapper.eq("origin_fphm", HZSQDXZTXX.getYFPHM());
                tempQueryWrapper.last(" limit 1 ");
                Redinfo tempRedInfoResult = redinfoMapper.selectOne(tempQueryWrapper);
                if (tempRedInfoResult == null) {
                    // HXResponse response = new HXResponse("9999", "未查到指定红字信息");
                    // return response;
                    continue;
                }
                tempRedInfoResult.setCompanyId(companyservice.getCompanyid());
                tempRedInfoResult.setSystemOrderno(tempRedInfoResult.getSystemOrderno() == null ? IdUtils.randomSystemOrderno() : tempRedInfoResult.getSystemOrderno());
                // tempRedInfoResult.setOutTradeOrderno(tempRedInfoResult.getOutTradeOrderno() == null ? downloadRedInfoDTO.getBillInfoNo() : tempRedInfoResult.getOutTradeOrderno());
                // tempRedInfoResult.setOutTradeOrderno(HZSQDXZTXX.getSQDH()); // 2022年7月和中举聊的需求，outTradeOrderNo作为用户的申请单号，fpqqlsh作为系统的申请单号，做一个映射
                tempRedInfoResult.setFpqqlsh(HZSQDXZTXX.getSQDH());
                tempRedInfoResult.setBillInfoId(tempRedInfoResult.getBillInfoId());
                tempRedInfoResult.setRedInfoNo(HZSQDXZTXX.getXXBBH());
                // HZSQDXZTXX.getZTDM(),TZD0000
                if (StringUtils.equalsAnyIgnoreCase(HZSQDXZTXX.getZTDM(), "TZD0000", "TZD1000")) {
                    tempRedInfoResult.setRedInfoStatus("1");
                } else {
                    tempRedInfoResult.setRedInfoStatus("2");
                }
                tempRedInfoResult.setRedInfoMessage(tempRedInfoResult.getRedInfoMessage() == null ? HZSQDXZTXX.getZTXX() : tempRedInfoResult.getRedInfoMessage());
                tempRedInfoResult.setRedInfoType(HZSQDXZTXX.getXXBLX());
                tempRedInfoResult.setOriginFpdm(HZSQDXZTXX.getYFPDM());
                tempRedInfoResult.setRedInfoSpecFlag(HZSQDXZTXX.getXXBTSBS());
                tempRedInfoResult.setOriginFphm(HZSQDXZTXX.getYFPHM());
                tempRedInfoResult.setTaxType(HZSQDXZTXX.getYYSBZ());
                tempRedInfoResult.setOriginKprq(tempRedInfoResult.getOriginKprq());
                tempRedInfoResult.setMultTaxRate(tempRedInfoResult.getMultTaxRate());
                tempRedInfoResult.setBillInputTime(HZSQDXZTXX.getTKSJ());
                tempRedInfoResult.setBuyerName(HZSQDXZTXX.getGMFMC());
                tempRedInfoResult.setBuyerTaxnum(HZSQDXZTXX.getGMFSBH());
                tempRedInfoResult.setSellerName(HZSQDXZTXX.getXHFMC());
                tempRedInfoResult.setSellerTaxnum(HZSQDXZTXX.getXHFSBH());
                tempRedInfoResult.setTaxfreeamt(new BigDecimal(HZSQDXZTXX.getHJJE()));
                tempRedInfoResult.setTax(new BigDecimal(HZSQDXZTXX.getHJSE()));
                tempRedInfoResult.setTaxamt(tempRedInfoResult.getTaxamt() == null ? tempRedInfoResult.getTaxfreeamt().add(tempRedInfoResult.getTax()) : tempRedInfoResult.getTaxamt());
                tempRedInfoResult.setApplyRemark(HZSQDXZTXX.getSQSM());
                tempRedInfoResult.setPdfUrl(tempRedInfoResult.getPdfUrl());
                tempRedInfoResult.setBmbbh(HZSQDXZTXX.getBMBBBH());
                tempRedInfoResult.setBusinessTaxCode(HZSQDXZTXX.getYYSBZ());
                tempRedInfoResult.setApplyTime(tempRedInfoResult.getApplyTime());
                String fplxdmTemp = HZSQDXZTXX.getFPLXDM();
                // 0.增值税专票 2 增值税普通纸质发票 51 增值税普通电子发票
                if (StringUtils.equals(HZSQDXZTXX.getFPLXDM(), "0")) {
                    fplxdmTemp = "004";
                }
                if (StringUtils.equals(HZSQDXZTXX.getFPLXDM(), "2")) {
                    fplxdmTemp = "007";
                }
                if (StringUtils.equals(HZSQDXZTXX.getFPLXDM(), "51")) {
                    fplxdmTemp = "026";
                }
                tempRedInfoResult.setInvoiceType(ElephantUtils.transElephantType(fplxdmTemp, 2));
                tempRedInfoResult.setFjh(tempRedInfoResult.getFjh());
                tempRedInfoResult.setTerminalNumber(tempRedInfoResult.getTerminalNumber());
                tempRedInfoResult.setJspbh(tempRedInfoResult.getJspbh());
                tempRedInfoResult.setSsyf(tempRedInfoResult.getSsyf());
                tempRedInfoResult.setTaxrate(tempRedInfoResult.getTaxrate());
                tempRedInfoResult.setSqxz(tempRedInfoResult.getSqxz());
                tempRedInfoResult.setJbr(tempRedInfoResult.getJbr());
                tempRedInfoResult.setReqnsrsbh(tempRedInfoResult.getReqnsrsbh());
                tempRedInfoResult.setProductOilFlag(tempRedInfoResult.getRedInfoSpecFlag());
                tempRedInfoResult.setServiceSupplierKey(downloadRedInfoDTO.getServiceKey());
                // 处理红字信息表详情
                // 偷个懒，少写个mapper
                Redinfo myRedinfo = redinfoMapper.selectRedinfoById(tempRedInfoResult.getId());
                List<Redinfodetail> redinfodetailList = new ArrayList<>();
                Map<String, DDMXXX> ddmxxxMap = HZSQDXZZXX.getDDMXXX().stream().collect(Collectors.toMap(DDMXXX::getXH, DDMXXX::getSelf));
                RedInfoDTO tempDTO = new RedInfoDTO();
                List<RedInfoDetailDTO> tempDetailDTO = new ArrayList<>();
                for (int j = 0; j < ddmxxxMap.size(); j++) {
                    Redinfodetail tempRedinfodetail = new Redinfodetail();
                    DDMXXX ddmxxx = ddmxxxMap.get(Integer.toString(j + 1));
                    tempRedinfodetail.setId(null);
                    tempRedinfodetail.setRedinfoId(myRedinfo.getId());
                    tempRedinfodetail.setIndex(Integer.parseInt(ddmxxx.getXH()));
                    // tempRedinfodetail.setBillno(tempRedInfoResult.getRedInfoNo());
                    tempRedinfodetail.setBillno(tempRedInfoResult.getOutTradeOrderno());
                    tempRedinfodetail.setGoodName(ddmxxx.getXMMC());
                    tempRedinfodetail.setUnit(ddmxxx.getDW());
                    tempRedinfodetail.setSpec(ddmxxx.getGGXH());
                    tempRedinfodetail.setTaxrate(new BigDecimal(ddmxxx.getSL()));
                    tempRedinfodetail.setZzstsgl(ddmxxx.getZZSTSGL());
                    tempRedinfodetail.setFphxz(0);
                    if (!StringUtils.isEmpty(ddmxxx.getFPHXZ())) {
                        tempRedinfodetail.setFphxz(Integer.parseInt(ddmxxx.getFPHXZ()));
                    }
                    if (StringUtils.isNotEmpty(ddmxxx.getKCE())) {
                        tempRedinfodetail.setKce(new BigDecimal(ddmxxx.getKCE()));
                    }
                    String hsbz = ddmxxx.getHSBZ();
                    if (StringUtils.equals(hsbz, "0")) {
                        tempRedinfodetail.setTaxfreeamt(new BigDecimal(ddmxxx.getJE()));
                        tempRedinfodetail.setTax(new BigDecimal(ddmxxx.getSE()));
                        tempRedinfodetail.setTaxamt(tempRedinfodetail.getTaxfreeamt().add(tempRedinfodetail.getTax()));
                        if (ddmxxx.getDJ() != null) {
                            tempRedinfodetail.setPrice(new BigDecimal(ddmxxx.getDJ()));
                        }
                    } else {
                        tempRedinfodetail.setTaxamt(new BigDecimal(ddmxxx.getJE()));
                        tempRedinfodetail.setTax(new BigDecimal(ddmxxx.getSE()));
                        tempRedinfodetail.setTaxfreeamt(tempRedinfodetail.getTaxamt().add(tempRedinfodetail.getTax()));
                        if (ddmxxx.getDJ() != null) {
                            // 如果是含税的单价 则不含税单价为 含税单价 / (1 + 税率)
                            BigDecimal priceWithoutTax = (new BigDecimal(ddmxxx.getDJ())).divide((new BigDecimal(1)).add(tempRedinfodetail.getTaxrate()));
                            tempRedinfodetail.setPrice(priceWithoutTax);
                            // new BigDecimal(ddmxxx.getDJ())
                        }
                    }
                    tempRedinfodetail.setLslbs(ddmxxx.getLSLBS());
                    tempRedinfodetail.setSpbm(ddmxxx.getSPBM());
                    tempRedinfodetail.setYhzcbs(Integer.parseInt(ddmxxx.getYHZCBS()));
                    if (ddmxxx.getSL() != null) {
                        tempRedinfodetail.setNum(new BigDecimal(ddmxxx.getSL()));
                    }
                    redinfodetailList.add(tempRedinfodetail);
                    RedInfoDetailDTO myTempDetailDTO = new RedInfoDetailDTO();
                    BeanUtils.copyProperties(tempRedinfodetail, myTempDetailDTO);
                    tempDetailDTO.add(myTempDetailDTO);
                }
                redinfoMapper.deleteRedinfodetailByRedinfoId(tempRedInfoResult.getId());
                redinfoMapper.batchRedinfodetail(redinfodetailList);

                redinfoMapper.updateRedinfo(tempRedInfoResult);
                tempRedInfoResult.setRedinfodetailList(redinfodetailList);
                result.add(tempRedInfoResult);
                BeanUtils.copyProperties(tempRedInfoResult, tempDTO);
                tempDTO.setMyRedinfodetailList(tempDetailDTO);
                // 判断一下是否是需要的dto
                if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillNo())) {
                    // if (!StringUtils.equals(tempDTO.getOutTradeOrderno(), downloadRedInfoDTO.getBillNo())) {
                    if (!((StringUtils.equals(tempDTO.getOriginFpdm(), redInfoResult.getOriginFpdm())) && (StringUtils.equals(tempDTO.getOriginFphm(), redInfoResult.getOriginFphm())))) { // 狗比大象，他的申请单号是他们返回的，诺诺是我们上传的，我们只能用他们返回的申请单号
                        continue;
                    } else {
                        page = 1000;
                        resultDTO.add(tempDTO);
                    }
                } else {
                    // 只有当billNo为空的时候，才返回列表，否则就是精确查询
                    resultDTO.add(tempDTO);
                }
            }
        }

        return new HXResponse("0000", "查询成功", JSONObject.toJSON(resultDTO));
    }

    /**
     * 发票作废
     *
     * @param billInfo
     * @return AjaxResult
     */
    @Override
    public HXResponse deprecateInvoice(JSONObject billInfo, Companyservice companyservice) {

        // TODO-: 2022/10/7  发票作废，兼容支持通过代码、号码获取。现在必须要开票返回的流水号。
        // 查找原来的发票
        String fpqqlsh = billInfo.getString("fpqqlsh");
        String fpdm = billInfo.getString("fpdm");
        String fphm = billInfo.getString("fphm");

        // 发票查询
        Invoice invoice = null;
        if (StringUtils.isNotEmpty(fpqqlsh)) {
            invoice = invoiceMapper.selectBySystemOrderNo(companyservice.getCompanyid(), fpqqlsh);
        } else if (StringUtils.isNotEmpty(fpdm) && StringUtils.isNotEmpty(fphm)) {
            invoice = invoiceMapper.selectByFpdmFphm(companyservice.getCompanyid(), fpdm, fphm);
        } else {
            throw new JianshuiParamErrorException(ErrorCode.EMPTY_FPQQLSH, companyservice, "invoice");
        }

        //发票不存在
        if (invoice == null) {
            throw new JianshuiParamErrorException(ErrorCode.INVOICE_NOT_EXISTS, companyservice, "invoice");
        }

        // TODO 发票状态查询

        // 发起作废
        JSONObject queryBody = new JSONObject();
        queryBody.put("XHFSBH", companyservice.getSellertax()); // 销货方纳税人识别号
        queryBody.put("FPLXDM", ElephantUtils.transElephantType(invoice.getInvoiceType(), 1));
        queryBody.put("FPDM", invoice.getFpdm());
        queryBody.put("FPHM", invoice.getFphm());
        queryBody.put("FPQH", invoice.getFphm());
        queryBody.put("FPZH", invoice.getFphm());
        queryBody.put("ZFLX", "1");
        queryBody.put("ZFPCH", IdUtils.randomSystemOrderno());
        // AjaxResult queryResult = ElephantUtils.sendRequest(ElephantConstants.DEPRECATE_INVOICE, JSONUtil.parse(queryBody));
        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.DEPRECATE_INVOICE_LOCALHOST, ElephantConstants.DEPRECATE_INVOICE_METHOD, JSONUtil.parse(queryBody), companyservice);
        } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
            log.error("【销项发票】【大象接口】【发票作废】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(queryBody).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】发票作废请求结果{}", queryResult.toString());

        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }

        // 处理返回报文
        JSONObject content = queryResult.getJsonData();
        String ztdm = content.getString("ZTDM");
        if (!StringUtils.equalsAny(ztdm, "040000")) {
            return new HXResponse(content.getString("ZTXX"));
        }
        // TODO 发票作废通过接口查询
        // // 获取作废状态
        // queryBody = new JSONObject();
        // queryBody.put("XHFSBH", companyservice.getSellertax()); // 销货方纳税人识别号
        // queryBody.put("FPDM", invoice.getFpdm());
        // queryBody.put("FPHM", invoice.getFphm());
        // // queryResult = ElephantUtils.sendRequest(ElephantConstants.DEPRECATE_INVOICE_RESULT, JSONUtil.parse(queryBody));
        // try {
        //     queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.DEPRECATE_INVOICE_RESULT_LOCALHOST, ElephantConstants.DEPRECATE_INVOICE_RESULT_METHOD, JSONUtil.parse(queryBody), companyservice);
        // } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException e) {
        //     log.error("【销项发票】【大象接口】【发票开具】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(queryBody).toString(), JSONObject.toJSONString(companyservice));
        //     e.printStackTrace();
        //     throw new JianshuiServiceException("系统异常！");
        // }
        // log.info("【销项发票】【大象发票】发票开具请求结果{}", queryResult.toString());
        //
        // // 判断外层报文是否成功
        // if (queryResult.isError()) {
        //     throw new JianshuiServiceException(queryResult.getMsg());
        // }
        //
        // // 处理返回报文
        // content = queryResult.getJsonData();
        // ztdm = content.getString("ZTDM");
        // if (!StringUtils.equals(ztdm, "000000")) {
        //     return new HXResponse(content.getString("ZTXX"));
        // }

        // 修改原有发票状态为已作废
        invoice.setState(3);
        invoiceMapper.updateInvoice(invoice);

        // 更新原有订单
        BillInfo originBillInfo = billInfoMapper.selectBySystemOrderNo(companyservice.getCompanyid(), invoice.getSystemOrderno());
        // BillInfo originBillInfo = new BillInfo();
        if (originBillInfo == null) {
            log.error("【销项】【大象发票】作废发票，无法查找到原有发票{}", JSONObject.toJSONString(invoice));
        } else {
            originBillInfo.setState(3);
            billInfoMapper.updateBillInfo(originBillInfo);
        }

        String callbackUrl = originBillInfo.getCallbackUrl();
        if (StringUtils.isNotEmpty(callbackUrl)) {
            RedisQueueUtil.build().setData(invoice).onQueue("invoice_deprecate_callback_consumer").retry(0).dispatch();
        }

        return new HXResponse("0000", "操作完成", null, false);
    }

    /**
     * 发票作废结果查询
     *
     * @param companyservice
     * @return
     */
    public HXResponse deprecateQueryInvoice(DeprecateQueryInvoiceDTO deprecateQueryInvoiceDTO, Companyservice companyservice) {
        Invoice invoice = new Invoice();
        invoice.setSellerTaxnum(companyservice.getSellertax());
        invoice.setFpdm(deprecateQueryInvoiceDTO.getFpdm());
        invoice.setFphm(deprecateQueryInvoiceDTO.getFphm());
        QueryWrapper<Invoice> queryWrapper = new QueryWrapper<>(invoice);
        queryWrapper.last(" limit 1 ");
        Invoice result = invoiceMapper.selectOne(queryWrapper);
        if (result == null) {
            return new HXResponse("9999", "发票不存在");
        }

        JSONObject status = new JSONObject();
        status.put("status", result.getState());
        return new HXResponse("0000", "操作完成", status);
    }

    /**
     * 打印接口
     *
     * @param invoice
     * @return
     */
    @Override
    public AjaxResult printInvoice(Invoice invoice, Companyservice companyservice) {
        return AjaxResult.error("系统维护中");
    }

    /**
     * 打印机查询
     *
     * @param queryPrinterDTO
     * @param companyservice
     * @return
     */
    public HXResponse queryPrinter(QueryPrinterDTO queryPrinterDTO, Companyservice companyservice) {
        JSONObject query = new JSONObject();
        query.put("NSRSBH", companyservice.getSellertax());
        query.put("DYJMC", queryPrinterDTO.getPrinterName());
        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.QUERY_PRINTER_LOCALHOST, ElephantConstants.QUERY_PRINTER, JSONUtil.parse(query), companyservice);
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
            log.error("【销项发票】【大象接口】【打印机查询】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(query).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】打印机查询请求结果{}", queryResult.toString());


        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }

        JSONObject result = queryResult.getJsonData();
        JSONObject contentJson = result;

        // 如果content不为空，判断状态代码
        if (contentJson != null) {
            String ztdm = contentJson.getString("ZTDM");
            if (!StringUtils.equals("0000", ztdm) && !StringUtils.equals("000000", ztdm)) {
                return new HXResponse(contentJson.getString("ZTXX"));
            }
        }

        JSONArray printerList = contentJson.getJSONArray("DYJXX"); // 获取打印机信息
        List<QueryPrinterResultDTO> resultDTOS = new ArrayList<>();
        for (Object printerTemp : printerList) {
            QueryPrinterResultDTO temp = new QueryPrinterResultDTO();
            JSONObject printer = (JSONObject) printerTemp;
            temp.setPrinterId(printer.getString("DYJID"));
            temp.setPrinterName(printer.getString("DYJMC"));
            temp.setXxpy(printer.getString("XXPY"));
            temp.setXypy(printer.getString("XYPY"));
            temp.setBz(printer.getString("BZ"));
            resultDTOS.add(temp);
        }

        return new HXResponse("0000", "操作完成", resultDTOS);
    }


    /**
     * 推送消息
     *
     * @return
     */
    @Override
    public HXResponse pushData(BillInfo billInfo, Companyservice companyservice) {
        // TODO 获取发票数据
        return new HXResponse("0000", "操作完成");
    }


    /**
     * 批量打印
     *
     * @param printDTO
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse batchPrint(PrintDTO printDTO, Companyservice companyservice) {
        JSONObject query = new JSONObject();
        query.put("NSRSBH", companyservice.getSellertax()); // "纳税人识别号",
        query.put("FJH", printDTO.getFjh()); // "分机号",
        query.put("DYJID", printDTO.getPrinterId()); // "打印机ID",
        query.put("DYPCH", printDTO.getDypch()); // "打印批次号",
        query.put("FPBS", printDTO.getFpbs());// "发票标识",
        List<PrintDetailDTO> printDetailDTOS = printDTO.getDetails();
        if (CollectionUtils.isNotEmpty(printDetailDTOS)) {
            JSONArray tmepDetails = new JSONArray();
            for (PrintDetailDTO temp : printDetailDTOS) {
                JSONObject tempQuery = new JSONObject();
                tempQuery.put("FPZLDM", ElephantUtils.transElephantType(temp.getInvoiceType(), 1)); // "发票种类代码",
                tempQuery.put("FPDM", temp.getFpdm()); // "发票代码",
                tempQuery.put("FPQH", temp.getFpqh()); // "发票起号",
                tempQuery.put("FPZH", temp.getFpzh()); // "发票止号"
                tmepDetails.add(tempQuery);
            }
            query.put("DYFPXX", tmepDetails);
        }

        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequestWithoutToken(ElephantConstants.BATCH_PRINT_LOCALHOST, ElephantConstants.BATCH_PRINT, JSONUtil.parse(query), companyservice);
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
            log.error("【销项发票】【大象接口】【打印机查询】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(query).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】打印机查询请求结果{}", queryResult.toString());


        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }

        JSONObject result = queryResult.getJsonData();
        JSONObject contentJson = result;

        // 如果content不为空，判断状态代码
        if (contentJson != null) {
            String ztdm = contentJson.getString("ZTDM");
            if (!StringUtils.equals("0000", ztdm) && !StringUtils.equals("000000", ztdm)) {
                return new HXResponse(contentJson.getString("ZTXX"));
            }
        }

        return new HXResponse("0000", "操作完成");
    }

    /**
     * 同步发票库存
     *
     * @param companyservice
     * @return
     */
    @Override
    public AjaxResult syncStockInfo(Companyservice companyservice) {
        return AjaxResult.error("系统维护中");
    }


    /**
     * 发票签章
     *
     * @param signESealDTO
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse signInvoice(SignESealDTO signESealDTO, Companyservice companyservice) {

        if (BeanUtil.isEmpty(signESealDTO)) {
            HXResponse response = new HXResponse("9999", "传输参数为空！");
            return response;
        }
        AjaxResult queryResult = null;
        System.out.println(JSONUtil.parse(signESealDTO).toString());
        try {
            queryResult = ElephantUtils.sendRequest(ElephantConstants.SIGN
                    , JSONUtil.parse(signESealDTO), companyservice, true);
        } catch (Exception e) {
            log.error("【销项发票】【大象接口】【发票签章】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(signESealDTO).toString()
                    , JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        // 判断外层报文是否成功
        if (queryResult.isError()) {
            log.info("【销项发票】【大象发票】发票签章外层报文异常{}", queryResult.toString());
            throw new JianshuiServiceException(queryResult.getMsg());
        }
        JSONObject result = queryResult.getJsonData();
        return new HXResponse("0000", "操作完成", result);
    }

    /**
     * 发票专用章图片生成
     *
     * @param createESealDTO
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse createESeal(CreateESealDTO createESealDTO, Companyservice companyservice) {
        if (BeanUtil.isEmpty(createESealDTO)) {
            HXResponse response = new HXResponse("9999", "传输参数为空！");
            return response;
        }

        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequest(ElephantConstants.SIGN_CREATE
                    , JSONUtil.parse(createESealDTO), companyservice, true);
        } catch (Exception e) {
            log.error("【销项发票】【大象接口】【发票专用章图片生成】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(createESealDTO).toString()
                    , JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】发票专用章图片生成请求结果{}", queryResult.toString());


        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }
        JSONObject result = queryResult.getJsonData();
        return new HXResponse("0000", "操作完成", result);
    }

    /**
     * 发票专用章导入
     *
     * @param createESealDTO
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse registerESeal(RegisterESealDTO createESealDTO, Companyservice companyservice) {
        if (BeanUtil.isEmpty(createESealDTO)) {
            HXResponse response = new HXResponse("9999", "传输参数为空！");
            return response;
        }

        AjaxResult queryResult = null;
        try {
            queryResult = ElephantUtils.sendRequest(ElephantConstants.SIGN_REGISTER
                    , JSONUtil.parse(createESealDTO), companyservice, true);
        } catch (Exception e) {
            log.error("【销项发票】【大象接口】【发票专用章导入】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(createESealDTO).toString()
                    , JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】发票专用章导入请求结果{}", queryResult.toString());


        // 判断外层报文是否成功
        if (queryResult.isError()) {
            throw new JianshuiServiceException(queryResult.getMsg());
        }
        JSONObject result = queryResult.getJsonData();
        return new HXResponse("0000", "操作完成", result);
    }

    /**
     * 月度汇总信息查询
     *
     * @param summaryReportQueryDTO
     * @param companyservice
     * @return
     */
    @Override
    public AjaxResult SummaryReport(SummaryReportQueryDTO summaryReportQueryDTO, Companyservice companyservice) {
        return AjaxResult.error("系统维护中");
    }

    /**
     * 回调处理
     *
     * @param request
     * @return
     */
    @Override
    public Object callback(HttpServletRequest request) {
        String respBody = HttpHelper.getBodyString(request);
        log.info("【销项发票】【大象发票】回调接口数据：{}", respBody);
        // 对content进行解码
        JSONObject jsonRaw = JSONObject.parseObject(respBody);
        String content = jsonRaw.getString("jsonRaw");
        // TODO 不止发票作废，发票开具成功等均有回调
        // 处理发票作废
        JSONObject json = JSONObject.parseObject(content);
        Long companyId = null;
        Companyservice companyservice = companyserviceMapper.selectFirstCompanyserviceBySellerTax(json.getString("XHFSBH"));
        if (companyservice != null) {
            companyId = companyservice.getCompanyid();
        }

        return AjaxResult.success();
    }

    @Override
    public Object addCallback(HttpServletRequest request) {
        String respBody = HttpHelper.getBodyString(request);
        log.info("【销项发票】【大象发票】开票回调接口数据：{}", respBody);
        // 对content进行解码
        JSONObject jsonRaw = JSONObject.parseObject(respBody);
        String content = jsonRaw.getString("content");
        content = Base64.decodeStr(content);
        JSONObject contentJson = JSONObject.parseObject(content);
        Long companyId = null;
        if (!StringUtils.equals("0000", contentJson.getString("ZTDM"))) {
            log.info("【销项发票】【大象发票】开票回调接口数据：{},状态代码非0000，异常", respBody);
            JSONObject resp = new JSONObject();
            resp.put("ZTDM", "009999");
            resp.put("ZTXX", "接收失败");
            return resp;
            // JSONArray array = new JSONArray();
            // resp.put("DDFPTS", "接受失败");
        }

        JSONArray respInvoiceArray = new JSONArray();
        JSONArray DDFZPXX = contentJson.getJSONArray("DDFPZXX");
        log.info("【销项发票】【大象发票】开票回调接口数据：{},共{}张明细", respBody, DDFZPXX.size());
        for (int i = 0; i < DDFZPXX.size(); i++) {
            JSONObject fp = DDFZPXX.getJSONObject(i);
            JSONObject DDFPXX = fp.getJSONObject("DDFPXX");
            String DDH = DDFPXX.getString("DDH");
            QueryWrapper<BillInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("system_orderno", DDH);
            queryWrapper.eq("seller_taxnum", DDFPXX.getString("NSRSBH"));
            BillInfo billInfo = billInfoMapper.selectOne(queryWrapper);
            if (billInfo == null) {
                log.info("【销项发票】【大象发票】开票回调接口数据：{},订单号{}不存在", respBody, DDH);
                continue;
            }

            companyId = billInfo.getCompanyId();
            Companyservice companyservice = companyserviceMapper.selectCompanyserviceByCompanyid(companyId);
            if (companyservice == null) {
                log.info("【销项发票】【大象发票】开票回调接口数据：{},销方不存在，订单号：{}", respBody, DDH);
                continue;
            }

            String DDQQLSH = DDFPXX.getString("DDQQLSH");
            QueryBillInfoDTO queryBillInfoDTO = new QueryBillInfoDTO();
            queryBillInfoDTO.setFpqqlsh(DDQQLSH);
            queryBillInfoDTO.setCompanyId(companyId);
            queryBillInfoDTO.setPushBillInfo(true); // 推送发票信息
            HXResponse queryResp = queryInvoice(queryBillInfoDTO, companyservice);
            log.info("【销项发票】【大象发票】开票回调接口查询发票信息：{}", JSONObject.toJSONString(queryResp));

            JSONObject tempResp = new JSONObject();
            tempResp.put("DDQQLSH", DDQQLSH);
            tempResp.put("DDH", DDH);
            tempResp.put("ZTDM", "000000");
            tempResp.put("ZTDM", "009999");
            respInvoiceArray.add(tempResp);
        }

        JSONObject resp = new JSONObject();
        resp.put("ZTDM", "000000");
        resp.put("ZTXX", "接收成功");
        resp.put("DDFPTS", respInvoiceArray);
        log.info("【销项发票】【大象发票】回调处理完成，开票回调接口返回数据：{}", JSONObject.toJSONString(resp));
        return resp;
    }

    @Override
    public Object decryptCallback(HttpServletRequest request) {
        String respBody = HttpHelper.getBodyString(request);
        log.info("【销项发票】【大象发票】作废回调接口数据：{}", respBody);
        // 对content进行解码
        JSONObject jsonRaw = JSONObject.parseObject(respBody);
        String content = jsonRaw.getString("content");
        content = Base64.decodeStr(content);
        JSONObject contentJson = JSONObject.parseObject(content);
        Long companyId = null;
        String sellerTaxno = contentJson.getString("XHFSBH");
        if (StringUtils.isEmpty(sellerTaxno)) {
            return AjaxResult.error("销方识别号为空");
        }
        Companyservice companyservice = companyserviceMapper.selectCompanyserviceByTaxcode(sellerTaxno);
        if (companyservice == null) {
            return AjaxResult.error("销方识别号不存在");
        }
        companyId = companyservice.getCompanyid();

        JSONArray jsonArray = contentJson.getJSONArray("ZFFPXX");
        JSONArray respArray = new JSONArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject fpxx = jsonArray.getJSONObject(i);
            String fpdm = fpxx.getString("FPDM");
            String fphm = fpxx.getString("FPHM");
            QueryWrapper<Invoice> temp = new QueryWrapper<>();
            temp.eq("fpdm", fpdm);
            temp.eq("fphm", fphm);
            temp.eq("company_id", companyId);
            temp.last("limit 1");
            Invoice invoice = invoiceMapper.selectOne(temp);
            boolean flag = false;
            if (invoice != null) {
                flag = true;
                String ztdm = fpxx.getString("ZTDM");
                if (StringUtils.equals(ztdm, "163000")) {
                    invoice.setState(3);
                    invoiceMapper.updateInvoice(invoice);
                }
            }
            if (!flag) {
                fpxx.put("ZTDM", "163999");
            } else {
                fpxx.put("ZTDM", "163000");
            }
            respArray.add(fpxx);
        }
        JSONObject resp = new JSONObject();
        resp.put("ZFPCH", contentJson.getString("ZFPCH"));
        resp.put("ZFFPXX", respArray);
        return resp;
    }

    @Override
    public HXResponse getFileUrl(InvoiceAllFileAcquisitionTWODTO invoiceAllFileAcquisitionTWODTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse getFileAcquisitionOn(InvoiceAllFileAcquisitionOnTWODTO invoiceAllFileAcquisitionOnTWODTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse qrcode(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse query(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse getPrintXML(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse issueFastRedInvoice(InvoiceAllKshcTWODTO invoiceAllKshcDTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse invoiceStatic(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse auditRedInfo(InvoiceAllShhzTWODTO invoiceAllShhzTWODTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse queryRedInfoDetail(InvoiceAllRedInvoiceDetailTWODTO invoiceAllRedInvoiceDetailDTO, Companyservice companyservice) {
        return null;
    }


}
