package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.busi.bu3;

import cn.estsh.i3plus.ext.mes.api.base.bu.IBusiConfigService;
import cn.estsh.i3plus.ext.mes.api.base.bu3.ISxCareerCorrelationCfgService;
import cn.estsh.i3plus.ext.mes.api.base.bu3.ISxPartCategoryPlanRateService;
import cn.estsh.i3plus.ext.mes.api.base.bu3.ISxPartCategoryTargetCfgService;
import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxEnergyCompositeRatePassAnalysisService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.IPartExtDao;
import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.*;
import cn.estsh.i3plus.ext.mes.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class SxEnergyCompositeRatePassAnalysisService implements ISxEnergyCompositeRatePassAnalysisService {

    @Autowired
    private IBusiConfigService busiConfigService;

    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;

    @Autowired
    private IPartExtDao partExtDao;

    @Autowired
    private MesShiftProdCenterRecordRepository shiftProdCenterRecordRepository;

    @Autowired
    private MesProdDataToStatisticsShiftProdRepository prodDataToStatisticsShiftProdRepository;

    @Autowired
    private MesOutPutStatisticsRepository outPutStatisticsRepository;

    @Autowired
    private MesProdDataToStatisticsOutPutRepository prodDataToStatisticsOutPutRepository;

    @Autowired
    private ISxPartCategoryTargetCfgService partCategoryTargetCfgService;

    @Autowired
    private ISxPartCategoryPlanRateService partCategoryPlanRateService;

    @Autowired
    private ISxCareerCorrelationCfgService careerCorrelationCfgService;

    @Override
    public SxEnergyCompositeRatePassAnalysisModel queryEnergyCompositeRatePassAnalysis(SxEnergyCompositeRatePassAnalysisModel data) {

        sxYearFlag(data);

        data.careerCodeList(handleMultipleChoice(data.getCareerCodeArr())).categoryCodeList(handleMultipleChoice(data.getCategoryCodeArr()));

        Map<String, String> dateMap = getDateMap(data);

        calcYmdTime(data, dateMap);

        calcQueryTime(data);

        List<MesWorkCenterExt> workCenterExtList = getWorkCenterExtList(data);

        Map<String, MesWorkCenterExt> centerMap = getCenterMap(filterWorkCenter(workCenterExtList, data.getWorkCenterCodeArr()));

        List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList = getRecordStatisticsList(data, centerMap, dateMap);

        List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList = getOutPutStatisticsList(data, centerMap, dateMap);

        if (CollectionUtils.isEmpty(recordStatisticsList) && CollectionUtils.isEmpty(outPutStatisticsList)) return data;

        if (MesExtConstWords.ZERO == data.getFlag() || CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == data.getFlag())
            handleUpPartData(data, dateMap, workCenterExtList, recordStatisticsList, outPutStatisticsList);

        if (MesExtConstWords.ZERO == data.getFlag() || CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() == data.getFlag())
            handleDownPartData(data, dateMap, recordStatisticsList, outPutStatisticsList);

        return data;
    }

    private void sxYearFlag(SxEChartsReportCommonDataModel data) {
        MesBusiConfig busiConfig = busiConfigService.getBusiConfigByCfgCode(data.getOrganizeCode(), MesExtConstWords.SX_REPORT_IS_PANASONIC_YEAR);
        if (null != busiConfig) data.setSxYearFlag(true);
    }

    private void calcYmdTime(SxEChartsReportCommonDataModel data, Map<String, String> dateMap) {

        switch (DIMENSION.getByCode(data.getDimension())) {
            case YEAR:
                if (!data.getSxYearFlag()) {
                    data.setYmdStart(data.getWorkTimeStart() + MesExtConstWords.DATE_MM_DD_01_01);
                    data.setYmdEnd(data.getWorkTimeEnd() + MesExtConstWords.DATE_MM_DD_12_31);
                } else {
                    data.setYmdStart(data.getWorkTimeStart() + MesExtConstWords.DATE_MM_DD_04_01);
                    data.setYmdEnd(Integer.valueOf(data.getWorkTimeEnd()) + 1 + MesExtConstWords.DATE_MM_DD_03_31);
                }
                break;
            case SEASON:
                data.setYmdStart(dateMap.get(data.getWorkTimeStart()).split(MesExtConstWords.AND)[0]);
                data.setYmdEnd(dateMap.get(data.getWorkTimeEnd()).split(MesExtConstWords.AND)[1]);
                break;
            case MONTH:
                data.setYmdStart(data.getWorkTimeStart() + MesExtConstWords.DATE_DD_01);
                data.setYmdEnd(getMonthLastDay(data.getWorkTimeEnd()));
                break;
            default:
                data.setYmdStart(data.getWorkTimeStart());
                data.setYmdEnd(data.getWorkTimeEnd());
                break;
        }

    }

    private String getMonthLastDay(String month) {
        return TimeTool.timeCalc(
                TimeTool.stringParseToDate(
                        (TimeTool.timeCalc(TimeTool.stringParseToDate(month, MesExtConstWords.DATE_FORMAT_YM), Calendar.MONTH, 1, MesExtConstWords.DATE_FORMAT_YM) + MesExtConstWords.DATE_DD_01),
                        MesExtConstWords.DATE_FORMAT),
                Calendar.DATE, -1, MesExtConstWords.DATE_FORMAT);
    }

    private void calcQueryTime(SxEChartsReportCommonDataModel data) {
        String curMonth = TimeTool.getToday().substring(0, 7);
        String curMonthBegin = curMonth + MesExtConstWords.DATE_DD_01;

        switch (DIMENSION.getByCode(data.getDimension())) {
            case YEAR:
            case SEASON:
            case MONTH:
                if (curMonthBegin.compareTo(data.getYmdStart()) <= 0) {
                    data.setWorkTimeYmdStart(data.getYmdStart());
                    data.setWorkTimeYmdEnd(data.getYmdEnd());
                } else if (curMonthBegin.compareTo(data.getYmdEnd()) > 0) {
                    data.setStatisticsYmStart(data.getYmdStart().substring(0, 7));
                    data.setStatisticsYmEnd(data.getYmdEnd().substring(0, 7));
                } else {
                    data.setStatisticsYmStart(data.getYmdStart().substring(0, 7));
                    data.setStatisticsYmEnd(TimeTool.timeCalc(TimeTool.stringParseToDate(curMonth, MesExtConstWords.DATE_FORMAT_YM), Calendar.MONTH, -1, MesExtConstWords.DATE_FORMAT_YM));
                    data.setWorkTimeYmdStart(curMonthBegin);
                    data.setWorkTimeYmdEnd(data.getYmdEnd());
                }
                break;
            default:
                if (curMonthBegin.compareTo(data.getYmdStart()) <= 0) {
                    data.setWorkTimeYmdStart(data.getYmdStart());
                    data.setWorkTimeYmdEnd(data.getYmdEnd());
                } else if (curMonthBegin.compareTo(data.getYmdEnd()) > 0) {
                    data.setStatisticsYmdStart(data.getYmdStart());
                    data.setStatisticsYmdEnd(data.getYmdEnd());
                } else {
                    data.setStatisticsYmdStart(data.getYmdStart());
                    data.setStatisticsYmdEnd(TimeTool.timeCalc(TimeTool.stringParseToDate(curMonthBegin, MesExtConstWords.DATE_FORMAT), Calendar.DATE, -1, MesExtConstWords.DATE_FORMAT));
                    data.setWorkTimeYmdStart(curMonthBegin);
                    data.setWorkTimeYmdEnd(data.getYmdEnd());
                }
                break;
        }
    }

    private List<MesWorkCenterExt> filterWorkCenter(List<MesWorkCenterExt> workCenterExtList, String workCenterCodeArr) {
        if (StringUtils.isEmpty(workCenterCodeArr)) return workCenterExtList;
        List<String> workCenterCodeList = handleMultipleChoice(workCenterCodeArr);
        return workCenterExtList.stream().filter(o -> (null != o && workCenterCodeList.contains(o.getWorkCenterCode()))).collect(Collectors.toList());
    }

    private List<MesWorkCenterExt> getWorkCenterExtList(SxEChartsReportCommonDataModel data) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(data.getIsDont(), MesExtConstWords.IS_DONT, packBean);
        DdlPreparedPack.getStringEqualPack(data.getDontClass(), MesExtConstWords.DONT_CLASS, packBean);
        return workCenterExtRepository.findByHqlWhere(packBean);
    }

    private Map<String, MesWorkCenterExt> getCenterMap(List<MesWorkCenterExt> workCenterExtList) {
        return CollectionUtils.isEmpty(workCenterExtList) ? null :
                workCenterExtList.stream().filter(o -> null != o).collect(Collectors.toMap(MesWorkCenterExt::getWorkCenterCode, o -> o));
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getRecordStatisticsList(SxEnergyCompositeRatePassAnalysisModel data, Map<String, MesWorkCenterExt> centerMap, Map<String, String> dateMap) {
        List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList = new ArrayList<>();
        if (!StringUtils.isEmpty(data.getWorkTimeYmdStart())) {
            List<SxShiftProdCenterRecordStatisticsModel> resultList = getShiftProdCenterRecordList(data, data.getWorkTimeYmdStart(), data.getWorkTimeYmdEnd(), centerMap, dateMap);
            if (!CollectionUtils.isEmpty(resultList)) recordStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmStart())) {
            List<SxShiftProdCenterRecordStatisticsModel> resultList = getShiftProdCenterRecordStatisticsList(data, data.getStatisticsYmStart(), data.getStatisticsYmEnd(), centerMap, dateMap);
            if (!CollectionUtils.isEmpty(resultList)) recordStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmdStart())) {
            List<SxShiftProdCenterRecordStatisticsModel> resultList = getShiftProdCenterRecordStatisticsList(data, data.getStatisticsYmdStart(), data.getStatisticsYmdEnd(), centerMap, dateMap);
            if (!CollectionUtils.isEmpty(resultList)) recordStatisticsList.addAll(resultList);
        }
        recordStatisticsList = CollectionUtils.isEmpty(recordStatisticsList) ? recordStatisticsList :
                recordStatisticsList.stream().filter(o -> (null != o && centerMap.containsKey(o.getWorkCenterCode()))).collect(Collectors.toList());
        recordStatisticsList = (CollectionUtils.isEmpty(data.getCareerCodeList()) || CollectionUtils.isEmpty(recordStatisticsList)) ? recordStatisticsList :
                recordStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()) && data.getCareerCodeList().contains(o.getCareerCode()))).collect(Collectors.toList());
        recordStatisticsList = (CollectionUtils.isEmpty(data.getCategoryCodeList()) || CollectionUtils.isEmpty(recordStatisticsList)) ? recordStatisticsList :
                recordStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCategoryCode()) && data.getCategoryCodeList().contains(o.getCategoryCode()))).collect(Collectors.toList());
        return recordStatisticsList;
    }

    private List<SxProdDataToStatisticsOutPutModel> getOutPutStatisticsList(SxEnergyCompositeRatePassAnalysisModel data, Map<String, MesWorkCenterExt> centerMap, Map<String, String> dateMap) {
        List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList = new ArrayList<>();
        if (!StringUtils.isEmpty(data.getWorkTimeYmdStart())) {
            List<SxProdDataToStatisticsOutPutModel> resultList = getOutPutStatisticsRecordList(data, data.getWorkTimeYmdStart(), data.getWorkTimeYmdEnd(), centerMap, dateMap);
            if (!CollectionUtils.isEmpty(resultList)) outPutStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmStart())) {
            List<SxProdDataToStatisticsOutPutModel> resultList = getProdDataOutPutStatisticsList(data, data.getStatisticsYmStart(), data.getStatisticsYmEnd(), centerMap, dateMap);
            if (!CollectionUtils.isEmpty(resultList)) outPutStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmdStart())) {
            List<SxProdDataToStatisticsOutPutModel> resultList = getProdDataOutPutStatisticsList(data, data.getStatisticsYmdStart(), data.getStatisticsYmdEnd(), centerMap, dateMap);
            if (!CollectionUtils.isEmpty(resultList)) outPutStatisticsList.addAll(resultList);
        }
        outPutStatisticsList = CollectionUtils.isEmpty(outPutStatisticsList) ? outPutStatisticsList :
                outPutStatisticsList.stream().filter(o -> (null != o && centerMap.containsKey(o.getWorkCenterCode()))).collect(Collectors.toList());
        outPutStatisticsList = (CollectionUtils.isEmpty(data.getCareerCodeList()) || CollectionUtils.isEmpty(outPutStatisticsList)) ? outPutStatisticsList :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()) && data.getCareerCodeList().contains(o.getCareerCode()))).collect(Collectors.toList());
        outPutStatisticsList = (CollectionUtils.isEmpty(data.getCategoryCodeList()) || CollectionUtils.isEmpty(outPutStatisticsList)) ? outPutStatisticsList :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCategoryCode()) && data.getCategoryCodeList().contains(o.getCategoryCode()))).collect(Collectors.toList());
        return outPutStatisticsList;
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getShiftProdCenterRecordList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd,
                                                                                      Map<String, MesWorkCenterExt> centerMap, Map<String, String> dateMap) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(data.getShiftCode(), MesExtConstWords.SHIFT_CODE, packBean);
        DdlPreparedPack.timeBuilder(workTimeStart, workTimeEnd, MesExtConstWords.WORK_TIME, packBean, false);
        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = shiftProdCenterRecordRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(shiftProdCenterRecordList)) return null;
        List<SxShiftProdCenterRecordStatisticsModel> resultList = new ArrayList<>();
        for (MesShiftProdCenterRecord item : shiftProdCenterRecordList) {
            if (null == item || StringUtils.isEmpty(item.getProdType())) continue;
            SxShiftProdCenterRecordStatisticsModel result = new SxShiftProdCenterRecordStatisticsModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(getGroupInfo(data, result.getWorkTime(), dateMap));
            result.setIsDont(getIsDont(centerMap, result.getWorkCenterCode()));
            try {
                result.setStatistics(MathOperation.mul(new Double(TimeTool.getSecoundsBetweenTime(2, item.getStartTime(), item.getEndTime())), item.getWorkerQty()));
            } catch (ParseException e) {
                result.setStatistics(new Double(0));
            }
            resultList.add(result);
        }
        return resultList;
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getShiftProdCenterRecordStatisticsList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd,
                                                                                                Map<String, MesWorkCenterExt> centerMap, Map<String, String> dateMap) {
        DdlPackBean packBean = getRecordStatisticsPackBeanByType(data, workTimeStart, workTimeEnd);
        List<MesProdDataToStatisticsShiftProd> prodDataToStatisticsShiftProdList = prodDataToStatisticsShiftProdRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(prodDataToStatisticsShiftProdList)) return null;
        List<SxShiftProdCenterRecordStatisticsModel> resultList = new ArrayList<>();
        for (MesProdDataToStatisticsShiftProd item : prodDataToStatisticsShiftProdList) {
            if (null == item || StringUtils.isEmpty(item.getProdType())) continue;
            SxShiftProdCenterRecordStatisticsModel result = new SxShiftProdCenterRecordStatisticsModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(getGroupInfo(data, result.getWorkTime(), dateMap));
            result.setIsDont(getIsDont(centerMap, result.getWorkCenterCode()));
            resultList.add(result);
        }
        return resultList;
    }

    private List<SxProdDataToStatisticsOutPutModel> getOutPutStatisticsRecordList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd,
                                                                                  Map<String, MesWorkCenterExt> centerMap, Map<String, String> dateMap) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(data.getShiftCode(), MesExtConstWords.SHIFT_CODE, packBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue(), MesExtConstWords.WORK_ORDER_TYPE, packBean);
        DdlPreparedPack.timeBuilder(workTimeStart, workTimeEnd, MesExtConstWords.WORK_TIME, packBean, false);
        List<MesOutPutStatistics> outPutStatisticsList = outPutStatisticsRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(outPutStatisticsList)) return null;

        Map<String, Double> partStandardWorkMap = partExtDao.queryPartExtStandardWorkMap(data.getOrganizeCode());

        List<SxProdDataToStatisticsOutPutModel> resultList = new ArrayList<>();
        for (MesOutPutStatistics item : outPutStatisticsList) {
            if (null == item) continue;
            SxProdDataToStatisticsOutPutModel result = new SxProdDataToStatisticsOutPutModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(getGroupInfo(data, result.getWorkTime(), dateMap));
            result.setIsDont(getIsDont(centerMap, result.getWorkCenterCode()));
            result.setStandardWork((!CollectionUtils.isEmpty(partStandardWorkMap) && partStandardWorkMap.containsKey(result.getPartNo())) ? partStandardWorkMap.get(result.getPartNo()) : new Double(0));
            result.setStatistics(MathOperation.mul(getUnRemakeQty(item.getQty(), item.getRemakeQty()), result.getStandardWork()));
            resultList.add(result);
        }
        return resultList;
    }

    private Double getUnRemakeQty(Double qty, Double remakeQty) {
        if (StringUtils.isEmpty(remakeQty) || MathOperation.compareTo(remakeQty, new Double(0)) == 0) return qty;
        return MathOperation.sub(qty, remakeQty);
    }

    private List<SxProdDataToStatisticsOutPutModel> getProdDataOutPutStatisticsList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd,
                                                                                    Map<String, MesWorkCenterExt> centerMap, Map<String, String> dateMap) {
        DdlPackBean packBean = getOutPutStatisticsPackBeanByType(data, workTimeStart, workTimeEnd);
        List<MesProdDataToStatisticsOutPut> prodDataToStatisticsOutPutList = prodDataToStatisticsOutPutRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(prodDataToStatisticsOutPutList)) return null;
        List<SxProdDataToStatisticsOutPutModel> resultList = new ArrayList<>();
        for (MesProdDataToStatisticsOutPut item : prodDataToStatisticsOutPutList) {
            if (null == item) continue;
            SxProdDataToStatisticsOutPutModel result = new SxProdDataToStatisticsOutPutModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(getGroupInfo(data, result.getWorkTime(), dateMap));
            result.setIsDont(getIsDont(centerMap, result.getWorkCenterCode()));
            resultList.add(result);
        }
        return resultList;
    }

    private DdlPackBean getRecordStatisticsPackBeanByType(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = getStatisticsPackBeanByType(data, workTimeStart, workTimeEnd);
        if (workTimeStart.length() == 7) {
            DdlPreparedPack.getStringEqualPack(MesExtConstWords.MONTH, MesExtConstWords.DATA_TYPE, packBean);
            DdlPreparedPack.getStringEqualPack(MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.SHIFT_PROD_MONTH_KEY.getValue(), MesExtConstWords.DATA_KEY, packBean);
        } else {
            DdlPreparedPack.getStringEqualPack(MesExtConstWords.DAY, MesExtConstWords.DATA_TYPE, packBean);
            DdlPreparedPack.getStringEqualPack(MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.SHIFT_PROD_DAY_KEY.getValue(), MesExtConstWords.DATA_KEY, packBean);
        }
        return packBean;
    }

    private DdlPackBean getOutPutStatisticsPackBeanByType(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = getStatisticsPackBeanByType(data, workTimeStart, workTimeEnd);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue(), MesExtConstWords.WORK_ORDER_TYPE, packBean);
        if (workTimeStart.length() == 7) {
            DdlPreparedPack.getStringEqualPack(MesExtConstWords.MONTH, MesExtConstWords.DATA_TYPE, packBean);
            DdlPreparedPack.getStringEqualPack(MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.OUT_PUT_MONTH_KEY1.getValue(), MesExtConstWords.DATA_KEY, packBean);
        } else {
            DdlPreparedPack.getStringEqualPack(MesExtConstWords.DAY, MesExtConstWords.DATA_TYPE, packBean);
            DdlPreparedPack.getStringEqualPack(MesExtEnumUtil.JOB_STATISTICS_PROD_DATA_KEY.OUT_PUT_DAY_KEY1.getValue(), MesExtConstWords.DATA_KEY, packBean);
        }
        return packBean;
    }

    private DdlPackBean getStatisticsPackBeanByType(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(data.getShiftCode(), MesExtConstWords.SHIFT_CODE, packBean);
        DdlPreparedPack.timeBuilder(workTimeStart, workTimeEnd, MesExtConstWords.WORK_TIME, packBean, false);
        return packBean;
    }

    private String getGroupInfo(SxEChartsReportCommonDataModel data, String workTime, Map<String, String> dateMap) {
        switch (DIMENSION.getByCode(data.getDimension())) {
            case YEAR:
                String year = workTime.substring(0, 4);
                if (!data.getSxYearFlag()) return year;
                else {
                    if (workTime.compareTo(year + MesExtConstWords.DATE_MM_DD_03_31) > 0) return year;
                    else return String.valueOf(Integer.valueOf(year) - 1);
                }
            case SEASON:
                return dateMap.get(workTime.substring(0, 7));
            case MONTH:
                return workTime.substring(0, 7);
            case WEEK:
                return dateMap.get(workTime);
            default:
                return workTime;
        }
    }

    private String getIsDont(Map<String, MesWorkCenterExt> centerMap, String workCenterCode) {
        if (!CollectionUtils.isEmpty(centerMap) && centerMap.containsKey(workCenterCode)) {
            MesWorkCenterExt workCenterExt = centerMap.get(workCenterCode);
            return workCenterExt.getIsDont();
        }
        return null;
    }

    private void handleUpPartData(SxEnergyCompositeRatePassAnalysisModel data, Map<String, String> dateMap, List<MesWorkCenterExt> workCenterExtList,
                                  List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList, List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList) {

        handleHeadData(data, recordStatisticsList, outPutStatisticsList);

        Map<String, List<SxShiftProdCenterRecordStatisticsModel>> recordStatisticsListMapByIsDont = getRecordStatisticsListMapByIsDont(recordStatisticsList);
        Map<String, List<SxProdDataToStatisticsOutPutModel>> outPutStatisticsListMapByIsDont = getOutPutStatisticsListMapByIsDont(outPutStatisticsList);

        Map<String, Double> standardTimeMap = getStandardTimeMap(outPutStatisticsListMapByIsDont);
        Map<String, String> shiftProdStatisticsMap = getShiftProdStatisticsMap(recordStatisticsListMapByIsDont);

        List<String> keyList = getKeyList4UpPart(workCenterExtList);

        handleDataByPartFlag(data, dateMap, keyList, standardTimeMap, shiftProdStatisticsMap, true);

        data.sortReversedMoreList();

    }

    private void handleDownPartData(SxEnergyCompositeRatePassAnalysisModel data, Map<String, String> dateMap,
                                    List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList, List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList) {
        Map<String, List<SxShiftProdCenterRecordStatisticsModel>> recordStatisticsListMapByTime = getRecordStatisticsListMapByTime(recordStatisticsList);
        Map<String, List<SxProdDataToStatisticsOutPutModel>> outPutStatisticsListMapByTime = getOutPutStatisticsListMapByTime(outPutStatisticsList);

        Map<String, Double> standardTimeMap = getStandardTimeMap(outPutStatisticsListMapByTime);
        Map<String, String> shiftProdStatisticsMap = getShiftProdStatisticsMap(recordStatisticsListMapByTime);

        List<String> keyList = getKeyList4Date(data, dateMap);

        handleDataByPartFlag(data, dateMap, keyList, standardTimeMap, shiftProdStatisticsMap, false);
    }

    private void handleHeadData(SxEnergyCompositeRatePassAnalysisModel data, List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList, List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList) {
        Double standardTime = getOutPutDataListStatistics(outPutStatisticsList);
        Double serviceTime = getShiftProdDataListStatistics(getShiftProdDataListByFlag(recordStatisticsList, true));
        Double nonWorkingTime = getShiftProdDataListStatistics(getShiftProdDataListByFlag(recordStatisticsList, false));
        Double workingTime = MathOperation.sub(serviceTime, nonWorkingTime);

        data.addHeadData("综合能率", getBigDecimalPercent(divThenMul100Format2RoundHalfUp(standardTime, serviceTime)))
                .addHeadData("作业能率", getBigDecimalPercent(divThenMul100Format2RoundHalfUp(standardTime, workingTime)))
                .addHeadData("稼动率", getBigDecimalPercent(divThenMul100Format2RoundHalfUp(workingTime, serviceTime)))
                .addHeadData("非作业率", getBigDecimalPercent(divThenMul100Format2RoundHalfUp(nonWorkingTime, serviceTime)));
    }

    private void handleDataByPartFlag(SxEnergyCompositeRatePassAnalysisModel data, Map<String, String> dateMap, List<String> keyList,
                                      Map<String, Double> standardTimeMap, Map<String, String> shiftProdStatisticsMap, Boolean partFlag) {

        Map<String, List<MesCareerCorrelationCfg>> targetCfgMap = null;
        String categoryCode = (!CollectionUtils.isEmpty(data.getCategoryCodeList()) && data.getCategoryCodeList().size() == 1) ? data.getCategoryCodeList().get(0) : null;
        if (!partFlag && !StringUtils.isEmpty(categoryCode)) targetCfgMap = getTargetCfgMap(data.getOrganizeCode(), categoryCode);

        for (String key : keyList) {
            Double standardTime = (!CollectionUtils.isEmpty(standardTimeMap) && standardTimeMap.containsKey(key)) ? standardTimeMap.get(key) : new Double(0);
            String statisticsData = (!CollectionUtils.isEmpty(shiftProdStatisticsMap) && shiftProdStatisticsMap.containsKey(key)) ?
                    shiftProdStatisticsMap.get(key) : new StringJoiner(MesExtConstWords.AND).add(MesExtConstWords.ZERO_STR).add(MesExtConstWords.ZERO_STR).add(MesExtConstWords.ZERO_STR).toString();
            String[] statisticsDataArr = statisticsData.split(MesExtConstWords.AND);
            Double serviceTime = new Double(statisticsDataArr[0]);
            Double nonWorkingTime = new Double(statisticsDataArr[1]);
            Double workingTime = new Double(statisticsDataArr[2]);

            if (partFlag)
                data.addCompositeList(key, divThenMul100Format2RoundHalfUp(standardTime, serviceTime))
                        .addStList(key, divThenMul100Format2RoundHalfUp(standardTime, workingTime))
                        .addUtilizationList(key, divThenMul100Format2RoundHalfUp(workingTime, serviceTime))
                        .addNonWorkingList(key, divThenMul100Format2RoundHalfUp(nonWorkingTime, serviceTime));
            else
                data.addDataList(
                        getItemKey(data.getDimension(), key),
                        MathOperation.div(workingTime, 1000),
                        MathOperation.div(nonWorkingTime, 1000),
                        divThenMul100Format2RoundHalfUp(standardTime, serviceTime),
                        divThenMul100Format2RoundHalfUp(standardTime, workingTime),
                        getTargetData(data, categoryCode, targetCfgMap, key, dateMap, true),
                        getTargetData(data, categoryCode, targetCfgMap, key, dateMap, false)
                ).dataUnit(DIMENSION.codeOfDescription(data.getDimension()));
        }
    }

    private List<String> getKeyList4UpPart(List<MesWorkCenterExt> workCenterExtList) {
        List<String> isDontList = CollectionUtils.isEmpty(workCenterExtList) ? null :
                workCenterExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsDont()))).map(MesWorkCenterExt::getIsDont).collect(Collectors.toList());
        isDontList = CollectionUtils.isEmpty(isDontList) ? null : isDontList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(isDontList)) Collections.sort(isDontList);
        return isDontList;
    }

    private List<String> getKeyList4Date(SxEChartsReportCommonDataModel data, Map<String, String> dateMap) {
        List<String> keyList = new ArrayList<>();
        switch (DIMENSION.getByCode(data.getDimension())) {
            case YEAR:
                for (int i = Integer.valueOf(data.getWorkTimeStart()); i <= Integer.valueOf(data.getWorkTimeEnd()); i ++) {
                    keyList.add(String.valueOf(i));
                }
                break;
            case SEASON:
                for (int i = Integer.valueOf(data.getWorkTimeStart().substring(0, 1)); i <= Integer.valueOf(data.getWorkTimeEnd().substring(0, 1)); i ++) {
                    keyList.add(i + "Q");
                }
                break;
            case MONTH:
                String startMonth = data.getWorkTimeStart();
                for (int i = 1; i <= 12; i ++) {
                    keyList.add(startMonth);
                    startMonth = TimeTool.timeCalc(TimeTool.stringParseToDate(startMonth, MesExtConstWords.DATE_FORMAT_YM), Calendar.MONTH, 1, MesExtConstWords.DATE_FORMAT_YM);
                    if (startMonth.compareTo(data.getWorkTimeEnd()) > 0) break;
                }
                break;
            case WEEK:
                for (int i = 1; i <= Integer.valueOf(dateMap.get(MesExtConstWords.WEEK_COUNT)); i ++) {
                    keyList.add(String.valueOf(i));
                }
                break;
            default:
                String startTime = data.getWorkTimeStart();
                for (int i = 1; i <= 31; i ++) {
                    keyList.add(startTime);
                    startTime = TimeTool.timeCalc(TimeTool.stringParseToDate(startTime, MesExtConstWords.DATE_FORMAT), Calendar.DATE, 1, MesExtConstWords.DATE_FORMAT);
                    if (startTime.compareTo(data.getWorkTimeEnd()) > 0) break;
                }
                break;
        }
        return keyList;
    }

    private String getItemKey(Integer dimension, String key) {
        switch (DIMENSION.getByCode(dimension)) {
            case YEAR:
            case SEASON:
            case WEEK:
                return key;
            case MONTH:
                return Integer.valueOf(key.substring(5, 7)).toString();
            default:
                return Integer.valueOf(key.substring(8, 10)).toString();
        }
    }

    private Double getOutPutDataListStatistics(List<SxProdDataToStatisticsOutPutModel> dataList) {
        return CollectionUtils.isEmpty(dataList) ? new Double(0) :
                dataList.stream().filter(o -> null != o).mapToDouble(SxProdDataToStatisticsOutPutModel::getStatistics).sum();
    }

    private Double getShiftProdDataListStatistics(List<SxShiftProdCenterRecordStatisticsModel> dataList) {
        return CollectionUtils.isEmpty(dataList) ? new Double(0) :
                dataList.stream().filter(o -> null != o).mapToDouble(SxShiftProdCenterRecordStatisticsModel::getStatistics).sum();
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getShiftProdDataListByFlag(List<SxShiftProdCenterRecordStatisticsModel> dataList, Boolean flag) {
        if (CollectionUtils.isEmpty(dataList)) return null;
        if (!flag) return dataList.stream().filter(o -> (null != o && (
                MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_STOP_CENTER.getValue() == o.getProdType() || MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue() == o.getProdType()
        ))).collect(Collectors.toList());
        else return dataList.stream().filter(o -> (null != o && (
                MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_PROD.getValue() == o.getProdType() || MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_PROD.getValue() == o.getProdType()
        ))).collect(Collectors.toList());
    }

    private Map<String, List<SxShiftProdCenterRecordStatisticsModel>> getRecordStatisticsListMapByIsDont(List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList) {
        return CollectionUtils.isEmpty(recordStatisticsList) ? null :
                recordStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsDont()))).collect(Collectors.groupingBy(SxShiftProdCenterRecordStatisticsModel::getIsDont));
    }

    private Map<String, List<SxProdDataToStatisticsOutPutModel>> getOutPutStatisticsListMapByIsDont(List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList) {
        return CollectionUtils.isEmpty(outPutStatisticsList) ? null :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsDont()))).collect(Collectors.groupingBy(SxProdDataToStatisticsOutPutModel::getIsDont));
    }

    private Map<String, List<SxShiftProdCenterRecordStatisticsModel>> getRecordStatisticsListMapByTime(List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList) {
        return CollectionUtils.isEmpty(recordStatisticsList) ? null :
                recordStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getGroupInfo()))).collect(Collectors.groupingBy(SxShiftProdCenterRecordStatisticsModel::getGroupInfo));
    }

    private Map<String, List<SxProdDataToStatisticsOutPutModel>> getOutPutStatisticsListMapByTime(List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList) {
        return CollectionUtils.isEmpty(outPutStatisticsList) ? null :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getGroupInfo()))).collect(Collectors.groupingBy(SxProdDataToStatisticsOutPutModel::getGroupInfo));
    }

    private Map<String, Double> getStandardTimeMap(Map<String, List<SxProdDataToStatisticsOutPutModel>> outPutStatisticsListMap) {
        if (CollectionUtils.isEmpty(outPutStatisticsListMap)) return null;
        Map<String, Double> standardTimeMap = new HashMap<>();
        for (Map.Entry<String, List<SxProdDataToStatisticsOutPutModel>> entry : outPutStatisticsListMap.entrySet()) {
            if (null == entry) continue;
            standardTimeMap.put(entry.getKey(), getOutPutDataListStatistics(entry.getValue()));
        }
        return standardTimeMap;
    }

    private Map<String, String> getShiftProdStatisticsMap(Map<String, List<SxShiftProdCenterRecordStatisticsModel>> recordStatisticsListMap) {
        if (CollectionUtils.isEmpty(recordStatisticsListMap)) return null;
        Map<String, String> shiftProdStatisticsMap = new HashMap<>();
        for (Map.Entry<String, List<SxShiftProdCenterRecordStatisticsModel>> entry : recordStatisticsListMap.entrySet()) {
            if (null == entry) continue;
            Double serviceTime = getShiftProdDataListStatistics(getShiftProdDataListByFlag(entry.getValue(), true));
            Double nonWorkingTime = getShiftProdDataListStatistics(getShiftProdDataListByFlag(entry.getValue(), false));
            shiftProdStatisticsMap.put(entry.getKey(), new StringJoiner(MesExtConstWords.AND)
                    .add(serviceTime.toString()).add(nonWorkingTime.toString()).add(String.valueOf(MathOperation.sub(serviceTime, nonWorkingTime))).toString());
        }
        return shiftProdStatisticsMap;
    }

    private Map<String, List<MesCareerCorrelationCfg>> getTargetCfgMap(String organizeCode, String categoryCode) {
        List<MesCareerCorrelationCfg> TargetCfgList = careerCorrelationCfgService.getCareerCorrelationCfgListByCategoryCode(organizeCode, MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_DIMENSION.CATEGORY.getValue(), MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_TYPE.COMPOSITE_RATE_TARGET.getValue() ,categoryCode);
        return CollectionUtils.isEmpty(TargetCfgList) ? null :
                TargetCfgList.stream().filter(o -> null != o && o.splitValue() != null).collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getCategoryCode()).add(o.getDataKey()).toString()));
    }

    private BigDecimal getTargetData(SxEnergyCompositeRatePassAnalysisModel data, String categoryCode, Map<String, List<MesCareerCorrelationCfg>> targetCfgMap, String key, Map<String, String> dateMap, Boolean dataFlag) {
        if (StringUtils.isEmpty(categoryCode)) return format2RoundHalfUp(new Double(0));
        return format2RoundHalfUp(mul100(getTargetDataByDimension(data, categoryCode, targetCfgMap, key, dateMap, dataFlag)));
    }

    private Double getTargetDataByDimension(SxEnergyCompositeRatePassAnalysisModel data, String categoryCode, Map<String, List<MesCareerCorrelationCfg>> targetCfgMap, String key, Map<String, String> dateMap, Boolean dataFlag) {
        if (data.getDimension() == DIMENSION.YEAR.getCode()) return getTargetData(targetCfgMap, dataFlag, new StringJoiner(MesExtConstWords.AND).add(categoryCode).add(key).toString());
        if (data.getDimension() == DIMENSION.SEASON.getCode()) return getTargetData(targetCfgMap, dataFlag, new StringJoiner(MesExtConstWords.AND).add(categoryCode).add(data.getYear().toString()).toString());
        if (data.getDimension() == DIMENSION.WEEK.getCode()) return getTargetData(targetCfgMap, dataFlag, new StringJoiner(MesExtConstWords.AND).add(categoryCode).add(getYearByFlag(data.getSxYearFlag(), dateMap.get(MesExtConstWords.WEEK_COUNT + key))).toString());
        return getTargetData(targetCfgMap, dataFlag, new StringJoiner(MesExtConstWords.AND).add(categoryCode).add(getYearByFlag(data.getSxYearFlag(), key)).toString());
    }

    private String getYearByFlag(Boolean sxYearFlag, String date) {
        String year = date.substring(0, 4);
        if (!sxYearFlag) return year;
        String time = year + (date.length() == 7 ? "-04" : MesExtConstWords.DATE_MM_DD_04_01);
        if (date.compareTo(time) < 0) return String.valueOf(Integer.parseInt(year) - 1);
        return year;
    }

    private Double getTargetData(Map<String, List<MesCareerCorrelationCfg>> targetCfgMap, Boolean dataFlag, String dataKey) {
        try {
            return (CollectionUtils.isEmpty(targetCfgMap) || !targetCfgMap.containsKey(dataKey)) ? new Double(0) : dataFlag ? getCfgValue(targetCfgMap.get(dataKey).get(0).getCfgValue2()) : getCfgValue(targetCfgMap.get(dataKey).get(0).getCfgValue1());
        } catch (NumberFormatException e) {
            return new Double(0);
        }
    }

    private Double getCfgValue(String cfgValue) {
        if (StringUtils.isEmpty(cfgValue)) return new Double(0);
        else return new Double(cfgValue);
    }

    private String getBigDecimalPercent(BigDecimal b) {
        return b + MesExtConstWords.PERCENT;
    }

    private BigDecimal divThenMul100Format2RoundHalfUp(Double d1, Double d2) {
        Double d = (MathOperation.compareTo(d1, new Double(0)) == 0 || MathOperation.compareTo(d2, new Double(0)) == 0) ? null : mul100(MathOperation.div(d1, d2));
        return format2RoundHalfUp(d);
    }

    private BigDecimal format2RoundHalfUp(Double d) {
        if (StringUtils.isEmpty(d)) d = new Double(0);
        BigDecimal bd = new BigDecimal(d);
        bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
        return bd;
    }

    private Double mul100(Double value) {
        return MathOperation.mul(value, new Double(100));
    }

    private Double mul100(String value) {
        return mul100(new Double(value));
    }

    private Map<String, String> getDateMap(SxEChartsReportCommonDataModel data) {

        Map<String, String> dateMap = null;

        if (DIMENSION.SEASON.getCode() == data.getDimension()) {
            if (StringUtils.isEmpty(data.getYear())) data.setYear(Integer.valueOf(TimeTool.getYear()));
            dateMap = new HashMap<>();
            if (!data.getSxYearFlag()) {
                dateMap.put("1Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_01_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_03_31).toString());
                dateMap.put("2Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_04_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_06_30).toString());
                dateMap.put("3Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_07_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_09_30).toString());
                dateMap.put("4Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_10_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_12_31).toString());

                dateMap.put(data.getYear() + "-01", "1Q");
                dateMap.put(data.getYear() + "-02", "1Q");
                dateMap.put(data.getYear() + "-03", "1Q");
                dateMap.put(data.getYear() + "-04", "2Q");
                dateMap.put(data.getYear() + "-05", "2Q");
                dateMap.put(data.getYear() + "-06", "2Q");
                dateMap.put(data.getYear() + "-07", "3Q");
                dateMap.put(data.getYear() + "-08", "3Q");
                dateMap.put(data.getYear() + "-09", "3Q");
                dateMap.put(data.getYear() + "-10", "4Q");
                dateMap.put(data.getYear() + "-11", "4Q");
                dateMap.put(data.getYear() + "-12", "4Q");

            } else {
                Integer nextYear = data.getYear() + 1;

                dateMap.put("1Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_04_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_06_30).toString());
                dateMap.put("2Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_07_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_09_30).toString());
                dateMap.put("3Q", new StringJoiner(MesExtConstWords.AND).add(data.getYear() + MesExtConstWords.DATE_MM_DD_10_01).add(data.getYear() + MesExtConstWords.DATE_MM_DD_12_31).toString());
                dateMap.put("4Q", new StringJoiner(MesExtConstWords.AND).add(nextYear + MesExtConstWords.DATE_MM_DD_01_01).add(nextYear + MesExtConstWords.DATE_MM_DD_03_31).toString());

                dateMap.put(data.getYear() + "-04", "1Q");
                dateMap.put(data.getYear() + "-05", "1Q");
                dateMap.put(data.getYear() + "-06", "1Q");
                dateMap.put(data.getYear() + "-07", "2Q");
                dateMap.put(data.getYear() + "-08", "2Q");
                dateMap.put(data.getYear() + "-09", "2Q");
                dateMap.put(data.getYear() + "-10", "3Q");
                dateMap.put(data.getYear() + "-11", "3Q");
                dateMap.put(data.getYear() + "-12", "3Q");
                dateMap.put(nextYear + "-01", "4Q");
                dateMap.put(nextYear + "-02", "4Q");
                dateMap.put(nextYear + "-03", "4Q");
            }
        }

        if (DIMENSION.WEEK.getCode() == data.getDimension()) {
            dateMap = new HashMap<>();

            String startTime = data.getWorkTimeStart();
            for (int i = 1; i <= 5; i ++) {
                dateMap.put(MesExtConstWords.WEEK_COUNT + i, startTime);
                for (int j = 1; j <= 7; j ++) {
                    dateMap.put(startTime, String.valueOf(i));
                    startTime = TimeTool.timeCalc(TimeTool.stringParseToDate(startTime, MesExtConstWords.DATE_FORMAT), Calendar.DATE, 1, MesExtConstWords.DATE_FORMAT);
                }
                if (startTime.compareTo(data.getWorkTimeEnd()) > 0) {
                    dateMap.put(MesExtConstWords.WEEK_COUNT, String.valueOf(i));
                    break;
                }
            }
        }
        return dateMap;
    }

    @Override
    public SxEnergyCompositeRateAnalysisModel queryEnergyCompositeRateAnalysis(SxEnergyCompositeRateAnalysisModel data) {

        sxYearFlag(data);

        handleMultipleChoice(data);

        Map<String, String> groupObjMap = DIMENSION1.CAREER.code == data.getDimension() ? data.getCareerMap() : data.getCategoryMap();

        if (CollectionUtils.isEmpty(groupObjMap)) return data;

        calcAnalysisTime(data);

        List<MesWorkCenterExt> workCenterExtList = getWorkCenterExtList(data);

        Map<String, MesWorkCenterExt> centerMap = getCenterMap(workCenterExtList);

        List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList = getRecordStatisticsList(data, centerMap);

        List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList = getOutPutStatisticsList(data, centerMap);

        handleMonthMap(data);

        Map<String, List<SxShiftProdCenterRecordStatisticsModel>> recordStatisticsListMap = getRecordStatisticsListMap(recordStatisticsList, data.getDimension());

        Map<String, List<SxProdDataToStatisticsOutPutModel>> outPutStatisticsListMap = getOutPutStatisticsListMap(outPutStatisticsList, data.getDimension());

        Map<String, MesCareerCorrelationCfg> careerCorrelationCfgMap = getCareerCorrelationCfgMap(data);

        groupObjMap.keySet().forEach(o -> data.addAnalysisData(handleAnalysisData(data, o, groupObjMap.get(o), recordStatisticsListMap, outPutStatisticsListMap, careerCorrelationCfgMap)));

        return data;
    }

    private Map<String, MesCareerCorrelationCfg> getCareerCorrelationCfgMap(SxEnergyCompositeRateAnalysisModel data) {
        String year = data.getWorkTimeStart().substring(0, 4);
        String startYear = data.getSxYearFlag() && data.getWorkTimeStart().compareTo(year + "-04") < 0 ? String.valueOf(Integer.parseInt(year) -1) : year;

        Map<String, MesCareerCorrelationCfg> careerCorrelationCfgMap = new HashMap<>();
        Map<String, List<MesCareerCorrelationCfg>> careerCorrelationCfgDbMap;
        if (DIMENSION1.CAREER.code == data.getDimension()) {
            List<MesCareerCorrelationCfg> careerCorrelationCfgList = careerCorrelationCfgService.getCareerCorrelationCfgList(data.getOrganizeCode(), MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_DIMENSION.CAREER.getValue(), MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_TYPE.COMPOSITE_RATE_TARGET.getValue(),  startYear, data.getWorkTimeEnd().substring(0, 4));
            careerCorrelationCfgDbMap = careerCorrelationCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()))).collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getCareerCode()).add(o.getDataKey()).toString()));
        } else {
            List<MesCareerCorrelationCfg> careerCorrelationCfgList = careerCorrelationCfgService.getCareerCorrelationCfgList(data.getOrganizeCode(), MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_DIMENSION.CATEGORY.getValue(), MesExtEnumUtil.CAREER_CORRELATION_CFG_DATA_TYPE.COMPOSITE_RATE_TARGET.getValue(),  startYear, data.getWorkTimeEnd().substring(0, 4));
            careerCorrelationCfgDbMap = careerCorrelationCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCategoryCode()))).collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getCategoryCode()).add(o.getDataKey()).toString()));
        }

        if (CollectionUtils.isEmpty(careerCorrelationCfgDbMap)) return null;
        for (Map.Entry<String, List<MesCareerCorrelationCfg>> entry : careerCorrelationCfgDbMap.entrySet()) {
            careerCorrelationCfgMap.put(entry.getKey(), entry.getValue().get(0).splitValue());
        }
        return careerCorrelationCfgMap;
    }

    private void handleMultipleChoice(SxEnergyCompositeRateAnalysisModel data) {
        Map<String, String> careerMap = !StringUtils.isEmpty(data.getCareerCodeArr()) ? getMultipleChoiceMap(data.getCareerCodeArr(), data.getCareerNameArr()) : null;
        Map<String, String> categoryMap = !StringUtils.isEmpty(data.getCategoryCodeArr()) ? getMultipleChoiceMap(data.getCategoryCodeArr(), data.getCategoryNameArr()) : null;
        if (DIMENSION1.CAREER.code == data.getDimension() && CollectionUtils.isEmpty(careerMap)) careerMap = busiConfigService.getConfigMap(data.getOrganizeCode(), MesExtConstWords.SX_CAREER_CFG);;
        if (DIMENSION1.CATEGORY.code == data.getDimension() && CollectionUtils.isEmpty(categoryMap)) categoryMap = partCategoryPlanRateService.getCategoryMap(data.getOrganizeCode());
        data.careerMap(careerMap).categoryMap(categoryMap);
    }

    private List<String> handleMultipleChoice(String param) {
        return StringUtils.isEmpty(param) ? null : Arrays.asList(param.split(MesExtConstWords.COMMA));
    }

    private Map<String, String> getMultipleChoiceMap(String codeArr, String nameArr) {
        Map<String, String> careerMap = new LinkedHashMap<>();
        List<String> codes = handleMultipleChoice(codeArr);
        List<String> names = handleMultipleChoice(nameArr);
        for (int i = 0; i < codes.size(); i ++) {
            careerMap.put(codes.get(i), names.get(i));
        }
        return careerMap;
    }

    private void calcAnalysisTime(SxEnergyCompositeRateAnalysisModel data) {
        data.setYmdStart(data.getWorkTimeStart() + MesExtConstWords.DATE_DD_01);
        data.setYmdEnd(getMonthLastDay(data.getWorkTimeEnd()));

        String curMonth = TimeTool.getToday().substring(0, 7);
        String curMonthBegin = curMonth + MesExtConstWords.DATE_DD_01;

        if (curMonthBegin.compareTo(data.getYmdStart()) <= 0) {
            data.setWorkTimeYmdStart(data.getYmdStart());
            data.setWorkTimeYmdEnd(data.getYmdEnd());
        } else if (curMonthBegin.compareTo(data.getYmdEnd()) > 0) {
            data.setStatisticsYmStart(data.getYmdStart().substring(0, 7));
            data.setStatisticsYmEnd(data.getYmdEnd().substring(0, 7));
        } else {
            data.setStatisticsYmStart(data.getYmdStart().substring(0, 7));
            data.setStatisticsYmEnd(TimeTool.timeCalc(TimeTool.stringParseToDate(curMonth, MesExtConstWords.DATE_FORMAT_YM), Calendar.MONTH, -1, MesExtConstWords.DATE_FORMAT_YM));
            data.setWorkTimeYmdStart(curMonthBegin);
            data.setWorkTimeYmdEnd(data.getYmdEnd());
        }
    }

    private void handleMonthMap(SxEnergyCompositeRateAnalysisModel data) {
        String startMonth = data.getWorkTimeStart();
        for (int i = 1; i <= 12; i ++) {
            data.putMonthMap(startMonth, Integer.valueOf(startMonth.substring(5, 7)).toString());
            startMonth = TimeTool.timeCalc(TimeTool.stringParseToDate(startMonth, MesExtConstWords.DATE_FORMAT_YM), Calendar.MONTH, 1, MesExtConstWords.DATE_FORMAT_YM);
            if (startMonth.compareTo(data.getWorkTimeEnd()) > 0) break;
        }
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getRecordStatisticsList(SxEnergyCompositeRateAnalysisModel data, Map<String, MesWorkCenterExt> centerMap) {
        List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList = new ArrayList<>();
        if (!StringUtils.isEmpty(data.getWorkTimeYmdStart())) {
            List<SxShiftProdCenterRecordStatisticsModel> resultList = getShiftProdCenterRecordList(data, data.getWorkTimeYmdStart(), data.getWorkTimeYmdEnd());
            if (!CollectionUtils.isEmpty(resultList)) recordStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmStart())) {
            List<SxShiftProdCenterRecordStatisticsModel> resultList = getShiftProdCenterRecordStatisticsList(data, data.getStatisticsYmStart(), data.getStatisticsYmEnd());
            if (!CollectionUtils.isEmpty(resultList)) recordStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmdStart())) {
            List<SxShiftProdCenterRecordStatisticsModel> resultList = getShiftProdCenterRecordStatisticsList(data, data.getStatisticsYmdStart(), data.getStatisticsYmdEnd());
            if (!CollectionUtils.isEmpty(resultList)) recordStatisticsList.addAll(resultList);
        }
        recordStatisticsList = CollectionUtils.isEmpty(recordStatisticsList) ? recordStatisticsList :
                recordStatisticsList.stream().filter(o -> (null != o && centerMap.containsKey(o.getWorkCenterCode()))).collect(Collectors.toList());
        recordStatisticsList = (CollectionUtils.isEmpty(data.getCareerMap()) || CollectionUtils.isEmpty(recordStatisticsList)) ? recordStatisticsList :
                recordStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()) && data.getCareerMap().containsKey(o.getCareerCode()))).collect(Collectors.toList());
        recordStatisticsList = (CollectionUtils.isEmpty(data.getCategoryMap()) || CollectionUtils.isEmpty(recordStatisticsList)) ? recordStatisticsList :
                recordStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCategoryCode()) && data.getCategoryMap().containsKey(o.getCategoryCode()))).collect(Collectors.toList());
        return recordStatisticsList;
    }

    private List<SxProdDataToStatisticsOutPutModel> getOutPutStatisticsList(SxEnergyCompositeRateAnalysisModel data, Map<String, MesWorkCenterExt> centerMap) {
        List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList = new ArrayList<>();
        if (!StringUtils.isEmpty(data.getWorkTimeYmdStart())) {
            List<SxProdDataToStatisticsOutPutModel> resultList = getOutPutStatisticsRecordList(data, data.getWorkTimeYmdStart(), data.getWorkTimeYmdEnd());
            if (!CollectionUtils.isEmpty(resultList)) outPutStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmStart())) {
            List<SxProdDataToStatisticsOutPutModel> resultList = getProdDataOutPutStatisticsList(data, data.getStatisticsYmStart(), data.getStatisticsYmEnd());
            if (!CollectionUtils.isEmpty(resultList)) outPutStatisticsList.addAll(resultList);
        }
        if (!StringUtils.isEmpty(data.getStatisticsYmdStart())) {
            List<SxProdDataToStatisticsOutPutModel> resultList = getProdDataOutPutStatisticsList(data, data.getStatisticsYmdStart(), data.getStatisticsYmdEnd());
            if (!CollectionUtils.isEmpty(resultList)) outPutStatisticsList.addAll(resultList);
        }
        outPutStatisticsList = CollectionUtils.isEmpty(outPutStatisticsList) ? outPutStatisticsList :
                outPutStatisticsList.stream().filter(o -> (null != o && centerMap.containsKey(o.getWorkCenterCode()))).collect(Collectors.toList());
        outPutStatisticsList = (CollectionUtils.isEmpty(data.getCareerMap()) || CollectionUtils.isEmpty(outPutStatisticsList)) ? outPutStatisticsList :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()) && data.getCareerMap().containsKey(o.getCareerCode()))).collect(Collectors.toList());
        outPutStatisticsList = (CollectionUtils.isEmpty(data.getCategoryMap()) || CollectionUtils.isEmpty(outPutStatisticsList)) ? outPutStatisticsList :
                outPutStatisticsList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCategoryCode()) && data.getCategoryMap().containsKey(o.getCategoryCode()))).collect(Collectors.toList());
        return outPutStatisticsList;
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getShiftProdCenterRecordList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.timeBuilder(workTimeStart, workTimeEnd, MesExtConstWords.WORK_TIME, packBean, false);
        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = shiftProdCenterRecordRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(shiftProdCenterRecordList)) return null;
        List<SxShiftProdCenterRecordStatisticsModel> resultList = new ArrayList<>();
        for (MesShiftProdCenterRecord item : shiftProdCenterRecordList) {
            if (null == item || StringUtils.isEmpty(item.getProdType())) continue;
            SxShiftProdCenterRecordStatisticsModel result = new SxShiftProdCenterRecordStatisticsModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(result.getWorkTime().substring(0, 7));
            try {
                result.setStatistics(MathOperation.mul(new Double(TimeTool.getSecoundsBetweenTime(2, item.getStartTime(), item.getEndTime())), item.getWorkerQty()));
            } catch (ParseException e) {
                result.setStatistics(new Double(0));
            }
            resultList.add(result);
        }
        return resultList;
    }

    private List<SxShiftProdCenterRecordStatisticsModel> getShiftProdCenterRecordStatisticsList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = getRecordStatisticsPackBeanByType(data, workTimeStart, workTimeEnd);
        List<MesProdDataToStatisticsShiftProd> prodDataToStatisticsShiftProdList = prodDataToStatisticsShiftProdRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(prodDataToStatisticsShiftProdList)) return null;
        List<SxShiftProdCenterRecordStatisticsModel> resultList = new ArrayList<>();
        for (MesProdDataToStatisticsShiftProd item : prodDataToStatisticsShiftProdList) {
            if (null == item || StringUtils.isEmpty(item.getProdType())) continue;
            SxShiftProdCenterRecordStatisticsModel result = new SxShiftProdCenterRecordStatisticsModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(result.getWorkTime());
            resultList.add(result);
        }
        return resultList;
    }

    private List<SxProdDataToStatisticsOutPutModel> getOutPutStatisticsRecordList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue(), MesExtConstWords.WORK_ORDER_TYPE, packBean);
        DdlPreparedPack.timeBuilder(workTimeStart, workTimeEnd, MesExtConstWords.WORK_TIME, packBean, false);
        List<MesOutPutStatistics> outPutStatisticsList = outPutStatisticsRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(outPutStatisticsList)) return null;

        Map<String, Double> partStandardWorkMap = partExtDao.queryPartExtStandardWorkMap(data.getOrganizeCode());

        List<SxProdDataToStatisticsOutPutModel> resultList = new ArrayList<>();
        for (MesOutPutStatistics item : outPutStatisticsList) {
            if (null == item) continue;
            SxProdDataToStatisticsOutPutModel result = new SxProdDataToStatisticsOutPutModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(result.getWorkTime().substring(0, 7));
            result.setStandardWork((!CollectionUtils.isEmpty(partStandardWorkMap) && partStandardWorkMap.containsKey(result.getPartNo())) ? partStandardWorkMap.get(result.getPartNo()) : new Double(0));
            result.setStatistics(MathOperation.mul(getUnRemakeQty(item.getQty(), item.getRemakeQty()), result.getStandardWork()));
            resultList.add(result);
        }
        return resultList;
    }

    private List<SxProdDataToStatisticsOutPutModel> getProdDataOutPutStatisticsList(SxEChartsReportCommonDataModel data, String workTimeStart, String workTimeEnd) {
        DdlPackBean packBean = getOutPutStatisticsPackBeanByType(data, workTimeStart, workTimeEnd);
        List<MesProdDataToStatisticsOutPut> prodDataToStatisticsOutPutList = prodDataToStatisticsOutPutRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(prodDataToStatisticsOutPutList)) return null;
        List<SxProdDataToStatisticsOutPutModel> resultList = new ArrayList<>();
        for (MesProdDataToStatisticsOutPut item : prodDataToStatisticsOutPutList) {
            if (null == item) continue;
            SxProdDataToStatisticsOutPutModel result = new SxProdDataToStatisticsOutPutModel();
            BeanUtils.copyProperties(item, result);
            result.setGroupInfo(result.getWorkTime());
            resultList.add(result);
        }
        return resultList;
    }

    private Map<String, List<SxShiftProdCenterRecordStatisticsModel>> getRecordStatisticsListMap(List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList, Integer dimension) {
        if (CollectionUtils.isEmpty(recordStatisticsList)) return null;
        if (DIMENSION1.CAREER.code == dimension)
            return recordStatisticsList.stream().filter(o -> null != o).collect(Collectors.groupingBy(SxShiftProdCenterRecordStatisticsModel::getCareerCode));
        else
            return recordStatisticsList.stream().filter(o -> null != o).collect(Collectors.groupingBy(SxShiftProdCenterRecordStatisticsModel::getCategoryCode));
    }

    private Map<String, List<SxProdDataToStatisticsOutPutModel>> getOutPutStatisticsListMap(List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList, Integer dimension) {
        if (CollectionUtils.isEmpty(outPutStatisticsList)) return null;
        if (DIMENSION1.CAREER.code == dimension)
            return outPutStatisticsList.stream().filter(o -> null != o).collect(Collectors.groupingBy(SxProdDataToStatisticsOutPutModel::getCareerCode));
        else
            return outPutStatisticsList.stream().filter(o -> null != o).collect(Collectors.groupingBy(SxProdDataToStatisticsOutPutModel::getCategoryCode));
    }

    private SxEnergyCompositeRateAnalysisModel handleAnalysisData(SxEnergyCompositeRateAnalysisModel data, String groupObj, String title,
                                                                  Map<String, List<SxShiftProdCenterRecordStatisticsModel>> recordStatisticsListMap,
                                                                  Map<String, List<SxProdDataToStatisticsOutPutModel>> outPutStatisticsListMap,
                                                                  Map<String, MesCareerCorrelationCfg> careerCorrelationCfgMap) {

        List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsList = CollectionUtils.isEmpty(recordStatisticsListMap) ? null : recordStatisticsListMap.get(groupObj);
        List<SxProdDataToStatisticsOutPutModel> outPutStatisticsList = CollectionUtils.isEmpty(outPutStatisticsListMap) ? null : outPutStatisticsListMap.get(groupObj);

        Map<String, List<SxShiftProdCenterRecordStatisticsModel>> recordStatisticsListMapByTime = getRecordStatisticsListMapByTime(recordStatisticsList);
        Map<String, List<SxProdDataToStatisticsOutPutModel>> outPutStatisticsListMapByTime = getOutPutStatisticsListMapByTime(outPutStatisticsList);

        SxEnergyCompositeRateAnalysisModel analysisData = new SxEnergyCompositeRateAnalysisModel().title(title);
        for (Map.Entry<String, String> entry : data.getMonthMap().entrySet()) {
            if (null == entry) continue;
            List<SxShiftProdCenterRecordStatisticsModel> recordStatisticsListByTime = CollectionUtils.isEmpty(recordStatisticsListMapByTime) ? null : recordStatisticsListMapByTime.get(entry.getKey());
            List<SxProdDataToStatisticsOutPutModel> outPutStatisticsListByTime = CollectionUtils.isEmpty(outPutStatisticsListMapByTime) ? null : outPutStatisticsListMapByTime.get(entry.getKey());
            Double serviceTime = getShiftProdDataListStatistics(getShiftProdDataListByFlag(recordStatisticsListByTime, true));
            Double nonWorkingTime = getShiftProdDataListStatistics(getShiftProdDataListByFlag(recordStatisticsListByTime, false));
            Double workingTime = MathOperation.sub(serviceTime, nonWorkingTime);
            Double standardTime = getOutPutDataListStatistics(outPutStatisticsListByTime);
            MesCareerCorrelationCfg targetCfg = getTargetCfg(careerCorrelationCfgMap, groupObj, entry.getKey(), data.getSxYearFlag());
            if (null == targetCfg) analysisData.addLineData(entry.getValue(), format2RoundHalfUp(new Double(0)));
            else analysisData.addLineData(entry.getValue(), format2RoundHalfUp(mul100(targetCfg.getCfgValue1())), format2RoundHalfUp(mul100(targetCfg.getCfgValue2())), format2RoundHalfUp(mul100(targetCfg.getCfgValue3())));
            analysisData.addBarData(entry.getValue(), divThenMul100Format2RoundHalfUp(standardTime, workingTime), divThenMul100Format2RoundHalfUp(standardTime, serviceTime), divThenMul100Format2RoundHalfUp(nonWorkingTime, serviceTime));
        }
        return analysisData;
    }

    private MesCareerCorrelationCfg getTargetCfg(Map<String, MesCareerCorrelationCfg> careerCorrelationCfgMap, String groupObj, String month, Boolean sxYearFlag) {
        if (CollectionUtils.isEmpty(careerCorrelationCfgMap)) return null;
        return careerCorrelationCfgMap.get(new StringJoiner(MesExtConstWords.AND).add(groupObj).add(getYearByFlag(sxYearFlag, month)).toString());
    }

    enum DIMENSION {

        YEAR(10, "年"),
        SEASON(20, "季"),
        MONTH(30, "月"),
        WEEK(40, "周"),
        DAY(50, "日");

        private Integer code;
        private String description;

        DIMENSION(Integer code, String description) {
            this.code = code;
            this.description = description;
        }

        public static DIMENSION getByCode(int code) {
            DIMENSION[] var1 = values();
            int var2 = var1.length;

            for (int var3 = 0; var3 < var2; ++var3) {
                DIMENSION dimension = var1[var3];
                if (dimension.getCode() == code) {
                    return dimension;
                }
            }
            return null;
        }

        public int getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }

        public static String codeOfDescription(Integer code) {
            String tmp = null;
            for (int i = 0; i < values().length; i++) {
                if (values()[i].code == code) {
                    tmp = values()[i].description;
                }
            }
            return tmp;
        }

    }

    enum DIMENSION1 {

        CAREER(10, "事业别"),
        CATEGORY(20, "产品别");

        private Integer code;
        private String description;

        DIMENSION1(Integer code, String description) {
            this.code = code;
            this.description = description;
        }

        public static DIMENSION1 getByCode(int code) {
            DIMENSION1[] var1 = values();
            int var2 = var1.length;

            for (int var3 = 0; var3 < var2; ++var3) {
                DIMENSION1 dimension = var1[var3];
                if (dimension.getCode() == code) {
                    return dimension;
                }
            }
            return null;
        }

        public int getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }

        public static String codeOfDescription(Integer code) {
            String tmp = null;
            for (int i = 0; i < values().length; i++) {
                if (values()[i].code == code) {
                    tmp = values()[i].description;
                }
            }
            return tmp;
        }

    }

}
