package com.artfess.cqlt.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.artfess.base.enums.SubjectSpeciesEnum;
import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.CommonUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.cqlt.dao.QfFinanceSasacCompanyMDao;
import com.artfess.cqlt.manager.QfFinanceBsDManager;
import com.artfess.cqlt.manager.QfFinanceCfDManager;
import com.artfess.cqlt.manager.QfFinancePlDManager;
import com.artfess.cqlt.manager.QfFinanceReportingSummaryDManager;
import com.artfess.cqlt.manager.QfFinanceSasacCompanyDManager;
import com.artfess.cqlt.manager.QfFinanceSasacCompanyMManager;
import com.artfess.cqlt.manager.QfHrPersonDManager;
import com.artfess.cqlt.manager.QfReportRangeManager;
import com.artfess.cqlt.manager.QfReportSubjectManager;
import com.artfess.cqlt.model.QfEnterpriseInfo;
import com.artfess.cqlt.model.QfFinanceSasacCompanyD;
import com.artfess.cqlt.model.QfFinanceSasacCompanyM;
import com.artfess.cqlt.model.QfSubjectInfo;
import com.artfess.cqlt.vo.ReportDataVo;
import com.artfess.i18n.util.I18nUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * 财务--国资委子企业季度填报主表 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2023-03-02
 */
@Slf4j
@Service
public class QfFinanceSasacCompanyMManagerImpl extends BaseManagerImpl<QfFinanceSasacCompanyMDao, QfFinanceSasacCompanyM> implements QfFinanceSasacCompanyMManager {

    @Autowired
    private QfReportSubjectManager reportSubjectManager;

    @Autowired
    private QfReportRangeManager reportRangeManager;

    @Autowired
    private QfFinanceSasacCompanyDManager financeSasacCompanyDManager;

    @Autowired
    private QfFinanceBsDManager financeBsDManager;

    @Autowired
    private QfFinancePlDManager financePlDManager;

    @Autowired
    private QfHrPersonDManager personDManager;

    @Autowired
    private QfFinanceCfDManager financeCfDManager;

    @Autowired
    private QfFinanceReportingSummaryDManager reportingSummaryDManager;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean conversion(String mainId) throws ExecutionException, InterruptedException {
        if (StringUtils.isEmpty(mainId)) {
            return false;
        }
        QfFinanceSasacCompanyM mainInfo = baseMapper.selectById(mainId);
        if (null == mainInfo) {
            return false;
        }
        Assert.isTrue(!"1".equals(mainInfo.getStatus()),  I18nUtil.getMessage("data_operate", LocaleContextHolder.getLocale()));
        String reportId = mainInfo.getReportId();

        List<QfEnterpriseInfo> rangeList = reportRangeManager.getQfEnterpriseInfo(reportId);
        //获取报表关联国内科目信息
        List<QfSubjectInfo> subjectInfoList = reportSubjectManager.getSubjectInfo(reportId);
        if (CollectionUtils.isEmpty(subjectInfoList)) {
            return false;
        }

        QueryWrapper<QfFinanceSasacCompanyD> companyDQueryWrapper = new QueryWrapper<>();
        companyDQueryWrapper.eq("main_id_", mainId);
        financeSasacCompanyDManager.remove(companyDQueryWrapper);
        //根据分类获取不同报表类型的科目编码
        Map<String, List<String>> typeSubjectMap = this.getTypeSubjectMap(subjectInfoList);
        //根据不同报表类型去相应的填报数据详情表获取数据
        List<ReportDataVo> allData = this.getAllData(mainInfo, typeSubjectMap);
        //获取境外企业
        Map<String, QfEnterpriseInfo> enterpriseInfoMap = rangeList.stream().collect(Collectors.toMap(item -> item.getCode(), item -> item));
        List<QfFinanceSasacCompanyD> detailList = Lists.newArrayList();
        subjectInfoList.forEach(subjectInfo -> {
            processDetail(subjectInfo, detailList, allData, mainInfo, enterpriseInfoMap);
        });

        if (CollectionUtils.isEmpty(detailList)) {
            return false;
        }
        //分批保存数据结果
        try {
            partitionSave(detailList);
        } catch (Exception e) {
            log.error("转换国资委报表失败:{}", e.getMessage());
            return false;
        }
        return true;
    }

    private void processDetail(QfSubjectInfo subjectInfo,
                               List<QfFinanceSasacCompanyD> detailList,
                               List<ReportDataVo> allData,
                               QfFinanceSasacCompanyM mainInfo,
                               Map<String, QfEnterpriseInfo> enterpriseInfoMap) {
        Map<String, List<ReportDataVo>> enterpriseMap = allData.stream().collect(Collectors.groupingBy(ReportDataVo::getEnterpriseCode));
        String targetCalculation = subjectInfo.getExpression();
        List<String> expressionKey = CommonUtil.getExpressionKey(targetCalculation);
        enterpriseMap.forEach((enterpriseCode, dataVoList) -> {
            if (!enterpriseInfoMap.containsKey(enterpriseCode)) {
                return;
            }
            QfEnterpriseInfo qfEnterpriseInfo = enterpriseInfoMap.get(enterpriseCode);
            QfFinanceSasacCompanyD detail = new QfFinanceSasacCompanyD();
            createBaseInfo(mainInfo, subjectInfo, detail);
            detail.setEnterpriseNameEn(qfEnterpriseInfo.getNameEn());
            detail.setEnterpriseName(qfEnterpriseInfo.getName());
            detail.setEnterpriseCode(enterpriseCode);
            if (!StringUtils.isEmpty(targetCalculation)) {
                calculateData(subjectInfo, mainInfo, targetCalculation, expressionKey, dataVoList, detail);
            }

            detailList.add(detail);
        });
    }


    private void partitionSave(List<QfFinanceSasacCompanyD> detailList) throws InterruptedException {
        List<List<QfFinanceSasacCompanyD>> partition = BeanUtils.partition(detailList, 100);
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(partition.size());
        // 声明线程计数器 记录单个任务的执行次数
        CountDownLatch countDownLatch = new CountDownLatch(partition.size());
        // 遍历处理拆分的list数据
        for (int i = 0; i < partition.size(); i++) {
            int finalI = i;
            executorService.execute(() -> {
                // 业务处理部分
                List<QfFinanceSasacCompanyD> importParamDTOList = partition.get(finalI);
                financeSasacCompanyDManager.saveBatch(importParamDTOList);
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        //关闭线程池
        executorService.shutdown();
    }

    private void calculateData(QfSubjectInfo subjectInfo,
                               QfFinanceSasacCompanyM mainInfo,
                               String targetCalculation,
                               List<String> expressionKey,
                               List<ReportDataVo> dataVoList,
                               QfFinanceSasacCompanyD detail) {

        BigDecimal fillUnrealData = BigDecimal.ZERO;

        BigDecimal lastYearfillRealData = BigDecimal.ZERO;

        BigDecimal lastYearfillUnrealData = BigDecimal.ZERO;

        BigDecimal fillRealData = BigDecimal.ZERO;

        // targetCalculationMap TCM
        Map<String, BigDecimal> fillUnreal_TCM = Maps.newHashMap();
        Map<String, BigDecimal> lastYearfillReal_TCM = Maps.newHashMap();
        Map<String, BigDecimal> lastYearfillUnReal_TCM = Maps.newHashMap();
        Map<String, BigDecimal> fillReal_TCM = Maps.newHashMap();
        Map<String, ReportDataVo> dataVoMap = dataVoList.stream().collect(Collectors.toMap(item -> item.getSubjectCode(), item -> item));
        for (String key : expressionKey) {
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            if (!dataVoMap.containsKey(key)) {
                continue;
            }
            ReportDataVo dataVo = dataVoMap.get(key);
            key = "U" + key;

            fillReal_TCM.put(key, dataVo.getFillRealData());

            fillUnreal_TCM.put(key, dataVo.getFillUnrealData());

            lastYearfillReal_TCM.put(key, dataVo.getLastYearfillRealData());

            lastYearfillUnReal_TCM.put(key, dataVo.getLastYearfillUnrealData());
        }

        log.info("expressionKey:{},targetCalculation:{},fillReal_TCM:{},公司编码：{}", expressionKey, targetCalculation, fillReal_TCM, detail.getEnterpriseCode());
        //汇率值
        Map<String, BigDecimal> dataRataMap = getDataRata(subjectInfo, mainInfo);
        String handledTargetCalculation = targetCalculation;

        for (String key : expressionKey) {
            key = "U" + key;
            if (!fillReal_TCM.containsKey(key)) {
                fillReal_TCM.put(key, BigDecimal.ZERO);
            }
            if (!fillUnreal_TCM.containsKey(key)) {
                fillUnreal_TCM.put(key, BigDecimal.ZERO);
            }
            if (!lastYearfillUnReal_TCM.containsKey(key)) {
                lastYearfillUnReal_TCM.put(key, BigDecimal.ZERO);
            }
            if (!lastYearfillReal_TCM.containsKey(key)) {
                lastYearfillReal_TCM.put(key, BigDecimal.ZERO);
            }
        }

        if (fillReal_TCM.size() == expressionKey.size()) {
            targetCalculation = CommonUtil.replaceExpression(expressionKey, handledTargetCalculation);
            BigDecimal dataRata = BigDecimal.ONE;
            if (dataRataMap.containsKey("fillRealData") && null != dataRataMap.get("fillRealData")) {
                dataRata = dataRataMap.get("fillRealData");
            }
            fillRealData = CommonUtil.convertToCode(targetCalculation, fillReal_TCM, 2).multiply(dataRata);
        }
        detail.setFillRealData(fillRealData);

        if (fillUnreal_TCM.size() == expressionKey.size()) {
            BigDecimal dataRata = BigDecimal.ONE;
            if (dataRataMap.containsKey("fillUnrealData") && null != dataRataMap.get("fillUnrealData")) {
                dataRata = dataRataMap.get("fillUnrealData");
            }
            targetCalculation = CommonUtil.replaceExpression(expressionKey, handledTargetCalculation);
            fillUnrealData = CommonUtil.convertToCode(targetCalculation, fillUnreal_TCM, 2).multiply(dataRata);
        }
        detail.setFillUnrealData(fillUnrealData);

        if (lastYearfillUnReal_TCM.size() == expressionKey.size()) {
            BigDecimal dataRata = BigDecimal.ONE;
            if (dataRataMap.containsKey("lastYearfillUnrealData") && null != dataRataMap.get("lastYearfillUnrealData")) {
                dataRata = dataRataMap.get("lastYearfillUnrealData");
            }
            targetCalculation = CommonUtil.replaceExpression(expressionKey, handledTargetCalculation);
            lastYearfillUnrealData = CommonUtil.convertToCode(targetCalculation, lastYearfillUnReal_TCM, 2).multiply(dataRata);
        }
        detail.setLastYearfillUnrealData(lastYearfillUnrealData);

        if (lastYearfillReal_TCM.size() == expressionKey.size()) {
            BigDecimal dataRata = BigDecimal.ONE;
            if (dataRataMap.containsKey("lastYearfillRealData") && null != dataRataMap.get("lastYearfillRealData")) {
                dataRata = dataRataMap.get("lastYearfillRealData");
            }
            targetCalculation = CommonUtil.replaceExpression(expressionKey, handledTargetCalculation);
            lastYearfillRealData = CommonUtil.convertToCode(targetCalculation, lastYearfillReal_TCM, 2).multiply(dataRata);
        }
        detail.setLastYearfillRealData(lastYearfillRealData);

    }

    private void createBaseInfo(QfFinanceSasacCompanyM mainInfo, QfSubjectInfo subjectInfo, QfFinanceSasacCompanyD
            detail) {
        detail.setMainId(mainInfo.getId());
        detail.setFillDate(mainInfo.getFillDate());
        detail.setSubjectCode(subjectInfo.getCode());
        detail.setSubjectName(subjectInfo.getName());
        detail.setSubjectLevel(subjectInfo.getLevel());
        detail.setSubjectNameEn(subjectInfo.getNameEn());
        detail.setSubjectUnit(subjectInfo.getUnit());
        detail.setSn(subjectInfo.getSn());
        detail.setStartMonth(1);
        detail.setEndMonth(mainInfo.getFillQuarter() * 3);
    }

    /**
     * @param subjectInfo
     * @param mainInfo
     * @return
     */
    private Map<String, BigDecimal> getDataRata(QfSubjectInfo subjectInfo, QfFinanceSasacCompanyM mainInfo) {
        Map<String, BigDecimal> map = Maps.newHashMap();
        if (StringUtils.isEmpty(subjectInfo.getRateType())) {
            return map;
        }
        if (StringUtil.isEmpty(subjectInfo.getCode()) || !"￥".equals(subjectInfo.getUnit())) {
            return map;
        }
        if (subjectInfo.getRateType().equals(1)) {
            //今年同期数据汇率
            map.put("fillUnrealData", mainInfo.getYearAvgRate());
            //去年同期数据汇率
            map.put("lastYearfillUnrealData", mainInfo.getLastYearAvgRate());
            //今年累计数据汇率
            map.put("fillRealData", mainInfo.getYearYtdAvgRate());
            //去年累计数据汇率
            map.put("lastYearfillRealData", mainInfo.getLastYearYtdAvgRate());

        } else if (subjectInfo.getRateType().equals(2)) {
            //今年同期数据汇率
            map.put("fillUnrealData", mainInfo.getYearEndRate());
            //去年同期数据汇率
            map.put("lastYearfillUnrealData", mainInfo.getLastYearEndRate());
            //今年累计数据汇率
            map.put("fillRealData", mainInfo.getYearYtdEndRate());
            //去年累计数据汇率
            map.put("lastYearfillRealData", mainInfo.getLastYearYtdEndRate());
        }
        return map;
    }

    /**
     * 获取对应科目数据明细
     *
     * @param mainInfo
     * @param typeSubjectMap
     * @return
     */
    private List<ReportDataVo> getAllData(QfFinanceSasacCompanyM mainInfo, Map<String, List<String>> typeSubjectMap) throws ExecutionException, InterruptedException {
        List<ReportDataVo> list = Lists.newArrayList();
        //获取年份
        Integer endMonth = mainInfo.getFillQuarter() * 3;
        //开启第一个异步任务
        CompletableFuture<Void> cfFuture = CompletableFuture.runAsync(() -> {
            if (typeSubjectMap.containsKey(SubjectSpeciesEnum.CF.getType())) {
                List<ReportDataVo> cfList = financeCfDManager.getCfDataList(typeSubjectMap.get(SubjectSpeciesEnum.CF.getType()), mainInfo.getFillYear(), endMonth);
                if (!CollectionUtils.isEmpty(cfList)) {
                    list.addAll(cfList);
                }
            }
        }, threadPoolExecutor);

        CompletableFuture<Void> bsFuture = CompletableFuture.runAsync(() -> {
            if (typeSubjectMap.containsKey(SubjectSpeciesEnum.BS.getType())) {
                List<ReportDataVo> bsList = financeBsDManager.getBsDataList(typeSubjectMap.get(SubjectSpeciesEnum.BS.getType()), mainInfo.getFillYear(), endMonth);
                if (!CollectionUtils.isEmpty(bsList)) {
                    list.addAll(bsList);
                }
            }
        }, threadPoolExecutor);

        CompletableFuture<Void> hrFuture = CompletableFuture.runAsync(() -> {
            if (typeSubjectMap.containsKey(SubjectSpeciesEnum.HR.getType())) {
                List<ReportDataVo> personList = personDManager.getPersonDataList(typeSubjectMap.get(SubjectSpeciesEnum.HR.getType()), mainInfo.getFillYear(), endMonth);
                if (!CollectionUtils.isEmpty(personList)) {
                    list.addAll(personList);
                }
            }
        }, threadPoolExecutor);

        CompletableFuture<Void> plFuture = CompletableFuture.runAsync(() -> {
            if (typeSubjectMap.containsKey(SubjectSpeciesEnum.PL.getType())) {
                List<ReportDataVo> plList = financePlDManager.getActualDataList(typeSubjectMap.get(SubjectSpeciesEnum.PL.getType()), mainInfo.getFillYear(), endMonth);
                if (!CollectionUtils.isEmpty(plList)) {
                    list.addAll(plList);
                }
            }
        }, threadPoolExecutor);

        CompletableFuture<Void> reportFuture = CompletableFuture.runAsync(() -> {
            if (typeSubjectMap.containsKey(SubjectSpeciesEnum.SA.getType())) {
                List<ReportDataVo> cfList = reportingSummaryDManager.getDataList(typeSubjectMap.get(SubjectSpeciesEnum.SA.getType()), mainInfo.getFillYear(), endMonth);
                if (!CollectionUtils.isEmpty(cfList)) {
                    list.addAll(cfList);
                }
            }

        }, threadPoolExecutor);

        CompletableFuture.allOf(cfFuture, bsFuture, hrFuture, plFuture, reportFuture).get();
        return list;
    }

    private Map<String, List<String>> getTypeSubjectMap(List<QfSubjectInfo> relationList) {
        relationList.forEach(subjectInfo -> {
            if (subjectInfo.getType().contains(SubjectSpeciesEnum.BS.getType())) {
                subjectInfo.setType(SubjectSpeciesEnum.BS.getType());
            } else if (subjectInfo.getType().contains(SubjectSpeciesEnum.PL.getType())) {
                subjectInfo.setType(SubjectSpeciesEnum.PL.getType());
            } else if (subjectInfo.getType().contains(SubjectSpeciesEnum.HR.getType())) {
                subjectInfo.setType(SubjectSpeciesEnum.HR.getType());
            } else if (subjectInfo.getType().contains(SubjectSpeciesEnum.CF.getType())) {
                subjectInfo.setType(SubjectSpeciesEnum.CF.getType());
            } else if (subjectInfo.getType().contains(SubjectSpeciesEnum.SA.getType())) {
                subjectInfo.setType(SubjectSpeciesEnum.SA.getType());
            }
        });
        Map<String, List<QfSubjectInfo>> gnSubjectMap = relationList.stream().collect(Collectors.groupingBy(QfSubjectInfo::getType));
        Map<String, List<String>> typeSubjectMap = Maps.newHashMap();
        gnSubjectMap.forEach((k, v) -> {
            List<String> subjectCodes = Lists.newArrayList();
            v.forEach(qfSubjectInfo -> {
                if (StringUtils.isEmpty(qfSubjectInfo.getExpression())) {
                    return;
                }
                subjectCodes.addAll(CommonUtil.getExpressionKey(qfSubjectInfo.getExpression()));
            });
            if (k.contains(SubjectSpeciesEnum.BS.getType())) {
                typeSubjectMap.put(SubjectSpeciesEnum.BS.getType(), subjectCodes);
            } else if (k.contains(SubjectSpeciesEnum.PL.getType())) {
                typeSubjectMap.put(SubjectSpeciesEnum.PL.getType(), subjectCodes);
            } else if (k.contains(SubjectSpeciesEnum.HR.getType())) {
                typeSubjectMap.put(SubjectSpeciesEnum.HR.getType(), subjectCodes);
            } else if (k.contains(SubjectSpeciesEnum.CF.getType())) {
                typeSubjectMap.put(SubjectSpeciesEnum.CF.getType(), subjectCodes);
            } else if (k.contains(SubjectSpeciesEnum.SA.getType())) {
                typeSubjectMap.put(SubjectSpeciesEnum.SA.getType(), subjectCodes);
            }
        });

        return typeSubjectMap;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(QfFinanceSasacCompanyM t) {
        QfFinanceSasacCompanyM QfFinanceSasacCompanyM = baseMapper.selectById(t.getId());
        if (null == QfFinanceSasacCompanyM) {
            return false;
        }
        QfFinanceSasacCompanyM.setStatus(QfFinanceSasacCompanyM.getStatus() == 0 ? 1 : 0);
        int i = this.baseMapper.updateById(QfFinanceSasacCompanyM);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(QfFinanceSasacCompanyM t) {
        QueryWrapper<QfFinanceSasacCompanyM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("fill_quarter_", t.getFillQuarter());
        queryWrapper.eq("report_id_", t.getReportId());
        queryWrapper.ne("id_", t.getId());
        List<QfFinanceSasacCompanyM> QfFinanceSasacCompanyMS = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(QfFinanceSasacCompanyMS)) {
            throw new BaseException(I18nUtil.getMessage("QfOperationKpiM.repeat", LocaleContextHolder.getLocale()));
        }
        int insert = this.baseMapper.updateById(t);
        if (insert > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertInfo(QfFinanceSasacCompanyM t) {
        QueryWrapper<QfFinanceSasacCompanyM> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fill_year_", t.getFillYear());
        queryWrapper.eq("fill_quarter_", t.getFillQuarter());
        queryWrapper.eq("report_id_", t.getReportId());
        List<QfFinanceSasacCompanyM> QfFinanceSasacCompanyMS = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(QfFinanceSasacCompanyMS)) {
            throw new BaseException(I18nUtil.getMessage("QfOperationKpiM.repeat", LocaleContextHolder.getLocale()));
        }
        int insert = this.baseMapper.insert(t);
        if (insert > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<JSONObject> detailQuery(List<QfFinanceSasacCompanyD> list) {

        if (CollectionUtils.isEmpty(list)) {
            return com.google.api.client.util.Lists.newArrayList();
        }
        String mainId = list.get(0).getMainId();
        QfFinanceSasacCompanyM mainInfo = baseMapper.selectById(mainId);
        List<QfEnterpriseInfo> rangeList = reportRangeManager.getQfEnterpriseInfo(mainInfo.getReportId());
        //获取报表关联国内科目信息
        List<QfSubjectInfo> subjectInfoList = reportSubjectManager.getSubjectInfo(mainInfo.getReportId());

        List<JSONObject> detailList = Lists.newArrayList();
        createHeaderInfo(mainInfo, rangeList, detailList);
        for (QfSubjectInfo subject : subjectInfoList) {
            JSONObject data = new JSONObject(true);
            data.put("subjectCode", subject.getCode());
            for (QfFinanceSasacCompanyD companyD : list) {
                if (companyD.getSubjectCode().equals(subject.getCode())) {
                    data.put("subjectName", companyD.getSubjectName());
                    data.put("sn", companyD.getSn());
                    if (!StringUtils.isEmpty(subject.getUnit()) && "￥".equals(subject.getUnit())) {
                        companyD.setSubjectUnit("万元");
                        if (null != companyD.getFillUnrealData()) {
                            companyD.setFillUnrealData(companyD.getFillUnrealData().divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
                        }
                        if (null != companyD.getLastYearfillUnrealData()) {
                            companyD.setLastYearfillUnrealData(companyD.getLastYearfillUnrealData().divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
                        }
                        if (null != companyD.getFillRealData()) {
                            companyD.setFillRealData(companyD.getFillUnrealData().divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
                        }
                        if (null != companyD.getLastYearfillRealData()) {
                            companyD.setLastYearfillRealData(companyD.getFillUnrealData().divide(new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
                        }
                    }
                    data.put("unit", companyD.getSubjectUnit());
                    data.put("subjectLevel", companyD.getSubjectLevel());

                    if ("CIGR".equals(companyD.getEnterpriseCode())) {
                        data.put("fillUnrealData", companyD.getFillUnrealData());
                        data.put("lastYearfillUnrealData", companyD.getLastYearfillUnrealData());
                        data.put("fillRealData", companyD.getFillRealData());
                        data.put("lastYearfillRealData", companyD.getLastYearfillRealData());
                    } else {
                        data.put("nowUnreal" + companyD.getEnterpriseCode(), companyD.getFillUnrealData());
                        data.put("lastUnreal" + companyD.getEnterpriseCode(), companyD.getLastYearfillUnrealData());
                        data.put("nowReal" + companyD.getEnterpriseCode(), companyD.getFillRealData());
                        data.put("lastReal" + companyD.getEnterpriseCode(), companyD.getLastYearfillRealData());
                    }

                }
            }
            detailList.add(data);
        }

        return detailList;
    }

    private void createHeaderInfo(QfFinanceSasacCompanyM
                                          mainInfo, List<QfEnterpriseInfo> enterpriseHeader, List<JSONObject> detailList) {
        JSONObject detail = new JSONObject(true);
        detail.put("subjectName", "项目");
        detail.put("sn", "行次");
        detail.put("unit", "单位");
        detail.put("fillUnrealData", "1-" + (mainInfo.getFillQuarter() * 3 - 1) + "月本年累计");
        detail.put("lastYearfillUnrealData", "1-" + (mainInfo.getFillQuarter() * 3 - 1) + "月上年同期");
        detail.put("fillRealData", "1-" + (mainInfo.getFillQuarter() * 3) + "月本年累计");
        detail.put("lastYearfillRealData", "1-" + (mainInfo.getFillQuarter() * 3) + "月上年同期");
        detail.put("subjectLevel", "subjectLevel");
        enterpriseHeader.forEach(enterprise -> {
            String code = enterprise.getCode();
            if ("CIGR".equals(code)) {
                return;
            }
            detail.put("nowUnreal" + code, code + "\n" + "1-" + (mainInfo.getFillQuarter() * 3 - 1) + "月本年累计");
            detail.put("lastUnreal" + code, code + "\n" + "1-" + (mainInfo.getFillQuarter() * 3 - 1) + "月上年同期");
            detail.put("nowReal" + code, code + "\n" + "1-" + (mainInfo.getFillQuarter() * 3) + "月本年累计");
            detail.put("lastReal" + code, code + "\n" + "1-" + (mainInfo.getFillQuarter() * 3) + "月上年同期");
        });
        detailList.add(detail);
    }
}
