/** * Copyright © 2002 Instituto Superior Técnico * * This file is part of FenixEdu Academic. * * FenixEdu Academic is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Academic is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.academic.domain.studentCurriculum; import static org.fenixedu.academic.domain.studentCurriculum.StudentCurricularPlanEnrolmentPreConditions.EnrolmentPreConditionResult.createFalse; import static org.fenixedu.academic.domain.studentCurriculum.StudentCurricularPlanEnrolmentPreConditions.EnrolmentPreConditionResult.createTrue; import org.fenixedu.academic.domain.EnrolmentPeriod; import org.fenixedu.academic.domain.ExecutionSemester; import org.fenixedu.academic.domain.StudentCurricularPlan; import org.fenixedu.academic.domain.student.Registration; import org.fenixedu.academic.domain.student.registrationStates.RegistrationState; import org.fenixedu.academic.domain.student.registrationStates.RegistrationStateType; public class StudentCurricularPlanEnrolmentPreConditions { static public class EnrolmentPreConditionResult { private boolean valid = false; private String message; private String[] args; private EnrolmentPeriod period; private EnrolmentPreConditionResult valid(final boolean value) { this.valid = value; return this; } public boolean isValid() { return valid; } private EnrolmentPreConditionResult message(final String message, final String... args) { this.message = message; this.args = args; return this; } private EnrolmentPreConditionResult withPeriod(EnrolmentPeriod period) { this.period = period; return this; } public String message() { return this.message; } public String[] args() { return this.args; } public EnrolmentPeriod getEnrolmentPeriod() { return period; } static public EnrolmentPreConditionResult createTrue() { return new EnrolmentPreConditionResult().valid(true); } static public EnrolmentPreConditionResult createFalse(final String message, final String... args) { return new EnrolmentPreConditionResult().valid(false).message(message, args); } } /* * Change? If next period is not defined then we should use last? Or previous of given semester? */ static private EnrolmentPreConditionResult outOfPeriodResult(final String periodType, final EnrolmentPeriod nextPeriod) { if (nextPeriod != null) { return createFalse("message.out.curricular.course.enrolment.period." + periodType, nextPeriod.getStartDateDateTime().toString("dd/MM/yyyy"), nextPeriod.getEndDateDateTime().toString("dd/MM/yyyy")).withPeriod(nextPeriod); } else { return createFalse("message.out.curricular.course.enrolment.period." + periodType + ".noDates"); } } static public EnrolmentPreConditionResult checkPreConditionsToEnrol(StudentCurricularPlan scp, ExecutionSemester semester) { final EnrolmentPreConditionResult result = checkEnrolmentPeriods(scp, semester); if (!result.isValid()) { return result; } return checkDebts(scp); } /** * * Check if student has any debts that prevent him to enrol in curricular * courses * * @param scp * @return EnrolmentPreConditionResult */ static EnrolmentPreConditionResult checkDebts(StudentCurricularPlan scp) { if (scp.getRegistration().getStudent().isAnyGratuityOrAdministrativeOfficeFeeAndInsuranceInDebt()) { return createFalse("error.StudentCurricularPlan.cannot.enrol.with.debts.for.previous.execution.years"); } if (scp.getPerson().hasAnyResidencePaymentsInDebtForPreviousYear()) { return createFalse("error.StudentCurricularPlan.cannot.enrol.with.residence.debts"); } return createTrue(); } static private boolean hasSpecialSeason(final StudentCurricularPlan scp, final ExecutionSemester semester) { if (scp.hasSpecialSeasonFor(semester)) { return true; } final Registration registration = scp.getRegistration(); return registration.getSourceRegistration() != null && registration.getSourceRegistration().getLastStudentCurricularPlan().hasSpecialSeasonFor(semester); } /** * Check student enrolment periods * * @param scp * @param semester * @return EnrolmentPreConditionResult */ static EnrolmentPreConditionResult checkEnrolmentPeriods(StudentCurricularPlan scp, ExecutionSemester semester) { if (semester.isFirstOfYear() && hasSpecialSeason(scp, semester)) { if (!scp.getDegreeCurricularPlan().getActiveEnrolmentPeriodInCurricularCoursesSpecialSeason(semester).isPresent()) { return outOfPeriodResult("specialSeason", scp.getDegreeCurricularPlan() .getNextEnrolmentPeriodInCurricularCoursesSpecialSeason()); } } else if (semester.isFirstOfYear() && hasPrescribed(scp, semester)) { if (!scp.getDegreeCurricularPlan().getActiveEnrolmentPeriodInCurricularCoursesFlunkedSeason(semester).isPresent()) { return outOfPeriodResult("flunked", scp.getDegreeCurricularPlan() .getNextEnrolmentPeriodInCurricularCoursesFlunkedSeason()); } } else if (!scp.getDegreeCurricularPlan().getActiveCurricularCourseEnrolmentPeriod(semester).isPresent()) { return outOfPeriodResult("normal", scp.getDegreeCurricularPlan().getNextEnrolmentPeriod()); } return createTrue(); } static EnrolmentPreConditionResult checkEnrolmentPeriodsForSpecialSeason(StudentCurricularPlan scp, ExecutionSemester semester) { if (!scp.getDegreeCurricularPlan().hasOpenSpecialSeasonEnrolmentPeriod(semester)) { return outOfPeriodResult("specialSeason", scp.getDegreeCurricularPlan() .getNextEnrolmentPeriodInCurricularCoursesSpecialSeason()); } return createTrue(); } /* * Student must have flunked state and then registered (in same year), otherwise is not considered to be prescribed */ private static boolean hasPrescribed(StudentCurricularPlan scp, ExecutionSemester semester) { for (RegistrationState state : scp.getRegistration().getRegistrationStates(semester.getExecutionYear())) { if (state.getExecutionYear().equals(semester.getExecutionYear()) && RegistrationStateType.FLUNKED.equals(state.getStateType())) { return scp.getRegistration().hasRegisteredActiveState(); } } return false; } }