/* * @(#)PersonelExpenseItem.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 module.finance.util.Money; import module.organization.domain.Person; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; /** * * @author Luis Cruz * */ public abstract class PersonelExpenseItem extends PersonelExpenseItem_Base { private transient Mission missionForCreation; public PersonelExpenseItem() { super(); } @Override public String getItemDescription() { return BundleUtil.getString("resources/MissionResources", "label.mission.items.personel.expense"); } @Override public boolean isPersonelExpenseItem() { return true; } public Mission getMissionForCreation() { return missionForCreation; } public void setMissionForCreation(final Mission mission) { missionForCreation = mission; } @Override public Money getPrevisionaryCosts() { return getValue(); } public int calculateNumberOfDays() { final LocalDate startDate = getStart().toLocalDate(); final LocalDate endDate = getEnd().toLocalDate().plusDays(1); return Days.daysBetween(startDate, endDate).getDays(); } @Override public void delete() { setDailyPersonelExpenseCategory(null); super.delete(); } public double getWeightedExpenseFactor() { return getExpenseFactor(); } public double getExpenseFactor() { double result = 0.0; for (final Person person : getPeopleSet()) { result += getExpenseFactor(person); } return result; } public double getExpenseFactor(final Person person) { double result = 0.0; if (getPeopleSet().contains(person)) { final Mission mission = getMissionVersion().getMission(); final PersonelExpenseItem firstPersonelExpenseItem = findFirstPersonelExpenseItemFor(mission, person); final PersonelExpenseItem lastPersonelExpenseItem = findLastPersonelExpenseItemFor(mission, person); int numberOfDays = calculateNumberOfDays(); if (this == firstPersonelExpenseItem) { numberOfDays--; result += mission.getFirstDayPersonelDayExpensePercentage(this); } if (this == lastPersonelExpenseItem && numberOfDays > 0) { numberOfDays--; result += mission.getLastDayPersonelDayExpensePercentage(this); } result += (numberOfDays * mission.getMiddleDayPersonelDayExpensePercentage(firstPersonelExpenseItem)); } return result; } private static PersonelExpenseItem findFirstPersonelExpenseItemFor(final Mission mission, final Person person) { PersonelExpenseItem result = null; for (final MissionItem missionItem : mission.getMissionItemsSet()) { if (missionItem.isPersonelExpenseItem()) { final PersonelExpenseItem personelExpenseItem = (PersonelExpenseItem) missionItem; if (personelExpenseItem.getPeopleSet().contains(person)) { if (result == null || personelExpenseItem.getStart().isBefore(result.getStart())) { result = personelExpenseItem; } } } } return result; } private static PersonelExpenseItem findLastPersonelExpenseItemFor(final Mission mission, final Person person) { PersonelExpenseItem result = null; for (final MissionItem missionItem : mission.getMissionItemsSet()) { if (missionItem.isPersonelExpenseItem()) { final PersonelExpenseItem personelExpenseItem = (PersonelExpenseItem) missionItem; if (personelExpenseItem.getPeopleSet().contains(person)) { if (result == null || personelExpenseItem.getStart().isAfter(result.getStart())) { result = personelExpenseItem; } } } } return result; } public static int calculateNumberOfFullPersonelExpenseDays(final Mission mission, final Person person) { int result = 0; for (final MissionItem missionItem : mission.getMissionItemsSet()) { if (missionItem instanceof PersonelExpenseItem && missionItem.getPeopleSet().contains(person)) { final PersonelExpenseItem personelExpenseItem = (PersonelExpenseItem) missionItem; result += personelExpenseItem.calculateNumberOfDays(); } } return result; } @Override public boolean isConsistent() { final Mission mission = getMissionVersion().getMission(); final DateTime departure = mission.getDaparture(); final DateTime arrival = mission.getArrival(); return getStart().isBefore(getEnd()) && !getStart().isBefore(departure) && !getEnd().isAfter(arrival) && super.isConsistent(); } @Override public void hookAfterChanges() { super.hookAfterChanges(); final Mission mission = getMissionVersion().getMission(); for (final MissionItem missionItem : mission.getMissionItemsSet()) { if (missionItem != this && missionItem.isPersonelExpenseItem()) { if (!missionItem.areAllCostsDistributed()) { missionItem.distributeCosts(); } } } } public int getNunberOfLunchesToDiscount(final Person person) { int result = 0; if (getPeopleSet().contains(person)) { final Mission mission = getMissionVersion().getMission(); final PersonelExpenseItem firstPersonelExpenseItem = findFirstPersonelExpenseItemFor(mission, person); final PersonelExpenseItem lastPersonelExpenseItem = findLastPersonelExpenseItemFor(mission, person); int numberOfDays = calculateNumberOfDays(); if (this == firstPersonelExpenseItem) { numberOfDays--; result += mission.getNunberOfLunchesToDiscountOnFirstPersonelExpenseDay(this); } if (this == lastPersonelExpenseItem) { numberOfDays--; result += mission.getNunberOfLunchesToDiscountOnLastPersonelExpenseDay(this); } result += numberOfDays; } return result; } @Override public boolean requiresFundAllocation() { return false; } @Override protected void setNewVersionInformation(final MissionItem missionItem) { final PersonelExpenseItem personelExpenseItem = (PersonelExpenseItem) missionItem; personelExpenseItem.setStart(getStart()); personelExpenseItem.setEnd(getEnd()); personelExpenseItem.setDailyPersonelExpenseCategory(getDailyPersonelExpenseCategory()); } @Override public boolean isAvailableForEdit() { final MissionVersion missionVersion = getMissionVersion(); final Mission mission = missionVersion.getMission(); return super.isAvailableForEdit() || mission.isTerminatedWithChanges(); } @Override protected boolean canAutoArchive() { return false; } @Deprecated public boolean hasStart() { return getStart() != null; } @Deprecated public boolean hasEnd() { return getEnd() != null; } @Deprecated public boolean hasDailyPersonelExpenseCategory() { return getDailyPersonelExpenseCategory() != null; } }