/* * @(#)MissionFinancer.java * * Copyright 2010 Instituto Superior Tecnico * Founding Authors: Luis Cruz, Nuno Ochoa, Paulo Abrantes * * https://fenix-ashes.ist.utl.pt/ * * This file is part of the Expenditure Tracking Module. * * The Expenditure Tracking 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 Expenditure Tracking 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 Expenditure Tracking Module. If not, see <http://www.gnu.org/licenses/>. * */ package module.mission.domain; import java.util.Set; import module.finance.util.Money; import module.organization.domain.Person; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.security.Authenticate; import pt.ist.expenditureTrackingSystem._development.Bundle; import pt.ist.expenditureTrackingSystem.domain.authorizations.Authorization; import pt.ist.expenditureTrackingSystem.domain.organization.AccountingUnit; import pt.ist.expenditureTrackingSystem.domain.organization.Project; import pt.ist.expenditureTrackingSystem.domain.organization.SubProject; import pt.ist.expenditureTrackingSystem.domain.organization.Unit; import pt.ist.expenditureTrackingSystem.domain.util.DomainException; /** * * @author Luis Cruz * */ public class MissionFinancer extends MissionFinancer_Base { public MissionFinancer() { super(); setMissionSystem(MissionSystem.getInstance()); } public MissionFinancer(final Mission mission, final Unit unit) { this(mission.getMissionVersion(), unit); } public MissionFinancer(final MissionVersion missionVersion, final Unit unit) { this(); checkUnitIsActive(unit); setMissionVersion(missionVersion); setUnit(unit); } private void checkUnitIsActive(final Unit unit) { if (!unit.isActive()) { throw new DomainException(Bundle.MISSION, "error.mission.financer.closed"); } } public void delete() { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { missionItemFinancer.delete(); } setMissionVersion(null); setUnit(null); setMissionSystem(null); setAccountingUnit(null); deleteDomainObject(); } public Money getAmount() { Money result = Money.ZERO; for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { final Money amount = missionItemFinancer.getAmount(); if (amount != null) { result = result.add(amount); } } return result; } public boolean isPendingApprovalBy(final User user) { return !hasApproval() && canApprove(user); } public boolean isPendingAuthorizationBy(final User user) { return !hasAuthorization() && canAuthorize(user); } public boolean isPendingDirectAuthorizationBy(final User user) { return !hasAuthorization() && canAuthorizeDirect(user); } public boolean isPendingCheckByUnderlings(final User user) { final Unit unit = getUnit(); return isPendingCheckByUnderlings(user, unit); } private boolean isPendingCheckByUnderlings(final User user, final Unit unit) { if (unit == null) { return false; } final Set<Unit> checked = getCheckedUnitSet(); if (!checked.contains(unit)) { for (final Authorization authorization : unit.getAuthorizationsSet()) { if (authorization.isValid() && authorization.getMaxAmount().isGreaterThanOrEqual(getAmount())) { return false; } } for (final Authorization authorization : unit.getAuthorizationsSet()) { if (authorization.isValid() && authorization.getPerson() == user.getExpenditurePerson()) { return true; } } } return isPendingCheckByUnderlings(user, unit.getParentUnit()); } public boolean canApprove(final User user) { final Unit unit = getUnit(); return unit.isResponsible(user.getExpenditurePerson()); } public boolean canAuthorize(final User user) { final Unit unit = getUnit(); return unit.isResponsible(user.getExpenditurePerson(), getAmount()); } public boolean canAuthorizeDirect(final User user) { final Unit unit = getUnit(); return unit.isMostDirectAuthorization(user.getExpenditurePerson(), getAmount()); } public void approve(final User user) { if (!hasApproval()) { final Authorization authorization = findAuthorizationForApproval(user); if (authorization != null) { setApproval(authorization); } } } public void authorize(final User user) { if (!hasAuthorization()) { final Authorization authorization = findAuthorizationForAuthorization(user); if (authorization != null) { setAuthorization(authorization); } } } public void preAuthorize(final User user) { if (!hasAuthorization()) { final Authorization authorization = findAuthorizationForApproval(user); if (authorization != null) { markCheckedUnits(authorization, getUnit()); } } } private void markCheckedUnits(final Authorization authorization, final Unit unit) { if (unit != null) { getCheckedUnitSet().add(unit); if (authorization.getUnit() != unit) { markCheckedUnits(authorization, unit.getParentUnit()); } } } private Authorization findAuthorizationForApproval(final User user) { return findAuthorization(user, Money.ZERO); } private Authorization findAuthorizationForAuthorization(final User user) { return findAuthorization(user, getAmount()); } private Authorization findAuthorization(final User user, final Money amount) { final Unit unit = getUnit(); return unit.findClosestAuthorization(user.getExpenditurePerson(), amount); } public void unapprove(final User user) { if (hasApproval() && canApprove(user)) { setApproval(null); } } public void unauthorize(final User user) { if (hasAuthorization() && canAuthorize(user)) { setAuthorization(null); } } public void unPreAuthorize(final User user) { final Authorization authorization = findAuthorizationForApproval(user); if (authorization != null) { unMarkCheckedUnits(authorization, getUnit()); } } private void unMarkCheckedUnits(final Authorization authorization, final Unit unit) { if (unit != null) { getCheckedUnitSet().remove(unit); if (authorization.getUnit() != unit) { unMarkCheckedUnits(authorization, unit.getParentUnit()); } } } public boolean canRemoveApproval(final User user) { return !hasAnyAllocatedFunds() && hasApproval() && canApprove(user); } public boolean canRemoveAuthorization(final User user) { return hasAuthorization() && canAuthorize(user); } public boolean canRemovePreAuthorization(final User user) { return !hasAuthorization() && findAuthorizationForApproval(user) != null; } public boolean hasAllAllocatedFunds() { if (!hasAnyMissionItemFinancers()) { return false; } for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { final MissionItem missionItem = missionItemFinancer.getMissionItem(); if (missionItem.requiresFundAllocation()) { final Money amount = missionItemFinancer.getAmount(); if (amount != null && amount.isPositive() && missionItemFinancer.getFundAllocationId() == null) { return false; } } } return true; } public boolean hasAnyAllocatedFunds() { if (!hasAnyMissionItemFinancers()) { return false; } for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { final MissionItem missionItem = missionItemFinancer.getMissionItem(); if (missionItem.requiresFundAllocation()) { final Money amount = missionItemFinancer.getAmount(); if (amount != null && amount.isPositive() && missionItemFinancer.getFundAllocationId() != null && !missionItemFinancer.getFundAllocationId().isEmpty()) { return true; } } } return false; } public boolean hasAllAllocatedProjectFunds() { if (!hasAnyMissionItemProjectFinancers()) { return false; } for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { final MissionItemProjectFinancer missionItemProjectFinancer = (MissionItemProjectFinancer) missionItemFinancer; final Money amount = missionItemProjectFinancer.getAmount(); if (amount != null && amount.isPositive() && missionItemProjectFinancer.getProjectFundAllocationId() == null) { return false; } } } return true; } public boolean hasAnyAllocatedProjectFunds() { if (!hasAnyMissionItemProjectFinancers()) { return false; } for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { final MissionItemProjectFinancer missionItemProjectFinancer = (MissionItemProjectFinancer) missionItemFinancer; final Money amount = missionItemProjectFinancer.getAmount(); if (amount != null && amount.isPositive() && missionItemProjectFinancer.getProjectFundAllocationId() != null) { return true; } } } return false; } public boolean hasAnyMissionItemProjectFinancers() { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { return true; } } return false; } public boolean canAllocateFunds(final Person person) { return person != null && hasAccountingUnit() && getAccountingUnit().getPeopleSet().contains(person.getUser().getExpenditurePerson()); } public boolean isAccountManager(final Person person) { final Unit unit = getUnit(); if (!unit.hasSomeAccountManager()) { return true; } else if (person == null) { return false; } else { return unit.isAccountManager(person.getUser().getExpenditurePerson()); } } public boolean canAllocateProjectFunds(final Person person) { return person != null && hasAccountingUnit() && getAccountingUnit().getProjectAccountantsSet().contains(person.getUser().getExpenditurePerson()) && hasPendingProjectFundAllocations(); } public boolean isDirectResponsibleForPendingProjectFundAllocation(final Person person) { return canAllocateProjectFunds(person) && isAccountManager(person); } private boolean hasPendingProjectFundAllocations() { final Mission mission = getMissionVersion().getMission(); final MissionProcess missionProcess = mission.getMissionProcess(); if (missionProcess.isCanceled()) { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { final MissionItemProjectFinancer missionItemProjectFinancer = (MissionItemProjectFinancer) missionItemFinancer; final String allocationId = missionItemProjectFinancer.getProjectFundAllocationId(); if (allocationId != null && !allocationId.isEmpty()) { return true; } } } return false; } else { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { final MissionItemProjectFinancer missionItemProjectFinancer = (MissionItemProjectFinancer) missionItemFinancer; final String allocationId = missionItemProjectFinancer.getProjectFundAllocationId(); if (allocationId == null || allocationId.isEmpty()) { return true; } } } return false; } } public void unAllocateFunds(final Person person) { if (canAllocateFunds(person)) { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { missionItemFinancer.setFundAllocationId(null); } } } public String getFundAllocationId() { final StringBuilder stringBuilder = new StringBuilder(); for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { final String fundAllocationId = missionItemFinancer.getFundAllocationId(); if (fundAllocationId != null) { if (stringBuilder.length() > 0) { stringBuilder.append(", "); } stringBuilder.append(fundAllocationId); } } return stringBuilder.toString(); } public String getProjectFundAllocationId() { final StringBuilder stringBuilder = new StringBuilder(); for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { final MissionItemProjectFinancer missionItemProjectFinancer = (MissionItemProjectFinancer) missionItemFinancer; final String projectFundAllocationId = missionItemProjectFinancer.getProjectFundAllocationId(); if (projectFundAllocationId != null) { if (stringBuilder.length() > 0) { stringBuilder.append(", "); } stringBuilder.append(missionItemProjectFinancer.getProjectFundAllocationId()); } } } return stringBuilder.toString(); } public void unAllocateProjectFunds(Person person) { if (getAccountingUnit().getProjectAccountantsSet().contains(person.getUser().getExpenditurePerson())) { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { if (missionItemFinancer instanceof MissionItemProjectFinancer) { final MissionItemProjectFinancer missionItemProjectFinancer = (MissionItemProjectFinancer) missionItemFinancer; missionItemProjectFinancer.setProjectFundAllocationId(null); } } } } public boolean isProjectFinancer() { final Unit unit = getUnit(); return unit instanceof Project || unit instanceof SubProject; } public boolean isAuthorized() { return hasAuthorization(); } public void clearFundAllocations() { for (final MissionItemFinancer missionItemFinancer : getMissionItemFinancersSet()) { missionItemFinancer.clearFundAllocations(); } } MissionFinancer createNewVersion(final MissionVersion missionVersion) { final MissionFinancer missionFinancer = new MissionFinancer(missionVersion, getUnit()); missionFinancer.setApproval(getApproval()); missionFinancer.setAuthorization(getAuthorization()); return missionFinancer; } public boolean isCurrentUserAccountant() { final Unit unit = getUnit(); final User user = Authenticate.getUser(); return unit.isAccountingEmployee(user.getExpenditurePerson()); } public boolean isCurrentUserProjectAccountant() { final Unit unit = getUnit(); final User user = Authenticate.getUser(); return unit.isProjectAccountingEmployee(user.getExpenditurePerson()); } public boolean isCurrentUserDirectProjectAccountant() { final Unit unit = getUnit(); final User user = Authenticate.getUser(); return unit.isProjectAccountingEmployee(user.getExpenditurePerson()) && (!unit.hasSomeAccountManager() || unit.isAccountManager(user.getExpenditurePerson())); } @Override public AccountingUnit getAccountingUnit() { final AccountingUnit accountingUnit = super.getAccountingUnit(); return accountingUnit == null && hasUnit() ? getUnit().getAccountingUnit() : accountingUnit; } public boolean isUnitObserver(final User user) { return getUnit().isUnitObserver(user); } public pt.ist.expenditureTrackingSystem.domain.organization.Person getAccountManager() { final Unit unit = getUnit(); return unit == null ? null : unit.getAccountManager(); } @Deprecated public java.util.Set<module.mission.domain.MissionItemFinancer> getMissionItemFinancers() { return getMissionItemFinancersSet(); } @Deprecated public boolean hasAnyMissionItemFinancers() { return !getMissionItemFinancersSet().isEmpty(); } @Deprecated public boolean hasCommitmentNumber() { return getCommitmentNumber() != null; } @Deprecated public boolean hasMissionVersion() { return getMissionVersion() != null; } @Deprecated public boolean hasUnit() { return getUnit() != null; } @Deprecated public boolean hasMissionSystem() { return getMissionSystem() != null; } @Deprecated public boolean hasAuthorization() { return getAuthorization() != null; } @Deprecated public boolean hasAccountingUnit() { return getAccountingUnit() != null; } @Deprecated public boolean hasApproval() { return getApproval() != null; } public boolean hasBeenCheckedByUnderlings() { final Unit unit = getUnit(); return hasBeenCheckedByUnderlings(unit); } private boolean hasBeenCheckedByUnderlings(final Unit unit) { if (unit == null) { return false; } final Set<Unit> checked = getCheckedUnitSet(); boolean hasAnyUnderlings = false; for (final Authorization authorization : unit.getAuthorizationsSet()) { if (authorization.isValid()) { if (authorization.getMaxAmount().isGreaterThanOrEqual(getAmount())) { return true; } else { hasAnyUnderlings = true; } } } return ((!hasAnyUnderlings) || checked.contains(unit)) && hasBeenCheckedByUnderlings(unit.getParentUnit()); } }