/** * 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.serviceRequests.documentRequests; import static org.fenixedu.academic.predicate.AccessControl.check; import java.util.Collection; import java.util.HashSet; import java.util.Locale; import java.util.Optional; import java.util.Set; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.accounting.EventType; import org.fenixedu.academic.domain.accounting.events.serviceRequests.DegreeFinalizationCertificateRequestEvent; import org.fenixedu.academic.domain.degreeStructure.CycleType; import org.fenixedu.academic.domain.degreeStructure.ProgramConclusion; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.domain.serviceRequests.AcademicServiceRequestSituationType; import org.fenixedu.academic.domain.serviceRequests.IProgramConclusionRequest; import org.fenixedu.academic.domain.serviceRequests.RegistryCode; import org.fenixedu.academic.domain.student.MobilityProgram; import org.fenixedu.academic.domain.student.Registration; import org.fenixedu.academic.domain.student.curriculum.ConclusionProcess; import org.fenixedu.academic.domain.student.curriculum.ICurriculum; import org.fenixedu.academic.domain.student.curriculum.ICurriculumEntry; import org.fenixedu.academic.domain.studentCurriculum.CurriculumGroup; import org.fenixedu.academic.domain.studentCurriculum.CycleCurriculumGroup; import org.fenixedu.academic.domain.studentCurriculum.Dismissal; import org.fenixedu.academic.dto.serviceRequests.AcademicServiceRequestBean; import org.fenixedu.academic.dto.serviceRequests.DocumentRequestCreateBean; import org.fenixedu.academic.dto.student.RegistrationConclusionBean; import org.fenixedu.academic.predicate.AcademicPredicates; import org.fenixedu.academic.util.Bundle; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.joda.time.YearMonthDay; import pt.ist.fenixframework.Atomic; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; public class DegreeFinalizationCertificateRequest extends DegreeFinalizationCertificateRequest_Base implements IProgramConclusionRequest { protected DegreeFinalizationCertificateRequest() { super(); } public DegreeFinalizationCertificateRequest(final DocumentRequestCreateBean bean) { this(); super.init(bean); checkParameters(bean); super.setAverage(bean.getAverage()); super.setDetailed(bean.getDetailed()); super.setMobilityProgram(bean.getMobilityProgram()); super.setIgnoreExternalEntries(bean.isIgnoreExternalEntries()); super.setIgnoreCurriculumInAdvance(bean.isIgnoreCurriculumInAdvance()); super.setTechnicalEngineer(bean.getTechnicalEngineer()); super.setInternshipAbolished(bean.getInternshipAbolished()); super.setInternshipApproved(bean.getInternshipApproved()); super.setStudyPlan(bean.getStudyPlan()); super.setBranch(bean.getBranchName()); super.setExceptionalConclusionDate(bean.getExceptionalConclusionDate()); super.setLanguage(bean.getLanguage()); super.setProgramConclusion(bean.getProgramConclusion()); } @Override protected void checkParameters(final DocumentRequestCreateBean bean) { if (bean.getAverage() == null) { throw new DomainException("DegreeFinalizationCertificateRequest.average.cannot.be.null"); } if (bean.getDetailed() == null) { throw new DomainException("DegreeFinalizationCertificateRequest.detailed.cannot.be.null"); } if (bean.getMobilityProgram() != null && bean.isIgnoreExternalEntries()) { throw new DomainException("ApprovementCertificateRequest.cannot.ignore.external.entries.within.a.mobility.program"); } if ((bean.getInternshipAbolished() || bean.getInternshipApproved() || bean.getStudyPlan()) && bean.getExceptionalConclusionDate() == null) { throw new DomainException( "DegreeFinalizationCertificateRequest.must.indicate.date.for.exceptional.conclusion.situation"); } if (bean.getLanguage() == null) { throw new DomainException("DegreeFinalizationCertificateRequest.missing.language"); } if (bean.getProgramConclusion() == null) { throw new DomainException("error.program.conclusion.empty"); } checkSpecificConditions(bean.getProgramConclusion()); } protected void checkSpecificConditions(ProgramConclusion programConclusion) { if (!programConclusion.getGraduationTitle().isEmpty()) { checkForDiplomaRequest(getRegistration(), programConclusion); } else { if (!programConclusion.isConclusionProcessed(getRegistration())) { throw new DomainException("DiplomaRequest.registration.not.submited.to.conclusion.process"); } } } static public void checkForDiplomaRequest(final Registration registration, final ProgramConclusion programConclusion) { final DiplomaRequest diplomaRequest = registration.getDiplomaRequest(programConclusion); final PastDiplomaRequest pastDiplomaRequest = registration.getPastDiplomaRequest(); if (diplomaRequest == null) { if (pastDiplomaRequest == null) { checkForRegistryRequest(registration, programConclusion); } } else if (diplomaRequest.isPayedUponCreation() && diplomaRequest.getEvent() != null && !diplomaRequest.getEvent().isPayed()) { throw new DomainException("DegreeFinalizationCertificateRequest.registration.withoutPayedDiplomaRequest"); } } static public void checkForRegistryRequest(final Registration registration, final ProgramConclusion programConclusion) { final RegistryDiplomaRequest registryRequest = registration.getRegistryDiplomaRequest(programConclusion); if (registryRequest == null) { throw new DomainException("DegreeFinalizationCertificateRequest.registration.withoutRegistryRequest"); } else if (registryRequest.isPayedUponCreation() && registryRequest.getEvent() != null && !registryRequest.getEvent().isPayed()) { throw new DomainException("DegreeFinalizationCertificateRequest.registration.withoutPayedRegistryRequest"); } } @Override final protected void internalChangeState(AcademicServiceRequestBean academicServiceRequestBean) { if (academicServiceRequestBean.isToProcess()) { checkSpecificConditions(getProgramConclusion()); if (!getProgramConclusion().isConclusionProcessed(getRegistration())) { throw new DomainException("DegreeFinalizationCertificateRequest.registration.not.submited.to.conclusion.process"); } final RegistryDiplomaRequest registryRequest = getRegistration().getRegistryDiplomaRequest(getProgramConclusion()); if (registryRequest != null && registryRequest.getAcademicServiceRequestSituationType().compareTo( AcademicServiceRequestSituationType.SENT_TO_EXTERNAL_ENTITY) < 0) { throw new DomainException( "DegreeFinalizationCertificateRequest.registration.registryRequestIsNotSentToExternalEntity"); } if (!getFreeProcessed()) { final Optional<CurriculumGroup> curriculumGroup = getProgramConclusion().groupFor(getRegistration()); if (curriculumGroup.isPresent()) { assertPayedEvents(curriculumGroup.get().getIEnrolmentsLastExecutionYear()); } else { assertPayedEvents(); } } if (hasPersonalInfo() && hasMissingPersonalInfo()) { throw new DomainException("AcademicServiceRequest.has.missing.personal.info"); } } if (academicServiceRequestBean.isToConclude()) { tryConcludeServiceRequest(academicServiceRequestBean); } if (academicServiceRequestBean.isToCancelOrReject() && getEvent() != null) { getEvent().cancel(academicServiceRequestBean.getResponsible()); } if (academicServiceRequestBean.isToDeliver()) { if (isPayable() && !isPayed()) { throw new DomainException("AcademicServiceRequest.hasnt.been.payed"); } } } @Override final public String getDescription() { return Joiner.on(" : ").join(BundleUtil.getString(Bundle.ENUMERATION, getDocumentRequestType().name()), getProgramConclusion().getName().getContent()); } @Override final public DocumentRequestType getDocumentRequestType() { return DocumentRequestType.DEGREE_FINALIZATION_CERTIFICATE; } @Override final public String getDocumentTemplateKey() { return getClass().getName(); } @Override final public void setAverage(final Boolean average) { throw new DomainException("DegreeFinalizationCertificateRequest.cannot.modify.average"); } @Override final public void setDetailed(final Boolean detailed) { throw new DomainException("DegreeFinalizationCertificateRequest.cannot.modify.detailed"); } @Override public void setMobilityProgram(MobilityProgram mobilityProgram) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public void setIgnoreExternalEntries(Boolean ignoreExternalEntries) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public void setTechnicalEngineer(Boolean technicalEngineer) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public void setInternshipAbolished(Boolean internshipAbolished) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public void setInternshipApproved(Boolean internshipApproved) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public void setExceptionalConclusionDate(YearMonthDay exceptionalConclusionDate) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public void setStudyPlan(Boolean studyPlan) { throw new DomainException("error.DegreeFinalizationCertificateRequest.cannot.modify"); } @Override public CycleType getRequestedCycle() { return getProgramConclusion().groupFor(getRegistration()).filter(CurriculumGroup::isCycleCurriculumGroup) .map(ccg -> ((CycleCurriculumGroup) ccg).getCycleType()).orElse(null); } public static Set<EventType> getPossibleEventTypes() { return ImmutableSet.of(EventType.DEGREE_FINALIZATION_CERTIFICATE_REQUEST); } @Override final public EventType getEventType() { return EventType.DEGREE_FINALIZATION_CERTIFICATE_REQUEST; } @Override final public Integer getNumberOfUnits() { return getDetailed() ? getEntriesToReport().size() : 0; } final private RegistrationConclusionBean getBean() { return new RegistrationConclusionBean(getRegistration(), getProgramConclusion()); } final public boolean hasExceptionalConclusionDate() { return getExceptionalConclusionDate() != null; } final public boolean hasExceptionalConclusionInfo() { return getTechnicalEngineer() || getInternshipAbolished() || getInternshipApproved() || getStudyPlan(); } final public boolean mustHideConclusionDate() { return getInternshipAbolished() || getInternshipApproved() || (getStudyPlan() && getRegistration().isFirstCycleAtributionIngression()); } final public YearMonthDay getConclusionDate() { return getBean().getConclusionDate(); } final public Integer getFinalAverage() { return getBean().getFinalGrade().getIntegerValue(); } final public double getEctsCredits() { return getBean().getEctsCredits(); } final public ICurriculum getCurriculum() { return getBean().getCurriculumForConclusion(); } final public Collection<ICurriculumEntry> getEntriesToReport() { final Collection<ICurriculumEntry> result = new HashSet<ICurriculumEntry>(); for (final ICurriculumEntry entry : getCurriculum().getCurriculumEntries()) { if (entry instanceof Dismissal) { final Dismissal dismissal = (Dismissal) entry; if (dismissal.getCredits().isEquivalence() || (dismissal.isCreditsDismissal() && !dismissal.getCredits().isSubstitution())) { continue; } } result.add(entry); } return result; } @Override public boolean hasPersonalInfo() { return true; } @Override public RegistryCode getRegistryCode() { RegistryDiplomaRequest registry = getRegistration().getRegistryDiplomaRequest(getProgramConclusion()); return registry != null ? registry.getRegistryCode() : null; } @Atomic @Override public void revertToProcessingState() { check(this, AcademicPredicates.SERVICE_REQUESTS_REVERT_TO_PROCESSING_STATE); internalRevertToProcessingState(); } @Override protected void createCertificateRequestEvent() { new DegreeFinalizationCertificateRequestEvent(getAdministrativeOffice(), getRegistration().getPerson(), this); } public ExecutionYear getConclusionYear() { return getProgramConclusion().groupFor(getRegistration()).map(CurriculumGroup::getConclusionProcess) .map(ConclusionProcess::getConclusionYear).orElse(null); } @Override public String getGraduateTitle(Locale locale) { final StringBuilder res = new StringBuilder(); if (!getProgramConclusion().getGraduationTitle().isEmpty()) { res.append(", ").append( BundleUtil.getString(Bundle.ACADEMIC, getLanguage(), "documents.DegreeFinalizationCertificate.graduateTitleInfo")); res.append(" ").append(getRegistration().getGraduateTitle(getProgramConclusion(), getLanguage())); } return res.toString(); } }