pt.ist.expenditureTrackingSystem.domain.acquisitions.RegularAcquisitionProcess.java Source code

Java tutorial

Introduction

Here is the source code for pt.ist.expenditureTrackingSystem.domain.acquisitions.RegularAcquisitionProcess.java

Source

/*
 * @(#)RegularAcquisitionProcess.java
 *
 * Copyright 2009 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 pt.ist.expenditureTrackingSystem.domain.acquisitions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.fenixedu.bennu.core.domain.User;
import org.joda.time.LocalDate;

import module.finance.util.Money;
import pt.ist.expenditureTrackingSystem._development.Bundle;
import pt.ist.expenditureTrackingSystem.domain.ExpenditureTrackingSystem;
import pt.ist.expenditureTrackingSystem.domain.acquisitions.simplified.activities.FundAllocationExpirationDate.FundAllocationNotAllowedException;
import pt.ist.expenditureTrackingSystem.domain.organization.Person;
import pt.ist.expenditureTrackingSystem.domain.organization.Supplier;
import pt.ist.expenditureTrackingSystem.domain.organization.Unit;
import pt.ist.expenditureTrackingSystem.domain.util.DomainException;

/**
 * 
 * @author Paulo Abrantes
 * @author Luis Cruz
 * 
 */
public abstract class RegularAcquisitionProcess extends RegularAcquisitionProcess_Base {

    public enum ActivityScope {
        REQUEST_INFORMATION, REQUEST_ITEM;
    }

    public RegularAcquisitionProcess() {
        super();
    }

    public boolean isSimplifiedAcquisitionProcess() {
        return false;
    }

    public boolean isStandardAcquisitionProcess() {
        return false;
    }

    public Set<AcquisitionInvoice> getConfirmedInvoices(Person person) {
        return getAcquisitionRequest().getAcquisitionRequestItemStream()
                .flatMap(i -> i.getConfirmedInvoices(person).stream()).collect(Collectors.toSet());
    }

    public Set<AcquisitionInvoice> getUnconfirmedInvoices(Person person) {
        return getAcquisitionRequest().getAcquisitionRequestItemStream().filter(i -> i.isResponsible(person))
                .flatMap(i -> i.getUnconfirmedInvoices(person).stream()).collect(Collectors.toSet());
    }

    public Set<AcquisitionInvoice> getAllUnconfirmedInvoices() {
        return getAcquisitionRequest().getAcquisitionRequestItemStream()
                .flatMap(i -> i.getAllUnconfirmedInvoices().stream()).collect(Collectors.toSet());
    }

    public void confirmInvoiceBy(Person person) {
        getAcquisitionRequest().confirmInvoiceFor(person);
        if (getAcquisitionRequest().isInvoiceConfirmedBy()
                && getLastAcquisitionProcessState().isPendingInvoiceConfirmation()) {
            confirmInvoice();
        }
    }

    public void cancelInvoiceConfirmationBy(final Person person) {
        getAcquisitionRequest().unconfirmInvoiceFor(person);
        if (getLastAcquisitionProcessState().isInvoiceConfirmed()) {
            cancelInvoiceConfirmation(null);
        }
    }

    public void unconfirmInvoiceForAll(final AcquisitionInvoice acquisitionInvoice) {
        getAcquisitionRequest().unconfirmInvoiceForAll(acquisitionInvoice);
        cancelInvoiceConfirmation(acquisitionInvoice);
    }

    @Override
    public void allocateFundsPermanently() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.FUNDS_ALLOCATED_PERMANENTLY);
    }

    public void cancel() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.CANCELED);
    }

    @Override
    protected void authorize() {
        final AcquisitionProcessStateType type;
        if (ExpenditureTrackingSystem.isInvoiceAllowedToStartAcquisitionProcess() && hasInvoiceFile()) {
            type = AcquisitionProcessStateType.INVOICE_RECEIVED;
            getRequest().processReceivedInvoice();
        } else {
            type = AcquisitionProcessStateType.AUTHORIZED;
        }
        new AcquisitionProcessState(this, type);
    }

    protected void cancelInvoiceConfirmation(final AcquisitionInvoice acquisitionInvoice) {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.SUBMITTED_FOR_CONFIRM_INVOICE);
    }

    protected void confirmInvoice() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.INVOICE_CONFIRMED);
    }

    @Override
    public void allocateFundsToUnit() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.FUNDS_ALLOCATED);
    }

    public void allocateFundsToSupplier() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.FUNDS_ALLOCATED_TO_SERVICE_PROVIDER);
    }

    public void acquisitionPayed() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.ACQUISITION_PAYED);
    }

    public void invoiceReceived() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.INVOICE_RECEIVED);
    }

    public void reject() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.REJECTED);
    }

    public void inGenesis() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.IN_GENESIS);
    }

    @Override
    public void submitForApproval() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.SUBMITTED_FOR_APPROVAL);
    }

    public void processAcquisition() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.ACQUISITION_PROCESSED);
    }

    public void revertProcessedAcquisition() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.AUTHORIZED);
    }

    public void submitedForInvoiceConfirmation() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.SUBMITTED_FOR_CONFIRM_INVOICE);
        getAcquisitionRequest().getAcquisitionRequestItemStream().flatMap(i -> i.getInvoicesFilesSet().stream())
                .map(i -> (AcquisitionInvoice) i).filter(i -> i.getState() == AcquisitionInvoiceState.RECEIVED)
                .forEach(i -> i.setState(AcquisitionInvoiceState.AWAITING_CONFIRMATION));
    }

    @Override
    public void submitForFundAllocation() {
        final AcquisitionProcessStateType type;
        if (ExpenditureTrackingSystem.isInvoiceAllowedToStartAcquisitionProcess() && hasInvoiceFile()) {
            type = AcquisitionProcessStateType.FUNDS_ALLOCATED_TO_SERVICE_PROVIDER;
            createFundAllocationRequest(false);
        } else {
            type = AcquisitionProcessStateType.SUBMITTED_FOR_FUNDS_ALLOCATION;
        }
        new AcquisitionProcessState(this, type);
    }

    public void skipFundAllocation() {
        new AcquisitionProcessState(this, AcquisitionProcessStateType.FUNDS_ALLOCATED_TO_SERVICE_PROVIDER);
    }

    @Override
    public void resetEffectiveFundAllocationId() {
        getAcquisitionRequest().resetEffectiveFundAllocationId();
        confirmInvoice();
    }

    @Override
    public boolean isProcessFlowCharAvailable() {
        return true;
    }

    @Override
    public void setSkipSupplierFundAllocation(Boolean skipSupplierFundAllocation) {
        throw new DomainException(Bundle.EXPENDITURE, "error.illegal.method.use");
    }

    public void unSkipSupplierFundAllocation() {
        checkSupplierLimit();
        super.setSkipSupplierFundAllocation(Boolean.FALSE);
        if (!getAcquisitionProcessState().isInGenesis()) {
            LocalDate now = new LocalDate();
            setFundAllocationExpirationDate(now.plusDays(90));
        }
    }

    public void skipSupplierFundAllocation() {
        super.setSkipSupplierFundAllocation(Boolean.TRUE);
        setFundAllocationExpirationDate(null);
    }

    public boolean isFinanceByAnyUnit(List<Unit> fromUnits) {
        for (Financer financer : getAcquisitionRequest().getFinancers()) {
            if (fromUnits.contains(financer.getUnit())) {
                return true;
            }
        }
        return false;
    }

    public boolean isPersonAbleToDirectlyAuthorize(Person person) {
        return isFinanceByAnyUnit(person.getDirectResponsibleUnits()) ? true
                : getRequestingUnit().isMostDirectAuthorization(person,
                        getAcquisitionRequest().getTotalItemValueWithAdditionalCostsAndVat());
    }

    public List<Unit> getFinancingUnits() {
        List<Unit> units = new ArrayList<Unit>();
        for (Financer financer : getAcquisitionRequest().getFinancers()) {
            units.add(financer.getUnit());
        }
        return units;
    }

    @Override
    public boolean isInAuthorizedState() {
        return getAcquisitionProcessState().isAuthorized();
    }

    public boolean isPendingInvoiceConfirmation() {
        return getAcquisitionProcessState().isPendingInvoiceConfirmation();
    }

    public void removeFundAllocationExpirationDate() {
        setFundAllocationExpirationDate(null);
        if (!getAcquisitionProcessState().isCanceled()) {
            submitForFundAllocation();
        }
    }

    @Override
    public boolean isInAllocatedToUnitState() {
        return getAcquisitionProcessState().isInAllocatedToUnitState();
    }

    @Override
    public Money getTotalValue() {
        return getAcquisitionRequest().getCurrentTotalValue();
    }

    @Override
    public Set<CPVReference> getCPVReferences() {
        final AcquisitionRequest acquisitionRequest = getRequest();
        return acquisitionRequest.getCPVReferences();
    }

    public void createFundAllocationRequest(final boolean isFinalFundAllocation) {
        final AcquisitionRequest acquisitionRequest = getAcquisitionRequest();
        acquisitionRequest.createFundAllocationRequest(isFinalFundAllocation);
    }

    public void cancelFundAllocationRequest(final boolean isFinalFundAllocation) {
        final AcquisitionRequest acquisitionRequest = getAcquisitionRequest();
        acquisitionRequest.cancelFundAllocationRequest(isFinalFundAllocation);
    }

    public boolean hasInvoiceFile() {
        return false;
    }

    public boolean isCommitted() {
        final ExpenditureTrackingSystem instance = ExpenditureTrackingSystem.getInstance();
        if (instance.getRequireCommitmentNumber() != null && instance.getRequireCommitmentNumber().booleanValue()) {
            final AcquisitionRequest acquisitionRequest = getAcquisitionRequest();
            return acquisitionRequest.isCommitted();
        }
        return true;
    }

    public boolean isPendingCommitmentByUser(final User user) {
        final ExpenditureTrackingSystem instance = ExpenditureTrackingSystem.getInstance();
        if (instance.getRequireCommitmentNumber() != null && instance.getRequireCommitmentNumber().booleanValue()) {
            final AcquisitionRequest acquisitionRequest = getAcquisitionRequest();
            return acquisitionRequest.isPendingCommitmentByUser(user);
        }
        return false;
    }

    public boolean hasCommitmentByUser(final User user) {
        final ExpenditureTrackingSystem instance = ExpenditureTrackingSystem.getInstance();
        if (instance.getRequireCommitmentNumber() != null && instance.getRequireCommitmentNumber().booleanValue()) {
            final AcquisitionRequest acquisitionRequest = getAcquisitionRequest();
            return acquisitionRequest.hasCommitmentByUser(user);
        }
        return false;
    }

    public void checkSupplierLimit() {
        final Map<Supplier, Map<CPVReference, Money>> allocationMap = new HashMap<Supplier, Map<CPVReference, Money>>();

        for (final RequestItem requestItem : getRequest().getRequestItemsSet()) {
            final AcquisitionRequestItem acquisitionRequestItem = (AcquisitionRequestItem) requestItem;
            final CPVReference cpvReference = requestItem.getCPVReference();
            final Money value = acquisitionRequestItem.getCurrentSupplierAllocationValue();

            for (final Supplier supplier : getSuppliers()) {
                final String key = cpvReference.getExternalId() + supplier.getExternalId();

                if (!allocationMap.containsKey(supplier)) {
                    allocationMap.put(supplier, new HashMap<CPVReference, Money>());
                }
                final Map<CPVReference, Money> map = allocationMap.get(supplier);
                if (map.containsKey(cpvReference)) {
                    map.put(cpvReference, value.add(map.get(cpvReference)));
                } else {
                    map.put(cpvReference, value);
                }
            }
        }

        final boolean checkSupplierLimitsByCPV = ExpenditureTrackingSystem.getInstance().checkSupplierLimitsByCPV();

        for (final Entry<Supplier, Map<CPVReference, Money>> entry : allocationMap.entrySet()) {
            final Supplier supplier = entry.getKey();
            final Map<CPVReference, Money> map = entry.getValue();

            Money total = Money.ZERO;
            for (final Entry<CPVReference, Money> centry : map.entrySet()) {
                final CPVReference cpvReference = centry.getKey();
                final Money value = centry.getValue();
                if (checkSupplierLimitsByCPV && !supplier.isFundAllocationAllowed(cpvReference.getCode(), value)) {
                    throw new FundAllocationNotAllowedException();
                }
                total = total.add(value);
            }
            if (!checkSupplierLimitsByCPV && !supplier.isFundAllocationAllowed(total)) {
                throw new FundAllocationNotAllowedException();
            }
        }
    }

    public boolean isReverifiedAfterCommitment() {
        final Boolean b = getProcessNeedsReverification();
        return b == null || !b.booleanValue();
    }

    public void reverifiedAfterCommitment() {
        setProcessNeedsReverification(Boolean.FALSE);
    }

    public Set<AcquisitionApprovalTerm> getLastAcquisitionApprovalTerms() {
        return getAcquisitionApprovalTermSet()
                .stream().map(aap -> aap.getApprover()).distinct().map(p -> p.getAcquisitionApprovalTermSet()
                        .stream().sorted(Collections.reverseOrder()).findFirst().orElse(null))
                .collect(Collectors.toCollection(TreeSet::new));
    }

}