/**
* 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;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections.comparators.ComparatorChain;
import org.fenixedu.academic.domain.AcademicProgram;
import org.fenixedu.academic.domain.DomainObjectUtil;
import org.fenixedu.academic.domain.ExecutionYear;
import org.fenixedu.academic.domain.Person;
import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicAccessRule;
import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicOperationType;
import org.fenixedu.academic.domain.accounting.EventType;
import org.fenixedu.academic.domain.accounting.events.serviceRequests.AcademicServiceRequestEvent;
import org.fenixedu.academic.domain.administrativeOffice.AdministrativeOffice;
import org.fenixedu.academic.domain.documents.GeneratedDocument;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.serviceRequests.documentRequests.AcademicServiceRequestType;
import org.fenixedu.academic.domain.serviceRequests.documentRequests.DocumentRequest;
import org.fenixedu.academic.domain.util.email.Message;
import org.fenixedu.academic.domain.util.email.Recipient;
import org.fenixedu.academic.domain.util.email.Sender;
import org.fenixedu.academic.dto.serviceRequests.AcademicServiceRequestBean;
import org.fenixedu.academic.dto.serviceRequests.AcademicServiceRequestCreateBean;
import org.fenixedu.academic.predicate.AccessControl;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import org.fenixedu.bennu.core.security.Authenticate;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.YearMonthDay;
import pt.ist.fenixframework.Atomic;
import com.google.common.base.Strings;
abstract public class AcademicServiceRequest extends AcademicServiceRequest_Base {
private static final String SERVICE_REQUEST_NUMBER_YEAR_SEPARATOR = "/";
public static final Comparator<AcademicServiceRequest> COMPARATOR_BY_NUMBER = new Comparator<AcademicServiceRequest>() {
@Override
public int compare(AcademicServiceRequest o1, AcademicServiceRequest o2) {
return o1.getServiceRequestNumber().compareTo(o2.getServiceRequestNumber());
}
};
public static final Comparator<AcademicServiceRequest> EXECUTION_YEAR_COMPARATOR = new Comparator<AcademicServiceRequest>() {
@Override
public int compare(AcademicServiceRequest o1, AcademicServiceRequest o2) {
if (o1.getExecutionYear() == null && o2.getExecutionYear() == null) {
return 0;
} else if (o1.getExecutionYear() != null && o2.getExecutionYear() == null) {
return 1;
} else if (o1.getExecutionYear() == null && o2.getExecutionYear() != null) {
return -1;
}
return ExecutionYear.COMPARATOR_BY_YEAR.compare(o1.getExecutionYear(), o2.getExecutionYear());
}
};
public static final Comparator<AcademicServiceRequest> EXECUTION_YEAR_AND_OID_COMPARATOR =
new Comparator<AcademicServiceRequest>() {
@Override
public int compare(AcademicServiceRequest o1, AcademicServiceRequest o2) {
final ComparatorChain comparatorChain = new ComparatorChain();
comparatorChain.addComparator(EXECUTION_YEAR_COMPARATOR);
comparatorChain.addComparator(DomainObjectUtil.COMPARATOR_BY_ID);
return comparatorChain.compare(o1, o2);
}
};
protected AcademicServiceRequest() {
super();
super.setRootDomainObject(Bennu.getInstance());
}
protected void init(final AcademicServiceRequestCreateBean bean, AdministrativeOffice office) {
checkParameters(bean);
super.setAdministrativeOffice(office);
super.setAcademicServiceRequestYear(AcademicServiceRequestYear.readByYear(bean.getRequestDate().year().get(), true));
super.setServiceRequestNumber(getAcademicServiceRequestYear().generateServiceRequestNumber());
super.setRequestDate(bean.getRequestDate());
super.setUrgentRequest(bean.getUrgentRequest());
super.setFreeProcessed(bean.getFreeProcessed());
super.setExecutionYear(bean.getExecutionYear());
super.setLanguage(bean.getLanguage());
final AcademicServiceRequestBean situationBean =
new AcademicServiceRequestBean(AcademicServiceRequestSituationType.NEW, AccessControl.getPerson());
situationBean.setSituationDate(getRequestDate().toYearMonthDay());
createAcademicServiceRequestSituations(situationBean);
}
private int getServiceRequestYear() {
return getAcademicServiceRequestYear().getYear();
}
private void checkParameters(final AcademicServiceRequestCreateBean bean) {
if (bean.getRequestDate() == null || bean.getRequestDate().isAfterNow()) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.invalid.requestDate");
}
if (bean.getUrgentRequest() == null) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.urgentRequest.cannot.be.null");
}
if (bean.getFreeProcessed() == null) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.freeProcessed.cannot.be.null");
}
if (bean.getLanguage() == null) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.language.cannot.be.null");
}
}
@Override
final public void setUrgentRequest(Boolean urgentRequest) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.modify.urgentRequest");
}
@Override
final public void setFreeProcessed(Boolean freeProcessed) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.modify.freeProcessed");
}
@Override
final public void setExecutionYear(ExecutionYear executionYear) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.modify.executionYear");
}
@Override
final public void setRequestDate(DateTime requestDate) {
super.setRequestDate(requestDate);
}
final public boolean isUrgentRequest() {
return getUrgentRequest().booleanValue();
}
public boolean isFreeProcessed() {
return getFreeProcessed();
}
public boolean isFree() {
return !isPayable() || isFreeProcessed();
}
final protected boolean isPayable() {
return getEventType() != null;
}
protected boolean isPayed() {
return getEvent() == null || getEvent().isPayed();
}
final public boolean getIsPayed() {
return isPayed();
}
abstract public boolean isPayedUponCreation();
public boolean isPaymentsAccessible() {
final AcademicProgram program = getAcademicProgram();
return AcademicAccessRule
.getProgramsAccessibleToFunction(AcademicOperationType.MANAGE_STUDENT_PAYMENTS, Authenticate.getUser())
.anyMatch(p -> p == program);
}
public boolean isRegistrationAccessible() {
final AcademicProgram program = getAcademicProgram();
return AcademicAccessRule
.getProgramsAccessibleToFunction(AcademicOperationType.MANAGE_REGISTRATIONS, Authenticate.getUser())
.anyMatch(p -> p == program);
}
protected String getDescription(final AcademicServiceRequestType academicServiceRequestType, final String specificServiceType) {
final StringBuilder result = new StringBuilder();
result.append(BundleUtil.getString(Bundle.ENUMERATION, academicServiceRequestType.getQualifiedName()));
if (specificServiceType != null) {
result.append(": ");
result.append(BundleUtil.getString(Bundle.ENUMERATION, specificServiceType));
}
return result.toString();
}
protected String getDescription(final AcademicServiceRequestType academicServiceRequestType) {
return getDescription(academicServiceRequestType, null);
}
public String getDescription() {
return getDescription(getAcademicServiceRequestType());
}
@Atomic
final public void process() throws DomainException {
process(AccessControl.getPerson());
}
final public void process(final Person responsible) throws DomainException {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.PROCESSING, responsible));
}
final public void process(final Person responsible, final YearMonthDay situationDate) throws DomainException {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.PROCESSING, responsible, situationDate, ""));
}
final public void process(final YearMonthDay situationDate) throws DomainException {
process(AccessControl.getPerson(), situationDate);
}
@Atomic
public void sendToExternalEntity(final YearMonthDay sendDate, final String description) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.SENT_TO_EXTERNAL_ENTITY,
AccessControl.getPerson(), sendDate, description));
}
@Atomic
final public void receivedFromExternalEntity(final YearMonthDay receivedDate, final String description) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.RECEIVED_FROM_EXTERNAL_ENTITY,
AccessControl.getPerson(), receivedDate, description));
}
@Atomic
final public void reject(final String justification) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.REJECTED, AccessControl.getPerson(),
justification));
}
@Atomic
final public void cancel(final String justification) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.CANCELLED, AccessControl.getPerson(),
justification));
}
final public void conclude() {
conclude(AccessControl.getPerson());
}
final public void conclude(final Person responsible) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.CONCLUDED, responsible));
}
final public void conclude(final YearMonthDay situationDate, final String justification) {
conclude(AccessControl.getPerson(), situationDate, justification);
}
final public void conclude(final Person responsible, final YearMonthDay situationDate) {
conclude(responsible, situationDate, "");
}
final public void conclude(final Person responsible, final YearMonthDay situationDate, final String justification) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.CONCLUDED, responsible, situationDate,
justification));
}
@Atomic
final public void conclude(final YearMonthDay situationDate, final String justification, boolean sendEmail) {
conclude(AccessControl.getPerson(), situationDate, justification);
if (sendEmail) {
sendConcludeEmail();
}
}
private void sendConcludeEmail() {
String body = BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.message1");
body += " " + getServiceRequestNumberYear();
body += " " + BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.message2");
body += " '" + getDescription();
body += "' " + BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.message3");
if (getAcademicServiceRequestType() == AcademicServiceRequestType.SPECIAL_SEASON_REQUEST) {
if (((SpecialSeasonRequest) this).getDeferred() == null) {
throw new DomainException("special.season.request.deferment.cant.be.null");
}
if (((SpecialSeasonRequest) this).getDeferred() == true) {
body += "\n" + BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.messageSSR4A");
} else {
body += "\n" + BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.messageSSR4B");
}
body += "\n\n" + BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.messageSSR5");
} else {
body += "\n\n" + BundleUtil.getString(Bundle.APPLICATION, "mail.academicServiceRequest.concluded.message4");
}
final Sender sender = getAdministrativeOffice().getUnit().getUnitBasedSenderSet().iterator().next();
final Recipient recipient = new Recipient(getPerson().getUser().groupOf());
new Message(sender, sender.getReplyTosSet(), recipient.asCollection(), getDescription(), body, "");
}
@Atomic
final public void delivered() {
delivered(AccessControl.getPerson());
}
final public void delivered(final Person responsible) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.DELIVERED, responsible));
}
final public void delivered(final Person responsible, final YearMonthDay situationDate) {
edit(new AcademicServiceRequestBean(AcademicServiceRequestSituationType.DELIVERED, responsible, situationDate, ""));
}
final public void delete() {
checkRulesToDelete();
disconnect();
super.deleteDomainObject();
}
protected void disconnect() {
for (; !getAcademicServiceRequestSituationsSet().isEmpty(); getAcademicServiceRequestSituationsSet().iterator().next()
.delete()) {
;
}
super.setAdministrativeOffice(null);
if (getEvent() != null) {
getEvent().delete();
}
super.setExecutionYear(null);
super.setRootDomainObject(null);
super.setAcademicServiceRequestYear(null);
}
protected void checkRulesToDelete() {
}
@Override
public void setAdministrativeOffice(AdministrativeOffice administrativeOffice) {
throw new DomainException("error.serviceRequests.RegistrationAcademicServiceRequest.cannot.modify.administrativeOffice");
}
@Override
final public void setServiceRequestNumber(Integer serviceRequestNumber) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.modify.serviceRequestNumber");
}
final public String getServiceRequestNumberYear() {
return getServiceRequestNumber() + SERVICE_REQUEST_NUMBER_YEAR_SEPARATOR + getServiceRequestYear();
}
@Override
final public void addAcademicServiceRequestSituations(AcademicServiceRequestSituation academicServiceRequestSituation) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.add.academicServiceRequestSituation");
}
@Override
final public void setEvent(AcademicServiceRequestEvent event) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.modify.event");
}
@Override
final public Set<AcademicServiceRequestSituation> getAcademicServiceRequestSituationsSet() {
return Collections.unmodifiableSet(super.getAcademicServiceRequestSituationsSet());
}
@Override
final public void removeAcademicServiceRequestSituations(AcademicServiceRequestSituation academicServiceRequestSituation) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.remove.academicServiceRequestSituation");
}
final public AcademicServiceRequestSituation getActiveSituation() {
return !getAcademicServiceRequestSituationsSet().isEmpty() ? Collections.min(getAcademicServiceRequestSituationsSet(),
AcademicServiceRequestSituation.COMPARATOR_BY_MOST_RECENT_SITUATION_DATE_AND_ID) : null;
}
final public DateTime getActiveSituationDate() {
return getActiveSituation().getSituationDate();
}
final public AcademicServiceRequestSituation getConclusionSituation() {
return getSituationByType(AcademicServiceRequestSituationType.CONCLUDED);
}
final public AcademicServiceRequestSituation getSituationByType(final AcademicServiceRequestSituationType type) {
for (final AcademicServiceRequestSituation situation : getAcademicServiceRequestSituationsSet()) {
if (situation.getAcademicServiceRequestSituationType().equals(type)) {
return situation;
}
}
return null;
}
final public AcademicServiceRequestSituationType getAcademicServiceRequestSituationType() {
return getActiveSituation().getAcademicServiceRequestSituationType();
}
public void edit(final AcademicServiceRequestBean academicServiceRequestBean) {
if (!isEditable()) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.is.not.editable");
}
if (getAcademicServiceRequestSituationType() != academicServiceRequestBean.getAcademicServiceRequestSituationType()) {
checkRulesToChangeState(academicServiceRequestBean.getAcademicServiceRequestSituationType());
internalChangeState(academicServiceRequestBean);
createAcademicServiceRequestSituations(academicServiceRequestBean);
} else {
getActiveSituation().edit(academicServiceRequestBean);
}
}
protected void checkRulesToChangeState(final AcademicServiceRequestSituationType situationType) {
if (!isAcceptedSituationType(situationType)) {
String sourceState = getActiveSituation().getAcademicServiceRequestSituationType().getLocalizedName();
String targetState = situationType.getLocalizedName();
throw new DomainException(
"error.serviceRequests.AcademicServiceRequest.cannot.change.from.source.state.to.target.state", sourceState,
targetState);
}
}
final protected boolean isAcceptedSituationType(final AcademicServiceRequestSituationType situationType) {
return getAcceptedSituationTypes(getAcademicServiceRequestSituationType()).contains(situationType);
}
final public boolean isCancelledSituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.CANCELLED);
}
final public boolean isRejectedSituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.REJECTED);
}
final public boolean isProcessingSituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.PROCESSING);
}
final public boolean isSendToExternalEntitySituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.SENT_TO_EXTERNAL_ENTITY);
}
final public boolean isReceivedSituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.RECEIVED_FROM_EXTERNAL_ENTITY);
}
final public boolean isConcludedSituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.CONCLUDED);
}
final public boolean isDeliveredSituationAccepted() {
return isAcceptedSituationType(AcademicServiceRequestSituationType.DELIVERED);
}
public boolean isDownloadPossible() {
return false;
}
final public boolean isRePrintPossible() {
return finishedSuccessfully() && isToPrint();
}
private List<AcademicServiceRequestSituationType> getAcceptedSituationTypes(AcademicServiceRequestSituationType situationType) {
switch (situationType) {
case NEW:
return getNewSituationAcceptedSituationsTypes();
case PROCESSING:
return getProcessingSituationAcceptedSituationsTypes();
case SENT_TO_EXTERNAL_ENTITY:
return getSentToExternalEntitySituationAcceptedSituationsTypes();
case RECEIVED_FROM_EXTERNAL_ENTITY:
return getReceivedFromExternalEntitySituationAcceptedSituationsTypes();
case CONCLUDED:
return getConcludedSituationAcceptedSituationsTypes();
default:
return Collections.emptyList();
}
}
protected List<AcademicServiceRequestSituationType> getNewSituationAcceptedSituationsTypes() {
return Collections.unmodifiableList(Arrays.asList(AcademicServiceRequestSituationType.CANCELLED,
AcademicServiceRequestSituationType.REJECTED, AcademicServiceRequestSituationType.PROCESSING));
}
protected List<AcademicServiceRequestSituationType> getProcessingSituationAcceptedSituationsTypes() {
if (isPossibleToSendToOtherEntity()) {
return Collections.unmodifiableList(Arrays.asList(AcademicServiceRequestSituationType.CANCELLED,
AcademicServiceRequestSituationType.REJECTED, AcademicServiceRequestSituationType.SENT_TO_EXTERNAL_ENTITY));
} else {
return Collections.unmodifiableList(Arrays.asList(AcademicServiceRequestSituationType.CANCELLED,
AcademicServiceRequestSituationType.REJECTED, AcademicServiceRequestSituationType.CONCLUDED));
}
}
protected List<AcademicServiceRequestSituationType> getSentToExternalEntitySituationAcceptedSituationsTypes() {
return Collections.unmodifiableList(Collections
.singletonList(AcademicServiceRequestSituationType.RECEIVED_FROM_EXTERNAL_ENTITY));
}
protected List<AcademicServiceRequestSituationType> getReceivedFromExternalEntitySituationAcceptedSituationsTypes() {
return Collections.unmodifiableList(Arrays.asList(AcademicServiceRequestSituationType.CANCELLED,
AcademicServiceRequestSituationType.REJECTED, AcademicServiceRequestSituationType.CONCLUDED));
}
protected List<AcademicServiceRequestSituationType> getConcludedSituationAcceptedSituationsTypes() {
return Collections.unmodifiableList(Arrays.asList(AcademicServiceRequestSituationType.CANCELLED,
AcademicServiceRequestSituationType.DELIVERED));
}
/** This method is overwritten in the subclasses */
protected void internalChangeState(final AcademicServiceRequestBean academicServiceRequestBean) {
if (academicServiceRequestBean.isToCancelOrReject() && getEvent() != null) {
getEvent().cancel(academicServiceRequestBean.getResponsible());
}
verifyIsToProcessAndHasPersonalInfo(academicServiceRequestBean);
verifyIsToDeliveredAndIsPayed(academicServiceRequestBean);
}
protected void verifyIsToDeliveredAndIsPayed(final AcademicServiceRequestBean academicServiceRequestBean) {
if (academicServiceRequestBean.isToDeliver()) {
if (isPayable() && !isPayed()) {
throw new DomainException("AcademicServiceRequest.hasnt.been.payed");
}
}
}
protected void verifyIsToProcessAndHasPersonalInfo(final AcademicServiceRequestBean academicServiceRequestBean) {
if (academicServiceRequestBean.isToProcess() && hasPersonalInfo() && hasMissingPersonalInfo()) {
throw new DomainException("AcademicServiceRequest.has.missing.personal.info");
}
}
protected void createAcademicServiceRequestSituations(final AcademicServiceRequestBean academicServiceRequestBean) {
AcademicServiceRequestSituation.create(this, academicServiceRequestBean);
}
public boolean isPiggyBackedOnRegistry() {
return false;
}
final public boolean isNewRequest() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.NEW;
}
final public boolean isProcessing() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.PROCESSING;
}
final public boolean hasProcessed() {
return getSituationByType(AcademicServiceRequestSituationType.PROCESSING) != null;
}
final public boolean isSentToExternalEntity() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.SENT_TO_EXTERNAL_ENTITY;
}
final public boolean isReceivedFromExternalEntity() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.RECEIVED_FROM_EXTERNAL_ENTITY;
}
final public boolean isConcluded() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.CONCLUDED;
}
final public boolean hasConcluded() {
return getSituationByType(AcademicServiceRequestSituationType.CONCLUDED) != null;
}
final public boolean isDelivered() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.DELIVERED;
}
final public boolean isRejected() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.REJECTED;
}
final public boolean isCancelled() {
return getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.CANCELLED;
}
final public boolean isHistorical() {
return isDelivered() || isRejected() || isCancelled();
}
final public boolean isEditable() {
return !(isRejected() || isCancelled() || isDelivered());
}
final public boolean finishedSuccessfully() {
return isConcluded() || isDelivered();
}
final public boolean finishedUnsuccessfully() {
return isRejected() || isCancelled();
}
final public boolean isDocumentRequest() {
return this instanceof DocumentRequest;
}
/**
* Indicates if is possible to print document again
*/
abstract public boolean isToPrint();
/**
* Indicates if is possible to AdministrativeOffice send this request to
* another entity
*/
abstract public boolean isPossibleToSendToOtherEntity();
/**
* Indicates that the document external shipping to rectorate is done using
* the rectorate batches. The {@link AcademicServiceRequestSituationType#SENT_TO_EXTERNAL_ENTITY} and
* {@link AcademicServiceRequestSituationType#RECEIVED_FROM_EXTERNAL_ENTITY} states are handled through this system.
*
* @return true if managed by batch, false otherwise.
*/
abstract public boolean isManagedWithRectorateSubmissionBatch();
/**
* Special condition for pre-existing documents that are able to consume a
* registry number.
*/
public boolean isCanGenerateRegistryCode() {
return false;
}
final public boolean createdByStudent() {
return getSituationByType(AcademicServiceRequestSituationType.NEW).getCreator() == null;
}
/**
* See if this can be avoided.
*/
@Deprecated
final public boolean getLoggedPersonCanCancel() {
return isCancelledSituationAccepted()
&& (!isPayable() || getEvent() == null || !isPayed())
&& (createdByStudent() && !isConcluded() || AcademicAccessRule.isProgramAccessibleToFunction(
AcademicOperationType.SERVICE_REQUESTS, this.getAcademicProgram(), Authenticate.getUser()));
}
final public DateTime getCreationDate() {
return getSituationByType(AcademicServiceRequestSituationType.NEW).getCreationDate();
}
final public DateTime getProcessingDate() {
AcademicServiceRequestSituation state = getSituationByType(AcademicServiceRequestSituationType.PROCESSING);
return state != null ? state.getCreationDate() : null;
}
final public DateTime getRequestConclusionDate() {
AcademicServiceRequestSituation conclusionSituation = getConclusionSituation();
return conclusionSituation != null ? conclusionSituation.getCreationDate() : null;
}
public boolean isRequestForPerson() {
return false;
}
public boolean isRequestForPhd() {
return false;
}
public boolean isRequestForRegistration() {
return false;
}
public boolean isFor(final ExecutionYear executionYear) {
return getExecutionYear() != null && getExecutionYear().equals(executionYear);
}
abstract public Person getPerson();
abstract public EventType getEventType();
abstract public AcademicServiceRequestType getAcademicServiceRequestType();
/**
* Indicates if the service result needs personal info
*/
abstract public boolean hasPersonalInfo();
protected boolean hasMissingPersonalInfo() {
return Strings.isNullOrEmpty(getPerson().getParishOfBirth()) || Strings.isNullOrEmpty(getPerson().getDistrictOfBirth());
}
public void revertToProcessingState() {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cannot.revert.to.processing.state");
}
protected void internalRevertToProcessingState() {
AcademicServiceRequestSituation activeSituation = getActiveSituation();
if (activeSituation == null || activeSituation.isProcessing() || activeSituation.isNew()) {
throw new DomainException(
"error.serviceRequests.AcademicServiceRequest.revert.to.processing.in.only.possibile.from.later.states");
} else if (activeSituation.isCancelled()) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.cancelled.requests.cannot.be.reverted");
}
if (getAcademicServiceRequestSituationsSet().size() <= 1) {
throw new DomainException("error.serviceRequests.AcademicServiceRequest.revert.is.requires.more.than.one.state");
}
while (getAcademicServiceRequestSituationsSet().size() > 1 && !activeSituation.isProcessing()) {
activeSituation.delete(false);
activeSituation = getActiveSituation();
}
}
public boolean isDiploma() {
return false;
}
public boolean isPastDiploma() {
return false;
}
public boolean isRegistryDiploma() {
return false;
}
public boolean isDiplomaSupplement() {
return false;
}
public GeneratedDocument getLastGeneratedDocument() {
DateTime last = null;
GeneratedDocument lastDoc = null;
for (GeneratedDocument document : getDocumentSet()) {
if (last == null || document.getCreationDate().isAfter(last)) {
last = document.getCreationDate();
lastDoc = document;
}
}
return lastDoc;
}
public boolean isBatchSet() {
return getRectorateSubmissionBatch() != null;
}
public abstract AcademicProgram getAcademicProgram();
public boolean hasExecutionYear() {
return getExecutionYear() != null;
}
public boolean hasRegistryCode() {
return getRegistryCode() != null;
}
public static Set<AcademicServiceRequest> getAcademicServiceRequests(Person person, Integer year,
AcademicServiceRequestSituationType situation, Interval interval) {
Set<AcademicServiceRequest> serviceRequests = new HashSet<AcademicServiceRequest>();
Set<AcademicProgram> programs =
AcademicAccessRule.getProgramsAccessibleToFunction(AcademicOperationType.SERVICE_REQUESTS, person.getUser())
.collect(Collectors.toSet());
Collection<AcademicServiceRequest> possible = null;
if (year != null) {
possible = AcademicServiceRequestYear.getAcademicServiceRequests(year);
} else {
possible = Bennu.getInstance().getAcademicServiceRequestsSet();
}
for (AcademicServiceRequest request : possible) {
if (!programs.contains(request.getAcademicProgram())) {
continue;
}
if (situation != null && !request.getAcademicServiceRequestSituationType().equals(situation)) {
continue;
}
if (interval != null && !interval.contains(request.getActiveSituationDate())) {
continue;
}
serviceRequests.add(request);
}
return serviceRequests;
}
}