package org.synyx.urlaubsverwaltung.web.account; import org.joda.time.DateMidnight; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.synyx.urlaubsverwaltung.core.settings.AbsenceSettings; import org.synyx.urlaubsverwaltung.core.settings.Settings; import org.synyx.urlaubsverwaltung.core.settings.SettingsService; import java.math.BigDecimal; /** * Validates {@link AccountForm}. * * @author Aljona Murygina - murygina@synyx.de */ @Component class AccountValidator implements Validator { private static final String ERROR_MANDATORY_FIELD = "error.entry.mandatory"; private static final String ERROR_ENTRY = "error.entry.invalid"; private static final String ERROR_PERIOD = "error.entry.invalidPeriod"; private static final String ERROR_COMMENT_TO_LONG = "error.entry.commentTooLong"; private static final String ATTRIBUTE_ANNUAL_VACATION_DAYS = "annualVacationDays"; private static final String ATTRIBUTE_ACTUAL_VACATION_DAYS = "actualVacationDays"; private static final String ATTRIBUTE_REMAINING_VACATION_DAYS = "remainingVacationDays"; private static final String ATTRIBUTE_REMAINING_VACATION_DAYS_NOT_EXPIRING = "remainingVacationDaysNotExpiring"; private static final String ATTRIBUTE_COMMENT = "comment"; private final SettingsService settingsService; @Autowired AccountValidator(SettingsService settingsService) { this.settingsService = settingsService; } @Override public boolean supports(Class<?> clazz) { return AccountForm.class.equals(clazz); } @Override public void validate(Object target, Errors errors) { AccountForm form = (AccountForm) target; validatePeriod(form, errors); validateAnnualVacation(form, errors); validateActualVacation(form, errors); validateRemainingVacationDays(form, errors); validateComment(form, errors); } void validateComment(AccountForm form, Errors errors) { String comment = form.getComment(); if (comment != null && comment.length() > 200) { errors.rejectValue(ATTRIBUTE_COMMENT, ERROR_COMMENT_TO_LONG); } } void validatePeriod(AccountForm form, Errors errors) { DateMidnight holidaysAccountValidFrom = form.getHolidaysAccountValidFrom(); DateMidnight holidaysAccountValidTo = form.getHolidaysAccountValidTo(); validateDateNotNull(holidaysAccountValidFrom, "holidaysAccountValidFrom", errors); validateDateNotNull(holidaysAccountValidTo, "holidaysAccountValidTo", errors); if (holidaysAccountValidFrom != null && holidaysAccountValidTo != null) { boolean periodIsNotWithinOneYear = holidaysAccountValidFrom.getYear() != form.getHolidaysAccountYear() || holidaysAccountValidTo.getYear() != form.getHolidaysAccountYear(); boolean periodIsOnlyOneDay = holidaysAccountValidFrom.equals(holidaysAccountValidTo); boolean beginOfPeriodIsAfterEndOfPeriod = holidaysAccountValidFrom.isAfter(holidaysAccountValidTo); if (periodIsNotWithinOneYear || periodIsOnlyOneDay || beginOfPeriodIsAfterEndOfPeriod) { errors.reject(ERROR_PERIOD); } } } private void validateDateNotNull(DateMidnight date, String field, Errors errors) { // may be that date field is null because of cast exception, than there is already a field error if (date == null && errors.getFieldErrors(field).isEmpty()) { errors.rejectValue(field, ERROR_MANDATORY_FIELD); } } void validateAnnualVacation(AccountForm form, Errors errors) { BigDecimal annualVacationDays = form.getAnnualVacationDays(); Settings settings = settingsService.getSettings(); AbsenceSettings absenceSettings = settings.getAbsenceSettings(); BigDecimal maxDays = BigDecimal.valueOf(absenceSettings.getMaximumAnnualVacationDays()); validateNumberNotNull(annualVacationDays, ATTRIBUTE_ANNUAL_VACATION_DAYS, errors); if (annualVacationDays != null) { validateNumberOfDays(annualVacationDays, ATTRIBUTE_ANNUAL_VACATION_DAYS, maxDays, errors); } } private void validateNumberNotNull(BigDecimal number, String field, Errors errors) { // may be that number field is null because of cast exception, than there is already a field error if (number == null && errors.getFieldErrors(field).isEmpty()) { errors.rejectValue(field, ERROR_MANDATORY_FIELD); } } private void validateNumberOfDays(BigDecimal days, String field, BigDecimal maximumDays, Errors errors) { // is number of days < 0 ? if (days.compareTo(BigDecimal.ZERO) < 0) { errors.rejectValue(field, ERROR_ENTRY); } // is number of days unrealistic? if (days.compareTo(maximumDays) > 0) { errors.rejectValue(field, ERROR_ENTRY); } } void validateActualVacation(AccountForm form, Errors errors) { BigDecimal actualVacationDays = form.getActualVacationDays(); validateNumberNotNull(actualVacationDays, ATTRIBUTE_ACTUAL_VACATION_DAYS, errors); if (actualVacationDays != null) { BigDecimal annualVacationDays = form.getAnnualVacationDays(); validateNumberOfDays(actualVacationDays, ATTRIBUTE_ACTUAL_VACATION_DAYS, annualVacationDays, errors); } } void validateRemainingVacationDays(AccountForm form, Errors errors) { Settings settings = settingsService.getSettings(); AbsenceSettings absenceSettings = settings.getAbsenceSettings(); BigDecimal maxDays = BigDecimal.valueOf(absenceSettings.getMaximumAnnualVacationDays()); BigDecimal remainingVacationDays = form.getRemainingVacationDays(); BigDecimal remainingVacationDaysNotExpiring = form.getRemainingVacationDaysNotExpiring(); validateNumberNotNull(remainingVacationDays, ATTRIBUTE_REMAINING_VACATION_DAYS, errors); validateNumberNotNull(remainingVacationDaysNotExpiring, ATTRIBUTE_REMAINING_VACATION_DAYS_NOT_EXPIRING, errors); if (remainingVacationDays != null) { // field entitlement's remaining vacation days validateNumberOfDays(remainingVacationDays, ATTRIBUTE_REMAINING_VACATION_DAYS, maxDays, errors); if (remainingVacationDaysNotExpiring != null) { validateNumberOfDays(remainingVacationDaysNotExpiring, ATTRIBUTE_REMAINING_VACATION_DAYS_NOT_EXPIRING, remainingVacationDays, errors); } } } }