package com.engine.bjcj220907.service.impl; import com.engine.bjcj220907.dao.MonthBonusDAO; import com.engine.bjcj220907.entity.*; import com.engine.bjcj220907.service.GetKQ4MonthBonusService; import com.engine.bjcj220907.service.MonthBonusCountService; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import weaver.general.BaseBean; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; /** * @author Harryxzy * @date 2022/09/08 16:35 * @description */ public class MonthBonusCountServiceImpl extends Service implements MonthBonusCountService { BaseBean baseBean = new BaseBean(); public MonthBonusDAO getMonthBonusDAO(){ return new MonthBonusDAO(); } private GetKQ4MonthBonusService getKQ4MonthBonusService() { return ServiceUtil.getService(GetKQ4MonthBonusServiceImpl.class,user); } /*** * @description 计算月度绩效 * @return String * @author Harryxzy * @date 2022/9/8 17:04 */ @Override public String countMonthBonus(CountMonthBonusParam param) { Date bonusMonth = param.getBonusMonth(); Date bonusSendMonth = param.getBonusSendMonth(); // 绩效所属季度 Calendar bonusCal = Calendar.getInstance(); bonusCal.setTime(bonusMonth); int bonusYear = bonusCal.get(Calendar.YEAR); int bonusSeason =bonusCal.get(Calendar.MONTH)/3+1; // 获取已经离职并且已经发放过绩效的人员信息 baseBean.writeLog("获取已经离职并且已经发放过绩效的人员信息"); List haveSendDepartureInfo = getMonthBonusDAO().getHaveSendDepartureInfo().stream().map(i->i.getXm()).collect(Collectors.toList()); // 获取所有人的绩效等级 --> 绩效系数 baseBean.writeLog("获取所有人的绩效等级、绩效系数等信息"); List result = getMonthBonusDAO().getJXInfo(bonusSendMonth,bonusMonth,bonusYear,bonusSeason,haveSendDepartureInfo); // 获取所有本月(薪资发放月)离职人员信息 List departureInfo = getMonthBonusDAO().getDepartureInfo(bonusSendMonth); baseBean.writeLog("发放月离职人员信息:"+departureInfo); List departureTemp = new ArrayList<>(); // 循环所属月下一个月到离职月之间的绩效等级-》绩效系数 baseBean.writeLog("获取所有离职人员所属月下一个月到离职月之间的绩效等级、绩效系数等信息"); for(int i=0;i { getMonthBonusDAO().getXCDJ(r); return r; }).collect(Collectors.toList()); baseBean.writeLog("获取所有人的薪酬等级和绩效工资"); // 获取在职员工的考勤周期(上个月29-这个月28) Calendar startAttendanceCal = getStartAttendanceCal(bonusMonth); Calendar endAttendanceCal = getEndAttendanceCal(bonusMonth); // 获取所有人的境外常驻信息 List czInfos = getMonthBonusDAO().getCZInfo(); baseBean.writeLog("获取所有人的境外常驻信息"); // 将境外常驻信息格式化 List jwCZInfos = formatJwCZInfo(czInfos); baseBean.writeLog("将境外常驻信息格式化"); // 获取所有用户考勤模块中缺勤天数 Attend4MonthBonus p = Attend4MonthBonus.builder().beginDate(startAttendanceCal.getTime()).endDate(endAttendanceCal.getTime()).build(); Map qqDatas = getKQ4MonthBonusService().getKQDatas(p); baseBean.writeLog("获取所有用户考勤模块中缺勤天数"); // 循环将离职人员的各个月的缺勤天数取到 Map qqDatasDepar= new HashMap<>(); for(int i=0;i jwCZUsers = jwCZInfos.stream().map(item -> item.getXm()).collect(Collectors.toList()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); // 计算考勤月内的月度绩效信息 baseBean.writeLog("计算考勤月内的月度绩效信息"); result = result.stream().map(item -> { if(!jwCZUsers.contains(item.getXm())){ // 用户不存在境外常驻信息(全勤21.75) item.setYcq(21.75); double qq=0.0; if(qqDatas.containsKey( (item.getXm()+"-"+sdf.format(item.getKqyf())) )){ qq = qqDatas.get((item.getXm()+"-"+sdf.format(item.getKqyf()))); } item.setQq(qq); // 实出勤天数 =应出勤天数-缺勤天数 double scqTemp = 21.75-qq; if (scqTemp<0){ scqTemp=0.0; } item.setScq(scqTemp); // 奖金基数(考勤)= 月度绩效奖金基数-月度绩效基数/满勤*缺勤天数 double kqjs= item.getYdjjjxjs() - item.getYdjjjxjs()/21.75*qq; item.setJjjskq(kqjs); // 奖金实发放额= 奖金基数(考勤)*个人绩效系数 item.setYfje(item.getGrjxxs() * kqjs); }else{ // 用户存在境外常驻信息,获取该用户所有常驻信息 List collect = jwCZInfos.stream().filter(i -> i.getXm().equals( item.getXm())).collect(Collectors.toList()); List infos = collect.get(0).getInfos(); double[] ycq = {0}; List details = new ArrayList<>(); // 考勤开始日期(在职、离职) Calendar s = getStartAttendanceCal(item.getKqyf()); // 考勤结束日期(在职、离职) Calendar e = getEndAttendanceCal(item.getKqyf()); // 用于存储计算到哪一天的日期 Calendar c = Calendar.getInstance(); c.setTime(e.getTime()); Calendar[] countDay = {c}; for(int i=0;i map = departureInfo.stream().collect(Collectors.toMap(DepartureInfo::getXm,d->d.getLzrq())); departureTemp.stream().forEach(i-> { // 离职日期 Date date = map.get(Integer.valueOf(i.getXm())); Date kqyf = i.getKqyf(); if( date.getMonth() == kqyf.getMonth()){ // 是离职所在月份,获取离职日期重新计算该月缺勤日期以及绩效 Calendar deparLastDay = Calendar.getInstance(); deparLastDay.setTime(date); deparLastDay.add(Calendar.DATE,1); Calendar deaprAttendEndDay = getEndAttendanceCal(kqyf); double[] sqq={0.0}; if(Math.abs(i.getYcq()-21.75) < 0.000000002){ int[] qq={0}; Calendar countCal = Calendar.getInstance(); countCal.setTime(deaprAttendEndDay.getTime()); // 均为境内,取离职日后一天-考勤最后一天的工作日 while (deparLastDay.getTime().before(countCal.getTime()) || deparLastDay.getTime().equals(countCal.getTime())){ if( (countCal.get(Calendar.DAY_OF_WEEK) != 1) && (countCal.get(Calendar.DAY_OF_WEEK)!=7) ){ qq[0]++; } countCal.add(Calendar.DATE,-1); } sqq[0] = i.getQq()+qq[0]; }else{ // 存在境外,取离职日后一天-考勤最后一天的自然日 sqq[0] = i.getQq()+getDays(deparLastDay.getTime(), deaprAttendEndDay.getTime()); } i.setQq(sqq[0]); // 重新计算1、实出勤天数 =应出勤天数-缺勤天数 2、奖金基数(考勤)= 月度绩效奖金基数-月度绩效基数/满勤*缺勤天数 3、奖金实发放额= 奖金基数(考勤)*个人绩效系数 double scqTemp =i.getYcq()-sqq[0]; if (scqTemp<0){ scqTemp=0.0; } i.setScq(scqTemp); double jjjskq = i.getYdjjjxjs() - i.getYdjjjxjs() / i.getYcq() * sqq[0]; i.setJjjskq(jjjskq); i.setYfje(i.getGrjxxs()*jjjskq); } }); // 先删除建模中脏数据 baseBean.writeLog("先删除建模中脏数据"); getMonthBonusDAO().clear(bonusMonth,bonusSendMonth,haveSendDepartureInfo); // 将数据插入建模中 List departureUsers = departureInfo.stream().map(i -> i.getXm()).collect(Collectors.toList()); baseBean.writeLog("将数据插入建模中"); getMonthBonusDAO().insertList(result,departureUsers,bonusSendMonth); return "null"; } /*** * @description 境外常驻信息格式化 * @return void * @author Harryxzy * @date 2022/9/11 17:07 */ private List formatJwCZInfo(List czInfos) { Map> groupByName = czInfos.stream().collect(Collectors.groupingBy(item -> item.getXm())); List formatJwCZInfos = new ArrayList<>(); for (Map.Entry> entry : groupByName.entrySet()) { JwCZInfo build = new JwCZInfo().builder().xm(entry.getValue().get(0).getXm()).infos(entry.getValue()).build(); formatJwCZInfos.add(build); } return formatJwCZInfos; } /** * @description 获取2个时间段中有多少天 * @return Long * @author Harryxzy * @date 2022/9/11 20:12 */ private int getDays(Date startDate,Date endDate) { int days = (int)( (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24) + 1); return days; } /** * @description 判断某一天是否在某一个时间区间内 * @return Long * @author Harryxzy * @date 2022/9/11 20:12 */ private boolean isBetween(Date now,Date startDate,Date endDate) { if( (now.after(startDate) || now.equals(startDate)) && ( (now.before(endDate) || now.equals(endDate)) )){ return true; } return false; } /*** * @description 根据考勤所属月获取考勤开始日期 * @return Calendar * @author Harryxzy * @date 2022/9/14 21:57 */ private Calendar getStartAttendanceCal(Date bonusMonth){ Calendar startAttendanceCal = Calendar.getInstance(); startAttendanceCal.setTime(bonusMonth); startAttendanceCal.add(Calendar.MONTH,-1); if(startAttendanceCal.getActualMaximum(Calendar.DAY_OF_MONTH) == 28){ // 2月只有28天的情况(从3.1开始) startAttendanceCal.add(Calendar.MONTH, 1); startAttendanceCal.set(Calendar.DAY_OF_MONTH, 1); startAttendanceCal.set(Calendar.HOUR_OF_DAY, 0); startAttendanceCal.set(Calendar.MINUTE, 0); startAttendanceCal.set(Calendar.SECOND, 0); startAttendanceCal.set(Calendar.MILLISECOND, 0); }else{ startAttendanceCal.set(Calendar.DAY_OF_MONTH, 29); startAttendanceCal.set(Calendar.HOUR_OF_DAY, 0); startAttendanceCal.set(Calendar.MINUTE, 0); startAttendanceCal.set(Calendar.SECOND, 0); startAttendanceCal.set(Calendar.MILLISECOND, 0); } return startAttendanceCal; } /*** * @description 根据考勤所属月获取考勤结束日期 * @return Calendar * @author Harryxzy * @date 2022/9/14 21:57 */ private Calendar getEndAttendanceCal(Date bonusMonth){ Calendar endAttendanceCal = Calendar.getInstance(); endAttendanceCal.setTime(bonusMonth); endAttendanceCal.set(Calendar.DAY_OF_MONTH,28); endAttendanceCal.set(Calendar.HOUR_OF_DAY, 23); endAttendanceCal.set(Calendar.MINUTE, 59); endAttendanceCal.set(Calendar.SECOND, 59); endAttendanceCal.set(Calendar.MILLISECOND, 999); return endAttendanceCal; } }