package org.synyx.urlaubsverwaltung.web.statistics; import org.joda.time.DateMidnight; import org.springframework.util.Assert; import org.synyx.urlaubsverwaltung.core.application.domain.Application; import org.synyx.urlaubsverwaltung.core.application.domain.ApplicationStatus; import org.synyx.urlaubsverwaltung.core.application.domain.VacationCategory; import org.synyx.urlaubsverwaltung.core.period.DayLength; import org.synyx.urlaubsverwaltung.core.person.Person; import org.synyx.urlaubsverwaltung.core.util.DateUtil; import org.synyx.urlaubsverwaltung.core.workingtime.WorkDaysService; import java.math.BigDecimal; import java.util.List; /** * Object to abstract how many days have been used in a year. * * @author Aljona Murygina - murygina@synyx.de */ public class UsedDaysOverview { private final int year; // used days for vacation type HOLIDAY private final UsedDays holidayDays; // used days for all the other vacation types except HOLIDAY private final UsedDays otherDays; public UsedDaysOverview(List<Application> applications, int year, WorkDaysService calendarService) { this.year = year; this.holidayDays = new UsedDays(ApplicationStatus.WAITING, ApplicationStatus.ALLOWED, ApplicationStatus.TEMPORARY_ALLOWED); this.otherDays = new UsedDays(ApplicationStatus.WAITING, ApplicationStatus.ALLOWED, ApplicationStatus.TEMPORARY_ALLOWED); for (Application application : applications) { ApplicationStatus status = application.getStatus(); if (application.hasStatus(ApplicationStatus.WAITING) || application.hasStatus(ApplicationStatus.ALLOWED) || application.hasStatus(ApplicationStatus.TEMPORARY_ALLOWED)) { BigDecimal days = getVacationDays(application, calendarService); if (application.getVacationType().isOfCategory(VacationCategory.HOLIDAY)) { this.holidayDays.addDays(status, days); } else { this.otherDays.addDays(status, days); } } } } public UsedDays getHolidayDays() { return holidayDays; } public UsedDays getOtherDays() { return otherDays; } private BigDecimal getVacationDays(Application application, WorkDaysService calendarService) { int yearOfStartDate = application.getStartDate().getYear(); int yearOfEndDate = application.getEndDate().getYear(); Assert.isTrue(yearOfStartDate == this.year || yearOfEndDate == this.year, "Either start date or end date must be in the given year."); DayLength dayLength = application.getDayLength(); Person person = application.getPerson(); if (yearOfStartDate != yearOfEndDate) { DateMidnight startDate = getStartDateForCalculation(application); DateMidnight endDate = getEndDateForCalculation(application); return calendarService.getWorkDays(dayLength, startDate, endDate, person); } return calendarService.getWorkDays(dayLength, application.getStartDate(), application.getEndDate(), person); } private DateMidnight getStartDateForCalculation(Application application) { if (application.getStartDate().getYear() != this.year) { return DateUtil.getFirstDayOfYear(application.getEndDate().getYear()); } return application.getStartDate(); } private DateMidnight getEndDateForCalculation(Application application) { if (application.getEndDate().getYear() != this.year) { return DateUtil.getLastDayOfYear(application.getStartDate().getYear()); } return application.getEndDate(); } }