考勤-加班计划流程,加班时长去除休息班次中的休息时段

zm_dev
sy 8 months ago
parent 5d3b9aefbe
commit d7b410364a

@ -18,6 +18,8 @@ public interface UtilService {
Map<String, List<Map<String, Object>>> getScheduleInfoWithEmpId(List<String> empIdList, String startDate, String endDate);
String getRqlxInScheduleInfo(String empId,String date);
/**
*
*

@ -1459,7 +1459,7 @@ public class AttendanceSummaryServiceImpl extends Service implements AttendanceS
String startDate = (String) forceTimeItem.get("startDate");
String endDate = (String) forceTimeItem.get("endDate");
return rq.compareTo(startDate) >= 0 && ("".equals(endDate) || rq.compareTo(endDate) <= 0);
} else if (listType.equals(PersonGroupListTypeEnum.CONDITION.getKey())) {
} else if (listType.equals(PersonGroupListTypeEnum.CONDITION.getKey()) || listType.equals(PersonGroupListTypeEnum.SQLCONDITION.getKey())) {
List<Map<String, Object>> forceTimeItemList = (List<Map<String, Object>>) userManageInfo.get(empId);
boolean forceTimeAllowSign;
for (Map<String, Object> forceTimeItem : forceTimeItemList) {

@ -66,7 +66,24 @@ public class UtilServiceImpl extends Service implements UtilService {
}
return scheduleInfo;
}
/**
*
*/
@Override
public String getRqlxInScheduleInfo(String empId,String date) {
Map<String,Object> params = new HashMap<>();
params.put("tableName", "uf_pbjg");
params.put("startDate", date);
params.put("endDate", date);
params.put("pblx", "0");
params.put("current", "1");
params.put("pageSize", "99");
params.put("recurrence", "1");
params.put("pbdx", empId);
Map<String,Object> schedulingResultsMap = schedulingResultsService.queryDataTableActualUse(params);
List<Map<String, Object>> schedulingData = (List<Map<String, Object>>) schedulingResultsMap.get("data");
return schedulingData.size() > 0 ? Util.null2String(schedulingData.get(0).get("rqlx")) : "";
}
/**
*

@ -1,19 +1,26 @@
package com.engine.jucailinkq.attendance.workflow.action;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.UtilService;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.UtilServiceImpl;
import com.engine.jucailinkq.attendance.enums.AccountingUnitEnum;
import com.engine.jucailinkq.attendance.enums.AttendanceItemTypeEnum;
import com.engine.jucailinkq.attendance.enums.DateTypeEnum;
import com.engine.jucailinkq.attendance.enums.WorkForTimeEnum;
import com.engine.jucailinkq.attendance.workflow.service.MakeUpClockInService;
import com.engine.jucailinkq.attendance.workflow.service.impl.MakeUpClockInServiceImpl;
import com.engine.jucailinkq.common.util.CommonUtil;
import com.engine.jucailinkq.common.util.DateUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.jucailinkq.common.util.DbTools;
import com.engine.jucailinkq.common.util.Utils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -23,6 +30,7 @@ import java.util.stream.Collectors;
public class OvertimePlanCheckAction implements Action {
private MakeUpClockInService makeUpClockInService = ServiceUtil.getService(MakeUpClockInServiceImpl.class);
private UtilService utilService = ServiceUtil.getService(UtilServiceImpl.class);
@Override
public String execute(RequestInfo requestInfo) {
@ -34,15 +42,29 @@ public class OvertimePlanCheckAction implements Action {
//加班人员
String jbry = mainTableData.get("jbry");
try {
//获取人员id和姓名信息
List<String> empIdList = Arrays.asList(jbry.split(","));
Map<String, String> empIdToNameInfo = CommonUtil.empIdToNameInfo(empIdList);
//获取作用时段包含计划加班的加班类型的考勤项目集合
String sql = "select id,mc, bddrqlx, jbqsfzs, xzzjbsc, rzdjbxss, zzdjbxss, yzdjbxss, zysd, ccclfs from uf_jcl_kq_kqxm where xmlx = ?";
List<Map<String, Object>> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey());
Map<String, Map<String, Object>> jblxInfo = jblxAttendanceList.stream()
.filter(f -> Util.null2String(f.get("zysd")).contains(WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey()))
.collect(Collectors.toMap(e->e.get("id").toString(), e->e));
//明细数据按照人员分组
Map<String,List<Map<String, String>>> detailGroupMap = detailTableData.stream().collect(Collectors.groupingBy(e->Util.null2String(e.get("jbry"))));
List<String> errorMessage = new ArrayList<>();
for (Map.Entry<String,List<Map<String, String>>> tableEntry :detailGroupMap.entrySet()){
List<Map<String, String>> detailGroupByUserList = tableEntry.getValue();
Map<String, Object> params = Maps.newHashMap();
if ("".equals(tableEntry.getKey())){
params.put("userId",jbry);
String empId = tableEntry.getKey();
if ("".equals(empId)){
log.error("明细表中存在缺少加班人员信息的数据!");
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
requestInfo.getRequestManager().setMessagecontent("明细表中存在缺少加班人员信息的数据!");
return Action.FAILURE_AND_CONTINUE;
}else {
params.put("userId",tableEntry.getKey());
params.put("userId", empId);
}
params.put("submitDate",DateUtil.getCurrentDate());
params.put("submitStr","ksrq");
@ -82,6 +104,105 @@ public class OvertimePlanCheckAction implements Action {
requestInfo.getRequestManager().setMessagecontent(message);
return Action.FAILURE_AND_CONTINUE;
}
//校验加班类型中最小加班分钟数、工作日最大加班小时数、周最大加班小时数、月最大加班小时数等限定值
List<Map<String, String>> overtimeDetailList = tableEntry.getValue();
Map<String, Object> matchItemInfo;
if (overtimeDetailList == null || overtimeDetailList.size() == 0) {
continue;
}
Map<String, Double> weekOvertimeInfo = new HashMap<>();
Map<String, Double> monthOvertimeInfo = new HashMap<>();
for (Map<String, String> overtimeDetailItem : overtimeDetailList) {
String belongDate = overtimeDetailItem.get("gsrq");
//从排班信息获取归属日日期类型
String belongDateType = utilService.getRqlxInScheduleInfo(empId, belongDate);
//排班信息无法获取日期类型时,从日历信息获取
belongDateType = "".equals(belongDateType) ? CommonUtil.getRqlx(empId, belongDate) : belongDateType;
//排班和日历都无法获取时,默认为工作日
belongDateType = "".equals(belongDateType) ? DateTypeEnum.WORK_DAY.getKey() : belongDateType;
String startDate = overtimeDetailItem.get("ksrq");
String jbsc = overtimeDetailItem.get("jbsc");
double overtimeMinutes = Double.parseDouble(jbsc) * 60;
String jblxId = overtimeDetailItem.getOrDefault("jblx", "");
matchItemInfo = jblxInfo.getOrDefault(jblxId, new HashMap<>());
String minMinutes = Util.null2String(matchItemInfo.get("jbqsfzs"));
if (!"".equals(minMinutes) && Integer.parseInt(minMinutes) > overtimeMinutes) {
//最小加班分钟数大于单条明细的加班时长分钟数
String message = Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班分钟数小于加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的最小加班分钟数!";
log.error(message);
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
requestInfo.getRequestManager().setMessagecontent(message);
return Action.FAILURE_AND_CONTINUE;
}
String limitTotalOvertimeSc = Util.null2String(matchItemInfo.get("xzzjbsc"));
if ("1".equals(limitTotalOvertimeSc)) {
String limitWorkDayHours = Util.null2String(matchItemInfo.get("rzdjbxss"));
String limitWeekHours = Util.null2String(matchItemInfo.get("zzdjbxss"));
String limitMonthHours = Util.null2String(matchItemInfo.get("yzdjbxss"));
String limitDealType = Util.null2String(matchItemInfo.get("ccclfs"));
boolean doLimitWorkDayHours = false;
boolean doLimitWeekHours = false;
boolean doLimitMonthHours = false;
//判断是否满足工作日加班最大小时数
boolean needCheckWorkDayHours = !"".equals(limitWorkDayHours) && (belongDateType.equals(DateTypeEnum.WORK_DAY.getKey()) || belongDateType.equals(DateTypeEnum.CHANGECLASS.getKey()));
if (needCheckWorkDayHours && Double.compare(Double.parseDouble(limitWorkDayHours), overtimeMinutes / 60.0) < 0) {
doLimitWorkDayHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的工作日加班最大小时数!");
}
//判断是否满足周加班最大小时数
if (!"".equals(limitWeekHours)) {
int weekRank = DateUtil.weekRank(belongDate);
double maxWeekMinutes = Double.parseDouble(limitWeekHours) *60;
double weekOvertimeMinutes;
if (weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank) == null) {
String countStartDate = DateUtil.beforeDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01", 6);
String countEndDate = DateUtil.AfterDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-28", 9);
weekOvertimeMinutes = getWeekTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
weekOvertimeMinutes = weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank);
}
weekOvertimeInfo.put(belongDate.split("-")[0] + "" + weekRank, weekOvertimeMinutes + overtimeMinutes);
if (maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0) {
//达到周加班最大小时数
doLimitWeekHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的周加班最大小时数!");
}
}
//判断是否满足月加班最大小时数
if (!"".equals(limitMonthHours)) {
String yearMonth = belongDate.substring(0, 7);
double maxMonthMinutes = Double.parseDouble(limitMonthHours) *60;
double monthOvertimeMinutes;
if (monthOvertimeInfo.get(yearMonth) == null) {
String countStartDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01";
String countEndDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-31";
monthOvertimeMinutes = getMonthTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
monthOvertimeMinutes = monthOvertimeInfo.get(yearMonth);
}
monthOvertimeInfo.put(yearMonth, monthOvertimeMinutes + overtimeMinutes);
if (maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0) {
//达到月加班最大小时数
doLimitMonthHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + startDate + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的月加班最大小时数!");
}
}
//判断是否超出工作日、周、月最大小时数要求,在加班类型考勤项目中设置为“禁止提交时”,返回报错
if ("1".equals(limitDealType) && (doLimitWorkDayHours || doLimitWeekHours || doLimitMonthHours)) {
log.error("超出加班类型工作日/周/月最大加班小时数限制!");
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
requestInfo.getRequestManager().setMessagecontent(String.valueOf(errorMessage));
return Action.FAILURE_AND_CONTINUE;
}
}
}
}
}catch (Exception e){
@ -90,4 +211,63 @@ public class OvertimePlanCheckAction implements Action {
}
return Action.SUCCESS;
}
/**
*
* @param dataList
* @return
*/
public double getWeekTimeMinutes(List<Map<String, Object>> dataList,String date){
int day = TimeUtil.getDayOfWeek(date);
if (day ==0){
day = 7;
}
String startDate = DateUtil.beforeDay(date,day-1);
String endDate = DateUtil.AfterDay(date,7-day);
List<Map<String, Object>> list = dataList.stream().filter(e->{
String sjksrq = Util.null2String(e.get("sjksrq"));
if (DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(startDate)) >=0 &&
DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(endDate)) <=0 &&
DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(date)) !=0){
return true;
}else {
return false;
}
}).collect(Collectors.toList());
double totalMinutes = 0;
for (Map<String, Object> data:list){
String hsdw = data.get("hsdw").toString();
totalMinutes += Utils.getItemduration(1, AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
}
return totalMinutes;
}
/**
*
* @param dataList
* @return
*/
public double getMonthTimeMinutes(List<Map<String, Object>> dataList,String date){
String startDate = date.split("-")[0]+"-"+ date.split("-")[1]+"-01";
String endDate = date.split("-")[0]+"-"+ date.split("-")[1]+"-31";
List<Map<String, Object>> list = dataList.stream().filter(e->DateUtil.getTime(e.get("sjksrq").toString()).compareTo(DateUtil.getTime(startDate))>=0 &&
DateUtil.getTime(e.get("sjjsrq").toString()).compareTo(DateUtil.getTime(endDate))<=0).collect(Collectors.toList());
double totalMinutes = 0;
for (Map<String, Object> data:list){
String hsdw = data.get("hsdw").toString();
totalMinutes += Utils.getItemduration(1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
}
return totalMinutes;
}
/**
*
*/
public List<Map<String, Object>> getWorkOverTimeResults(String startDate,String endDate,String userId){
String sql = "select a.sjjbsc, a.sjksrq, a.sjjsrq, a.jblx, b.hsdw from uf_jcl_kq_jbjg a left join uf_jcl_kq_kqxm b on a.jblx = b.id where a.jbry=? and a.sjksrq>=? and a.sjjsrq<=?";
List<Map<String, Object>> dataList = DbTools.getSqlToList(sql,userId,startDate,endDate);
return dataList;
}
}

@ -4,15 +4,14 @@ import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.UtilService;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.UtilServiceImpl;
import com.engine.jucailinkq.attendance.enums.AttendanceItemTypeEnum;
import com.engine.jucailinkq.attendance.enums.ClassSegmentTypeEnum;
import com.engine.jucailinkq.attendance.enums.DateTypeEnum;
import com.engine.jucailinkq.attendance.enums.WorkForTimeEnum;
import com.engine.jucailinkq.attendance.enums.*;
import com.engine.jucailinkq.attendance.workflow.service.OvertimePlanService;
import com.engine.jucailinkq.common.util.CommonUtil;
import com.engine.jucailinkq.common.util.DateUtil;
import com.engine.jucailinkq.common.util.DbTools;
import com.engine.jucailinkq.common.util.Utils;
import lombok.extern.slf4j.Slf4j;
import weaver.general.TimeUtil;
import weaver.general.Util;
import java.util.*;
@ -68,6 +67,8 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
Map<String, String> dateToBcxxMap = scheduleInfoList == null ? new HashMap<>() : scheduleInfoList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("bcrq")), e->Util.null2String(e.get("bcxx"))));
Map<String, String> dateTypeInfoFromBc = scheduleInfoList == null ? new HashMap<>() : scheduleInfoList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("bcrq")), e->Util.null2String(e.get("rqlx"))));
existOvertimePlanList = existOvertimePlanInfo.get(empId);
Map<String, Double> weekOvertimeInfo = new HashMap<>();
Map<String, Double> monthOvertimeInfo = new HashMap<>();
for (String date : dateList) {
String realEndDate = date;
detailItem = new HashMap<>();
@ -76,8 +77,8 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
detailItem.put("ksrq", date);
detailItem.put("kssj", startTime);
detailItem.put("jssj", endTime);
detailItem.put("jblx", null);
detailItem.put("jblxName", null);
detailItem.put("jblx", "");
detailItem.put("jblxName", "");
//开始时时和结束时间存在跨天情况时,即开始时间大于等于结束时间
if (startTime.compareTo(endTime) >= 0) {
realEndDate = DateUtil.AfterDay(date,1);
@ -157,23 +158,23 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
boolean currentDayOverLap = !"".equals(currentDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, currentDayStartTime, currentDayEndTime);
boolean beforeDayOverLap = !"".equals(beforeDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, beforeDayStartTime, beforeDayEndTime);
boolean nextDayOverLap = !"".equals(nextDayStartToEnd) && DateUtil.isOverlapping(date + " " + startTime, realEndDate + " " + endTime, nextDayStartTime, nextDayEndTime);
//20240814需求变更。非休息班次出现重叠时间自动调整加班开始或结束时间并返回提示
Map<String, String> adjustInfo = new HashMap<>();
adjustInfo.put("startWithAdjust", date + " " + startTime);
adjustInfo.put("endWithAdjust", realEndDate + " " + endTime);
if ((!currentDayRestBc && currentDayOverLap) || (!beforeDayRestBc && beforeDayOverLap) || (!nextDayRestBc && nextDayOverLap)) {
//20240814需求变更。非休息班次出现重叠时间自动调整加班开始或结束时间并返回提示
Map<String, String> adjustInfo = new HashMap<>();
adjustInfo.put("startWithAdjust", date + " " + startTime);
adjustInfo.put("endWithAdjust", realEndDate + " " + endTime);
//处理前一天
if(beforeDayOverLap) {
if(!beforeDayRestBc && beforeDayOverLap) {
belongDate = DateUtil.beforeDay(date, 1);
adjustInfo = doAdjust(adjustInfo, beforeDayStartTime, beforeDayEndTime);
}
//处理当天
if(currentDayOverLap) {
if(!currentDayRestBc && currentDayOverLap) {
belongDate = "".equals(belongDate) ? date : belongDate;
adjustInfo = doAdjust(adjustInfo, currentDayStartTime, currentDayEndTime);
}
//处理次日
if(nextDayOverLap) {
if(!nextDayRestBc && nextDayOverLap) {
belongDate = "".equals(belongDate) ? DateUtil.AfterDay(date, 1) : belongDate;
adjustInfo = doAdjust(adjustInfo, nextDayStartTime, nextDayEndTime);
}
@ -183,19 +184,27 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
detailItem.put("jssj", adjustInfo.get("endTime"));
detailItem.put("jsrq", adjustInfo.get("endDate"));
overtimeMinutes = DateUtil.getBetWeenMinutes(adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"));
detailItem.put("jbsc", String.format("%.2f", overtimeMinutes / 60.0));
//4-非休息班次,出现重叠时间,属于不合理加班安排,返回提示”已自动调整开始和结束时间点“
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划区间和非休息班次班段出现时间重叠,已自动调整开始和结束时间点!");
//5-加班区间和休息班次出现重叠,首次重叠的日期,即为归属日期
} else if (beforeDayRestBc && beforeDayOverLap) {
}
//5-加班区间和休息班次出现重叠,首次重叠的日期,即为归属日期;如果已有归属日,则比较当前日期和归属日谁更早
//20240816需求变更需要去除重叠的休息班次中的休息时段时长
int restOverLapMinutes = 0;
if (beforeDayRestBc && beforeDayOverLap) {
belongDate = DateUtil.beforeDay(date, 1);
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(beforeDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), DateUtil.beforeDay(date, 1));
} else if (currentDayRestBc && currentDayOverLap) {
belongDate = date;
belongDate = "".equals(belongDate) || date.compareTo(belongDate) < 0 ? date : belongDate;
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(currentDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), date);
} else if (nextDayRestBc && nextDayOverLap) {
belongDate = DateUtil.AfterDay(date, 1);
belongDate = "".equals(belongDate) ? DateUtil.AfterDay(date, 1) : belongDate;
restOverLapMinutes = restOverLapMinutes
+ countRestOverLapMinutes(nextDayBcId, adjustInfo.get("startWithAdjust"), adjustInfo.get("endWithAdjust"), DateUtil.AfterDay(date, 1));
}
overtimeMinutes = overtimeMinutes - restOverLapMinutes;
detailItem.put("jbsc", String.format("%.2f", overtimeMinutes / 60.0));
}
//判断归属日的日期类型,首先从排班的信息来获取
String belongDateType = dateTypeInfoFromBc.getOrDefault(belongDate, "");
@ -208,6 +217,7 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取人员在归属日被设置的考勤项目
List<Map<String, Object>> attendanceItemSetList = CommonUtil.getAttendanceItemsByEmpIdDate(empId, belongDate);
List<String> kqxmSetIds = attendanceItemSetList.stream().map(f->f.get("keyid").toString()).collect(Collectors.toList());
log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的可用考勤项目:" + kqxmSetIds);
Map<String, Object> matchItemInfo = new HashMap<>();
for (Map<String, Object> attendanceItemInfo : jblxAttendanceList) {
//判断该加班类型考勤项目是否被该人员使用,且考勤项目的绑定的日期类型是否包含归属日期类型
@ -221,9 +231,11 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
detailItem.put("gsrq", belongDate);
//20240814需求变更。增加单条明细的最小加班分钟数校验工作日加班最大小时数、周加班最大小时数、月加班最大小时数
if (matchItemInfo.size() == 0) {
log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划未匹配到合适的加班类型!");
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划未匹配到合适的加班类型!");
continue;
} else {
log.info(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划匹配到:" + Util.null2String(matchItemInfo.get("mc")));
String minMinutes = Util.null2String(matchItemInfo.get("jbqsfzs"));
if (!"".equals(minMinutes) && Integer.parseInt(minMinutes) > overtimeMinutes) {
//最小加班分钟数大于单条明细的加班时长分钟数
@ -236,21 +248,61 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
String limitWorkDayHours = Util.null2String(matchItemInfo.get("rzdjbxss"));
String limitWeekHours = Util.null2String(matchItemInfo.get("zzdjbxss"));
String limitMonthHours = Util.null2String(matchItemInfo.get("yzdjbxss"));
String limitDealType = Util.null2String(matchItemInfo.get("ccclfs"));
boolean doLimitWorkDayHours = false;
boolean doLimitWeekHours = false;
boolean doLimitMonthHours = false;
//判断是否满足工作日加班最大小时数
boolean needCheckWorkDayHours = !"".equals(limitWorkDayHours) && (belongDateType.equals(DateTypeEnum.WORK_DAY.getKey()) || belongDateType.equals(DateTypeEnum.CHANGECLASS.getKey()));
if (needCheckWorkDayHours && Double.compare(Double.parseDouble(limitWorkDayHours), overtimeMinutes / 60.0) < 0) {
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长加班类型-"
doLimitWorkDayHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的工作日加班最大小时数!");
continue;
}
//判断是否满足周加班最大小时数
if (!"".equals(limitWeekHours)) {
int weekRank = DateUtil.weekRank(belongDate);
double maxWeekMinutes = Double.parseDouble(limitWeekHours) *60;
double weekOvertimeMinutes;
if (weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank) == null) {
String countStartDate = DateUtil.beforeDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01", 6);
String countEndDate = DateUtil.AfterDay(belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-28", 9);
weekOvertimeMinutes = getWeekTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
weekOvertimeMinutes = weekOvertimeInfo.get(belongDate.split("-")[0] + "" + weekRank);
}
weekOvertimeInfo.put(belongDate.split("-")[0] + "" + weekRank, weekOvertimeMinutes + overtimeMinutes);
if (maxWeekMinutes - weekOvertimeMinutes - overtimeMinutes < 0) {
//达到周加班最大小时数
doLimitWeekHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的周加班最大小时数!");
}
}
//判断是否满足月加班最大小时数
if (!"".equals(limitMonthHours)) {
String yearMonth = belongDate.substring(0, 7);
double maxMonthMinutes = Double.parseDouble(limitMonthHours) *60;
double monthOvertimeMinutes;
if (monthOvertimeInfo.get(yearMonth) == null) {
String countStartDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-01";
String countEndDate = belongDate.split("-")[0]+"-"+ belongDate.split("-")[1]+"-31";
monthOvertimeMinutes = getMonthTimeMinutes(getWorkOverTimeResults(countStartDate, countEndDate, empId), belongDate);
} else {
monthOvertimeMinutes = monthOvertimeInfo.get(yearMonth);
}
monthOvertimeInfo.put(yearMonth, monthOvertimeMinutes + overtimeMinutes);
if (maxMonthMinutes - monthOvertimeMinutes - overtimeMinutes < 0) {
//达到月加班最大小时数
doLimitMonthHours = true;
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班时长累计后超过了加班类型-"
+ Util.null2String(matchItemInfo.get("mc")) +"设置的月加班最大小时数!");
}
}
// //判断是否超出工作日、周、月最大小时数要求
// if ("1".equals(limitDealType) && (doLimitWorkDayHours || doLimitWeekHours || doLimitMonthHours)) {
// continue;
// }
}
}
overtimePlanDetailList.add(detailItem);
@ -258,12 +310,11 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
if (errorMessage.size() == 0) {
resultMap.put("status", true);
resultMap.put("data", overtimePlanDetailList);
} else {
resultMap.put("status", false);
resultMap.put("errorInfo", errorMessage);
resultMap.put("data", null);
}
resultMap.put("data", overtimePlanDetailList);
} catch (Exception e) {
log.info(e.getMessage());
@ -274,6 +325,21 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
return resultMap;
}
/**
*
*/
private int countRestOverLapMinutes(String nextDayBcId, String startTime, String endTime, String date) {
List<String> countBdlxList = new ArrayList<>();
countBdlxList.add(ClassSegmentTypeEnum.REST_AND_DINE.getKey());
countBdlxList.add(ClassSegmentTypeEnum.REST_PERIOD.getKey());
countBdlxList.add(ClassSegmentTypeEnum.DINING_PERIOD.getKey());
String sql = "select id, bdlx, gsrq, kssj as dtkssj, jssj as dtjssj from uf_jcl_kq_bcxx_dt1 where mainid = " + nextDayBcId;
List<Map<String, Object>> bcDetailData = DbTools.getSqlToList(sql);
bcDetailData = bcDetailData.stream().filter(e -> countBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
//获取需要累计的班段时长区间和目标区间存在交集的分钟数
return Utils.removeTime(startTime, endTime, bcDetailData, date);
}
private Map<String, String> doAdjust(Map<String, String> adjustInfo, String bcStartTime, String bcEndTime) {
String startWithAdjust = adjustInfo.get("startWithAdjust");
String endWithAdjust = adjustInfo.get("endWithAdjust");
@ -366,4 +432,63 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
return startToEnd;
}
/**
*
* @param dataList
* @return
*/
public double getWeekTimeMinutes(List<Map<String, Object>> dataList,String date){
int day = TimeUtil.getDayOfWeek(date);
if (day ==0){
day = 7;
}
String startDate = DateUtil.beforeDay(date,day-1);
String endDate = DateUtil.AfterDay(date,7-day);
List<Map<String, Object>> list = dataList.stream().filter(e->{
String sjksrq = Util.null2String(e.get("sjksrq"));
if (DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(startDate)) >=0 &&
DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(endDate)) <=0 &&
DateUtil.getTime(sjksrq).compareTo(DateUtil.getTime(date)) !=0){
return true;
}else {
return false;
}
}).collect(Collectors.toList());
double totalMinutes = 0;
for (Map<String, Object> data:list){
String hsdw = data.get("hsdw").toString();
totalMinutes += Utils.getItemduration(1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
}
return totalMinutes;
}
/**
*
* @param dataList
* @return
*/
public double getMonthTimeMinutes(List<Map<String, Object>> dataList,String date){
String startDate = date.split("-")[0]+"-"+ date.split("-")[1]+"-01";
String endDate = date.split("-")[0]+"-"+ date.split("-")[1]+"-31";
List<Map<String, Object>> list = dataList.stream().filter(e->DateUtil.getTime(e.get("sjksrq").toString()).compareTo(DateUtil.getTime(startDate))>=0 &&
DateUtil.getTime(e.get("sjjsrq").toString()).compareTo(DateUtil.getTime(endDate))<=0).collect(Collectors.toList());
double totalMinutes = 0;
for (Map<String, Object> data:list){
String hsdw = data.get("hsdw").toString();
totalMinutes += Utils.getItemduration(1,AccountingUnitEnum.MINUTES.getKey(), Double.valueOf(data.get("sjjbsc").toString()),AccountingUnitEnum.getEnum(hsdw),8);
}
return totalMinutes;
}
/**
*
*/
public List<Map<String, Object>> getWorkOverTimeResults(String startDate,String endDate,String userId){
String sql = "select a.sjjbsc, a.sjksrq, a.sjjsrq, a.jblx, b.hsdw from uf_jcl_kq_jbjg a left join uf_jcl_kq_kqxm b on a.jblx = b.id where a.jbry=? and a.sjksrq>=? and a.sjjsrq<=?";
List<Map<String, Object>> dataList = DbTools.getSqlToList(sql,userId,startDate,endDate);
return dataList;
}
}

@ -591,6 +591,7 @@ public class CommonUtil {
sqltj = Utils.converSQL(sqltj);
log.info("getPersonnelGroupingByPerson sqltj : [{}]",sqltj);
List<Map<String,Object>> dataList = DbTools.getSqlToList(sqltj);
log.info("dataList_size :{}",dataList.size());
for (Map<String,Object> dataMap :dataList){
String hrmId = Util.null2String(dataMap.get("id"));
if (empGroupUserInfo.get(hrmId) == null) {
@ -921,7 +922,7 @@ public class CommonUtil {
if (dataIds.size() > 0){
sql = "select b.id keyid,b.mc kqxm,c.mc famc,b.* from uf_jcl_kq_kqfa_dt1 a left join uf_jcl_kq_kqxm b on a.kqxm=b.id left join uf_jcl_kq_kqfa c on a.mainid=c.id " +
"where mainid in ("+String.join(",",dataIds)+") and (b.xmzt is null or b.xmzt <> '0') " +
"and c.zt = 0 and (c.sxrq0 is null or c.sxrq0 >= ?) and (c.sxrq1 is null or c.sxrq1 <= ?)";
"and c.zt = 0 and (c.sxrq0 is null or c.sxrq0 <= ?) and (c.sxrq1 is null or c.sxrq1 >= ?)";
attendanceItems.addAll(DbTools.getSqlToList(sql, date, date));
}
return attendanceItems;

@ -419,4 +419,16 @@ public class DateUtil {
// 如果不重叠返回0
return 0;
}
/**
*
*/
public static int weekRank(String dateStr) throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = formatter.parse(dateStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置星期一为一周开始的第一天
return calendar.get(Calendar.WEEK_OF_YEAR);
}
}

Loading…
Cancel
Save