diff --git a/src/com/engine/jucailinkq/attendance/workflow/service/impl/OvertimePlanServiceImpl.java b/src/com/engine/jucailinkq/attendance/workflow/service/impl/OvertimePlanServiceImpl.java index 0b1f852..9f659f8 100644 --- a/src/com/engine/jucailinkq/attendance/workflow/service/impl/OvertimePlanServiceImpl.java +++ b/src/com/engine/jucailinkq/attendance/workflow/service/impl/OvertimePlanServiceImpl.java @@ -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 generateOvertimePlanDetails(Map params) { Map resultMap = new HashMap<>(); + List errorMessage = new ArrayList<>(); try { // 流程表单主表数据 Map mainTableData = (Map)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 dateList = DateUtil.getDatesBetween(startDate, endDate); //获取人员列表在日期区间的班次数据 - Map>> scheduleInfoMap = utilService.getScheduleInfoWithEmpId(empIdList, startDate, DateUtil.AfterDay(endDate,1)); + Map>> scheduleInfoMap = utilService.getScheduleInfoWithEmpId(empIdList, DateUtil.beforeDay(startDate, 1), DateUtil.AfterDay(endDate,1)); List> overtimePlanDetailList = new ArrayList<>(); List 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 detailItem; String sql = ""; - //获取加班类型信息 - sql = "select id,mc from uf_jcl_kq_kqxm where id = " + jblx; - Map 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> jblxAttendanceList = DbTools.getSqlToList(sql, AttendanceItemTypeEnum.WORK_OVERTIME.getKey(), WorkForTimeEnum.PLAN_WORK_OVERTIME.getKey()); + //获取人员id和姓名信息 Map empIdToNameInfo = CommonUtil.empIdToNameInfo(empIdList); - List> bcDetailData; + for (String empId : empIdList) { List> scheduleInfoList = scheduleInfoMap.get(empId); Map dateToBcxxMap = scheduleInfoList == null ? new HashMap<>() : scheduleInfoList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("bcrq")), e->Util.null2String(e.get("bcxx")))); + Map 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> attendanceItemSetList = CommonUtil.getAttendanceItemsByEmpIdDate(empId, belongDate); + List kqxmSetIds = attendanceItemSetList.stream().map(f->f.get("keyid").toString()).collect(Collectors.toList()); + + for (Map 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 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> 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; + } } diff --git a/src/com/engine/jucailinkq/common/util/CommonUtil.java b/src/com/engine/jucailinkq/common/util/CommonUtil.java index e3e53bd..9732390 100644 --- a/src/com/engine/jucailinkq/common/util/CommonUtil.java +++ b/src/com/engine/jucailinkq/common/util/CommonUtil.java @@ -837,5 +837,93 @@ public class CommonUtil { return null; } + /** + * @param empId 人员id + * @param date 日期 + * @return 返回人员在指定日期在考勤方案和通用中被设置的考勤项目集合 + */ + public static List> getAttendanceItemsByEmpIdDate(String empId, String date) { + String modeId = Utils.getFormmodeIdMap().get("uf_jcl_kq_kqfa"); + Map resultMap = Maps.newHashMap(); + + String sql = "select dxlx,dataid,dx from uf_jcl_syzz where modeid=?"; + List> organizationList = DbTools.getSqlToList(sql,modeId); + sql = "select id,departmentid,subcompanyid1 from hrmresource where id =?"; + Map departMentMap = DbTools.getSqlToMap(sql, empId); + Set dataIds = Sets.newHashSet(); + Map>> organizationListGroupBydxlx = organizationList.stream().collect(Collectors.groupingBy(e ->e.get("dxlx").toString())); + //对象类型为人员 + List> personOrganizationList = organizationListGroupBydxlx.get("0"); + //对象类型为人员组织 + List> personGroupOrganizationList = organizationListGroupBydxlx.get("1"); + //对象类型为部门 + List> departmentOrganizationList = organizationListGroupBydxlx.get("2"); + //对象类型为分部 + List> subCompanyOrganizationList = organizationListGroupBydxlx.get("3"); + if (personOrganizationList != null){ + for (Map 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 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 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 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> personGroupData = DbTools.getSqlToList(sql); + Set personnelGroupIds = PersongroupCommonUtil.getPersonnelGroupingByPerson(personGroupData, empId,date, date); + + for (Map 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> 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; + } }