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

434 lines
24 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.dao.OverseasAllowanceDAO;
import com.engine.bjcj220907.entity.*;
import com.engine.bjcj220907.service.GetKQ4OverseasAllowanceCountService;
import com.engine.bjcj220907.service.OverseasAllowanceCountService;
import com.engine.bjcj220907.utils.BjcjCommonUtils;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import weaver.general.BaseBean;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Harryxzy
* @date 2022/09/26 14:03
* @description 境外津贴
*/
public class OverseasAllowanceCountServiceImpl extends Service implements OverseasAllowanceCountService {
BaseBean baseBean = new BaseBean();
public MonthBonusDAO getMonthBonusDAO(){
return new MonthBonusDAO();
}
public OverseasAllowanceDAO getOverseasAllowanceDAO(){
return new OverseasAllowanceDAO();
}
private GetKQ4OverseasAllowanceCountService GetKQ4OverseasAllowanceCountService() {
return ServiceUtil.getService(GetKQ4OverseasAllowanceCountServiceImpl.class,user);
}
/**
* @description 计算境外津贴
* @return void
* @author Harryxzy
* @date 2022/9/26 14:06
*/
@Override
public void countOverseasAllowance(Calendar countCal) {
// 境外津贴包含:境外津贴(天标准)+境外工龄补贴(月标准)+艰苦地区补贴(天标准)
// 考勤开始日期
Calendar startAttendanceCal = BjcjCommonUtils.getStartAttendanceCal(countCal.getTime());
// 考勤结束日期
Calendar endAttendanceCal = BjcjCommonUtils.getEndAttendanceCal(countCal.getTime());
baseBean.writeLog("考勤开始日期:"+startAttendanceCal.getTime()+",考勤结束日期:"+endAttendanceCal);
// 获取境外津贴(天标准) --计算当月应常驻天数
// 获取所有人的境外常驻信息
List<JwCZInfoDetail> czInfos = getOverseasAllowanceDAO().getCZInfo(startAttendanceCal.getTime(),endAttendanceCal.getTime());
baseBean.writeLog("获取所有人的境外常驻信息,共:"+czInfos.size());
// 将境外常驻信息格式化
List<JwCZInfo> jwCZInfos = formatJwCZInfo(czInfos,startAttendanceCal,endAttendanceCal);
baseBean.writeLog("将境外常驻信息格式化,共:"+jwCZInfos.size());
// 如果用户在考勤周期内存在境外常驻信息则过滤出来,并且计算当月应常驻天数及境内工作天数
List<JWJT> results = new ArrayList<>();
jwCZInfos = getCZInfosAndCZDays(jwCZInfos, startAttendanceCal, endAttendanceCal,results);
baseBean.writeLog("获取用户在考勤周期内存在境外常驻信息过滤出来,并且计算当月境外应常驻天数及境内工作天数,共::"+results.size());
// 计算考勤所属月员工的薪酬等级,获取相应的境外津贴标准
List<String> users = results.stream().map(i -> i.getUser()).collect(Collectors.toList());
Map<Integer, XcdjJwjtParam> usersXCDJ = getOverseasAllowanceDAO().getXCDJByUsers(users,startAttendanceCal);
baseBean.writeLog("获取所有员工考勤所属月的薪酬等级及所对应的境外津贴标准、四项补贴合计,共:"+usersXCDJ.size());
// 获取考勤员工的公务回国天数 及 缺勤日期
Attend4MonthBonus build = Attend4MonthBonus.builder().beginDate(startAttendanceCal.getTime()).endDate(endAttendanceCal.getTime()).build();
Map<String, Object> kqDatas = GetKQ4OverseasAllowanceCountService().getKQDatas(build,users);
baseBean.writeLog("调用考勤接口获取公务回国天数 及 缺勤日期:"+kqDatas);
// 获取员工公务回国国内工作日天数
Map<Integer, List<JwCZInfoDetail>> gwhgInfos = getOverseasAllowanceDAO().getGwhg();
baseBean.writeLog("获取年假建模中所有公务回国信息,共:"+gwhgInfos.size());
// 过滤考勤周期内的公务回国信息,并计算出国内工作日天数
Map<Integer, Integer> validGwhgAndCountWorkdays = getValidGwhgAndCountWorkdays(gwhgInfos, startAttendanceCal.getTime(), endAttendanceCal.getTime());
baseBean.writeLog("过滤考勤周期内的公务回国信息,并计算出国内工作日天数:"+validGwhgAndCountWorkdays);
// 封装计算薪酬等级、境外津贴标准、考勤天数、四项补助合计、公务回国国内工作日天数
getXcdjAndJwjtbz(results,usersXCDJ,kqDatas,validGwhgAndCountWorkdays,jwCZInfos);
baseBean.writeLog("封装薪酬等级、境外津贴标准、考勤天数、境外实际常驻天数并计算实出勤天数、境外津贴,共:"+results.size());
// 处理第三国出差(2)、境外国内出差3艰苦地区补贴
Map<Integer, List<JwCZInfoDetail>> dsgccJkdq = getOverseasAllowanceDAO().getDsgcc();
baseBean.writeLog("获取第三国出差(2)、境外国内出差3艰苦地区补贴,共:"+dsgccJkdq.size());
baseBean.writeLog("第三国出差(2)、境外国内出差3艰苦地区补贴:"+dsgccJkdq);
// 封装第三国出差数、境外国内出差据到result中
getDsgcc(results,dsgccJkdq,startAttendanceCal.getTime(),endAttendanceCal.getTime());
// 计算艰苦地区补贴合计
coutJkdqbthj(results);
// 四项补贴合计(天标准)*(公务回国工作日天数+境外国内出差工作日天数+国内工作日天数)
countSxbthj(results);
baseBean.writeLog("计算四项补贴合计:"+results.size());
// 将结果插入建模表中
getOverseasAllowanceDAO().insertOverseasAllowance(results);
baseBean.writeLog("将结果插入建模表中");
}
/**
* @description 计算艰苦地区补贴合计
* @return void
* @author Harryxzy
* @date 2022/10/24 14:11
*/
private void coutJkdqbthj(List<JWJT> results) {
results.stream().forEach(result->{
double[] total={0.0};
List<JKDQBT> jkdqbts = result.getJkdqbts();
jkdqbts.stream().forEach(j -> {
total[0]=total[0]+j.getJkdqbt();
});
result.setJkdqbthj(total[0]);
});
}
/**
* @description 获取用户在考勤周期内存在境外常驻信息过滤出来,并且计算当月境外应常驻天数及境内工作天数
* @return List<JwCZInfo>
* @author Harryxzy
* @date 2022/9/26 16:29
*/
public List<JwCZInfo> getCZInfosAndCZDays(List<JwCZInfo> jwCZInfos,Calendar startAttendanceCal,Calendar endAttendanceCal,List<JWJT> results ){
List<JwCZInfo> collect = jwCZInfos.stream().filter(czInfo -> {
List<JwCZInfoDetail> czDetails = czInfo.getInfos();
// 用于存储计算到哪一天的日期
Calendar c = Calendar.getInstance();
c.setTime(endAttendanceCal.getTime());
Calendar[] countDay = {c};
int[] ycq = {0};
int[] gnycq = {0};
List<Date> details = new ArrayList<>();
ArrayList<JKDQBT> jkdqbts = new ArrayList<>();
for (int i = 0; i < czDetails.size(); i++) {
JwCZInfoDetail detail = czDetails.get(i);
if (detail.getLx() == 0 && (detail.getJwczksrq().before(endAttendanceCal.getTime()) || detail.getJwczksrq().equals(endAttendanceCal.getTime()))) {
// 涉及考勤周期内的开始常驻
if (detail.getJwczksrq().after(startAttendanceCal.getTime())) {
// 开始常驻日期在 考勤开始日期后,结束日期前
int days = BjcjCommonUtils.getDays(detail.getJwczksrq(), endAttendanceCal.getTime());
ycq[0] += days;
countDay[0].setTime(detail.getJwczksrq());
countDay[0].add(Calendar.DATE, -1);
// 存入常驻天数用于计算艰苦地区补贴
// int days1 = BjcjCommonUtils.getDays(detail.getJwczksrq(), endAttendanceCal.getTime());
detail.setDays(days);
JKDQBT jk = JKDQBT.builder().lx(detail.getLx()).days(days).jkdq(detail.getJkdq()).jkdqbtbz(detail.getJkdqbtbz()).jkdqbt((days*detail.getJkdqbtbz())).build();
jkdqbts.add(jk);
} else {
// 开始常驻日期在 考勤开始日期前(应出勤日期为自然日)
int days = BjcjCommonUtils.getDays(startAttendanceCal.getTime(), endAttendanceCal.getTime());
// 存入常驻天数用于计算艰苦地区补贴
// int days1 = BjcjCommonUtils.getDays(startAttendanceCal.getTime(), endAttendanceCal.getTime());
detail.setDays(days);
JKDQBT jk = JKDQBT.builder().lx(detail.getLx()).days(days).jkdq(detail.getJkdq()).jkdqbtbz(detail.getJkdqbtbz()).jkdqbt((days*detail.getJkdqbtbz())).build();
JWJT build = JWJT.builder().user(czInfo.getXm()).sfzh(czInfo.getSfzh()).jwycq(days).gngzts(0.0).kqMonth(endAttendanceCal.getTime()).jwgl(czInfo.getJsglts()).jwglbtybz(czInfo.getGlbtybz()).jwglbtrbz(czInfo.getGlbtrbz()).build();
ArrayList<JKDQBT> jkdqbtList = new ArrayList<>();
jkdqbtList.add(jk);
build.setJkdqbts(jkdqbtList);
results.add(build);
return true;
}
}
if (detail.getLx() == 1 &&
((detail.getJwczksrq().before(endAttendanceCal.getTime()) || detail.getJwczksrq().equals(endAttendanceCal.getTime()))
&& (detail.getJwczjsrq().after(startAttendanceCal.getTime()) || detail.getJwczjsrq().equals(startAttendanceCal.getTime())))) {
// 涉及考勤周期内的结束常驻
// 将区间转换为记录
Calendar starCal = Calendar.getInstance();
starCal.setTime(detail.getJwczksrq());
while (starCal.getTime().before(detail.getJwczjsrq()) || starCal.getTime().equals(detail.getJwczjsrq())) {
details.add(starCal.getTime());
starCal.add(Calendar.DAY_OF_YEAR, 1);
}
// 修正常驻开始时间和结束时间
Calendar countStartCal = Calendar.getInstance();
countStartCal.setTime(detail.getJwczksrq());
Calendar countEndCal = Calendar.getInstance();
countEndCal.setTime(detail.getJwczjsrq());
if(countStartCal.getTime().before(startAttendanceCal.getTime())){
countStartCal.setTime(startAttendanceCal.getTime());
}
if(countEndCal.getTime().after(endAttendanceCal.getTime())){
countEndCal.setTime(endAttendanceCal.getTime());
}
int days = BjcjCommonUtils.getDays(countStartCal.getTime(), countEndCal.getTime());
detail.setDays(days);
JKDQBT jk = JKDQBT.builder().lx(detail.getLx()).days(days).jkdq(detail.getJkdq()).jkdqbtbz(detail.getJkdqbtbz()).jkdqbt((days*detail.getJkdqbtbz())).build();
jkdqbts.add(jk);
}
if (i == czDetails.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(endAttendanceCal.getTime())) {
// 该考勤周期内员工没有境外常驻信息
return false;
}
while (startAttendanceCal.getTime().before(aCal.getTime()) || startAttendanceCal.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)) {
// 是工作日
gnycq[0]++;
}
aCal.add(Calendar.DATE, -1);
}
}
JWJT build = JWJT.builder().user(czInfo.getXm()).sfzh(czInfo.getSfzh()).jwycq(ycq[0]).gngzts(gnycq[0]).kqMonth(endAttendanceCal.getTime()).jwgl(czInfo.getJsglts()).jwglbtybz(czInfo.getGlbtybz()).jwglbtrbz(czInfo.getGlbtrbz()).build();
build.setJkdqbts(jkdqbts);
results.add(build);
return true;
}
}
return false;
}).collect(Collectors.toList());
return collect;
}
/**
* @description 将获取到的缺勤天数(请假)、公务回国天数、薪酬等级与境外津贴标准与人员对应并计算出实出勤天数
* @return void
* @author Harryxzy
* @date 2022/9/27 15:37
*/
public void getXcdjAndJwjtbz(List<JWJT> results ,Map<Integer, XcdjJwjtParam> usersXSDJ,Map<String, Object> kqDatas,Map<Integer, Integer> validGwhgAndCountWorkdays,List<JwCZInfo> jwCZInfos){
Map<String, List<JwCZInfoDetail>> czInfos = jwCZInfos.stream().collect(Collectors.toMap(JwCZInfo::getXm, JwCZInfo::getInfos));
results.stream().forEach(item-> {
XcdjJwjtParam param = usersXSDJ.get(Integer.valueOf(item.getUser()));
item.setXcdj(param.getXcdj());
item.setJwjtbz(param.getJwjtbz());
item.setSxbzhjbz(param.getSxbzhj());
item.setSxbzhjrbz(param.getSxbzhj()/21.75);
if(kqDatas.get(item.getUser() + "-qq") == null){
// 目前该员工没有考勤数据
item.setGnQq(0.0);
item.setJwQq(0.0);
item.setGwhg(0.0);
baseBean.writeLog("员工" +item.getUser()+"没有考勤数据!请核对考勤报表");
}else{
List<Date> qqDate =(List <Date>) kqDatas.get(item.getUser() + "-qq");
double gnQqDays=0.0;
double jwQqDays=0.0;
// 判断是境内缺勤还是境外缺勤
List<JwCZInfoDetail> jwCZInfoDetails = czInfos.get(item.getUser());
if(jwCZInfoDetails != null && jwCZInfoDetails.size()>0){
for(Date d : qqDate){
Boolean flag = false;
for(int i=0; (i<jwCZInfoDetails.size() && flag == false) ;i++){
JwCZInfoDetail detail = jwCZInfoDetails.get(i);
Calendar k = Calendar.getInstance();
k.setTime(detail.getJwczksrq());
setLastMinute(k);
detail.setJwczksrq(k.getTime());
if(detail.getJwczjsrq() != null){
Calendar j = Calendar.getInstance();
j.setTime(detail.getJwczjsrq());
setLastMinute(j);
detail.setJwczjsrq(j.getTime());
}
if(detail.getLx()==0){
// 开始常驻
if(detail.getJwczksrq().before(d) || detail.getJwczksrq().equals(d)){
// 在境外常驻期内的缺勤
jwQqDays++;
flag=true;
}
}else {
// 结束常驻
if(detail.getJwczjsrq().before(d)){
// 境外常驻结束日期在缺勤日前
gnQqDays++;
flag=true;
}
if(BjcjCommonUtils.isBetween(d,detail.getJwczksrq(),detail.getJwczjsrq())){
// 在境外常驻期内的缺勤
jwQqDays++;
flag=true;
}
}
if( (i+1 == jwCZInfoDetails.size()) && (flag == false)){
gnQqDays++;
}
}
}
}
item.setGnQq(gnQqDays);
item.setJwQq(jwQqDays);
item.setGwhg((Double) kqDatas.get(item.getUser()+"-gwhg"));
}
item.setJwscq(item.getJwycq()-item.getJwQq()-item.getGwhg());
item.setGnscq(item.getGngzts() - item.getGnQq());
item.setJwjt(item.getJwscq()*item.getJwjtbz());
if(validGwhgAndCountWorkdays.containsKey(Integer.valueOf(item.getUser()))){
// 该员工有公务回国数据
Integer workDays = validGwhgAndCountWorkdays.get(Integer.valueOf(item.getUser()));
item.setGwhgWorkdays(workDays);
}
});
}
private void setLastMinute(Calendar c){
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 59);
c.set(Calendar.SECOND, 59);
c.set(Calendar.MILLISECOND, 999);
}
/**
* @description 境外常驻信息格式化
* @return void
* @author Harryxzy
* @date 2022/9/28 17:07
*/
public static List<JwCZInfo> formatJwCZInfo(List<JwCZInfoDetail> czInfos,Calendar startAttendanceCal,Calendar endAttendanceCal) {
Map<String, List<JwCZInfoDetail>> groupByName = czInfos.stream().collect(Collectors.groupingBy(item -> item.getXm()));
int days = BjcjCommonUtils.getDays(startAttendanceCal.getTime(), endAttendanceCal.getTime());
List<JwCZInfo> formatJwCZInfos = new ArrayList<>();
for (Map.Entry<String, List<JwCZInfoDetail>> entry : groupByName.entrySet()) {
List<JwCZInfoDetail> values = entry.getValue();
JwCZInfo build = new JwCZInfo().builder().xm(values.get(0).getXm()).sfzh(values.get(0).getSfzh()).jsglts(values.get(0).getJsglts())
.glbtybz(values.get(0).getGlbtybz()).glbtrbz(values.get(0).getGlbtybz()/days)
.infos(entry.getValue()).build();
formatJwCZInfos.add(build);
}
return formatJwCZInfos;
}
/**
* @description 封装第三国出差和境外国内出差数据到results中
* @return void
* @author Harryxzy
* @date 2022/9/28 17:07
*/
public void getDsgcc(List<JWJT> results,Map<Integer, List<JwCZInfoDetail>> dsgccJkdq,Date startAttendance,Date endAttendance) {
results.stream().forEach(jwjt->{
Integer user = Integer.valueOf(jwjt.getUser());
if(dsgccJkdq.containsKey(user)){
// 该员工存在第三国出差数据
List<JwCZInfoDetail> jwCZInfoDetails = dsgccJkdq.get(user);
for(int i=0; i < jwCZInfoDetails.size(); i++){
JwCZInfoDetail detail = jwCZInfoDetails.get(i);
if ((detail.getJwczksrq().before(endAttendance) || detail.getJwczksrq().equals(endAttendance))
&& (detail.getJwczjsrq().after(startAttendance) || detail.getJwczjsrq().equals(startAttendance))) {
// 在考勤周期内的第三国出差数据
// 修正常驻开始时间和结束时间
Calendar countStartCal = Calendar.getInstance();
countStartCal.setTime(detail.getJwczksrq());
Calendar countEndCal = Calendar.getInstance();
countEndCal.setTime(detail.getJwczjsrq());
if(countStartCal.getTime().before(startAttendance)){
countStartCal.setTime(startAttendance);
}
if(countEndCal.getTime().after(endAttendance)){
countEndCal.setTime(endAttendance);
}
int days = BjcjCommonUtils.getDays(countStartCal.getTime(), countEndCal.getTime());
JKDQBT jk = JKDQBT.builder().lx(detail.getLx()).days(days).jkdq(detail.getJkdq()).jkdqbtbz(detail.getJkdqbtbz()).jkdqbt((days * detail.getJkdqbtbz())).build();
jwjt.getJkdqbts().add(jk);
}
}
}
});
}
/**
* @description 计算四项补助合计 = 四项补贴合计(天标准)*(公务回国工作日天数+国内工作日天数)
* @return void
* @author Harryxzy
* @date 2022/9/29 17:59
*/
private void countSxbthj(List<JWJT> results) {
results.stream().forEach(result->{
// 获取员工的公务回国工作日天数和国内工作日天数 * 四项补助日标准
result.setSxbzhj((result.getGnscq()+result.getGwhgWorkdays()) * result.getSxbzhjrbz());
});
}
/**
* @description 过滤考勤周期内的公务回国信息,并计算出国内工作日天数
* @return void
* @author Harryxzy
* @date 2022/10/21 9:47
*/
private Map<Integer,Integer> getValidGwhgAndCountWorkdays(Map<Integer, List<JwCZInfoDetail>> gwhgInfos, Date startAttendance, Date endAttendance) {
Map<Integer,Integer> result = new HashMap();
for(Map.Entry<Integer,List<JwCZInfoDetail>> entrySet : gwhgInfos.entrySet()){
List<JwCZInfoDetail> values = entrySet.getValue();
values.stream().forEach(value ->{
if( (value.getJwczksrq().before(endAttendance) || value.getJwczksrq().equals(endAttendance))
&& (value.getJwczjsrq().after(startAttendance) || value.getJwczjsrq().equals(startAttendance)) ){
// 在考勤周期内的公务回国,计算国内工作天数
Calendar countCal = Calendar.getInstance();
if(value.getJwczjsrq().after(endAttendance)){
countCal.setTime(endAttendance);
}else {
countCal.setTime(value.getJwczjsrq());
}
Calendar countStarCal = Calendar.getInstance();
if(value.getJwczksrq().before(startAttendance)){
countStarCal.setTime(startAttendance);
}else{
countStarCal.setTime(value.getJwczksrq());
}
int workDays=0;
while (countCal.getTime().after(countStarCal.getTime()) || countCal.getTime().equals(countStarCal.getTime())){
// 判断是否是工作日
if((countCal.get(Calendar.DAY_OF_WEEK) != 1) && (countCal.get(Calendar.DAY_OF_WEEK)!=7)){
workDays++;
}
countCal.add(Calendar.DATE,-1);
}
if(result.containsKey(entrySet.getKey())){
Integer integer = result.get(entrySet.getKey());
result.put(entrySet.getKey(), integer + workDays);
}else{
result.put(entrySet.getKey(), workDays);
}
}
});
}
return result;
}
}