feat(wms): 添加倒班跨天考勤记录处理功能
- 新增 isBackwardCrossDay 方法判断倒班跨天情况 - 修改 sliceRecordsForDay 方法支持 backward 参数 - 更新 buildCheck 方法传递 crossDay 参数 - 实现倒班跨天情况下调整考勤时间窗口逻辑 - 优化跨天班次的时间范围计算规则
This commit is contained in:
@@ -130,11 +130,12 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService
|
|||||||
List<WmsAttendanceCheck> checksToInsert = new ArrayList<>(toProcess.size());
|
List<WmsAttendanceCheck> checksToInsert = new ArrayList<>(toProcess.size());
|
||||||
for (WmsAttendanceScheduleVo schedule : toProcess) {
|
for (WmsAttendanceScheduleVo schedule : toProcess) {
|
||||||
boolean crossDay = isCrossDayShift(schedule);
|
boolean crossDay = isCrossDayShift(schedule);
|
||||||
|
boolean backward = isBackwardCrossDay(schedule);
|
||||||
List<AttendanceRecords> records = sliceRecordsForDay(
|
List<AttendanceRecords> records = sliceRecordsForDay(
|
||||||
recordsByEmployee.get(schedule.getEmployeeName()),
|
recordsByEmployee.get(schedule.getEmployeeName()),
|
||||||
schedule.getWorkDate(),
|
schedule.getWorkDate(),
|
||||||
crossDay);
|
crossDay, backward);
|
||||||
checksToInsert.add(buildCheck(schedule, rule, records));
|
checksToInsert.add(buildCheck(schedule, rule, records, crossDay));
|
||||||
}
|
}
|
||||||
|
|
||||||
baseMapper.insertBatch(checksToInsert, BATCH_SIZE);
|
baseMapper.insertBatch(checksToInsert, BATCH_SIZE);
|
||||||
@@ -146,6 +147,12 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService
|
|||||||
return schedule.getShiftIsCrossDay() != null && schedule.getShiftIsCrossDay() == 1;
|
return schedule.getShiftIsCrossDay() != null && schedule.getShiftIsCrossDay() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBackwardCrossDay(WmsAttendanceScheduleVo schedule) {
|
||||||
|
if (!isCrossDayShift(schedule)) return false;
|
||||||
|
if (schedule.getShiftStartTime() == null || schedule.getShiftEndTime() == null) return false;
|
||||||
|
return toLocalTime(schedule.getShiftStartTime()).getHour() >= 16;
|
||||||
|
}
|
||||||
|
|
||||||
private WmsAttendanceRule getActiveRule() {
|
private WmsAttendanceRule getActiveRule() {
|
||||||
LambdaQueryWrapper<WmsAttendanceRule> wrapper = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<WmsAttendanceRule> wrapper = Wrappers.lambdaQuery();
|
||||||
wrapper.eq(WmsAttendanceRule::getDelFlag, 0);
|
wrapper.eq(WmsAttendanceRule::getDelFlag, 0);
|
||||||
@@ -207,13 +214,13 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService
|
|||||||
/**
|
/**
|
||||||
* 与原先 {@code getRecords(ename, workDate, crossDay)} 的时间窗口一致。
|
* 与原先 {@code getRecords(ename, workDate, crossDay)} 的时间窗口一致。
|
||||||
*/
|
*/
|
||||||
private List<AttendanceRecords> sliceRecordsForDay(List<AttendanceRecords> prefetched, Date workDate, boolean crossDay) {
|
private List<AttendanceRecords> sliceRecordsForDay(List<AttendanceRecords> prefetched, Date workDate, boolean crossDay, boolean backward) {
|
||||||
if (prefetched == null || prefetched.isEmpty()) {
|
if (prefetched == null || prefetched.isEmpty()) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
LocalDate ld = toLocalDate(workDate);
|
LocalDate ld = toLocalDate(workDate);
|
||||||
LocalDateTime rangeStart = ld.atStartOfDay();
|
LocalDateTime rangeStart = ld.atStartOfDay();
|
||||||
LocalDateTime rangeEnd = crossDay
|
LocalDateTime rangeEnd = crossDay && !backward
|
||||||
? ld.plusDays(1).atTime(LocalTime.of(23, 59, 59))
|
? ld.plusDays(1).atTime(LocalTime.of(23, 59, 59))
|
||||||
: ld.atTime(LocalTime.of(23, 59, 59));
|
: ld.atTime(LocalTime.of(23, 59, 59));
|
||||||
return prefetched.stream()
|
return prefetched.stream()
|
||||||
@@ -238,7 +245,7 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private WmsAttendanceCheck buildCheck(WmsAttendanceScheduleVo schedule, WmsAttendanceRule rule,
|
private WmsAttendanceCheck buildCheck(WmsAttendanceScheduleVo schedule, WmsAttendanceRule rule,
|
||||||
List<AttendanceRecords> records) {
|
List<AttendanceRecords> records, boolean crossDay) {
|
||||||
WmsAttendanceCheck check = new WmsAttendanceCheck();
|
WmsAttendanceCheck check = new WmsAttendanceCheck();
|
||||||
check.setScheduleId(schedule.getScheduleId());
|
check.setScheduleId(schedule.getScheduleId());
|
||||||
check.setUserId(schedule.getUserId());
|
check.setUserId(schedule.getUserId());
|
||||||
@@ -249,7 +256,6 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService
|
|||||||
check.setShiftType(schedule.getShiftType());
|
check.setShiftType(schedule.getShiftType());
|
||||||
|
|
||||||
boolean hasPeriod2 = schedule.getShiftStartTime2() != null && schedule.getShiftEndTime2() != null;
|
boolean hasPeriod2 = schedule.getShiftStartTime2() != null && schedule.getShiftEndTime2() != null;
|
||||||
boolean crossDay = isCrossDayShift(schedule);
|
|
||||||
|
|
||||||
if (records.isEmpty()) {
|
if (records.isEmpty()) {
|
||||||
check.setOverallStatus("absent_full");
|
check.setOverallStatus("absent_full");
|
||||||
@@ -303,7 +309,12 @@ public class WmsAttendanceCheckServiceImpl implements IWmsAttendanceCheckService
|
|||||||
LocalDateTime windowStart;
|
LocalDateTime windowStart;
|
||||||
LocalDateTime windowEnd;
|
LocalDateTime windowEnd;
|
||||||
|
|
||||||
if (crossDay) {
|
boolean backward = st != null && et != null && st.getHour() >= 16 && crossDay;
|
||||||
|
|
||||||
|
if (crossDay && backward) {
|
||||||
|
windowStart = LocalDateTime.of(ld, et).minusHours(2);
|
||||||
|
windowEnd = LocalDateTime.of(ld, et).plusHours(2);
|
||||||
|
} else if (crossDay) {
|
||||||
windowStart = LocalDateTime.of(ld, st).minusHours(2);
|
windowStart = LocalDateTime.of(ld, st).minusHours(2);
|
||||||
windowEnd = LocalDateTime.of(ld.plusDays(1), et).plusHours(2);
|
windowEnd = LocalDateTime.of(ld.plusDays(1), et).plusHours(2);
|
||||||
} else if (st != null && et != null) {
|
} else if (st != null && et != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user