package com.artfess.cqxy.processManagermant.manager.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.artfess.base.context.BaseContext;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.query.QueryOP;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.cqxy.contract.manager.ContractManager;
import com.artfess.cqxy.contract.model.Contract;
import com.artfess.cqxy.processManagermant.dao.ProgressManageDao;
import com.artfess.cqxy.processManagermant.manager.ProgressManageDefiniteManager;
import com.artfess.cqxy.processManagermant.manager.ProgressManageManager;
import com.artfess.cqxy.processManagermant.model.ProgressManage;
import com.artfess.cqxy.processManagermant.model.ProgressManageDefinite;
import com.artfess.cqxy.processManagermant.vo.AppropriatedlVo;
import com.artfess.cqxy.processManagermant.vo.ProgressManageTotalVo;
import com.artfess.cqxy.projectManagement.enums.ProjectStatusEnum;
import com.artfess.cqxy.projectManagement.manager.ProjectManagementManager;
import com.artfess.cqxy.projectManagement.model.ProjectManagement;
import com.artfess.cqxy.search.enums.FunctionEnum;
import com.artfess.cqxy.search.manager.GlobalRetrievalManager;
import com.artfess.cqxy.search.model.GlobalRetrieval;
import com.artfess.cqxy.statistics.vo.StatisticsVo;
import com.artfess.cqxy.universal.manager.AccessoryManager;
import com.artfess.cqxy.universal.model.Accessory;
import com.artfess.cqxy.utils.BizUtils;
import com.artfess.cqxy.utils.ThreadUtil;
import com.artfess.poi.util.ExcelUtil;
import com.artfess.sysConfig.persistence.manager.SysDictionaryManager;
import com.artfess.sysConfig.persistence.param.DictModel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import groovy.util.logging.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * 过程管理 - 进度管理(BizProgressManage)表服务实现类
 *
 * @author 黎沐华
 * @since 2022-03-04 16:49:30
 */
@Service
public class ProgressManageManagerImpl extends BaseManagerImpl<ProgressManageDao, ProgressManage> implements ProgressManageManager {
    private static Logger log = LoggerFactory.getLogger(ProgressManageManagerImpl.class);
    /**
     * 项目根目录
     */
    public static final String ROOT_PATH = System.getProperty("user.dir");

    /**
     * 模板下载、文件导入临时文件目录名
     */
    public static final String DATA_TEMP_FILE = "tempFile";

    /**
     * 模板下载、文件导入临时文件目录
     */
    public static final String TEMP_DATA_EXCEL = ROOT_PATH + File.separator + DATA_TEMP_FILE;

    @Autowired
    private AccessoryManager accessoryManager;

    @Autowired
    private ProjectManagementManager pm;

    @Autowired
    ProgressManageDefiniteManager progressManageDefiniteManager;

    @Autowired
    private ContractManager contractManager;
//
//    @Autowired
//    private ProgressManageDefiniteManager definiteManager;
    @Resource
    private ProgressManageDao progressManageDao;

    @Autowired
    private SysDictionaryManager sdm;

    @Autowired
    private BaseContext baseContext;

    @Autowired
    private GlobalRetrievalManager grm;

    @Override
    public boolean saveOrUpdateEntity(ProgressManage entity) {
        boolean save = StringUtils.isEmpty(entity.getId());
        Date registerDate = entity.getRegisterDate();
        entity.setRegisterDate(null == registerDate ?new Date(): registerDate);
        //处理已拨款额
//        handleAmountAppropriated(entity);
        // saveOrUpdate() 方法未能正确执行更新

        if(null != entity.getId() && !entity.getId().isEmpty()){

            SimpleDateFormat syd = new SimpleDateFormat("yyyy-MM-dd");

            BigDecimal total = this.baseMapper.getAmountAppropriatedlExceptId(entity.getProjectId(), syd.format(registerDate), entity.getContractId(),entity.getId());
            entity.setAmountAppropriated(total);
        }

        boolean savedMain = null==entity.getId()?save(entity):updateById(entity);
        // 处理拨款明细
        List<ProgressManageDefinite> definites = entity.getDefiniteInfo();
        if(null != definites && definites.size() > 0){
            for(ProgressManageDefinite ele:definites){
                ele.setProgressManageId(entity.getId());
            }
            progressManageDefiniteManager.saveOrUpdateBatch(definites);
        }
        // 处理附件信息
        List<Accessory> flag = entity.getAccessoryInfo();//处理空指针
        List<Accessory> accessoryList = null == flag ? new ArrayList<>() : flag;
        for (Accessory ele : accessoryList) {
            ele.setSourceId(entity.getId());
            ele.setProjectId(entity.getProjectId());
            ele.setDirectory(ProjectStatusEnum.eleven.getCode());
            ele.setGroup("ProgressManage");
            ele.setNode(ProjectStatusEnum.eleven.getCode());
            ele.setCreateBy(baseContext.getCurrentUserId());
            ele.setCreateName(baseContext.getCurrentUserName());
            ele.setCreateTime(LocalDateTime.now());
        }
        // 先清空该ID下的所有附件信息再添加
        accessoryManager.removeBySourceId(entity.getId());
        // 如果没有附件则返回true，不进入添加
        boolean saveAcc = accessoryList.size() == 0 || accessoryManager.saveAccess(accessoryList);
        //更新项目状态
        pm.updateStatusById(entity.getProjectId(), Integer.valueOf(ProjectStatusEnum.eleven.getCode()));
        // 同步到检索表
        GlobalRetrieval globalRetrieval= grm.getByBizId(entity.getId());
        // 如果合同不为空并且收款单位不为空则修改合同的收款人、收款人账号、收款人联系电话
        if(StringUtils.isNotBlank(entity.getContractId())){
            Contract contract = contractManager.getById(entity.getContractId());
            if(null != contract){
                // 收款人
                if(StringUtils.isNotBlank(entity.getRegisterPersonName())){
                    contract.setPayee(entity.getRegisterPersonName());
                }
                // 收款账号
                if(StringUtils.isNotBlank(entity.getHandlerPerson())){
                    contract.setPayeeAccount(entity.getHandlerPerson());
                }
                // 开户行
                if(StringUtils.isNotBlank(entity.getRegisterPersonId())){
                    contract.setPayeeContactPhone(entity.getRegisterPersonId());
                }
                contractManager.update(contract);
            }
        }
        handleRetrieval(save || BeanUtils.isEmpty(globalRetrieval) ?new GlobalRetrieval():globalRetrieval,entity);

        return savedMain && saveAcc;
    }

    private void handleRetrieval(GlobalRetrieval globalRetrieval, ProgressManage entity){
        ProjectManagement projectManagement = pm.getById(entity.getProjectId());
        globalRetrieval.setProjectId(entity.getProjectId());
        globalRetrieval.setProjectName(projectManagement.getProjectName());
        globalRetrieval.setPersonCharge(projectManagement.getProjectManager());
        globalRetrieval.setArchivesType(1);
        globalRetrieval.setBizDataId(entity.getId());
        globalRetrieval.setFunctionCode(FunctionEnum.twentyOne.getCode());
        globalRetrieval.setFunctionName(FunctionEnum.twentyOne.getName());
        globalRetrieval.setBizTableName(FunctionEnum.twentyOne.getTableName());
        globalRetrieval.setDetailsRoteUrl(FunctionEnum.twentyOne.getTableRoteUrl());
        globalRetrieval.setTableRoteUrl(FunctionEnum.twentyOne.getTableRoteUrl());
        globalRetrieval.setTableApiUrl(FunctionEnum.twentyOne.getTableApiUrl());
        globalRetrieval.setDetailsApiUrl(FunctionEnum.twentyOne.getDetailsApiUrl());
        globalRetrieval.setFunctionPath(FunctionEnum.twentyOne.getFunctionPath());
        globalRetrieval.setSearchTitle(entity.getDept()+"_"+entity.getRegisterPersonName()+"_"+entity.getAmountTotalWords()+"_"+
                entity.getHandlerPerson()+"_"+entity.getRegisterPersonName());
        grm.saveOrUpdate(globalRetrieval);
    }

    @Override
    public boolean deleteByIds(List<String> ids) {
        // 同步删除检索表中的信息
        for(String ele:ids){
            grm.remove(1,ele);
        }
        return removeByIds(ids);
    }

    // 处理已拨款额
    private ProgressManage handleAmountAppropriated(ProgressManage entity){
        List<ProgressManage> progressManageList = baseMapper.selectList(
                new QueryWrapper<ProgressManage>().eq("IS_DELE_","0").eq("PROJECT_ID_",entity.getProjectId()));
        List<ProgressManage> result = null == progressManageList ? new ArrayList<>() :progressManageList;
        BigDecimal amountAppropriated = new BigDecimal(0);
        for(ProgressManage ele : result){
            BigDecimal value = null == ele.getPayeeAmountTotal() ? new BigDecimal(0):ele.getPayeeAmountTotal();
            amountAppropriated.add(value);
        }
        entity.setAmountAppropriated(amountAppropriated);
        return entity;
    }

    @Override
    public ProgressManage getById(String id) {
        ProgressManage result = baseMapper.getById(id);
        result.setAccessoryInfo(accessoryManager.getAccessoryBySourceId(id));
        List<ProgressManageDefinite> definites = progressManageDefiniteManager.list(new QueryWrapper<ProgressManageDefinite>().
                eq("PROGRESS_MANAGE_ID_",result.getId()).eq("IS_DELE_","0"));
        result.setDefiniteInfo(definites);
        return result;
    }

    @Override
    public PageList<ProgressManage> queryAllByPage(QueryFilter<ProgressManage> queryFilter) {
//        BizUtils.handleFilter(queryFilter, "bpm", true);
        queryFilter.addFilter( "bpm.IS_DELE_", "0", QueryOP.EQUAL);
        queryFilter.addFilter("pm.IS_DELE_", "0", QueryOP.EQUAL);
        queryFilter.addFilter("pm.VALID_FLAG_", 1, QueryOP.EQUAL);
//        if (hasContract) {
//            queryFilter.addFilter("bc.IS_DELE_", "0", QueryOP.EQUAL);
//        }
        IPage<ProgressManage> result =
                baseMapper.queryAllByPage(
                        convert2IPage(queryFilter.getPageBean()),
                        convert2Wrapper(queryFilter, currentModelClass()));
        // 附件、拨款明细处理
        List<ProgressManage> records = result.getRecords();
        for (ProgressManage ele : records) {
            ele.setAccessoryInfo(accessoryManager.getAccessoryBySourceId(ele.getId()));

            List<ProgressManageDefinite> definites = progressManageDefiniteManager.list(new QueryWrapper<ProgressManageDefinite>().
                    eq("PROGRESS_MANAGE_ID_",ele.getId()).eq("IS_DELE_","0"));
            ele.setDefiniteInfo(definites);
        }

        return new PageList<>(result);
    }

    @Override
    public void importExcelData(MultipartFile file, String projectId, String contractId/**, String registerPersonId, String registerPersonName**/) {
        Assert.notNull(projectId, "项目ID不能为空");
        Assert.notNull(contractId, "合同ID不能为空");

        // 获取字典
//        List<DictModel> fundPlan = sdm.queryDictListItemsByCode("jdgl-sfyzjjh");
        List<DictModel> purpose = sdm.queryDictListItemsByCode("jdgl-yt");
//        List<DictModel> billType = sdm.queryDictListItemsByCode("jdgl-jspj");

        try(InputStream inputStream = file.getInputStream();) {
            // 获取数据
            List<ProgressManage> data = ExcelImportUtil.importExcel(inputStream,ProgressManage.class,new ImportParams());
            data = removeNullData(data);
            for(ProgressManage ele:data){
                ele.setProjectId(projectId);
                ele.setContractId(contractId);
                ele.setPurpose(BizUtils.getDicCodeByValue(purpose,ele.getPurpose()));
                handleAmountAppropriated(ele);
                // 保存数据 & 同步到检索表
                save(ele);
                handleRetrieval(new GlobalRetrieval(),ele);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List<ProgressManage> removeNullData(List<ProgressManage> data){
        List<ProgressManage> result = new ArrayList<>();
        data.forEach(e->{
            if(StringUtils.isNotEmpty(e.getPurpose())){
                result.add(e);
            }
        });
        return result;
    }

    @Override
    public void exportDataToExcel(QueryFilter<ProgressManage> queryFilter, HttpServletResponse response) throws IOException {
        String fileName = "过程管理-进度管理-导出结果";

        // 获取字典
        List<DictModel> fundPlan = sdm.queryDictListItemsByCode("jdgl-sfyzjjh");
        List<DictModel> purpose = sdm.queryDictListItemsByCode("jdgl-yt");
        List<DictModel> billType = sdm.queryDictListItemsByCode("jdgl-jspj");

        // 获取数据
        BizUtils.handleFilter(queryFilter, "bpm", true);
        List<ProgressManage> data = baseMapper.queryAllByPage(
                       convert2IPage(new PageBean(0, -1, false)),
                       convert2Wrapper(queryFilter, currentModelClass())).
               getRecords();

        if(null==data||data.size()==0){
            throw new RuntimeException("没有要导出的的数据！");
        }

        // 翻译字典
        for(ProgressManage ele : data){
            ele.setPurpose(BizUtils.getDicValueByCode(purpose, ele.getPurpose()));
            ele.setHaveFundPlan(BizUtils.getDicValueByCode(fundPlan, ele.getHaveFundPlan()));
            ele.setSettlementBillType(BizUtils.getDicValueByCode(billType, ele.getSettlementBillType()));
            if(null != ele.getTotalInvestment()){
                ele.setTotalInvestment(ele.getTotalInvestment().stripTrailingZeros());
            }
            if(null != ele.getPayeeAmountTotal()){
                ele.setPayeeAmountTotal(ele.getPayeeAmountTotal().stripTrailingZeros());
            }
            if(null != ele.getAmountAppropriated()){
                ele.setAmountAppropriated(ele.getAmountAppropriated().stripTrailingZeros());
            }
            if(null != ele.getOutputValue()){
                ele.setOutputValue(ele.getOutputValue().stripTrailingZeros());
            }
        }

        // EasyPoi 导出参数、样式、表格格式设置
        ExportParams exportParams = BizUtils.getExportParams(fileName);
        fileName += ".xlsx";

        // 导出下载excel文件
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ProgressManage.class, data);
        ExcelUtil.downloadExcel(workbook, fileName, response);
    }

    @Override
    public void updateProjectIdByProiectId(String oldProjectIds, String newProjectId) {
        UpdateWrapper<ProgressManage> wrapper = new UpdateWrapper<ProgressManage>()
                .set(StringUtils.isNotBlank(newProjectId), "PROJECT_ID_", newProjectId)
                .in("PROJECT_ID_", Arrays.asList(oldProjectIds.split(",")));
        this.update(wrapper);
    }

    @Override
    public List<Map<String, Object>> queryInvestment(StatisticsVo statisticsVo) {
        return this.baseMapper.queryInvestment(statisticsVo);
    }

    @Override
    public BigDecimal getAmountAppropriatedl(AppropriatedlVo appropriatedlVo) {
        String projectId = appropriatedlVo.getProjectId(),
        registerDate = appropriatedlVo.getRegisterDate();
        String contractId = appropriatedlVo.getContractId();
        if(StringUtils.isBlank(registerDate)){
            registerDate = LocalDate.now().toString();
        }
        BigDecimal total = this.baseMapper.getAmountAppropriatedl(projectId, registerDate, contractId);
        if (total == null){
            total = new BigDecimal(0);
        }
        return total;
    }



    @Override
    public BigDecimal getNotAppropriatedl(String projectId, String registerDate) {
        if(StringUtils.isBlank(registerDate)){
            registerDate = LocalDate.now().toString();
        }
        BigDecimal total = this.baseMapper.getNotAppropriatedl(projectId, registerDate);
        if (total == null){
            total = new BigDecimal(0);
        }
        return total;
    }

    @Override
    public void exportApprovalForm(String id, HttpServletResponse response) throws IOException {
        String fileName = "西永微电园公司项目拨（付）款申请审批单";
        List<DictModel> purpose = sdm.queryDictListItemsByCode("jdgl-yt");
        ProgressManage data = baseMapper.getById(id);

//        InputStream inputStream = new ClassPathResource("template/appropriationApprovalTemplate.xls").getInputStream();
        File filePath = new File(TEMP_DATA_EXCEL);
        if (!filePath.exists() && !filePath.isDirectory()) {
            filePath.mkdirs();
        }
        File file = new File(TEMP_DATA_EXCEL + File.separator + "appropriationApprovalTemplate.xls");
        FileInputStream inputStream = new FileInputStream(file);
        HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
        HSSFSheet sheet = workbook.getSheetAt(0);

        Date registerDate = data.getRegisterDate();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(registerDate);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH)+1;
        int day = calendar.get(Calendar.DATE);
        sheet.addMergedRegion(new CellRangeAddress(1,1,22,23));

        HSSFRow row1 = sheet.getRow(1);
        row1.getCell(0).setCellValue(row1.getCell(0).getStringCellValue()+data.getDept());

        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        row1.getCell(22).setCellStyle(style);

        row1.getCell(22).setCellValue(year);
        row1.getCell(25).setCellValue(month);
        row1.getCell(27).setCellValue(day);

        HSSFRow row2 = sheet.getRow(2);
        row2.getCell(5).setCellValue(BeanUtils.isEmpty(data.getProjectInfo())?"":data.getProjectInfo().getProjectName());
        row2.getCell(22).setCellValue(BizUtils.getDicValueByCode(purpose, data.getPurpose()));

        HSSFRow row3 = sheet.getRow(3);
        NumberFormat nf = new DecimalFormat("￥,###.##");

        BigDecimal bigDecimal1 = new BigDecimal(null == data.getTotalInvestment() ? "0.00" : data.getTotalInvestment().toPlainString());
        if (new BigDecimal(bigDecimal1.intValue()).compareTo(bigDecimal1)==0) {
            row3.getCell(5).setCellValue(nf.format(bigDecimal1).toString()+".00");
        }else {
            bigDecimal1.setScale(2);
            row3.getCell(5).setCellValue(nf.format(bigDecimal1));
        }

        BigDecimal bigDecimal2 = new BigDecimal(null == data.getAmountAppropriated() ? "0.00" : data.getAmountAppropriated().toPlainString());
        if (new BigDecimal(bigDecimal2.intValue()).compareTo(bigDecimal2)==0) {
            row3.getCell(22).setCellValue(nf.format(bigDecimal2).toString()+".00");
        }else{
            bigDecimal2.setScale(2);
            row3.getCell(22).setCellValue(nf.format(bigDecimal2));
        }

        sheet.getRow(4).getCell(5).setCellValue(StringUtils.isEmpty(data.getMeasurementData())?"":"    "+data.getMeasurementData());

        sheet.getRow(8).getCell(24).setCellValue(data.getSettlementBillNum());

        HSSFRow row11 = sheet.getRow(11);
        row11.getCell(6).setCellValue(data.getRegisterPersonName());
        row11.getCell(22).setCellValue(data.getRegisterPersonId());

        HSSFRow row12 = sheet.getRow(12);
        row12.getCell(6).setCellValue(data.getHandlerPerson());

        BigDecimal bigDecimal3 = new BigDecimal(null == data.getPayeeAmountTotal() ? "0.00" : data.getPayeeAmountTotal().toPlainString());
        if (new BigDecimal(bigDecimal3.intValue()).compareTo(bigDecimal3)==0) {
            row12.getCell(23).setCellValue(nf.format(bigDecimal3).toString()+".00");
        }else {
            bigDecimal3.setScale(2);
            row12.getCell(23).setCellValue(nf.format(bigDecimal3));
        }

        // 大写金额行，模板中全部初始化为 零X，获取数据从后往前写，遇到整或元，则跳过分角
        HSSFRow row13 = sheet.getRow(13);
//        String capital = null==data.getAmountTotalWords()?"":data.getAmountTotalWords();

//        String capital = null==data.getPayeeAmountTotal()?"":StringUtil.convertToChineseNumeral(data.getPayeeAmountTotal().doubleValue());
        String capital = null==data.getPayeeAmountTotal()?"":StringUtil.convertToChineseNumeral2(data.getPayeeAmountTotal().doubleValue());
        for(int i = 28; i>6 ;i--){
//            if(capital.length()>0){
//                if("整".equals(String.valueOf(capital.charAt(capital.length()-1)))){
//                    capital = capital.substring(0,capital.length()-1);
//                    i = 23;
//                }
//                if("元".equals(String.valueOf(capital.charAt(capital.length()-1)))){
//                    i = 23;
//                }
                row13.getCell(i).setCellValue(String.valueOf(capital.charAt(capital.length()-1)));
                capital = capital.substring(0,capital.length()-1);
//            }
        }

        ExcelUtil.downloadExcel(workbook, fileName, response);
    }

    @Override
    public ProgressManageTotalVo getProgressByProjectId(ProgressManageTotalVo progressManageTotalVoParam){
        ProgressManageTotalVo progressManageTotalVo = progressManageDao.getProgressManageTotalByProjectId(progressManageTotalVoParam);
        progressManageTotalVo = progressManageTotalVo == null ? new ProgressManageTotalVo() : progressManageTotalVo;
        // 如果总投资为空设置总投资为项目总投资
        BigDecimal totalInvestment = progressManageTotalVo.getTotalInvestment();
        if(null == totalInvestment || totalInvestment.stripTrailingZeros().equals(BigDecimal.ZERO.stripTrailingZeros())){
            ProjectManagement projectManagement = pm.get(progressManageTotalVoParam.getProjectId());
            if(null != projectManagement && null != projectManagement.getProjectMoney()){
                progressManageTotalVo.setTotalInvestment(projectManagement.getProjectMoney());
            }else {
                progressManageTotalVo.setTotalInvestment(BigDecimal.ZERO);
            }
        }
        // 格式化已拨款金额
//        if(progressManageTotalVo.getAmountAppropriated() != null && !progressManageTotalVo.getAmountAppropriated().equals(BigDecimal.ZERO)){
//            progressManageTotalVo.setAmountAppropriated(progressManageTotalVo.getAmountAppropriated()
//                    .setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
//        }
//        if(progressManageTotalVo.getTotalInvestment() == null){
//            progressManageTotalVo.setTotalInvestment(BigDecimal.ZERO);
//        }
        // 设置支付比例
        if(progressManageTotalVo.getTotalInvestment()==null)progressManageTotalVo.setTotalInvestment(BigDecimal.ZERO);
        if(progressManageTotalVo.getAmountAppropriated()==null)progressManageTotalVo.setAmountAppropriated(BigDecimal.ZERO);
        if(BigDecimal.ZERO.equals(progressManageTotalVo.getTotalInvestment()) || BigDecimal.ZERO.equals(progressManageTotalVo.getAmountAppropriated())){
            progressManageTotalVo.setMeasurementData("-");
        }else {
            //计算支付比例（=已拨款金额/总投资*100%）
            BigDecimal percentageNum = progressManageTotalVo.getAmountAppropriated()
                    // 计算支付比例并转化为百分比
                    .divide(progressManageTotalVo.getTotalInvestment(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).stripTrailingZeros();
            if (null == percentageNum){
                progressManageTotalVo.setMeasurementData("-");
            }else if(percentageNum.compareTo(new BigDecimal("100")) > 0) {
                progressManageTotalVo.setMeasurementData("100%");
            }else {
                progressManageTotalVo.setMeasurementData(percentageNum.toString()+"%");
            }
        }
        //计算未拨款金额（=总投资减去已拨款金额）
        if(progressManageTotalVo.getTotalInvestment().equals(BigDecimal.ZERO)){
            progressManageTotalVo.setOutputValue(BigDecimal.ZERO);
        }else {
            BigDecimal outputValue = progressManageTotalVo.getTotalInvestment().subtract(progressManageTotalVo.getAmountAppropriated())
                    .setScale(0, BigDecimal.ROUND_HALF_UP).stripTrailingZeros();
            progressManageTotalVo.setOutputValue(outputValue);
        }
        return progressManageTotalVo;
    }

    @Override
    public ProgressManage getProgressManageByProjectId(String projectId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.isNotNull("REGISTER_PERSON_NAME_");
        queryWrapper.eq("PROJECT_ID_", projectId);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public BigDecimal geTamountAppropriatedTotalByProjectId(String projectId) {

        return baseMapper.geTamountAppropriatedTotalByProjectId(projectId);
    }


    @Override
    public BigDecimal geTamountAppropriatedTotalByProjectIdAndPurpose(String projectId, boolean operation, String purpose) {
        List<String> purposeList = Arrays.asList(purpose.split(","));
        QueryWrapper<ProgressManage> queryWrapper = new QueryWrapper<ProgressManage>();
        queryWrapper.select("ifnull(sum(PAYEE_AMOUNT_TOTAL_),0) as totalInvestment");
        if(operation){
            queryWrapper.eq("IS_DELE_", 0).eq("PROJECT_ID_", projectId).in("PURPOSE_", purposeList);
        }else {
            queryWrapper.eq("IS_DELE_", 0).eq("PROJECT_ID_", projectId).notIn("PURPOSE_", purposeList);
        }

        ProgressManage one = this.getOne(queryWrapper);
//        baseMapper.geTamountAppropriatedTotalByProjectIdAndPurpose(projectId, purpose)
        return one.getTotalInvestment();
    }

    @Override
    public List<ProgressManage> fundplanGetProgressManage(LambdaQueryWrapper<ProgressManage> lambdaQueryWrapper){
        return super.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public BigDecimal getTwoPrice(String projectId, String purpose) {
        List<String> purposeList = Arrays.asList(purpose.split(","));
        return baseMapper.getTwoPrice(projectId,purposeList);
    }


    /**
     * 多线程重算项目支付
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recalManage(String projectId) {
        /**
        查支付表，查出有多少个项目，
         项目分线程。线程里查出项目的所有支付明细。合同分组（忽略合同为空的数据），查出已拨款额（查询sum）修改
         */
       if(null !=projectId && !"".equals(projectId)){
           //手动传值不使用线程处理
           List<String> projectIds= Arrays.asList(projectId);
           recalManageLogic(projectIds);
       } else {
           List<String> projectIds= baseMapper.selectProjectIds();
           //线程处理
           if(null != projectIds && projectIds.size() > 0){
               log.info("项目支付重算开始，项目共"+projectIds.size()+"个");
               //分线程
               int projectNum = projectIds.size();
               //暂定4线程
               int threadNum = 4;
               //每个线程任务数量
               int threadTaskNum = ThreadUtil.getThreadTaskNum(threadNum, projectNum);
               //开启多线程
               log.info("项目支付重算-开启多线程, 任务数[{}], 线程数[{}], 每个线程任务数[{}]", projectNum, threadNum, threadTaskNum);
               for (int i = 0; i < threadNum; i++) {
                   List<String> subList = projectIds.subList(i * threadTaskNum, i == threadNum - 1 ? projectNum : (i + 1) * threadTaskNum);
                   Future<Object[]> future = ThreadUtil.publicPool.submit(new ProgressManageManagerImpl.recalManageThread(subList));
               }
           }
       }
       log.info("项目支付重算全部完成");
    }


    /**
     * 多线程开启
     */
    class recalManageThread implements Callable<Object[]> {
        private List<String> projectIds;
        public recalManageThread(List<String> projectIds) {
            this.projectIds = projectIds;
        }

        @Override
        @SuppressWarnings("unchecked")
        public Object[] call() {
            recalManageLogic(projectIds);
            return new Object[] {};
        }
    }


    /**
     * 项目支付重算 实际执行逻辑
     * @param projectIds
     */
    private void recalManageLogic(List<String> projectIds) {

        for (String projectId : projectIds) {
            log.info("项目支付重算开始-projectId:"+projectId);
            //查询该项目的支付情况 排除没有合同的
            List<ProgressManage> progressManageList= baseMapper.selectByProjectId(projectId);

            if(null != progressManageList && progressManageList.size() > 0){
                for (ProgressManage progressManage : progressManageList) {
                    String contractId = progressManage.getContractId();
                    Date registerDate = progressManage.getRegisterDate();
                    String id = progressManage.getId();
                    BigDecimal amountAppropriated = baseMapper.selectAmountAppropriated(projectId,contractId,registerDate,id);
                    progressManage.setAmountAppropriated(amountAppropriated);
                }
                this.saveOrUpdateBatch(progressManageList);
            }
            log.info("项目支付重算完成-projectId:"+projectId);
        }
    }

}

