package com.dsk.cscec.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.JsonUtils;
import com.dsk.common.utils.StringUtils;
import com.dsk.common.utils.poi.ExcelUtil;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.*;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualPushBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import com.dsk.cscec.domain.vo.CbCostMeasuresImportVo;
import com.dsk.cscec.domain.vo.CbProjectExpenseSummaryImportVo;
import com.dsk.cscec.domain.vo.CbProjectExpenseSummaryVo;
import com.dsk.cscec.listener.ProjectCostMeasureImportListener;
import com.dsk.cscec.listener.ProjectCostMeasureSummaryImportListener;
import com.dsk.cscec.mapper.CbCostMeasureActualMapper;
import com.dsk.cscec.service.*;
import com.sun.org.apache.bcel.internal.generic.IFNULL;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dsk.cscec.mapper.CbCostMeasureMapper;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.Collator;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CbCostMeasureServiceImpl extends ServiceImpl<CbCostMeasureMapper, CbCostMeasure> implements ICbCostMeasureService {


    private final String firstPattern = "[\\(（]*[一|二|三|四|五|六|七|八|九|十]+[\\)）]*";
    private final Pattern secondPattern = Pattern.compile("^\\d+(\\.\\d+)*$");
    private final Pattern pattern3 = Pattern.compile("^([1-9][0-9]*|0)$");
    private Long planMeasureIdTemp;

    @Autowired
    private CbProjectRecordService cbProjectRecordService;
    @Autowired
    private ICbCostMeasureActualService cbCostMeasureActualService;
    @Resource
    private CbCostMeasureActualMapper cbCostMeasureActualMapper;
    @Autowired
    private CbProjectFileService cbProjectFileService;
    @Autowired
    private CbProjectExpenseSummaryService cbProjectExpenseSummaryService;

    @SneakyThrows
    @Override
    public void importExcelData(InputStream inputStream, String fileName, Long fileId, Long projectId) {
        // 检查项目
        checkProjectExist(projectId);
        ProjectCostMeasureImportListener importListener = new ProjectCostMeasureImportListener(projectId);
        EasyExcel.read(inputStream, CbCostMeasuresImportVo.class, importListener).sheet().doRead();
        ExcelResult<CbCostMeasuresImportVo> result = importListener.getExcelResult();
        String analysis = result.getAnalysis();
        List<CbCostMeasuresImportVo> list = result.getList();
        List<String> errorList = result.getErrorList();
        if (CollectionUtil.isNotEmpty(errorList) || CollectionUtil.isEmpty(list)) {
            //解析失败
            log.debug(">>>>解析失败" + list.size());
            //todo 解析失败更新文件备注
            cbProjectFileService.UpdateProjectFileStatus(fileId, analysis, CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
            return;
        }
        log.debug(">>>>" + list.size());

        //删除 该项目历史解析数据
        LambdaQueryWrapper<CbCostMeasure> summaryLambdaQueryWrapper = Wrappers.lambdaQuery();
        summaryLambdaQueryWrapper.eq(CbCostMeasure::getProjectId, projectId);
        summaryLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(fileId), CbCostMeasure::getProjectFileId, fileId);
        this.remove(summaryLambdaQueryWrapper);

        CbCostMeasure rootCbCostMeasure = new CbCostMeasure();
        rootCbCostMeasure.setItemContent(fileName);
        rootCbCostMeasure.setLevel(0);
        rootCbCostMeasure.setParentId(0L);
        rootCbCostMeasure.setProjectId(projectId);
        if (ObjectUtil.isNotEmpty(fileId)) {
            rootCbCostMeasure.setProjectFileId(fileId);
        }


        LambdaQueryWrapper<CbCostMeasure> tWrapper = Wrappers.lambdaQuery(rootCbCostMeasure);
        CbCostMeasure rootMeasure = this.getOne(tWrapper);
        if (ObjectUtil.isEmpty(rootMeasure)) {
            this.save(rootCbCostMeasure);
            rootCbCostMeasure.setNo(String.valueOf(rootCbCostMeasure.getId()));
            this.updateById(rootCbCostMeasure);
        }

        Long rootMeasuresId = rootCbCostMeasure.getId();
        if (CollectionUtil.isNotEmpty(list)) {
            for (CbCostMeasuresImportVo importVo : list) {
                String number = importVo.getNumber();

                CbCostMeasure cbCostMeasure = new CbCostMeasure();
                cbCostMeasure.setProjectId(projectId);
                cbCostMeasure.setProjectFileId(fileId);
                //保存一级节点
                if (ReUtil.isMatch(firstPattern, number) || ReUtil.isMatch(pattern3, number)) {
                    BeanUtil.copyProperties(importVo, cbCostMeasure);
                    cbCostMeasure.setParentId(rootMeasuresId);
                    cbCostMeasure.setLevel(1);

                } else if (ReUtil.isMatch(secondPattern, number)) {
                    BeanUtil.copyProperties(importVo, cbCostMeasure);
                    // 根据no查询父级节点
                    CbCostMeasure parentCbCostMeasure = getCbCostMeasure(rootMeasuresId, number, projectId);
                    String[] split = number.split("\\.");
                    cbCostMeasure.setLevel(split.length);
                    cbCostMeasure.setParentId(parentCbCostMeasure.getId());
                }
                String newNo = String.valueOf(rootMeasuresId).concat(".").concat(cbCostMeasure.getNo());
                cbCostMeasure.setNo(newNo);
                this.save(cbCostMeasure);
            }

            cbProjectFileService.UpdateProjectFileStatus(fileId, null, CbProjectConstants.PROJECT_FILE_STATUS_PARSE_SUCCESS);
        }

    }

    @Override
    public List<Map<String, Object>> listByLevel(Long projectId, int i) {

        CbProjectRecord byId = cbProjectRecordService.getById(projectId);
        Assert.notNull(byId, "项目信息不能为空");

        CbCostMeasure rootCbCostMeasure = new CbCostMeasure();
        rootCbCostMeasure.setParentId(0L);
        rootCbCostMeasure.setProjectId(projectId);

        QueryWrapper<CbCostMeasure> tWrapper = Wrappers.query(rootCbCostMeasure);
        tWrapper.select("id", "item_content as itemContent");
        tWrapper.orderByAsc("id");
        List<Map<String, Object>> mapList = this.listMaps(tWrapper);

        Collator collator = Collator.getInstance(Locale.CHINA);
        Collections.sort(mapList, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> m1, Map<String, Object> m2) {
                String itemContent1 = (String) m1.get("itemContent");
                String itemContent2 = (String) m2.get("itemContent");
                return collator.compare(itemContent1, itemContent2);
            }
        });
        return mapList;
    }

    @Override
    public List<Tree<Long>> selectDataList(CbCostMeasureActualBo costMeasureActualBo) {
        List<CbCostMeasureActualVo> dataList = new ArrayList<>();

        Assert.notNull(costMeasureActualBo.getProjectId(), "项目ID不能为空");
        checkProjectExist(costMeasureActualBo.getProjectId());
        //查询项目某项措施费所有计划成本
        dataList = baseMapper.selectListByProjectAndNo(costMeasureActualBo);

        //统计截止本月差值
        dataList.forEach(item -> {
            item.setSumDifference(cbCostMeasureActualMapper.calculateSumDifference(item));
        });
//配置类
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setParentIdKey("parentId");
        treeNodeConfig.setChildrenKey("children");
//构建树形
        List<Tree<Long>> trees = TreeUtil.build(dataList, costMeasureActualBo.getId(), treeNodeConfig, ((object, treeNode) -> {
            treeNode.setId(object.getId());//id
            treeNode.setParentId(object.getParentId());//父id
            // 扩展属性 ...
            treeNode.putExtra("actualId", object.getActualId());
            treeNode.putExtra("itemContent", object.getItemContent());
            treeNode.putExtra("number", object.getNumber());
            treeNode.putExtra("workContent", object.getWorkContent());
            treeNode.putExtra("unit", object.getUnit());
            treeNode.putExtra("quantity", object.getQuantity());
            treeNode.putExtra("unitPriceExcludingTax", object.getUnitPriceExcludingTax());
            treeNode.putExtra("usageTime", object.getUsageTime());
            treeNode.putExtra("amountExcludingTax", object.getAmountExcludingTax());
            treeNode.putExtra("taxRate", object.getTaxRate());
            treeNode.putExtra("amountIncludingTax", object.getAmountIncludingTax());
            treeNode.putExtra("amortizationRatio", object.getAmortizationRatio());
            treeNode.putExtra("amountIncludeTaxAmortized", object.getAmountIncludeTaxAmortized());
            treeNode.putExtra("amountExcludeTaxAmortized", object.getAmountExcludeTaxAmortized());
            treeNode.putExtra("taxAmount", object.getTaxAmount());
            treeNode.putExtra("remarks", object.getRemarks());
            treeNode.putExtra("costSubject", object.getCostSubject());
            treeNode.putExtra("taxType", object.getTaxType());
            treeNode.putExtra("planMeasureId", object.getPlanMeasureId());
            treeNode.putExtra("monthCostRate", object.getMonthCostRate());
            treeNode.putExtra("costEffective", object.getCostEffective());
            treeNode.putExtra("projectVolume", object.getProjectVolume());
            treeNode.putExtra("currentProjectVolume", object.getCurrentProjectVolume());
            treeNode.putExtra("submitProjectVolume", object.getSubmitProjectVolume());
            treeNode.putExtra("difference", object.getDifference());
            treeNode.putExtra("sumDifference", object.getSumDifference());
            treeNode.putExtra("month", object.getMonth());
            treeNode.putExtra("pushTime", object.getPushTime());
            treeNode.putExtra("pushDataJson", object.getPushDataJson());
            treeNode.putExtra("createTime", object.getCreateTime());
        }));

        return trees;
    }

    @Override
    public void saveBatchCostMeasureActual(List<CbCostMeasureActualSaveBo> boList) {
        //递归
        //this.recursionSaveBatchCostMeasureActual(boList, boList.get(0).getId(), null);
        Assert.isTrue(ObjectUtil.isNotEmpty(boList), "数据不能为空");
        boList.forEach(item -> {
            CbCostMeasureActual actual = BeanUtil.toBean(item, CbCostMeasureActual.class);
            Assert.notNull(actual.getPlanMeasureId(), "基础数据id不能为空");
            Assert.notNull(actual.getMonth(), "填写月份不能为空");
            actual.setId(ObjectUtil.isNull(actual.getId()) ? IdUtil.getSnowflakeNextId() : actual.getId());
            // 查询计划成本累积实际成本
            BigDecimal bigDecimal = cbCostMeasureActualService.selectSumData(item);
            actual.setCurrentProjectVolume(NumberUtil.add(bigDecimal, actual.getProjectVolume()));
            actual.setUpdateUser(Objects.requireNonNull(LoginHelper.getUsername()));
            actual.setUpdateId(Objects.requireNonNull(LoginHelper.getUserId()));
            actual.setDelFlag(0);
            boolean b = cbCostMeasureActualService.saveOrUpdate(actual);
            if (!b) {
                log.error("CbQuantitySummaryServiceImpl.updateActual() data insert error! data:" + JSONUtil.toJsonStr(actual));
                throw new ServiceException("数据添加错误！");
            }
        });
    }

    /**
     * 递归保存或修改每月措施费
     *
     * @param boList        每月措施费集合
     * @param planMeasureId 计划成本措施费id
     * @param month         月份
     */
    public void recursionSaveBatchCostMeasureActual(List<CbCostMeasureActualSaveBo> boList, Long planMeasureId, String month) {
        List<CbCostMeasureActual> saveList = new ArrayList<>();
        planMeasureIdTemp = planMeasureId;
        for (CbCostMeasureActualSaveBo cbCostMeasureActualSaveBo : boList) {
            CbCostMeasureActual cbCostMeasureActual = new CbCostMeasureActual();
            BeanUtil.copyProperties(cbCostMeasureActualSaveBo, cbCostMeasureActual);

            if (ObjectUtil.isNotNull(planMeasureId)) {
                cbCostMeasureActual.setPlanMeasureId(planMeasureIdTemp++);
            }
            if (StringUtils.isNotEmpty(month)) {
                cbCostMeasureActual.setMonth(month);
            }
            cbCostMeasureActual.setDelFlag(0);
//            cbCostMeasureActual.setUpdateId(LoginHelper.getUserId());
//            cbCostMeasureActual.setUpdateUser(LoginHelper.getUsername());
            // 查询计划成本累积实际成本
            BigDecimal bigDecimal = cbCostMeasureActualService.selectSumData(cbCostMeasureActualSaveBo);
            cbCostMeasureActual.setCurrentProjectVolume(NumberUtil.add(bigDecimal, cbCostMeasureActual.getProjectVolume()));
            saveList.add(cbCostMeasureActual);

            List<CbCostMeasureActualSaveBo> childrenList = cbCostMeasureActualSaveBo.getChildren();
            if (ObjectUtil.isNotNull(childrenList) && !childrenList.isEmpty()) {
                this.recursionSaveBatchCostMeasureActual(childrenList, planMeasureIdTemp, cbCostMeasureActualSaveBo.getMonth());
            }
        }
        cbCostMeasureActualService.saveOrUpdateBatch(saveList);
        //CbCostMeasureActual cbCostMeasureActual = saveList.get(0);

        //todo 查询最新的二级费用合计, 用于更新一级费用项
        //cbCostMeasureActualService.selectMonthProjectVolumeByLevel(1,cbCostMeasureActual.GET);

        //更新
    }

    @Override
    public void pushCostMeasureActual(CbCostMeasureActualPushBo pushBo) {

        //todo 推送到Ipm系统

        CbCostMeasureActual cbCostMeasureActual = new CbCostMeasureActual();
        cbCostMeasureActual.setId(pushBo.getId());
        cbCostMeasureActual.setPushTime(new Date());
        cbCostMeasureActual.setSubmitProjectVolume(pushBo.getSubmitProjectVolume());
        cbCostMeasureActual.setPushDataJson(JsonUtils.toJsonString(pushBo));
        cbCostMeasureActualService.updateById(cbCostMeasureActual);
    }

    @SneakyThrows
    @Override
    public List<String> importExcelSummaryData(InputStream inputStream, Long projectId, Long fileId, Integer dataType) {
        CbProjectRecord byId = cbProjectRecordService.getById(projectId);
        Assert.notNull(byId, "项目信息不能为空");

        // 删除历史数据
        LambdaUpdateWrapper<CbProjectExpenseSummary> summaryLambdaQueryWrapper = Wrappers.lambdaUpdate();
        summaryLambdaQueryWrapper.eq(CbProjectExpenseSummary::getProjectId, projectId);
        summaryLambdaQueryWrapper.eq(CbProjectExpenseSummary::getDataType, 2);
        cbProjectExpenseSummaryService.remove(summaryLambdaQueryWrapper);

        ExcelResult<CbProjectExpenseSummaryImportVo> excelResult = ExcelUtil.importExcel(inputStream, CbProjectExpenseSummaryImportVo.class, new ProjectCostMeasureSummaryImportListener(projectId, fileId, dataType));
        List<String> errorList = excelResult.getErrorList();
        if (CollectionUtil.isNotEmpty(errorList) || CollectionUtil.isEmpty(excelResult.getList())) {
            return errorList;
        }
        return null;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void parseCbCostMeasureFile(Long projectId) {
        // 检查项目
        checkProjectExist(projectId);

        //获取项目待解析文件
        List<CbProjectFile> cbProjectFiles = new ArrayList<>();
        cbProjectFiles = cbProjectFileService.list(new LambdaQueryWrapper<CbProjectFile>()
                .eq(CbProjectFile::getProjectId, projectId)
                .eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PARSING)
                .eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_MEASURE_PROJECT)
        );
        if (CollectionUtil.isEmpty(cbProjectFiles)) {
            log.debug("措施费数据文件不存在");
            return;
        }

        for (CbProjectFile cbProjectFile : cbProjectFiles) {
            String fileName = cbProjectFile.getFileName();
            String prefix = FileNameUtil.getPrefix(fileName);
            // 解析汇总
            if ("措施费".equals(prefix)) {
                byte[] bytes = HttpUtil.downloadBytes(cbProjectFile.getFileOssUrl());
                InputStream inputStream = new ByteArrayInputStream(bytes);
                List<String> errlist = importExcelSummaryData(inputStream, projectId, cbProjectFile.getId(), 2);
                if (CollectionUtil.isNotEmpty(errlist)) {
                    cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
                } else {
                    // 修改文件解析状态
                    cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_SUCCESS);
                }
                cbProjectFileService.updateById(cbProjectFile);
            } else {
                byte[] bytes = HttpUtil.downloadBytes(cbProjectFile.getFileOssUrl());
                InputStream inputStream = new ByteArrayInputStream(bytes);
                importExcelData(inputStream, prefix, cbProjectFile.getId(), projectId);
            }


        }

    }

    private void checkProjectExist(Long projectId) {
        CbProjectRecord byId = cbProjectRecordService.getById(projectId);
        Assert.notNull(byId, "项目信息不能为空");
    }


    @Override
    public boolean reparseCbCostMeasureFile(Long projectId, Long projectFileId) {
        // 查询项目
        CbProjectRecord byId = cbProjectRecordService.getById(projectId);
        Assert.notNull(byId, "项目信息不能为空");
        List<CbProjectFile> cbProjectFiles = new ArrayList<>();
        Assert.notNull(projectFileId, "措施费文件ID不能为空");
        if (ObjectUtil.isNotEmpty(projectFileId)) {
            CbProjectFile cbProjectFile = cbProjectFileService.getById(projectFileId);
            Assert.notNull(cbProjectFile, "措施费导入文件不存在");
            String fileName = cbProjectFile.getFileName();
            String prefix = FileNameUtil.getPrefix(fileName);
            // 解析汇总
            if ("措施费".equals(prefix)) {
                byte[] bytes = HttpUtil.downloadBytes(cbProjectFile.getFileOssUrl());
                InputStream inputStream = new ByteArrayInputStream(bytes);
                List<String> errlist = importExcelSummaryData(inputStream, projectId, projectFileId, 2);
                if (CollectionUtil.isNotEmpty(errlist)) {
                    cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
                } else {
                    // 修改文件解析状态
                    cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_SUCCESS);
                }

            } else {
                byte[] bytes = HttpUtil.downloadBytes(cbProjectFile.getFileOssUrl());
                InputStream inputStream = new ByteArrayInputStream(bytes);
                importExcelData(inputStream, prefix, cbProjectFile.getId(), projectId);
            }

            //更新

            return true;
        }


        return false;
    }

    @Override
    public String lastProjectVolume(Long measuresId) {
        LambdaQueryWrapper<CbCostMeasureActual> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(CbCostMeasureActual::getPlanMeasureId, measuresId)
                .isNotNull(CbCostMeasureActual::getPushTime)
                .orderByDesc(CbCostMeasureActual::getUpdateTime).last(" limit 1");
        CbCostMeasureActual cbCostMeasureActual = cbCostMeasureActualService.getOne(lambdaQueryWrapper);
        if (ObjectUtil.isNotEmpty(cbCostMeasureActual)) {
            return cbCostMeasureActual.getPushDataJson();
        }
        return null;
    }

    @Override
    public List<String> actualMonthList(CbCostMeasureActualBo cbCostMeasureBo) {
        List<String> months = baseMapper.actualMonthList(cbCostMeasureBo);
        return months;
    }

    @Override
    public List<CbProjectExpenseSummaryVo> getSummaryData(Long projectId, Integer dataType, String month) {
        List<CbProjectExpenseSummaryVo> dataList = new ArrayList<>();

        List<CbProjectExpenseSummary> cbProjectExpenseSummaries = cbProjectExpenseSummaryService.queryCbSceneExpenseSummaryDataByType(projectId, dataType);
        if (CollectionUtil.isEmpty(cbProjectExpenseSummaries)) {
            return new ArrayList<>();
        }
        Map<String, BigDecimal> map = new HashMap<>();
        //查询本月实际工程量
        List<CbCostMeasureActualVo> monthActualCostList = cbCostMeasureActualService.getMonthActualCostList(projectId, month);
        if (CollectionUtil.isNotEmpty(monthActualCostList)) {
            map = monthActualCostList.stream()
                    .collect(Collectors.toMap(
                            CbCostMeasureActualVo::getItemContent,     // 把CbCostMeasureActualVo属性提取为map的key
                            CbCostMeasureActualVo::getCostEffective    // 把CbCostMeasureActualVo属性提取为map的value
                    ));
        }

        for (CbProjectExpenseSummary cbProjectExpenseSummary : cbProjectExpenseSummaries) {
            CbProjectExpenseSummaryVo summaryVo = BeanUtil.copyProperties(cbProjectExpenseSummary, CbProjectExpenseSummaryVo.class);
            summaryVo.setMonthsProjectQuantity(map.get(cbProjectExpenseSummary.getExpenseName()));
            dataList.add(summaryVo);

        }


        return dataList;
    }


    /**
     * 根据当前序号、项目id、成本阶段查询父级信息
     *
     * @param number
     * @param projectId
     * @param cbStage
     * @return
     */
    public CbCostMeasure getCbCostMeasure(Long rootMeasuresId, String number, Long projectId) {
        String parentNo = number.substring(0, number.lastIndexOf('.'));
        parentNo = String.valueOf(rootMeasuresId).concat(".").concat(parentNo);
        CbCostMeasure rootCbCostMeasure = new CbCostMeasure();
        rootCbCostMeasure.setNo(parentNo);
        rootCbCostMeasure.setProjectId(projectId);
        LambdaQueryWrapper<CbCostMeasure> tWrapper = Wrappers.lambdaQuery(rootCbCostMeasure);
        CbCostMeasure rootMeasure = this.getOne(tWrapper);
        return rootMeasure;
    }


}
