package com.nantian.cloud.jljc.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nantian.cloud.jljc.dto.AuditorDto;
import com.nantian.cloud.jljc.dto.TReportEnergysTructureDto;
import com.nantian.cloud.jljc.entity.*;
import com.nantian.cloud.jljc.service.*;
import com.nantian.sc.cloud.common.core.util.R;
import com.nantian.sc.cloud.common.log.annotation.SysLog;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.text.DecimalFormat;
import java.util.*;


/**
 * 报表1-2能源消费表
 *
 * @author stz
 * @date 2020-09-16
 */
@Slf4j
@CrossOrigin
@RestController
@AllArgsConstructor
@RequestMapping("/tReportEnergysTructure")
@Api(value = "tReportEnergysTructure", tags = "报表1-2能源消费表")
public class TReportEnergysTructureeController {

    final private TReportEnergysTructureService tReportEnergysTructureService;
    final private TReportEnergyOutService tReportEnergyOutService;
    final private TReportEnterpriseService tReportEnterpriseService;
    final private TReportService tReportService;
    final private EnergyInfoService energyInfoService;
    final private TReportParaService tReportParaService;
    private final EcAbnormalVolatilityService ecAbnormalVolatilityService;
    private final EcAbnormalVolatilityInfoService ecAbnormalVolatilityInfoService;
    final private TReportFinancialService tReportFinancialService;
    final private EcAbnormalVolatilityInfoController volatilityInfoController;
    private final EpcEnergyAccuracyAnalysisService epcEnergyAccuracyAnalysisService;
    private final EnterpriseInfoService enterpriseInfoService;


    /**
     * 分页查询
     */
    @GetMapping("/page")
    @SysLog("查询报表1-2能源消费表")
    @ApiOperation(value = "查询报表1-2能源消费表", notes = "条件查询报表1-2能源消费表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tReportEnergysTructure", value = "报表1-2能源消费表", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path")
    })
    public R getcheckGaugesPage(Page page, TReportEnergysTructure tReportEnergysTructure) {
        tReportEnergysTructure.setDelFlag("1"); //查询未删除数据
        //return R.ok(tReportEnergysTructureService.getPageScope(page,tReportEnergysTructure));
        //return R.ok(tReportEnergysTructureService.page(page, Wrappers.query(tReportEnergysTructure)));
        return R.ok(tReportEnergysTructureService.selByPage(page, tReportEnergysTructure));
    }

    /**
     * 通过id查询报表1-2能源消费表
     */
    @GetMapping("/{tReportEnergysTructureId}")
    @SysLog("通过id查询报表1-2能源消费表")
    @ApiOperation(value = "通过id查询报表1-2能源消费表", notes = "通过id查询报表1-2能源消费表")
    @ApiImplicitParam(name = "tReportEnergysTructureId", value = "报表1-2能源消费表id", required = true, paramType = "path", dataType = "int")
    public R getById(@PathVariable("tReportEnergysTructureId") Integer tReportEnergysTructureId) {
        return R.ok(tReportEnergysTructureService.getById(tReportEnergysTructureId));
    }


    /**
     * 通过年份查询报表1-2能源消费表
     */
    @GetMapping("/getByYear")
    @SysLog("通过年份查询报表1-2能源消费表")
    @ApiOperation(value = "通过年份查询报表1-2能源消费表", notes = "通过年份查询报表1-2能源消费表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "enterpriseCode", value = "企业社会信用编码", required = true, dataType = "json", paramType = "path")
    })
    public R<Map<String, Object>> getByYear(String year, String enterpriseCode) {
        if (year == null || "".equals(year)) {
            return R.failed("查询能源消费表失败，年度不能为空");
        }
        if (enterpriseCode == null || "".equals(enterpriseCode)) {
            return R.failed("查询能源消费表失败，企业社会信用编码不能为空");
        }
        //ScUser u = SecurityUtils.getUser();
        //获取能源报表信息
        TReport report = tReportService.getInfoByType(enterpriseCode, year, "2");
        if (report == null) {
            return R.ok();
        }
        //获取能源消费表信息
        List<TReportEnergysTructure> tructureList = tReportEnergysTructureService.getTructureByReportId(report.getId());

        Map<String, Object> map = new HashMap();
        map.put("tructureList", tructureList);

        //工业总产值
        Double productionSum = 0d;
        for (TReportEnergysTructure tructure : tructureList) {
            if ("合计当量值".equals(tructure.getEnergyCodeName())) {
                productionSum = tructure.getProductionSum();
            }
        }
        map.put("productionSum", productionSum);
        return R.ok(map);
    }


    /**
     * 批量更新报表1-2属性设置
     */
    @PostMapping("/upEnergyInfo")
    @SysLog("批量更新报表1-2属性设置")
    @ApiOperation(value = "批量更新报表1-2属性设置", notes = "批量更新报表1-2属性设置（参数说明是键值对说明），参数s除外")
    @ApiImplicitParam(name = "data", value = "能源信息", required = true, dataType = "String")
    public R upEnergyInfo(@RequestBody String s) {

        log.error("批量更新报表1-2属性设置：" + s);

        JSONObject json = JSONObject.parseObject(s);
        //获取报表1-2属性设置
        String data = json.getString("data");
        List<EnergyInfo> energyInfoList = (List<EnergyInfo>) JSONObject.parseArray(data, EnergyInfo.class);
        if (energyInfoList.size() == 0) {
            return R.ok();
        }

        List<EnergyInfo> newList = new ArrayList<>();
        ScUser u = SecurityUtils.getUser();
        for (EnergyInfo energyInfo : energyInfoList) {
            if (energyInfo.getId() == null) {
                return R.failed("更新报表2属性设置失败！");
            }
            energyInfo.setUserid(u.getId());
            energyInfo.setUpdateTime(new Date());
            newList.add(energyInfo);
        }

        return R.ok(energyInfoService.updateBatchById(newList));
    }


    /**
     * 获取企业加工转换信息
     */
    @GetMapping("/getProLink")
    @SysLog("获取企业加工转换信息")
    @ApiOperation(value = "获取企业加工转换信息", notes = "获取企业加工转换信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "enterpriseCode", value = "企业社会信用编码", required = true, dataType = "json", paramType = "path")
    })
    public R getProLink(String year, String enterpriseCode) {

        if (year == null || "".equals(year)) {
            return R.failed("获取企业加工转换信息失败，年度不能为空");
        }
        if (StringUtils.isEmpty(enterpriseCode)) {
            enterpriseCode = SecurityUtils.getUser().getEnterpriseCode();
        }
        TReportEnterprise enterpriseInfo = tReportEnterpriseService.getEnterpriseInfo(enterpriseCode, year);
        if (enterpriseInfo == null) {
            return R.failed(year + "年 报表设置【企业基本信息】未完成，请前去设置");
        }

        Map<String, Object> map = new HashMap();
        //企业是否为加工转换
        String processingLinkStr = enterpriseInfo.getProcessingLinkJson();
        System.err.println("processingLinkStr：" + processingLinkStr);
        if (processingLinkStr == null || "".equals(processingLinkStr)) {
            map.put("processingLinkJson", processingLinkStr);
        } else {
            if (processingLinkStr.startsWith("[")) {
                //加工环节信息json 是数组，就进行转换
                processingLinkStr = processingLinkStr.replaceAll("\\[","").replaceAll("]","");
            }
            String linkStr = "";
            if (processingLinkStr.contains(",")) { //加工装换环节
                Set<String> setTmp = new HashSet<>(Arrays.asList(processingLinkStr.split(","))); //字符去重
                linkStr = StringUtils.join(setTmp,",");
                linkStr = linkStr.startsWith(",") ? linkStr.substring(1) : linkStr; //去除第一逗号字符
            }else{
                linkStr = processingLinkStr;
            }
            map.put("processingLinkJson", linkStr);
        }
        map.put("processingLink", enterpriseInfo.getProcessingLink());
        //企业加工转换的类型

        //企业报表设置的能源信息
        String energyInfoStr = tReportEnterpriseService.getEnergyInfo(enterpriseCode, year);
        map.put("energyInfo", energyInfoStr);

        //获取工业生产消费量
        Map<String,Double> consumeIndustry = new HashMap<>();
        TReport report = tReportService.getInfoByType(enterpriseCode, year, "2");
        //获取能源消费表信息
        List<TReportEnergysTructure> tructureList = tReportEnergysTructureService.getTructureByReportId(report == null ? 0 : report.getId());
        if (tructureList.size() > 0) {
            for (TReportEnergysTructure tructure : tructureList) {
                if (!"合计当量值".equals(tructure.getEnergyCodeName()) && !"合计等价值".equals(tructure.getEnergyCodeName())) {
                    consumeIndustry.put(tructure.getEnergyCodeName(),tructure.getConsumeIndustry() == null ? 0 : tructure.getConsumeIndustry());
                }
            }
        } else {
            List<EnergyInfo> energyInfoList = (List<EnergyInfo>) JSONArray.parseArray(energyInfoStr, EnergyInfo.class);
            for (EnergyInfo energyInfo : energyInfoList) {
                if ("true".equals(energyInfo.getCompBuyEnergy()) || "true".equals(energyInfo.getProcessEnergy()) || "true".equals(energyInfo.getCraftEnergy())) {
                    consumeIndustry.put(energyInfo.getEnergyName(),0d);
                }
            }
        }
        map.put("consumeIndustry", consumeIndustry);

        return R.ok(map);
    }


    /**
     * 批量更新报表1-2能源消费表（企业端）
     */
    @Transactional
    @PostMapping("/upTructure")
    @SysLog("批量更新报表1-2能源消费表（企业端）")
    @ApiOperation(value = "批量报表1-2能源消费表（企业端）（参数说明是键值对说明，参数s除外）", notes = "批量报表1-2能源消费表（企业端）（参数说明是键值对说明），参数s除外")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "report", value = "能源报表信息", required = true, dataType = "String"),
            @ApiImplicitParam(name = "data", value = "报表1-2能源消费表", required = true, dataType = "String")
    })
    public R upTructure(@RequestBody String s) {

        log.error("批量更新报表1-2能源消费表：" + s);

        JSONObject json = JSONObject.parseObject(s);
        //获取能源报表信息
        TReport report = JSONObject.parseObject(json.getString("report"), TReport.class);
        if (report.getYear() == null || "".equals(report.getYear())) {
            return R.failed("更新报表1-2能源消费表失败，年度不能为空");
        }

        ScUser u = SecurityUtils.getUser();
        String enterpriseCode = StringUtils.isNotEmpty(report.getEnterpriseCode()) ? report.getEnterpriseCode() : u.getEnterpriseCode();
        String data = json.getString("data");
        //获取能源消费表列表
        //List<TReportEnergysTructure> tructureList = (List<TReportEnergysTructure>) JSONArray.parseArray(data, TReportEnergysTructure.class);
        List<TReportEnergysTructureDto> dtoList = (List<TReportEnergysTructureDto>) JSONArray.parseArray(data, TReportEnergysTructureDto.class);
        List<TReportEnergysTructure> tructureList = new ArrayList<>();
        if(dtoList!=null && dtoList.size()>0){
            for (TReportEnergysTructureDto dto : dtoList) {
                TReportEnergysTructure tmp = new TReportEnergysTructure(dto.getId(),dto.getReportId(),dto.getEnergyCode(),dto.getEnergyCodeName(),dto.getUnit(),
                        dto.getStartInventory(),dto.getObject(),dto.getMoney(),dto.getConsumeSum(),dto.getConsumeIndustry(),dto.getConsumeMaterial(),dto.getConsumeNoindustry(),
                        dto.getConsumeTransport(),dto.getEndInventory(),dto.getModulus(),dto.getRefModulus(),dto.getProductionSum());
                tructureList.add(tmp);
            }
        }
        //获取工业总产值（当年价）
        double productionSum = JSONObject.parseObject(json.getString("productionSum"), Double.class);

        //获取报表信息id（有数据就返回id，无数据就新增记录后返回id）
        long reportId = tReportService.getTReportIdByType(enterpriseCode, report.getYear() + "", "2", u);
        //计算本年能源消费信息的 合计当量值和合计等价值
        //返回集合，下标  0：sumInfo合计当量值  1：sumEquInfo合计等价值
        List<TReportEnergysTructure> sumList = getSum(tructureList, reportId, productionSum);
        tructureList.addAll(sumList);

        //进行异常波动分析
        R map = getEcAbnormalVolatility(report, u, tructureList);
        if (map != null) return map;

        //批量更新报表1-2能源消费表信息
        //更新报表信息
        report.setId(reportId);
        report.setUserid(u.getId());
        report.setUpdateTime(new Date());
        report.setReportStatus("2");
        //boolean b = tReportService.updateById(report);

        //获取报表设置的企业信息
        TReportEnterprise enterprise = tReportEnterpriseService.getEnterpriseInfo(enterpriseCode, report.getYear() + "");
        List<TReportEnergysTructure> newTructureList = new ArrayList<TReportEnergysTructure>();
        for (TReportEnergysTructure tructure : tructureList) {
            if ("原煤".equals(tructure.getEnergyCodeName())) {
                TReportEnergysTructure rawCoal = getRawCoal(tructureList, u, reportId);
                newTructureList.add(rawCoal);
            } else {
                hasOld(u, tructure, reportId);
                tructure.setReportId(reportId);
                tructure.setUserid(u.getId());
                tructure.setUpdateTime(new Date());
                newTructureList.add(tructure);
            }

            if ("合计当量值".equals(tructure.getEnergyCodeName()) && enterprise != null) {
                if ("2".equals(enterprise.getProcessingLink())) { //该企业不是加工转换企业
                    updateFinancial(report, u, enterpriseCode, tructure);
                }
            }

            if ("合计等价值".equals(tructure.getEnergyCodeName()) && enterprise != null) {
                if ("2".equals(enterprise.getProcessingLink())) { //该企业不是加工转换企业
                    updateFinancialRef(report, u, enterpriseCode, tructure, "1");
                }
            }

            if ("合计当量值(参考指标系数计算)".equals(tructure.getEnergyCodeName()) && enterprise != null) {
                if ("2".equals(enterprise.getProcessingLink())) { //该企业不是加工转换企业
                    updateFinancialRef(report, u, enterpriseCode, tructure, "2");
                }
            }
        }

        //return R.ok(tReportEnergysTructureService.saveOrUpdateBatch(newTructureList));
        boolean updateBatch = tReportEnergysTructureService.saveOrUpdateBatch(newTructureList);

        if (enterprise != null) {
            if ("1".equals(enterprise.getProcessingLink())) {
                //企业是加工转换企业，企业需要填写报表2-1，若已经有报表2-1信息，需要把工业生产消费量放进去
                TReport reportOut = tReportService.getInfoByType(enterpriseCode, report.getYear() + "", "2-1");
                TReportEnergyOut outQuery = new TReportEnergyOut();
                outQuery.setDelFlag("1");
                outQuery.setReportId(reportOut != null ? reportOut.getId() : 0);
                List<TReportEnergyOut> outList = tReportEnergyOutService.list(Wrappers.query(outQuery));
                List<TReportEnergyOut> newOutList = new ArrayList<>();
                if (outList != null && outList.size() > 0) {
                    //表1-2数据
                    for (TReportEnergysTructure tructure : newTructureList) {
                        //表1-2-1数据
                        for (TReportEnergyOut out : outList) {
                            if (tructure.getEnergyCodeName().equals(out.getEnergyCodeName())) {
                                //设置工业生产消费量
                                out.setProductionConsumption(tructure.getConsumeIndustry() != null ? tructure.getConsumeIndustry() : 0);
                                newOutList.add(out);
                            }
                            /*if ("合计当量值".equals(tructure.getEnergyCodeName()) && "合计当量值".equals(out.getEnergyCodeName())) {
                                //设置工业生产消费量
                                out.setProductionConsumption(tructure.getConsumeIndustry() != null ? tructure.getConsumeIndustry() : 0);
                                newOutList.add(out);
                            }*/
                        }
                    }
                    //修改报表2-1数据
                    tReportEnergyOutService.updateBatchById(newOutList);
                }
            }
        }

        if (updateBatch) {
            //只有报表2更新成功，才能更新报表信息
            return R.ok(tReportService.updateById(report));
        } else {
            return R.failed();
        }
    }


    /**
     * 该企业不是加工转换企业，设置财务信息的综合能源消费量、单位产值综合能耗（折标系数异常的，采用参考折标计算）
     */
    private boolean updateFinancialRef(TReport report, ScUser u, String enterpriseCode, TReportEnergysTructure tructure, String type) {

        //根据报表信息id取值，有值为修改，否则新增
        //存在，先填写报表2，再填写报表1的情况
        long reportIdByType1 = tReportService.getTReportIdByType(enterpriseCode, report.getYear() + "", "1", u);
        TReportFinancial financial = new TReportFinancial();
        TReportFinancial oldFinancial = tReportFinancialService.getFinancialsByReportId(reportIdByType1);

        financial.setReportId(reportIdByType1);
        //获取企业信息
        EnterpriseInfo info = enterpriseInfoService.getInfoByCode(u.getEnterpriseCode());
        //企业端新增信息，添加deptid
        financial.setDeptId(info != null && info.getRegionCode()!=null ? Integer.parseInt(info.getRegionCode()) : u.getDeptId());
        financial.setDelFlag("1");
        financial.setUserid(u.getId());
        financial.setUpdateTime(new Date());

        //设置报表1 财务信息 综合能源消费量(万吨标准煤) = 报表2 工业生产消费的能源折标量合计/10000 回显
        //Double energyConsumption = (tructure.getConsumeIndustry() != 0 && tructure.getConsumeIndustry() != null) ? tructure.getConsumeIndustry() / 10000 : 0;

        //设置报表1 财务信息 综合能源消费量(万吨标准煤) = 报表2 能源消费合计量折标后合计/10000 回显
        Double energyConsumption = (tructure.getConsumeSum() != 0 && tructure.getConsumeSum() != null) ? tructure.getConsumeSum() / 10000 : 0;

        //计算财务信息的 单位产值综合能耗（可比价） 以及上年值的变化率
        double unitEnergyConsumption = 0;
        if (oldFinancial != null) {
            //有历史数据，属于修改
            financial.setId(oldFinancial.getId());

            //单位产值综合能耗(吨标准煤/万元) = 综合能源消费量(万吨标准煤) * 10000 / 工业总产值(万元)
            if (tructure.getConsumeSum() != 0 && oldFinancial.getIndustrialYield() != null && oldFinancial.getIndustrialYield() != 0) { //综合能源消费量的值来源于报表2
                //unitEnergyConsumption = (energyConsumption * 10000) / financial.getIndustrialYield();
                unitEnergyConsumption = tructure.getConsumeSum() / oldFinancial.getIndustrialYield();
            }
        }

        DecimalFormat df2 = new DecimalFormat(".0000"); //保留4位小数
        DecimalFormat df = new DecimalFormat(".00"); //保留2位小数
        if("1".equals(type)){ //等价值
            financial.setEnergyConsumptionEqu(Double.parseDouble(df2.format(energyConsumption)));
            financial.setUnitEnergyConsumptionEqu(Double.parseDouble(df.format(unitEnergyConsumption)));
        }else{
            financial.setEnergyConsumptionRef(Double.parseDouble(df2.format(energyConsumption)));
            financial.setUnitEnergyConsumptionRef(Double.parseDouble(df.format(unitEnergyConsumption)));
        }

        return tReportFinancialService.saveOrUpdate(financial);
    }

    /**
     * 该企业不是加工转换企业，设置财务信息的综合能源消费量、单位产值综合能耗
     */
    private boolean updateFinancial(TReport report, ScUser u, String enterpriseCode, TReportEnergysTructure tructure) {

        //根据报表信息id取值，有值为修改，否则新增
        //存在，先填写报表2，再填写报表1的情况
        long reportIdByType1 = tReportService.getTReportIdByType(enterpriseCode, report.getYear() + "", "1", u);
        TReportFinancial financial = new TReportFinancial();
        TReportFinancial oldFinancial = tReportFinancialService.getFinancialsByReportId(reportIdByType1);
        /*if (oldFinancial != null) { //修改
            financial.setId(oldFinancial.getId());
        }*/

        financial.setReportId(reportIdByType1);
        //financial.setDeptId(u.getDeptId());
        //获取企业信息
        EnterpriseInfo info = enterpriseInfoService.getInfoByCode(u.getEnterpriseCode());
        //企业端新增信息，添加deptid
        financial.setDeptId(info != null && info.getRegionCode()!=null ? Integer.parseInt(info.getRegionCode()) : u.getDeptId());
        financial.setDelFlag("1");
        financial.setUserid(u.getId());
        financial.setUpdateTime(new Date());

        //获取上年的财务信息
        TReport r = tReportService.getInfoByType(enterpriseCode, (report.getYear() - 1) + "", "1");
        TReportFinancial frontFinancial = new TReportFinancial();
        if (r != null) {
            TReportFinancial front = new TReportFinancial();
            front.setReportId(r.getId());
            front.setDelFlag("1");
            frontFinancial = tReportFinancialService.getOne(Wrappers.query(front));
        }

        //设置报表1 财务信息 综合能源消费量(万吨标准煤) = 报表2 工业生产消费的能源折标量合计/10000 回显
        //double energyConsumption = (tructure.getConsumeIndustry() != 0 && tructure.getConsumeIndustry() != null) ? tructure.getConsumeIndustry() / 10000 : 0;

        //设置报表1 财务信息 综合能源消费量(万吨标准煤) = 报表2 能源消费合计量折标后合计/10000 回显
        Double energyConsumption = (tructure.getConsumeSum() != 0 && tructure.getConsumeSum() != null) ? tructure.getConsumeSum() / 10000 : 0;

        //计算财务信息的 单位产值综合能耗（可比价） 以及上年值的变化率
        double energyConsumptionRate = 0, unitEnergyConsumption = 0, unitEnergyConsumption2 = 0, unitEnergyConsumptionRate = 0;
        if (oldFinancial != null) {
            //有历史数据，属于修改
            financial.setId(oldFinancial.getId());

            //单位产值综合能耗(吨标准煤/万元) = 综合能源消费量(万吨标准煤) * 10000 / 工业总产值(万元)
            if (tructure.getConsumeSum() != 0 && oldFinancial.getIndustrialYield() != null && oldFinancial.getIndustrialYield() != 0) { //综合能源消费量的值来源于报表2
                //unitEnergyConsumption = (energyConsumption * 10000) / financial.getIndustrialYield();
                unitEnergyConsumption = tructure.getConsumeSum() / oldFinancial.getIndustrialYield();
            }

            //有上年数据，计算变化率
            if (frontFinancial != null) {
                if (frontFinancial.getEnergyConsumption() != null && frontFinancial.getEnergyConsumption() != 0 && energyConsumption != 0) {
                    energyConsumptionRate = (energyConsumption / frontFinancial.getEnergyConsumption() - 1) * 100;
                }
                if (frontFinancial.getEnergyConsumption() != null && frontFinancial.getIndustrialYield() != null
                        && frontFinancial.getEnergyConsumption() != 0 && frontFinancial.getIndustrialYield() != 0) { //综合能源消费量的值来源于报表2
                    unitEnergyConsumption2 = (frontFinancial.getEnergyConsumption() * 10000) / frontFinancial.getIndustrialYield();
                }
                if (unitEnergyConsumption != 0 && unitEnergyConsumption2 != 0) {
                    unitEnergyConsumptionRate = (unitEnergyConsumption / unitEnergyConsumption2 - 1) * 100;
                }
            }
        }

        DecimalFormat df2 = new DecimalFormat(".0000"); //保留4位小数
        DecimalFormat df = new DecimalFormat(".00"); //保留2位小数
        financial.setEnergyConsumption(Double.parseDouble(df2.format(energyConsumption)));
        financial.setEnergyConsumptionRate(Double.parseDouble(df2.format(energyConsumptionRate)));
        financial.setUnitEnergyConsumption(Double.parseDouble(df.format(unitEnergyConsumption)));
        financial.setUnitEnergyConsumptionRate(Double.parseDouble(df.format(unitEnergyConsumptionRate)));

        //return tReportFinancialService.saveOrUpdate(financial);
        boolean c = epcEnergyAccuracyAnalysisService.getEpcEnergyAccuracyAnalysis(report, energyConsumption != 0 ? energyConsumption * 10000 : 0, df, u);
        boolean b = tReportFinancialService.saveOrUpdate(financial);

        return b && c;
    }

    /**
     * 若有原煤能源信息，需将其所有子能源数据累加存入原煤
     */
    private TReportEnergysTructure getRawCoal(List<TReportEnergysTructure> tructureList, ScUser u, long reportId) {
        double startInventory = 0, object = 0, money = 0, consumeSum = 0, consumeIndustry = 0, consumeMaterial = 0,
                consumeNoindustry = 0, consumeTransport = 0, endInventory = 0;

        for (TReportEnergysTructure tructure : tructureList) {
            if ("无烟煤".equals(tructure.getEnergyCodeName())
                    || "炼焦烟煤".equals(tructure.getEnergyCodeName())
                    || "一般烟煤".equals(tructure.getEnergyCodeName())
                    || "褐煤".equals(tructure.getEnergyCodeName())) {
                startInventory += tructure.getStartInventory() != null ? tructure.getStartInventory() : 0;
                object += tructure.getObject() != null ? tructure.getObject() : 0;
                money += tructure.getMoney() != null ? tructure.getMoney() : 0; //只有金额是累加，其他需要乘折标系数
                consumeSum += tructure.getConsumeSum() != null ? tructure.getConsumeSum() : 0;
                consumeIndustry += tructure.getConsumeIndustry() != null ? tructure.getConsumeIndustry() : 0;
                consumeMaterial += tructure.getConsumeMaterial() != null ? tructure.getConsumeMaterial() : 0;
                consumeNoindustry += tructure.getConsumeNoindustry() != null ? tructure.getConsumeNoindustry() : 0;
                consumeTransport += tructure.getConsumeTransport() != null ? tructure.getConsumeTransport() : 0;
                endInventory += tructure.getEndInventory() != null ? tructure.getEndInventory() : 0;
            }
        }

        EnergyInfo energyInfo = new EnergyInfo();
        energyInfo.setDelFlag("1");
        energyInfo.setEnergyName("原煤");
        EnergyInfo info = energyInfoService.getOne(Wrappers.query(energyInfo));

        TReportEnergysTructure rawCoal = new TReportEnergysTructure("原煤", "吨", startInventory,
                object, money, consumeSum, consumeIndustry, consumeMaterial, consumeNoindustry, consumeTransport, endInventory, (Double) 0.0);
        if (info != null) {
            rawCoal.setEnergyCode(Integer.parseInt(info.getCode()));
        }
        hasOld(u, rawCoal, reportId);
        rawCoal.setReportId(reportId);
        rawCoal.setUserid(u.getId());
        rawCoal.setUpdateTime(new Date());
        return rawCoal;
    }

    /**
     * 判断是否有历史数据
     */
    private void hasOld(ScUser u, TReportEnergysTructure tructure, long reportId) {
        TReportEnergysTructure old = new TReportEnergysTructure();
        old.setReportId(reportId);
        old.setDelFlag("1");
        old.setEnergyCodeName(tructure.getEnergyCodeName());
        TReportEnergysTructure o = tReportEnergysTructureService.getOne(Wrappers.query(old));
        if (o != null) { //有历史数据为修改
            tructure.setId(o.getId());
        } else {
            //tructure.setDeptId(u.getId());
            //获取企业信息
            EnterpriseInfo info = enterpriseInfoService.getInfoByCode(u.getEnterpriseCode());
            //企业端新增信息，添加deptid
            tructure.setDeptId(info != null && info.getRegionCode()!=null? Integer.parseInt(info.getRegionCode()) : u.getDeptId());
            tructure.setDelFlag("1");
        }
    }


    /**
     * 计算本年能源消费信息的 合计当量值和合计等价值
     */
    public List<TReportEnergysTructure> getSum(List<TReportEnergysTructure> tructureList, long reportId, Double productionSum) {
        double startInventory = 0, object = 0, money = 0, consumeSum = 0, consumeIndustry = 0, consumeMaterial = 0,
                consumeNoindustry = 0, consumeTransport = 0, endInventory = 0;
        double startInventory2 = 0, object2 = 0, money2 = 0, consumeSum2 = 0, consumeIndustry2 = 0, consumeMaterial2 = 0,
                consumeNoindustry2 = 0, consumeTransport2 = 0, endInventory2 = 0;
        double startInventory3 = 0, object3 = 0, money3 = 0, consumeSum3 = 0, consumeIndustry3 = 0, consumeMaterial3 = 0,
                consumeNoindustry3 = 0, consumeTransport3 = 0, endInventory3 = 0;
        for (TReportEnergysTructure tructure : tructureList) {

            if (!"原煤".equals(tructure.getEnergyCodeName())) {
                //采用折标系数不存在，就使用参考折标系数
                String modulus = tructure.getModulus() != null ? tructure.getModulus() : tructure.getRefModulus();
                if (modulus != null && !"".equals(modulus)) {
                    String[] split = modulus.split("-");
                    //当量值
                    Double value = split.length > 0 ? Double.parseDouble(split[0]) : 0;
                    //等价值不存在，就取当量值
                    Double equvalue = Double.parseDouble((split.length <= 1) ? value + "" : split[1]);
                    if("33".equals(tructure.getEnergyCode())){ //电力等价折标系数
                        equvalue = 3.05d;
                    }

                    //求合计 当量值
                    startInventory += (tructure.getStartInventory() != null ? tructure.getStartInventory() * value : 0);
                    object += (tructure.getObject() != null ? tructure.getObject() * value : 0);
                    money += tructure.getMoney() != null ? tructure.getMoney() : 0; //只有金额是累加，其他需要乘折标系数
                    consumeSum += (tructure.getConsumeSum() != null ? tructure.getConsumeSum() * value : 0);
                    consumeIndustry += (tructure.getConsumeIndustry() != null ? tructure.getConsumeIndustry() * value : 0);
                    consumeMaterial += (tructure.getConsumeMaterial() != null ? tructure.getConsumeMaterial() * value : 0);
                    consumeNoindustry += (tructure.getConsumeNoindustry() != null ? tructure.getConsumeNoindustry() * value : 0);
                    consumeTransport += (tructure.getConsumeTransport() != null ? tructure.getConsumeTransport() * value : 0);
                    endInventory += (tructure.getEndInventory() != null ? tructure.getEndInventory() * value : 0);

                    //求合计 等价值
                    startInventory2 += (tructure.getStartInventory() != null ? tructure.getStartInventory() * equvalue : 0);
                    object2 += (tructure.getObject() != null ? tructure.getObject() * equvalue : 0);
                    money2 += tructure.getMoney() != null ? tructure.getMoney() : 0; //只有金额是累加，其他需要乘折标系数
                    consumeSum2 += (tructure.getConsumeSum() != null ? tructure.getConsumeSum() * equvalue : 0);
                    consumeIndustry2 += (tructure.getConsumeIndustry() != null ? tructure.getConsumeIndustry() * equvalue : 0);
                    consumeMaterial2 += (tructure.getConsumeMaterial() != null ? tructure.getConsumeMaterial() * equvalue : 0);
                    consumeNoindustry2 += (tructure.getConsumeNoindustry() != null ? tructure.getConsumeNoindustry() * equvalue : 0);
                    consumeTransport2 += (tructure.getConsumeTransport() != null ? tructure.getConsumeTransport() * equvalue : 0);
                    endInventory2 += (tructure.getEndInventory() != null ? tructure.getEndInventory() * equvalue : 0);

                    //折标系数异常的，采用参考折标计算，当量值
                    double temp = 0;
                    if (tructure.getRefModulus() != null) {
                        String[] refsplit = tructure.getRefModulus().split("-");
                        temp = refsplit.length > 0 ? Double.parseDouble(refsplit[0]) : 0;
                    }
                    double refvalue = value != 0 && value < 20 ? value : temp;

                    startInventory3 += (tructure.getStartInventory() != null ? tructure.getStartInventory() * refvalue : 0);
                    object3 += (tructure.getObject() != null ? tructure.getObject() * refvalue : 0);
                    money3 += tructure.getMoney() != null ? tructure.getMoney() : 0; //只有金额是累加，其他需要乘折标系数
                    consumeSum3 += (tructure.getConsumeSum() != null ? tructure.getConsumeSum() * refvalue : 0);
                    consumeIndustry3 += (tructure.getConsumeIndustry() != null ? tructure.getConsumeIndustry() * refvalue : 0);
                    consumeMaterial3 += (tructure.getConsumeMaterial() != null ? tructure.getConsumeMaterial() * refvalue : 0);
                    consumeNoindustry3 += (tructure.getConsumeNoindustry() != null ? tructure.getConsumeNoindustry() * refvalue : 0);
                    consumeTransport3 += (tructure.getConsumeTransport() != null ? tructure.getConsumeTransport() * refvalue : 0);
                    endInventory3 += (tructure.getEndInventory() != null ? tructure.getEndInventory() * refvalue : 0);
                }
            }
        }

        TReportEnergysTructure sumInfo = new TReportEnergysTructure("合计当量值", "吨标准煤", startInventory,
                object, money, consumeSum, consumeIndustry, consumeMaterial, consumeNoindustry, consumeTransport, endInventory, productionSum);
        TReportEnergysTructure sumEquInfo = new TReportEnergysTructure("合计等价值", "吨标准煤", startInventory2,
                object2, money2, consumeSum2, consumeIndustry2, consumeMaterial2, consumeNoindustry2, consumeTransport2, endInventory2, productionSum);
        TReportEnergysTructure sumRefInfo = new TReportEnergysTructure("合计当量值(参考指标系数计算)", "吨标准煤", startInventory3,
                object3, money3, consumeSum3, consumeIndustry3, consumeMaterial3, consumeNoindustry3, consumeTransport3, endInventory3, productionSum);

        TReportEnergysTructure o = tReportEnergysTructureService.getSumInfo(reportId, "合计当量值");
        if (o != null) { //有历史数据为修改
            sumInfo.setId(o.getId());
        }
        TReportEnergysTructure oEqu = tReportEnergysTructureService.getSumInfo(reportId, "合计等价值");
        if (oEqu != null) { //有历史数据为修改
            sumEquInfo.setId(oEqu.getId());
        }
        TReportEnergysTructure oRef = tReportEnergysTructureService.getSumInfo(reportId, "合计当量值(参考指标系数计算)");
        if (oRef != null) { //有历史数据为修改
            sumRefInfo.setId(oRef.getId());
        }

        List<TReportEnergysTructure> sumList = new ArrayList<>();
        sumList.add(sumInfo);
        sumList.add(sumEquInfo);
        sumList.add(sumRefInfo);

        /*Map<String, TReportEnergysTructure> map = new HashMap();
        map.put("sumInfo",sumInfo);
        map.put("sumEquInfo",sumEquInfo);*/
        return sumList;
    }

    /**
     * 进行异常波动分析
     */
    private R getEcAbnormalVolatility(TReport report, ScUser u, List<TReportEnergysTructure> tructureList) {
        //获取上年的报表信息
        String frontYear = (report.getYear() - 1) + "";
        String enterpriseCode = StringUtils.isNotEmpty(report.getEnterpriseCode()) ? report.getEnterpriseCode() : u.getEnterpriseCode();
        TReport frontReport = tReportService.getInfoByType(enterpriseCode, frontYear, "2");
        if (frontReport != null) {
            //获取上一年能源消费信息
           /* 用这个默认接口，会带上 productionSum=0.0 条件，查询结果不对
           TReportEnergysTructure front = new TReportEnergysTructure();
            front.setReportId(frontReport.getId());
            front.setDelFlag("1");
            List<TReportEnergysTructure> frontTructureList = tReportEnergysTructureService.list(Wrappers.query(front));*/
            List<TReportEnergysTructure> frontTructureList = tReportEnergysTructureService.getTructureByReportId(frontReport.getId());
            if (frontTructureList.size() > 0) { //上年数据存在，进行异常波动分析
                boolean flage = false; //波动标志默认为，false，不波动
                //取出异常波动 预警区间
                TReportPara tReportPara = new TReportPara();
                tReportPara.setType("1");
                /*List<TReportPara> paras = tReportParaService.list(Wrappers.query(tReportPara));
                for (TReportPara para : paras) {*/
                TReportPara para = tReportParaService.list(Wrappers.query(tReportPara)).get(1);
                if (para != null && (para.getUplimt() != null || para.getDownlimt() != null)) {
                    //取出本年的异常波动表
                    EcAbnormalVolatility ecAbnormalVolatility = new EcAbnormalVolatility();
                    ecAbnormalVolatility.setYear(report.getYear() + "");
                    ecAbnormalVolatility.setDelFlag("1");
                    ecAbnormalVolatility.setEpc(u.getEnterpriseCode());
                    EcAbnormalVolatility volatility = ecAbnormalVolatilityService.getOne(Wrappers.query(ecAbnormalVolatility));
                    //取出本年的异常波动详情表
                   /* EcAbnormalVolatilityInfo ecAbnormalVolatilityInfo = new EcAbnormalVolatilityInfo();
                    ecAbnormalVolatilityInfo.setAbnormalVolatilityId(volatility != null ? volatility.getId() : 0);
                    ecAbnormalVolatilityInfo.setDelFlag("1");
                    ecAbnormalVolatilityInfo.setDataTable("表2");*/
                    //进行异常波动分析
                    DecimalFormat df = new DecimalFormat(".00"); //保留两位小数
                    Map<String, Object> map = new HashMap();
                    map.put("dataTable", "表2");

                    //本年能源消费信息
                    for (TReportEnergysTructure tructure : tructureList) {
                        boolean addState = true; //新增标志默认为，true，是新增项
                        //上年能源消费信息
                        for (TReportEnergysTructure frontTructure : frontTructureList) {
                            if (tructure.getEnergyCodeName().equals(frontTructure.getEnergyCodeName())) {
                                addState = false;  //该条产品，不是新增项

                                //报表2目前只比较，能源合计的当量值
                                if ("合计当量值".equals(tructure.getEnergyCodeName())) {


                                    VolatilityTmpController.VolatilityTmp volatilityTmp = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getProductionSum(),
                                            frontTructure.getProductionSum(),
                                            //(tructure.getProductionSum() / frontTructure.getProductionSum() - 1) * 100,
                                            "工业总产值（当年价），超出波动范围。若确定数值，请填写变化情况说明！",
                                            "工业总产值（当年价）",
                                            "万元");
                                    volatilityTmp.invoke();
                                    if (volatilityTmp.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp.isFlage(); //更新超期标志

                                    //VolatilityTmpController.VolatilityTmp volatilityTmp2 = new VolatilityTmpController.VolatilityTmp(
                                    //        ecAbnormalVolatilityInfoService,
                                    //        u, flage, para, volatility, df, map,
                                    //        null,
                                    //        "表2",
                                    //        tructure.getStartInventory(),
                                    //        frontTructure.getStartInventory(),
                                    //        //(tructure.getStartInventory() / frontTructure.getStartInventory() - 1) * 100,
                                    //        "期初库存量折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                    //        "期初库存量折标量合计",
                                    //        "吨标准煤").invoke();
                                    //if (volatilityTmp2.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                    //    return R.failed(map);
                                    //}
                                    //flage = volatilityTmp2.isFlage(); //更新超期标志

                                    VolatilityTmpController.VolatilityTmp volatilityTmp3 = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getObject(),
                                            frontTructure.getObject(),
                                            //(tructure.getObject() / frontTructure.getObject() - 1) * 100,
                                            "购进量实物量折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                            "购进量实物量折标量合计",
                                            "吨标准煤").invoke();
                                    if (volatilityTmp3.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp3.isFlage(); //更新超期标志

                                    VolatilityTmpController.VolatilityTmp volatilityTmp4 = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getMoney(),
                                            frontTructure.getMoney(),
                                            //(tructure.getMoney() / frontTructure.getMoney() - 1) * 100,
                                            "购进量金额合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                            "购进量金额合计",
                                            "千元").invoke();
                                    if (volatilityTmp4.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp4.isFlage(); //更新超期标志

                                    //能源消费合计不做比较
                                    //Double consumeSum = (tructure.getConsumeSum() / frontTructure.getConsumeSum() - 1) * 100;

                                    VolatilityTmpController.VolatilityTmp volatilityTmp5 = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getConsumeIndustry(),
                                            frontTructure.getConsumeIndustry(),
                                            //(tructure.getConsumeIndustry() / frontTructure.getConsumeIndustry() - 1) * 100,
                                            "消费量工业生产消费折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                            "消费量工业生产消费折标量合计",
                                            "吨标准煤").invoke();
                                    if (volatilityTmp5.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp5.isFlage(); //更新超期标志

                                    VolatilityTmpController.VolatilityTmp volatilityTmp6 = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getConsumeMaterial(),
                                            frontTructure.getConsumeMaterial(),
                                            //(tructure.getConsumeMaterial() / frontTructure.getConsumeMaterial() - 1) * 100,
                                            "消费量用于原料材料折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                            "消费量用于原料材料折标量合计",
                                            "吨标准煤").invoke();
                                    if (volatilityTmp6.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp6.isFlage(); //更新超期标志

                                    VolatilityTmpController.VolatilityTmp volatilityTmp7 = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getConsumeNoindustry(),
                                            frontTructure.getConsumeNoindustry(),
                                            //(tructure.getConsumeNoindustry() / frontTructure.getConsumeNoindustry() - 1) * 100,
                                            "消费量非工业生产消费折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                            "消费量非工业生产消费折标量合计",
                                            "吨标准煤").invoke();
                                    if (volatilityTmp7.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp7.isFlage(); //更新超期标志

                                    VolatilityTmpController.VolatilityTmp volatilityTmp8 = new VolatilityTmpController.VolatilityTmp(
                                            ecAbnormalVolatilityInfoService,
                                            u, flage, para, volatility, df, map,
                                            null,
                                            "表2",
                                            tructure.getConsumeTransport(),
                                            frontTructure.getConsumeTransport(),
                                            //(tructure.getConsumeTransport() / frontTructure.getConsumeTransport() - 1) * 100,
                                            "消费量合计中运输工具消费折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                            "消费量合计中运输工具消费折标量合计",
                                            "吨标准煤").invoke();
                                    if (volatilityTmp8.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                        return R.failed(map);
                                    }
                                    flage = volatilityTmp8.isFlage(); //更新超期标志

                                    //VolatilityTmpController.VolatilityTmp volatilityTmp9 = new VolatilityTmpController.VolatilityTmp(
                                    //        ecAbnormalVolatilityInfoService,
                                    //        u, flage, para, volatility, df, map,
                                    //        null,
                                    //        "表2",
                                    //        tructure.getEndInventory(),
                                    //        frontTructure.getEndInventory(),
                                    //        //(tructure.getEndInventory() / frontTructure.getEndInventory() - 1) * 100,
                                    //        "期末库存量折标量合计，超出波动范围。若确定数值，请填写变化情况说明！",
                                    //        "期末库存量折标量合计",
                                    //        "吨标准煤").invoke();
                                    //if (volatilityTmp9.is()) { //超出波动范围，且未填写波动说明，返回错误信息
                                    //    return R.failed(map);
                                    //}
                                    //flage = volatilityTmp9.isFlage(); //更新超期标志

                                }

                            }
                        }

                        if (!tructure.getEnergyCodeName().contains("合计") && !tructure.getEnergyCodeName().contains("原煤")) { //不是合计值
                            //遍历完上年数据，无相同名称的能源，属于新增
                            //取出本年的异常波动详情表
                            EcAbnormalVolatilityInfo ecAbnormalVolatilityInfo = new EcAbnormalVolatilityInfo();
                            ecAbnormalVolatilityInfo.setAbnormalVolatilityId(volatility != null ? volatility.getId() : 0);
                            ecAbnormalVolatilityInfo.setDelFlag("1");
                            ecAbnormalVolatilityInfo.setDataTable("表2");
                            ecAbnormalVolatilityInfo.setDataContent(tructure.getEnergyCodeName());
                            ecAbnormalVolatilityInfo.setAddState("T");
                            EcAbnormalVolatilityInfo addVolatilityInfo = ecAbnormalVolatilityInfoService.getOne(Wrappers.query(ecAbnormalVolatilityInfo));
                            if (addState) {
                                List<String> codeList = energyInfoService.getCodeByPid();
                                boolean b = true; //需进行是否新增能源判断
                                if (codeList.size() > 0) {
                                    for (String s : codeList) {
                                        if (s.equals(tructure.getEnergyCode())) {
                                            //当前的能源信息编码与父级能源编码一致，将不进行是否为新增能源判断
                                            b = false;
                                        } else {
                                            b = true;
                                        }
                                    }
                                }
                                if (addVolatilityInfo == null && b) {
                                    map.put("msg", tructure.getEnergyCodeName() + "，属于新增能源，请填写新增情况说明！");
                                    map.put("dataContent", tructure.getEnergyCodeName());
                                    map.put("unitVal", tructure.getUnit());
                                    map.put("addState", "T");
                                    return R.failed(map);
                                }
                            } else {
                                if (addVolatilityInfo != null) {
                                    //没有新增，却有新增记录，需要删除
                                    deleteVolatilityInfo(u, addVolatilityInfo);
                                }
                            }
                        }

                        //采用折标系数值过大
                            /*if(tructure.getModulus()!=null){
                                String[] split = tructure.getModulus().split("-");
                                if(split.length>0 && 20<Integer.parseInt(split[0])){ //采用的折标系数数值过大需要填写说明
                                    map.put("msg", tructure.getEnergyCodeName() + "，采用的折标系数过大，请填写情况说明！");
                                    map.put("dataContent", tructure.getEnergyCodeName()+"(折标系数)");
                                    return R.failed(map);
                                }
                            }*/

                    }

                    //表2没有数据超出异常范围，判断是否记录了其他异常波动信息，若无主表信息需要删除
                    if (!flage && volatility != null) {
                        upVolatility(u, volatility);
                    }


                }
            }
        }
        return null;
    }

    /**
     * 没有超出波动范围，却有波动记录，需要删除波动记录
     */
    private void deleteVolatilityInfo(ScUser u, EcAbnormalVolatilityInfo volatilityInfo) {
        volatilityInfo.setDelFlag("4");
        volatilityInfo.setUserid(u.getId());
        volatilityInfo.setUpdateTime(new Date());
        boolean delete = ecAbnormalVolatilityInfoService.updateById(volatilityInfo);
    }

    /**
     * 判断是否记录了其他异常波动信息，若无主表信息需要删除
     */
    private void upVolatility(ScUser u, EcAbnormalVolatility volatility) {

        //其他报表的异常波动详情表信息
        EcAbnormalVolatilityInfo volatilityInfoOther = new EcAbnormalVolatilityInfo();
        volatilityInfoOther.setAbnormalVolatilityId(volatility != null ? volatility.getId() : 0);
        volatilityInfoOther.setDelFlag("1");
        List<EcAbnormalVolatilityInfo> volatilityInfoOtherList = ecAbnormalVolatilityInfoService.list(Wrappers.query(volatilityInfoOther));
        if (!(volatilityInfoOtherList.size() > 0)) {
            //其他报表的异常波动详情信息不存在，删除主表
            volatility.setDelFlag("4");
            volatility.setUpdateTime(new Date());
            volatility.setUserid(u.getId());
            ecAbnormalVolatilityService.updateById(volatility);
        }
    }


    /**
     * 提交报表1-2能源消费表
     */
    @PostMapping("/submit")
    @SysLog("提交报表1-2能源消费表")
    @ApiOperation(value = "提交报表1-2能源消费表", notes = "提交报表1-2能源消费表")
    @ApiImplicitParam(name = "TReport", value = "能源报表信息", required = true, dataType = "String")
    public R save(@RequestBody TReport tReport) {
        if (tReport.getYear() == null || "".equals(tReport.getYear())) {
            return R.failed("提交报表1-2能源消费表失败，年度不能为空");
        }
        ScUser u = SecurityUtils.getUser();
        //获取报表信息id
        //long reportId = tReportService.getTReportIdByType(u.getEnterpriseCode(), tReport.getYear()+"", "2", u);
        String enterpriseCode = StringUtils.isNotEmpty(tReport.getEnterpriseCode()) ? tReport.getEnterpriseCode() : u.getEnterpriseCode();
        TReport oldReport = tReportService.getInfoByType(enterpriseCode, tReport.getYear() + "", "2");
        if (oldReport == null) {
            return R.failed("请先保存能源消费表再上报！");
        }

        //获取能源消费表信息
        List<TReportEnergysTructure> tructureList = tReportEnergysTructureService.getTructureByReportId(oldReport.getId());
        if (tructureList.size() <= 0) {
            return R.failed("请先保存能源消费表再上报！");
        }

        tReport.setId(oldReport.getId());
        tReport.setUpdateTime(new Date());
        tReport.setUserid(u.getId());
        tReport.setReportStatus("3");
        tReport.setAuditStatus("1");
        tReport.setAuditStatus2("1");
        tReport.setAuditStatus3("1");
        return R.ok(tReportService.updateById(tReport));
    }


    /**
     * 保存报表1-2能源消费表
     */
    @PostMapping("/save")
    @SysLog("保存报表1-2能源消费表")
    @ApiOperation(value = "保存报表1-2能源消费表", notes = "新增报表1-2能源消费表")
    @ApiImplicitParam(name = "TReportEnergysTructure", value = "报表1-2能源消费表", required = true, dataType = "json", paramType = "path")
    public R save(@RequestBody TReportEnergysTructure tReportEnergysTructure) {
        ScUser u = SecurityUtils.getUser();
        tReportEnergysTructure.setUserid(u.getId());
        //tReportEnergysTructure.setDeptId(u.getDeptId());
        //获取企业信息
        EnterpriseInfo info = enterpriseInfoService.getInfoByCode(u.getEnterpriseCode());
        //企业端新增信息，添加deptid
        tReportEnergysTructure.setDeptId(info != null && info.getRegionCode()!=null ? Integer.parseInt(info.getRegionCode()) : u.getDeptId());
        tReportEnergysTructure.setDelFlag("1");
        tReportEnergysTructure.setUpdateTime(new Date());
        return R.ok(tReportEnergysTructureService.save(tReportEnergysTructure));
    }

    /**
     * 修改报表1-2能源消费表信息
     */
    @PutMapping
    @SysLog("修改报表1-2能源消费表信息")
    @ApiOperation(value = "修改报表1-2能源消费表信息", notes = "修改报表1-2能源消费表信息")
    @ApiImplicitParam(name = "TReportEnergysTructure", value = "报表1-2能源消费表", required = true, dataType = "json", paramType = "path")
    public R updateById(@RequestBody TReportEnergysTructure tReportEnergysTructure) {
        ScUser u = SecurityUtils.getUser();
        tReportEnergysTructure.setUserid(u.getId());
        tReportEnergysTructure.setUpdateTime(new Date());
        return R.ok(tReportEnergysTructureService.updateById(tReportEnergysTructure));
    }

    /**
     * 删除报表1-2能源消费表
     */
    @DeleteMapping("/{tReportEnergysTructureId}")
    @SysLog("删除报表1-2能源消费表")
    @ApiOperation(value = "删除报表1-2能源消费表", notes = "删除报表1-2能源消费表信息")
    @ApiImplicitParam(name = "tReportEnergysTructureId", value = "报表1-2能源消费表信息ID", required = true, dataType = "int", paramType = "path")
    public R removeById(@PathVariable("tReportEnergysTructureId") Long tReportEnergysTructureId) {
        TReportEnergysTructure tReportEnergysTructure = tReportEnergysTructureService.getById(tReportEnergysTructureId);
        if (tReportEnergysTructure == null) {
            return R.failed("报表1-2能源消费表信息不存在，删除失败！");
        }
        ScUser u = SecurityUtils.getUser();
        tReportEnergysTructure.setUserid(u.getId());
        tReportEnergysTructure.setDelFlag("4");
        tReportEnergysTructure.setUpdateTime(new Date());
        return R.ok(tReportEnergysTructureService.updateById(tReportEnergysTructure));
    }

    /**
     * 企业端预览报表1-2能源消费表
     */
    @GetMapping("/preview")
    @SysLog("企业端预览报表1-2能源消费表")
    @ApiOperation(value = "企业端预览报表1-2能源消费表", notes = "企业端预览报表1-2能源消费表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "enterpriseCode", value = "企业编码", required = false, dataType = "json", paramType = "path")
    })
    public R getByReportId(String year, String enterpriseCode) {

        if (year == null || "".equals(year)) {
            return R.failed("预览报表1-2能源消费表失败，年度不能为空");
        }
        if (StringUtils.isEmpty(enterpriseCode)) {
            enterpriseCode = SecurityUtils.getUser().getEnterpriseCode();
        }
        //企业端 flag为false
        return previewReport(year, enterpriseCode, false);

    }

    /**
     * 政府端预览报表1-2能源消费表
     */
    @GetMapping("/previewGov")
    @SysLog("政府端预览报表1-2能源消费表")
    @ApiOperation(value = "政府端预览报表1-2能源消费表", notes = "政府端预览报表1-2能源消费表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "enterpriseCode", value = "企业编码", required = false, dataType = "json", paramType = "path")
    })
    public R getByReportIdGov(String year, String enterpriseCode) {

        if (year == null || "".equals(year)) {
            return R.failed("预览报表1-2能源消费表失败，年度不能为空");
        }
        if (enterpriseCode == null || "".equals(enterpriseCode)) {
            return R.failed("预览报表1-2能源消费表失败，企业社会信用编码不能为空");
        }
        //政府端 flag为true
        return previewReport(year, enterpriseCode, true);

    }

    private R previewReport(String year, String enterpriseCode, boolean flag) {
        //获取能源报表信息
        //TReport report = tReportService.getById(reportId);
        TReport report = tReportService.getInfoByType(enterpriseCode, year, "2");
        if (report == null) {
            return R.ok();
        }

        //获取企业信息
        TReportEnterprise enterprise = tReportEnterpriseService.getEnterpriseInfo(enterpriseCode, year);

        //获取能源消费表信息
        //List<TReportEnergysTructure> tructureList = tReportEnergysTructureService.getTructureByReportId(report.getId());
        //获取完整的能源消费表信息（39项）
        List<TReportEnergysTructure> tructureList = tReportEnergysTructureService.getAllTructureByReportId(report.getId());
        //处理原煤数据
        TReportEnergysTructure rawCoal = getRawCoal(tructureList, SecurityUtils.getUser(), report.getId());
        tructureList.set(0,rawCoal);
        //获取能源消费表合计信息
        List<TReportEnergysTructure> tructureListSum = tReportEnergysTructureService.getTructureByReportIdAndName(report.getId(), "合计当量值");
        //根据报表id和名称为“合计当量值”，能获取唯一一条数据
        TReportEnergysTructure tructureSum = tructureListSum.size() > 0 ? tructureListSum.get(0) : null;
        if (tructureSum != null) {
            tructureSum.setEnergyCodeName("能源合计"); //表2 发改委格式预览，合计当量值名称为能源合计
            tructureList.add(tructureSum);
        } else {
            //工业总产值(当年价)
            double productionSum = 0;
            //从列表中获取
            for (TReportEnergysTructure tructure : tructureList) {
                if (tructure.getProductionSum() != null && tructure.getProductionSum().intValue() != 0) {
                    productionSum = tructure.getProductionSum();
                    break;
                }
            }
            //没有获取到，从财务信息获取
            if (productionSum == 0) {
                //获取当前年度财务信息
                TReportFinancial financial = tReportFinancialService.getFinancialsByReportId(report.getId());
                if (financial != null) {
                    productionSum = (financial.getIndustrialYield() != null ? financial.getIndustrialYield() : 0);
                }
            }

            //计算本年能源消费信息的能源合计值，并追加到列表尾部
            //返回集合，下标  0：sumInfo合计当量值  1：sumEquInfo合计等价值
            List<TReportEnergysTructure> sumList = getSum(tructureList, report.getId(), productionSum);
            TReportEnergysTructure tructure = (sumList.size() > 0 ? sumList.get(0) : new TReportEnergysTructure());
            tructure.setEnergyCodeName("能源合计");
            tructureList.add(tructure);
        }

        Map<String, Object> map = new HashMap();
        map.put("enterprise", enterprise);
        map.put("report", report);
        map.put("tructure", tructureList);
        //map.put("sum", tructureListSum);


        if (flag) { //政府端，要追加异常波动分析
            R<List<EcAbnormalVolatilityInfo>> volatilityInfo = volatilityInfoController.listByReport(year, enterpriseCode, "表2");
            List<EcAbnormalVolatilityInfo> volatility = new ArrayList<>();
            if (volatilityInfo != null) {
                if (volatilityInfo.getCode() == 0 && volatilityInfo.getData().size() > 0) {
                    volatility.addAll(volatilityInfo.getData());
                }
            }
            map.put("volatility", volatility);
        }


        return R.ok(map);
    }

    /**
     * 审核报表1-2能源消费表
     */
    @PostMapping("/auditor")
    @SysLog("审核报表1-2能源消费表")
    @ApiOperation(value = "审核报表1-2能源消费表", notes = "审核报表1-2能源消费表")
    @ApiImplicitParam(name = "auditorDto", value = "报表审核对象", required = true, dataType = "json", paramType = "path")
    public R updateByAuditor(@RequestBody AuditorDto auditorDto) {
        ScUser u = SecurityUtils.getUser();
        if (auditorDto.getId() == null) {
            return R.failed("报表id为空，审核报表1-2能源消费表失败！");
        }
        TReport tReport = new TReport();
        tReport.setId(auditorDto.getId());
        tReport.setUpdateTime(new Date());
        tReport.setUserid(u.getId());
        tReport.setAuditStatus(auditorDto.getAuditStatus());
        tReport.setAuditRemark(auditorDto.getAuditRemark());
        boolean b = tReportService.updateById(tReport);
        return b ? R.ok("2".equals(auditorDto.getAuditStatus()) ? "已审核" : "已退回") : R.failed("审核失败");
    }

}
