package com.dxhy.jxpt.baseService.sign.service.fpqs.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dxhy.api.model.config.UserInfo;
import com.dxhy.api.model.config.sys.SysEnterpriseConfigEntity;
import com.dxhy.api.model.invoice.TDxRecordInvoice;
import com.dxhy.api.model.sign.*;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.*;
import com.dxhy.common.service.InvoiceLogService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.DateTimeHelper;
import com.dxhy.common.util.ScanIdUtils;
import com.dxhy.common.util.UserInfoUtil;
import com.dxhy.common.utils.CommonUtil;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.common.vo.InvoiceLog;
import com.dxhy.jxpt.baseService.sign.dao.SignRecordInvoiceDao;
import com.dxhy.jxpt.baseService.sign.dao.SysEnterpriseConfigSignDao;
import com.dxhy.jxpt.baseService.sign.service.elec.SignInvoiceScanService;
import com.dxhy.jxpt.baseService.sign.service.fpqs.FpqsService;
import com.dxhy.jxpt.baseService.sign.service.singletable.SignInvoiceDetailService;
import com.dxhy.jxpt.baseService.sign.service.singletable.SignInvoiceStatisticsService;
import com.dxhy.jxpt.baseService.sign.service.singletable.SignSaveInvoiceInfoService;
import com.dxhy.jxpt.baseService.util.InvoiceQueryUtil;
import com.dxhy.jxpt.baseService.util.SignRulesUtils;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class FpqsServiceImpl extends MpBaseServiceImpl<SignRecordInvoiceDao, TDxRecordInvoice> implements FpqsService {

    @Resource
    private SignRulesUtils signRulesUtils;

    @Resource
    private InvoiceQueryUtil invoiceQueryUtil;

    @Resource
    private SysEnterpriseConfigSignDao sysEnterpriseConfigSignDao;

    @Resource
    private SignSaveInvoiceInfoService saveInvoiceInfoService;

    @Resource
    private ScanIdUtils scanIdUtils;

    @Resource
    private SignInvoiceScanService signInvoiceScanService;

    @Resource
    private SignInvoiceDetailService signInvoiceDetailService;

    @Resource
    private InvoiceLogService invoiceLogService;

    @Resource
    private SignSaveInvoiceInfoService signSaveInvoiceInfoService;

    @Resource
    private SignInvoiceStatisticsService signInvoiceStatisticsService;

    /**
     * 底账表对比签收
     *
     * @param pramsMap
     *            请求参数
     * @param userInfo
     *            用户信息
     * @param qsType
     *            invoiceType 请求参数
     * @return 逻辑如下： 1、基础信息校验 不一致insertOrUpdate扫描表 2、查看扫描表中是否存在此发票信息(是否重复签收) 3、查询底账表信息 4、签收规则校验，不一致insertOrUpdate扫描表
     *         5、发票insertOrUpdate入库
     */
    @Override
    public Object[] zpSaveInvoice(Map<String, String> pramsMap, UserInfo userInfo, String qsType, String invoiceType,JSONObject checkInvoiceResult) {
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);

        // 获取该公司的所需权限
        List<SignRulesEntity> rules = getRules(pramsMap.get("company"));
        log.info("签收的发票信息为：{} ----签收发票的方式为:{}", pramsMap,qsType);

        // 返回信息组装
        Object[] result = new Object[3];
        result[0] = false;

        // 1、基础信息校验
//        String note ="";
        String uuid ="";
        uuid = (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode")) + pramsMap.get("invoiceNo");

        //支持全电，用查到的票种和数电号码
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);

//        if(!FplxEnum.QDZZP.getFplxDm().equals(invoiceType)
//                &&!FplxEnum.QDPP.getFplxDm().equals(invoiceType)
//                &&!FplxEnum.TLKP.getFplxDm().equals(invoiceType)
//                &&!FplxEnum.HKDZFP.getFplxDm().equals(invoiceType)
//                &&!FplxEnum.JDCDZ.getFplxDm().equals(invoiceType)
//                &&!FplxEnum.TLKP.getFplxDm().equals(invoiceType)
//                &&!FplxEnum.HKDZFP.getFplxDm().equals(invoiceType)
//        ){
//            note = signRulesUtils.validateInvoiceInfo(pramsMap.get("invoiceCode"), pramsMap.get("invoiceNo"));
//        }


        // 2、查看扫描表中是否存在此发票信息
        TDxInvoice scanInvoice = signInvoiceScanService.queryByUuid(uuid, userInfo.getDbName());

        if (scanInvoice == null) {
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice = signInvoiceScanService.queryByScanId(pramsMap.get("scanId"), userInfo.getDbName());
            }
        }
//        if (StringUtils.isNotBlank(note)) {
//            // 校验失败存储失败扫描信息
//            result[1] = note;
//            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
//            createFailScanInvoice(pramsMap, note, scanInvoice, userInfo, invoiceType, qsType);
//            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
//            return result;
//        }

        // 判断该发票是否已签收
        if (scanInvoice != null) {
            if (scanInvoice.getQsStatus().equals(FpqsjgEnum.YQS.getQsjgDm())) {
                result[1] = "该发票已签收，请检查发票信息是否识别正确";
                log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
                return result;
            }
        }

        // 3、查询底账表信息

        TDxRecordInvoice recordInvoice = getRecordInvoiceByUuid(uuid);
        if (recordInvoice == null) {
            log.info("要是有查验结果，用查验结果赋值:{}",ObjectUtil.isNotEmpty(checkInvoiceResult)?true:false);
            if(ObjectUtil.isNotEmpty(checkInvoiceResult)){
                recordInvoice = saveInvoiceInfoService.getRecordInvoice(checkInvoiceResult, userInfo.getUsername(), qsType);
            }
            // 校验失败存储失败扫描信息
            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
            createFailScanInvoice(pramsMap, "发票信息不存在", scanInvoice, userInfo, invoiceType, qsType,recordInvoice);
            result[1] = "发票信息不存在";
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            return result;
        }
        //把金额，税额，价税合计放入pramsMap中
//        pramsMap.put("invoiceAmount", recordInvoice.getInvoiceAmount()+"");
//        pramsMap.put("taxAmount",recordInvoice.getTaxAmount()+"");
//        pramsMap.put("totalAmount",recordInvoice.getTotalAmount()+"");
        result[2] = recordInvoice;

        // 扫描仪签收方式查询底账信息
        if (qsType.equals(QsfsEnum.SMYQS.getQsfsDm())) {
            if (rules != null && rules.size() > 0) {
                for (SignRulesEntity signRulesEntity : rules) {
                    if ("1008".contains(signRulesEntity.getRuleCode())) {
                        // 获取底账信息
                    } else if ("1009".contains(signRulesEntity.getRuleCode())) {
                        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
                        //TODO 可能有问题
                        //recordInvoice = this.baseMapper.selectOne(
                        //    new QueryWrapper<TDxRecordInvoice>().eq("invoice_no", pramsMap.get("invoiceNo")));
                        //2023年6月8日11:21:10 wangruwei 去掉上面几行代码，能走到这里说明抵账库已经有票了，没必要再去查
                    }
                }
            }
        }
        // 通行费没有校验码、明细的时候补明细
        List<TDxRecordInvoiceDetail> recordInvoiceDetail = new ArrayList<>();
        List<TDxRecordInvoiceStatistics> invoiceStatistics = new ArrayList<>();
        if (FplxEnum.TXF.getFplxDm().equals(invoiceType) && recordInvoice != null
            && StringUtils.isBlank(recordInvoice.getCheckCode())) {
            JSONObject queryInvoiceResult =
                invoiceQueryUtil.queryInvoice(pramsMap.get("invoiceCode"), pramsMap.get("invoiceNo"),
                    pramsMap.get("invoiceDate"), null, pramsMap.get("checkCode"), recordInvoice.getGfTaxNo(),invoiceType);
            if (!queryInvoiceResult.containsKey("returnCode")) {

                String resultCode = queryInvoiceResult.getString("resultCode");
                if ("0001".equals(resultCode)) {
                    updateRecordInvoice(queryInvoiceResult, recordInvoice);
                    recordInvoiceDetail = saveInvoiceInfoService.getRecordInvoiceDetail(queryInvoiceResult);
                    invoiceStatistics = getInvoiceStatistics(queryInvoiceResult);
                }
            }
            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        }

        //如果是代扣代缴，不走规则
        if(!"3".equals(pramsMap.get("xxly"))){
            // 4、签收规则校验
            String notes = signRulesUtils.checkRules(userInfo, qsType, pramsMap, recordInvoice, invoiceType, rules);
            if (StringUtils.isNotBlank(notes)) {
                // 校验失败存储失败扫描信息
                DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
                createFailScanInvoice(pramsMap, notes, scanInvoice, userInfo, invoiceType, qsType,recordInvoice);
                result[1] = notes;
                log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
                return result;
            }
        }

        // 5、签收通过保存数据信息
        if (scanInvoice == null) {
            scanInvoice = new TDxInvoice();
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice.setScanId(pramsMap.get("scanId"));
            }else{
                scanInvoice.setScanId(UUID.randomUUID().toString());
            }
            // if (QsfsEnum.PDFQS.getQsfsDm().equals(qsType) || QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
            // scanInvoice.setScanId(pramsMap.get("scanId"));
            // }
        }else{
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice.setScanId(pramsMap.get("scanId"));
            }else{
                scanInvoice.setScanId(UUID.randomUUID().toString());
            }
        }

        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        excuteManualWrite(userInfo, scanInvoice, recordInvoice, invoiceType, pramsMap.get("businessCode"),
            pramsMap.get("businessName"), qsType);
        if (recordInvoiceDetail != null && recordInvoiceDetail.size() > 0) {
            boolean deleteDetail = signInvoiceDetailService.deleteDetail(recordInvoice.getUuid(), userInfo.getDbName());
            if (deleteDetail) {
                signInvoiceDetailService.saveInvoiceDetail(recordInvoiceDetail, userInfo.getDbName());
            }
        }
        // 保存税率统计表
        if (invoiceStatistics.size() > 0) {
            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
            signInvoiceStatisticsService.remove(new UpdateWrapper<TDxRecordInvoiceStatistics>()
                .eq("invoice_code", pramsMap.get("invoiceCode")).eq("invoice_no", pramsMap.get("invoiceNo")));
            signInvoiceStatisticsService.saveBatch(invoiceStatistics);
        }

        result[0] = true;
        result[1] = "签收成功";

        log.info("发票号码：" + pramsMap.get("invoiceNo") + "签收成功");
        // 增加发票签收日志
        InvoiceLog log = new InvoiceLog();
        log.setInputName(userInfo.getUsername());
        log.setInputStatus("1");
        if(StringUtils.isNotBlank(pramsMap.get("invoiceCode"))){
            log.setInvoiceCode(pramsMap.get("invoiceCode"));
        }
        log.setInvoiceNo(pramsMap.get("invoiceNo"));
        log.setQsType(qsType);
        log.setType("3");
        log.setCreateDate(new Date());
        List<InvoiceLog> logs = new ArrayList<>();
        logs.add(log);
        invoiceLogService.toInvoiceLog(logs);
        return result;
    }

    public List<SignRulesEntity> getRules(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);

        return this.baseMapper.getRules(company);

    }

    /**
     * 查验签收
     *
     * @param pramsMap
     *            请求参数
     * @param userInfo
     *            用户信息
     * @param invoiceType
     *            返回结果
     * @return error 查验签收逻辑如下：1、基础信息校验 2、查看扫描表中是否存在此发票信息(是否重复签收) 3、扫描方式获取底账库信息/发票查验接口调用获取发票信息
     *         （查验接口返回结果为失败（接口不通or数据有问题），则将签收状态更新到扫描表中或者insert数据到扫描表，然后return） 4、查验成功，则开始校验权限，通过=true，不通过=false
     *         5、查询底账表是否有数据，如果有，则return如果没没有数据，则 保存查验信息到底账表
     */
    @Override
    public Object[] dzpSaveInvoice(Map<String, String> pramsMap, UserInfo userInfo, String qsType, String invoiceType) {
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);

        List<SignRulesEntity> rules = getRules(pramsMap.get("company"));

        Gson gson = new Gson();
        log.info("签收的发票信息为：{}----签收发票的方式为:{}", gson.toJson(pramsMap), qsType);

        // 返回参数
        Object[] result = new Object[3];
        List<SysEnterpriseConfigEntity> orgList = sysEnterpriseConfigSignDao.selectList(null);
        String gfsh = "";
        if(orgList.size()>0){
            gfsh = orgList.get(0).getNsrsbh();
        }

        // 1、基础信息校验
        String note = signRulesUtils.validateInvoiceInfo(pramsMap.get("invoiceCode"), pramsMap.get("invoiceNo"));

        // uuid = 发票代码+发票号码
        String uuid = (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode")) + pramsMap.get("invoiceNo");
        // 2、查询扫描表是否有数据，有（重复扫描）且签收结果为成功则return，下一个
        TDxInvoice scanInvoice = signInvoiceScanService.queryByUuid(uuid, userInfo.getDbName());

        if (scanInvoice == null) {
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice = signInvoiceScanService.queryByScanId(pramsMap.get("scanId"), userInfo.getDbName());
            }
        }
        if (StringUtils.isNotBlank(note)) {
            // 校验失败存储失败扫描信息
            result[0] = false;
            result[1] = note;
            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
            createFailScanInvoice(pramsMap, note, scanInvoice, userInfo, invoiceType, qsType,null);
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            return result;
        }

        if (scanInvoice != null && FpqsjgEnum.YQS.getQsjgDm().equals(scanInvoice.getQsStatus())) {
            result[0] = false;
            result[1] = "该发票已签收，请检查发票信息是否识别正确";
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            return result;
        }
        // 3、扫描方式获取底账库信息
        TDxRecordInvoice invoice = null;
        if (qsType.equals(QsfsEnum.SMYQS.getQsfsDm())) {
            if (rules != null && rules.size() > 0) {
                for (SignRulesEntity signRulesEntity : rules) {
                    if ("1008".contains(signRulesEntity.getRuleCode())) {

                        // 获取底账信息
                        invoice = getRecordInvoiceByUuid(uuid);
                    } else if ("1009".contains(signRulesEntity.getRuleCode())) {
                        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
                        invoice = this.baseMapper.selectOne(
                            new QueryWrapper<TDxRecordInvoice>().eq("invoice_no", pramsMap.get("invoiceNo")));
                    }
                }
            }
        }
        // 3、发票查验接口调用获取发票信息
        String invoiceAmount = null;

        if (FplxEnum.ESC.getFplxDm().equals(invoiceType)||FplxEnum.ZZDZ.getFplxDm().equals(invoiceType)) {
            if (StringUtils.isNotBlank(pramsMap.get("invoiceAmount"))) {
                invoiceAmount = pramsMap.get("invoiceAmount");
            } else {
                invoiceAmount = pramsMap.get("totalAmount");
            }
        }
        JSONObject queryInvoiceResult = invoiceQueryUtil.queryInvoice(pramsMap.get("invoiceCode"),

            pramsMap.get("invoiceNo"), pramsMap.get("invoiceDate"), invoiceAmount, pramsMap.get("checkCode"), gfsh,invoiceType);
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        String resultCode = queryInvoiceResult.getString("resultCode");

        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);

        // 调用查验接口失败，将签收状态更新到扫描表中或者insert数据到扫描表，然后return；
        if (queryInvoiceResult.containsKey("returnCode")) {
            // 接口不通
            result[0] = false;
            result[1] = queryInvoiceResult.getString("returnMessage");
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            // insertOrUpdate 扫描表
            createFailScanInvoice(pramsMap, result[1].toString(), scanInvoice, userInfo, invoiceType, qsType,null);
            return result;
        }
        if (!"0001".equals(resultCode)) {
            // 接口通过但，调用返回失败
            result[0] = false;
            result[1] = queryInvoiceResult.getString("resultTip");
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            // insertOrUpdate 扫描表
            createFailScanInvoice(pramsMap, result[1].toString(), scanInvoice, userInfo, invoiceType, qsType,null);
            return result;
        }
        // 根据查验结果整理底账表数据
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);

        if (invoice == null) {
            invoice = saveInvoiceInfoService.getRecordInvoice(queryInvoiceResult, userInfo.getUsername(), qsType);
        }
        //把金额，税额，价税合计放入pramsMap中
//        pramsMap.put("invoiceAmount", invoice.getInvoiceAmount()+"");
//        pramsMap.put("taxAmount",invoice.getTaxAmount()+"");
//        pramsMap.put("totalAmount",invoice.getTotalAmount()+"");

        log.info("以查验成功后的返回票种为准");
        invoiceType = queryInvoiceResult.getString("invoiceType");
        // 4、查验成功，则开始校验权限，通过=true，不通过=false
        String notes = signRulesUtils.checkRules(userInfo, qsType, pramsMap, invoice, invoiceType, rules);
        if (StringUtils.isNotBlank(notes)) {
            // 校验失败存储失败扫描信息
            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);

            createFailScanInvoice(pramsMap, notes, scanInvoice, userInfo, invoiceType, qsType,invoice);
            result[0] = false;
            result[1] = notes;
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            return result;
        }

        // 权限通过， insertOrUpdate 扫描表
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        if (scanInvoice == null) {
            scanInvoice = new TDxInvoice();
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice.setScanId(pramsMap.get("scanId"));
            }else{
                scanInvoice.setScanId(UUID.randomUUID().toString());
            }
        }else{
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice.setScanId(pramsMap.get("scanId"));
            }else{
                scanInvoice.setScanId(UUID.randomUUID().toString());
            }
        }
        // 根据底账信息，构建扫描表数据
        scanInvoice = createSuccessScanInvoice(invoice, scanInvoice, qsType, userInfo, invoiceType,
            pramsMap.get("businessCode"), pramsMap.get("businessName"));
//        if (QsfsEnum.PDFQS.getQsfsDm().equals(qsType) || QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
//            scanInvoice.setScanId(pramsMap.get("scanId"));
//        }
        signInvoiceScanService.insertOrUpdate(scanInvoice);

        // 5：查询底账表是否有数据，如果有，则下一个
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);
        TDxRecordInvoice recordInvoice = getRecordInvoiceByUuid(uuid);
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);

        if (recordInvoice == null) {
            // 底账表没有数据，则 保存查验信息到底账表，有数据则不再操作
            queryInvoiceResult.put("deptName", pramsMap.get("businessName"));
            queryInvoiceResult.put("deptId", pramsMap.get("businessCode"));
            queryInvoiceResult.put("sourceSystem", "1");
            queryInvoiceResult.put("company", userInfo.getCompany());
//            if (QsfsEnum.PDFQS.getQsfsDm().equals(qsType) || QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
//                queryInvoiceResult.put("scanId", pramsMap.get("scanId"));
//            }
            if(StringUtils.isNotBlank( pramsMap.get("scanId"))){
                queryInvoiceResult.put("scanId", pramsMap.get("scanId"));
            }else {
                queryInvoiceResult.put("scanId", UUID.randomUUID().toString());
            }
            saveInvoiceInfoService.saveQueryInvoiceResult(queryInvoiceResult, userInfo.getUsername(), qsType,
                userInfo.getDbName());
        } else {
            if (!"1".equals(recordInvoice.getQsStatus())) {
                if ("Y".equals(queryInvoiceResult.getString("isCancelled"))) {
                    recordInvoice.setInvoiceStatus(FpztEnum.ZF.getFpztDm(FpztEnum.ZF.getIndex()));
                } else if ("N".equals(queryInvoiceResult.getString("isCancelled"))) {
                    recordInvoice.setInvoiceStatus(FpztEnum.ZC.getFpztDm(FpztEnum.ZC.getIndex()));
                } else {
                    recordInvoice.setInvoiceStatus(queryInvoiceResult.getString("isCancelled"));
                }
                recordInvoice.setLastUpdateDate(new Date());
                recordInvoice.setQsDate(DateUtils.getSqlDateLong());
                recordInvoice.setQsStatus(FpqsjgEnum.YQS.getQsjgDm());
                recordInvoice.setQsType(qsType);
                recordInvoice.setValid("1");
                recordInvoice.setDeptName(pramsMap.get("businessName"));
                recordInvoice.setDeptId(pramsMap.get("businessCode"));
                recordInvoice.setQsName(userInfo.getUsername());
                if(StringUtils.isNotBlank( pramsMap.get("scanId"))){
                    queryInvoiceResult.put("scanId", pramsMap.get("scanId"));
                }else {
                    queryInvoiceResult.put("scanId", UUID.randomUUID().toString());
                }
                super.updateById(recordInvoice);
            }
        }
        log.info("发票号码：" + pramsMap.get("invoiceNo") + "签收成功");
        // 增加发票签收日志
        InvoiceLog log = new InvoiceLog();
        log.setInputName(userInfo.getUsername());
        log.setInputStatus("1");
        log.setInvoiceCode(pramsMap.get("invoiceCode"));
        log.setInvoiceNo(pramsMap.get("invoiceNo"));
        log.setQsType(qsType);
        log.setType("3");
        log.setCreateDate(new Date());
        List<InvoiceLog> logs = new ArrayList<>();
        logs.add(log);
        invoiceLogService.toInvoiceLog(logs);

        result[0] = true;
        result[1] = "签收成功";
        result[2] = invoice;
        return result;
    }



    private List<TDxRecordInvoiceStatistics> getInvoiceStatistics(JSONObject queryInvoiceResult) {
        List<TDxRecordInvoiceStatistics> invoiceStatisticsList = new ArrayList<>();
        String invoiceType = queryInvoiceResult.getString("invoiceType");
        if (FplxEnum.JDC.getFplxDm().equals(invoiceType)) {
            TDxRecordInvoiceStatistics invoiceStatistics = new TDxRecordInvoiceStatistics();
            invoiceStatistics.setCreateDate(DateUtils.getSqlDateLong());
            invoiceStatistics.setInvoiceCode(queryInvoiceResult.getString("invoiceCode"));
            invoiceStatistics.setInvoiceNo(queryInvoiceResult.getString("invoiceNo"));
            invoiceStatistics.setDetailAmount(queryInvoiceResult.getBigDecimal("invoiceAmount"));
            invoiceStatistics.setTaxRate(queryInvoiceResult.getString("taxRate"));
            invoiceStatistics.setTaxAmount(queryInvoiceResult.getBigDecimal("taxAmount"));
            invoiceStatistics.setTotalAmount(queryInvoiceResult.getBigDecimal("totalAmount"));
            invoiceStatisticsList.add(invoiceStatistics);
        } else {
            if (queryInvoiceResult.containsKey("detailList")) {
                invoiceStatisticsList = this.buildRecordInvoiceStatisticsList(queryInvoiceResult);
            }
        }

        return invoiceStatisticsList;
    }

    /**
     * 构建统计实体集
     *
     * @param queryInvoiceResult
     *            响应实体
     * @return 抵账统计实体
     */
    public List<TDxRecordInvoiceStatistics> buildRecordInvoiceStatisticsList(JSONObject queryInvoiceResult) {
        List<TDxRecordInvoiceDetail> recordInvoiceDetail =
            signSaveInvoiceInfoService.getRecordInvoiceDetail(queryInvoiceResult);
        // 定义返回值
        final List<TDxRecordInvoiceStatistics> recordInvoiceStatisticsList = new ArrayList<>();
        // 最终要的结果
        final Map<String, List<TDxRecordInvoiceDetail>> resultMap = new HashMap<>();
        // 按税率分组
        recordInvoiceDetail.forEach(dataItem -> {
            if (!"原价合计".equals(dataItem.getGoodsName().trim()) && !"折扣额合计".equals(dataItem.getGoodsName().trim())
                && !"(详见销货清单)".equals(dataItem.getGoodsName().trim())
                && !"（详见销货清单）".equals(dataItem.getGoodsName().trim())
                && StringUtils.isNotEmpty(dataItem.getTaxRate())) {
                if (resultMap.containsKey(dataItem.getTaxRate())) {
                    resultMap.get(dataItem.getTaxRate()).add(dataItem);
                } else {
                    final List<TDxRecordInvoiceDetail> list = new ArrayList<>();
                    list.add(dataItem);
                    resultMap.put(dataItem.getTaxRate(), list);
                }
            }
        });
        // 循环遍历map获取每组明细，并循环遍历每组里的明细组装抵账统计数据
        for (Map.Entry<String, List<TDxRecordInvoiceDetail>> entry : resultMap.entrySet()) {
            // 获取每组明细
            final List<TDxRecordInvoiceDetail> detailList = entry.getValue();
            // 定义抵账统计实体
            final TDxRecordInvoiceStatistics recordInvoiceStatistics = new TDxRecordInvoiceStatistics();
            // 税额
            BigDecimal taxAmount = new BigDecimal("0.0");
            // 金额
            BigDecimal detailAmount = new BigDecimal("0.0");
            // 循环赋值
            for (TDxRecordInvoiceDetail invoiceDetail : detailList) {
                BigDecimal bigDecimal;
                try {
                    bigDecimal = new BigDecimal(invoiceDetail.getTaxAmount());
                } catch (Exception e) {
                    bigDecimal = new BigDecimal("0");
                }
                taxAmount = taxAmount.add(bigDecimal);
                detailAmount = detailAmount.add(new BigDecimal(invoiceDetail.getDetailAmount()));
            }
            // 价税合计
            final BigDecimal totalAmount = taxAmount.add(detailAmount);
            // 税率
            recordInvoiceStatistics.setTaxRate(entry.getKey());
            // 发票号码
            recordInvoiceStatistics.setInvoiceNo(queryInvoiceResult.getString("invoiceNo"));
            // 发票代码
            recordInvoiceStatistics.setInvoiceCode(queryInvoiceResult.getString("invoiceCode"));
            // 税额
            recordInvoiceStatistics.setTaxAmount(taxAmount);
            // 金额
            recordInvoiceStatistics.setDetailAmount(detailAmount);
            // 价税合计
            recordInvoiceStatistics.setTotalAmount(totalAmount);
            // 放入集合
            recordInvoiceStatisticsList.add(recordInvoiceStatistics);
        }
        // 返回
        return recordInvoiceStatisticsList;
    }

    /**
     * @param userInfo
     *            用户信息
     * @param scanInvoice
     *            请求参数
     * @param recordInvoice
     *            请求参数
     * @param invoiceType
     *            请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void excuteManualWrite(UserInfo userInfo, TDxInvoice scanInvoice, TDxRecordInvoice recordInvoice,
        String invoiceType, String businessCode, String businessName, String qsType) {
        // 校验通过则更改签收信息
        recordInvoice.setQsStatus(FpqsjgEnum.YQS.getQsjgDm());
        recordInvoice.setQsDate(DateUtils.getSqlDateLong());
        recordInvoice.setDeptId(businessCode);
        recordInvoice.setDeptName(businessName);
        recordInvoice.setQsName(userInfo.getUsername());
        recordInvoice.setQsType(qsType);
        // if (QsfsEnum.PDFQS.getQsfsDm().equals(qsType) || QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
        // recordInvoice.setScanId(scanInvoice.getScanId());
        // }
        if (StringUtils.isNotBlank(scanInvoice.getScanId())) {
            recordInvoice.setScanId(scanInvoice.getScanId());
        }
        if(CommonUtil.isSdfp(invoiceType)){
            recordInvoice.setInvoiceSource("1");
        }else {
            recordInvoice.setInvoiceSource("0");
        }
        super.updateById(recordInvoice);

        // 保存成功信息到扫描表
        scanInvoice = createSuccessScanInvoice(recordInvoice, scanInvoice, qsType, userInfo, invoiceType, businessCode,
            businessName);
        signInvoiceScanService.insertOrUpdate(scanInvoice);
    }

    /**
     * 新建扫描表信息
     *
     * @param invoice
     *            抵账表信息
     * @param qsType
     *            签收类型
     * @param userInfo
     *            用户信息
     * @return 返回结果
     */
    private TDxInvoice createSuccessScanInvoice(TDxRecordInvoice invoice, TDxInvoice record, String qsType,
        UserInfo userInfo, String invoiceType, String businessCode, String businessName) {
        if (record == null) {
            record = new TDxInvoice();
        }
        // if (QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
        // record.setInvoiceSerialNo(Long.valueOf(scanIdUtils.createSerialNum()));
        // }
        record.setInvoiceSerialNo(Long.valueOf(scanIdUtils.createSerialNum()));
        // 发票类型
        record.setInvoiceType(invoiceType);
        // 发票代码
        if(StringUtils.isNotBlank(invoice.getInvoiceCode())){
            record.setInvoiceCode(invoice.getInvoiceCode());
        }
        // 发票号码
        record.setInvoiceNo(invoice.getInvoiceNo());
        //如果是20位
        if(FplxEnum.QDPP.getFplxDm().equals(invoice.getInvoiceType()) || FplxEnum.QDZZP.getFplxDm().equals(invoice.getInvoiceType())){
            if(invoice.getInvoiceNo().length()==20){
                String invoiceNo = invoice.getInvoiceNo();
                record.setInvoiceCode(invoiceNo.substring(0,12));
                record.setInvoiceNo(invoiceNo.substring(12,20));
            }
        }
        //数电号码
        if(StringUtils.isNotBlank(invoice.getEleInvoiceNo())){
            record.setEleInvoiceNo(invoice.getEleInvoiceNo());
        }
        // 购方税号
        record.setGfTaxNo(invoice.getGfTaxNo());
        // 购方名称
        record.setGfName(invoice.getGfName());
        // 销方税号
        record.setXfTaxNo(invoice.getXfTaxNo());
        // 销方名称
        record.setXfName(invoice.getXfName());
        // 金额
        record.setInvoiceAmount(invoice.getInvoiceAmount());
        // 税额
        record.setTaxAmount(invoice.getTaxAmount());
        // 价税合计
        record.setTotalAmount(invoice.getTotalAmount());
        // 开票时间
        record.setInvoiceDate(invoice.getInvoiceDate());
        // 签收人账号
        record.setUserAccount(userInfo.getId());
        // 签收人
        record.setUserName(userInfo.getUsername());
        // 签收方式
        record.setQsType(qsType);
        // 签收结果
        record.setQsStatus(FpqsjgEnum.YQS.getQsjgDm());
        record.setNotes("签收成功");
        // 是否有效
        record.setValid(ValidEnum.YX.getYxztDm());
        // uuid
        record.setUuid(invoice.getUuid());
        // 签收时间
        record.setQsDate(DateUtils.getSqlDateLong());

        // 校验码
        record.setCheckCode(invoice.getCheckCode());
        // 发票状态 为正常
        record.setInvoiceStatus(FpztEnum.ZC.getFpztDm());
        // 创建时间

        if (record.getCreateDate() == null) {
            record.setCreateDate(DateUtils.getSqlDateLong());
        }

        // 业务单元id
        record.setDeptId(businessCode);
        // 更新时间
        record.setUpdateDate(new Date());

        // 业务单元名称
        record.setDeptName(businessName);
        // if (QsfsEnum.PDFQS.getQsfsDm().equals(qsType) || QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
        // record.setScanId(record.getScanId());
        // }
        if (StringUtils.isNotBlank(record.getScanId())) {
            record.setScanId(record.getScanId());
        }else {
            record.setScanId(UUID.randomUUID().toString());
        }
        record.setCompany(userInfo.getCompany());

        if(CommonUtil.isSdfp(invoiceType)){
            record.setInvoiceSource("1");
        }else {
            record.setInvoiceSource("0");
        }
        //保存乐企特定要素类型代码  优化查询
        record.setLqTdyslxDm(record.getLqTdyslxDm());
        return record;
    }

    /**
     * 签收失败，insertOrUpdate扫描表
     *
     * @param pramsMap
     *            请求参数
     * @param note
     *            请求参数
     * @param scanInvoicce
     *            请求参数
     */
    private void createFailScanInvoice(Map<String, String> pramsMap, String note, TDxInvoice scanInvoicce,
        UserInfo userInfo, String invoiceType, String qsType,TDxRecordInvoice recordInvoice) {

        /**
        * 处理签收失败时候的逻辑，判断请求参数pramsMap里是否有 金额，税额，价税合计，有则用,没有则取recordInvoice,再没有则取查验
        * @Author wangruwei
        * @Date 2023/6/7 15:35
        **/
        if(StringUtils.isBlank(pramsMap.get("invoiceAmount"))){
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("invoiceAmount", recordInvoice.getInvoiceAmount()+"");
            }
        }
        if(StringUtils.isBlank(pramsMap.get("taxAmount"))){
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("taxAmount", recordInvoice.getTaxAmount()+"");
            }
        }
        if(StringUtils.isBlank(pramsMap.get("taxAmount"))){
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("taxAmount", recordInvoice.getTaxAmount()+"");
            }
        }

        if (StringUtils.isBlank(pramsMap.get("gfName"))) {
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("gfName", recordInvoice.getGfName());
            }
        }
        if (StringUtils.isBlank(pramsMap.get("gfsh"))) {
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("gfsh", recordInvoice.getGfTaxNo());
            }
        }
        if (StringUtils.isBlank(pramsMap.get("xfName"))) {
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("xfName", recordInvoice.getXfName());
            }
        }
        if (StringUtils.isBlank(pramsMap.get("xfsh"))) {
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("xfsh", recordInvoice.getXfTaxNo());
            }
        }
        if (StringUtils.isBlank(pramsMap.get("xfsh"))) {
            if(ObjectUtil.isNotEmpty(recordInvoice)){
                pramsMap.put("xfsh", recordInvoice.getXfTaxNo());
            }
        }


        Date now = DateUtils.getSqlDateLong();
        if (scanInvoicce == null) {
            // 调用失败则保存请求中的基本扫描信息
            scanInvoicce = new TDxInvoice();
            // 创建时间
            if (scanInvoicce.getCreateDate() == null) {
                scanInvoicce.setCreateDate(now);
            }
        }
        // 发票代码
        scanInvoicce.setInvoiceCode(pramsMap.get("invoiceCode"));
        // 发票号码
        scanInvoicce.setInvoiceNo(pramsMap.get("invoiceNo"));
        if(StringUtils.isNotBlank(pramsMap.get("invoiceNo"))&&pramsMap.get("invoiceNo").length()==20){
            scanInvoicce.setEleInvoiceNo(pramsMap.get("invoiceNo"));
            scanInvoicce.setInvoiceCode(pramsMap.get("invoiceNo").substring(0,12));
            scanInvoicce.setInvoiceNo(pramsMap.get("invoiceNo").substring(12,20));
        }
        if(StringUtils.isNotBlank(pramsMap.get("eleInvoiceNo"))){
            //数电号码
            scanInvoicce.setEleInvoiceNo(pramsMap.get("eleInvoiceNo"));
        }
        //uuid
        scanInvoicce.setUuid( (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode")) + pramsMap.get("invoiceNo"));
        // 开票日期
        if (pramsMap.get("invoiceDate").length() == 8) {
            scanInvoicce.setInvoiceDate(DateTimeHelper.parseDateTime(pramsMap.get("invoiceDate"), "yyyyMMdd"));
        } else {
            scanInvoicce.setInvoiceDate(DateTimeHelper.parseDateTime(pramsMap.get("invoiceDate"), "yyyy-MM-dd"));
        }
        // 校验码
        scanInvoicce.setCheckCode(pramsMap.get("checkCode"));
        // 发票类型
        scanInvoicce.setInvoiceType(invoiceType);
        // if (QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
        //
        // }
        scanInvoicce.setInvoiceSerialNo(Long.valueOf(scanIdUtils.createSerialNum()));
        // 签收结果 为签收失败
        scanInvoicce.setQsStatus(FpqsjgEnum.WQS.getQsjgDm());
        // 签收方式 为pdf
        scanInvoicce.setQsType(qsType);
        // 签收日期
        scanInvoicce.setQsDate(now);
        // 备注说明
        scanInvoicce.setNotes(note);
        // 更新时间
        scanInvoicce.setUpdateDate(now);

        // 签收账号
        scanInvoicce.setUserAccount(userInfo.getId());
        // 签收人
        scanInvoicce.setUserName(userInfo.getUsername());
        // 有效，可修改，否则无法查询
        scanInvoicce.setValid(ValidEnum.YX.getYxztDm());
        // 业务单元id
        scanInvoicce.setDeptId(pramsMap.get("businessCode"));
        // 业务单元名
        scanInvoicce.setDeptName(pramsMap.get("businessName"));
        // if (QsfsEnum.PDFQS.getQsfsDm().equals(qsType) || QsfsEnum.SMYQS.getQsfsDm().equals(qsType)) {
        //
        // }
        if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
            scanInvoicce.setScanId(pramsMap.get("scanId"));
        }else {
            scanInvoicce.setScanId(UUID.randomUUID().toString());
        }
        scanInvoicce.setCompany(pramsMap.get("company"));
        /*
        * @Description 不管什么票种，都应该入值钱
        * @Author wangruwei
        * @Date 2023/1/11 11:13
        *if(!(FplxEnum.QDZZP.getFplxDm().equals(invoiceType) || FplxEnum.QDPP.getFplxDm().equals(invoiceType))){
            if (StringUtils.isNotBlank(pramsMap.get("invoiceAmount"))) {
                try {
                    scanInvoicce.setInvoiceAmount(new BigDecimal(pramsMap.get("invoiceAmount")));
                } catch (Exception e) {
                }
            }
        }*/

        if (StringUtils.isNotBlank(pramsMap.get("taxAmount"))) {
            try {
                scanInvoicce.setTaxAmount(new BigDecimal(pramsMap.get("taxAmount")));
            } catch (Exception e) {
            }
        }
        if (StringUtils.isNotBlank(pramsMap.get("totalAmount"))) {
            try {
                scanInvoicce.setTotalAmount(new BigDecimal(pramsMap.get("totalAmount")));
            } catch (Exception e) {
            }
        }
        if (StringUtils.isNotBlank(pramsMap.get("invoiceAmount"))) {
            try {
                scanInvoicce.setInvoiceAmount(new BigDecimal(pramsMap.get("invoiceAmount")));
            } catch (Exception e) {
            }
        }
        if (StringUtils.isNotBlank(pramsMap.get("gfName"))) {
            scanInvoicce.setGfName(pramsMap.get("gfName"));
        }
        if (StringUtils.isNotBlank(pramsMap.get("gfsh"))) {
            scanInvoicce.setGfTaxNo(pramsMap.get("gfsh"));
        }
        if (StringUtils.isNotBlank(pramsMap.get("xfName"))) {
            scanInvoicce.setXfName(pramsMap.get("xfName"));
        }
        if (StringUtils.isNotBlank(pramsMap.get("xfsh"))) {
            scanInvoicce.setXfTaxNo(pramsMap.get("xfsh"));
        }
        if(CommonUtil.isSdfp(invoiceType)){
           scanInvoicce.setInvoiceSource("1");
        }else {
            scanInvoicce.setInvoiceSource("0");
        }
        signInvoiceScanService.insertOrUpdate(scanInvoicce);
    }

    public TDxRecordInvoice updateRecordInvoice(JSONObject queryInvoiceResult, TDxRecordInvoice invoice) {

        invoice.setInvoiceAmount(queryInvoiceResult.getBigDecimal("invoiceAmount"));
        invoice.setTaxAmount(queryInvoiceResult.getBigDecimal("taxAmount"));
        invoice.setTotalAmount(queryInvoiceResult.getBigDecimal("totalAmount"));
        invoice.setGfAddressAndPhone(queryInvoiceResult.getString("buyerAddressPhone"));
        invoice.setGfBankAndNo(queryInvoiceResult.getString("buyerAccount"));
        invoice.setGfName(queryInvoiceResult.getString("buyerName"));
        invoice.setGfTaxNo(queryInvoiceResult.getString("buyerTaxNo"));
        invoice.setXfAddressAndPhone(queryInvoiceResult.getString("salerAddressPhone"));
        invoice.setXfBankAndNo(queryInvoiceResult.getString("buyerAccount"));
        invoice.setXfName(queryInvoiceResult.getString("salerName"));
        invoice.setXfTaxNo(queryInvoiceResult.getString("salerTaxNo"));
        invoice.setMachinecode(queryInvoiceResult.getString("machineNo"));
        invoice.setRemark(queryInvoiceResult.getString("remark"));
        invoice.setCheckCode(queryInvoiceResult.getString("checkCode"));
        invoice.setTxfbz(queryInvoiceResult.getString("txfbz"));
        if (queryInvoiceResult.containsKey("detailList")) {
            JSONArray dataArray = queryInvoiceResult.getJSONArray("detailList");
            if (dataArray != null && dataArray.size() > 0) {
                invoice.setDetailYesorno("1");

            } else {
                invoice.setDetailYesorno("0");
            }
        } else {
            invoice.setDetailYesorno("0");
        }
        invoice.setLastUpdateDate(new Date());
        return invoice;
    }

    /**
     * 根据uuid获取底账表数据
     *
     * @param uuid
     *            uuid
     * @return 返回结果
     */
    private TDxRecordInvoice getRecordInvoiceByUuid(String uuid) {
        QueryWrapper<TDxRecordInvoice> invoiceWrapper = new QueryWrapper<>();
        invoiceWrapper.lambda().eq(TDxRecordInvoice::getUuid, uuid);
        return super.getOne(invoiceWrapper);
    }

    @Override
    public JSONObject checkInvoice(Map<String, String> pramsMap, UserInfo userInfo,String qsType, String invoiceType) {

        // uuid = 发票代码+发票号码
        String uuid = (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode")) + pramsMap.get("invoiceNo");

        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);

        TDxInvoice scanInvoice = signInvoiceScanService.queryByUuid(uuid, userInfo.getDbName());

        if (scanInvoice == null) {
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice = signInvoiceScanService.queryByScanId(pramsMap.get("scanId"), userInfo.getDbName());
            }
        }
        List<String> gfshAll = UserInfoUtil.getGfshAll(userInfo.getOrg());
        String gfsh = "";
        if (gfshAll.size() > 0) {
            gfsh = gfshAll.get(0);
        }
        //此查验方法只是验证全电票，传的invoiceType是31 代码传空，号码传 代码+号码
        String invoiceNo = (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode"))+pramsMap.get("invoiceNo");
        JSONObject queryInvoiceResult = invoiceQueryUtil.queryInvoice("",
                invoiceNo, pramsMap.get("invoiceDate"), pramsMap.get("invoiceAmount"), pramsMap.get("checkCode"),
                gfsh,"31");
        //todo 这块后续还是得用totalAmount
        pramsMap.put("totalAmount", pramsMap.get("invoiceAmount"));
        pramsMap.put("invoiceAmount", "");

        String resultCode = queryInvoiceResult.getString("resultCode");

        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        // 调用查验接口失败，将签收状态更新到扫描表中或者insert数据到扫描表，然后return；
        if (queryInvoiceResult.containsKey("returnCode")) {
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + queryInvoiceResult.getString("returnMessage"));
            createFailScanInvoice(pramsMap, queryInvoiceResult.getString("returnMessage"), scanInvoice, userInfo, invoiceType, qsType,null);
            return queryInvoiceResult;
        }
        if (!"0001".equals(resultCode)) {
            // 接口通过但，调用返回失败
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + queryInvoiceResult.getString("resultTip"));
            createFailScanInvoice(pramsMap, queryInvoiceResult.getString("resultTip"), scanInvoice, userInfo, invoiceType, qsType,null);
            return queryInvoiceResult;
        }
        return queryInvoiceResult;
    }

    /**
    * @Description 底账没有，查验成功，开始签收
    * @Author wangruwei
    * @Date 2023/4/19 19:39
    **/
    @Override
    public Object[]  qdSaveInvoice(Map<String, String> pramsMap, UserInfo userInfo, String qsType, String invoiceType,JSONObject queryInvoiceResult) {
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);

        List<SignRulesEntity> rules = getRules(pramsMap.get("company"));

        Gson gson = new Gson();
        log.info("签收的发票信息为：{}", gson.toJson(pramsMap), "----签收发票的方式为:{}", qsType);

        // 返回参数
        Object[] result = new Object[3];
        // uuid = 发票代码+发票号码
        String uuid = (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode")) + pramsMap.get("invoiceNo");
        // 查询扫描表是否有数据，有（重复扫描）且签收结果为成功则return，下一个
        TDxInvoice scanInvoice = signInvoiceScanService.queryByUuid(uuid, userInfo.getDbName());

        if (scanInvoice == null) {
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice = signInvoiceScanService.queryByScanId(pramsMap.get("scanId"), userInfo.getDbName());
            }
        }

        if (scanInvoice != null && FpqsjgEnum.YQS.getQsjgDm().equals(scanInvoice.getQsStatus())) {
            result[0] = false;
            result[1] = "该发票已签收，请检查发票信息是否识别正确";
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            return result;
        }
        // 扫描方式获取底账库信息
        TDxRecordInvoice invoice = null;
        if (qsType.equals(QsfsEnum.SMYQS.getQsfsDm())) {
            if (rules != null && rules.size() > 0) {
                for (SignRulesEntity signRulesEntity : rules) {
                    if ("1008".contains(signRulesEntity.getRuleCode())) {

                        // 获取底账信息
                        invoice = getRecordInvoiceByUuid(uuid);
                    } else if ("1009".contains(signRulesEntity.getRuleCode())) {
                        DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
                        invoice = this.baseMapper.selectOne(
                                new QueryWrapper<TDxRecordInvoice>().eq("invoice_no", pramsMap.get("invoiceNo")));
                    }
                }
            }
        }

        // 根据查验结果整理底账表数据
        if (invoice == null) {
            invoice = saveInvoiceInfoService.getRecordInvoice(queryInvoiceResult, userInfo.getUsername(), qsType);
        }
        //把金额，税额，价税合计放入pramsMap中
//        pramsMap.put("invoiceAmount", invoice.getInvoiceAmount()+"");
//        pramsMap.put("taxAmount",invoice.getTaxAmount()+"");
//        pramsMap.put("totalAmount",invoice.getTotalAmount()+"");

        //校验权限，通过=true，不通过=false
        String notes = signRulesUtils.checkRules(userInfo, qsType, pramsMap, invoice, invoiceType, rules);
        if (StringUtils.isNotBlank(notes)) {
            // 校验失败存储失败扫描信息
            DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
            createFailScanInvoice(pramsMap, notes, scanInvoice, userInfo, invoiceType, qsType,invoice);
            result[0] = false;
            result[1] = notes;
            log.error("发票号码：" + pramsMap.get("invoiceNo") + "签收失败，失败原因:" + result[1]);
            return result;
        }

        // 权限通过， insertOrUpdate 扫描表
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        if (scanInvoice == null) {
            scanInvoice = new TDxInvoice();
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice.setScanId(pramsMap.get("scanId"));
            }else{
                scanInvoice.setScanId(UUID.randomUUID().toString());
            }
        }else{
            if (StringUtils.isNotBlank(pramsMap.get("scanId"))) {
                scanInvoice.setScanId(pramsMap.get("scanId"));
            }else{
                scanInvoice.setScanId(UUID.randomUUID().toString());
            }
        }
        // 根据底账信息，构建扫描表数据
        scanInvoice = createSuccessScanInvoice(invoice, scanInvoice, qsType, userInfo, invoiceType,
                pramsMap.get("businessCode"), pramsMap.get("businessName"));

        signInvoiceScanService.insertOrUpdate(scanInvoice);

        // 查询底账表是否有数据，如果有，则下一个
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);
        TDxRecordInvoice recordInvoice = getRecordInvoiceByUuid(uuid);
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);

        if (recordInvoice == null) {
            // 底账表没有数据，则 保存查验信息到底账表，有数据则不再操作
            queryInvoiceResult.put("deptName", pramsMap.get("businessName"));
            queryInvoiceResult.put("deptId", pramsMap.get("businessCode"));
            queryInvoiceResult.put("sourceSystem", "1");
            queryInvoiceResult.put("company", userInfo.getCompany());
            if(StringUtils.isNotBlank( pramsMap.get("scanId"))){
                queryInvoiceResult.put("scanId", pramsMap.get("scanId"));
            }else {
                queryInvoiceResult.put("scanId", UUID.randomUUID().toString());
            }
            saveInvoiceInfoService.saveQueryInvoiceResult(queryInvoiceResult, userInfo.getUsername(), qsType,
                    userInfo.getDbName());
        } else {
            if (!"1".equals(recordInvoice.getQsStatus())) {
                if ("Y".equals(queryInvoiceResult.getString("isCancelled"))) {
                    recordInvoice.setInvoiceStatus(FpztEnum.ZF.getFpztDm(FpztEnum.ZF.getIndex()));
                } else if ("N".equals(queryInvoiceResult.getString("isCancelled"))) {
                    recordInvoice.setInvoiceStatus(FpztEnum.ZC.getFpztDm(FpztEnum.ZC.getIndex()));
                } else {
                    recordInvoice.setInvoiceStatus(queryInvoiceResult.getString("isCancelled"));
                }
                recordInvoice.setLastUpdateDate(new Date());
                recordInvoice.setQsDate(DateUtils.getSqlDateLong());
                recordInvoice.setQsStatus(FpqsjgEnum.YQS.getQsjgDm());
                recordInvoice.setQsType(qsType);
                recordInvoice.setValid("1");
                recordInvoice.setDeptName(pramsMap.get("businessName"));
                recordInvoice.setDeptId(pramsMap.get("businessCode"));
                recordInvoice.setQsName(userInfo.getUsername());
                if(StringUtils.isNotBlank( pramsMap.get("scanId"))){
                    recordInvoice.setScanId(pramsMap.get("scanId"));
                }else {
                    recordInvoice.setScanId(UUID.randomUUID().toString());
                }
                super.updateById(recordInvoice);
            }
        }
        log.info("发票号码：" + pramsMap.get("invoiceNo") + "签收成功");
        // 增加发票签收日志
        InvoiceLog log = new InvoiceLog();
        log.setInputName(userInfo.getUsername());
        log.setInputStatus("1");
        log.setInvoiceCode(pramsMap.get("invoiceCode"));
        log.setInvoiceNo(pramsMap.get("invoiceNo"));
        log.setQsType(qsType);
        log.setType("3");
        log.setCreateDate(new Date());
        List<InvoiceLog> logs = new ArrayList<>();
        logs.add(log);
        invoiceLogService.toInvoiceLog(logs);

        result[0] = true;
        result[1] = "签收成功";
        result[2] = invoice;
        return result;
    }
}
