/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.accounts.savings.interest; import java.util.ArrayList; import java.util.List; import org.joda.time.Days; import org.mifos.framework.util.helpers.Money; /** * I represent a valid Interest Calculation Period. * * In mifos, savings interest calculation is to occur every x days/months. */ public class InterestCalculationPeriodDetail { private final CalendarPeriod interval; private final List<EndOfDayDetail> dailyDetails; private final Money balanceBeforeInterval; private final boolean isFirstActivityBeforeInterval; /** * I am responsible for ensuring a {@link InterestCalculationPeriodDetail} is populated with correct * {@link EndOfDayDetail}'s applicable to given period and with the running balance of the account before this * period. */ public static InterestCalculationPeriodDetail populatePeriodDetailBasedOnInterestCalculationInterval( CalendarPeriod calculationPeriod, List<EndOfDayDetail> allEndOfDayDetailsForAccount, Money balanceBeforeInterval) { Money balance = balanceBeforeInterval; boolean isFirstActivityBeforeInterval = true; if(!allEndOfDayDetailsForAccount.isEmpty()) { if(!allEndOfDayDetailsForAccount.get(0).getDate().isBefore(calculationPeriod.getStartDate())) { isFirstActivityBeforeInterval = false; } } List<EndOfDayDetail> applicableDailyDetailsForPeriod = new ArrayList<EndOfDayDetail>(); for (EndOfDayDetail endOfDayDetail : allEndOfDayDetailsForAccount) { if (calculationPeriod.contains(endOfDayDetail.getDate())) { applicableDailyDetailsForPeriod.add(endOfDayDetail); } } return new InterestCalculationPeriodDetail(calculationPeriod, applicableDailyDetailsForPeriod, balance, isFirstActivityBeforeInterval); } public InterestCalculationPeriodDetail(CalendarPeriod interval, List<EndOfDayDetail> dailyDetails, Money balanceBeforeInterval, boolean isFirstActivityBeforeInterval) { this.dailyDetails = dailyDetails; this.balanceBeforeInterval = balanceBeforeInterval; this.interval = interval; this.isFirstActivityBeforeInterval = isFirstActivityBeforeInterval; } public CalendarPeriod getInterval() { return this.interval; } public List<EndOfDayDetail> getDailyDetails() { return this.dailyDetails; } public int getDuration() { int duration = Days.daysBetween(interval.getStartDate(), interval.getEndDate()).getDays(); if (isFirstActivityBeforeInterval) { duration += 1; } return duration; } public Money getBalanceBeforeInterval() { return balanceBeforeInterval; } public boolean isFirstActivityBeforeInterval() { return isFirstActivityBeforeInterval; } public Money zeroAmount() { return Money.zero(this.balanceBeforeInterval.getCurrency()); } public Money sumOfPrincipal() { Money principalForPeriod = zeroAmount(); for (EndOfDayDetail daysDetail : this.dailyDetails) { principalForPeriod = principalForPeriod.add(daysDetail.getResultantAmountForDay()); } return principalForPeriod; } public Money sumOfInterest() { Money interestForPeriod = zeroAmount(); for (EndOfDayDetail daysDetail : this.dailyDetails) { interestForPeriod = interestForPeriod.add(daysDetail.getInterest()); } return interestForPeriod; } }