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

343 lines
18 KiB
Java
Raw Normal View History

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;
2022-09-26 14:52:34 +08:00
import com.engine.bjcj220907.utils.BjcjCommonUtils;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
2023-02-07 11:30:46 +08:00
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) {
2022-09-20 15:39:37 +08:00
// 获取绩效日期的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;
2023-02-07 11:30:46 +08:00
// 获取已经离职并且已经发放过绩效的人员信息
baseBean.writeLog("获取已经离职并且已经发放过绩效的人员信息");
List<Integer> haveSendDepartureInfo = getMonthBonusDAO().getHaveSendDepartureInfo().stream().map(i->i.getXm()).collect(Collectors.toList());
2023-02-07 11:30:46 +08:00
baseBean.writeLog("获取已经离职并且已经发放过绩效的人员信息 共:"+haveSendDepartureInfo.size());
// 获取所有人的入职日期、离职日期、其他缺勤天数
List<DepartureInfo> rybsInfo = getMonthBonusDAO().getRybsInfo();
2023-02-28 15:33:46 +08:00
baseBean.writeLog("获取所有人的入职日期、离职日期、其他缺勤天数"+rybsInfo.size());
2023-02-07 11:30:46 +08:00
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);
2022-09-19 23:04:29 +08:00
baseBean.writeLog("获取所有人的绩效等级、绩效系数等信息,共计:"+result.size());
// 获取所有本月(薪资发放月)离职人员信息
List<DepartureInfo> departureInfo = getMonthBonusDAO().getDepartureInfo(bonusSendMonth);
2023-02-28 15:33:46 +08:00
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);
2023-02-07 11:30:46 +08:00
// 核算月在员工入职日期前
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
2022-09-26 14:52:34 +08:00
Calendar startAttendanceCal = BjcjCommonUtils.getStartAttendanceCal(bonusMonth);
Calendar endAttendanceCal = BjcjCommonUtils.getEndAttendanceCal(bonusMonth);
// 获取所有人的境外常驻信息
List<JwCZInfoDetail> czInfos = getMonthBonusDAO().getCZInfo();
2022-09-19 23:04:29 +08:00
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);
2023-04-07 18:00:57 +08:00
if(qqDatas != null){
baseBean.writeLog("获取所有用户考勤模块中缺勤天数:"+qqDatas.size());
}
// 循环将离职人员的各个月的缺勤天数取到
Map<String, Double> qqDatasDepar= new HashMap<>();
for(int i=0;i<departureTemp.size();i++){
2022-09-26 14:52:34 +08:00
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()));
}
2023-02-28 15:33:46 +08:00
baseBean.writeLog("获取所有离职人员的各个月的缺勤天数:"+qqDatasDepar.size());
// 将缺勤信息合并
qqDatas.putAll(qqDatasDepar);
2023-04-07 18:00:57 +08:00
// 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 -> {
2023-02-07 11:30:46 +08:00
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())));
}
2023-02-07 11:30:46 +08:00
// 是否是入职月或离职月 加上其他缺勤天数
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();
}
2022-11-01 13:40:19 +08:00
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<>();
// 考勤开始日期(在职、离职)
2022-09-26 14:52:34 +08:00
Calendar s = BjcjCommonUtils.getStartAttendanceCal(item.getKqyf());
// 考勤结束日期(在职、离职)
2022-09-26 14:52:34 +08:00
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())){
// 开始常驻日期在 考勤开始日期后,结束日期前
2022-09-26 14:52:34 +08:00
int d = BjcjCommonUtils.getDays(infoi.getJwczksrq(), e.getTime());
ycq[0]+=d;
countDay[0].setTime(infoi.getJwczksrq());
countDay[0].add(Calendar.DATE,-1);
}else{
// 开始常驻日期在 考勤开始日期前(应出勤日期为自然日)
2022-09-26 14:52:34 +08:00
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())));
}
2023-02-07 11:30:46 +08:00
// 是否是入职月或离职月 加上其他缺勤天数
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();
}
2022-11-01 13:40:19 +08:00
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
2023-02-07 11:30:46 +08:00
// 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);
2023-04-07 18:00:57 +08:00
baseBean.writeLog("先删除建模中脏数据");
// 将数据插入建模中
List<Integer> departureUsers = departureInfo.stream().map(i -> i.getXm()).collect(Collectors.toList());
2022-09-20 13:43:56 +08:00
baseBean.writeLog("将数据插入建模中共:"+result.size());
2022-09-20 15:39:37 +08:00
getMonthBonusDAO().insertList(result,departureUsers,bonusSendMonth,id);
return "null";
}
2022-09-26 14:52:34 +08:00
/**
* @description 境外常驻信息格式化
* @return void
* @author Harryxzy
* @date 2022/9/11 17:07
*/
2022-09-26 14:52:34 +08:00
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;
}
}