/** * 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.accounting; import java.util.Comparator; import org.apache.commons.lang.StringUtils; import org.fenixedu.academic.FenixEduAcademicConfiguration; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.accounting.util.PaymentCodeGenerator; import org.fenixedu.academic.domain.accounting.util.PaymentCodeGeneratorFactory; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.util.Bundle; import org.fenixedu.academic.util.Money; import org.fenixedu.bennu.core.domain.Bennu; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.joda.time.DateTime; import org.joda.time.YearMonthDay; import pt.ist.fenixframework.Atomic; public abstract class PaymentCode extends PaymentCode_Base { public static final String SIBS_IGNORE_MAX_AMOUNT = "99999999.99"; public static Comparator<PaymentCode> COMPARATOR_BY_CODE = new Comparator<PaymentCode>() { @Override public int compare(PaymentCode leftPaymentCode, PaymentCode rightPaymentCode) { int comparationResult = leftPaymentCode.getCode().compareTo(rightPaymentCode.getCode()); if (comparationResult == 0) { throw new DomainException("error.accounting.PaymentCode.data.is.corrupted.because.found.duplicate.codes"); } return comparationResult; } }; public static Comparator<PaymentCode> COMPARATOR_BY_END_DATE = new Comparator<PaymentCode>() { @Override public int compare(PaymentCode leftPaymentCode, PaymentCode rightPaymentCode) { int comparationResult = leftPaymentCode.getEndDate().compareTo(rightPaymentCode.getEndDate()); return (comparationResult == 0) ? leftPaymentCode.getExternalId().compareTo(rightPaymentCode.getExternalId()) : comparationResult; } }; protected PaymentCode() { super(); super.setRootDomainObject(Bennu.getInstance()); super.setWhenCreated(new DateTime()); super.setWhenUpdated(new DateTime()); super.setState(PaymentCodeState.NEW); super.setEntityCode(FenixEduAcademicConfiguration.getConfiguration().getSibsEntityCode()); } protected void init(final PaymentCodeType paymentCodeType, final YearMonthDay startDate, final YearMonthDay endDate, final Money minAmount, final Money maxAmount, final Person person) { checkParameters(paymentCodeType, startDate, endDate, minAmount, maxAmount, person); super.setCode(getPaymentCodeGenerator(paymentCodeType).generateNewCodeFor(paymentCodeType, person)); super.setType(paymentCodeType); super.setStartDate(startDate); super.setEndDate(endDate); super.setMinAmount(minAmount); super.setMaxAmount(maxAmount != null ? maxAmount : new Money(SIBS_IGNORE_MAX_AMOUNT)); super.setPerson(person); } private void checkParameters(PaymentCodeType paymentCodeType, YearMonthDay startDate, YearMonthDay endDate, Money minAmount, Money maxAmount, final Person person) { if (paymentCodeType == null) { throw new DomainException("error.accounting.PaymentCode.paymentCodeType.cannot.be.null"); } checkParameters(startDate, endDate, minAmount, maxAmount); } private void checkParameters(YearMonthDay startDate, YearMonthDay endDate, Money minAmount, Money maxAmount) { if (startDate == null) { throw new DomainException("error.accounting.PaymentCode.startDate.cannot.be.null"); } if (endDate == null) { throw new DomainException("error.accounting.PaymentCode.endDate.cannot.be.null"); } if (minAmount == null) { throw new DomainException("error.accounting.PaymentCode.minAmount.cannot.be.null"); } } public String getFormattedCode() { final StringBuilder result = new StringBuilder(); int i = 1; for (char character : getCode().toCharArray()) { result.append(character); if (i % 3 == 0) { result.append(" "); } i++; } return result.charAt(result.length() - 1) == ' ' ? result.deleteCharAt(result.length() - 1).toString() : result .toString(); } @Override public void setWhenCreated(DateTime whenCreated) { throw new DomainException("error.accounting.PaymentCode.cannot.modify.whenCreated"); } @Override public void setCode(String code) { throw new DomainException("error.accounting.PaymentCode.cannot.modify.code"); } @Override public void setStartDate(YearMonthDay startDate) { throw new DomainException("error.org.fenixedu.academic.domain.accounting.PaymentCode.cannot.modify.startDate"); } @Override public void setEndDate(YearMonthDay endDate) { throw new DomainException("error.org.fenixedu.academic.domain.accounting.PaymentCode.cannot.modify.endDate"); } @Override public void setMinAmount(Money minAmount) { throw new DomainException("error.org.fenixedu.academic.domain.accounting.PaymentCode.cannot.modify.minAmount"); } @Override public void setMaxAmount(Money maxAmount) { throw new DomainException("error.org.fenixedu.academic.domain.accounting.PaymentCode.cannot.modify.maxAmount"); } @Override public void setWhenUpdated(DateTime whenUpdated) { throw new DomainException("error.accounting.PaymentCode.cannot.modify.whenUpdated"); } @Override @Atomic public void setState(PaymentCodeState state) { super.setWhenUpdated(new DateTime()); super.setState(state); } @Override public void setEntityCode(String entityCode) { throw new DomainException("error.accounting.PaymentCode.cannot.modify.entityCode"); } public boolean isNew() { return getState() == PaymentCodeState.NEW; } protected void reuseCode() { setState(PaymentCodeState.NEW); } public boolean isProcessed() { return getState() == PaymentCodeState.PROCESSED; } public boolean isCancelled() { return getState() == PaymentCodeState.CANCELLED; } public boolean isInvalid() { return getState() == PaymentCodeState.INVALID; } public void cancel() { setState(PaymentCodeState.CANCELLED); } public boolean isAvailableForReuse() { return !isNew(); } public void update(final YearMonthDay startDate, final YearMonthDay endDate, final Money minAmount, final Money maxAmount) { checkParameters(startDate, endDate, maxAmount, maxAmount); super.setStartDate(startDate); super.setEndDate(endDate); super.setMinAmount(minAmount); super.setMaxAmount(maxAmount != null ? maxAmount : new Money(SIBS_IGNORE_MAX_AMOUNT)); super.setWhenUpdated(new DateTime()); } @Atomic public void process(Person responsiblePerson, Money amount, DateTime whenRegistered, String sibsTransactionId, String comments) { if (isProcessed()) { return; } if (isInvalid()) { throw new DomainException("error.accounting.PaymentCode.cannot.process.invalid.codes"); } internalProcess(responsiblePerson, amount, whenRegistered, sibsTransactionId, comments); if (!getType().isReusable()) { setState(PaymentCodeState.PROCESSED); } } public void delete() { super.setPerson(null); for (PaymentCodeMapping mapping : getOldPaymentCodeMappingsSet()) { mapping.delete(); } for (PaymentCodeMapping mapping : getNewPaymentCodeMappingsSet()) { removeNewPaymentCodeMappings(mapping); } setStudentCandidacy(null); setRootDomainObject(null); deleteDomainObject(); } public String getDescription() { return BundleUtil.getString(Bundle.ENUMERATION, getType().getQualifiedName()); } abstract protected void internalProcess(final Person person, final Money amount, final DateTime whenRegistered, final String sibsTransactionId, final String comments); public PaymentCodeMapping getOldPaymentCodeMapping(final ExecutionYear executionYear) { for (final PaymentCodeMapping mapping : getOldPaymentCodeMappingsSet()) { if (mapping.has(executionYear)) { return mapping; } } return null; } protected static PaymentCodeGenerator getPaymentCodeGenerator(PaymentCodeType paymentCodeType) { return PaymentCodeGeneratorFactory.getGenerator(paymentCodeType); } static public PaymentCode readByCode(final String code) { if (StringUtils.isEmpty(code)) { return null; } for (final PaymentCode paymentCode : Bennu.getInstance().getPaymentCodesSet()) { if (paymentCode.getCode().equals(code)) { return paymentCode; } } return null; } public static boolean canGenerateNewCode(Class<? extends PaymentCode> paymentCodeClass, PaymentCodeType paymentCodeType, final Person person) { return getPaymentCodeGenerator(paymentCodeType).canGenerateNewCode(paymentCodeType, person); } public boolean isInstallmentPaymentCode() { return false; } public boolean isAccountingEventPaymentCode() { return false; } public boolean isForRectorate() { return false; } }