/* * 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.mifos.accounts.savings.interest.schedule.InterestScheduledEvent; import org.mifos.framework.util.helpers.Money; /** * I am responsible for working out how much interest should be applied to a given calculation period. */ public class InterestCalculationPeriodCalculator implements NonCompoundingInterestCalculator { private final InterestCalculator interestCalculator; private final InterestScheduledEvent interestCalculationSchedule; private final CalendarPeriodHelper interestCalculationIntervalHelper; public InterestCalculationPeriodCalculator(InterestCalculator interestCalculator, InterestScheduledEvent interestCalculationSchedule, CalendarPeriodHelper interestCalculationIntervalHelper) { this.interestCalculator = interestCalculator; this.interestCalculationSchedule = interestCalculationSchedule; this.interestCalculationIntervalHelper = interestCalculationIntervalHelper; } /** * I do this by determining all legal 'calculation periods' within a given {@link CalendarPeriod} time period. * * For each 'interest calculation period' derived, I create a {@link InterestCalculationPeriodDetail} which will hold all the information * necessary for the {@link InterestCalculator} to return a {@link InterestCalculationPeriodResult}. */ @Override public List<InterestCalculationPeriodResult> calculateDetails(CalendarPeriod calculationPeriod, Money totalBalanceBeforeCalculationPeriod, List<EndOfDayDetail> endOfDayDetailsForCalculationPeriod) { List<InterestCalculationPeriodResult> calculationPeriodResults = new ArrayList<InterestCalculationPeriodResult>(); List<CalendarPeriod> allPossible = interestCalculationIntervalHelper.determineAllPossiblePeriods( calculationPeriod.getStartDate(), this.interestCalculationSchedule, calculationPeriod.getEndDate()); Money runningBalance = totalBalanceBeforeCalculationPeriod; for (CalendarPeriod interestCalculationPeriod : allPossible) { InterestCalculationPeriodDetail interestCalculationPeriodDetail = InterestCalculationPeriodDetail .populatePeriodDetailBasedOnInterestCalculationInterval(interestCalculationPeriod, endOfDayDetailsForCalculationPeriod, runningBalance); InterestCalculationPeriodResult calculationPeriodResult = interestCalculator.calculateSavingsDetailsForPeriod(interestCalculationPeriodDetail); calculationPeriodResults.add(calculationPeriodResult); runningBalance = runningBalance.add(calculationPeriodResult.getTotalPrincipal()); } return calculationPeriodResults; } @Override public InterestCalculationPeriodResult calculateCalculationPeriodDetail(InterestCalculationPeriodDetail interestCalculationPeriodDetail) { return interestCalculator.calculateSavingsDetailsForPeriod(interestCalculationPeriodDetail); } }