package com.dxhy.base.service.receipt;

import cn.hutool.core.util.ObjectUtil;
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.base.dao.BaseReceiptOutDao;
import com.dxhy.base.dao.BaseTDxOutReasonDao;
import com.dxhy.base.dao.BaseTDxTaxCurrentDao;
import com.dxhy.base.entity.BaseTDxOutReason;
import com.dxhy.base.entity.BaseTDxRecordInvoice;
import com.dxhy.base.entity.BaseTDxRecordInvoiceOut;
import com.dxhy.base.entity.BaseTDxTaxCurrent;
import com.dxhy.base.model.*;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.constant.DictConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.FpztEnum;
import com.dxhy.common.enums.JxszcCancelEnum;
import com.dxhy.common.enums.JxszcZtEnum;
import com.dxhy.common.service.DictdetaServcice;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.util.StringHelper;
import com.dxhy.common.util.UserInfoUtil;
import com.dxhy.common.utils.DateUtils;
import com.dxhy.common.utils.RRException;
import com.github.pagehelper.PageInfo;
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.*;
import java.util.stream.Collectors;

/**
 * @author peipei.li
 * @date 2019-04-24 进项税转出相关操作
 */
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaCollectionInitShouldAssignCapacity",
    "AlibabaLowerCamelCaseVariableNaming"})
@Service("baseIReceiptOutService")
public class BaseReceiptOutServiceImpl extends MpBaseServiceImpl<BaseReceiptOutDao, BaseTDxRecordInvoiceOut>
    implements BaseIReceiptOutService {

    @Resource
    private BaseIInvoiceOutService baseIInvoiceOutService;

    @Resource
    private BaseIReceiptInvoiceService baseIReceiptInvoiceService;

    @Resource
    private BaseTDxOutReasonDao baseTDxOutReasonDao;

    @Resource
    private BaseTDxTaxCurrentDao baseTDxTaxCurrentDao;
    @Resource
    private TabulateRedisService tabulateRedisService;
    @Resource
    private DictdetaServcice dictdetaServcice;

    /**
     * 已转出进项税，列表页数据
     *
     * @param reqVO
     *            请求参数
     * @return 返回结果
     */
    @Override
    public String listOutReceipt(BaseReceiptOutReqVO reqVO) {
        DynamicContextHolder.push(reqVO.getUserInfo().getDbName() + DbConstant.BUSINESS_READ);

        String company = reqVO.getCompany();
        String menuId = reqVO.getMenuId();
        JSONObject json = tabulateRedisService.getTabulateMenu(company, menuId);

        List<String> statusList = new ArrayList<>();
        statusList.add(JxszcZtEnum.QBZC.getZcztDm());
        statusList.add(JxszcZtEnum.BFZC.getZcztDm());

        // map构建查询条件
        Map<String, Object> filter = new HashMap<>(16);
        filter.put("curr", reqVO.getCurr());
        filter.put("size", reqVO.getSize());
        // 转出状态为已转出的发票(全部转出and部分转出)
        filter.put("invoiceOutStatus", statusList);
        filter.put("orderByClause", "out_date desc,invoice_date desc");
        // 进项税转出流水=未取消
        filter.put("cancelStatus", JxszcCancelEnum.WQX.getQxztDm());

        // 购方税号
        List<String> allTaxNo = new ArrayList<>();
        if (StringHelper.isBlank(reqVO.getGfsh()) || "99".equals(reqVO.getGfsh())) {
            allTaxNo = UserInfoUtil.getGfshAll(reqVO.getUserInfo().getOrg());
        } else {
            allTaxNo.add(reqVO.getGfsh());
        }
        filter.put("gfshList", allTaxNo);

        // 销方名称
        filter.put("sellerName", StringHelper.isBlank(reqVO.getSellerName()) ? null : reqVO.getSellerName());

        //处理号码
        if(StringUtils.isNotBlank(reqVO.getInvoiceNo())){
            if(reqVO.getInvoiceNo().length()==8){
                filter.put("invoiceNo", reqVO.getInvoiceNo());
            }else {
                filter.put("eleInvoiceNo", reqVO.getInvoiceNo());
            }
        }

        // 转出原因
        filter.put("reasonId", (StringHelper.isBlank(reqVO.getReasonId()) || "99".equals(reqVO.getReasonId())) ? null
            : reqVO.getReasonId());
        // 发票状态
        filter.put("invoiceStatus",
            (StringHelper.isBlank(reqVO.getInvoiceStatus()) || "99".equals(reqVO.getInvoiceStatus())) ? null
                : reqVO.getInvoiceStatus());
        // 转出开始时间
        filter.put("outStartDate", reqVO.getOutStartDate());
        // 转出结束时间
        filter.put("outEndDate", reqVO.getOutEndDate());
        // 业务参数
        filter.put("businessCode",
            (StringHelper.isBlank(reqVO.getBusinessCode()) || "99".equals(reqVO.getBusinessCode())) ? null
                : reqVO.getBusinessCode());
        filter.put("company", reqVO.getCompany());
        // 执行查询并排序
        PageInfo<BaseReceiptInvoiceView> pageInfo = baseIInvoiceOutService.listPageByInvoice(filter);

        // 发票状态码map
        Map<String, String> invoiceStatusMap = FpztEnum.getEnumMap();

        // 查询结果封装为view
        List<BaseReceiptOutRespVO> respVos = new ArrayList<>();
        int index = 1;
        for (BaseReceiptInvoiceView view : pageInfo.getList()) {
            BaseReceiptOutRespVO vo = convertToInvoiceView(view, invoiceStatusMap);
            // 序号计算 = (当前页-1)*每页条数+1
            vo.setXh((long)((pageInfo.getPageNum() - 1) * pageInfo.getPageSize() + index));
            index++;
            respVos.add(vo);
        }

        // 设置记录总数
        json.put("total", pageInfo.getTotal());
        json.put("datalist", respVos);

        // 合计金额 and 合计税额
        BaseReceiptInvoiceView view = baseIInvoiceOutService.querySumForInvoice(filter);
        BigDecimal totalAmount =
            (view == null || view.getInvoiceAmount() == null) ? new BigDecimal(0) : view.getInvoiceAmount();
        BigDecimal taxAmount = (view == null || view.getTaxAmount() == null) ? new BigDecimal(0) : view.getTaxAmount();
        json.put("sumInvoiceAmount", AmountFormatUtil.fmtMicrometer(MathUtil.round(totalAmount.toPlainString())));
        json.put("sumTaxAmount", AmountFormatUtil.fmtMicrometer(MathUtil.round(taxAmount.toPlainString())));

        return super.responseResult(json);
    }

    /**
     * pojo转为view
     *
     * @param record
     *            请求参数
     * @param invoiceStatusMap
     *            请求参数
     * @return 返回结果
     */
    private BaseReceiptOutRespVO convertToInvoiceView(BaseReceiptInvoiceView record,
        Map<String, String> invoiceStatusMap) {
        BaseReceiptOutRespVO vo = new BaseReceiptOutRespVO();
        // uuid作为主键
        vo.setId(record.getUuid());
        // 转出日期
        vo.setOutDate(DateUtils.dateToStr(record.getOutDate()));
        // 发票号码
        vo.setInvoiceNo(record.getInvoiceNo());
        // 发票代码
        vo.setInvoiceCode(record.getInvoiceCode());
        // 数电号码
        vo.setEleInvoiceNo(record.getEleInvoiceNo());
        // 发票类型
        vo.setInvoiceType(record.getInvoiceType());
        // 开票日期
        vo.setInvoiceDate(DateUtils.dateToStr(record.getInvoiceDate()));
        // 发票状态
        vo.setInvoiceStatusName(dictdetaServcice.queryDictName(DictConstant.INVOICE_STATUS,record.getInvoiceStatus()));
        // 购方税号
        vo.setGfsh(record.getGfTaxNo());
        // 购方名称
        vo.setBuyerName(record.getGfName());
        // 销方名称
        vo.setSellerName(record.getXfName());
        // 金额
        if(ObjectUtil.isNotEmpty(record.getInvoiceAmount())){
            vo.setAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getInvoiceAmount().toPlainString())));
        }

        // 税额
        if(ObjectUtil.isNotEmpty(record.getTaxAmount())){
            vo.setTaxAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getTaxAmount().toPlainString())));
        }
        // 转出金额
        if(ObjectUtil.isNotEmpty(record.getOutInvoiceAmout())){
            vo.setOutAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getOutInvoiceAmout().toPlainString())));
        }

        // 转出税额
        if(ObjectUtil.isNotEmpty(record.getOutTaxAmount())){
            vo.setOutTax(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getOutTaxAmount().toPlainString())));
        }


        vo.setRemark(record.getOutRemark());
        vo.setOutBelongDate(record.getOutBelongDate());

        // 转出原因
        QueryWrapper<BaseTDxOutReason> query = new QueryWrapper<>();
        query.eq("reason_code", record.getOutReason());
        BaseTDxOutReason reason = baseTDxOutReasonDao.selectOne(query);
        vo.setReason(reason.getOutReason());
        return vo;
    }

    /**
     * 根据转出类型 set 抵账表中进项税转出相关字段 (部分转出 or 全部转出)
     *
     * @param invoices
     *            请求参数
     * @param condVO
     *            请求参数
     * @param userInfo
     *            请求参数
     * @return 返回结果
     */
    private List<BaseTDxRecordInvoice> setPartInvoiceByType(List<BaseTDxRecordInvoice> invoices,
        BaseInvoiceEditCondVO condVO, UserInfo userInfo) {
        List<BaseTDxRecordInvoice> condList = new ArrayList<>();
        for (BaseTDxRecordInvoice record : invoices) {
            QueryWrapper<BaseTDxTaxCurrent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("taxno", record.getGfTaxNo());
            BaseTDxTaxCurrent taxCurrent = baseTDxTaxCurrentDao.selectOne(queryWrapper);
            record.setOutBelongDate(taxCurrent.getCurrentTaxPeriod());
            BaseTDxRecordInvoice condRecord = new BaseTDxRecordInvoice();
            condRecord.setId(record.getId());
            // 转出状态
            condRecord.setOutStatus(condVO.getOutStatus());
            // 转出原因
            condRecord.setOutReason(condVO.getOutReason());
            // 备注
            condRecord.setOutRemark(condVO.getOutRemark());
            // 转出日期
            condRecord.setOutDate(DateUtils.getNow());
            // 转出人
            condRecord.setOutBy(userInfo.getUsername());
            // 税款所属期
            condRecord.setOutBelongDate(taxCurrent.getCurrentTaxPeriod());

            /*全部转出 */
            if (JxszcZtEnum.QBZC.getZcztDm().equals(condVO.getOutStatus())) {
                // 转出金额
                condRecord.setOutInvoiceAmout(record.getInvoiceAmount());
                // 转出税额
                condRecord.setOutTaxAmount(record.getDkTaxAmount());
            }
            /*部分转出 */
            if (JxszcZtEnum.BFZC.getZcztDm().equals(condVO.getOutStatus())) {
                // 转出金额累加
                BigDecimal oldOutAmount =
                    record.getOutInvoiceAmout() == null ? new BigDecimal(0) : record.getOutInvoiceAmout();
                BigDecimal newOutAmount = oldOutAmount.add(new BigDecimal(condVO.getOutAmount()));
                // -1=小于； 0=等于； 1=大于；
                int compareOut = newOutAmount.compareTo(record.getInvoiceAmount());
                if (compareOut > 0) {
                    throw new RRException("累计转出金额不能大于发票金额");
                }
                // 转出金额
                condRecord.setOutInvoiceAmout(newOutAmount);

                // 转出税额累加
                BigDecimal oldOutTax = record.getOutTaxAmount() == null ? new BigDecimal(0) : record.getOutTaxAmount();
                BigDecimal newOutTax = oldOutTax.add(new BigDecimal(condVO.getOutTax()));
                int compareTax = newOutTax.compareTo(record.getDkTaxAmount());
                if (compareTax > 0) {
                    throw new RRException("累计转出税额不能大于发票税额");
                }
                // 转出税额
                condRecord.setOutTaxAmount(newOutTax);

                if (compareOut == 0 && compareTax == 0) {
                    // 金额税额已经全部转完，设为 全部转出
                    condRecord.setOutStatus(JxszcZtEnum.QBZC.getZcztDm());
                }
            }
            condList.add(condRecord);

        }
        return condList;
    }

    /**
     * 构建进项税转出明细
     *
     * @param condVO
     *            请求参数
     * @param userInfo
     *            请求参数
     * @param invoice
     *            请求参数
     * @param record
     *            请求参数
     */
    private void createInvoiceOut(BaseInvoiceEditCondVO condVO, UserInfo userInfo, BaseTDxRecordInvoice invoice,
        BaseTDxRecordInvoiceOut record) {
        // uuid
        record.setUuid(invoice.getUuid());
        // 发票号码
        record.setInvoiceNo(invoice.getInvoiceNo());
        // 发票代码
        record.setInvoiceCode(invoice.getInvoiceCode());
        // 数电号码
        record.setEleInvoiceNo(invoice.getEleInvoiceNo());
        record.setOutBelongDate(invoice.getOutBelongDate());
        // 转出状态
        record.setOutStatus(condVO.getOutStatus());

        /* 全部转出 */
        if (JxszcZtEnum.QBZC.getZcztDm().equals(condVO.getOutStatus())) {
            // 转出金额
            record.setOutInvoiceAmout(invoice.getInvoiceAmount());
            // 转出税额
            record.setOutTaxAmount(invoice.getDkTaxAmount());
        }
        /* 部分转出 */
        if (JxszcZtEnum.BFZC.getZcztDm().equals(condVO.getOutStatus())) {
            // 转出金额累加
            BigDecimal oldOutAmount =
                record.getOutInvoiceAmout() == null ? new BigDecimal(0) : record.getOutInvoiceAmout();
            BigDecimal newOutAmount = oldOutAmount.add(new BigDecimal(condVO.getOutAmount()));
            // -1=小于； 0=等于； 1=大于；
            int compareOut = newOutAmount.compareTo(invoice.getInvoiceAmount());
            if (compareOut > 0) {
                throw new RRException("累计转出金额不能大于发票金额");
            }
            // 转出金额
            record.setOutInvoiceAmout(newOutAmount);

            // 转出税额累加
            BigDecimal oldOutTax = record.getOutTaxAmount() == null ? new BigDecimal(0) : record.getOutTaxAmount();
            BigDecimal newOutTax = oldOutTax.add(new BigDecimal(condVO.getOutTax()));
            int compareTax = newOutTax.compareTo(invoice.getDkTaxAmount());
            if (compareTax > 0) {
                throw new RRException("累计转出税额不能大于发票税额");
            }
            // 转出税额
            record.setOutTaxAmount(newOutTax);

            // 金额税额全部转完，设置状态为 全部转出
            if (compareOut == 0 && compareTax == 0) {
                record.setOutStatus(JxszcZtEnum.QBZC.getZcztDm());
            }
        }

        // 转出日期
        record.setOutDate(DateUtils.getNow());
        // 转出原因
        record.setOutReason(condVO.getOutReason());
        // 备注
        record.setOutRemark(condVO.getOutRemark());
        // 转出人
        record.setOutBy(userInfo.getUsername());
        // 是否取消，默认未取消
        record.setIsCancel(JxszcCancelEnum.WQX.getQxztDm());
    }

    /**
     * 进项税转出保存
     * <p>
     * <p>
     * 查询底账表数据，查询转出流水 如果已经有转出流水，则update 如果没有转出流水，则insert 更正底账表转出相关字段
     *
     * @param condVO
     *            请求参数
     * @param userInfo
     *            请求参数
     * @return 返回结果
     */
    @Override
    public String transferTax(BaseInvoiceEditCondVO condVO, UserInfo userInfo) {
        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);

        String idStr = condVO.getPrimaryKey();
        String[] ids = idStr.split(",");

        // first：查询出底账表相关数据
        List<BaseTDxRecordInvoice> invoices = baseIReceiptInvoiceService.selectByUuids(ids);
        // second：根据uuids查询出转出明细并转为map，key=uuid ，value=转出明细
        List<BaseTDxRecordInvoiceOut> outs = listByUuids(ids);
        Map<String, BaseTDxRecordInvoiceOut> outMap =
            outs.stream().collect(Collectors.toMap(BaseTDxRecordInvoiceOut::getUuid, tri -> tri));

        // third：设置底账表中的 进项税转出 部分相关字段
        List<BaseTDxRecordInvoice> condList = setPartInvoiceByType(invoices, condVO, userInfo);

        List<BaseTDxRecordInvoiceOut> outList = new ArrayList<>();
        // fourth：对比流水明细，区分底账表list中需要update或者insert的数据
        invoices.forEach(invoice -> {
            BaseTDxRecordInvoiceOut e = new BaseTDxRecordInvoiceOut();
            if (outMap.containsKey(invoice.getUuid())) {
                e = outMap.get(invoice.getUuid());
            }
            // 从构建的底账数据中（进项税转出相关字段），更新需要变更的流水字段
            e.setCompany(userInfo.getCompany());
            createInvoiceOut(condVO, userInfo, invoice, e);
            outList.add(e);
        });

        DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
        excuteTransferWrite(condList, outList);

        return "success";
    }

    /**
     * 数据源设置end，事物处理
     *
     * @param condList
     *            请求参数
     * @param outList
     *            请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void excuteTransferWrite(List<BaseTDxRecordInvoice> condList, List<BaseTDxRecordInvoiceOut> outList) {
        // 流水表批量insert or update
        saveOrUpdateBatch(outList);
        // 抵账表批量update
        baseIReceiptInvoiceService.updateBatch(condList);
    }

    /**
     * 批量update 转出流水
     *
     * @param list
     *            请求参数
     */
    private void saveOrUpdateBatch(List<BaseTDxRecordInvoiceOut> list) {
        if (list != null && list.size() > 0) {
            super.saveOrUpdateBatch(list);
        }
    }

    /**
     * 根据uuids查询进项税转出明细
     *
     * @param uuids
     *            请求参数
     * @return 返回结果
     */
    private List<BaseTDxRecordInvoiceOut> listByUuids(String[] uuids) {
        QueryWrapper<BaseTDxRecordInvoiceOut> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(BaseTDxRecordInvoiceOut::getUuid, uuids);
        return super.list(queryWrapper);
    }

    /**
     * 取消已转出进项税 请求确认
     *
     * @param reqVO
     *            请求参数
     * @return 返回结果
     */
    @Override
    public String cancelOut(BaseReceiptOutCancelEditReqVO reqVO) {
        DynamicContextHolder.push(reqVO.getUserInfo().getDbName() + DbConstant.BUSINESS_WRITE);

        String[] uuids = reqVO.getPrimaryKey().split(",");
        excuteCancelWrite(uuids);

        return "取消转出成功";
    }

    /**
     * 数据库操作
     *
     * @param uuids
     *            请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void excuteCancelWrite(String[] uuids) {
        // 批量将状态设置为 已取消
        updateBatchByUuid(uuids);
        // 批量revert抵账表 转出时候更新的数据
        updatePartInvoiceForCancel(uuids);
    }

    /**
     * 取消进项税转出，批量revert抵账表已经更新的字段
     *
     * @param ids
     *            请求参数
     */
    private void updatePartInvoiceForCancel(String[] ids) {
        List<BaseTDxRecordInvoice> list = baseIReceiptInvoiceService.selectByUuids(ids);
        for (BaseTDxRecordInvoice condRecord : list) {
            // 转出状态 revert为未转出
            condRecord.setOutStatus(JxszcZtEnum.WZC.getZcztDm());
            // 转出原因
            condRecord.setOutReason(null);
            // 备注
            condRecord.setOutRemark(null);
            // 转出日期
            condRecord.setOutDate(null);
            // 转出人
            condRecord.setOutBy(null);
            // 转出金额
            condRecord.setOutInvoiceAmout(null);
            // 转出税额
            condRecord.setOutTaxAmount(null);

        }
        // 更新抵账表
        baseIReceiptInvoiceService.updateBatch(list);
    }

    /**
     * 进项税弹框显示 ，下拉框内容
     *
     * @param map
     *            请求参数
     * @return 返回结果
     */
    @Override
    public String listCond(Map<String, String> map) {
        Map<String, String> statusMap = new HashMap<>(16);
        statusMap.put(JxszcZtEnum.QBZC.getZcztDm(), JxszcZtEnum.QBZC.getZcztMc(JxszcZtEnum.QBZC.getIndex()));
        statusMap.put(JxszcZtEnum.BFZC.getZcztDm(), JxszcZtEnum.BFZC.getZcztMc(JxszcZtEnum.BFZC.getIndex()));

        DynamicContextHolder.push(map.get("dbName") + DbConstant.BUSINESS_READ);
        QueryWrapper<BaseTDxOutReason> query = new QueryWrapper<>();
        List<String> cmpy = new ArrayList<>();
        cmpy.add("DX");
        cmpy.add(map.get("company"));
        query.in("company", cmpy);
        query.orderByAsc("id");
        List<BaseTDxOutReason> list = baseTDxOutReasonDao.selectList(query);
        Map<String, String> reasonMap = new HashMap<>();
        if (list != null && list.size() > 0) {
            for (BaseTDxOutReason reason : list) {
                reasonMap.put(reason.getReasonCode(), reason.getOutReason());
            }
        }

        JSONObject json = new JSONObject();

        json.put("statusMap", statusMap);
        json.put("reasonMap", reasonMap);

        return super.responseResult(json);

    }

    /**
     * 取消已转出进项税列表
     *
     * @param reqVO
     *            请求参数
     * @return 返回结果
     */
    @Override
    public String listCancelReceipt(BaseReceiptOutReqVO reqVO) {
        DynamicContextHolder.push(reqVO.getUserInfo().getDbName() + DbConstant.BUSINESS_READ);

        String company = reqVO.getCompany();
        String menuId = reqVO.getMenuId();
        JSONObject json = tabulateRedisService.getTabulateMenu(company, menuId);

        List<String> statusList = new ArrayList<>();
        statusList.add(JxszcZtEnum.QBZC.getZcztDm());
        statusList.add(JxszcZtEnum.BFZC.getZcztDm());

        // map构建查询条件
        Map<String, Object> filter = new HashMap<>(16);
        filter.put("curr", reqVO.getCurr());
        filter.put("size", reqVO.getSize());
        // 进项税明细中取消状态为 已取消
        filter.put("cancelStatus", JxszcCancelEnum.WQX.getQxztDm());
        // 转出状态为已转出的发票(全部转出and部分转出)
        filter.put("invoiceOutStatus", statusList);
        filter.put("orderByClause", "out_date desc,invoice_date desc");

        // 购方税号
        List<String> allTaxNo = new ArrayList<>();
        if (StringHelper.isBlank(reqVO.getGfsh()) || "99".equals(reqVO.getGfsh())) {
            allTaxNo = UserInfoUtil.getGfshAll(reqVO.getUserInfo().getOrg());
        } else {
            allTaxNo.add(reqVO.getGfsh());
        }
        filter.put("gfshList", allTaxNo);

        // 销方名称
        filter.put("sellerName", StringHelper.isBlank(reqVO.getSellerName()) ? null : reqVO.getSellerName());

        //处理号码
        if(StringUtils.isNotBlank(reqVO.getInvoiceNo())){
            if(reqVO.getInvoiceNo().length()==8){
                filter.put("invoiceNo", reqVO.getInvoiceNo());
            }else {
                filter.put("eleInvoiceNo", reqVO.getInvoiceNo());
            }
        }

        // 转出原因
        filter.put("reasonId", (StringHelper.isBlank(reqVO.getReasonId()) || "99".equals(reqVO.getReasonId())) ? null
            : reqVO.getReasonId());
        // 发票状态
        filter.put("invoiceStatus",
            (StringHelper.isBlank(reqVO.getInvoiceStatus()) || "99".equals(reqVO.getInvoiceStatus())) ? null
                : reqVO.getInvoiceStatus());
        // 转出开始时间
        filter.put("outStartDate", reqVO.getOutStartDate());
        // 转出结束时间
        filter.put("outEndDate", reqVO.getOutEndDate());
        // 业务参数
        filter.put("businessCode",
            (StringHelper.isBlank(reqVO.getBusinessCode()) || "99".equals(reqVO.getBusinessCode())) ? null
                : reqVO.getBusinessCode());
        filter.put("company", reqVO.getCompany());
        // 执行查询并排序
        PageInfo<BaseReceiptInvoiceView> pageInfo = baseIInvoiceOutService.listPageByInvoice(filter);

        // 查询结果封装为view
        List<BaseReceiptOutCancelRespVO> respVos = new ArrayList<>();
        int index = 1;
        Map<String, String> invoiceStatusMap = FpztEnum.getEnumMap();
        for (BaseReceiptInvoiceView view : pageInfo.getList()) {
            BaseReceiptOutCancelRespVO vo = convertToInvoiceCancelView(view, invoiceStatusMap);
            // 序号计算 = (当前页-1)*每页条数+1
            vo.setXh((long)((pageInfo.getPageNum() - 1) * pageInfo.getPageSize() + index));
            index++;
            respVos.add(vo);
        }

        // 设置记录总数
        json.put("total", pageInfo.getTotal());
        json.put("datalist", respVos);

        // 合计金额 and 合计税额
        BaseReceiptInvoiceView view = baseIInvoiceOutService.querySumForInvoice(filter);
        BigDecimal totalAmount =
            (view == null || view.getInvoiceAmount() == null) ? new BigDecimal(0) : view.getInvoiceAmount();
        BigDecimal taxAmount = (view == null || view.getTaxAmount() == null) ? new BigDecimal(0) : view.getTaxAmount();
        json.put("sumInvoiceAmount", AmountFormatUtil.fmtMicrometer(MathUtil.round(totalAmount.toPlainString())));
        json.put("sumTaxAmount", AmountFormatUtil.fmtMicrometer(MathUtil.round(taxAmount.toPlainString())));

        return super.responseResult(json);
    }

    /**
     * 取消已转出进项税 pojo转vo
     *
     * @param record
     *            请求参数
     * @param invoiceStatusMap
     *            请求参数
     * @return 返回结果
     */
    private BaseReceiptOutCancelRespVO convertToInvoiceCancelView(BaseReceiptInvoiceView record,
        Map<String, String> invoiceStatusMap) {
        BaseReceiptOutCancelRespVO vo = new BaseReceiptOutCancelRespVO();
        // uuid作为主键
        vo.setId(record.getUuid());
        // 发票号码
        vo.setInvoiceNo(record.getInvoiceNo());
        // 发票代码
        vo.setInvoiceCode(record.getInvoiceCode());
        // 数电号码
        vo.setEleInvoiceNo(record.getEleInvoiceNo());
        // 发票类型
        vo.setInvoiceType(record.getInvoiceType());
        // 开票日期
        vo.setInvoiceDate(DateUtils.dateToStr(record.getInvoiceDate()));
        // 发票状态
        vo.setInvoiceStatusName(dictdetaServcice.queryDictName(DictConstant.INVOICE_STATUS,record.getInvoiceStatus()));
        // 购方税号
        vo.setGfsh(record.getGfTaxNo());
        // 购方名称
        vo.setBuyerName(record.getGfName());
        // 销方名称
        vo.setSellerName(record.getXfName());
        // 金额
        if(ObjectUtil.isNotEmpty(record.getInvoiceAmount())){
            vo.setAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getInvoiceAmount().toPlainString())));
        }

        // 税额
        if(ObjectUtil.isNotEmpty(record.getTaxAmount())){
            vo.setTaxAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getTaxAmount().toPlainString())));
        }

        // 转出金额
        if(ObjectUtil.isNotEmpty(record.getOutInvoiceAmout())){
            vo.setOutAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getOutInvoiceAmout().toPlainString())));
        }

        // 转出税额
        if(ObjectUtil.isNotEmpty(record.getOutTaxAmount())){
            vo.setOutTax(AmountFormatUtil.fmtMicrometer(MathUtil.round(record.getOutTaxAmount().toPlainString())));
        }

        vo.setRemark(record.getOutRemark());
        vo.setOutDate(DateUtils.dateToStr(record.getOutDate()));
        vo.setOutBelongDate(record.getOutBelongDate());
        // 转出原因
        QueryWrapper<BaseTDxOutReason> query = new QueryWrapper<>();
        query.eq("reason_code", record.getOutReason());
        BaseTDxOutReason reason = baseTDxOutReasonDao.selectOne(query);
        vo.setReason(reason.getOutReason());
        // 认证日期 string类型的长日期转为string类型的短日期
        String certDate = record.getCertDate();
        Date date = DateUtils.strToDate(certDate);
        vo.setCertDate(DateUtils.dateToStr(date));
        return vo;
    }

    /**
     * 批量将 进项税 明细转为已取消
     *
     * @param uuids
     *            请求参数
     */
    private void updateBatchByUuid(String[] uuids) {
        BaseTDxRecordInvoiceOut entity = new BaseTDxRecordInvoiceOut();
        // 已取消
        entity.setIsCancel(JxszcCancelEnum.YQX.getQxztDm());

        UpdateWrapper<BaseTDxRecordInvoiceOut> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().in(BaseTDxRecordInvoiceOut::getUuid, uuids);
        super.remove(updateWrapper);
    }

}
