/** * 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.candidacyProcess.mobility; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.fenixedu.academic.domain.CurricularCourse; import org.fenixedu.academic.domain.Degree; import org.fenixedu.academic.domain.DegreeCurricularPlan; import org.fenixedu.academic.domain.ExecutionSemester; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.StudentCurricularPlan; import org.fenixedu.academic.domain.candidacy.IngressionType; import org.fenixedu.academic.domain.candidacyProcess.IndividualCandidacyProcess; import org.fenixedu.academic.domain.candidacyProcess.IndividualCandidacyProcessBean; import org.fenixedu.academic.domain.candidacyProcess.erasmus.ApprovedLearningAgreementDocumentFile; import org.fenixedu.academic.domain.candidacyProcess.erasmus.NationalIdCardAvoidanceQuestion; import org.fenixedu.academic.domain.curricularRules.executors.ruleExecutors.CurricularRuleLevel; import org.fenixedu.academic.domain.degreeStructure.Context; import org.fenixedu.academic.domain.degreeStructure.CycleType; import org.fenixedu.academic.domain.enrolment.DegreeModuleToEnrol; import org.fenixedu.academic.domain.enrolment.IDegreeModuleToEvaluate; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.domain.student.PersonalIngressionData; import org.fenixedu.academic.domain.student.PrecedentDegreeInformation; import org.fenixedu.academic.domain.student.Registration; import org.fenixedu.academic.domain.studentCurriculum.CurriculumGroup; import org.fenixedu.academic.domain.studentCurriculum.NoCourseGroupCurriculumGroup; import org.fenixedu.academic.domain.studentCurriculum.NoCourseGroupCurriculumGroupType; import org.joda.time.DateTime; import org.joda.time.LocalDate; public class MobilityIndividualApplication extends MobilityIndividualApplication_Base { public MobilityIndividualApplication() { super(); } MobilityIndividualApplication(final MobilityIndividualApplicationProcess process, final MobilityIndividualApplicationProcessBean bean) { this(); Person person = init(bean, process); createEramusStudentData(bean); associateCurricularCourses(bean.getSelectedCurricularCourses()); } private void associateCurricularCourses(Set<CurricularCourse> selectedCurricularCourses) { for (CurricularCourse curricularCourse : selectedCurricularCourses) { addCurricularCourses(curricularCourse); } } private void createEramusStudentData(MobilityIndividualApplicationProcessBean bean) { setMobilityStudentData(new MobilityStudentData(this, bean.getMobilityStudentDataBean(), bean.determineMobilityQuota())); } @Override protected void createDebt(final Person person) { } @Override protected void checkParameters(final Person person, final IndividualCandidacyProcess process, final IndividualCandidacyProcessBean bean) { MobilityIndividualApplicationProcess erasmusIndividualCandidacyProcess = (MobilityIndividualApplicationProcess) process; MobilityIndividualApplicationProcessBean secondCandidacyProcessBean = (MobilityIndividualApplicationProcessBean) bean; LocalDate candidacyDate = bean.getCandidacyDate(); checkParameters(person, erasmusIndividualCandidacyProcess, candidacyDate, null); } private void checkParameters(final Person person, final MobilityIndividualApplicationProcess process, final LocalDate candidacyDate, Object dummy) { checkParameters(person, process, candidacyDate); /* * 31/03/2009 - The candidacy may be submited externally hence may not * be associated to a person * * * if(person.hasValidSecondCycleIndividualCandidacy(process. * getCandidacyExecutionInterval())) { throw newDomainException( * "error.SecondCycleIndividualCandidacy.person.already.has.candidacy", * process .getCandidacyExecutionInterval().getName()); } */ } void editDegreeAndCoursesInformation(MobilityIndividualApplicationProcessBean bean) { Set<CurricularCourse> setOne = new HashSet<CurricularCourse>(this.getCurricularCoursesSet()); setOne.addAll(bean.getSelectedCurricularCourses()); getMobilityStudentData().setSelectedOpening(bean.determineMobilityQuota()); for (CurricularCourse curricularCourse : setOne) { if (getCurricularCoursesSet().contains(curricularCourse) && !bean.getSelectedCurricularCourses().contains(curricularCourse)) { removeCurricularCourses(curricularCourse); } else if (!getCurricularCoursesSet().contains(curricularCourse) && bean.getSelectedCurricularCourses().contains(curricularCourse)) { addCurricularCourses(curricularCourse); } } } public Degree getSelectedDegree() { return getMobilityStudentData().getSelectedOpening().getDegree(); } protected boolean hasSelectedDegree() { return getSelectedDegree() != null; } @Override public Collection<Degree> getAllDegrees() { List<Degree> result = new ArrayList<Degree>(); result.add(getSelectedDegree()); return result; } @Override public String getDescription() { return getCandidacyProcess().getDisplayName() + (hasSelectedDegree() ? ": " + getSelectedDegree().getNameI18N() : ""); } @Override public MobilityIndividualApplicationProcess getCandidacyProcess() { return (MobilityIndividualApplicationProcess) super.getCandidacyProcess(); } public ApprovedLearningAgreementDocumentFile getMostRecentApprovedLearningAgreement() { if (!hasAnyActiveApprovedLearningAgreements()) { return null; } List<ApprovedLearningAgreementDocumentFile> approvedLearningAgreement = new ArrayList<ApprovedLearningAgreementDocumentFile>(getActiveApprovedLearningAgreements()); Collections.sort(approvedLearningAgreement, Collections.reverseOrder(ApprovedLearningAgreementDocumentFile.SUBMISSION_DATE_COMPARATOR)); return approvedLearningAgreement.iterator().next(); } public boolean isMostRecentApprovedLearningAgreementNotViewed() { if (!hasAnyActiveApprovedLearningAgreements()) { return false; } return !getMostRecentApprovedLearningAgreement().isApprovedLearningAgreementViewed(); } boolean hasProcessWithAcceptNotification() { return hasProcessWithAcceptNotificationAtDate(new DateTime()); } boolean hasProcessWithAcceptNotificationAtDate(final DateTime dateTime) { return getMostRecentApprovedLearningAgreement() == null || (getMostRecentApprovedLearningAgreement().getMostRecentSentEmailAcceptedStudentAction() != null && getMostRecentApprovedLearningAgreement() .getMostRecentSentEmailAcceptedStudentAction().getWhenOccured().isBefore(dateTime)); } public List<ApprovedLearningAgreementDocumentFile> getActiveApprovedLearningAgreements() { List<ApprovedLearningAgreementDocumentFile> activeDocuments = new ArrayList<ApprovedLearningAgreementDocumentFile>(); CollectionUtils.select(getApprovedLearningAgreementsSet(), new Predicate() { @Override public boolean evaluate(Object arg0) { ApprovedLearningAgreementDocumentFile document = (ApprovedLearningAgreementDocumentFile) arg0; return document.getCandidacyFileActive(); } }, activeDocuments); return activeDocuments; } public boolean hasAnyActiveApprovedLearningAgreements() { return !getActiveApprovedLearningAgreements().isEmpty(); } @Override public Registration createRegistration(final DegreeCurricularPlan degreeCurricularPlan, final CycleType cycleType, final IngressionType ingressionType) { if (getRegistration() != null) { throw new DomainException("error.IndividualCandidacy.person.with.registration", degreeCurricularPlan.getPresentationName()); } if (hasActiveRegistration(degreeCurricularPlan)) { final Registration registration = getStudent().getActiveRegistrationFor(degreeCurricularPlan); setRegistration(registration); ExecutionYear currentYear = ExecutionYear.readCurrentExecutionYear(); PersonalIngressionData pid = getStudent().getPersonalIngressionDataByExecutionYear(currentYear); pid.setCountryOfResidence(getPersonalDetails().getCountryOfResidence()); PrecedentDegreeInformation pdi = registration.getPrecedentDegreeInformation(currentYear); pdi.setSchoolLevel(getMobilityStudentData().getSchoolLevel()); pdi.setOtherSchoolLevel(getMobilityStudentData().getOtherSchoolLevel()); return registration; } getPersonalDetails().ensurePersonInternalization(); return createRegistration(getPersonalDetails().getPerson(), degreeCurricularPlan, cycleType, ingressionType); } @Override protected Registration createRegistration(final Person person, final DegreeCurricularPlan degreeCurricularPlan, final CycleType cycleType, final IngressionType ingressionType) { final Registration registration = new Registration(person, degreeCurricularPlan, getMobilityProgram().getRegistrationProtocol(), cycleType, ((ExecutionYear) getCandidacyExecutionInterval())); // Standalone group will be necessary for minor subjects NoCourseGroupCurriculumGroup.create(NoCourseGroupCurriculumGroupType.STANDALONE, registration .getActiveStudentCurricularPlan().getRoot()); registration.editStartDates(getStartDate(), registration.getHomologationDate(), registration.getStudiesStartDate()); setRegistration(registration); createRaidesInformation(registration); PersonalIngressionData pid = getStudent().getPersonalIngressionDataByExecutionYear(registration.getStartExecutionYear()); pid.setCountryOfResidence(getPersonalDetails().getCountryOfResidence()); PrecedentDegreeInformation pdi = registration.getPrecedentDegreeInformation(registration.getStartExecutionYear()); pdi.setSchoolLevel(getMobilityStudentData().getSchoolLevel()); pdi.setOtherSchoolLevel(getMobilityStudentData().getOtherSchoolLevel()); return registration; } void enrol() { final Registration registration = getRegistration(); final ExecutionYear executionYear = (ExecutionYear) getCandidacyExecutionInterval(); final ExecutionSemester semesterToEnrol = executionYear.getFirstExecutionPeriod(); Set<IDegreeModuleToEvaluate> degreeModulesToEnrol = new HashSet<IDegreeModuleToEvaluate>(); degreeModulesToEnrol.addAll(getModulesToEnrolForFirstSemester()); registration.getActiveStudentCurricularPlan().enrol(semesterToEnrol, degreeModulesToEnrol, Collections.EMPTY_LIST, CurricularRuleLevel.ENROLMENT_NO_RULES); } public Collection<DegreeModuleToEnrol> getModulesToEnrolForFirstSemester() { final Registration registration = getRegistration(); final ExecutionYear executionYear = (ExecutionYear) getCandidacyExecutionInterval(); final ExecutionSemester semesterToEnrol = executionYear.getFirstExecutionPeriod(); final StudentCurricularPlan studentCurricularPlan = registration.getActiveStudentCurricularPlan(); final DegreeCurricularPlan degreeCurricularPlan = registration.getLastDegreeCurricularPlan(); Set<DegreeModuleToEnrol> degreeModulesToEnrol = new HashSet<DegreeModuleToEnrol>(); for (CurricularCourse selectedCurricularCourse : getCurricularCoursesSet()) { List<Context> contextList = selectedCurricularCourse.getParentContextsByExecutionSemester(semesterToEnrol); if (contextList.isEmpty()) { continue; } Context selectedContext = contextList.iterator().next(); // WTF?.. /facepalm CurriculumGroup curriculumGroup = null; if (selectedCurricularCourse.getDegreeCurricularPlan().equals(degreeCurricularPlan)) { curriculumGroup = studentCurricularPlan.getRoot().findCurriculumGroupFor(selectedContext.getParentCourseGroup()); } else { // Enrol on standalone curriculum group curriculumGroup = studentCurricularPlan.getStandaloneCurriculumGroup(); } if (curriculumGroup == null) { continue; } DegreeModuleToEnrol toEnrol = new DegreeModuleToEnrol(curriculumGroup, selectedContext, semesterToEnrol); degreeModulesToEnrol.add(toEnrol); } return degreeModulesToEnrol; } public void answerNationalIdCardAvoidanceOnSubmission(MobilityIndividualApplicationProcessBean bean) { NationalIdCardAvoidanceQuestion question = bean.getNationalIdCardAvoidanceQuestion(); this.setNationalIdCardAvoidanceQuestion(question); this.setNationalIdCardAvoidanceAnswerDate(new DateTime()); this.setIdCardAvoidanceOtherReason(bean.getIdCardAvoidanceOtherReason()); } @Override public boolean isErasmus() { return true; } public MobilityProgram getMobilityProgram() { MobilityQuota selectedOpening = getMobilityStudentData().getSelectedOpening(); return selectedOpening.getMobilityAgreement().getMobilityProgram(); } }