Untitled
Anonymous
plain_text
02/12/2026 5:44 AM
8.1 KB
13
Indexable
public Timesheet computeTimesheet(Timesheet timesheet, Schedule schedule) {
LocalDate workDate = timesheet.getDate();
var earliestScheduleStart = workDate.atTime(schedule.getEarliestStartTime());
var latestScheduledStart = workDate.atTime(Optional.ofNullable(schedule.getLatestStartTime())
.orElse(schedule.getEarliestStartTime()));
var approvedLeave = leaveRequestRepository.findByLeaveAllocation_EmployeeDetail_EmployeeIdentifierAndLeaveDateAndStatus(
UserUtil.getUser().getEmployeeNumber(),
workDate,
FilingStatus.APPROVED
);
if (approvedLeave.isPresent()) {
if (approvedLeave.get().getPartOfDaySchedule().equals(PartOfDaySchedule.AM)) {
earliestScheduleStart = workDate.atTime(schedule.getEarliestStartTimeHalfDayPM());
latestScheduledStart = workDate.atTime(schedule.getLatestStartTimeHalfDayPM());
}
}
//add 1 if earliest is greater than latest in terms of date
latestScheduledStart = earliestScheduleStart.isAfter(latestScheduledStart) ?
latestScheduledStart.plusDays(1) : latestScheduledStart;
var graceTime = latestScheduledStart.plusMinutes(schedule.getGracePeriod());
//Not late if within grace period, but if after grace period, late minutes will be computed from start time
// till time in
if (timesheet.getTimeIn().isAfter(graceTime)) {
timesheet.setMinutesLate((int) Duration.between(latestScheduledStart, timesheet.getTimeIn().withSecond(0))
.toMinutes());
} else {
timesheet.setMinutesLate(0);
}
if (timesheet.getTimeIn() != null && timesheet.getTimeOut() != null) {
var scheduledEndTime = isNightShift(schedule) ? workDate.plusDays(1)
.atTime(schedule.getEarliestEndTime()) : workDate.atTime(schedule.getEarliestEndTime());
var totalScheduledMinutes = Duration.between(earliestScheduleStart, scheduledEndTime).toMinutes();
//get start, set effective start as scheduled start if time in is earlier than scheduled start else the
// actual time in
//to be used for computing work minutes, valid work minutes are minutes within the schedule.
LocalDateTime effectiveStart = timesheet.getTimeIn()
.isBefore(earliestScheduleStart) ? earliestScheduleStart : timesheet.getTimeIn();
//evaluate if schedule ends the next day (eg. night/graveyard shifts)
var nextDayEnd = isNightShift(schedule);
LocalDateTime breakStart = workDate.atTime(schedule.getBreakStartTime()).withSecond(0).withNano(0);
LocalDateTime breakEnd = workDate.atTime(schedule.getBreakEndTime()).withSecond(0).withNano(0);
if (Optional.ofNullable(schedule.getLatestStartTime()).orElse(schedule.getEarliestStartTime())
.isAfter(schedule.getBreakStartTime()) ||
timesheet.getTimeIn().isAfter(breakStart)) {
breakStart = breakStart.plusDays(1);
}
if (nextDayEnd && breakEnd.isBefore(breakStart)) {
breakEnd = breakEnd.plusDays(1);
}
var rawWorkedMinutes = Duration.between(effectiveStart.withSecond(0), timesheet.getTimeOut().withSecond(0))
.toMinutes();
if (approvedLeave.isPresent()) {
if (!approvedLeave.get().getPartOfDaySchedule().equals(PartOfDaySchedule.WHOLE)) {
totalScheduledMinutes = totalScheduledMinutes / 2;
if (approvedLeave.get().getPartOfDaySchedule().equals(PartOfDaySchedule.PM)) {
rawWorkedMinutes = Duration.between(effectiveStart.withSecond(0),
timesheet.getTimeOut().withSecond(0))
.toMinutes();
var halfScheduledEnd =
timesheet.getTimeIn().plusMinutes(totalScheduledMinutes).withSecond(0).withNano(0);
// add break duration if AM Attendance end crosses break start
if (halfScheduledEnd.isAfter(breakStart)) {
totalScheduledMinutes =
totalScheduledMinutes + Duration.between(schedule.getBreakStartTime(),
schedule.getBreakEndTime())
.toMinutes();
}
}
} else {
totalScheduledMinutes = 0;
}
} else {
totalScheduledMinutes = totalScheduledMinutes -
Duration.between(schedule.getBreakStartTime(), schedule.getBreakEndTime()).toMinutes();
//deduct break minutes from total work minutes, if break is within the scheduled start and end
if (timesheet.getTimeIn().isBefore(breakEnd) && timesheet.getTimeOut().isAfter(breakStart)) {
Duration breakOverlap = Duration.between(
timesheet.getTimeIn().isAfter(breakStart) ? timesheet.getTimeIn().withSecond(0) : breakStart,
timesheet.getTimeOut().isBefore(breakEnd) ? timesheet.getTimeOut().withSecond(0) : breakEnd
);
rawWorkedMinutes -= Math.max(0, breakOverlap.toMinutes());
}
}
timesheet.setTotalWorkMinutes((int) rawWorkedMinutes);
if (rawWorkedMinutes < totalScheduledMinutes) {
timesheet.setMinutesUndertime((int) (totalScheduledMinutes - rawWorkedMinutes));
} else {
timesheet.setMinutesUndertime(0);
}
if (schedule.getOvertimeEligible() && rawWorkedMinutes > totalScheduledMinutes) {
timesheet.setMinutesOvertime((int) (rawWorkedMinutes - totalScheduledMinutes));
} else {
timesheet.setMinutesOvertime(0);
}
}
return timesheet;
}Editor is loading...
Leave a Comment