package cn.palmte.work.service;

import cn.palmte.work.bean.*;
import cn.palmte.work.model.*;
import cn.palmte.work.utils.InterfaceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.jfunc.common.db.QueryHelper;
import top.jfunc.common.db.bean.Page;
import top.jfunc.common.db.utils.Pagination;
import top.jfunc.common.utils.CollectionUtil;
import top.jfunc.common.utils.StrUtil;

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

/**
 * @author xiongshiyan at 2021/10/29 , contact me with email yanshixiong@126.com or phone 15208384257
 */
@Service
public class ProjectService {
    private static final Logger logger = LoggerFactory.getLogger(ProjectService.class);
    @Autowired
    private Pagination pagination;
    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private ActTaskDefService actTaskDefService;
    @Autowired
    private ProjectInstanceRelationRepository projectInstanceRelationRepository;
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private ProjectVisibleRepository projectVisibleRepository;
    @Autowired
    private SysRoleRepository sysRoleRepository;
    @Autowired
    private AdminRepository adminRepository;
    @Autowired
    private ProjectEstimateService projectEstimateService;
    @Autowired
    private ProjectInstanceService projectInstanceService;
    @Autowired
    private ProjectBudgetService projectBudgetService;
    @Autowired
    private NumSeqService numSeqService;
    @Autowired
    private ProjectTaskRecordRepository projectTaskRecordRepository;
    @Autowired
    private ProjectTaskRecordService projectTaskRecordService;

    private QueryHelper getQueryHelper(Map<String, String> searchInfo) {
        /*"CASE p.type WHEN 1 THEN '工程集成类' WHEN 2 THEN '设备集成类' WHEN 3 THEN '战略合作类' ELSE '未知' AS typeDesc," +
                "CASE p.status WHEN 0 THEN '草稿' WHEN 1 THEN '项目创建' WHEN 5 THEN '概算完成' WHEN 10 THEN '预算完成' WHEN 15 THEN '结算中' WHEN 20 THEN '决算完成' ELSE '未知' AS statusDesc," +
                "CASE p.approve_status WHEN 0 THEN '待审核' WHEN 1 THEN '审核通过' WHEN 2 THEN '审核不通过' ELSE '未知' AS approveStatusDesc," +
                */
        QueryHelper queryHelper = new QueryHelper("SELECT p.*, FORMAT(p.contract_amount,2) as contractRound, FORMAT(p.huazhi_product_amount,2) as huazhiRound, FORMAT(p.huizhi_product_amount,2) as huizhiRound, FORMAT(p.huasan_product_amount,2) as huasanRound, FORMAT(p.ziguang_other_amount,2) as ziguangRound" +
                ", FORMAT(p.gross_profit,2) as grossProfitRound, FORMAT(p.gross_profit_margin,2) as grossProfitMarginRound, FORMAT(p.advance_interest_amount,2) as advanceInterestAmountRound, FORMAT(p.advance_peak_amount,2) as advancePeakAmountRound, pe.is_budget as isBudget" +
                ", FORMAT(pe.contract_amount,2) as contractRound2, FORMAT(pe.huazhi_product_amount,2) as huazhiRound2, FORMAT(pe.huizhi_product_amount,2) as huizhiRound2, FORMAT(pe.huasan_product_amount,2) as huasanRound2, FORMAT(pe.ziguang_other_amount,2) as ziguangRound2" +
                ", FORMAT(pe.gross_profit,2) as grossProfitRound2, FORMAT(pe.gross_profit_margin,2) as grossProfitMarginRound2, FORMAT(pe.advance_interest_amount,2) as advanceInterestAmountRound2, FORMAT(pe.advance_peak_amount,2) as advancePeakAmountRound2","project","p");
        queryHelper.leftJoin("project_extend pe", "p.id = pe.project_id");
        if(StrUtil.isNotEmpty(searchInfo.get("status")) && !"-1".equals(searchInfo.get("status"))){
            queryHelper.addCondition("p.status=?", Integer.parseInt(searchInfo.get("status")));
        }
        queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("projectNo")),"p.project_no LIKE ?", "%"+searchInfo.get("projectNo")+"%");
        queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("name")),"p.name LIKE ?", "%"+searchInfo.get("name")+"%");
        queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("creatorName")),"p.creator_name LIKE ?", "%"+searchInfo.get("creatorName")+"%");
        queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("customer")),"p.customer LIKE ?", "%"+searchInfo.get("customer")+"%");
        queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("terminalCustomer")),"p.terminal_customer LIKE ?", "%"+searchInfo.get("terminalCustomer")+"%");
        queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("principal")),"p.principal LIKE ?", "%"+searchInfo.get("principal")+"%");

        ///
        /*if(StrUtil.isNotEmpty(searchInfo.get("approveId"))){
            int approveId = Integer.parseInt(searchInfo.get("approveId"));
            queryHelper.addCondition("p.approve_id=?", approveId);
        }*/
        if(StrUtil.isNotEmpty(searchInfo.get("approveStatus")) && !"-1".equals(searchInfo.get("approveStatus"))){
            int approveStatus = Integer.parseInt(searchInfo.get("approveStatus"));
            //四种状态满足其一即可
            queryHelper.addCondition("((p.status=? AND p.approve_status_estimate=?) OR (p.status=? AND p.approve_status_budget=?) OR (p.status=? AND p.approve_status_settle=?) OR (p.status=? AND p.approve_status_final=?))",
                    StatusEnum.ESTIMATE_ACCOUNTS.getStatus(),approveStatus,
                    StatusEnum.BUDGET_ACCOUNTS.getStatus(),approveStatus,
                    StatusEnum.SETTLE_ACCOUNTS.getStatus(),approveStatus,
                    StatusEnum.FINAL_ACCOUNTS.getStatus(),approveStatus);
        }
        if(StrUtil.isNotEmpty(searchInfo.get("deptId")) && !"-1".equals(searchInfo.get("deptId"))){
            queryHelper.addCondition("p.dept_id=?", Integer.parseInt(searchInfo.get("deptId")));
        }
        if(StrUtil.isNotEmpty(searchInfo.get("type")) && !"-1".equals(searchInfo.get("type"))){
            queryHelper.addCondition("p.type=?", Integer.parseInt(searchInfo.get("type")));
        }
        if(StrUtil.isNotEmpty(searchInfo.get("cooperateType")) && !"-1".equals(searchInfo.get("cooperateType"))){
            queryHelper.addCondition("p.cooperate_type=?", Integer.parseInt(searchInfo.get("cooperateType")));
        }
        if(StrUtil.isNotEmpty(searchInfo.get("underwrittenMode")) && !"-1".equals(searchInfo.get("underwrittenMode"))){
            queryHelper.addCondition("p.underwritten_mode=?", Integer.parseInt(searchInfo.get("underwrittenMode")));
        }
        if(StrUtil.isNotEmpty(searchInfo.get("certainty")) && !"-1".equals(searchInfo.get("certainty"))){
            queryHelper.addCondition("p.certainty=?", Integer.parseInt(searchInfo.get("certainty")));
        }
        if(StrUtil.isNotEmpty(searchInfo.get("estimateStatus")) && !"-1".equals(searchInfo.get("estimateStatus"))){
            queryHelper.addCondition("p.approve_status_estimate>=1 and p.approve_status_estimate<=2");
        }

        if(StrUtil.isNotEmpty(searchInfo.get("extend")) && "0".equals(searchInfo.get("extend"))) {
            if (StrUtil.isNotEmpty(searchInfo.get("stage")) && !"-1".equals(searchInfo.get("stage"))) {
                queryHelper.addCondition("p.stage=?", Integer.parseInt(searchInfo.get("stage")));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("isSecond")) && !"-1".equals(searchInfo.get("isSecond"))) {
                queryHelper.addCondition("p.is_second=?", Integer.parseInt(searchInfo.get("isSecond")));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("signType")) && !"-1".equals(searchInfo.get("signType"))) {
                queryHelper.addCondition("p.sign_type=?", Integer.parseInt(searchInfo.get("signType")));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("resolvePlan")) && !"-1".equals(searchInfo.get("resolvePlan"))) {
                queryHelper.addCondition("p.resolve_plan=?", Integer.parseInt(searchInfo.get("resolvePlan")));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("industryScene")) && !"-1".equals(searchInfo.get("industryScene"))) {
                queryHelper.addCondition("p.industry_scene=?", Integer.parseInt(searchInfo.get("industryScene")));
            }
//            queryHelper.addCondition(StrUtil.isNotEmpty(searchInfo.get("industryScenario")), "p.industry_scenario LIKE ?", "%" + searchInfo.get("industryScenario") + "%");
            /**
             * 只选择了一个时间的情况，就项目时间包括这个时间的
             */
            if (StrUtil.isNotEmpty(searchInfo.get("startDate")) && StrUtil.isEmpty(searchInfo.get("endDate"))) {
                String time = searchInfo.get("startDate") + " 00:00:00";
                queryHelper.addCondition("p.start_date<=? AND p.end_date>=?", time, time);
            }
            if (StrUtil.isNotEmpty(searchInfo.get("endDate")) && StrUtil.isEmpty(searchInfo.get("startDate"))) {
                String time = searchInfo.get("endDate") + " 00:00:00";
                queryHelper.addCondition("p.start_date<=? AND p.end_date>=?", time, time);
            }
            /**
             * 两个时间都选了，则包含项目时间
             */
            if (StrUtil.isNotEmpty(searchInfo.get("startDate")) && StrUtil.isNotEmpty(searchInfo.get("endDate"))) {
                String startTime = searchInfo.get("startDate") + " 00:00:00";
                String endTime = searchInfo.get("endDate") + " 23:59:59";
                queryHelper.addCondition("p.start_date>=? AND p.end_date<=?", startTime, endTime);
            }

            if (StrUtil.isNotEmpty(searchInfo.get("startUpdateDate"))) {
                String time = searchInfo.get("startUpdateDate") + " 00:00:00";
                queryHelper.addCondition("p.last_update_time>=?", time);
            }
            if (StrUtil.isNotEmpty(searchInfo.get("endUpdateDate"))) {
                String time = searchInfo.get("endUpdateDate") + " 00:00:00";
                queryHelper.addCondition("p.last_update_time<=?", time);
            }
            if (StrUtil.isNotEmpty(searchInfo.get("contractStartTime"))) {
                String time = searchInfo.get("contractStartTime") + " 00:00:00";
                queryHelper.addCondition("p.contract_time>=?", time);
            }
            if (StrUtil.isNotEmpty(searchInfo.get("contractEndTime"))) {
                String time = searchInfo.get("contractEndTime") + " 00:00:00";
                queryHelper.addCondition("p.contract_time<=?", time);
            }

            //金额，需判断是概算项目还是过了预算的项目，如过了预算则从project_extend表中取数
            if (StrUtil.isNotEmpty(searchInfo.get("huizhiStart"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.huizhi_product_amount >= ?) or (pe.is_budget = 1 and pe.huizhi_product_amount >= ?))", searchInfo.get("huizhiStart"), searchInfo.get("huizhiStart"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("huizhiEnd"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.huizhi_product_amount <= ?) or (pe.is_budget = 1 and pe.huizhi_product_amount <= ?))", searchInfo.get("huizhiEnd"), searchInfo.get("huizhiEnd"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("huazhiStart"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.huazhi_product_amount >= ?) or (pe.is_budget = 1 and pe.huazhi_product_amount >= ?))", searchInfo.get("huazhiStart"), searchInfo.get("huazhiStart"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("huazhiEnd"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.huazhi_product_amount <= ?) or (pe.is_budget = 1 and pe.huazhi_product_amount <= ?))", searchInfo.get("huazhiEnd"), searchInfo.get("huazhiEnd"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("huasanStart"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.huasan_product_amount >= ?) or (pe.is_budget = 1 and pe.huasan_product_amount >= ?))", searchInfo.get("huasanStart"), searchInfo.get("huasanStart"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("huasanEnd"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.huasan_product_amount <= ?) or (pe.is_budget = 1 and pe.huasan_product_amount <= ?))", searchInfo.get("huasanEnd"), searchInfo.get("huasanEnd"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("otherStart"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.ziguang_other_amount >= ?) or (pe.is_budget = 1 and pe.ziguang_other_amount >= ?))", searchInfo.get("otherStart"), searchInfo.get("otherStart"));
            }
            if (StrUtil.isNotEmpty(searchInfo.get("otherEnd"))) {
                queryHelper.addCondition("((pe.is_budget = 0 and p.ziguang_other_amount <= ?) or (pe.is_budget = 1 and pe.ziguang_other_amount <= ?))", searchInfo.get("otherEnd"), searchInfo.get("otherEnd"));
            }
        }

        //项目可见性，根据角色和人员id
        Admin admin = InterfaceUtil.getAdmin();
        int roleId = admin.getRoleId();
        Integer adminId = admin.getId();
        //自己创建的肯定能看见，配置的可以看见，系统管理员可以看见
        SysRole sysRole = sysRoleRepository.findSysRoleById(roleId);
        if(SysRole.ROLE_TYPE_SYSTEM != sysRole.getType()){
            queryHelper.addCondition("(p.creator_id=? OR p.approve_id=? OR p.id in (SELECT pv1.project_id FROM project_visible pv1 WHERE pv1.type=1 AND pv1.tid=? UNION SELECT pv2.project_id FROM project_visible pv2 WHERE pv2.type=2 AND pv2.tid=?))", adminId, adminId, roleId, adminId);
        }

        if (searchInfo.containsKey("orderType")) {
            if ("projectNoDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.project_no");
            } else if ("projectNoUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.project_no");
            } else if ("projectNameDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.name");
            } else if ("projectNameUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.name");
            } else if ("projectTypeDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.type_desc");
            } else if ("projectTypeUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.type_desc");
            } else if ("underModeDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.underwritten_mode_str");
            } else if ("underModeUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.underwritten_mode_str");
            } else if ("underIntDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.advance_interest_amount");
            } else if ("underIntUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.advance_interest_amount");
            } else if ("underPeakDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.advance_peak_amount");
            } else if ("underPeakUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.advance_peak_amount");
            } else if ("projectContractDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.contract_amount");
            } else if ("projectContractUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.contract_amount");
            } else if ("grossProfitDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.gross_profit");
            } else if ("grossProfitUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.gross_profit");
            } else if ("grossProfitMarginDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.gross_profit_margin");
            } else if ("grossProfitMarginUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.gross_profit_margin");
            } else if ("certaintyDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.certainty_str");
            } else if ("certaintyUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.certainty_str");
            } else if ("huizhiDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.huizhi_product_amount");
            } else if ("huizhiUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.huizhi_product_amount");
            } else if ("huazhiDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.huazhi_product_amount");
            } else if ("huazhiUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.huazhi_product_amount");
            } else if ("huasanDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.huasan_product_amount");
            } else if ("huasanUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.huasan_product_amount");
            } else if ("otherDown".equals(searchInfo.get("orderType"))) {
                queryHelper.addDescOrderProperty("p.ziguang_other_amount");
            } else if ("otherUp".equals(searchInfo.get("orderType"))) {
                queryHelper.addAscOrderProperty("p.ziguang_other_amount");
            }
        } else {
            queryHelper.addDescOrderProperty("p.last_update_time");
        }

        return queryHelper;
    }

    public Page<Project> list(Map<String, String> searchInfo, int pageNumber, int pageSize){
        QueryHelper queryHelper = getQueryHelper(searchInfo);

        Page<Project> page = pagination.paginate(queryHelper.getSql(), Project.class, pageNumber, pageSize);
        List<Project> list = page.getList();
        if(CollectionUtil.isNotEmpty(list)) {
            //查询项目当前审批任务节点
            for (Project project : list) {
                if (project.getApproveStatusBudget() > -1 && project.getIsBudget() == 1) {
                    project.setContractRound(project.getContractRound2());
                    project.setHuizhiRound(project.getHuizhiRound2());
                    project.setHuazhiRound(project.getHuazhiRound2());
                    project.setHuasanRound(project.getHuasanRound2());
                    project.setZiguangRound(project.getZiguangRound2());
                    project.setGrossProfitRound(project.getGrossProfitRound2());
                    project.setGrossProfitMarginRound(project.getGrossProfitMarginRound2());
                    project.setAdvancePeakAmountRound(project.getAdvancePeakAmountRound2());
                    project.setAdvanceInterestAmountRound(project.getAdvanceInterestAmountRound2());
                }
                if(null == project.getStage()){
                  project.setStageName(getStageName(-1));
                }else {
                  project.setStageName(getStageName(project.getStage()));
                }
            }
        }
        return page;
    }

    public String getStageName(int stage){
        if(stage == 0){
            return "S0-概算立项";
        }else if(stage == 1){
          return "S1-项目调研";
        }else if(stage == 2){
          return "S2-方案设计";
        }else if(stage == 3){
          return "S3-预算评估";
        }else if(stage == 4){
          return "S4-招标期";
        }else if(stage == 5){
          return "S5-合同期";
        }else if(stage == 6){
          return "S6-交付期";
        }else if(stage == 7){
          return "S7-结算期";
        }else if(stage == 8){
          return "S8-决算期";
        }else if(stage == 9){
          return "L-项目丢失";
        }else {
          return "无项目阶段";
        }
    }


    /**
     * 找到待我审核项目
     */
    public Page<Project> findMyApproveProjects(Map<String, String> searchInfo, int adminId, int pageNumber, int pageSize){
        //待审核状态的条件
        searchInfo.put("approveStatus", ""+ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());

        QueryHelper queryHelper = getQueryHelper(searchInfo);
        //在列表基础上增加审核人是我
        queryHelper.addCondition("p.approve_id=?", adminId);
        Page<Project> page = pagination.paginate(queryHelper.getSql(), Project.class, pageNumber, pageSize);
        List<Project> list = page.getList();
        if(CollectionUtil.isNotEmpty(list)) {
            //查询项目当前审批任务节点
            for (Project project : list) {
                if (project.getApproveStatusBudget() > -1 && project.getIsBudget() == 1) {
                    project.setContractRound(project.getContractRound2());
                    project.setHuizhiRound(project.getHuizhiRound2());
                    project.setHuazhiRound(project.getHuazhiRound2());
                    project.setHuasanRound(project.getHuasanRound2());
                    project.setZiguangRound(project.getZiguangRound2());
                    project.setGrossProfitRound(project.getGrossProfitRound2());
                    project.setGrossProfitMarginRound(project.getGrossProfitMarginRound2());
                    project.setAdvancePeakAmountRound(project.getAdvancePeakAmountRound2());
                    project.setAdvanceInterestAmountRound(project.getAdvanceInterestAmountRound2());
                }
                if(null == project.getStage()){
                    project.setStageName(getStageName(-1));
                }else {
                    project.setStageName(getStageName(project.getStage()));
                }
            }
        }
        return page;
    }



    public Project getProject(int id){
        return projectRepository.findOne(id);
    }


    public Project addProject(Project project, Admin admin, ApproveStatusEnum approveStatusEnum) {
        String projectNo = numSeqService.generate();
        if (project.getCooperateType() != 1) {
            project.setCollaborator(null);
            project.setCollaboratorUrl(null);
        }
        if (project.getUnderwrittenMode() <= 2) {
            project.setAdvancePeakAmount(new BigDecimal(0));
            project.setAdvanceInterestAmount(new BigDecimal(0));
        }
        project.setProjectNo(projectNo);
        project.setTypeDesc(TypeEnum.parseType(project.getType()).getTypeDesc());
        project.setUnderwrittenModeStr(UnderwrittenModeEnum.parseUnderwrittenMode(project.getUnderwrittenMode()).getUnderwrittenModeStr());
        project.setCooperateTypeStr(CooperateTypeEnum.parseCooperateType(project.getCooperateType()).getCooperateTypeStr());
        project.setCertaintyStr(CertaintyEnum.parseCertainty(project.getCertainty()).getCertaintyStr());
        project.setIsSecondStr(IsSecondEnum.parseIsSecond(project.getIsSecond()).getIsSecondStr());
        project.setSignTypeStr(SignTypeEnum.parseSignType(project.getSignType()).getSignTypeStr());
        project.setResolvePlanStr(ResolvePlanEnum.parseResolvePlan(project.getResolvePlan()).getResolvePlanStr());
        project.setStatus(StatusEnum.ESTIMATE_ACCOUNTS.getStatus());
        project.setStatusDesc(StatusEnum.ESTIMATE_ACCOUNTS.getStatusDesc());
        project.setApproveStatusEstimate(approveStatusEnum.getApproveStatus());
        project.setIndustryScenario(IndustrySceneEnum.parseScene(project.getIndustryScene()).getScenario());
        project.setCreatorId(admin.getId());
        project.setCreatorName(admin.getRealName());

        ProjectConfigBean projectConfigBeanConfig = sysConfigService.getProjectConfigBeanConfig();
        project.setProjectContributionProfitRateThreshold(projectConfigBeanConfig.getProjectContributionProfitRateThreshold());
        project.setUnderwrittenTaxRate(projectConfigBeanConfig.getUnderwrittenTaxRate());

        project.setApproveId(0);
        project.setApproveName("");

        Dept one = deptRepository.findOne(admin.getDeptId());
        project.setDeptId(one.getId());
        project.setDeptName(one.getName());

        Date now = new Date();
        project.setCreateTime(now);
        project.setLastUpdateTime(now);

        project = projectRepository.saveAndFlush(project);
        return project;
    }

    public Project estimateEditProject(Project project, Project projectInDb) {

        //只有如下可以修改
        projectInDb.setName(project.getName());
        projectInDb.setCustomer(project.getCustomer());
        projectInDb.setTerminalCustomer(project.getTerminalCustomer());
        projectInDb.setIndustryScene(project.getIndustryScene());
        projectInDb.setIndustryScenario(IndustrySceneEnum.parseScene(project.getIndustryScene()).getScenario());
        projectInDb.setType(project.getType());
        projectInDb.setTypeDesc(TypeEnum.parseType(project.getType()).getTypeDesc());
        projectInDb.setUnderwrittenMode(project.getUnderwrittenMode());
        projectInDb.setUnderwrittenModeStr(UnderwrittenModeEnum.parseUnderwrittenMode(project.getUnderwrittenMode()).getUnderwrittenModeStr());
        projectInDb.setCooperateType(project.getCooperateType());
        projectInDb.setCooperateTypeStr(CooperateTypeEnum.parseCooperateType(project.getCooperateType()).getCooperateTypeStr());
        projectInDb.setCertainty(project.getCertainty());
        projectInDb.setCertaintyStr(CertaintyEnum.parseCertainty(project.getCertainty()).getCertaintyStr());
        projectInDb.setIsSecond(project.getIsSecond());
        projectInDb.setIsSecondStr(IsSecondEnum.parseIsSecond(project.getIsSecond()).getIsSecondStr());
        projectInDb.setSignType(project.getSignType());
        projectInDb.setSignTypeStr(SignTypeEnum.parseSignType(project.getSignType()).getSignTypeStr());
        projectInDb.setResolvePlan(project.getResolvePlan());
        projectInDb.setResolvePlanStr(ResolvePlanEnum.parseResolvePlan(project.getResolvePlan()).getResolvePlanStr());

        if (project.getCooperateType() != 1) {
            projectInDb.setCollaborator(null);
            projectInDb.setCollaboratorUrl(null);
        } else {
            projectInDb.setCollaborator(project.getCollaborator());
            projectInDb.setCollaboratorUrl(project.getCollaboratorUrl());
        }
        if (project.getUnderwrittenMode() <= 2) {
            projectInDb.setAdvancePeakAmount(new BigDecimal(0));
            projectInDb.setAdvanceInterestAmount(new BigDecimal(0));
        } else {
            projectInDb.setAdvanceInterestAmount(project.getAdvanceInterestAmount());
            projectInDb.setAdvancePeakAmount(project.getAdvancePeakAmount());
        }
        projectInDb.setGrossProfit(project.getGrossProfit());
        projectInDb.setGrossProfitMargin(project.getGrossProfitMargin());
        projectInDb.setStartDate(project.getStartDate());
        projectInDb.setEndDate(project.getEndDate());
        projectInDb.setContractAmount(project.getContractAmount());
        projectInDb.setHuazhiProductAmount(project.getHuazhiProductAmount());
        projectInDb.setHuizhiProductAmount(project.getHuizhiProductAmount());
        projectInDb.setHuasanProductAmount(project.getHuasanProductAmount());
        projectInDb.setZiguangOtherAmount(project.getZiguangOtherAmount());
        projectInDb.setPrincipal(project.getPrincipal());
        projectInDb.setContractTime(project.getContractTime());
        projectInDb.setBidsTime(project.getBidsTime());
        projectInDb.setMainContractCollectionTerms(project.getMainContractCollectionTerms());
        projectInDb.setMainContractResolvePlan(project.getMainContractResolvePlan());
        projectInDb.setCalculationCollection(project.getCalculationCollection());
        projectInDb.setValueRisk(project.getValueRisk());
        projectInDb.setOtherName(project.getOtherName());

        projectInDb.setPlanStartStr(project.getPlanStartStr());
        projectInDb.setPlanEndStr(project.getPlanEndStr());
        /// projectInDb.setApproveStatusEstimate(approveStatusEnum.getApproveStatus());

        projectInDb.setLastUpdateTime(new Date());

        return projectInDb;
    }

    public Project editProject(Project project, Project projectInDb) {

        //只有如下可以修改
        projectInDb.setName(project.getName());
        projectInDb.setCustomer(project.getCustomer());
        projectInDb.setTerminalCustomer(project.getTerminalCustomer());
        projectInDb.setIndustryScene(project.getIndustryScene());
        projectInDb.setIndustryScenario(IndustrySceneEnum.parseScene(project.getIndustryScene()).getScenario());
        projectInDb.setType(project.getType());
        projectInDb.setTypeDesc(TypeEnum.parseType(project.getType()).getTypeDesc());
        projectInDb.setUnderwrittenMode(project.getUnderwrittenMode());
        projectInDb.setUnderwrittenModeStr(UnderwrittenModeEnum.parseUnderwrittenMode(project.getUnderwrittenMode()).getUnderwrittenModeStr());
        projectInDb.setCooperateType(project.getCooperateType());
        projectInDb.setCooperateTypeStr(CooperateTypeEnum.parseCooperateType(project.getCooperateType()).getCooperateTypeStr());
        projectInDb.setCertainty(project.getCertainty());
        projectInDb.setCertaintyStr(CertaintyEnum.parseCertainty(project.getCertainty()).getCertaintyStr());
//        projectInDb.setIsSecond(project.getIsSecond());
//        projectInDb.setIsSecondStr(IsSecondEnum.parseIsSecond(project.getIsSecond()).getIsSecondStr());
//        projectInDb.setSignType(project.getSignType());
//        projectInDb.setSignTypeStr(SignTypeEnum.parseSignType(project.getSignType()).getSignTypeStr());
//        projectInDb.setResolvePlan(project.getResolvePlan());
//        projectInDb.setResolvePlanStr(ResolvePlanEnum.parseResolvePlan(project.getResolvePlan()).getResolvePlanStr());

        projectInDb.setCollaborator(project.getCollaborator());
        projectInDb.setCollaboratorUrl(project.getCollaboratorUrl());
        projectInDb.setGrossProfit(project.getGrossProfit());
        projectInDb.setGrossProfitMargin(project.getGrossProfitMargin());
        projectInDb.setStartDate(project.getStartDate());
        projectInDb.setEndDate(project.getEndDate());
        projectInDb.setContractAmount(project.getContractAmount());
        projectInDb.setHuazhiProductAmount(project.getHuazhiProductAmount());
        projectInDb.setHuizhiProductAmount(project.getHuizhiProductAmount());
        projectInDb.setHuasanProductAmount(project.getHuasanProductAmount());
        projectInDb.setZiguangOtherAmount(project.getZiguangOtherAmount());
//        projectInDb.setPrincipal(project.getPrincipal());
//        projectInDb.setContractTime(project.getContractTime());
//        projectInDb.setBidsTime(project.getBidsTime());
//        projectInDb.setAdvanceInterestAmount(project.getAdvanceInterestAmount());
//        projectInDb.setAdvancePeakAmount(project.getAdvancePeakAmount());
//        projectInDb.setMainContractCollectionTerms(project.getMainContractCollectionTerms());
//        projectInDb.setMainContractResolvePlan(project.getMainContractResolvePlan());
//        projectInDb.setCalculationCollection(project.getCalculationCollection());
        projectInDb.setValueRisk(project.getValueRisk());
        projectInDb.setOtherName(project.getOtherName());

        projectInDb.setPlanStartStr(project.getPlanStartStr());
        projectInDb.setPlanEndStr(project.getPlanEndStr());
        /// projectInDb.setApproveStatusEstimate(approveStatusEnum.getApproveStatus());

        projectInDb.setLastUpdateTime(new Date());

        return projectInDb;
    }


    public ResponseMsg completeTask(int projectId, String json,int approvetype) {
        List<ProjectInstanceRelation> relationList = projectInstanceRelationRepository.findByProjectIdOrderByCreateTimeDesc(projectId);
        if (relationList == null || relationList.isEmpty()) {
            return ResponseMsg.buildFailedMsg("审核失败");
        }
        ProjectInstanceRelation projectInstanceRelation = relationList.get(0);
        JSONObject obj = JSON.parseObject(json);
        actTaskDefService.completeTaskByProcInsId(projectInstanceRelation.getProcessInsId(),
                obj.getIntValue("type"), obj.getString("message"));

        return ResponseMsg.buildSuccessMsg("审核成功",approvetype);
    }


    /**
     * 会签
     *
     * @param projectId
     * @param json
     * @return
     */
    public ResponseMsg skipTask(int projectId, String json) {
        List<ProjectInstanceRelation> relationList = projectInstanceRelationRepository.findByProjectIdOrderByCreateTimeDesc(projectId);
        if (relationList == null || relationList.isEmpty()) {
            return ResponseMsg.buildFailedMsg("会签失败");
        }

        JSONObject obj = JSON.parseObject(json);
        String fileUrl = obj.getString("fileUrl");
        String message = obj.getString("message");

        ProjectInstanceRelation projectInstanceRelation = relationList.get(0);
        return actTaskDefService.skipTaskByProcInsId(projectInstanceRelation.getProcessInsId(), fileUrl, message);
    }

    /**
     * 更新项目状态和审批状态
     */
    public void updateStatusAndApproveStatus(int projectId, StatusEnum statusEnum, ApproveStatusEnum approveStatusEnum, String otherName) {
        Project one = projectRepository.findOne(projectId);
        one.setStatus(statusEnum.getStatus());
        one.setStatusDesc(statusEnum.getStatusDesc());
        one.setOtherName(otherName);

        int approveStatus = approveStatusEnum.getApproveStatus();
        switch (statusEnum) {
            case ESTIMATE_ACCOUNTS:
                one.setApproveStatusEstimate(approveStatus);
                break;
            case BUDGET_ACCOUNTS:
                one.setApproveStatusBudget(approveStatus);
                break;
            case SETTLE_ACCOUNTS:
                one.setApproveStatusSettle(approveStatus);
                break;
            case FINAL_ACCOUNTS:
                one.setApproveStatusFinal(approveStatus);
                break;
            default:
        }

        one.setLastUpdateTime(new Date());
        projectRepository.saveAndFlush(one);
    }


    private static final String PREFIX_ROLE = "r-";
    private static final String PREFIX_USER = "u-";
    /**
     * 把所有的角色和人员按照层级返回
     */
    public List<ZTreeNode> getZTreeNodes(int projectId){
        List<SysRole> roleList = sysRoleRepository.findAllRole();
        //过滤掉系统管理员角色
        roleList = roleList.stream().filter(sysRole -> sysRole.getType()!=SysRole.ROLE_TYPE_SYSTEM).collect(Collectors.toList());


        List<Admin> adminList = adminRepository.getAllEnable();
        List<ZTreeNode> zTreeNodes = new ArrayList<>(roleList.size()+adminList.size());

        List<ProjectVisible> projectVisibles = projectVisibleRepository.findAllByProjectIdEquals(projectId);
        List<ProjectVisible> visibleRoleList = filterByType(projectVisibles, ProjectVisible.TYPE_ROLE);
        List<ProjectVisible> visibleUserList = filterByType(projectVisibles, ProjectVisible.TYPE_USER);


        for (SysRole sysRole : roleList) {
            List<ZTreeNode> filterAdmins = filterAdmins(adminList, sysRole, visibleUserList);
            if(CollectionUtil.isNotEmpty(filterAdmins)){
                //下面有人才要
                zTreeNodes.add(new ZTreeNode(PREFIX_ROLE + sysRole.getId(), "0", sysRole.getName(),
                        isChecked(visibleRoleList, sysRole.getId()), false));
                zTreeNodes.addAll(filterAdmins);
            }
        }

        return zTreeNodes;
    }

    /**
     * 把所有的角色和人员按照层级返回
     */
    public List<ZTreeNode> getZTreeNodes(){
        List<SysRole> roleList = sysRoleRepository.findAllRole();
        //过滤掉系统管理员角色
        roleList = roleList.stream().filter(sysRole -> sysRole.getType()!=SysRole.ROLE_TYPE_SYSTEM).collect(Collectors.toList());


        List<Admin> adminList = adminRepository.getAllEnable();
        List<ZTreeNode> zTreeNodes = new ArrayList<>(roleList.size()+adminList.size());

        List<ProjectVisible> visibleRoleList = new ArrayList<>();
        List<ProjectVisible> visibleUserList = new ArrayList<>();


        for (SysRole sysRole : roleList) {
            List<ZTreeNode> filterAdmins = filterAdmins(adminList, sysRole, visibleUserList);
            if(CollectionUtil.isNotEmpty(filterAdmins)){
                //下面有人才要
                zTreeNodes.add(new ZTreeNode(PREFIX_ROLE + sysRole.getId(), "0", sysRole.getName(),
                        isChecked(visibleRoleList, sysRole.getId()), false));
                zTreeNodes.addAll(filterAdmins);
            }
        }

        return zTreeNodes;
    }

    private List<ZTreeNode> filterAdmins(List<Admin> adminList, SysRole sysRole, List<ProjectVisible> visibleUserList) {
        List<Admin> admins = adminList.stream()
                .filter(a -> sysRole.getId() == a.getRoleId())
                .collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(admins)){
            ArrayList<ZTreeNode> zTreeNodes = new ArrayList<>(admins.size());
            for (Admin admin : admins) {
                zTreeNodes.add(new ZTreeNode(PREFIX_USER+admin.getId(),PREFIX_ROLE+sysRole.getId(),admin.getRealName(),
                        isChecked(visibleUserList, admin.getId()),false));
            }
            return zTreeNodes;
        }

        return Collections.emptyList();
    }

    private boolean isChecked(List<ProjectVisible> visibleList, int id) {
        return visibleList.stream().anyMatch(pv->pv.getTid()==id);
    }
    private List<ProjectVisible> filterByType(List<ProjectVisible> projectVisibles, int type){
        if(CollectionUtil.isEmpty(projectVisibles)){
            return Collections.emptyList();
        }
        return projectVisibles.stream().filter(pv -> pv.getType() == type).collect(Collectors.toList());
    }

    public void saveProjectVisible(Integer projectId, String[] idss) {
        //1.先清除以前的
        List<ProjectVisible> projectVisibles = projectVisibleRepository.findAllByProjectIdEquals(projectId);
        if(CollectionUtil.isNotEmpty(projectVisibles)){
            projectVisibleRepository.deleteInBatch(projectVisibles);
        }
        //2.再保存
        List<ProjectVisible> pvs = new ArrayList<>(idss.length);
        for (String s : idss) {
            //只要用户的，角色的不要
            if(s.startsWith(PREFIX_USER)){
                ProjectVisible pv = new ProjectVisible();
                pv.setProjectId(projectId);
                pv.setType(ProjectVisible.TYPE_USER);
                //去掉前缀
                pv.setTid(Integer.parseInt(s.substring(PREFIX_USER.length())));
                pvs.add(pv);
            }
        }
        projectVisibleRepository.save(pvs);
    }

    public void saveProjectVisibleBatch(String[] split, String[] idss) {
        List<ProjectVisible> pvs = new ArrayList<>();
        for (String projectIdStr : split) {
            Integer projectId = Integer.parseInt(projectIdStr);
            //1.先清除以前的
//            List<ProjectVisible> projectVisibles = projectVisibleRepository.findAllByProjectIdEquals(projectId);
//            if(CollectionUtil.isNotEmpty(projectVisibles)){
//                projectVisibleRepository.deleteInBatch(projectVisibles);
//            }
            //2.再保存

            for (String s : idss) {
                //只要用户的，角色的不要
                if(s.startsWith(PREFIX_USER)){
                    if (projectVisibleRepository.findByProjectIdAndTypeAndTid(projectId,
                            ProjectVisible.TYPE_USER, Integer.parseInt(s.substring(PREFIX_USER.length()))).isEmpty()) {
                        ProjectVisible pv = new ProjectVisible();
                        pv.setProjectId(projectId);
                        pv.setType(ProjectVisible.TYPE_USER);
                        //去掉前缀
                        pv.setTid(Integer.parseInt(s.substring(PREFIX_USER.length())));
                        pvs.add(pv);
                    }
                }
            }
        }
        projectVisibleRepository.save(pvs);
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseMsg deleteProject(int id) {
        Project one = projectRepository.findOne(id);
        if (one == null) {
            return ResponseMsg.buildFailedMsg("项目不存在");
        }

        if (one.getStatus() != StatusEnum.ESTIMATE_ACCOUNTS.getStatus()
                || one.getApproveStatusEstimate() != ApproveStatusEnum.APPROVAL_UNCOMMIT.getApproveStatus()) {
            return ResponseMsg.buildFailedMsg("项目当前状态下不能删除");
        }

        projectRepository.delete(id);

        projectEstimateService.deleteEstimate(id);

        return ResponseMsg.buildSuccessMsg("删除成功");
    }

    public void saveApprove(Project project, Admin admin) throws Exception {
        if (project.getApproveStatusEstimate() == ApproveStatusEnum.APPROVAL_UNCOMMIT.getApproveStatus()) {
            Integer approveStatusEstimate = project.getApproveStatusEstimate();

            projectEstimateService.estimateApprove(approveStatusEstimate, project, admin);
            project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
        } else if (project.getApproveStatusBudget() == ApproveStatusEnum.APPROVAL_UNCOMMIT.getApproveStatus()) {
            Integer approveStatusBudget = project.getApproveStatusBudget();

            projectBudgetService.budgetApprove(approveStatusBudget, project, admin);
            project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
        } else if (project.getApproveStatusSettle() == ApproveStatusEnum.APPROVAL_UNCOMMIT.getApproveStatus()) {
            projectInstanceService.startSettleProcessInstance(project, InterfaceUtil.getAdmin());
            project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
        } else if (project.getApproveStatusFinal() == ApproveStatusEnum.APPROVAL_UNCOMMIT.getApproveStatus()) {
            projectInstanceService.startFinalProcessInstance(project.getId(), InterfaceUtil.getAdmin());
            project.setApproveStatusFinal(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
        } else {
            return ;
        }
        projectRepository.save(project);
    }

    public Project findById(Integer id) {
        QueryHelper queryHelper = new QueryHelper("SELECT p.*, FORMAT(p.contract_amount,2) as contractRound, FORMAT(p.huazhi_product_amount,2) as huazhiRound, FORMAT(p.huizhi_product_amount,2) as huizhiRound, FORMAT(p.huasan_product_amount,2) as huasanRound, FORMAT(p.ziguang_other_amount,2) as ziguangRound" +
                ", FORMAT(p.gross_profit,2) as grossProfitRound, FORMAT(p.gross_profit_margin,2) as grossProfitMarginRound, FORMAT(p.advance_interest_amount,2) as advanceInterestAmountRound, FORMAT(p.advance_peak_amount,2) as advancePeakAmountRound","project","p");
        queryHelper.addCondition("p.id=?", id);
        Project first = pagination.findFirst(queryHelper.getSql(), Project.class);

        if(null == first.getStage()){
            first.setStageName(getStageName(-1));
        }else {
            first.setStageName(getStageName(first.getStage()));
        }
        return first;
    }

    public ProjectBudget findBudgetByProjectId(Integer id) {
        QueryHelper queryHelper = new QueryHelper("SELECT p.*, FORMAT(p.contract_amount_budget,2) as contractRoundBudget, FORMAT(p.huazhi_product_amount_budget,2) as huazhiRoundBudget, FORMAT(p.huizhi_product_amount_budget,2) as huizhiRoundBudget, FORMAT(p.huasan_product_amount_budget,2) as huasanRoundBudget, FORMAT(p.ziguang_other_amount_budget,2) as ziguangRoundBudget" +
                ", FORMAT(p.gross_profit_budget,2) as grossProfitRoundBudget, FORMAT(p.gross_profit_margin_budget,2) as grossProfitMarginRoundBudget, FORMAT(p.advance_interest_amount_budget,2) as advanceInterestAmountRoundBudget, FORMAT(p.advance_peak_amount_budget,2) as advancePeakAmountRoundBudget","project_budget","p");
        queryHelper.addCondition("p.project_id=?", id);
        return pagination.findFirst(queryHelper.getSql(), ProjectBudget.class);
    }

    /**
     * 将该自己审批的任务转交给别人
     *
     * @param json
     * @return
     */
    public ResponseMsg batchUpdateApprove(String json) {
        int myAdminId = InterfaceUtil.getAdminId();
        List<Project> projectList = projectRepository.findByApproveId(myAdminId);
        if (projectList.isEmpty()) {
            return ResponseMsg.buildSuccessMsg("当前没有审批项目需要承接");
        }

        JSONObject obj = JSON.parseObject(json);
        int adminId = obj.getIntValue("adminId");
        Admin targetAdmin = adminRepository.findOne(adminId);

        //更新项目审批人
        Integer targetAdminId = targetAdmin.getId();
        projectRepository.batchUpdateApprove(targetAdminId, targetAdmin.getRealName(), myAdminId);

        for (Project project : projectList) {
            int projectId = project.getId();
            if (projectVisibleRepository.findByProjectIdAndTypeAndTid(projectId,
                    ProjectVisible.TYPE_USER, targetAdminId).isEmpty()) {
                //如果被指定人不可见项目  那么增加一条可进行配置
                ProjectVisible visible = new ProjectVisible();
                visible.setType(ProjectVisible.TYPE_USER);
                visible.setProjectId(projectId);
                visible.setTid(targetAdminId);
                projectVisibleRepository.save(visible);
                logger.info("saveVisible pId:{}, tId:{}", project, targetAdminId);
            }

            //设置流程审批人  保存操作记录
            actTaskDefService.setTaskAssignAndSaveRecord(projectId, targetAdmin);
            logger.info("setTaskAssignAndSaveRecord pId:{}, tId:{}", project, targetAdminId);
        }

        return ResponseMsg.buildSuccessMsg("指定承接人成功");
    }




    /**
     * 退回到指定节点
     * 1、完结的项目允许重启并指定回退节点
     * 2、跨流程（概算、预算等）退回
     * 3、不跨流程退回（例如：仅在预算的审批流中退回某个节点）
     *
     * 因为要跨流程和重启结束流程 所以全部采用重新发起一个流程的方式
     */
    public void rollbackToRecord(String json) throws Exception{
        JSONObject obj = JSON.parseObject(json);
        int taskRecordId = obj.getIntValue("taskRecordId");
        String message = obj.getString("message");
        String rollbackDesc = obj.getString("rollbackDesc");

        ProjectTaskRecord one = projectTaskRecordRepository.findOne(taskRecordId);
        logger.info("rollbackTask  queryTaskRecord : {}", JSONObject.toJSONString(one));

        int projectId = one.getProjectId();
        int taskStatus = one.getTaskStatus();
        StatusEnum statusEnum = one.getStatusByProDefId();
        String proDefKey = one.getProcDefKey();

        //是否回退到发起节点
        boolean isStartTask = (taskStatus == 1);

        Project project = projectRepository.findOne(projectId);
        //项目退回到指定状态
        project.setStatus(statusEnum.getStatus());
        project.setStatusDesc(statusEnum.getStatusDesc());
        project.setLastUpdateTime(new Date());

        //指定审批人
        if (isStartTask) {
            //退回到发起节点 审批人设置为空
            project.setApproveId(0);
            project.setApproveName("");
        }else{
            project.setApproveId(Integer.parseInt(one.getAssigneeId()));
            project.setApproveName(one.getAssigneeName());
        }

        //先全部默认为未知 后面再根据情况更新
        setApproveStatus(statusEnum, isStartTask, project);

        //修改项目
        projectRepository.saveAndFlush(project);
        logger.info("rollbackTask  updateProject : {}", JSONObject.toJSONString(project));

        //保存退回审批记录
        projectTaskRecordService.saveTaskRecordWithRollback(projectId, one, message, rollbackDesc);

        //启动流程
        String processInstanceId = projectInstanceService.startProcessBySystem(project, proDefKey, one);
        logger.info("rollbackTask  startProcessBySystem : {}", processInstanceId);


        //跳到退回任务
        actTaskDefService.skipTaskByProcInsIdAndTaskName(processInstanceId, one.getTaskName());
        logger.info("rollbackTask  skipTaskByProcInsIdAndTaskName : success");
    }

    private void setApproveStatus(StatusEnum statusEnum, boolean isStartTask, Project project) {
        project.setApproveStatusEstimate(-1);
        project.setApproveStatusBudget(-1);
        project.setApproveStatusSettle(-1);
        project.setApproveStatusFinal(-1);

        if (statusEnum == StatusEnum.ESTIMATE_ACCOUNTS) {
            if (isStartTask) {
                //退回到发起节点 状态设置为审批未通过
                project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
            }else{
                project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
            }
        } else if (statusEnum == StatusEnum.BUDGET_ACCOUNTS) {
            project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());

            if (isStartTask) {
                project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
            }else{
                project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
            }

        }else if (statusEnum == StatusEnum.SETTLE_ACCOUNTS) {
            project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
            project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());

            if (isStartTask) {
                project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
            }else{
                project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
            }

        }else if (statusEnum == StatusEnum.FINAL_ACCOUNTS) {
            project.setApproveStatusEstimate(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
            project.setApproveStatusBudget(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());
            project.setApproveStatusSettle(ApproveStatusEnum.APPROVAL_PASSED.getApproveStatus());

            if (isStartTask) {
                project.setApproveStatusFinal(ApproveStatusEnum.APPROVAL_UNPASS.getApproveStatus());
            }else{
                project.setApproveStatusFinal(ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus());
            }

        }
    }

    public ResponseMsg stageRefreshSave(String json,int projectId) {
        JSONObject obj = JSON.parseObject(json);
        int stage = obj.getIntValue("stage");
        String stageRemark = obj.getString("stageRemark");

        Project project = projectRepository.getOne(projectId);
        if(null == project){
            return ResponseMsg.buildFailedMsg("项目不存在");
        }

        project.setStage(stage);
        project.setStageRemark(stageRemark);
        projectRepository.saveAndFlush(project);
        return ResponseMsg.buildSuccessMsg("保存成功");
    }
}
