Package org.mifosplatform.portfolio.savings.domain

Source Code of org.mifosplatform.portfolio.savings.domain.SavingsHelper

/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.savings.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.account.service.AccountTransfersReadPlatformService;
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.interest.CompoundInterestHelper;
import org.mifosplatform.portfolio.savings.domain.interest.PostingPeriod;

public final class SavingsHelper {

    AccountTransfersReadPlatformService accountTransfersReadPlatformService = null;

    public SavingsHelper(AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
        this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
    }

    private final CompoundInterestHelper compoundInterestHelper = new CompoundInterestHelper();

    public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate startInterestCalculationLocalDate,
            final LocalDate interestPostingUpToDate, final SavingsPostingInterestPeriodType postingPeriodType,
            final Integer financialYearBeginningMonth) {

        final List<LocalDateInterval> postingPeriods = new ArrayList<>();

        LocalDate periodStartDate = startInterestCalculationLocalDate;
        LocalDate periodEndDate = periodStartDate;

        while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) {

            final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType,
                    interestPostingUpToDate, financialYearBeginningMonth);
            periodEndDate = interestPostingLocalDate.minusDays(1);

            postingPeriods.add(LocalDateInterval.create(periodStartDate, periodEndDate));

            periodEndDate = interestPostingLocalDate;
            periodStartDate = interestPostingLocalDate;
        }

        return postingPeriods;
    }

    private LocalDate determineInterestPostingPeriodEndDateFrom(final LocalDate periodStartDate,
            final SavingsPostingInterestPeriodType interestPostingPeriodType, final LocalDate interestPostingUpToDate,
            Integer financialYearBeginningMonth) {

        LocalDate periodEndDate = interestPostingUpToDate;
        final Integer monthOfYear = periodStartDate.getMonthOfYear();
        financialYearBeginningMonth--;
      if(financialYearBeginningMonth == 0)
        financialYearBeginningMonth = 12;
     
      final ArrayList<LocalDate> quarterlyDates = new ArrayList<>();
      quarterlyDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth).dayOfMonth().withMaximumValue());
      quarterlyDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth)
          .plusMonths(3).withYear(periodStartDate.getYear()).dayOfMonth().withMaximumValue());
      quarterlyDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth)
          .plusMonths(6).withYear(periodStartDate.getYear()).dayOfMonth().withMaximumValue());
      quarterlyDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth)
          .plusMonths(9).withYear(periodStartDate.getYear()).dayOfMonth().withMaximumValue());
      Collections.sort(quarterlyDates);
     
      final ArrayList<LocalDate> biannualDates = new ArrayList<>();
      biannualDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth).dayOfMonth().withMaximumValue());
      biannualDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth).plusMonths(6)
          .withYear(periodStartDate.getYear()).dayOfMonth().withMaximumValue());
      Collections.sort(biannualDates);
     
      boolean isEndDateSet = false;
     
    switch (interestPostingPeriodType) {
    case INVALID:
      break;
    case MONTHLY:
      // produce period end date on last day of current month
      periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
      break;
    case QUATERLY:
      for(LocalDate quarterlyDate : quarterlyDates) {
        if(quarterlyDate.isAfter(periodStartDate)) {
          periodEndDate = quarterlyDate;
          isEndDateSet = true;
          break;
        }
      }
     
      if(!isEndDateSet)
        periodEndDate = quarterlyDates.get(0).plusYears(1).dayOfMonth().withMaximumValue();
      break;
    case BIANNUAL:
      for(LocalDate biannualDate : biannualDates) {
        if(biannualDate.isAfter(periodStartDate)) {
          periodEndDate = biannualDate;
          isEndDateSet = true;
          break;
        }
      }
     
      if(!isEndDateSet)
        periodEndDate = biannualDates.get(0).plusYears(1).dayOfMonth().withMaximumValue();
      break;
    case ANNUAL:
      if (financialYearBeginningMonth < monthOfYear) {
        periodEndDate = periodStartDate
            .withMonthOfYear(financialYearBeginningMonth);
        periodEndDate = periodEndDate.plusYears(1);
      } else {
        periodEndDate = periodStartDate
            .withMonthOfYear(financialYearBeginningMonth);
      }
      periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
      break;
    }

        // interest posting always occurs on next day after the period end date.
        periodEndDate = periodEndDate.plusDays(1);

        return periodEndDate;
    }

    public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List<PostingPeriod> allPeriods,
            LocalDate accountLockedUntil, Boolean immediateWithdrawalOfInterest) {
        return this.compoundInterestHelper.calculateInterestForAllPostingPeriods(currency, allPeriods, accountLockedUntil,
                immediateWithdrawalOfInterest);
    }

    public Collection<Long> fetchPostInterestTransactionIds(Long accountId) {
        return this.accountTransfersReadPlatformService.fetchPostInterestTransactionIds(accountId);
    }
}
TOP

Related Classes of org.mifosplatform.portfolio.savings.domain.SavingsHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.