package org.synyx.urlaubsverwaltung.web.overview; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import org.joda.time.DateMidnight; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.synyx.urlaubsverwaltung.core.account.domain.Account; import org.synyx.urlaubsverwaltung.core.account.service.AccountService; import org.synyx.urlaubsverwaltung.core.account.service.VacationDaysService; 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.overtime.OvertimeService; import org.synyx.urlaubsverwaltung.core.person.Person; import org.synyx.urlaubsverwaltung.core.person.PersonService; import org.synyx.urlaubsverwaltung.core.settings.SettingsService; 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.core.workingtime.WorkDaysService; import org.synyx.urlaubsverwaltung.security.SessionService; import org.synyx.urlaubsverwaltung.web.ControllerConstants; import org.synyx.urlaubsverwaltung.web.application.ApplicationForLeave; import org.synyx.urlaubsverwaltung.web.person.PersonConstants; import org.synyx.urlaubsverwaltung.web.person.UnknownPersonException; import org.synyx.urlaubsverwaltung.web.sicknote.ExtendedSickNote; import org.synyx.urlaubsverwaltung.web.statistics.SickDaysOverview; import org.synyx.urlaubsverwaltung.web.statistics.UsedDaysOverview; import java.util.List; import java.util.Optional; /** * Controller to display the personal overview page with basic information about overtime, applications for leave and * sick notes. * * @author Aljona Murygina - murygina@synyx.de */ @Controller @RequestMapping("/web") public class OverviewController { @Autowired private PersonService personService; @Autowired private AccountService accountService; @Autowired private VacationDaysService vacationDaysService; @Autowired private SessionService sessionService; @Autowired private ApplicationService applicationService; @Autowired private WorkDaysService calendarService; @Autowired private SickNoteService sickNoteService; @Autowired private OvertimeService overtimeService; @Autowired private SettingsService settingsService; @RequestMapping(value = "/overview", method = RequestMethod.GET) public String showOverview( @RequestParam(value = ControllerConstants.YEAR_ATTRIBUTE, required = false) String year) { Person user = sessionService.getSignedInUser(); if (StringUtils.hasText(year)) { return "redirect:/web/staff/" + user.getId() + "/overview?year=" + year; } return "redirect:/web/staff/" + user.getId() + "/overview"; } @RequestMapping(value = "/staff/{personId}/overview", method = RequestMethod.GET) public String showOverview(@PathVariable("personId") Integer personId, @RequestParam(value = ControllerConstants.YEAR_ATTRIBUTE, required = false) Integer year, Model model) throws UnknownPersonException, AccessDeniedException { Person person = personService.getPersonByID(personId).orElseThrow(() -> new UnknownPersonException(personId)); Person signedInUser = sessionService.getSignedInUser(); if (!sessionService.isSignedInUserAllowedToAccessPersonData(signedInUser, person)) { throw new AccessDeniedException(String.format( "User '%s' has not the correct permissions to access the overview page of user '%s'", signedInUser.getLoginName(), person.getLoginName())); } model.addAttribute(PersonConstants.PERSON_ATTRIBUTE, person); Integer yearToShow = year == null ? DateMidnight.now().getYear() : year; prepareApplications(person, yearToShow, model); prepareHolidayAccounts(person, yearToShow, model); prepareSickNoteList(person, yearToShow, model); prepareSettings(model); model.addAttribute(ControllerConstants.YEAR_ATTRIBUTE, DateMidnight.now().getYear()); return "person/overview"; } private void prepareSickNoteList(Person person, int year, Model model) { List<SickNote> sickNotes = sickNoteService.getByPersonAndPeriod(person, DateUtil.getFirstDayOfYear(year), DateUtil.getLastDayOfYear(year)); List<ExtendedSickNote> extendedSickNotes = FluentIterable.from(sickNotes).transform(input -> new ExtendedSickNote(input, calendarService)).toSortedList((o1, o2) -> { // show latest sick notes at first return o2.getStartDate().compareTo(o1.getStartDate()); }); model.addAttribute("sickNotes", extendedSickNotes); SickDaysOverview sickDaysOverview = new SickDaysOverview(sickNotes, calendarService); model.addAttribute("sickDaysOverview", sickDaysOverview); } private void prepareApplications(Person person, int year, Model model) { // get the person's applications for the given year List<Application> applications = FluentIterable.from( applicationService.getApplicationsForACertainPeriodAndPerson(DateUtil.getFirstDayOfYear(year), DateUtil.getLastDayOfYear(year), person)) .filter(input -> !input.hasStatus(ApplicationStatus.REVOKED)) .toList(); if (!applications.isEmpty()) { ImmutableList<ApplicationForLeave> applicationsForLeave = FluentIterable.from(applications) .transform(input -> new ApplicationForLeave(input, calendarService)) .toSortedList((o1, o2) -> { // show latest applications at first return o2.getStartDate().compareTo(o1.getStartDate()); }); model.addAttribute("applications", applicationsForLeave); UsedDaysOverview usedDaysOverview = new UsedDaysOverview(applications, year, calendarService); model.addAttribute("usedDaysOverview", usedDaysOverview); } model.addAttribute("overtimeTotal", overtimeService.getTotalOvertimeForPersonAndYear(person, year)); model.addAttribute("overtimeLeft", overtimeService.getLeftOvertimeForPerson(person)); } private void prepareHolidayAccounts(Person person, int year, Model model) { // get person's holidays account and entitlement for the given year Optional<Account> account = accountService.getHolidaysAccount(year, person); if (account.isPresent()) { model.addAttribute("vacationDaysLeft", vacationDaysService.getVacationDaysLeft(account.get())); model.addAttribute("account", account.get()); model.addAttribute(PersonConstants.BEFORE_APRIL_ATTRIBUTE, DateUtil.isBeforeApril(DateMidnight.now())); } } private void prepareSettings(Model model) { model.addAttribute("settings", settingsService.getSettings()); } }