package org.synyx.urlaubsverwaltung.restapi.availability;
import org.joda.time.DateMidnight;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.synyx.urlaubsverwaltung.core.period.DayLength;
import org.synyx.urlaubsverwaltung.core.person.Person;
import org.synyx.urlaubsverwaltung.core.workingtime.WorkingTime;
import org.synyx.urlaubsverwaltung.core.workingtime.WorkingTimeService;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
/**
* @author Timo Eifler - eifler@synyx.de
*/
@Service
class FreeTimeAbsenceProvider extends AbstractTimedAbsenceProvider {
private final WorkingTimeService workingTimeService;
@Autowired
FreeTimeAbsenceProvider(HolidayAbsenceProvider nextPriorityProvider, WorkingTimeService workingTimeService) {
super(nextPriorityProvider);
this.workingTimeService = workingTimeService;
}
@Override
TimedAbsenceSpans addAbsence(TimedAbsenceSpans knownAbsences, Person person, DateMidnight date) {
Optional<TimedAbsence> freeTimeAbsence = checkForFreeTime(date, person);
if (freeTimeAbsence.isPresent()) {
List<TimedAbsence> knownAbsencesList = knownAbsences.getAbsencesList();
knownAbsencesList.add(freeTimeAbsence.get());
return new TimedAbsenceSpans(knownAbsencesList);
}
return knownAbsences;
}
@Override
boolean isLastPriorityProvider() {
return false;
}
private Optional<TimedAbsence> checkForFreeTime(DateMidnight currentDay, Person person) {
DayLength expectedWorktime = getExpectedWorktimeFor(person, currentDay);
BigDecimal expectedWorktimeDuration = expectedWorktime.getDuration();
boolean expectedWorktimeIsLessThanFullDay = expectedWorktimeDuration.compareTo(BigDecimal.ONE) < 0;
if (expectedWorktimeIsLessThanFullDay) {
return Optional.of(new TimedAbsence(expectedWorktime.getInverse(), TimedAbsence.Type.FREETIME));
}
return Optional.empty();
}
private DayLength getExpectedWorktimeFor(Person person, DateMidnight currentDay) {
Optional<WorkingTime> workingTimeOrNot = workingTimeService.getByPersonAndValidityDateEqualsOrMinorDate(person,
currentDay);
if (!workingTimeOrNot.isPresent()) {
throw new IllegalStateException("Person " + person + " does not have workingTime configured");
}
WorkingTime workingTime = workingTimeOrNot.get();
DayLength dayLengthForWeekDay = workingTime.getDayLengthForWeekDay(currentDay.getDayOfWeek());
return dayLengthForWeekDay;
}
}