/** * 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.mobility.outbound; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import org.fenixedu.academic.domain.Country; import org.fenixedu.academic.domain.ExecutionDegree; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.candidacyProcess.mobility.MobilityAgreement; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.domain.organizationalStructure.Unit; import org.fenixedu.academic.domain.student.Registration; import org.fenixedu.academic.domain.student.Student; import org.fenixedu.academic.domain.student.registrationStates.RegistrationState; import org.fenixedu.bennu.core.domain.Bennu; import pt.ist.fenixframework.Atomic; public class OutboundMobilityCandidacyContest extends OutboundMobilityCandidacyContest_Base implements Comparable<OutboundMobilityCandidacyContest> { public OutboundMobilityCandidacyContest(final OutboundMobilityCandidacyPeriod outboundMobilityCandidacyPeriod, final OutboundMobilityCandidacyContestGroup mobilityGroup, final MobilityAgreement mobilityAgreement, final Integer vacancies) { setRootDomainObject(Bennu.getInstance()); setOutboundMobilityCandidacyPeriod(outboundMobilityCandidacyPeriod); setMobilityAgreement(mobilityAgreement); setOutboundMobilityCandidacyContestGroup(mobilityGroup); for (final ExecutionDegree executionDegree : mobilityGroup.getExecutionDegreeSet()) { addExecutionDegree(executionDegree); } setVacancies(vacancies); } @Override public int compareTo(final OutboundMobilityCandidacyContest o) { final int edc = compareDegrees(o); if (edc == 0) { final int cc = compareCountries(o); if (cc == 0) { final int uc = compareUniversities(o); if (uc == 0) { final int pc = comparePrograms(o); return pc == 0 ? getExternalId().compareTo(o.getExternalId()) : pc; } return uc; } return cc; } return edc; } private int compareCountries(final OutboundMobilityCandidacyContest o) { final Country c1 = getMobilityAgreement().getUniversityUnit().getCountry(); final Country c2 = o.getMobilityAgreement().getUniversityUnit().getCountry(); return c1 == c2 ? 0 : (c1 != null && c2 != null ? c1.getName().compareTo(c2.getName()) : (c1 == null ? -1 : 1)); } private int comparePrograms(final OutboundMobilityCandidacyContest o) { return getMobilityAgreement().getMobilityProgram().getRegistrationProtocol().getDescription() .compareTo(o.getMobilityAgreement().getMobilityProgram().getRegistrationProtocol().getDescription()); } private int compareUniversities(final OutboundMobilityCandidacyContest o) { return Unit.COMPARATOR_BY_NAME_AND_ID.compare(getMobilityAgreement().getUniversityUnit(), o.getMobilityAgreement() .getUniversityUnit()); } private int compareDegrees(final OutboundMobilityCandidacyContest o) { return executionDegreesCompareHash(o.getOutboundMobilityCandidacyContestGroup().getExecutionDegreeSet()).compareTo( executionDegreesCompareHash(getOutboundMobilityCandidacyContestGroup().getExecutionDegreeSet())); } private String executionDegreesCompareHash(final Set<ExecutionDegree> executionDegreeSet) { final SortedSet<String> strings = new TreeSet<String>(); for (final ExecutionDegree executionDegree : executionDegreeSet) { strings.add(executionDegree.getDegree().getSigla()); } final StringBuilder builder = new StringBuilder(); for (final String string : strings) { builder.append(string); } return builder.toString(); } public boolean isAcceptingCandidacies() { return getOutboundMobilityCandidacyPeriod().isAcceptingCandidacies(); } public boolean isAcceptingCandidacies(final Student student) { return isAcceptingCandidacies() && findBestRegistration(student) != null; } public void apply(final Student student) { if (isAcceptingCandidacies()) { final Registration registration = findBestRegistration(student); if (registration == null) { throw new DomainException("error.OutboundMobilityCandidacyContest.not.accepting.for.studnt"); } else { apply(registration); } } else { throw new DomainException("error.CandidacyPeriod.not.accepting.candidacies"); } } private void apply(final Registration registration) { OutboundMobilityCandidacySubmission.apply(this, registration); } public Registration findBestRegistration(final Student student) { for (final Registration registration : student.getRegistrationsSet()) { for (final ExecutionDegree executionDegree : getOutboundMobilityCandidacyContestGroup().getExecutionDegreeSet()) { if (executionDegree.getDegree() == registration.getDegree()) { final ExecutionYear executionYear = (ExecutionYear) getOutboundMobilityCandidacyPeriod().getExecutionInterval(); final RegistrationState registrationState = registration.getLastRegistrationState(executionYear); if (registrationState != null && registrationState.getStateType().isActive()) { return registration; } } } } return null; } public boolean hasCandidacy(final Student student) { for (final Registration registration : student.getRegistrationsSet()) { for (final OutboundMobilityCandidacySubmission submission : registration.getOutboundMobilityCandidacySubmissionSet()) { for (final OutboundMobilityCandidacy candidacy : submission.getOutboundMobilityCandidacySet()) { if (candidacy.getOutboundMobilityCandidacyContest() == this) { return true; } } } } return false; } @Override public void addExecutionDegree(final ExecutionDegree executionDegree) { super.addExecutionDegree(executionDegree); // TODO : This is a hack due to a bug in the consistency predicate or fenix-framework code. // When the relation is initialized but never traversed, the consistency predicate always // fails. Forcing a traversal will resolve this issue. The bug has already been solved in // the framework, but the framework has not yet been updated on this project. getExecutionDegreeSet().size(); } @Atomic public void delete() { final OutboundMobilityCandidacyContestGroup mobilityGroup = getOutboundMobilityCandidacyContestGroup(); for (final OutboundMobilityCandidacy candidacy : getOutboundMobilityCandidacySet()) { candidacy.deleteWithNotification(); } getExecutionDegreeSet().clear(); setMobilityAgreement(null); setOutboundMobilityCandidacyContestGroup(null); setOutboundMobilityCandidacyPeriod(null); setRootDomainObject(null); if (mobilityGroup != null && mobilityGroup.getOutboundMobilityCandidacyContestSet().size() == 0) { mobilityGroup.delete(); } deleteDomainObject(); } public int countSelectedCandidates() { int c = 0; for (OutboundMobilityCandidacy candidacy : getOutboundMobilityCandidacySet()) { if (candidacy.getSubmissionFromSelectedCandidacy() != null) { c++; } } return c; } public boolean hasVacancy() { final Integer vacancies = getVacancies(); return vacancies == null || vacancies.intValue() > countSelectedCandidates(); } @Atomic public void editVacancies(final Integer vacancies) { setVacancies(vacancies); } }