|
|
|
@ -12,6 +12,7 @@ import com.engine.common.util.Utils;
|
|
|
|
|
import com.engine.core.impl.Service;
|
|
|
|
|
import weaver.conn.RecordSet;
|
|
|
|
|
import weaver.general.BaseBean;
|
|
|
|
|
import weaver.general.MathUtil;
|
|
|
|
|
import weaver.general.Util;
|
|
|
|
|
|
|
|
|
|
import java.time.Duration;
|
|
|
|
@ -236,15 +237,19 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
List<String> kqxmIdsWithCq = collectKqxmIdsByCq(map);
|
|
|
|
|
//收集下出勤结果中进出时间,仅收集进出两个时间点都有的数据
|
|
|
|
|
List<Map<String, String>> jcInfoList = collectJcInfoByCq(map);
|
|
|
|
|
//收集下出勤结果中,项目1-8中累积的加班时长,处理成分钟数
|
|
|
|
|
Integer realOvertimeMinutes = collectOvertimeMinutes(map, jbKqxmUnitInfo);
|
|
|
|
|
//出勤日期
|
|
|
|
|
String cqRq = Util.null2String(map.get("rq"));
|
|
|
|
|
// //收集下出勤结果中,项目1-8中累积的加班时长,处理成分钟数
|
|
|
|
|
// Integer realOvertimeMinutes = collectOvertimeMinutes(map, jbKqxmUnitInfo);
|
|
|
|
|
//20240703需求变更,收集加班结果列表中的加班时长
|
|
|
|
|
List<Map<String, String>> realOvertimeInfoList = collectOvertimeInfo(empId, cqRq, jbKqxmUnitInfo);
|
|
|
|
|
int realOvertimeMinutes = realOvertimeInfoList.stream().mapToInt(e->Integer.parseInt(e.get("scMinutes"))).sum();
|
|
|
|
|
bs.writeLog("realOvertimeMinutes : " + realOvertimeMinutes);
|
|
|
|
|
//最终核算分钟数
|
|
|
|
|
double countMinutes = 0;
|
|
|
|
|
//出勤时长
|
|
|
|
|
double cqsc = Util.null2String(map.get("cqsc")).equals("") ? 0 : Double.parseDouble(map.get("cqsc").toString());
|
|
|
|
|
//出勤日期
|
|
|
|
|
String cqRq = Util.null2String(map.get("rq"));
|
|
|
|
|
|
|
|
|
|
//获取班次班段时间范围
|
|
|
|
|
List<Map<String, String>> bcTimeRangeList = collectBcTimeRangeInfo(shiftIdToDetailInfo.get(bc), cqRq);
|
|
|
|
|
//遍历该出勤结果中班次、人员都关联的津贴项目
|
|
|
|
@ -274,8 +279,13 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
String onDutyTime = Util.null2String(allowanceInfo.get("sjd"));
|
|
|
|
|
//判断特定在岗时间点指向日期
|
|
|
|
|
String onDutyDate = getOnDutyDate(shiftIdToStartInfo.get(bc), onDutyTime, cqRq);
|
|
|
|
|
//时间点之前的时长也计入核算量_标识,0-否,1-是
|
|
|
|
|
String includeHoursBeforeDutyTime = Util.null2String(allowanceInfo.get("jljxysjdzqdsc"));
|
|
|
|
|
//20240704需求变更,jljxysjdzqdsc字段为“累计时间点前时长”,ljsjdhdsc字段为“累计时间点后时长”
|
|
|
|
|
// //时间点之前的时长也计入核算量_标识,0-否,1-是
|
|
|
|
|
//// String includeHoursBeforeDutyTime = Util.null2String(allowanceInfo.get("jljxysjdzqdsc"));
|
|
|
|
|
//累计时间点前时长计入核算量_标识,0-否,1-是
|
|
|
|
|
String onlyCountBeforeDutyTime = Util.null2String(allowanceInfo.get("jljxysjdzqdsc"));
|
|
|
|
|
//累计时间点后时长计入核算量_标识,0-否,1-是
|
|
|
|
|
String onlyCountAfterDutyTime = Util.null2String(allowanceInfo.get("ljsjdhdsc"));
|
|
|
|
|
//起算分钟数(不包含)
|
|
|
|
|
String startMinutes = Util.null2String(allowanceInfo.get("jtqsfzs"));
|
|
|
|
|
//最大核算分钟数(包含)
|
|
|
|
@ -283,7 +293,7 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
//超出起算时长的单次累加分钟数
|
|
|
|
|
String oneTimeAddMinutes = Util.null2String(allowanceInfo.get("cchsfzs"));
|
|
|
|
|
bs.writeLog("includeDailyWorkHours : " + includeDailyWorkHours + ",checkOneTimeOnDuty : " + checkOneTimeOnDuty
|
|
|
|
|
+ ",onDutyTime : " + onDutyTime + ",includeHoursBeforeDutyTime : " + includeHoursBeforeDutyTime
|
|
|
|
|
+ ",onDutyTime : " + onDutyTime + ",onlyCountBeforeDutyTime : " + onlyCountBeforeDutyTime + ",onlyCountAfterDutyTime : " + onlyCountAfterDutyTime
|
|
|
|
|
+ ",startMinutes : " + startMinutes,"maxMinutes : " + maxMinutes + ",oneTimeAddMinutes : " + oneTimeAddMinutes);
|
|
|
|
|
//逐一判断是否满足津贴时长计入规则
|
|
|
|
|
//1-此为考勤项目的多选,如果员工当天出勤中的项目1~项目8存在不核算此津贴的项目,则员工不能获得此津贴
|
|
|
|
@ -313,20 +323,21 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
//a-时长默认为取当天所有项目1~项目8中的各加班类型的考勤项目对应的时长
|
|
|
|
|
//b-如果勾选“工作时长也计入核算量”,则还需要累加当天的“出勤时长”字段值
|
|
|
|
|
//c-一旦勾选了“检查特定时间点是否在岗”,且只取“时间点”之后的分钟数时长
|
|
|
|
|
//d-如果勾选了“时间点之前的时长也计入核算量”则上一点不需要做
|
|
|
|
|
|
|
|
|
|
if (includeHoursBeforeDutyTime.equals("1")) {
|
|
|
|
|
//d-如果“累计时间点前时长”和“累计时间点后时长”同时勾选
|
|
|
|
|
if ("1".equals(onlyCountBeforeDutyTime) && "1".equals(onlyCountAfterDutyTime)) {
|
|
|
|
|
countMinutes = overtimeMinutes;
|
|
|
|
|
if (includeDailyWorkHours.equals("1")) {
|
|
|
|
|
if ("1".equals(includeDailyWorkHours)) {
|
|
|
|
|
countMinutes = countMinutes + cqsc * 60;
|
|
|
|
|
}
|
|
|
|
|
} else if(!"1".equals(onlyCountBeforeDutyTime) && !"1".equals(onlyCountAfterDutyTime)) {
|
|
|
|
|
countMinutes = 0;
|
|
|
|
|
} else {
|
|
|
|
|
countMinutes = getMinutesWithAfterPointTime(cqRq, bcTimeRangeList, jcInfoList, overtimeMinutes, onDutyTimeWithDate, includeDailyWorkHours);
|
|
|
|
|
countMinutes = getMinutesWithAfterPointTime(onlyCountBeforeDutyTime, onlyCountAfterDutyTime, bcTimeRangeList, jcInfoList,realOvertimeInfoList, onDutyTimeWithDate, includeDailyWorkHours);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//未勾选“检查特定时间点是否在岗”
|
|
|
|
|
countMinutes = overtimeMinutes;
|
|
|
|
|
if (includeDailyWorkHours.equals("1")) {
|
|
|
|
|
if ("1".equals(includeDailyWorkHours)) {
|
|
|
|
|
countMinutes = countMinutes + cqsc * 60;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -336,7 +347,7 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
double allowanceMinutes = 0;
|
|
|
|
|
bs.writeLog("countMinutes : " + countMinutes);
|
|
|
|
|
if (countMinutes > Double.parseDouble(startMinutes)) {
|
|
|
|
|
if (!oneTimeAddMinutes.equals("") && !oneTimeAddMinutes.equals("0")) {
|
|
|
|
|
if (!"".equals(oneTimeAddMinutes) && !"0".equals(oneTimeAddMinutes)) {
|
|
|
|
|
double multiple = (countMinutes - Double.parseDouble(startMinutes)) / Double.parseDouble(oneTimeAddMinutes);
|
|
|
|
|
allowanceMinutes = Double.parseDouble(startMinutes) + Double.parseDouble(oneTimeAddMinutes) * Math.floor(multiple);
|
|
|
|
|
} else {
|
|
|
|
@ -381,6 +392,49 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
}
|
|
|
|
|
return allowanceInfoList;
|
|
|
|
|
}
|
|
|
|
|
//收集加班结果列表中的加班时长信息列表
|
|
|
|
|
private List<Map<String, String>> collectOvertimeInfo(String empId, String cqRq, Map<String, String> jbKqxmUnitInfo) {
|
|
|
|
|
List<Map<String, String>> overtimeInfo = new ArrayList<>();
|
|
|
|
|
String sql = "select * from uf_jcl_kq_jbjg where zt = 1 and jbry = " + empId + " and (jbgzrq = '" + cqRq + "' or sjksrq = '" + cqRq + "')";
|
|
|
|
|
List<Map<String, Object>> data = DbTools.getSqlToList(sql);
|
|
|
|
|
data = data.stream().
|
|
|
|
|
filter(f -> Util.null2String(f.get("jbgzrq")).equals(cqRq)
|
|
|
|
|
|| ("".equals(Util.null2String(f.get("jbgzrq"))) && Util.null2String(f.get("sjksrq")).equals(cqRq)))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
Map<String, String> overtimeInfoItem;
|
|
|
|
|
Map<String, Integer> unitToMinutes = new HashMap<>();
|
|
|
|
|
unitToMinutes.put(AccountingUnitEnum.DAY.getKey(), 1440);
|
|
|
|
|
unitToMinutes.put(AccountingUnitEnum.HOUR.getKey(), 60);
|
|
|
|
|
unitToMinutes.put(AccountingUnitEnum.MINUTES.getKey(), 1);
|
|
|
|
|
unitToMinutes.put(AccountingUnitEnum.ONCE.getKey(), 0);
|
|
|
|
|
String unit;
|
|
|
|
|
int minutes;
|
|
|
|
|
|
|
|
|
|
for (Map<String, Object> item : data) {
|
|
|
|
|
String startDate = Util.null2String(item.get("sjksrq"));
|
|
|
|
|
String endDate = Util.null2String(item.get("sjjsrq"));
|
|
|
|
|
String startTime = Util.null2String(item.get("sjkssj"));
|
|
|
|
|
String endTime = Util.null2String(item.get("sjjssj"));
|
|
|
|
|
String kqxmId = Util.null2String(item.get("jblx"));
|
|
|
|
|
String scStr = Util.null2String(item.get("sjjbsc"));
|
|
|
|
|
double sc = "".equals(scStr) ? 0 : Double.parseDouble(scStr);
|
|
|
|
|
if (!"".equals(startDate) && !"".equals(endDate) && !"".equals(startTime) && !"".equals(endTime) && !"".equals(kqxmId) && sc > 0) {
|
|
|
|
|
overtimeInfoItem = new HashMap<>();
|
|
|
|
|
overtimeInfoItem.put("startTime", startDate + " " + startTime);
|
|
|
|
|
overtimeInfoItem.put("endTime", endDate + " " + endTime);
|
|
|
|
|
unit = Util.null2String(jbKqxmUnitInfo.get(kqxmId));
|
|
|
|
|
minutes = 0;
|
|
|
|
|
if (!"".equals(unit)) {
|
|
|
|
|
minutes = (int) (sc * unitToMinutes.get(unit));
|
|
|
|
|
}
|
|
|
|
|
overtimeInfoItem.put("scMinutes", String.valueOf(minutes));
|
|
|
|
|
overtimeInfo.add(overtimeInfoItem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return overtimeInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Map<String, String> collectShiftIdToStartInfo() {
|
|
|
|
|
Map<String, String> shiftIdToStartInfo = new HashMap<>();
|
|
|
|
@ -436,13 +490,15 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
* 获取考虑特殊在岗时间点情况下的考核时长分钟数
|
|
|
|
|
* 勾选在岗时间点时,
|
|
|
|
|
* 1-处于班次工作时间段时,结合进出时间和班次班段判断班段时间内实际工作分钟数
|
|
|
|
|
* 2-处于加班时间段内,结合进出时间记录,累加
|
|
|
|
|
* @param overtimeMinutes
|
|
|
|
|
* 2-处于加班时间段内,结合加班结果中的进出时间记录,累加
|
|
|
|
|
*
|
|
|
|
|
* @param onlyCountBeforeDutyTime
|
|
|
|
|
* @param onlyCountAfterDutyTime
|
|
|
|
|
* @param onDutyTimeWithDate
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private double getMinutesWithAfterPointTime(String cqRq, List<Map<String, String>> bcTimeRangeList, List<Map<String, String>> jcInfoList,
|
|
|
|
|
Integer overtimeMinutes, String onDutyTimeWithDate, String includeDailyWorkHours) {
|
|
|
|
|
private double getMinutesWithAfterPointTime(String onlyCountBeforeDutyTime, String onlyCountAfterDutyTime, List<Map<String, String>> bcTimeRangeList, List<Map<String, String>> jcInfoList,
|
|
|
|
|
List<Map<String, String>> realOvertimeInfoList, String onDutyTimeWithDate, String includeDailyWorkHours) {
|
|
|
|
|
double bcOnDutyMinutes = 0;
|
|
|
|
|
double realOverWorkMinutes = 0;
|
|
|
|
|
if (includeDailyWorkHours.equals("1")) {
|
|
|
|
@ -483,26 +539,49 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//遍历获取班次班段时间内的累计时长(某一在岗时间点之后的时间)
|
|
|
|
|
for (Map<String, String> bcRealTimeInfo : bcRealOnDutyTimeRange) {
|
|
|
|
|
if (onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("startTime")) <= 0) {
|
|
|
|
|
bcOnDutyMinutes = bcOnDutyMinutes + getMinutesByTwo(bcRealTimeInfo.get("startTime"), bcRealTimeInfo.get("endTime"));
|
|
|
|
|
} else if (onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("startTime")) >= 0 && onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("endTime")) <= 0) {
|
|
|
|
|
bcOnDutyMinutes = bcOnDutyMinutes + getMinutesByTwo(onDutyTimeWithDate, bcRealTimeInfo.get("endTime"));
|
|
|
|
|
if ("1".equals(onlyCountBeforeDutyTime)) {
|
|
|
|
|
//遍历获取班次班段时间内的累计时长(某一在岗时间点之前的时间)
|
|
|
|
|
for (Map<String, String> bcRealTimeInfo : bcRealOnDutyTimeRange) {
|
|
|
|
|
if (onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("endTime")) >= 0) {
|
|
|
|
|
bcOnDutyMinutes = bcOnDutyMinutes + getMinutesByTwo(bcRealTimeInfo.get("startTime"), bcRealTimeInfo.get("endTime"));
|
|
|
|
|
} else if (onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("startTime")) >= 0 && onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("endTime")) <= 0) {
|
|
|
|
|
bcOnDutyMinutes = bcOnDutyMinutes + getMinutesByTwo(bcRealTimeInfo.get("startTime"), onDutyTimeWithDate);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if ("1".equals(onlyCountAfterDutyTime)) {
|
|
|
|
|
//遍历获取班次班段时间内的累计时长(某一在岗时间点之后的时间)
|
|
|
|
|
for (Map<String, String> bcRealTimeInfo : bcRealOnDutyTimeRange) {
|
|
|
|
|
if (onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("startTime")) <= 0) {
|
|
|
|
|
bcOnDutyMinutes = bcOnDutyMinutes + getMinutesByTwo(bcRealTimeInfo.get("startTime"), bcRealTimeInfo.get("endTime"));
|
|
|
|
|
} else if (onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("startTime")) >= 0 && onDutyTimeWithDate.compareTo(bcRealTimeInfo.get("endTime")) <= 0) {
|
|
|
|
|
bcOnDutyMinutes = bcOnDutyMinutes + getMinutesByTwo(onDutyTimeWithDate, bcRealTimeInfo.get("endTime"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//判断在岗时间点和加班时间区间的关系,即进出打卡记录是否与在岗时间点有包含关系,分情况累计时间
|
|
|
|
|
for (Map<String, String> jcInfo : jcInfoList) {
|
|
|
|
|
if (onDutyTimeWithDate.compareTo(jcInfo.get("signIn")) <= 0) {
|
|
|
|
|
realOverWorkMinutes = realOverWorkMinutes + getMinutesByTwo(jcInfo.get("signIn"), jcInfo.get("signOut"));
|
|
|
|
|
} else if (onDutyTimeWithDate.compareTo(jcInfo.get("signIn")) >= 0 && onDutyTimeWithDate.compareTo(jcInfo.get("signOut")) <= 0) {
|
|
|
|
|
realOverWorkMinutes = realOverWorkMinutes + getMinutesByTwo(onDutyTimeWithDate, jcInfo.get("signOut"));
|
|
|
|
|
|
|
|
|
|
if ("1".equals(onlyCountBeforeDutyTime)) {
|
|
|
|
|
//判断在岗时间点和加班时间区间的关系,即加班结果表中的进出记录是否与在岗时间点有包含关系,分情况累计某一在岗时间点之前的时间
|
|
|
|
|
for (Map<String, String> jcInfo : realOvertimeInfoList) {
|
|
|
|
|
String scStr = Util.null2String(jcInfo.get("scMinutes"));
|
|
|
|
|
int scMinutes = Integer.parseInt(scStr);
|
|
|
|
|
if (onDutyTimeWithDate.compareTo(jcInfo.get("endTime")) >= 0) {
|
|
|
|
|
realOverWorkMinutes = realOverWorkMinutes + scMinutes;
|
|
|
|
|
} else if (onDutyTimeWithDate.compareTo(jcInfo.get("startTime")) >= 0 && onDutyTimeWithDate.compareTo(jcInfo.get("endTime")) <= 0) {
|
|
|
|
|
realOverWorkMinutes = realOverWorkMinutes + Math.min(getMinutesByTwo(jcInfo.get("startTime"), onDutyTimeWithDate), scMinutes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if ("1".equals(onlyCountAfterDutyTime)) {
|
|
|
|
|
//判断在岗时间点和加班时间区间的关系,即加班结果表中的进出记录是否与在岗时间点有包含关系,分情况累计某一在岗时间点之后的时间
|
|
|
|
|
for (Map<String, String> jcInfo : realOvertimeInfoList) {
|
|
|
|
|
String scStr = Util.null2String(jcInfo.get("scMinutes"));
|
|
|
|
|
int scMinutes = Integer.parseInt(scStr);
|
|
|
|
|
if (onDutyTimeWithDate.compareTo(jcInfo.get("startTime")) <= 0) {
|
|
|
|
|
realOverWorkMinutes = realOverWorkMinutes + scMinutes;
|
|
|
|
|
} else if (onDutyTimeWithDate.compareTo(jcInfo.get("startTime")) >= 0 && onDutyTimeWithDate.compareTo(jcInfo.get("endTime")) <= 0) {
|
|
|
|
|
realOverWorkMinutes = realOverWorkMinutes + Math.min(getMinutesByTwo(onDutyTimeWithDate, jcInfo.get("endTime")), scMinutes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//实际加班时长累计的核算分钟数,不可以超过项目1-8累计的加班时长分钟数
|
|
|
|
|
if (realOverWorkMinutes > overtimeMinutes) {
|
|
|
|
|
realOverWorkMinutes = overtimeMinutes;
|
|
|
|
|
}
|
|
|
|
|
return realOverWorkMinutes + bcOnDutyMinutes;
|
|
|
|
|
}
|
|
|
|
@ -603,6 +682,7 @@ public class AllowanceServiceImpl extends Service implements AllowanceService {
|
|
|
|
|
return unitInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//收集下出勤结果中,项目1-8中累积的加班时长,处理成分钟数
|
|
|
|
|
private Integer collectOvertimeMinutes(Map<String, Object> cqMap, Map<String, String> jbKqxmUnitInfo) {
|
|
|
|
|
double minutes = 0;
|
|
|
|
|
String xm = "";
|
|
|
|
|