package net.sourceforge.fenixedu.domain.studentCurriculum; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Collection; import java.util.HashSet; import java.util.Set; import net.sourceforge.fenixedu.dataTransferObject.administrativeOffice.dismissal.ISCTEDismissalBean.DismissalType; import net.sourceforge.fenixedu.dataTransferObject.administrativeOffice.dismissal.ISCTEDismissalBean.SelectedCurriculumEntry; import net.sourceforge.fenixedu.dataTransferObject.administrativeOffice.dismissal.ISCTEDismissalBean.SelectedDismissalEntry; import net.sourceforge.fenixedu.domain.ExecutionPeriod; import net.sourceforge.fenixedu.domain.Grade; import net.sourceforge.fenixedu.domain.GradeScale; import net.sourceforge.fenixedu.domain.StudentCurricularPlan; import net.sourceforge.fenixedu.domain.degreeStructure.CourseGroup; import net.sourceforge.fenixedu.domain.exceptions.DomainException; /** * * @author rjmvo * */ public class ISCTEEquivalence extends ISCTEEquivalence_Base { public ISCTEEquivalence() { super(); } public ISCTEEquivalence(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, Collection dismissals, Grade grade) { this(); init(scp, executionPeriod, enrolments, dismissals, grade); } public ISCTEEquivalence(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, CurriculumGroup curriculumGroup, Double givenCredits, Grade grade) { this(); init(scp, executionPeriod, enrolments, curriculumGroup, givenCredits, grade); } public ISCTEEquivalence(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, Collection dismissals, CourseGroup courseGroup, Double givenCredits, Double weight, Grade grade) { this(); init(scp, executionPeriod, enrolments, dismissals, courseGroup, givenCredits, weight, grade); } protected void init(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Grade grade) { initExecutionPeriod(executionPeriod); if (scp == null) { throw new DomainException("error.equivalence.wrong.arguments"); } if (grade == null || grade.isEmpty()) { throw new DomainException("error.equivalence.must.define.enrolments.and.grade"); } setStudentCurricularPlan(scp); setGrade(grade); } protected void init(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, Collection dismissals, Grade grade) { init(scp, executionPeriod, enrolments, dismissals, grade, true); } protected void init(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, Collection dismissals, Grade grade, boolean checkGivenCredits) { init(scp, executionPeriod, grade); if (dismissals == null || dismissals.isEmpty()) { throw new DomainException("error.substitution.wrong.arguments"); } setStudentCurricularPlan(scp); if (checkGivenCredits) { ISCTEDismissalsUtils.checkGivenCredits(this, executionPeriod, enrolments, dismissals); } ISCTEDismissalsUtils.addCurriculumEntries(this, enrolments); ISCTEDismissalsUtils.addDismissalsEntries(this, dismissals); } protected void init(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, CurriculumGroup curriculumGroup, Double givenCredits, Grade grade) { init(scp, executionPeriod, grade); if (curriculumGroup == null || givenCredits == null) { throw new DomainException("error.substitution.wrong.arguments"); } ISCTEDismissalsUtils.checkGivenCredits(this, executionPeriod, enrolments, givenCredits); setGivenCredits(givenCredits); ISCTEDismissalsUtils.addCurriculumEntries(this, enrolments); Dismissal.createNewDismissal(this, scp, curriculumGroup, ISCTEDismissalsUtils.getEmptyCurricularCourses()); } public void init(StudentCurricularPlan scp, ExecutionPeriod executionPeriod, Collection enrolments, Collection dismissals, CourseGroup courseGroup, Double givenCredits, Double weight, Grade grade) { init(scp, executionPeriod, grade); if (enrolments == null || enrolments.isEmpty() || courseGroup == null || givenCredits == null || weight == null) { throw new DomainException("error.substitution.wrong.arguments"); } ISCTEDismissalsUtils.checkGivenCredits(this, executionPeriod, enrolments, givenCredits); setGivenCredits(givenCredits); setWeight(weight); ISCTEDismissalsUtils.addCurriculumEntries(this, enrolments); Dismissal.createNewDismissal(this, scp, courseGroup, ISCTEDismissalsUtils.getCurricularCourses(dismissals)); } public static Credits createDismissal(StudentCurricularPlan scp, CourseGroup courseGroup, CurriculumGroup curriculumGroup, Collection enrolments, Collection dismissals, ExecutionPeriod executionPeriod, Double givenCredits, Double weight, Grade givenGrade, DismissalType type) { switch (type) { case CURRICULAR_COURSE_CREDITS: return new ISCTEEquivalence(scp, executionPeriod, enrolments, dismissals, givenGrade); case CURRICULUM_GROUP_CREDITS: return new ISCTEEquivalence(scp, executionPeriod, enrolments, dismissals, courseGroup, givenCredits, weight, givenGrade); case NO_COURSE_GROUP_CURRICULUM_GROUP_CREDITS: return new ISCTEEquivalence(scp, executionPeriod, enrolments, curriculumGroup, givenCredits, givenGrade); } return null; } @Override public void updateGrade() { final Set entries = new HashSet(); for (final EnrolmentWrapper wrapper : getEnrolments()) { final SelectedCurriculumEntry entryToAdd = new SelectedCurriculumEntry(wrapper.getCurriculumEntry()); entryToAdd.setCreditsEcts(wrapper.getEctsCredits().doubleValue()); entryToAdd.setWeigth(wrapper.getCreditsWeight()); entries.add(entryToAdd); } setGrade(calculateAverateForEnrolmentEntries(entries)); for (final Dismissal dismissal : getDismissals()) { for (final ISCTEDismissalWrapper wrapper : dismissal.getDismissalWrappers()) { wrapper.updateCreditsGrade(); } } } public static Grade calculateAverateForEnrolmentEntries(Collection entries) { if (entries.isEmpty()) { return Grade.createEmptyGrade(); } final GradeScale gradeScale = calculateGradeScale(entries); BigDecimal numerator = BigDecimal.ZERO; BigDecimal denominator = BigDecimal.ZERO; for (SelectedCurriculumEntry entry : entries) { if (!entry.getCurriculumEntry().getGrade().isNumeric()) { return Grade.createEmptyGrade(); } final BigDecimal credits = new BigDecimal(entry.getCreditsEcts()); final BigDecimal grade = new BigDecimal(entry.getCurriculumEntry().getGradeValue()); numerator = numerator.add(credits.multiply(grade)); denominator = denominator.add(credits); } if (denominator.equals(BigDecimal.ZERO)) { return Grade.createEmptyGrade(); } return Grade.createGrade(numerator.divide(denominator, 0, RoundingMode.HALF_UP).toString(), gradeScale); } private static GradeScale calculateGradeScale(Collection entries) { GradeScale gradeScale = null; for (final SelectedCurriculumEntry entry : entries) { if (gradeScale == null) { gradeScale = entry.getCurriculumEntry().getGrade().getGradeScale(); } else { if (gradeScale != entry.getCurriculumEntry().getGrade().getGradeScale()) { throw new DomainException( "error.studentCurriculum.ISCTEEquivalence.entries.to.calculate.average.must.be.of.same.type"); } } } return gradeScale; } }