/** * 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 java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.fenixedu.academic.domain.Enrolment; import org.fenixedu.academic.domain.curricularRules.EnrolmentInSpecialSeasonEvaluation; import org.fenixedu.academic.domain.curricularRules.ICurricularRule; import org.fenixedu.academic.domain.curricularRules.MaximumNumberOfECTSInSpecialSeasonEvaluation; import org.fenixedu.academic.domain.curricularRules.SeniorStatuteSpecialSeasonEnrolmentScope; import org.fenixedu.academic.domain.curricularRules.executors.ruleExecutors.CurricularRuleLevel; import org.fenixedu.academic.domain.curricularRules.executors.ruleExecutors.EnrolmentResultType; import org.fenixedu.academic.domain.enrolment.EnroledCurriculumModuleWrapper; import org.fenixedu.academic.domain.enrolment.EnrolmentContext; import org.fenixedu.academic.domain.enrolment.IDegreeModuleToEvaluate; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.domain.student.Registration; import org.fenixedu.academic.domain.student.SeniorStatute; import org.fenixedu.academic.domain.student.Student; import org.fenixedu.academic.domain.student.StudentStatute; import org.fenixedu.academic.domain.student.registrationStates.RegistrationStateType; import org.fenixedu.academic.domain.studentCurriculum.StudentCurricularPlanEnrolmentPreConditions.EnrolmentPreConditionResult; public class StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager extends StudentCurricularPlanEnrolment { public StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager(final EnrolmentContext enrolmentContext) { super(enrolmentContext); } @Override protected void assertEnrolmentPreConditions() { if (!getRegistration().hasStateType(getExecutionYear(), RegistrationStateType.REGISTERED)) { throw new DomainException("error.StudentCurricularPlan.cannot.enrol.with.registration.inactive"); } super.assertEnrolmentPreConditions(); } @Override protected void checkDebts() { if (getStudent().isAnyGratuityOrAdministrativeOfficeFeeAndInsuranceInDebt(getExecutionYear())) { throw new DomainException("error.StudentCurricularPlan.cannot.enrol.with.debts.for.previous.execution.years"); } } @Override protected void assertAcademicAdminOfficePreConditions() { checkEnrolmentWithoutRules(); if (updateRegistrationAfterConclusionProcessPermissionEvaluated()) { return; } } @Override protected void assertStudentEnrolmentPreConditions() { if (!getRegistrationsToEnrolByStudent(getResponsiblePerson().getStudent()).contains(getRegistration())) { throw new DomainException("error.StudentCurricularPlan.student.is.not.allowed.to.perform.enrol"); } if (!hasSpecialSeasonStatute()) { throw new DomainException("error.StudentCurricularPlan.student.has.no.special.season.statute"); } if (getCurricularRuleLevel() != CurricularRuleLevel.SPECIAL_SEASON_ENROLMENT) { throw new DomainException("error.StudentCurricularPlan.invalid.curricular.rule.level"); } final EnrolmentPreConditionResult result = StudentCurricularPlanEnrolmentPreConditions.checkEnrolmentPeriodsForSpecialSeason(getStudentCurricularPlan(), getExecutionSemester()); if (!result.isValid()) { throw new DomainException(result.message(), result.args()); } } private Collection<Registration> getRegistrationsToEnrolByStudent(final Student student) { final Collection<Registration> registrations = new HashSet<Registration>(); for (final Registration registration : student.getRegistrationsSet()) { if (isRegistrationEnrolmentByStudentAllowed(registration)) { if (registration.isActive() || isRegistrationAvailableToEnrol(registration)) { registrations.add(registration); } } } return registrations; } public boolean isRegistrationEnrolmentByStudentAllowed(final Registration registration) { return registration.getRegistrationProtocol().isEnrolmentByStudentAllowed(); } private boolean isRegistrationAvailableToEnrol(final Registration registration) { return registration.hasAnyEnrolmentsIn(getExecutionYear()) && registration.getLastStudentCurricularPlan().hasExternalCycleCurriculumGroups(); } @Override protected void unEnrol() { for (final CurriculumModule curriculumModule : enrolmentContext.getToRemove()) { if (curriculumModule instanceof Enrolment) { final Enrolment enrolment = (Enrolment) curriculumModule; enrolment.deleteSpecialSeasonEvaluation(); } else { throw new DomainException( "StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager.can.only.manage.enrolment.evaluations.of.enrolments"); } } } @Override protected void addEnroled() { for (final Enrolment enrolment : getStudentCurricularPlan().getSpecialSeasonEnrolments(getExecutionYear())) { enrolmentContext.addDegreeModuleToEvaluate(new EnroledCurriculumModuleWrapper(enrolment, getExecutionSemester())); } } @Override protected Map<IDegreeModuleToEvaluate, Set<ICurricularRule>> getRulesToEvaluate() { final Map<IDegreeModuleToEvaluate, Set<ICurricularRule>> result = new HashMap<IDegreeModuleToEvaluate, Set<ICurricularRule>>(); for (final IDegreeModuleToEvaluate degreeModuleToEvaluate : enrolmentContext.getDegreeModulesToEvaluate()) { if (degreeModuleToEvaluate.isEnroled() && degreeModuleToEvaluate.canCollectRules()) { final EnroledCurriculumModuleWrapper moduleEnroledWrapper = (EnroledCurriculumModuleWrapper) degreeModuleToEvaluate; if (moduleEnroledWrapper.getCurriculumModule() instanceof Enrolment) { final Enrolment enrolment = (Enrolment) moduleEnroledWrapper.getCurriculumModule(); final Set<ICurricularRule> curricularRules = new HashSet<ICurricularRule>(); if (!enrolment.hasSpecialSeason()) { curricularRules.add(new EnrolmentInSpecialSeasonEvaluation(enrolment)); } curricularRules.add(new MaximumNumberOfECTSInSpecialSeasonEvaluation()); if (isEnrolingAsSenior(enrolment)) { curricularRules.add(new SeniorStatuteSpecialSeasonEnrolmentScope(enrolment, getRegistrationFromSeniorStatute(enrolment))); } result.put(degreeModuleToEvaluate, curricularRules); } else { throw new DomainException( "StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager.can.only.manage.enrolment.evaluations.of.enrolments"); } } } return result; } @Override protected void performEnrolments(final Map<EnrolmentResultType, List<IDegreeModuleToEvaluate>> degreeModulesToEvaluate) { for (final Entry<EnrolmentResultType, List<IDegreeModuleToEvaluate>> entry : degreeModulesToEvaluate.entrySet()) { for (final IDegreeModuleToEvaluate degreeModuleToEvaluate : entry.getValue()) { if (degreeModuleToEvaluate.isEnroled()) { final EnroledCurriculumModuleWrapper moduleEnroledWrapper = (EnroledCurriculumModuleWrapper) degreeModuleToEvaluate; if (moduleEnroledWrapper.getCurriculumModule() instanceof Enrolment) { final Enrolment enrolment = (Enrolment) moduleEnroledWrapper.getCurriculumModule(); if (!enrolment.hasSpecialSeason()) { enrolment.createSpecialSeasonEvaluation(getResponsiblePerson()); } } else { throw new DomainException( "StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager.can.only.manage.enrolment.evaluations.of.enrolments"); } } } } } private boolean hasSpecialSeasonStatute() { Collection<StudentStatute> statutes = getResponsiblePerson().getStudent().getStudentStatutesSet(); for (StudentStatute statute : statutes) { if (!statute.getType().isSpecialSeasonGranted() && !statute.hasSeniorStatuteForRegistration(getRegistration())) { continue; } if (!statute.isValidInExecutionPeriod(getExecutionSemester())) { continue; } return true; } return false; } private boolean isEnrolingAsSenior(Enrolment enrolment) { if (isResponsiblePersonAllowedToEnrolStudents()) { return false; } List<StudentStatute> statutesReader = new ArrayList<StudentStatute>(enrolment.getStudent().getStudentStatutesSet()); List<StudentStatute> validSeniorStatutes = new ArrayList<StudentStatute>(); List<StudentStatute> validOtherStatutes = new ArrayList<StudentStatute>(); for (StudentStatute statute : statutesReader) { if (statute instanceof SeniorStatute && statute.isValidInExecutionPeriod(getExecutionSemester())) { validSeniorStatutes.add(statute); } else if (statute.getType().isSpecialSeasonGranted() && statute.isValidInExecutionPeriod(getExecutionSemester())) { validOtherStatutes.add(statute); } } if (validOtherStatutes.size() > 0) { return false; } if (validSeniorStatutes.size() == 1 && validOtherStatutes.size() == 0) { return true; } else { throw new DomainException( "StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager.inconsistent.student.statutes.states"); } } private Registration getRegistrationFromSeniorStatute(Enrolment enrolment) { List<StudentStatute> statutesReader = new ArrayList<StudentStatute>(enrolment.getStudent().getStudentStatutesSet()); List<StudentStatute> statutesWriter = new ArrayList<StudentStatute>(); for (StudentStatute statute : statutesReader) { if (statute instanceof SeniorStatute && statute.isValidInExecutionPeriod(getExecutionSemester())) { statutesWriter.add(statute); } } if (statutesWriter.size() == 1) { SeniorStatute senior = (SeniorStatute) statutesWriter.iterator().next(); return senior.getRegistration(); } else { throw new DomainException( "StudentCurricularPlanEnrolmentInSpecialSeasonEvaluationManager.student.has.more.than.one.senior.statute.for.same.period"); } } }