package cn.com.ctop.kuaishou.modules.report.service.impl;

import cn.com.ctop.common.module.service.IAccountCompensationService;
import cn.com.ctop.common.module.service.ISysUserService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.kuaishou.modules.report.entity.KuaishouOperationReport;
import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouOperationReportMapper;
import cn.com.ctop.kuaishou.modules.report.service.IKuaishouOperationReportService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.entity.SysUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.system.entity.SysOperateRel;
import org.jeecg.modules.system.mapper.SysOperateRelMapper;
import org.jeecg.modules.system.service.ISysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 运营绩效
 *
 * @author jeecg-boot
 * 2022-09-20
 * @version V1.0
 */
@Service
public class KuaishouOperationReportServiceImpl extends ServiceImpl<KuaishouOperationReportMapper, KuaishouOperationReport> implements IKuaishouOperationReportService {

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private SysOperateRelMapper operateRelMapper;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private IAccountCompensationService compensationService;

    @Override
    public Result<Object> queryToutiaoMonthlyData(Integer time, String role, String userId, Integer pageNo, Integer pageSize) {
        List<Integer> monthInt = getMonthInt(time);
        Map<String, String> quarterMap = DateUtils.getCurrQuarter(time);
        String nextMonthEndDate = null;
        if (time != 4) {
            nextMonthEndDate = DateUtils.getCurrQuarter(time + 1).get("endDate");
        } else {
            nextMonthEndDate = quarterMap.get("endDate");
        }
        String startDate = quarterMap.get("startDate");
        String endDate = quarterMap.get("endDate");
        List<String> roleCode = new ArrayList<>();
        if (Check.isNull(role)) {
            //运营助理
            roleCode.add("operationAssistant");
            //头条运营经理
            roleCode.add("kuaishouOperationManager");
            roleCode.add("touTiaoOperationManager");
            //运营专员
            roleCode.add("operator");
        } else {
            if ("manager".equals(role)) {
                roleCode.add("kuaishouOperationManager");
                roleCode.add("touTiaoOperationManager");
            } else {
                roleCode.add(role);
            }
        }
        //查询岗位变动人员
        List<JSONObject> changeRoleUserIds = sysUserService.getQuarterlyChangeRoleOperators(roleCode, userId, startDate, endDate);
        //查询在职人员 1-在职
        List<JSONObject> onJobUserIds = sysUserService.getQuarterlyOnJobOperators(roleCode, userId, 1, changeRoleUserIds);
        //查询离职人员 2-离职
        List<JSONObject> offJobUserIds = sysUserService.getQuarterlyOffJobOperators(roleCode, userId, 2, startDate, nextMonthEndDate);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }
        onJobUserIds.addAll(changeRoleUserIds);
        onJobUserIds.addAll(offJobUserIds);
        List<JSONObject> dataList = new ArrayList<>();
        if (!Check.isNull(onJobUserIds)) {
            PageHelper.startPage(pageNo, pageSize);
            dataList = baseMapper.getTtMonthlyOnJobOperatorsCharge(onJobUserIds, dates.getInteger("startDate1"), dates.getInteger("endDate1"),
                    dates.getInteger("startDate2"), dates.getInteger("endDate2"), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
            consolidateData(onJobUserIds, dataList);
        }
        return Result.ok(new PageInfo<>(dataList));
    }

    @Override
    public Result<Object> queryToutiaoQuarterlyCharge(Integer time, String role, String userId, Integer pageNo, Integer pageSize) throws Exception {
        Map<String, String> quarterMap = DateUtils.getCurrQuarter(time);
        String nextMonthEndDate = null;
        if (time != 4) {
            nextMonthEndDate = DateUtils.getCurrQuarter(time + 1).get("endDate");
        } else {
            nextMonthEndDate = quarterMap.get("endDate");
        }
        String startDate = quarterMap.get("startDate");
        String endDate = quarterMap.get("endDate");
        List<String> roleCode = new ArrayList<>();
        if (Check.isNull(role)) {
            //运营助理
            roleCode.add("operationAssistant");
            //头条运营经理
            roleCode.add("kuaishouOperationManager");
            roleCode.add("touTiaoOperationManager");
            //运营专员
            roleCode.add("operator");
        } else {
            if ("manager".equals(role)) {
                roleCode.add("kuaishouOperationManager");
                roleCode.add("touTiaoOperationManager");
            } else {
                roleCode.add(role);
            }
        }

        //查询岗位变动人员
        List<JSONObject> changeRoleUserIds = sysUserService.getQuarterlyChangeRoleOperators(roleCode, userId, startDate, endDate);
        //查询在职人员 1-在职
        List<JSONObject> onJobUserIds = sysUserService.getQuarterlyOnJobOperators(roleCode, userId, 1, changeRoleUserIds);
        //查询离职人员 2-离职
        List<JSONObject> offJobUserIds = sysUserService.getQuarterlyOffJobOperators(roleCode, userId, 2, startDate, nextMonthEndDate);
        JSONObject dates = new JSONObject();

        List<JSONObject> dataList = new ArrayList<>();
        if (!Check.isNull(changeRoleUserIds)) {
            dataList.addAll(getTtChangeRoleData(changeRoleUserIds, time, quarterMap));
        }
        if (!Check.isNull(offJobUserIds)) {
            dataList.addAll(getTtOffJobUserData(offJobUserIds, time, quarterMap));
        }
        if (!Check.isNull(onJobUserIds)) {
            dataList.addAll(getTtOnJobUserData(onJobUserIds, time, quarterMap));
        }
        //后端代码排序
        if (!Check.isNull(dataList)) {
            Collections.sort(dataList, new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    return o2.getDouble("totalCharge").compareTo(o1.getDouble("totalCharge"));
                }
            });
        }
        return Result.ok(dataList);
    }

    /**
     * 查询岗位变动人员数据
     * 助理->专员
     * 专员->经理
     */
    private List<JSONObject> getTtChangeRoleData(List<JSONObject> users, Integer time, Map<String, String> dateMap) throws Exception {
        List<JSONObject> data = new ArrayList<>();
        Integer startDate = DateUtils.getDateInteger(dateMap.get("startDate"));
        Integer endDate = DateUtils.getDateInteger(dateMap.get("endDate"));
        for (JSONObject user : users) {
            //统计绩效有效月份
            String upTime = user.getString("upTime");
            if (!Check.isNull(upTime)) {
                Integer startMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd HH:mm:ss", upTime));
                Integer endMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd", dateMap.get("endDate")));
                user.put("monthCount", endMonth - startMonth + 1);
            }
        }
        List<Integer> monthInt = getMonthInt(time);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }
        for (JSONObject user : users) {
            String userId = user.getString("userId");
            String roleCode = user.getString("roleCode");
            //有效月份 =3，本季度全算給自己
            if (user.getInteger("monthCount") == 3) {
                Set<JSONObject> operatorsCharge = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), startDate, endDate);
                JSONObject obj = operatorsCharge.iterator().next();
                if ("operator".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate1"), dates.getInteger("endDate1"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    /*
                岗位变为经理，则分别计算转换前后的助理服务数据，转换前的算给自己（有效助理数据）
                * */
                } else if (roleCode.contains("Manager")) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                //有效助理数据
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                }
                data.add(obj);

                //有效月份=2，本季度第二，三个月算有效数据 计算绩效
            } else if (user.getInteger("monthCount") == 2) {
                //总数据
                Set<JSONObject> operatorsCharge = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), startDate, endDate);
                JSONObject obj = operatorsCharge.iterator().next();
                //有效数据
                Set<JSONObject> validQuarterlyCharge = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), dates.getInteger("startDate2"), endDate);
                JSONObject valid = validQuarterlyCharge.iterator().next();
                obj.put("validFWCharge", valid.getBigDecimal("totalCharge"));
                obj.put("validKFCharge", valid.getBigDecimal("KFCharge"));
                /*
                岗位变为专员，计算专员后是否带助理，计算助理数据
                * */
                if ("operator".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, dates.getInteger("startDate2"), endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    /*
                岗位变为经理，则分别计算转换前后的助理服务数据，转换前的算给自己（有效助理数据）
                * */
                } else if (roleCode.contains("Manager")) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    BigDecimal validAssistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                //有效助理数据
                                validAssistantCharge = validAssistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    obj.put("validAssistantCharge", validAssistantCharge);
                }
                data.add(obj);
            } else {
                //总数据
                Set<JSONObject> operatorsCharge = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), startDate, endDate);
                JSONObject obj = operatorsCharge.iterator().next();
                //有效数据
                Set<JSONObject> validQuarterlyCharge = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), dates.getInteger("startDate3"), endDate);
                JSONObject valid = validQuarterlyCharge.iterator().next();
                obj.put("validFWCharge", valid.getBigDecimal("totalCharge"));
                obj.put("validKFCharge", valid.getBigDecimal("KFCharge"));
                 /*
                岗位变为专员，计算专员后是否带助理，计算助理数据
                * */
                if ("operator".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, dates.getInteger("startDate3"), endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    /*
                岗位变为经理，则分别计算转换前后的助理服务数据，转换前的算给自己（有效助理数据）
                * */
                } else if (roleCode.contains("Manager")) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    BigDecimal validAssistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                //有效助理数据
                                validAssistantCharge = validAssistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                validAssistantCharge = validAssistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    obj.put("validAssistantCharge", validAssistantCharge);
                }
                data.add(obj);
            }
        }
        if (!Check.isNull(data)) {
            consolidateData(users, data);
            consolidateTtData(data, dateMap, dates, null);
        }
        return data;
    }

    /**
     * 查询在职人员数据
     */
    private List<JSONObject> getTtOnJobUserData(List<JSONObject> users, Integer time, Map<String, String> dateMap) throws ParseException {
        List<JSONObject> data = new ArrayList<>();
        Integer startDate = DateUtils.getDateInteger(dateMap.get("startDate"));
        Integer endDate = DateUtils.getDateInteger(dateMap.get("endDate"));

        List<String> userIds = new ArrayList<>();
        JSONObject userMap = new JSONObject();
        for (JSONObject user : users) {
            userIds.add(user.getString("userId"));
            userMap.put(user.getString("userId"), user);
        }
        List<Integer> monthInt = getMonthInt(time);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }

        Set<JSONObject> list = baseMapper.getTtQuarterlyOnJobOperatorsCharge(userIds, startDate, endDate);
        for (JSONObject dat : list) {
            String userId = dat.getString("userId");
            JSONObject user = userMap.getJSONObject(userId);
            if (!Check.isNull(user)) {
                String roleCode = user.getString("roleCode");
                if (!"operationAssistant".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate1"), dates.getInteger("endDate1"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                            }
                        }
                    }
                    dat.put("assistantCharge", assistantCharge);
                    data.add(dat);
                } else {
                    dat.put("assistantCharge", "0.0");
                    data.add(dat);
                }
            }
        }
        if (!Check.isNull(data)) {
            consolidateData(users, data);
            consolidateTtData(data, dateMap, null, null);
        }
        return data;
    }


    /**
     * 查询离职人员数据
     */
    private List<JSONObject> getTtOffJobUserData(List<JSONObject> users, Integer time, Map<String, String> dateMap) throws ParseException {
        List<JSONObject> data = new ArrayList<>();
        Integer startDate = DateUtils.getDateInteger(dateMap.get("startDate"));
        for (JSONObject user : users) {
            //统计绩效有效月份
            String quitTime = user.getString("quitTime");
            if (!Check.isNull(quitTime)) {
                Integer startMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd", dateMap.get("startDate")));
                Integer endMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd", quitTime));
                Integer num = endMonth - startMonth + 1;
                user.put("monthCount", num > 3 ? 3 : num);
            }
        }
        List<Integer> monthInt = getMonthInt(time);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }
        for (JSONObject user : users) {
            String userId = user.getString("userId");
            Integer quitTime = DateUtils.getDateInteger(DateUtils.formatDate(user.getString("quitTime"), "yyyy-MM-dd"));
            Set<JSONObject> operatorsCharge = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(user.getString("userId")), startDate, quitTime);
            JSONObject dat = operatorsCharge.iterator().next();
            String roleCode = user.getString("roleCode");
            if (!"operationAssistant".equals(roleCode)) {
                List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, quitTime);
                BigDecimal assistantCharge = new BigDecimal("0.0");
                if (!Check.isNull(relList)) {
                    for (SysOperateRel rel : relList) {
                        String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                        String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                        String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                        String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                        String quitTimeStr = DateUtils.getMonth("yyyyMMdd", String.valueOf(quitTime));
                        if (month.equals(month1)) {
                            Integer endDate = dates.getInteger("endDate1");
                            if (quitTimeStr.equals(month1)) {
                                endDate = quitTime;
                            }
                            Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate1"), endDate);
                            assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                        } else if (month.equals(month2)) {
                            Integer endDate = dates.getInteger("endDate2");
                            if (quitTimeStr.equals(month2)) {
                                endDate = quitTime;
                            }
                            Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), endDate);
                            assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                        } else if (month.equals(month3)) {
                            Integer endDate = dates.getInteger("endDate3");
                            if (quitTimeStr.equals(month3)) {
                                endDate = quitTime;
                            }
                            Set<JSONObject> AssistantData = baseMapper.getTtQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), endDate);
                            assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("totalCharge"));
                        }
                    }
                }
                dat.put("assistantCharge", assistantCharge);
                data.add(dat);
            } else {
                dat.put("assistantCharge", "0.0");
                data.add(dat);
            }
        }
        if (!Check.isNull(data)) {
            consolidateData(users, data);
            consolidateTtData(data, dateMap, null, "off");
        }
        return data;
    }

    /**
     * 整合头条数据
     */
    private void consolidateTtData(List<JSONObject> data, Map<String, String> dateMap, JSONObject dates, String type) throws ParseException {
        for (JSONObject datum : data) {
            String userId = datum.getString("userId");
            SysUser userEntity = sysUserService.getById(userId);

            //助理消耗
            BigDecimal assistantCharge = datum.getBigDecimal("assistantCharge");
            //服务消耗
            BigDecimal fwCharge = datum.getBigDecimal("totalCharge");
            datum.put("FWCharge", fwCharge);

            BigDecimal validFWCharge = datum.getBigDecimal("validFWCharge");
            if (!Check.isNull(validFWCharge)) {
                fwCharge = validFWCharge;
            }

            //经理管理消耗提成
            BigDecimal manageChargeCommission = null;

            Integer monthCount = datum.getInteger("monthCount");

            if (!Check.isNull(userEntity) && !Check.isNull(userEntity.getPaySalary())) {
                String paySalary = userEntity.getPaySalary();
                datum.put("paySalary", "1".equals(paySalary) ? "是" : "否");
            }
            //扣减金额
            BigDecimal d = compensationService.getCompMoney(userId, dateMap.get("startDate"), dateMap.get("endDate"));
            BigDecimal compMoney = Check.isNull(d) ? new BigDecimal("0.0") : d;
            datum.put("compMoney", compMoney);
            //发放金额
            BigDecimal putMoney = null;
            //季度管理消耗
            String roleName = datum.getString("roleName");
            if (roleName.contains("经理")) {
                BigDecimal managenCharge = null;
                //陈思宇和李超 就这俩人定制化
                if ("4afe739502ae4258a18c36a000d7ff20".equals(userId) ||
                        "f6a6843879c949618e4a859140c8a127".equals(userId)) {
                    List<String> managers = baseMapper.getTtManagers(userId, DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate")));
                    managenCharge = baseMapper.getTtManageChargeCommission(Arrays.asList(userId), DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate")));
                    managenCharge = managenCharge.add(baseMapper.getTtManageChargeCommission(managers, DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate"))));
                } else {
                    if ("off".equals(type)) {
                        managenCharge = baseMapper.getTtManageChargeCommission(Arrays.asList(userId), DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(DateUtils.formatDate(datum.getString("quitTime"), "yyyy-MM-dd")));
                    } else {
                        if (Check.isNull(monthCount) || monthCount == 3) {
                            managenCharge = baseMapper.getTtManageChargeCommission(Arrays.asList(userId), DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate")));
                        } else if (monthCount == 2) {
                            managenCharge = baseMapper.getTtManageChargeCommission(Arrays.asList(userId), dates.getInteger("startDate2"), DateUtils.getDateInteger(dateMap.get("endDate")));
                        } else if (monthCount == 1) {
                            managenCharge = baseMapper.getTtManageChargeCommission(Arrays.asList(userId), dates.getInteger("startDate3"), DateUtils.getDateInteger(dateMap.get("endDate")));
                        }
                    }
                }
                //季度管理消耗
                datum.put("manageCharge", managenCharge);
                //季度管理服务提成
                manageChargeCommission = managenCharge.multiply(new BigDecimal("0.003")).multiply(new BigDecimal("0.2")).setScale(3, BigDecimal.ROUND_HALF_UP);
                datum.put("manageChargeCommission", manageChargeCommission);
                //运营赔付扣罚比例
                datum.put("operateCompensation", "-");
                //经理 30%/总监 20%赔付比例
                datum.put("manageCompensation", "30%");
                //是否达标
                datum.put("FWChargeIsOk", "是");
                //是否符合发放
                datum.put("paySalary", "是");

                //有效助理消耗
                BigDecimal validAssistantCharge = datum.getBigDecimal("validAssistantCharge");
                if (Check.isNull(validAssistantCharge)) {
                    validAssistantCharge = new BigDecimal("0.0");
                }
                //服务消耗提成
                BigDecimal FWChargeCommission = fwCharge.add(validAssistantCharge).multiply(new BigDecimal("0.003")).setScale(3, BigDecimal.ROUND_HALF_UP);
                datum.put("FWChargeCommission", FWChargeCommission);
                //发放金额
                putMoney = manageChargeCommission.subtract(compMoney);
            } else {
                datum.put("manageCharge", "-");
                datum.put("manageChargeCommission", "-");
                datum.put("operateCompensation", "50%");
                datum.put("manageCompensation", "-");
                //服务消耗
                fwCharge = fwCharge.add(assistantCharge);
                //服务消耗提成
                BigDecimal FWChargeCommission = fwCharge.multiply(new BigDecimal("0.003")).setScale(3, BigDecimal.ROUND_HALF_UP);
                datum.put("FWChargeCommission", FWChargeCommission);

                Long value = 2400000l;
                if (!Check.isNull(monthCount)) {
                    value = 800000l * monthCount;
                }
                if (fwCharge.doubleValue() >= value) {
                    //是否达标
                    datum.put("FWChargeIsOk", "是");
                    //是否符合发放
                    datum.put("paySalary", "是");
                } else {
                    datum.put("FWChargeIsOk", "否");
                    datum.put("paySalary", "否");
                }

                putMoney = FWChargeCommission.subtract(compMoney);
            }
            datum.put("putMoney", putMoney);
            if (!Check.isNull(userEntity) && !Check.isNull(userEntity.getPaySalaryRatio())) {
                //发放系数
                datum.put("paySalaryRatio", userEntity.getPaySalaryRatio());
                if ("是".equals(datum.getString("paySalary"))) {
                    //最终发放金额
                    datum.put("finalPutMoney", new BigDecimal(userEntity.getPaySalaryRatio()).multiply(putMoney).setScale(3, BigDecimal.ROUND_HALF_UP));
                } else {
                    datum.put("finalPutMoney", 0.0);
                }
            } else {
                datum.put("paySalaryRatio", 1);
                if ("是".equals(datum.getString("paySalary"))) {
                    datum.put("finalPutMoney", putMoney);
                } else {
                    datum.put("finalPutMoney", 0.0);
                }
            }
        }
    }
    /*---------------------------------------------------------------------------------*/

    @Override
    public Result<Object> queryKuaishouMonthlyData(Integer time, String role, String userId, Integer pageNo, Integer pageSize) {
        List<Integer> monthInt = getMonthInt(time);
        Map<String, String> quarterMap = DateUtils.getCurrQuarter(time);
        String nextMonthEndDate = null;
        if (time != 4) {
            nextMonthEndDate = DateUtils.getCurrQuarter(time + 1).get("endDate");
        } else {
            nextMonthEndDate = quarterMap.get("endDate");
        }
        String startDate = quarterMap.get("startDate");
        String endDate = quarterMap.get("endDate");
        List<String> roleCode = new ArrayList<>();
        if (Check.isNull(role)) {
            //运营助理
            roleCode.add("operationAssistant");
            //快手运营经理
            roleCode.add("kuaishouOperationManager");
            roleCode.add("touTiaoOperationManager");
            //运营专员
            roleCode.add("operator");
        } else {
            if ("manager".equals(role)) {
                roleCode.add("kuaishouOperationManager");
                roleCode.add("touTiaoOperationManager");
            } else {
                roleCode.add(role);
            }
        }

        //查询岗位变动人员
        List<JSONObject> changeRoleUserIds = sysUserService.getQuarterlyChangeRoleOperators(roleCode, userId, startDate, endDate);
        //查询在职人员 1-在职
        List<JSONObject> onJobUserIds = sysUserService.getQuarterlyOnJobOperators(roleCode, userId, 1, changeRoleUserIds);
        //查询离职人员 2-离职
        List<JSONObject> offJobUserIds = sysUserService.getQuarterlyOffJobOperators(roleCode, userId, 2, startDate, nextMonthEndDate);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }
        onJobUserIds.addAll(changeRoleUserIds);
        onJobUserIds.addAll(offJobUserIds);
        List<JSONObject> dataList = new ArrayList<>();
        if (!Check.isNull(onJobUserIds)) {
            PageHelper.startPage(pageNo, pageSize);
            dataList = baseMapper.getKsMonthlyOnJobOperatorsCharge(onJobUserIds, dates.getInteger("startDate1"), dates.getInteger("endDate1"),
                    dates.getInteger("startDate2"), dates.getInteger("endDate2"), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
            consolidateData(onJobUserIds, dataList);
        }
        return Result.ok(new PageInfo<>(dataList));
    }

    /**
     *
     */
    @Override
    public Result<Object> queryKuaishouQuarterlyCharge(Integer time, String role, String userId, Integer pageNo, Integer pageSize) throws Exception {
        Map<String, String> quarterMap = DateUtils.getCurrQuarter(time);
        String nextMonthEndDate = null;
        if (time != 4) {
            nextMonthEndDate = DateUtils.getCurrQuarter(time + 1).get("endDate");
        } else {
            nextMonthEndDate = quarterMap.get("endDate");
        }
        Map<String, String> nextQuarterMap = DateUtils.getCurrQuarter(time);
        String startDate = quarterMap.get("startDate");
        String endDate = quarterMap.get("endDate");
        List<String> roleCode = new ArrayList<>();
        if (Check.isNull(role)) {
            //运营助理
            roleCode.add("operationAssistant");
            //快手运营经理
            roleCode.add("kuaishouOperationManager");
            roleCode.add("touTiaoOperationManager");
            //运营专员
            roleCode.add("operator");
        } else {
            if ("manager".equals(role)) {
                roleCode.add("kuaishouOperationManager");
                roleCode.add("touTiaoOperationManager");
            } else {
                roleCode.add(role);
            }
        }

        //查询岗位变动人员
        List<JSONObject> changeRoleUserIds = sysUserService.getQuarterlyChangeRoleOperators(roleCode, userId, startDate, endDate);
        //查询在职人员 1-在职
        List<JSONObject> onJobUserIds = sysUserService.getQuarterlyOnJobOperators(roleCode, userId, 1, changeRoleUserIds);
        //查询离职人员 2-离职
        List<JSONObject> offJobUserIds = sysUserService.getQuarterlyOffJobOperators(roleCode, userId, 2, startDate, nextMonthEndDate);
        JSONObject dates = new JSONObject();

        List<JSONObject> dataList = new ArrayList<>();
        if (!Check.isNull(changeRoleUserIds)) {
            dataList.addAll(getChangeRoleData(changeRoleUserIds, time, quarterMap));
        }
        if (!Check.isNull(offJobUserIds)) {
            dataList.addAll(getOffJobUserData(offJobUserIds, time, quarterMap));
        }
        if (!Check.isNull(onJobUserIds)) {
            dataList.addAll(getOnJobUserData(onJobUserIds, time, quarterMap));
        }
        //后端代码排序
        if (!Check.isNull(dataList)) {
            Collections.sort(dataList, new Comparator<JSONObject>() {
                @Override
                public int compare(JSONObject o1, JSONObject o2) {
                    return o2.getDouble("totalCharge").compareTo(o1.getDouble("totalCharge"));
                }
            });
        }
        return Result.ok(dataList);
    }

    /**
     * 查询岗位变动人员数据
     * 助理->专员
     * 专员->经理
     */
    private List<JSONObject> getChangeRoleData(List<JSONObject> users, Integer time, Map<String, String> dateMap) throws Exception {
        List<JSONObject> data = new ArrayList<>();
        Integer startDate = DateUtils.getDateInteger(dateMap.get("startDate"));
        Integer endDate = DateUtils.getDateInteger(dateMap.get("endDate"));
        for (JSONObject user : users) {
            //统计绩效有效月份
            String upTime = user.getString("upTime");
            if (!Check.isNull(upTime)) {
                Integer startMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd HH:mm:ss", upTime));
                Integer endMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd", dateMap.get("endDate")));
                user.put("monthCount", endMonth - startMonth + 1);
            }
        }
        List<Integer> monthInt = getMonthInt(time);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }
        for (JSONObject user : users) {
            String userId = user.getString("userId");
            String roleCode = user.getString("roleCode");
            //有效月份 =3，本季度全算給自己
            if (user.getInteger("monthCount") == 3) {
                Set<JSONObject> operatorsCharge = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), startDate, endDate);
                JSONObject obj = operatorsCharge.iterator().next();
                if ("operator".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate1"), dates.getInteger("endDate1"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    /*
                岗位变为经理，则分别计算转换前后的助理服务数据，转换前的算给自己（有效助理数据）
                * */
                } else if (roleCode.contains("Manager")) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                //有效助理数据
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                }
                data.add(obj);

                //有效月份=2，本季度第二，三个月算有效数据 计算绩效
            } else if (user.getInteger("monthCount") == 2) {
                //总数据
                Set<JSONObject> operatorsCharge = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), startDate, endDate);
                JSONObject obj = operatorsCharge.iterator().next();
                //有效数据
                Set<JSONObject> validQuarterlyCharge = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), dates.getInteger("startDate2"), endDate);
                JSONObject valid = validQuarterlyCharge.iterator().next();
                obj.put("validFWCharge", valid.getBigDecimal("FWCharge"));
                obj.put("validKFCharge", valid.getBigDecimal("KFCharge"));
                /*
                岗位变为专员，计算专员后是否带助理，计算助理数据
                * */
                if ("operator".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, dates.getInteger("startDate2"), endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    /*
                岗位变为经理，则分别计算转换前后的助理服务数据，转换前的算给自己（有效助理数据）
                * */
                } else if (roleCode.contains("Manager")) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    BigDecimal validAssistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                //有效助理数据
                                validAssistantCharge = validAssistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    obj.put("validAssistantCharge", validAssistantCharge);
                }
                data.add(obj);
            } else {
                //总数据
                Set<JSONObject> operatorsCharge = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), startDate, endDate);
                JSONObject obj = operatorsCharge.iterator().next();
                //有效数据
                Set<JSONObject> validQuarterlyCharge = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(userId), dates.getInteger("startDate3"), endDate);
                JSONObject valid = validQuarterlyCharge.iterator().next();
                obj.put("validFWCharge", valid.getBigDecimal("FWCharge"));
                obj.put("validKFCharge", valid.getBigDecimal("KFCharge"));
                 /*
                岗位变为专员，计算专员后是否带助理，计算助理数据
                * */
                if ("operator".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, dates.getInteger("startDate3"), endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    /*
                岗位变为经理，则分别计算转换前后的助理服务数据，转换前的算给自己（有效助理数据）
                * */
                } else if (roleCode.contains("Manager")) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    BigDecimal validAssistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                //有效助理数据
                                validAssistantCharge = validAssistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                validAssistantCharge = validAssistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    obj.put("assistantCharge", assistantCharge);
                    obj.put("validAssistantCharge", validAssistantCharge);
                }
                data.add(obj);
            }
        }
        if (!Check.isNull(data)) {
            consolidateData(users, data);
            consolidateData(data, dateMap, dates, null);
        }
        return data;
    }

    /**
     * 查询在职人员数据
     */
    private List<JSONObject> getOnJobUserData(List<JSONObject> users, Integer time, Map<String, String> dateMap) throws ParseException {
        List<JSONObject> data = new ArrayList<>();
        Integer startDate = DateUtils.getDateInteger(dateMap.get("startDate"));
        Integer endDate = DateUtils.getDateInteger(dateMap.get("endDate"));

        List<String> userIds = new ArrayList<>();
        JSONObject userMap = new JSONObject();
        for (JSONObject user : users) {
            userIds.add(user.getString("userId"));
            userMap.put(user.getString("userId"), user);
        }
        List<Integer> monthInt = getMonthInt(time);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }

        Set<JSONObject> list = baseMapper.getKsQuarterlyOnJobOperatorsCharge(userIds, startDate, endDate);
        for (JSONObject dat : list) {
            String userId = dat.getString("userId");
            JSONObject user = userMap.getJSONObject(userId);
            if (!Check.isNull(user)) {
                String roleCode = user.getString("roleCode");
                if (!"operationAssistant".equals(roleCode)) {
                    List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, endDate);
                    BigDecimal assistantCharge = new BigDecimal("0.0");
                    if (!Check.isNull(relList)) {
                        for (SysOperateRel rel : relList) {
                            String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                            String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                            String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                            String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                            if (month.equals(month1)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate1"), dates.getInteger("endDate1"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month2)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), dates.getInteger("endDate2"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            } else if (month.equals(month3)) {
                                Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), dates.getInteger("endDate3"));
                                assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                            }
                        }
                    }
                    dat.put("assistantCharge", assistantCharge);
                    data.add(dat);
                } else {
                    dat.put("assistantCharge", "0.0");
                    data.add(dat);
                }
            }
        }

        if (!Check.isNull(data)) {
            consolidateData(users, data);
            consolidateData(data, dateMap, null, null);
        }
        return data;
    }


    /**
     * 查询离职人员数据
     */
    private List<JSONObject> getOffJobUserData(List<JSONObject> users, Integer time, Map<String, String> dateMap) throws ParseException {
        List<JSONObject> data = new ArrayList<>();
        Integer startDate = DateUtils.getDateInteger(dateMap.get("startDate"));
        for (JSONObject user : users) {
            //统计绩效有效月份
            String quitTime = user.getString("quitTime");
            if (!Check.isNull(quitTime)) {
                Integer startMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd", dateMap.get("startDate")));
                Integer endMonth = Integer.valueOf(DateUtils.getMonth("yyyy-MM-dd", quitTime));
                Integer num = endMonth - startMonth + 1;
                user.put("monthCount", num > 3 ? 3 : num);
            }
        }
        List<Integer> monthInt = getMonthInt(time);
        JSONObject dates = new JSONObject();
        int count = 1;
        for (Integer month : monthInt) {
            Map<String, String> monthMap = DateUtils.getFirstDayAndLastDayOfTheSpecifiedMonth(DateUtils.getYear(), month);
            dates.put("startDate" + count, DateUtils.getDateInteger(monthMap.get("start")));
            dates.put("endDate" + count, DateUtils.getDateInteger(monthMap.get("end")));
            count++;
        }
        for (JSONObject user : users) {
            String userId = user.getString("userId");
            Integer quitTime = DateUtils.getDateInteger(DateUtils.formatDate(user.getString("quitTime"), "yyyy-MM-dd"));
            Set<JSONObject> operatorsCharge = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(user.getString("userId")), startDate, quitTime);
            JSONObject dat = operatorsCharge.iterator().next();
            String roleCode = user.getString("roleCode");
            if (!"operationAssistant".equals(roleCode)) {
                List<SysOperateRel> relList = operateRelMapper.getMoreByOperatorId(userId, startDate, quitTime);
                BigDecimal assistantCharge = new BigDecimal("0.0");
                if (!Check.isNull(relList)) {
                    for (SysOperateRel rel : relList) {
                        String month = DateUtils.getMonth("yyyy-MM", rel.getStatMonth());
                        String month1 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate1"));
                        String month2 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate2"));
                        String month3 = DateUtils.getMonth("yyyyMMdd", dates.getString("startDate3"));
                        String quitTimeStr = DateUtils.getMonth("yyyyMMdd", String.valueOf(quitTime));
                        if (month.equals(month1)) {
                            Integer endDate = dates.getInteger("endDate1");
                            if (quitTimeStr.equals(month1)) {
                                endDate = quitTime;
                            }
                            Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate1"), endDate);
                            assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                        } else if (month.equals(month2)) {
                            Integer endDate = dates.getInteger("endDate2");
                            if (quitTimeStr.equals(month2)) {
                                endDate = quitTime;
                            }
                            Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate2"), endDate);
                            assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                        } else if (month.equals(month3)) {
                            Integer endDate = dates.getInteger("endDate3");
                            if (quitTimeStr.equals(month3)) {
                                endDate = quitTime;
                            }
                            Set<JSONObject> AssistantData = baseMapper.getKsQuarterlyOnJobOperatorsCharge(Arrays.asList(rel.getAssistantId()), dates.getInteger("startDate3"), endDate);
                            assistantCharge = assistantCharge.add(AssistantData.iterator().next().getBigDecimal("FWCharge"));
                        }
                    }
                }
                dat.put("assistantCharge", assistantCharge);
                data.add(dat);
            } else {
                dat.put("assistantCharge", "0.0");
                data.add(dat);
            }
        }
        if (!Check.isNull(data)) {
            consolidateData(users, data);
            consolidateData(data, dateMap, null, "off");
        }
        return data;
    }


    private void consolidateData(List<JSONObject> data, Map<String, String> dateMap, JSONObject dates, String type) throws ParseException {
        for (JSONObject datum : data) {
            String userId = datum.getString("userId");
            SysUser userEntity = sysUserService.getById(userId);

            //助理消耗
            BigDecimal assistantCharge = datum.getBigDecimal("assistantCharge");
            //服务消耗
            BigDecimal fwCharge = datum.getBigDecimal("FWCharge");
            BigDecimal validFWCharge = datum.getBigDecimal("validFWCharge");
            if (!Check.isNull(validFWCharge)) {
                fwCharge = validFWCharge;
            }
            //框返消耗
            BigDecimal kfCharge = datum.getBigDecimal("KFCharge");
            BigDecimal validKFCharge = datum.getBigDecimal("validKFCharge");
            if (!Check.isNull(validKFCharge)) {
                kfCharge = validKFCharge;
            }
            //框返消耗提成
            BigDecimal KFChargeCommission = null;
            //经理管理消耗提成
            BigDecimal manageChargeCommission = null;

            Integer monthCount = datum.getInteger("monthCount");

            if (!Check.isNull(userEntity) && !Check.isNull(userEntity.getPaySalary())) {
                String paySalary = userEntity.getPaySalary();
                datum.put("paySalary", "1".equals(paySalary) ? "是" : "否");
            }
            //扣减金额
            BigDecimal d = compensationService.getCompMoney(userId, dateMap.get("startDate"), dateMap.get("endDate"));
            BigDecimal compMoney = Check.isNull(d) ? new BigDecimal("0.0") : d;
            datum.put("compMoney", compMoney);
            //发放金额
            BigDecimal putMoney = null;
            //季度管理消耗
            String roleName = datum.getString("roleName");
            if (roleName.contains("经理")) {
                BigDecimal managenCharge = null;
                //陈思宇和李超 就这俩人定制化
                if ("4afe739502ae4258a18c36a000d7ff20".equals(userId) ||
                        "f6a6843879c949618e4a859140c8a127".equals(userId)) {
                    List<String> managers = baseMapper.getManagers(userId, DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate")));
                    managenCharge = baseMapper.getManageChargeCommission(Arrays.asList(userId), DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate")));
                    managenCharge = managenCharge.add(baseMapper.getManageChargeCommission(managers, DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate"))));
                } else {
                    if ("off".equals(type)) {
                        managenCharge = baseMapper.getManageChargeCommission(Arrays.asList(userId), DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(DateUtils.formatDate(datum.getString("quitTime"), "yyyy-MM-dd")));
                    } else {
                        if (Check.isNull(monthCount) || monthCount == 3) {
                            managenCharge = baseMapper.getManageChargeCommission(Arrays.asList(userId), DateUtils.getDateInteger(dateMap.get("startDate")), DateUtils.getDateInteger(dateMap.get("endDate")));
                        } else if (monthCount == 2) {
                            managenCharge = baseMapper.getManageChargeCommission(Arrays.asList(userId), dates.getInteger("startDate2"), DateUtils.getDateInteger(dateMap.get("endDate")));
                        } else if (monthCount == 1) {
                            managenCharge = baseMapper.getManageChargeCommission(Arrays.asList(userId), dates.getInteger("startDate3"), DateUtils.getDateInteger(dateMap.get("endDate")));
                        }
                    }
                }
                //季度管理消耗
                datum.put("manageCharge", managenCharge);
                //季度管理服务提成
                manageChargeCommission = managenCharge.multiply(new BigDecimal("0.003")).multiply(new BigDecimal("0.2")).setScale(3, BigDecimal.ROUND_HALF_UP);
                datum.put("manageChargeCommission", manageChargeCommission);
                //运营赔付扣罚比例
                datum.put("operateCompensation", "-");
                //经理 30%/总监 20%赔付比例
                datum.put("manageCompensation", "30%");
                //是否达标
                datum.put("FWChargeIsOk", "是");
                //是否符合发放
                datum.put("paySalary", "是");

                //有效助理消耗
                BigDecimal validAssistantCharge = datum.getBigDecimal("validAssistantCharge");
                if (Check.isNull(validAssistantCharge)) {
                    validAssistantCharge = new BigDecimal("0.0");
                }
                //服务消耗提成
                BigDecimal FWChargeCommission = fwCharge.add(validAssistantCharge).multiply(new BigDecimal("0.003")).setScale(3, BigDecimal.ROUND_HALF_UP);
                datum.put("FWChargeCommission", FWChargeCommission);
                //发放金额
                putMoney = manageChargeCommission.subtract(compMoney);
            } else {
                datum.put("manageCharge", "-");
                datum.put("manageChargeCommission", "-");
                datum.put("operateCompensation", "50%");
                datum.put("manageCompensation", "-");
                //服务消耗提成
                BigDecimal FWChargeCommission = fwCharge.add(assistantCharge).multiply(new BigDecimal("0.003")).setScale(3, BigDecimal.ROUND_HALF_UP);
                datum.put("FWChargeCommission", FWChargeCommission);

                Long value = 2400000l;
                if (!Check.isNull(monthCount)) {
                    value = 800000l * monthCount;
                }
                if (fwCharge.doubleValue() >= value) {
                    //是否达标
                    datum.put("FWChargeIsOk", "是");
                    //是否符合发放
                    datum.put("paySalary", "是");
                } else {
                    datum.put("FWChargeIsOk", "否");
                    datum.put("paySalary", "否");
                }

                if (kfCharge.doubleValue() >= 300000) {
                    //季度框返是否满足30w
                    datum.put("KFChargeIsOk", "是");
                    //框返消耗提成
                    KFChargeCommission = kfCharge.multiply(new BigDecimal("0.003")).setScale(3, BigDecimal.ROUND_HALF_UP);
                    datum.put("KFChargeCommission", KFChargeCommission);
                } else {
                    KFChargeCommission = new BigDecimal("0.0");
                    datum.put("KFChargeIsOk", "否");
                    datum.put("KFChargeCommission", "-");
                }

                putMoney = FWChargeCommission.add(KFChargeCommission).subtract(compMoney);
            }
            datum.put("putMoney", putMoney);
            if (!Check.isNull(userEntity) && !Check.isNull(userEntity.getPaySalaryRatio())) {
                //发放系数
                datum.put("paySalaryRatio", userEntity.getPaySalaryRatio());
                if ("是".equals(datum.getString("paySalary"))) {
                    //最终发放金额
                    datum.put("finalPutMoney", new BigDecimal(userEntity.getPaySalaryRatio()).multiply(putMoney).setScale(3, BigDecimal.ROUND_HALF_UP));
                } else {
                    datum.put("finalPutMoney", 0.0);
                }
            } else {
                datum.put("paySalaryRatio", 1);
                if ("是".equals(datum.getString("paySalary"))) {
                    datum.put("finalPutMoney", putMoney);
                } else {
                    datum.put("finalPutMoney", 0.0);
                }
            }
        }
    }

    /**
     * 合并数据
     */
    private void consolidateData(List<JSONObject> userList, List<JSONObject> changeList) {
        if (Check.isNull(userList) || Check.isNull(changeList)) {
            return;
        }
        JSONObject data = new JSONObject();
        for (int i = 0; i < userList.size(); i++) {
            JSONObject user = userList.get(i);
            data.put(user.getString("userId"), user);
        }
        for (int i = 0; i < changeList.size(); i++) {
            JSONObject change = changeList.get(i);
            JSONObject user = data.getJSONObject(change.getString("userId"));
            if (Check.isNull(user)) {
                continue;
            }
            change.put("roleName", user.getString("roleName"));
            change.put("quitTime", user.getString("quitTime"));
            change.put("upTime", user.getString("upTime"));
            change.put("monthCount", user.getString("monthCount"));
        }
    }

    /**
     * 获取每季度月份1~12
     */
    @Override
    public List<Integer> getMonthInt(Integer time) {
        List<Integer> list = new ArrayList<>();
        if (1 == time) {
            for (int i = 1; i <= 3; i++) {
                list.add(i);
            }
        } else if (2 == time) {
            for (int i = 4; i <= 6; i++) {
                list.add(i);
            }
        } else if (3 == time) {
            for (int i = 7; i <= 9; i++) {
                list.add(i);
            }
        } else {
            for (int i = 10; i <= 12; i++) {
                list.add(i);
            }
        }
        return list;
    }

}
