package com.yeejoin.precontrol.common.service.impl;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.precontrol.common.constant.Constant;
import com.yeejoin.precontrol.common.dto.CommonPageableDto;
import com.yeejoin.precontrol.common.dto.StatisticsDto;
import com.yeejoin.precontrol.common.dto.TaskSalaryConfirmDto;
import com.yeejoin.precontrol.common.entity.Company;
import com.yeejoin.precontrol.common.entity.PersonClock;
import com.yeejoin.precontrol.common.entity.Project;
import com.yeejoin.precontrol.common.entity.ProjectAccount;
import com.yeejoin.precontrol.common.entity.ProjectClock;
import com.yeejoin.precontrol.common.entity.ProjectCompany;
import com.yeejoin.precontrol.common.entity.Task;
import com.yeejoin.precontrol.common.entity.TaskPerson;
import com.yeejoin.precontrol.common.enums.PersonContractEnum;
import com.yeejoin.precontrol.common.enums.TaskTypeEnum;
import com.yeejoin.precontrol.common.mapper.StatisticsMapper;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IPersonClockService;
import com.yeejoin.precontrol.common.service.IProjectAccountService;
import com.yeejoin.precontrol.common.service.IProjectClockService;
import com.yeejoin.precontrol.common.service.IProjectCompanyService;
import com.yeejoin.precontrol.common.service.IProjectService;
import com.yeejoin.precontrol.common.service.IStatisticalHRService;
import com.yeejoin.precontrol.common.service.ITaskPersonService;
import com.yeejoin.precontrol.common.service.ITaskSalaryConfirmService;
import com.yeejoin.precontrol.common.service.ITaskService;
import com.yeejoin.precontrol.common.utils.DateUtils;
import com.yeejoin.precontrol.common.utils.PlatformUtils;
import com.yeejoin.precontrol.common.vo.PersonClockVo;
import com.yeejoin.precontrol.common.vo.ProjectClockVo;

@Service
public class StatisticalHRServiceImpl implements IStatisticalHRService {

	@Autowired
	IProjectService iProjectService;

	@Autowired
	IProjectCompanyService iProjectCompanyService;

	@Autowired
	IProjectClockService iProjectClockService;

	@Autowired
	ICompanyService iCompanyService;

	@Autowired
	ITaskSalaryConfirmService iTaskSalaryConfirmService;

	@Autowired
	PlatformUtils platformUtils;

	@Autowired
	IProjectAccountService iProjectAccountService;

	@Autowired
	IPersonClockService iPersonClockService;

	@Autowired
	StatisticsMapper statisticsMapper;

	@Autowired
	ITaskPersonService iTaskPersonService;

	@Autowired
	ITaskService iTaskService;

	public Map<String, Object> getMap(String orgCode, Date startMonth, Date endMonth) {
		Map<String, Object> map = new HashMap<String, Object>();
		LambdaQueryWrapper<Project> wapper = new LambdaQueryWrapper<Project>();
		if (orgCode != null) {
			wapper.like(Project::getOrgCode, orgCode);
		}
		List<Project> projects = iProjectService.list(wapper);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startMonth);
		int startMonthValue = calendar.get(Calendar.MONTH) + 1;
		Date startDate = addTime(getFisrtDayOfMonth(calendar.get(Calendar.YEAR), startMonthValue), "00:00:00");
		calendar.setTime(endMonth);
		int endMonthValue = calendar.get(Calendar.MONTH) + 1;
		Date endDate = addTime(getLastDayOfMonth(calendar.get(Calendar.YEAR), endMonthValue), "23:59:59");
		int year = calendar.get(Calendar.YEAR);
		calendar.clear();
		int days = 0;
		try {
			days = DateUtils.dateBetween(startDate, endDate) + 1;
		} catch (ParseException e) {
			e.printStackTrace();
		}
//		platformUtils.setPlatFormAccess();
//		if (orgCode != null) {
//			FeignClientResult<DepartmentModel> result = Privilege.departmentClient.queryByOrgcode(orgCode);
//			if (result == null || result.getResult() == null) {
//				throw new BaseException("orgcode对应部门不存在");
//			}
//			map.put("department", result.getResult().getDepartmentName());
//		} else {
//			map.put("department", "总公司");
//		}
		map.put("department", "江西省电力建设有限公司");

		map.put("year", String.valueOf(year));

		StringBuffer sbType = new StringBuffer().append(startMonthValue).append("月-").append(endMonthValue).append("月");
		if (startMonthValue == endMonthValue) {
			sbType = new StringBuffer().append("月报-").append(startMonthValue).append("月");
		} else if (endMonthValue - startMonthValue == 2) {
			String quarter = "";
			if (startMonthValue == 1) {
				quarter = "1";
			} else if (startMonthValue == 4) {
				quarter = "2";
			} else if (startMonthValue == 7) {
				quarter = "3";
			} else if (startMonthValue == 10) {
				quarter = "4";
			}
			sbType = new StringBuffer().append("季报-").append(quarter).append("季度");
		} else if (endMonthValue - startMonthValue == 11) {
			sbType = new StringBuffer().append("年报");
		}

		map.put("type", sbType.toString());

		int allTotal = 0, allLWPQ = 0, allZJQD = 0, allLWFB = 0, allGCFB = 0, allOTHER = 0, allSign = 0,
				allIDNumber = 0;
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		DecimalFormat df = new DecimalFormat("0.00");
		if (orgCode != null) {
			for (Project project : projects) {
				List<ProjectCompany> projectCompanys = iProjectCompanyService.list(
						new LambdaQueryWrapper<ProjectCompany>().eq(ProjectCompany::getProjectId, project.getId()));
				for (ProjectCompany projectCompany : projectCompanys) {
					Map<String, Object> mapOne = new HashMap<String, Object>();
					mapOne.put("project", project.getName());
					Company company = iCompanyService.getById(projectCompany.getCompanyId());
					mapOne.put("company", company != null ? company.getName() : null);
					// 开始时间前最近一次的上岗是这个项目 或者 时间区间之间存在这个项目上岗记录
					int LWPQCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, PersonContractEnum.LWPQ.getLabel(), null);
					mapOne.put("LWPQ", LWPQCount);
					allLWPQ += LWPQCount;
					int ZJQDCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, PersonContractEnum.ZJQD.getLabel(), null);
					mapOne.put("ZJQD", ZJQDCount);
					allZJQD += ZJQDCount;
					int LWFBCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, PersonContractEnum.LWFB.getLabel(), null);
					mapOne.put("LWFB", LWFBCount);
					allLWFB += LWFBCount;
					int GCFBCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, PersonContractEnum.GCFB.getLabel(), null);
					mapOne.put("GCFB", GCFBCount);
					allGCFB += GCFBCount;
					int OTHERCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, PersonContractEnum.OTHER.getLabel(), null);
					mapOne.put("OTHER", OTHERCount);
					allOTHER += OTHERCount;
					int total = LWPQCount + ZJQDCount + LWFBCount + GCFBCount + OTHERCount;
					mapOne.put("total", total);
					allTotal += total;
					int signCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, null, true);
					mapOne.put("sign", signCount);
					allSign += signCount;
					double signProportion = total != 0 ? Double.valueOf(df.format((float) signCount / total)) : 0;
					mapOne.put("signProportion", signProportion);

					mapOne.put("IDNumber", total);
					allIDNumber += total;
					double IDNumberProportion = total != 0 ? Double.valueOf(df.format((float) total / total)) : 0;
					mapOne.put("IDNumberProportion", IDNumberProportion);

					// 平均
					double LWPQAverage = Double.valueOf(df.format((float) LWPQCount / days));
					mapOne.put("LWPQAverage", LWPQAverage);
					double ZJQDAverage = Double.valueOf(df.format((float) ZJQDCount / days));
					mapOne.put("ZJQDAverage", ZJQDAverage);
					double LWFBAverage = Double.valueOf(df.format((float) LWFBCount / days));
					mapOne.put("LWFBAverage", LWFBAverage);
					double GCFBAverage = Double.valueOf(df.format((float) GCFBCount / days));
					mapOne.put("GCFBAverage", GCFBAverage);
					double OTHERAverage = Double.valueOf(df.format((float) OTHERCount / days));
					mapOne.put("OTHERAverage", OTHERAverage);
					double totalAverage = Double.valueOf(df.format((float) total / days));
					mapOne.put("totalAverage", totalAverage);
					double signAverage = Double.valueOf(df.format((float) signCount / days));
					mapOne.put("signAverage", signAverage);
					double signAverageProportion = totalAverage != 0
							? Double.valueOf(df.format((float) signAverage / totalAverage))
							: 0;
					mapOne.put("signAverageProportion", signAverageProportion);
					double IDNumberAverage = Double.valueOf(df.format((float) total / days));
					mapOne.put("IDNumberAverage", IDNumberAverage);
					double IDNumberAverageProportion = IDNumberAverage != 0
							? Double.valueOf(df.format((float) IDNumberAverage / totalAverage))
							: 0;
					mapOne.put("IDNumberAverageProportion", IDNumberAverageProportion);
					list.add(mapOne);
				}
			}
		} else {
			for (Project project : projects) {
				List<ProjectCompany> projectCompanys = iProjectCompanyService.list(
						new LambdaQueryWrapper<ProjectCompany>().eq(ProjectCompany::getProjectId, project.getId()));
				int LWPQCount = 0, ZJQDCount = 0, LWFBCount = 0, GCFBCount = 0, OTHERCount = 0, total = 0,
						signCount = 0;
				for (ProjectCompany projectCompany : projectCompanys) {
					// 开始时间前最近一次的上岗是这个项目 或者 时间区间之间存在这个项目上岗记录
					LWPQCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, PersonContractEnum.LWPQ.getLabel(), null);
					ZJQDCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, PersonContractEnum.ZJQD.getLabel(), null);
					LWFBCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, PersonContractEnum.LWFB.getLabel(), null);
					GCFBCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, PersonContractEnum.GCFB.getLabel(), null);
					OTHERCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, PersonContractEnum.OTHER.getLabel(), null);
					total += LWPQCount + ZJQDCount + LWFBCount + GCFBCount + OTHERCount;
					signCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, null, true);
				}
				allLWPQ += LWPQCount;
				allZJQD += ZJQDCount;
				allLWFB += LWFBCount;
				allGCFB += GCFBCount;
				allOTHER += OTHERCount;
				allTotal += total;
				allSign += signCount;
				allIDNumber += total;
				Map<String, Object> mapOne = new HashMap<String, Object>();
				mapOne.put("project", project.getName());
				mapOne.put("LWPQ", LWPQCount);
				mapOne.put("ZJQD", ZJQDCount);
				mapOne.put("LWFB", LWFBCount);
				mapOne.put("GCFB", GCFBCount);
				mapOne.put("OTHER", OTHERCount);
				mapOne.put("total", total);
				mapOne.put("sign", signCount);
				double signProportion = total != 0 ? Double.valueOf(df.format((float) signCount / total)) : 0;
				mapOne.put("signProportion", signProportion);
				mapOne.put("IDNumber", total);
				double IDNumberProportion = total != 0 ? Double.valueOf(df.format((float) total / total)) : 0;
				mapOne.put("IDNumberProportion", IDNumberProportion);
				double LWPQAverage = Double.valueOf(df.format((float) LWPQCount / days));
				mapOne.put("LWPQAverage", LWPQAverage);
				double ZJQDAverage = Double.valueOf(df.format((float) ZJQDCount / days));
				mapOne.put("ZJQDAverage", ZJQDAverage);
				double LWFBAverage = Double.valueOf(df.format((float) LWFBCount / days));
				mapOne.put("LWFBAverage", LWFBAverage);
				double GCFBAverage = Double.valueOf(df.format((float) GCFBCount / days));
				mapOne.put("GCFBAverage", GCFBAverage);
				double OTHERAverage = Double.valueOf(df.format((float) OTHERCount / days));
				mapOne.put("OTHERAverage", OTHERAverage);
				double totalAverage = Double.valueOf(df.format((float) total / days));
				mapOne.put("totalAverage", totalAverage);
				double signAverage = Double.valueOf(df.format((float) signCount / days));
				mapOne.put("signAverage", signAverage);
				double signAverageProportion = totalAverage != 0
						? Double.valueOf(df.format((float) signAverage / totalAverage))
						: 0;
				mapOne.put("signAverageProportion", signAverageProportion);
				double IDNumberAverage = Double.valueOf(df.format((float) total / days));
				mapOne.put("IDNumberAverage", IDNumberAverage);
				double IDNumberAverageProportion = IDNumberAverage != 0
						? Double.valueOf(df.format((float) IDNumberAverage / totalAverage))
						: 0;
				mapOne.put("IDNumberAverageProportion", IDNumberAverageProportion);
				list.add(mapOne);
			}
		}

		map.put("allTotal", allTotal);
		map.put("allLWPQ", allLWPQ);
		map.put("allZJQD", allZJQD);
		map.put("allLWFB", allLWFB);
		map.put("allGCFB", allGCFB);
		map.put("allOTHER", allOTHER);
		map.put("allSign", allSign);
		map.put("allIDNumber", allIDNumber);
		map.put("allSignProportion", allTotal != 0 ? Double.valueOf(df.format((float) allSign / allTotal)) : 0);
		map.put("allIDNumberProportion", allTotal != 0 ? Double.valueOf(df.format((float) allTotal / allTotal)) : 0);
		double allTotalAverage = Double.valueOf(df.format((float) allTotal / days));
		map.put("allTotalAverage", allTotalAverage);
		map.put("allLWPQAverage", Double.valueOf(df.format((float) allLWPQ / days)));
		map.put("allZJQDAverage", Double.valueOf(df.format((float) allZJQD / days)));
		map.put("allLWFBAverage", Double.valueOf(df.format((float) allLWFB / days)));
		map.put("allGCFBAverage", Double.valueOf(df.format((float) allGCFB / days)));
		map.put("allOTHERAverage", Double.valueOf(df.format((float) allOTHER / days)));
		double allSignAverage = Double.valueOf(df.format((float) allSign / days));
		map.put("allSignAverage", allSignAverage);
		map.put("allSignAverageProportion",
				allTotalAverage != 0 ? Double.valueOf(df.format((float) allSignAverage / allTotalAverage)) : 0);
		double allIDNumberAverage = Double.valueOf(df.format((float) allTotal / days));
		map.put("allIDNumberAverage", allIDNumberAverage);
		map.put("allIDNumberAverageProportion",
				allTotalAverage != 0 ? Double.valueOf(df.format((float) allIDNumberAverage / allTotalAverage)) : 0);
		map.put("projects", list);
		return map;
	}

	public static Date addTime(String day, String timStr) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = sdf.parse(day + " " + timStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	public static String getFisrtDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		cal.set(Calendar.MONTH, month - 1);
		// 获取某月最小天数
		int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
		// 设置日历中月份的最小天数
		cal.set(Calendar.DAY_OF_MONTH, firstDay);
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String firstDayOfMonth = sdf.format(cal.getTime());
		return firstDayOfMonth;
	}

	public static String getLastDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		cal.set(Calendar.MONTH, month - 1);
		// 获取某月最大天数
		int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		// 设置日历中月份的最大天数
		cal.set(Calendar.DAY_OF_MONTH, lastDay);
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String lastDayOfMonth = sdf.format(cal.getTime());
		return lastDayOfMonth;
	}

	@Override
	public Map<String, Object> getSalaryMap(String orgCode, Date startMonth, Date endMonth) {
		Map<String, Object> map = new HashMap<String, Object>();
		LambdaQueryWrapper<Project> wapper = new LambdaQueryWrapper<Project>();
		if (orgCode != null) {
			wapper.like(Project::getOrgCode, orgCode);
		}
		List<Project> projects = iProjectService.list(wapper);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startMonth);
		int startMonthValue = calendar.get(Calendar.MONTH) + 1;
		Date startDate = addTime(getFisrtDayOfMonth(calendar.get(Calendar.YEAR), startMonthValue), "00:00:00");
		calendar.setTime(endMonth);
		int endMonthValue = calendar.get(Calendar.MONTH) + 1;
		Date endDate = addTime(getLastDayOfMonth(calendar.get(Calendar.YEAR), endMonthValue), "23:59:59");
		int year = calendar.get(Calendar.YEAR);
		calendar.clear();
		int days = 0;
		try {
			days = DateUtils.dateBetween(startDate, endDate) + 1;
		} catch (ParseException e) {
			e.printStackTrace();
		}
//		platformUtils.setPlatFormAccess();
//		if (orgCode != null) {
//			FeignClientResult<DepartmentModel> result = Privilege.departmentClient.queryByOrgcode(orgCode);
//			if (result == null || result.getResult() == null) {
//				throw new BaseException("orgcode对应部门不存在");
//			}
//			map.put("department", result.getResult().getDepartmentName());
//		} else {
//			map.put("department", "总公司");
//		}
		map.put("department", "江西省电力建设有限公司");

		map.put("year", String.valueOf(year));

		StringBuffer sbType = new StringBuffer().append(startMonthValue).append("月-").append(endMonthValue).append("月");
		Date lastStartDate = startDate;
		Date lastEndDate = endDate;
		if (startMonthValue == endMonthValue) {
			sbType = new StringBuffer().append("月报-").append(startMonthValue).append("月");
			calendar.setTime(lastStartDate);
			calendar.add(Calendar.MONTH, -1);
			lastStartDate = calendar.getTime();
			calendar.setTime(lastEndDate);
			calendar.add(Calendar.MONTH, -1);
			lastEndDate = calendar.getTime();
		} else if (endMonthValue - startMonthValue == 2) {
			String quarter = "";
			if (startMonthValue == 1) {
				quarter = "1";
			} else if (startMonthValue == 4) {
				quarter = "2";
			} else if (startMonthValue == 7) {
				quarter = "3";
			} else if (startMonthValue == 10) {
				quarter = "4";
			}
			sbType = new StringBuffer().append("季报-").append(quarter).append("季度");
			calendar.setTime(lastStartDate);
			calendar.add(Calendar.MONTH, -3);
			lastStartDate = calendar.getTime();
			calendar.setTime(lastEndDate);
			calendar.add(Calendar.MONTH, -3);
			lastEndDate = calendar.getTime();
		} else if (endMonthValue - startMonthValue == 11) {
			sbType = new StringBuffer().append("年报");
			calendar.setTime(lastStartDate);
			calendar.add(Calendar.YEAR, -1);
			lastStartDate = calendar.getTime();
			calendar.setTime(lastEndDate);
			calendar.add(Calendar.YEAR, -1);
			lastEndDate = calendar.getTime();
		}
		map.put("type", sbType.toString());

		wapper.eq(Project::getStatus, "在建");
		List<Project> projectInbuild = iProjectService.list(wapper);
		wapper.eq(Project::isHasAccount, true);
		List<Project> projectInbuildAccount = iProjectService.list(wapper);

		double allContractTotalSalary = 0, allCurrentPaySalary = 0, allCurrentUnconfirmSalary = 0,
				allCurrentConfirmSalary = 0, allLastUnconfirmSalary = 0, allCumUnconfirmSalary = 0,
				allJxdjPaySalary = 0;
		int allPersonCount = 0, allCurrentUnconfirmPerson = 0, allCurrentConfirmPerson = 0, allLastUnconfirmPerson = 0,
				allCumUnconfirmPerson = 0, allProjectAccount = 0, allBuildCount = 0, allBuildCountAccount = 0,
				allBankPersonCount = 0, allPayPersonCount = 0;
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		DecimalFormat df = new DecimalFormat("0.00");
		if (orgCode != null) {
			for (Project project : projects) {
				List<ProjectCompany> projectCompanys = iProjectCompanyService.list(
						new LambdaQueryWrapper<ProjectCompany>().eq(ProjectCompany::getProjectId, project.getId()));
				ProjectAccount projectAccount = iProjectAccountService.getById(project.getId());

				for (ProjectCompany projectCompany : projectCompanys) {
					Map<String, Object> mapOne = new HashMap<String, Object>();
					mapOne.put("project", project.getName());
					Company company = iCompanyService.getById(projectCompany.getCompanyId());
					mapOne.put("company", company != null ? company.getName() : null);
					Map<String, Object> current = iTaskSalaryConfirmService.statistic(project.getId(), company.getId(),
							startDate, endDate, null);
					double contractTotalSalary = Double.valueOf(String.valueOf(current.get("contractTotalSalary")));
					allContractTotalSalary += contractTotalSalary;
					mapOne.put("contractTotalSalary", contractTotalSalary);

					double currentPaySalary = Double.valueOf(String.valueOf(current.get("currentPaySalary")));
					allCurrentPaySalary += currentPaySalary;
					mapOne.put("currentPaySalary", currentPaySalary);

					int personCount = iProjectClockService.count(project.getId(), projectCompany.getCompanyId(),
							startDate, endDate, null, null);
					allPersonCount += personCount;
					double currentPaySalaryAverage = personCount != 0
							? Double.valueOf(df.format((float) contractTotalSalary / personCount))
							: 0;
					mapOne.put("currentPaySalaryAverage", currentPaySalaryAverage);

					double currentUnconfirmSalary = Double.valueOf(String.valueOf(current.get("unconfirmSalary")));
					allCurrentUnconfirmSalary += currentUnconfirmSalary;
					mapOne.put("currentUnconfirmSalary", currentUnconfirmSalary);
					int currentUnconfirmPerson = Integer.valueOf(String.valueOf(current.get("unconfirmPerson")));
					allCurrentUnconfirmPerson += currentUnconfirmPerson;
					mapOne.put("currentUnconfirmPerson", currentUnconfirmPerson);
					double currentConfirmSalary = Double.valueOf(String.valueOf(current.get("confirmSalary")));
					allCurrentConfirmSalary += currentConfirmSalary;
					mapOne.put("currentConfirmSalary", currentConfirmSalary);
					int currentConfirmPerson = Integer.valueOf(String.valueOf(current.get("unconfirmPerson")));
					allCurrentConfirmPerson += currentConfirmPerson;
					mapOne.put("currentConfirmPerson", currentConfirmPerson);

					// 上期
					Map<String, Object> last = iTaskSalaryConfirmService.statistic(project.getId(), company.getId(),
							lastStartDate, lastEndDate, null);
					double lastUnconfirmSalary = Double.valueOf(String.valueOf(last.get("unconfirmSalary")));
					allLastUnconfirmSalary += lastUnconfirmSalary;
					mapOne.put("lastUnconfirmSalary", lastUnconfirmSalary);
					int lastUnconfirmPerson = Integer.valueOf(String.valueOf(last.get("unconfirmPerson")));
					allLastUnconfirmPerson += lastUnconfirmPerson;
					mapOne.put("lastUnconfirmPerson", lastUnconfirmPerson);
					// 累计
					double cumUnconfirmSalary = currentUnconfirmSalary + lastUnconfirmSalary - currentConfirmSalary;
					cumUnconfirmSalary = cumUnconfirmSalary < 0 ? 0 : cumUnconfirmSalary;
					allCumUnconfirmSalary += cumUnconfirmSalary;
					mapOne.put("cumUnconfirmSalary", cumUnconfirmSalary);
					int cumUnconfirmPerson = currentUnconfirmPerson + lastUnconfirmPerson - currentConfirmPerson;
					cumUnconfirmPerson = cumUnconfirmPerson < 0 ? 0 : cumUnconfirmPerson;
					allCumUnconfirmPerson += cumUnconfirmPerson;
					mapOne.put("cumUnconfirmPerson", cumUnconfirmPerson);

					// 专户
					int hasProjectAccount = projectAccount != null ? 1 : 0;
					allProjectAccount += hasProjectAccount;
					mapOne.put("projectAccount", hasProjectAccount);
					int buildCount = projectInbuild.size();
					allBuildCount += buildCount;
					int buildCountAccount = projectInbuildAccount.size();
					allBuildCountAccount += buildCountAccount;
					mapOne.put("projectAccountCoverage",
							buildCountAccount != 0 ? Double.valueOf(df.format((float) buildCount / buildCountAccount))
									: 0);

					// 总承包代发
					Map<String, Object> jxdj = iTaskSalaryConfirmService.statistic(project.getId(), company.getId(),
							startDate, endDate, "江西电建代发工资");
					double jxdjPaySalary = Double.valueOf(String.valueOf(jxdj.get("currentPaySalary")));
					allJxdjPaySalary += jxdjPaySalary;
					mapOne.put("jxdjPaySalary", jxdjPaySalary);
					mapOne.put("jxdjPayRate",
							currentPaySalary != 0 ? Double.valueOf(df.format((float) jxdjPaySalary / currentPaySalary))
									: 0);
					// 银行代发人数
					Map<String, Object> bank = iTaskSalaryConfirmService.statistic(project.getId(), company.getId(),
							startDate, endDate, "银行代发工资");
					int bankPersonCount = Integer.valueOf(String.valueOf(bank.get("confirmPerson")))
							+ Integer.valueOf(String.valueOf(bank.get("unconfirmPerson")));
					// 代发人数
					Map<String, Object> pay = iTaskSalaryConfirmService.statistic(project.getId(), company.getId(),
							startDate, endDate, null);
					int payPersonCount = Integer.valueOf(String.valueOf(pay.get("confirmPerson")))
							+ Integer.valueOf(String.valueOf(pay.get("unconfirmPerson")));
					allBankPersonCount += bankPersonCount;
					allPayPersonCount += payPersonCount;
					mapOne.put("bankPaySalary", bankPersonCount);
					mapOne.put("bankPayRate",
							payPersonCount != 0 ? Double.valueOf(df.format((float) bankPersonCount / payPersonCount))
									: 0);
					list.add(mapOne);
				}
			}
		} else {
			for (Project project : projects) {
				List<ProjectCompany> projectCompanys = iProjectCompanyService.list(
						new LambdaQueryWrapper<ProjectCompany>().eq(ProjectCompany::getProjectId, project.getId()));
				ProjectAccount projectAccount = iProjectAccountService.getById(project.getId());
				double contractTotalSalary = 0, currentPaySalary = 0, currentUnconfirmSalary = 0,
						currentConfirmSalary = 0, lastUnconfirmSalary = 0, cumUnconfirmSalary = 0, jxdjPaySalary = 0;
				int personCount = 0, currentUnconfirmPerson = 0, currentConfirmPerson = 0, lastUnconfirmPerson = 0,
						cumUnconfirmPerson = 0, buildCount = 0, buildCountAccount = 0, bankPersonCount = 0,
						payPersonCount = 0;
				for (ProjectCompany projectCompany : projectCompanys) {
					Map<String, Object> current = iTaskSalaryConfirmService.statistic(project.getId(), null, startDate,
							endDate, null);
					contractTotalSalary += Double.valueOf(String.valueOf(current.get("contractTotalSalary")));
					currentPaySalary += Double.valueOf(String.valueOf(current.get("currentPaySalary")));

					personCount += iProjectClockService.count(project.getId(), projectCompany.getCompanyId(), startDate,
							endDate, null, null);
					currentUnconfirmSalary += Double.valueOf(String.valueOf(current.get("unconfirmSalary")));
					currentUnconfirmPerson += Integer.valueOf(String.valueOf(current.get("unconfirmPerson")));
					currentConfirmSalary += Double.valueOf(String.valueOf(current.get("confirmSalary")));
					currentConfirmPerson += Integer.valueOf(String.valueOf(current.get("confirmPerson")));

					// 上期
					Map<String, Object> last = iTaskSalaryConfirmService.statistic(project.getId(), null, lastStartDate,
							lastEndDate, null);
					lastUnconfirmSalary += Double.valueOf(String.valueOf(last.get("unconfirmSalary")));
					lastUnconfirmPerson += Integer.valueOf(String.valueOf(last.get("unconfirmPerson")));
					// 累计
					double cumUnconfirmSalaryOne = 0;
					cumUnconfirmSalaryOne = currentUnconfirmSalary + lastUnconfirmSalary - currentConfirmSalary;
					cumUnconfirmSalaryOne = cumUnconfirmSalaryOne < 0 ? 0 : cumUnconfirmSalaryOne;
					cumUnconfirmSalary += cumUnconfirmSalaryOne;

					int cumUnconfirmPersonOne = 0;
					cumUnconfirmPersonOne = currentUnconfirmPerson + lastUnconfirmPerson - currentConfirmPerson;
					cumUnconfirmPersonOne = cumUnconfirmPersonOne < 0 ? 0 : cumUnconfirmPersonOne;
					cumUnconfirmPerson += cumUnconfirmPersonOne;
					// 专户
					buildCount += projectInbuild.size();
					buildCountAccount += projectInbuildAccount.size();

					// 总承包代发金额
					Map<String, Object> jxdj = iTaskSalaryConfirmService.statistic(project.getId(), null, startDate,
							endDate, "江西电建代发工资");
					jxdjPaySalary += Double.valueOf(String.valueOf(jxdj.get("currentPaySalary")));
					// 银行代发人数
					Map<String, Object> bank = iTaskSalaryConfirmService.statistic(project.getId(), null, startDate,
							endDate, "银行代发工资");
					bankPersonCount += Integer.valueOf(String.valueOf(bank.get("confirmPerson")))
							+ Integer.valueOf(String.valueOf(bank.get("unconfirmPerson")));
					// 代发人数
					Map<String, Object> pay = iTaskSalaryConfirmService.statistic(project.getId(), null, startDate,
							endDate, null);
					payPersonCount += Integer.valueOf(String.valueOf(pay.get("confirmPerson")))
							+ Integer.valueOf(String.valueOf(pay.get("unconfirmPerson")));
				}
				allContractTotalSalary += contractTotalSalary;
				allCurrentPaySalary += currentPaySalary;
				allPersonCount += personCount;
				allCurrentUnconfirmSalary += currentUnconfirmSalary;
				allCurrentUnconfirmPerson += currentUnconfirmPerson;
				allCurrentConfirmSalary += currentConfirmSalary;
				allCurrentConfirmPerson += currentConfirmPerson;
				allLastUnconfirmSalary += lastUnconfirmSalary;
				allLastUnconfirmPerson += lastUnconfirmPerson;
				allCumUnconfirmSalary += cumUnconfirmSalary;
				allCumUnconfirmPerson += cumUnconfirmPerson;
				allBuildCount += buildCount;
				allBuildCountAccount += buildCountAccount;
				allJxdjPaySalary += jxdjPaySalary;
				allBankPersonCount += bankPersonCount;
				allPayPersonCount += payPersonCount;
				Map<String, Object> mapOne = new HashMap<String, Object>();
				mapOne.put("project", project.getName());
				mapOne.put("contractTotalSalary", contractTotalSalary);
				mapOne.put("currentPaySalary", currentPaySalary);
				double currentPaySalaryAverage = personCount != 0
						? Double.valueOf(df.format((float) currentPaySalary / personCount))
						: 0;
				mapOne.put("currentPaySalaryAverage", currentPaySalaryAverage);
				mapOne.put("currentUnconfirmSalary", currentUnconfirmSalary);
				mapOne.put("currentUnconfirmPerson", currentUnconfirmPerson);
				mapOne.put("currentConfirmSalary", currentConfirmSalary);
				mapOne.put("currentConfirmPerson", currentConfirmPerson);

				// 上期
				mapOne.put("lastUnconfirmSalary", lastUnconfirmSalary);
				mapOne.put("lastUnconfirmPerson", lastUnconfirmPerson);
				// 累计
				mapOne.put("cumUnconfirmSalary", cumUnconfirmSalary);
				mapOne.put("cumUnconfirmPerson", cumUnconfirmPerson);

				// 专户
				int hasProjectAccount = projectAccount != null ? 1 : 0;
				allProjectAccount += hasProjectAccount;
				mapOne.put("projectAccount", hasProjectAccount);
				mapOne.put("projectAccountCoverage",
						buildCountAccount != 0 ? Double.valueOf(df.format((float) buildCount / buildCountAccount)) : 0);

				// 总承包代发
				mapOne.put("jxdjPaySalary", jxdjPaySalary);
				mapOne.put("jxdjPayRate",
						currentPaySalary != 0 ? Double.valueOf(df.format((float) jxdjPaySalary / currentPaySalary))
								: 0);
				// 银行代发人数
				mapOne.put("bankPaySalary", bankPersonCount);
				mapOne.put("bankPayRate",
						payPersonCount != 0 ? Double.valueOf(df.format((float) bankPersonCount / payPersonCount)) : 0);
				list.add(mapOne);
			}
		}
		map.put("allContractTotalSalary", allContractTotalSalary);
		map.put("allCurrentPaySalary", allCurrentPaySalary);
		double allCurrentPaySalaryAverage = allPersonCount != 0
				? Double.valueOf(df.format((float) allCurrentPaySalary / allPersonCount))
				: 0;
		map.put("allCurrentPaySalaryAverage", allCurrentPaySalaryAverage);
		map.put("allLastUnconfirmSalary", allLastUnconfirmSalary);
		map.put("allLastUnconfirmPerson", allLastUnconfirmPerson);
		map.put("allCurrentUnconfirmSalary", allCurrentUnconfirmSalary);
		map.put("allCurrentUnconfirmPerson", allCurrentUnconfirmPerson);
		map.put("allCurrentConfirmSalary", allCurrentConfirmSalary);
		map.put("allCurrentConfirmPerson", allCurrentConfirmPerson);
		map.put("allCumUnconfirmSalary", allCumUnconfirmSalary);
		map.put("allCumUnconfirmPerson", allCumUnconfirmPerson);
		map.put("allProjectAccount", allProjectAccount);
		map.put("allProjectAccountCoverage",
				allBuildCountAccount != 0 ? Double.valueOf(df.format((float) allBuildCount / allBuildCountAccount))
						: 0);
		map.put("allJxdjPaySalary", allJxdjPaySalary);
		map.put("allJxdjPaySalaryRate",
				allCurrentPaySalary != 0 ? Double.valueOf(df.format((float) allJxdjPaySalary / allCurrentPaySalary))
						: 0);
		map.put("allBankPaySalary", allBankPersonCount);
		map.put("allBankPaySalaryRate",
				allPayPersonCount != 0 ? Double.valueOf(df.format((float) allBankPersonCount / allPayPersonCount)) : 0);
		map.put("projects", list);
		return map;
	}

	@Override
	public Map<String, Object> personStatistics(String orgCode, Date startMonth, Date endMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startMonth);
		int startMonthValue = calendar.get(Calendar.MONTH) + 1;
		Date startDate = addTime(getFisrtDayOfMonth(calendar.get(Calendar.YEAR), startMonthValue), "00:00:00");
		calendar.setTime(endMonth);
		int endMonthValue = calendar.get(Calendar.MONTH) + 1;
		Date endDate = addTime(getLastDayOfMonth(calendar.get(Calendar.YEAR), endMonthValue), "23:59:59");
		LambdaQueryWrapper<Project> wapper = new LambdaQueryWrapper<Project>();
		if (orgCode != null) {
			wapper.like(Project::getOrgCode, orgCode);
		}
		List<Project> projects = iProjectService.list(wapper);
		List<Long> projectIds = projects.stream().map(i -> i.getId()).collect(Collectors.toList());
		long inCount = 0;
		long outCount = 0;
		CommonPageableDto pageable = new CommonPageableDto();
		pageable.setPageNumber(0);
		pageable.setPageSize(10);
		if (projectIds.size() > 0) {
			PersonClockVo personClockVo = new PersonClockVo();
			personClockVo.setOrgCode(orgCode);
			personClockVo.setInOrOut(0);
			personClockVo.setStartDate(startDate);
			personClockVo.setEndDate(endDate);
			IPage<PersonClockVo> inlist = this.enterList(pageable, personClockVo);
			inCount = inlist.getTotal();
			personClockVo.setInOrOut(1);
			IPage<PersonClockVo> outlist = this.enterList(pageable, personClockVo);
			outCount = outlist.getTotal();
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("inCount", inCount);
		map.put("outCount", outCount);
		ProjectClockVo projectClockVo = new ProjectClockVo();
		projectClockVo.setOrgCode(orgCode);
		projectClockVo.setStartDate(startDate);
		projectClockVo.setEndDate(endDate);
		IPage<ProjectClockVo> dutylist = this.dutyList(pageable, projectClockVo);
		long dutyCount = dutylist.getTotal();
		map.put("dutyCount", dutyCount);
		return map;
	}

	@Override
	public Map<String, Object> projectStatistics(String orgCode, Date StartMonth, Date EndMonth) {
		StatisticsDto statisticsDto = new StatisticsDto();
		statisticsDto.setOrgCode(orgCode);
		Map<String, Object> map = new HashMap<String, Object>();
		// 项目
		int projectCount = statisticsMapper.projectCount(statisticsDto,
				Arrays.asList(Constant.BUILD_PROJECT_STATUS_GROUP));
		map.put("projectCount", projectCount);
		// 分包商
		int companyCount = statisticsMapper.companyCount(statisticsDto, false);
		map.put("companyCount", companyCount);

		TaskSalaryConfirmDto taskSalaryConfirmDto = new TaskSalaryConfirmDto();
		taskSalaryConfirmDto.setStatus(0);
		taskSalaryConfirmDto.setOrgCode(orgCode);
		CommonPageableDto commonPageableDto = new CommonPageableDto();
		commonPageableDto.setPageNumber(0);
		commonPageableDto.setPageSize(10);
		// 薪资确认
		long unSalaryCount = iTaskSalaryConfirmService.pageInfo(commonPageableDto, taskSalaryConfirmDto).getTotal();
		// statisticsMapper.taskCount(statisticsDto, false,
		// TaskTypeEnum.SALARY_CONFIRM.getValue(),
		// TaskStatusEnum.UNCOMPLETED.getLongType(), null);
		map.put("unSalaryCount", Integer.valueOf(String.valueOf(unSalaryCount)));
		// 未完成薪资确认人数
		int unconfirmSalaryCount = 0;
		LambdaQueryWrapper<Project> wapper = new LambdaQueryWrapper<Project>();
		if (orgCode != null) {
			wapper.like(Project::getOrgCode, orgCode);
		}
		List<Project> projects = iProjectService.list(wapper);
		List<Long> projectIds = projects.stream().map(i -> i.getId()).collect(Collectors.toList());
		if (projectIds.size() > 0) {
			List<Task> list = iTaskService.list(new LambdaQueryWrapper<Task>().in(Task::getProjectId, projectIds)
					.eq(Task::getType, TaskTypeEnum.SALARY_CONFIRM.getValue()));
			List<Long> taskIds = list.stream().map(i -> i.getId()).collect(Collectors.toList());
			if (taskIds.size() > 0) {
				unconfirmSalaryCount = iTaskPersonService.count(new LambdaQueryWrapper<TaskPerson>()
						.eq(TaskPerson::getReadStatus, 0L).in(TaskPerson::getTaskId, taskIds));
			}
		}
		map.put("unconfirmSalaryCount", unconfirmSalaryCount);
		return map;
	}

	@Override
	public IPage<ProjectClockVo> dutyList(CommonPageableDto pageable, ProjectClockVo projectClockVo) {
		if (pageable.getIsAll() == 1) {
			pageable.setPageNumber(0);
			pageable.setPageSize(Integer.MAX_VALUE);
		}
		Date startMonth = projectClockVo.getStartMonth();
		Date endMonth = projectClockVo.getEndMonth();
		if (startMonth != null && endMonth != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startMonth);
			int startMonthValue = calendar.get(Calendar.MONTH) + 1;
			Date startDate = StatisticalHRServiceImpl.addTime(
					StatisticalHRServiceImpl.getFisrtDayOfMonth(calendar.get(Calendar.YEAR), startMonthValue),
					"00:00:00");
			calendar.setTime(endMonth);
			int endMonthValue = calendar.get(Calendar.MONTH) + 1;
			Date endDate = StatisticalHRServiceImpl.addTime(
					StatisticalHRServiceImpl.getLastDayOfMonth(calendar.get(Calendar.YEAR), endMonthValue), "23:59:59");
			projectClockVo.setStartDate(startDate);
			projectClockVo.setEndDate(endDate);
		}
		projectClockVo.setType(2);
		Page<ProjectClockVo> page = new Page<ProjectClockVo>(pageable.getPageNumber(), pageable.getPageSize());
		return iProjectClockService.dutyList(page, projectClockVo);
	}

	@Override
	public IPage<PersonClockVo> enterList(CommonPageableDto pageable, PersonClockVo personClockVo) {
		if (pageable.getIsAll() == 1) {
			pageable.setPageNumber(0);
			pageable.setPageSize(Integer.MAX_VALUE);
		}
		Date startMonth = personClockVo.getStartMonth();
		Date endMonth = personClockVo.getEndMonth();
		if (startMonth != null && endMonth != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startMonth);
			int startMonthValue = calendar.get(Calendar.MONTH) + 1;
			Date startDate = StatisticalHRServiceImpl.addTime(
					StatisticalHRServiceImpl.getFisrtDayOfMonth(calendar.get(Calendar.YEAR), startMonthValue),
					"00:00:00");
			calendar.setTime(endMonth);
			int endMonthValue = calendar.get(Calendar.MONTH) + 1;
			Date endDate = StatisticalHRServiceImpl.addTime(
					StatisticalHRServiceImpl.getLastDayOfMonth(calendar.get(Calendar.YEAR), endMonthValue), "23:59:59");
			personClockVo.setStartDate(startDate);
			personClockVo.setEndDate(endDate);
		}
		Page<PersonClockVo> page = new Page<PersonClockVo>(pageable.getPageNumber(), pageable.getPageSize());
		return iPersonClockService.enterList(page, personClockVo);
	}
}
