You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
17 KiB
Java
274 lines
17 KiB
Java
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.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* 加班计划流程提交检查
|
|
*/
|
|
@Slf4j
|
|
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) {
|
|
String requestid = requestInfo.getRequestid();
|
|
// 流程表单主表数据
|
|
HashMap<String,String> mainTableData = CommonUtil.getMainTableInfo(requestInfo);
|
|
// 流程表单明细表数据
|
|
List<Map<String, String>> detailTableData = CommonUtil.getDetailTableInfo(requestInfo,0);
|
|
//加班人员
|
|
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();
|
|
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", empId);
|
|
}
|
|
params.put("submitDate",DateUtil.getCurrentDate());
|
|
params.put("submitStr","ksrq");
|
|
params.put("submitDataList",detailGroupByUserList);
|
|
|
|
/**
|
|
* 考勤周期校验
|
|
*/
|
|
if (detailGroupByUserList == null || detailGroupByUserList.size() == 0){
|
|
log.error("明细表没有数据!");
|
|
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
|
|
requestInfo.getRequestManager().setMessagecontent("明细表没有数据!");
|
|
return Action.FAILURE_AND_CONTINUE;
|
|
}
|
|
Map<String,Object> dataMap = makeUpClockInService.getKqCycleTimeIntervalCmd(params);
|
|
List<Map<String,Object>> closeList = (List<Map<String,Object>>)dataMap.get("closeList");
|
|
List<String> nocycleList = (List<String>)dataMap.get("nocycleList");
|
|
List<Map<String,Object>> dateList = (List<Map<String,Object>>)dataMap.get("dataList");
|
|
|
|
boolean status = (boolean)dataMap.get("status");
|
|
if (!status){
|
|
log.error("该人员没有考勤周期");
|
|
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
|
|
requestInfo.getRequestManager().setMessagecontent("该人员没有考勤周期!");
|
|
return Action.FAILURE_AND_CONTINUE;
|
|
}
|
|
if (closeList.size() > 0 || nocycleList.size() > 0){
|
|
String message = "";
|
|
if (nocycleList.size() > 0){
|
|
message = message +String.join(",",nocycleList)+"未找对对应的考勤周期;";
|
|
}
|
|
if (closeList.size() > 0){
|
|
List<String> list = closeList.stream().map(e->e.get("rq").toString()).collect(Collectors.toList());
|
|
message = message +String.join(",",list)+"对应的考勤周期的考勤周期已关账";
|
|
}
|
|
requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
|
|
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){
|
|
log.error("OvertimePlanCheckAction error : [{}]",e);
|
|
return Action.FAILURE_AND_CONTINUE;
|
|
}
|
|
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;
|
|
}
|
|
}
|