weaver-bjcj/src/com/engine/bjcj220907/service/impl/MonthBonusCountServiceImpl....

343 lines
18 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.bjcj220907.utils.BjcjCommonUtils;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.util.SalaryEntityUtil;
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) {
// 获取绩效日期的ID
Integer id = getMonthBonusDAO().getydjxID(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<Integer> haveSendDepartureInfo = getMonthBonusDAO().getHaveSendDepartureInfo().stream().map(i->i.getXm()).collect(Collectors.toList());
baseBean.writeLog("获取已经离职并且已经发放过绩效的人员信息 共:"+haveSendDepartureInfo.size());
// 获取所有人的入职日期、离职日期、其他缺勤天数
List<DepartureInfo> rybsInfo = getMonthBonusDAO().getRybsInfo();
baseBean.writeLog("获取所有人的入职日期、离职日期、其他缺勤天数"+rybsInfo.size());
Map<Integer,DepartureInfo> rybsInfoMap = SalaryEntityUtil.convert2Map(rybsInfo, DepartureInfo::getXm);
// 入职日期小于绩效所属月的不核算绩效
rybsInfo.stream().forEach(info -> {
if(BjcjCommonUtils.isBeforeMonth(param.getBonusMonth(),info.getRzrq())){
haveSendDepartureInfo.add(info.getXm());
}
});
// 获取所有人的绩效等级 --> 绩效系数
List<CountMonthBonus> result = getMonthBonusDAO().getJXInfo(bonusSendMonth,bonusMonth,bonusYear,bonusSeason,haveSendDepartureInfo);
baseBean.writeLog("获取所有人的绩效等级、绩效系数等信息,共计:"+result.size());
// 获取所有本月(薪资发放月)离职人员信息
List<DepartureInfo> departureInfo = getMonthBonusDAO().getDepartureInfo(bonusSendMonth);
baseBean.writeLog("发放月离职人员信息:"+departureInfo.size());
List<CountMonthBonus> departureTemp = new ArrayList<>();
// 循环所属月下一个月到离职月之间的绩效等级-》绩效系数
baseBean.writeLog("获取所有离职人员所属月下一个月到离职月之间的绩效等级、绩效系数等信息");
for(int i=0;i<departureInfo.size();i++){
DepartureInfo info = departureInfo.get(i);
Calendar countCal = Calendar.getInstance();
countCal.setTime(bonusMonth);
countCal.add(Calendar.MONTH,1);
// 核算月在员工入职日期前
if(rybsInfoMap.get(info.getXm()) != null && BjcjCommonUtils.isBeforeMonth(countCal.getTime(),rybsInfoMap.get(info.getXm()).getRzrq())){
continue;
}
while (countCal.getTime().before(info.getLzrq()) || countCal.getTime().equals(info.getLzrq())){
int year = countCal.get(Calendar.YEAR);
int season =countCal.get(Calendar.MONTH)/3+1;
CountMonthBonus j = getMonthBonusDAO().getJXInfoByUser(info.getXm(), bonusSendMonth, countCal.getTime(), year, season);
result.add(j);
departureTemp.add(j);
countCal.add(Calendar.MONTH,1);
}
}
//获取所有人的薪酬等级和绩效工资
result = result.stream().map(r -> {
getMonthBonusDAO().getXCDJ(r);
return r;
}).collect(Collectors.toList());
baseBean.writeLog("获取所有人的薪酬等级和绩效工资");
// 获取在职员工的考勤周期上个月29-这个月28
Calendar startAttendanceCal = BjcjCommonUtils.getStartAttendanceCal(bonusMonth);
Calendar endAttendanceCal = BjcjCommonUtils.getEndAttendanceCal(bonusMonth);
// 获取所有人的境外常驻信息
List<JwCZInfoDetail> czInfos = getMonthBonusDAO().getCZInfo();
baseBean.writeLog("获取所有人的境外常驻信息,共:"+czInfos.size());
// 将境外常驻信息格式化
List<JwCZInfo> jwCZInfos = formatJwCZInfo(czInfos);
baseBean.writeLog("将境外常驻信息格式化");
// 获取所有用户考勤模块中缺勤天数
Attend4MonthBonus p = Attend4MonthBonus.builder().beginDate(startAttendanceCal.getTime()).endDate(endAttendanceCal.getTime()).build();
Map<String, Double> qqDatas = getKQ4MonthBonusService().getKQDatas(p);
if(qqDatas != null){
baseBean.writeLog("获取所有用户考勤模块中缺勤天数:"+qqDatas.size());
}
// 循环将离职人员的各个月的缺勤天数取到
Map<String, Double> qqDatasDepar= new HashMap<>();
for(int i=0;i<departureTemp.size();i++){
Date saDate = BjcjCommonUtils.getStartAttendanceCal(departureTemp.get(i).getKqyf()).getTime();
Date eaDate = BjcjCommonUtils.getEndAttendanceCal(departureTemp.get(i).getKqyf()).getTime();
qqDatasDepar.putAll(getKQ4MonthBonusService().getKQDatas(Attend4MonthBonus.builder().beginDate(saDate).endDate(eaDate).user(Integer.valueOf(departureTemp.get(i).getXm())).build()));
}
baseBean.writeLog("获取所有离职人员的各个月的缺勤天数:"+qqDatasDepar.size());
// 将缺勤信息合并
qqDatas.putAll(qqDatasDepar);
// baseBean.writeLog("所有人员的各个月的缺勤天数:"+qqDatas.size());
// 所有有境外常驻信息的用户
List<String> jwCZUsers = jwCZInfos.stream().map(item -> item.getXm()).collect(Collectors.toList());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
// 计算考勤月内的月度绩效信息
baseBean.writeLog("计算考勤月内的月度绩效信息");
result = result.stream().map(item -> {
DepartureInfo userInfo = rybsInfoMap.get(new Integer(item.getXm()));
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())));
}
// 是否是入职月或离职月 加上其他缺勤天数
if(userInfo != null && BjcjCommonUtils.isEqualsMonth(userInfo.getRzrq(),item.getKqyf()) ){
qq = qq + userInfo.getRzqqts();
}
if(userInfo != null && BjcjCommonUtils.isEqualsMonth(userInfo.getLzrq(),item.getKqyf())){
qq = qq + userInfo.getLzqqts();
}
if(qq>21.75){
// 境内员工并且缺勤天数大于21.75可能导致负数因此修正缺勤天数为21.75
qq = 21.75;
}
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<JwCZInfo> collect = jwCZInfos.stream().filter(i -> i.getXm().equals( item.getXm())).collect(Collectors.toList());
List<JwCZInfoDetail> infos = collect.get(0).getInfos();
double[] ycq = {0};
List<Date> details = new ArrayList<>();
// 考勤开始日期(在职、离职)
Calendar s = BjcjCommonUtils.getStartAttendanceCal(item.getKqyf());
// 考勤结束日期(在职、离职)
Calendar e = BjcjCommonUtils.getEndAttendanceCal(item.getKqyf());
// 用于存储计算到哪一天的日期
Calendar c = Calendar.getInstance();
c.setTime(e.getTime());
Calendar[] countDay = {c};
for(int i=0;i<infos.size();i++){
JwCZInfoDetail infoi = infos.get(i);
if(infoi.getLx()==0 && (infoi.getJwczksrq().before(e.getTime()) || infoi.getJwczksrq().equals(e.getTime())) ){
// 开始常驻
if(infoi.getJwczksrq().after(s.getTime())){
// 开始常驻日期在 考勤开始日期后,结束日期前
int d = BjcjCommonUtils.getDays(infoi.getJwczksrq(), e.getTime());
ycq[0]+=d;
countDay[0].setTime(infoi.getJwczksrq());
countDay[0].add(Calendar.DATE,-1);
}else{
// 开始常驻日期在 考勤开始日期前(应出勤日期为自然日)
ycq[0]=BjcjCommonUtils.getDays(s.getTime(), e.getTime());
break;
}
}
if(infoi.getLx()==1 &&
((infoi.getJwczksrq().before(e.getTime()) || infoi.getJwczksrq().equals(e.getTime()))
&& (infoi.getJwczjsrq().after(s.getTime()) || infoi.getJwczjsrq().equals(s.getTime())) )){
// 将区间转换为记录
Calendar starCal = Calendar.getInstance();
starCal.setTime(infoi.getJwczksrq());
while (starCal.getTime().before(infoi.getJwczjsrq()) || starCal.getTime().equals(infoi.getJwczjsrq())) {
details.add(starCal.getTime());
starCal.add(Calendar.DAY_OF_YEAR, 1);
}
}
if(i==infos.size()-1){
// 已经将所有考勤周期内境外常驻的区间时间转换为记录
Calendar aCal = Calendar.getInstance();
aCal.setTime(countDay[0].getTime());
aCal.set(Calendar.HOUR_OF_DAY, 0);
aCal.set(Calendar.MINUTE, 0);
aCal.set(Calendar.SECOND, 0);
aCal.set(Calendar.MILLISECOND, 0);
if(details.size()==0 && countDay[0].getTime().equals(e.getTime())){
// 该考勤周期内员工没有境外常驻信息
ycq[0]=21.75;
break;
}
while (s.getTime().before(aCal.getTime()) || s.getTime().equals(aCal.getTime())){
if(details.contains(aCal.getTime())){
// 存在境外记录
ycq[0]++;
aCal.add(Calendar.DATE,-1);
}else{
// 没有境外记录,判断是否是工作日
if( (aCal.get(Calendar.DAY_OF_WEEK) != 1) && (aCal.get(Calendar.DAY_OF_WEEK)!=7) ){
// 是工作日
ycq[0]++;
}
aCal.add(Calendar.DATE,-1);
}
}
}
}
item.setYcq(ycq[0]);
double qq=0.0;
if(qqDatas.containsKey( (item.getXm()+"-"+sdf.format(item.getKqyf())) )){
qq = qqDatas.get((item.getXm()+"-"+sdf.format(item.getKqyf())));
}
// 是否是入职月或离职月 加上其他缺勤天数
if(userInfo != null && BjcjCommonUtils.isEqualsMonth(userInfo.getRzrq(),item.getKqyf()) ){
qq = qq + userInfo.getRzqqts();
}
if(userInfo != null && BjcjCommonUtils.isEqualsMonth(userInfo.getLzrq(),item.getKqyf())){
qq = qq + userInfo.getLzqqts();
}
if(ycq[0]==21.75 && qq>21.75){
// 没有境外常驻信息并且缺勤天数大于21.75可能导致负数因此修正缺勤天数为21.75
qq = 21.75;
}
item.setQq(qq);
// 实出勤天数 =应出勤天数-缺勤天数
double scqTemp =ycq[0]-qq;
if (scqTemp<0){
scqTemp=0.0;
}
item.setScq(scqTemp);
// 奖金基数(考勤)= 月度绩效奖金基数-月度绩效基数/满勤*缺勤天数
double kqjs= item.getYdjjjxjs() - item.getYdjjjxjs()/ycq[0]*qq;
item.setJjjskq(kqjs);
// 奖金实发放额= 奖金基数(考勤)*个人绩效系数
item.setYfje(item.getGrjxxs() * kqjs);
}
return item;
}).collect(Collectors.toList());
// 处理离职人员离职所在月份的数据
// 将离职信息转为map
// baseBean.writeLog("处理离职人员离职所在月份的数据");
// Map<Integer, Date> 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 = BjcjCommonUtils.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()+BjcjCommonUtils.getDays(deparLastDay.getTime(), deaprAttendEndDay.getTime());
// }
// DepartureInfo userRyInfo = rybsInfoMap.get(Integer.valueOf(i.getXm()));
// sqq[0] = i.getQq() + userRyInfo.getQtqqts();
//
// 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);
// }
// });
// 先删除建模中脏数据
getMonthBonusDAO().clear(bonusMonth,bonusSendMonth,haveSendDepartureInfo);
baseBean.writeLog("先删除建模中脏数据");
// 将数据插入建模中
List<Integer> departureUsers = departureInfo.stream().map(i -> i.getXm()).collect(Collectors.toList());
baseBean.writeLog("将数据插入建模中共:"+result.size());
getMonthBonusDAO().insertList(result,departureUsers,bonusSendMonth,id);
return "null";
}
/**
* @description 境外常驻信息格式化
* @return void
* @author Harryxzy
* @date 2022/9/11 17:07
*/
public static List<JwCZInfo> formatJwCZInfo(List<JwCZInfoDetail> czInfos) {
Map<String, List<JwCZInfoDetail>> groupByName = czInfos.stream().collect(Collectors.groupingBy(item -> item.getXm()));
List<JwCZInfo> formatJwCZInfos = new ArrayList<>();
for (Map.Entry<String, List<JwCZInfoDetail>> entry : groupByName.entrySet()) {
JwCZInfo build = new JwCZInfo().builder().xm(entry.getValue().get(0).getXm()).infos(entry.getValue()).build();
formatJwCZInfos.add(build);
}
return formatJwCZInfos;
}
}