/* * @(#)WorkingCapitalInitialization.java * * Copyright 2010 Instituto Superior Tecnico * Founding Authors: Luis Cruz * * https://fenix-ashes.ist.utl.pt/ * * This file is part of the Working Capital Module. * * The Working Capital Module 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. * * The Working Capital Module 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 the Working Capital Module. If not, see <http://www.gnu.org/licenses/>. * */ package module.workingCapital.domain; import java.util.Calendar; import java.util.Collection; import java.util.Comparator; import java.util.HashSet; import java.util.Set; import module.finance.util.Money; import module.organization.domain.Accountability; import module.organization.domain.Person; import module.workingCapital.util.Bundle; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.security.Authenticate; import org.joda.time.DateTime; import pt.ist.expenditureTrackingSystem.domain.authorizations.Authorization; import pt.ist.expenditureTrackingSystem.domain.organization.AccountingUnit; import pt.ist.expenditureTrackingSystem.domain.organization.Unit; import pt.ist.expenditureTrackingSystem.domain.util.DomainException; /** * * @author João Neves * @author Luis Cruz * */ public class WorkingCapitalInitialization extends WorkingCapitalInitialization_Base { public static enum WorkingCapitalInitializationState { ACTIVE, CANCELED, REJECTED; } public static final Comparator<WorkingCapitalInitialization> COMPARATOR_BY_REQUEST_CREATION = new Comparator<WorkingCapitalInitialization>() { @Override public int compare(final WorkingCapitalInitialization o1, final WorkingCapitalInitialization o2) { final int c = o1.getRequestCreation().compareTo(o2.getRequestCreation()); return c == 0 ? o2.hashCode() - o1.hashCode() : c; } }; public WorkingCapitalInitialization() { super(); setWorkingCapitalSystem(WorkingCapitalSystem.getInstanceForCurrentHost()); final Person person = Authenticate.getUser().getPerson(); if (person == null) { throw new DomainException(Bundle.WORKING_CAPITAL, "message.working.capital.requestor.cannot.be.null"); } setRequestor(person); setRequestCreation(new DateTime()); } public WorkingCapitalInitialization(final Integer year, final Unit unit, final Person person, final Money requestedAnualValue, final String fiscalId, final String internationalBankAccountNumber) { this(); if (hasAnotherOpenWorkingCapital(unit)) { throw new DomainException(Bundle.WORKING_CAPITAL, "message.open.working.capital.exists.for.unit"); } if (isRequestorOfAnotherOpenWorkingCapitalFromPreviousYears()) { throw new DomainException(Bundle.WORKING_CAPITAL, "message.requestor.of.open.working.capital.from.previous.years"); } if (isMovementResponsibleOfAnotherOpenWorkingCapitalFromPreviousYears(person)) { throw new DomainException(Bundle.WORKING_CAPITAL, "message.movement.responsible.of.open.working.capital.from.previous.years", person.getUser().getProfile() .getFullName()); } pt.ist.expenditureTrackingSystem.domain.organization.Person responsible = getDirectUnitResponsibleOfAnotherOpenWorkingCapitalFromPreviousYears(unit); if (responsible != null) { throw new DomainException(Bundle.WORKING_CAPITAL, "message.unit.responsible.of.open.working.capital.from.previous.years", responsible.getUser().getProfile() .getFullName()); } WorkingCapital workingCapital = WorkingCapital.find(year, unit); if (workingCapital == null) { workingCapital = new WorkingCapital(year, unit, person); } setWorkingCapital(workingCapital); setRequestedAnualValue(requestedAnualValue); setFiscalId(fiscalId); setInternationalBankAccountNumber(internationalBankAccountNumber); } private boolean hasAnotherOpenWorkingCapital(Unit unit) { for (WorkingCapital workingCapital : unit.getWorkingCapitalsSet()) { WorkingCapitalInitialization initialization = workingCapital.getWorkingCapitalInitialization(); if (initialization == null) { continue; } if (initialization == this) { continue; } if (initialization.isOpen()) { return true; } } return false; } private boolean isRequestorOfAnotherOpenWorkingCapitalFromPreviousYears() { for (WorkingCapitalInitialization initialization : Authenticate.getUser().getPerson() .getRequestedWorkingCapitalInitializationsSet()) { if (initialization == this) { continue; } if (initialization.getWorkingCapital().getWorkingCapitalYear().getYear() .equals(Integer.valueOf(Calendar.getInstance().get(Calendar.YEAR)))) { continue; } if (initialization.isOpen()) { return true; } } return false; } private boolean isMovementResponsibleOfAnotherOpenWorkingCapitalFromPreviousYears(Person person) { for (WorkingCapital workingCapital : person.getMovementResponsibleWorkingCapitalsSet()) { if (workingCapital == getWorkingCapital()) { continue; } WorkingCapitalInitialization initialization = workingCapital.getWorkingCapitalInitialization(); if (initialization == null) { continue; } if (initialization.getWorkingCapital().getWorkingCapitalYear().getYear() .equals(Integer.valueOf(Calendar.getInstance().get(Calendar.YEAR)))) { continue; } if (initialization.isOpen()) { return true; } } return false; } private pt.ist.expenditureTrackingSystem.domain.organization.Person getDirectUnitResponsibleOfAnotherOpenWorkingCapitalFromPreviousYears( Unit unit) { for (pt.ist.expenditureTrackingSystem.domain.organization.Person responsible : getUnitResponsibles(unit)) { if (isDirectUnitResponsibleOfAnotherOpenWorkingCapitalFromPreviousYears(responsible)) { return responsible; } } return null; } private static Collection<pt.ist.expenditureTrackingSystem.domain.organization.Person> getUnitResponsibles(Unit unit) { Set<pt.ist.expenditureTrackingSystem.domain.organization.Person> responsibles = new HashSet<pt.ist.expenditureTrackingSystem.domain.organization.Person>(); for (Authorization authorization : unit.getAuthorizationsSet()) { if (authorization.isValid()) { responsibles.add(authorization.getPerson()); } } return responsibles; } private boolean isDirectUnitResponsibleOfAnotherOpenWorkingCapitalFromPreviousYears( pt.ist.expenditureTrackingSystem.domain.organization.Person responsible) { for (Unit unit : getResponsibleUnits(responsible)) { if (hasAnotherOpenWorkingCapitalFromPreviousYears(unit)) { return true; } } return false; } private static Collection<Unit> getResponsibleUnits(pt.ist.expenditureTrackingSystem.domain.organization.Person responsible) { Set<Unit> responsibleUnits = new HashSet<Unit>(); for (Authorization authorization : responsible.getAuthorizationsSet()) { if (authorization.isValid()) { responsibleUnits.add(authorization.getUnit()); } } return responsibleUnits; } private boolean hasAnotherOpenWorkingCapitalFromPreviousYears(Unit unit) { for (WorkingCapital workingCapital : unit.getWorkingCapitalsSet()) { WorkingCapitalInitialization initialization = workingCapital.getWorkingCapitalInitialization(); if (initialization == null) { continue; } if (initialization.getWorkingCapital().getWorkingCapitalYear().getYear() .equals(Integer.valueOf(Calendar.getInstance().get(Calendar.YEAR)))) { continue; } if (initialization == this) { continue; } if (initialization.isOpen()) { return true; } } return false; } public boolean isOpen() { return !isCanceledOrRejected() && !getWorkingCapital().isRefunded(); } public void approve(final Person person) { final WorkingCapital workingCapital = getWorkingCapital(); final Money valueForAuthorization = Money.ZERO; final Authorization authorization = workingCapital.findUnitResponsible(person, valueForAuthorization); if (authorization == null) { throw new DomainException("person.cannot.approve.expense", person.getUser().getProfile().getFullName()); } setAprovalByUnitResponsible(new DateTime()); setResponsibleForUnitApproval(authorization); } public void unapprove() { setAprovalByUnitResponsible(null); setResponsibleForUnitApproval(null); } public void verify(final User user, final Money authorizedAnualValue, final Money maxAuthorizedAnualValue, final String fundAllocationId) { setAuthorizedAnualValue(authorizedAnualValue); setMaxAuthorizedAnualValue(maxAuthorizedAnualValue); if (!isAccountingResponsible(user)) { throw new DomainException("person.cannot.verify.expense", user.getPerson().getName()); } setVerificationByAccounting(new DateTime()); setResponsibleForAccountingVerification(user.getPerson()); allocateFunds(fundAllocationId); } public void allocateFunds(final String fundAllocationId) { final String value = fundAllocationId != null && !fundAllocationId.isEmpty() ? fundAllocationId : null; setFundAllocationId(value); } private boolean isAccountingResponsible(final User user) { return getWorkingCapital().isAccountingResponsible(user); } public void unverify() { setVerificationByAccounting(new DateTime()); setResponsibleForAccountingVerification(null); setAuthorizedAnualValue(null); setMaxAuthorizedAnualValue(null); setFundAllocationId(null); } public void unverifyCentral() { setVerificationByCentral(null); setResponsibleForCentralVerification(null); } public void verifyCentral(User user) { setVerificationByCentral(new DateTime()); setResponsibleForCentralVerification(user.getPerson()); } public void authorize(final User user) { final WorkingCapitalSystem workingCapitalSystem = WorkingCapitalSystem.getInstanceForCurrentHost(); final Accountability accountability = workingCapitalSystem.getManagementAccountability(user); if (accountability == null) { throw new DomainException("person.cannot.authorize.expense", user.getPerson().getName()); } setAuthorizationByUnitResponsible(new DateTime()); setResponsibleForUnitAuthorization(accountability); } public void unauthorize() { setAuthorizationByUnitResponsible(new DateTime()); setResponsibleForUnitAuthorization(null); } public boolean isPendingAproval(User user) { if (getAcceptedResponsability() != null && !hasResponsibleForUnitApproval()) { //final Money valueForAuthorization = getRequestedAnualValue(); final Money valueForAuthorization = Money.ZERO; final Authorization authorization = getWorkingCapital().findUnitResponsible(user.getPerson(), valueForAuthorization); if (authorization != null) { return true; } } return false; } public boolean isPendingDirectAproval(User user) { if (getAcceptedResponsability() != null && !hasResponsibleForUnitApproval()) { //final Money valueForAuthorization = getRequestedAnualValue(); final Money valueForAuthorization = Money.ZERO; final Authorization authorization = getWorkingCapital().findDirectUnitResponsible(user.getPerson(), valueForAuthorization); if (authorization != null) { return true; } } return false; } public boolean isPendingAproval() { return !hasResponsibleForUnitApproval(); } public boolean isPendingVerification() { return hasResponsibleForUnitApproval() && !hasResponsibleForAccountingVerification(); } public boolean isPendingCentralVerification() { return getResponsibleForAccountingVerification() != null && getResponsibleForCentralVerification() == null && getFundAllocationId() != null && !getFundAllocationId().isEmpty() && !hasResponsibleForUnitAuthorization(); } public boolean isPendingAuthorization() { return getResponsibleForAccountingVerification() != null && getResponsibleForCentralVerification() != null && getFundAllocationId() != null && !getFundAllocationId().isEmpty() && !hasResponsibleForUnitAuthorization(); } public boolean isAuthorized() { return hasResponsibleForUnitAuthorization(); } public void cancel() { setState(WorkingCapitalInitializationState.CANCELED); } public void reject() { setState(WorkingCapitalInitializationState.REJECTED); } public boolean isCanceledOrRejected() { final WorkingCapitalInitializationState state = getState(); return state == WorkingCapitalInitializationState.CANCELED || state == WorkingCapitalInitializationState.REJECTED; } @Override public AccountingUnit getAccountingUnit() { final AccountingUnit accountingUnit = super.getAccountingUnit(); return accountingUnit == null ? (hasWorkingCapital() ? getWorkingCapital().getUnit().getAccountingUnit() : null) : accountingUnit; } public boolean isPendingFundAllocation() { return !isCanceledOrRejected() && (getFundAllocationId() == null || getFundAllocationId().isEmpty()) && hasResponsibleForAccountingVerification() && !hasResponsibleForUnitAuthorization(); } public boolean isPendingFundUnAllocation() { return (isCanceledOrRejected() && (getFundAllocationId() != null) && (!getFundAllocationId().isEmpty())); } public void delete() { setWorkingCapital(null); setWorkingCapitalSystem(null); setRequestor(null); setAccountingUnit(null); deleteDomainObject(); } @Deprecated public boolean hasRequestCreation() { return getRequestCreation() != null; } @Deprecated public boolean hasRequestedAnualValue() { return getRequestedAnualValue() != null; } @Deprecated public boolean hasAuthorizedAnualValue() { return getAuthorizedAnualValue() != null; } @Deprecated public boolean hasMaxAuthorizedAnualValue() { return getMaxAuthorizedAnualValue() != null; } @Deprecated public boolean hasFiscalId() { return getFiscalId() != null; } @Deprecated public boolean hasInternationalBankAccountNumber() { return getInternationalBankAccountNumber() != null; } @Deprecated public boolean hasAprovalByUnitResponsible() { return getAprovalByUnitResponsible() != null; } @Deprecated public boolean hasAuthorizationByUnitResponsible() { return getAuthorizationByUnitResponsible() != null; } @Deprecated public boolean hasVerificationByAccounting() { return getVerificationByAccounting() != null; } @Deprecated public boolean hasState() { return getState() != null; } @Deprecated public boolean hasLastSubmission() { return getLastSubmission() != null; } @Deprecated public boolean hasRefundRequested() { return getRefundRequested() != null; } @Deprecated public boolean hasAcceptedResponsability() { return getAcceptedResponsability() != null; } @Deprecated public boolean hasFundAllocationId() { return getFundAllocationId() != null; } @Deprecated public boolean hasWorkingCapital() { return getWorkingCapital() != null; } @Deprecated public boolean hasResponsibleForAccountingVerification() { return getResponsibleForAccountingVerification() != null; } @Deprecated public boolean hasWorkingCapitalSystem() { return getWorkingCapitalSystem() != null; } @Deprecated public boolean hasRequestor() { return getRequestor() != null; } @Deprecated public boolean hasResponsibleForUnitAuthorization() { return getResponsibleForUnitAuthorization() != null; } @Deprecated public boolean hasResponsibleForUnitApproval() { return getResponsibleForUnitApproval() != null; } @Deprecated public boolean hasAccountingUnit() { return getAccountingUnit() != null; } }