package org.synyx.urlaubsverwaltung.restapi.absence;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import org.joda.time.DateMidnight;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.synyx.urlaubsverwaltung.core.application.domain.Application;
import org.synyx.urlaubsverwaltung.core.application.domain.ApplicationStatus;
import org.synyx.urlaubsverwaltung.core.application.service.ApplicationService;
import org.synyx.urlaubsverwaltung.core.person.Person;
import org.synyx.urlaubsverwaltung.core.person.PersonService;
import org.synyx.urlaubsverwaltung.core.sicknote.SickNote;
import org.synyx.urlaubsverwaltung.core.sicknote.SickNoteService;
import org.synyx.urlaubsverwaltung.core.util.DateUtil;
import org.synyx.urlaubsverwaltung.restapi.ResponseWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author Aljona Murygina - murygina@synyx.de
*/
@Api(value = "Absences", description = "Get all absences for a certain period")
@RestController("restApiAbsenceController")
@RequestMapping("/api")
public class AbsenceController {
private final PersonService personService;
private final ApplicationService applicationService;
private final SickNoteService sickNoteService;
@Autowired
AbsenceController(PersonService personService, ApplicationService applicationService,
SickNoteService sickNoteService) {
this.personService = personService;
this.applicationService = applicationService;
this.sickNoteService = sickNoteService;
}
@ApiOperation(
value = "Get all absences for a certain period and person",
notes = "Get all absences for a certain period and person"
)
@RequestMapping(value = "/absences", method = RequestMethod.GET)
public ResponseWrapper<DayAbsenceList> personsVacations(
@ApiParam(value = "Year to get the absences for", defaultValue = "2016")
@RequestParam("year")
String year,
@ApiParam(value = "Month of year to get the absences for")
@RequestParam(value = "month", required = false)
String month,
@ApiParam(value = "ID of the person")
@RequestParam("person")
Integer personId,
@ApiParam(value = "Type of absences, vacation or sick notes", allowableValues = "VACATION, SICK_NOTE")
@RequestParam(value = "type", required = false)
String type) {
Optional<Person> optionalPerson = personService.getPersonByID(personId);
if (!optionalPerson.isPresent()) {
throw new IllegalArgumentException("No person found for ID=" + personId);
}
List<DayAbsence> absences = new ArrayList<>();
Person person = optionalPerson.get();
DateMidnight startDate = getStartDate(year, Optional.ofNullable(month));
DateMidnight endDate = getEndDate(year, Optional.ofNullable(month));
if (type == null || DayAbsence.Type.valueOf(type).equals(DayAbsence.Type.VACATION)) {
absences.addAll(getVacations(startDate, endDate, person));
}
if (type == null || DayAbsence.Type.valueOf(type).equals(DayAbsence.Type.SICK_NOTE)) {
absences.addAll(getSickNotes(startDate, endDate, person));
}
return new ResponseWrapper<>(new DayAbsenceList(absences));
}
private static DateMidnight getStartDate(String year, Optional<String> optionalMonth) {
if (optionalMonth.isPresent()) {
return DateUtil.getFirstDayOfMonth(Integer.parseInt(year), Integer.parseInt(optionalMonth.get()));
}
return DateUtil.getFirstDayOfYear(Integer.parseInt(year));
}
private static DateMidnight getEndDate(String year, Optional<String> optionalMonth) {
if (optionalMonth.isPresent()) {
return DateUtil.getLastDayOfMonth(Integer.parseInt(year), Integer.parseInt(optionalMonth.get()));
}
return DateUtil.getLastDayOfYear(Integer.parseInt(year));
}
private List<DayAbsence> getVacations(DateMidnight start, DateMidnight end, Person person) {
List<DayAbsence> absences = new ArrayList<>();
List<Application> applications = applicationService.getApplicationsForACertainPeriodAndPerson(start, end,
person)
.stream()
.filter(application ->
application.hasStatus(ApplicationStatus.WAITING)
|| application.hasStatus(ApplicationStatus.TEMPORARY_ALLOWED)
|| application.hasStatus(ApplicationStatus.ALLOWED))
.collect(Collectors.toList());
for (Application application : applications) {
DateMidnight startDate = application.getStartDate();
DateMidnight endDate = application.getEndDate();
DateMidnight day = startDate;
while (!day.isAfter(endDate)) {
if (!day.isBefore(start) && !day.isAfter(end)) {
absences.add(new DayAbsence(day, application.getDayLength(), DayAbsence.Type.VACATION,
application.getStatus().name(), application.getId()));
}
day = day.plusDays(1);
}
}
return absences;
}
private List<DayAbsence> getSickNotes(DateMidnight start, DateMidnight end, Person person) {
List<DayAbsence> absences = new ArrayList<>();
List<SickNote> sickNotes = sickNoteService.getByPersonAndPeriod(person, start, end)
.stream()
.filter(SickNote::isActive)
.collect(Collectors.toList());
for (SickNote sickNote : sickNotes) {
DateMidnight startDate = sickNote.getStartDate();
DateMidnight endDate = sickNote.getEndDate();
DateMidnight day = startDate;
while (!day.isAfter(endDate)) {
if (!day.isBefore(start) && !day.isAfter(end)) {
absences.add(new DayAbsence(day, sickNote.getDayLength(), DayAbsence.Type.SICK_NOTE, "ACTIVE",
sickNote.getId()));
}
day = day.plusDays(1);
}
}
return absences;
}
}