/** * 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.math.BigDecimal; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.stream.Stream; import org.fenixedu.academic.domain.CurricularCourse; import org.fenixedu.academic.domain.CurricularCourseEquivalence; import org.fenixedu.academic.domain.DomainObjectUtil; import org.fenixedu.academic.domain.Enrolment; import org.fenixedu.academic.domain.ExecutionSemester; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.StudentCurricularPlan; import org.fenixedu.academic.domain.degreeStructure.DegreeModule; import org.fenixedu.academic.domain.enrolment.IDegreeModuleToEvaluate; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.util.EnrolmentAction; import org.fenixedu.academic.util.MultiLanguageString; import org.fenixedu.academic.util.predicates.ResultCollection; import org.fenixedu.bennu.core.security.Authenticate; import org.joda.time.YearMonthDay; abstract public class CurriculumLine extends CurriculumLine_Base { static final public Comparator<CurriculumLine> COMPARATOR_BY_APPROVEMENT_DATE_AND_ID = new Comparator<CurriculumLine>() { @Override public int compare(CurriculumLine o1, CurriculumLine o2) { int result = (o1.getApprovementDate() != null && o2.getApprovementDate() != null) ? o1.getApprovementDate().compareTo( o2.getApprovementDate()) : 0; return result == 0 ? DomainObjectUtil.COMPARATOR_BY_ID.compare(o1, o2) : result; } }; public CurriculumLine() { super(); setCreatedBy(getCurrentUser()); setUsedInSeparationCycle(false); } final public ExecutionYear getExecutionYear() { final ExecutionSemester executionSemester = getExecutionPeriod(); return executionSemester == null ? null : executionSemester.getExecutionYear(); } public YearMonthDay getApprovementDate() { return isApproved() ? calculateConclusionDate() : null; } @Override final public boolean isLeaf() { return true; } @Override final public boolean isRoot() { return false; } @Override public boolean isApproved(CurricularCourse curricularCourse, ExecutionSemester executionSemester) { return false; } @Override public boolean isEnroledInExecutionPeriod(CurricularCourse curricularCourse, ExecutionSemester executionSemester) { return false; } @Override public boolean isPropaedeutic() { return getCurriculumGroup().isPropaedeutic(); } public boolean isExtraCurricular() { return getCurriculumGroup().isExtraCurriculum(); } public boolean isOptional() { return false; } public boolean isStandalone() { return getCurriculumGroup().isStandalone(); } final protected void validateDegreeModuleLink(CurriculumGroup curriculumGroup, CurricularCourse curricularCourse) { if (!curriculumGroup.getDegreeModule().validate(curricularCourse)) { throw new DomainException("error.studentCurriculum.curriculumLine.invalid.curriculum.group"); } } @Override public List<Enrolment> getEnrolments() { return Collections.emptyList(); } @Override public boolean hasAnyEnrolments() { return false; } @Override final public void addApprovedCurriculumLines(final Collection<CurriculumLine> result) { if (isApproved()) { result.add(this); } } @Override final public boolean hasAnyApprovedCurriculumLines() { return isApproved(); } @Override public void collectDismissals(final List<Dismissal> result) { // nothing to do } @Override public StudentCurricularPlan getStudentCurricularPlan() { return getCurriculumGroup() != null ? getCurriculumGroup().getStudentCurricularPlan() : null; } @Override public boolean hasEnrolmentWithEnroledState(final CurricularCourse curricularCourse, final ExecutionSemester executionSemester) { return false; } @Override public ExecutionYear getIEnrolmentsLastExecutionYear() { return getExecutionYear(); } @Override public void getCurriculumModules(final ResultCollection<CurriculumModule> collection) { collection.condicionalAdd(this); } public CurricularCourse getCurricularCourse() { return (CurricularCourse) getDegreeModule(); } final public void setCurricularCourse(CurricularCourse curricularCourse) { setDegreeModule(curricularCourse); } @Override public void setDegreeModule(final DegreeModule degreeModule) { if (degreeModule != null && !(degreeModule instanceof CurricularCourse)) { throw new DomainException("error.curriculumLine.DegreeModuleCanOnlyBeCurricularCourse"); } super.setDegreeModule(degreeModule); } final public boolean hasCurricularCourse() { return getDegreeModule() != null; } @Override public Enrolment findEnrolmentFor(final CurricularCourse curricularCourse, final ExecutionSemester executionSemester) { return null; } @Override public Set<IDegreeModuleToEvaluate> getDegreeModulesToEvaluate(ExecutionSemester executionSemester) { return Collections.emptySet(); } @Override public Enrolment getApprovedEnrolment(final CurricularCourse curricularCourse) { return null; } @Override public Dismissal getDismissal(final CurricularCourse curricularCourse) { return null; } @Override public Collection<Enrolment> getSpecialSeasonEnrolments(ExecutionYear executionYear) { return Collections.emptySet(); } @Override public Collection<Enrolment> getSpecialSeasonEnrolments(ExecutionSemester executionSemester) { return Collections.emptySet(); } @Override final public void getAllDegreeModules(final Collection<DegreeModule> degreeModules) { degreeModules.add(getDegreeModule()); } @Override public Set<CurriculumLine> getAllCurriculumLines() { return Collections.singleton(this); } @Override public MultiLanguageString getName() { ExecutionSemester period = getExecutionPeriod(); CurricularCourse course = getCurricularCourse(); return new MultiLanguageString().with(MultiLanguageString.pt, course.getName(period)).with(MultiLanguageString.en, course.getNameEn(period)); } public boolean hasExecutionPeriod() { return getExecutionPeriod() != null; } protected boolean hasCurricularCourse(final CurricularCourse own, final CurricularCourse other, final ExecutionSemester executionSemester) { return own.isEquivalent(other) || hasCurricularCourseEquivalence(own, other, executionSemester); } private boolean hasCurricularCourseEquivalence(final CurricularCourse sourceCurricularCourse, final CurricularCourse equivalentCurricularCourse, final ExecutionSemester executionSemester) { for (final CurricularCourseEquivalence curricularCourseEquivalence : sourceCurricularCourse .getCurricularCourseEquivalencesFor(equivalentCurricularCourse)) { if (oldCurricularCoursesAreApproved(curricularCourseEquivalence, executionSemester)) { return true; } } return false; } private boolean oldCurricularCoursesAreApproved(final CurricularCourseEquivalence curricularCourseEquivalence, final ExecutionSemester executionSemester) { for (final CurricularCourse curricularCourse : curricularCourseEquivalence.getOldCurricularCoursesSet()) { if (!getStudentCurricularPlan().isApproved(curricularCourse, executionSemester)) { return false; } } return true; } @Override public boolean hasConcluded(final DegreeModule degreeModule, final ExecutionYear executionYear) { return getDegreeModule() == degreeModule && isConcluded(executionYear).value(); } @Override public CurriculumLine getApprovedCurriculumLine(CurricularCourse curricularCourse) { return isApproved(curricularCourse) ? this : null; } protected String getCurrentUser() { return Authenticate.getUser() != null ? Authenticate.getUser().getUsername() : null; } abstract public boolean isApproved(); abstract public boolean isValid(ExecutionSemester executionSemester); abstract public ExecutionSemester getExecutionPeriod(); @Override public boolean hasEnrolment(ExecutionSemester executionSemester) { return false; } @Override public boolean hasEnrolment(ExecutionYear executionYear) { return false; } @Override public boolean isEnroledInSpecialSeason(ExecutionSemester executionSemester) { return false; } @Override public boolean isEnroledInSpecialSeason(ExecutionYear executionYear) { return false; } public boolean hasCreatedBy() { return getCreatedBy() != null && !getCreatedBy().isEmpty(); } @Override public int getNumberOfAllApprovedEnrolments(final ExecutionSemester executionSemester) { return 0; } @Override public Set<CurriculumGroup> getAllCurriculumGroups() { return Collections.emptySet(); } @Override public Set<CurriculumGroup> getAllCurriculumGroupsWithoutNoCourseGroupCurriculumGroups() { return Collections.emptySet(); } abstract protected void createCurriculumLineLog(final EnrolmentAction action); abstract public BigDecimal getEctsCreditsForCurriculum(); abstract public double getAccumulatedEctsCredits(final ExecutionSemester executionSemester); abstract public String getModuleTypeName(); @Override public Stream<CurriculumLine> getCurriculumLineStream() { return Stream.of(this); } }