考勤-加班计划流程,加班计划明细中加班计划和归属日期自动匹配逻辑

zm_dev
sy 9 months ago
parent a8ff90dee3
commit 3d82396dfe

@ -4,7 +4,10 @@ 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.workflow.service.OvertimePlanService;
import com.engine.jucailinkq.common.util.CommonUtil;
import com.engine.jucailinkq.common.util.DateUtil;
@ -28,13 +31,13 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
@Override
public Map<String, Object> generateOvertimePlanDetails(Map<String, Object> params) {
Map<String,Object> resultMap = new HashMap<>();
List<String> errorMessage = new ArrayList<>();
try {
// 流程表单主表数据
Map<String,String> mainTableData = (Map<String,String>)params.get("mainTableData");
log.info("mainTableData : {}", mainTableData);
//加班人员、开始日期、结束日期、开始时间、结束时间
String jbry = Util.null2String(mainTableData.get("jbry"));
String jblx = Util.null2String(mainTableData.get("jblx"));
String startDate = Util.null2String(mainTableData.get("ksrq"));
String endDate = Util.null2String(mainTableData.get("jsrq"));
String startTime = Util.null2String(mainTableData.get("kssj"));
@ -44,32 +47,34 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//获取加班日期集合
List<String> dateList = DateUtil.getDatesBetween(startDate, endDate);
//获取人员列表在日期区间的班次数据
Map<String, List<Map<String, Object>>> scheduleInfoMap = utilService.getScheduleInfoWithEmpId(empIdList, startDate, DateUtil.AfterDay(endDate,1));
Map<String, List<Map<String, Object>>> scheduleInfoMap = utilService.getScheduleInfoWithEmpId(empIdList, DateUtil.beforeDay(startDate, 1), DateUtil.AfterDay(endDate,1));
List<Map<String, String>> overtimePlanDetailList = new ArrayList<>();
List<String> workBdlxList = new ArrayList<>();
workBdlxList.add(ClassSegmentTypeEnum.WORK_TIME.getKey());workBdlxList.add(ClassSegmentTypeEnum.EXTENDED_OVERTIME.getKey());
workBdlxList.add(ClassSegmentTypeEnum.EARLY_OVERTIME.getKey());workBdlxList.add(ClassSegmentTypeEnum.OVERTIME_IN_CLASS.getKey());
Map<String, String> detailItem;
String sql = "";
//获取加班类型信息
sql = "select id,mc from uf_jcl_kq_kqxm where id = " + jblx;
Map<String, Object> jblxData = DbTools.getSqlToMap(sql);
String jblxName = Util.null2String(jblxData.get("mc"));
//获取作用时段包含计划加班的加班类型的考勤项目集合
sql = "select id,mc, bddrqlx from uf_jcl_kq_kqxm where xmlx = ? and zysd = ?";
List<Map<String, Object>> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey(), WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey());
//获取人员id和姓名信息
Map<String, String> empIdToNameInfo = CommonUtil.empIdToNameInfo(empIdList);
List<Map<String, Object>> bcDetailData;
for (String empId : empIdList) {
List<Map<String, Object>> scheduleInfoList = scheduleInfoMap.get(empId);
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"))));
for (String date : dateList) {
String realEndDate = date;
detailItem = new HashMap<>();
detailItem.put("jbry", empId);
detailItem.put("jbryName", Util.null2String(empIdToNameInfo.get(empId)));
detailItem.put("jblx", jblx);
detailItem.put("jblxName", jblxName);
detailItem.put("ksrq", date);
detailItem.put("kssj", startTime);
detailItem.put("jssj", endTime);
detailItem.put("jblx", null);
detailItem.put("jblxName", null);
//开始时时和结束时间存在跨天情况时,即开始时间大于等于结束时间
if (startTime.compareTo(endTime) >= 0) {
realEndDate = DateUtil.AfterDay(date,1);
@ -81,47 +86,95 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
//根据班次数据,设置归属日期
//获取当天班次id
String currentDayBcId = Util.null2String(dateToBcxxMap.get(date)).split("-")[0];
//当天比较最晚工作时段/加班时段的结束时间点和加班计划明细的开始时间点的差值
Integer currentDayDiffMinutes = 9999;
if (!"".equals(currentDayBcId)) {
//查询当天班次明细
sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, kssj desc";
bcDetailData = DbTools.getSqlToList(sql);
bcDetailData = bcDetailData.stream().filter(e -> workBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
if (bcDetailData.size() > 0) {
String gsrqValue = Util.null2String(bcDetailData.get(0).get("gsrq"));
String jssj = Util.null2String(bcDetailData.get(0).get("jssj"));
String matchDate = "2".equals(gsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(gsrqValue) ? DateUtil.beforeDay(date,1) : date);
currentDayDiffMinutes = (matchDate + jssj).compareTo(date + startTime) > 0 ? DateUtil.getBetWeenMinutes(date + " " + startTime, matchDate + " " + jssj) : DateUtil.getBetWeenMinutes(matchDate + " " + jssj, date + " " + startTime);
}
}
//获取当天班次开始时间和结束时间
String currentDayStartToEnd = getBcStartAndEndTime(date, currentDayBcId, workBdlxList);
String currentDayStartTime = !"".equals(currentDayStartToEnd) ? currentDayStartToEnd.split(",")[0] : "";
String currentDayEndTime = !"".equals(currentDayStartToEnd) ? currentDayStartToEnd.split(",")[1] : "";
//获取前1天班次id
String beforeDayBcId = Util.null2String(dateToBcxxMap.get(DateUtil.beforeDay(date, 1))).split("-")[0];
//获取前1天班次开始时间和结束时间
String beforeDayStartToEnd = getBcStartAndEndTime(DateUtil.beforeDay(date, 1), beforeDayBcId, workBdlxList);
String beforeDayStartTime = !"".equals(beforeDayStartToEnd) ? beforeDayStartToEnd.split(",")[0] : "";
String beforeDayEndTime = !"".equals(beforeDayStartToEnd) ? beforeDayStartToEnd.split(",")[1] : "";
//获取次日班次id
String nextDay = DateUtil.AfterDay(date,1);
String nextDayBcId = Util.null2String(dateToBcxxMap.get(nextDay)).split("-")[0];
//次日比较最早工作时段/加班时段的开始时间点和加班计划明细的结束时间点的差值
Integer nextDayDiffMinutes = 9999;
if (!"".equals(nextDayBcId)) {
//查次日班次明细
sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + nextDayBcId + " order by gsrq, kssj";
bcDetailData = DbTools.getSqlToList(sql);
bcDetailData = bcDetailData.stream().filter(e -> workBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
if (bcDetailData.size() > 0) {
String gsrqValue = Util.null2String(bcDetailData.get(0).get("gsrq"));
String kssj = Util.null2String(bcDetailData.get(0).get("kssj"));
String matchDate = "2".equals(gsrqValue) ? DateUtil.AfterDay(nextDay,1) : ("0".equals(gsrqValue) ? DateUtil.beforeDay(nextDay,1) : nextDay);
nextDayDiffMinutes = (matchDate + kssj).compareTo(realEndDate + endTime) > 0 ? DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, matchDate + " " + kssj) : DateUtil.getBetWeenMinutes(matchDate + " " + kssj, realEndDate + " " + endTime);
}
String nextDayBcId = Util.null2String(dateToBcxxMap.get(DateUtil.AfterDay(date, 1))).split("-")[0];
//获取次日班次开始时间和结束时间
String nextDayStartToEnd = getBcStartAndEndTime(DateUtil.AfterDay(date, 1), nextDayBcId, workBdlxList);
String nextDayStartTime = !"".equals(nextDayStartToEnd) ? nextDayStartToEnd.split(",")[0] : "";
String nextDayEndTime = !"".equals(nextDayStartToEnd) ? nextDayStartToEnd.split(",")[1] : "";
//梳理加班时间段和班段时间段合理的情况
boolean beforeToCurrentDay = false;
boolean currentToNextDay = false;
boolean beforeToNextDay = false;
String belongDate = "";
if (!"".equals(currentDayStartToEnd)) {
//1-加班时间段处于前一日下班后和当日上班前
beforeToCurrentDay = ("".equals(beforeDayEndTime) || beforeDayEndTime.compareTo(date + " " + startTime) <= 0) && currentDayStartTime.compareTo(realEndDate + " " + endTime) >=0;
//2-加班时间段处于当日下班后和次日上班前
currentToNextDay = ("".equals(nextDayStartTime) || nextDayStartTime.compareTo(realEndDate + " " + endTime) >= 0) && currentDayEndTime.compareTo(date + " " + startTime) <=0;
} else {
//3-加班时间段处于前一日下班后和次日上班前
beforeToNextDay = ("".equals(beforeDayEndTime) || beforeDayEndTime.compareTo(date + " " + startTime) <= 0)
&& ("".equals(nextDayStartTime) || nextDayStartTime.compareTo(realEndDate + " " + endTime) >= 0);
}
if (currentDayDiffMinutes <= nextDayDiffMinutes) {
detailItem.put("gsrq", date);
if (beforeToCurrentDay) {
int beforeDayDiffMinutes = !"".equals(beforeDayEndTime) ? DateUtil.getBetWeenMinutes(beforeDayEndTime, date + " " + startTime) : 9999;
int currentDayDiffMinutes = DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, currentDayStartTime);
belongDate = currentDayDiffMinutes < beforeDayDiffMinutes ? date : DateUtil.beforeDay(date, 1);
} else if (currentToNextDay) {
int nextDayDiffMinutes = !"".equals(nextDayStartTime) ? DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, nextDayStartTime) : 9999;
int currentDayDiffMinutes = DateUtil.getBetWeenMinutes(currentDayEndTime, date + " " + startTime);
belongDate = currentDayDiffMinutes <= nextDayDiffMinutes ? date : DateUtil.AfterDay(date, 1);
} else if (beforeToNextDay) {
int beforeDayDiffMinutes = !"".equals(beforeDayEndTime) ? DateUtil.getBetWeenMinutes(beforeDayEndTime, date + " " + startTime) : 9999;
int nextDayDiffMinutes = !"".equals(nextDayStartTime) ? DateUtil.getBetWeenMinutes(realEndDate + " " + endTime, nextDayStartTime) : 9999;
if (beforeDayDiffMinutes > 120 && nextDayDiffMinutes > 120) {
//当天没班次时前后两天班次班段与加班区间相隔超过120分钟时则归属日为请假开始日期
belongDate = date;
} else {
belongDate = beforeDayDiffMinutes <= nextDayDiffMinutes ? DateUtil.beforeDay(date, 1) : DateUtil.AfterDay(date, 1);
}
} else {
detailItem.put("gsrq", nextDay);
//4-其他情况,属于不合理加班安排,返回报错
errorMessage.add(Util.null2String(empIdToNameInfo.get(empId)) + "在日期" + date + "的加班计划区间和班次班段出现时间重叠,不允许申请加班!");
continue;
}
//判断归属日的日期类型,首先从排班的信息来获取
String belongDateType = dateTypeInfoFromBc.getOrDefault(belongDate, "");
//排班信息无法获取日期类型时,从日历信息获取
belongDateType = "".equals(belongDateType) ? CommonUtil.getRqlx(empId, belongDate) : belongDateType;
//排班和日历都无法获取时,默认为工作日
belongDateType = "".equals(belongDateType) ? DateTypeEnum.WORK_DAY.getKey() : belongDateType;
//通过人员id、归属日期、归属日期类型来自动匹配加班类型
//获取人员在归属日被设置的考勤项目
List<Map<String, Object>> attendanceItemSetList = CommonUtil.getAttendanceItemsByEmpIdDate(empId, belongDate);
List<String> kqxmSetIds = attendanceItemSetList.stream().map(f->f.get("keyid").toString()).collect(Collectors.toList());
for (Map<String, Object> attendanceItemInfo : jblxAttendanceList) {
//判断该加班类型考勤项目是否被该人员使用,且考勤项目的绑定的日期类型是否包含归属日期类型
if (kqxmSetIds.contains(Util.null2String(attendanceItemInfo.get("id")))
&& Util.null2String(attendanceItemInfo.get("bddrqlx")).contains(belongDateType)) {
detailItem.put("jblx", Util.null2String(attendanceItemInfo.get("id")));
detailItem.put("jblxName", Util.null2String(attendanceItemInfo.get("mc")));
}
}
detailItem.put("gsrq", belongDate);
overtimePlanDetailList.add(detailItem);
}
}
resultMap.put("status", true);
resultMap.put("data", overtimePlanDetailList);
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);
}
} catch (Exception e) {
log.info(e.getMessage());
resultMap.put("status", false);
@ -130,4 +183,28 @@ public class OvertimePlanServiceImpl extends Service implements OvertimePlanServ
}
return resultMap;
}
public String getBcStartAndEndTime(String date, String currentDayBcId, List<String> workBdlxList) {
String startToEnd = "";
if (!"".equals(currentDayBcId)) {
//查询当天班次明细
String sql = "select id, bdlx, gsrq, kssj, jssj from uf_jcl_kq_bcxx_dt1 where mainid = " + currentDayBcId + " order by gsrq desc, kssj desc";
List<Map<String, Object>> bcDetailData = DbTools.getSqlToList(sql);
bcDetailData = bcDetailData.stream().filter(e -> workBdlxList.contains(Util.null2String(e.get("bdlx")))).collect(Collectors.toList());
if (bcDetailData.size() > 0) {
String endGsrqValue = Util.null2String(bcDetailData.get(0).get("gsrq"));
String lastJssj = Util.null2String(bcDetailData.get(0).get("jssj"));
String lastKssj = Util.null2String(bcDetailData.get(0).get("kssj"));
String bdEndDate = "2".equals(endGsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(endGsrqValue) ? DateUtil.beforeDay(date,1) : date);
bdEndDate = lastKssj.compareTo(lastJssj) >= 0 ? DateUtil.AfterDay(bdEndDate,1) : bdEndDate;
String startGsrqValue = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("gsrq"));
String firstKssj = Util.null2String(bcDetailData.get(bcDetailData.size() - 1).get("kssj"));
String bdStartDate = "2".equals(startGsrqValue) ? DateUtil.AfterDay(date,1) : ("0".equals(startGsrqValue) ? DateUtil.beforeDay(date,1) : date);
startToEnd = bdStartDate + " " + firstKssj + "," + bdEndDate + " " + lastJssj;
}
}
return startToEnd;
}
}

@ -837,5 +837,93 @@ public class CommonUtil {
return null;
}
/**
* @param empId id
* @param date
* @return
*/
public static List<Map<String,Object>> getAttendanceItemsByEmpIdDate(String empId, String date) {
String modeId = Utils.getFormmodeIdMap().get("uf_jcl_kq_kqfa");
Map<String,Object> resultMap = Maps.newHashMap();
String sql = "select dxlx,dataid,dx from uf_jcl_syzz where modeid=?";
List<Map<String,Object>> organizationList = DbTools.getSqlToList(sql,modeId);
sql = "select id,departmentid,subcompanyid1 from hrmresource where id =?";
Map<String,Object> departMentMap = DbTools.getSqlToMap(sql, empId);
Set<String> dataIds = Sets.newHashSet();
Map<String, List<Map<String,Object>>> organizationListGroupBydxlx = organizationList.stream().collect(Collectors.groupingBy(e ->e.get("dxlx").toString()));
//对象类型为人员
List<Map<String,Object>> personOrganizationList = organizationListGroupBydxlx.get("0");
//对象类型为人员组织
List<Map<String,Object>> personGroupOrganizationList = organizationListGroupBydxlx.get("1");
//对象类型为部门
List<Map<String,Object>> departmentOrganizationList = organizationListGroupBydxlx.get("2");
//对象类型为分部
List<Map<String,Object>> subCompanyOrganizationList = organizationListGroupBydxlx.get("3");
if (personOrganizationList != null){
for (Map<String,Object> personOrganization :personOrganizationList){
String dx = Util.null2String(personOrganization.get("dx"));
String ids = dx.split("-")[0];
if (ids.equals(empId)){
dataIds.add(Util.null2String(personOrganization.get("dataid")));
}
}
}
try {
if (departmentOrganizationList != null){
String deptid = Util.null2String(departMentMap.get("departmentid"));
String pdeptids = "";
pdeptids = new DepartmentComInfo().getAllParentDepartId(Util.null2String(departMentMap.get("departmentid")), pdeptids);
pdeptids = deptid + pdeptids;
for (Map<String,Object> departmentOrganization :departmentOrganizationList){
String dx = Util.null2String(departmentOrganization.get("dx"));
String ids = dx.split("-")[0];
for (String pdeptid : pdeptids.split(",")){
if (pdeptid.equals(ids)){
dataIds.add(Util.null2String(departmentOrganization.get("dataid")));
}
}
}
}
}catch (Exception e){
log.error("catch error :{}",e);
}
if (subCompanyOrganizationList != null){
String subCompanyId = Util.null2String(departMentMap.get("subcompanyid1"));
for (Map<String,Object> subCompanyOrganization :subCompanyOrganizationList){
String dx = Util.null2String(subCompanyOrganization.get("dx"));
String ids = dx.split("-")[0];
if (ids.equals(subCompanyId)){
dataIds.add(Util.null2String(subCompanyOrganization.get("dataid")));
}
}
}
if (personGroupOrganizationList != null){
Set<String> personGroupIds = personGroupOrganizationList.stream().map(e -> Util.null2String(e.get("dx")).split("-")[0]).collect(Collectors.toSet());
sql = "select mainid,empid,filters,sqltj,bdate,edate from uf_ryqz_dt1 where mainid in ("+String.join(",",personGroupIds)+")";
List<Map<String,Object>> personGroupData = DbTools.getSqlToList(sql);
Set<String> personnelGroupIds = PersongroupCommonUtil.getPersonnelGroupingByPerson(personGroupData, empId,date, date);
for (Map<String,Object> personGroupOrganization :personGroupOrganizationList){
String personnelGroupId = Util.null2String(personGroupOrganization.get("dx")).split("-")[0];
if (personnelGroupIds.contains(personnelGroupId)){
dataIds.add(Util.null2String(personGroupOrganization.get("dataid")));
}
}
}
//收集通用考勤项目
sql = "select id keyid,mc kqxm,a.* from uf_jcl_kq_kqxm a where tyxm=1 and (xmzt is null or xmzt <> '0')";
List<Map<String,Object>> attendanceItems = DbTools.getSqlToList(sql);
//收集目标人员适用考勤方案中的考勤项目
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 <= ?)";
attendanceItems.addAll(DbTools.getSqlToList(sql, date, date));
}
return attendanceItems;
}
}

Loading…
Cancel
Save