MIFOSX-1422 : added number of days configuration for loan schedule

This commit is contained in:
Pramod Nuthakki
2014-07-22 12:50:29 +05:30
parent b758e88a4e
commit 0cd593d145
7 changed files with 102 additions and 79 deletions
@@ -12,8 +12,8 @@ import java.util.List;
* <ul> * <ul>
* People typically use either of the following settings when calculating there * People typically use either of the following settings when calculating there
* interest using the daily method: * interest using the daily method:
* <li>360 and</li> * <li>Actual or</li>
* <li>365</li> * <li>30</li>
* </ul> * </ul>
*/ */
public enum DaysInMonthType { public enum DaysInMonthType {
@@ -64,4 +64,8 @@ public enum DaysInMonthType {
} }
return repaymentFrequencyType; return repaymentFrequencyType;
} }
public boolean isDaysInMonth_30() {
return DaysInMonthType.DAYS_30.getValue().equals(this.value);
}
} }
@@ -12,7 +12,9 @@ import java.util.List;
* <ul> * <ul>
* People typically use either of the following settings when calculating there * People typically use either of the following settings when calculating there
* interest using the daily method: * interest using the daily method:
* <li>360 and</li> * <li>Actual or</li>
* <li>360 or</li>
* <li>364 or</li>
* <li>365</li> * <li>365</li>
* </ul> * </ul>
*/ */
@@ -71,4 +73,8 @@ public enum DaysInYearType {
} }
return repaymentFrequencyType; return repaymentFrequencyType;
} }
public boolean isActual() {
return DaysInYearType.ACTUAL.getValue().equals(this.value);
}
} }
@@ -66,8 +66,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
final Collection<LoanScheduleModelPeriod> periods = createNewLoanScheduleListWithDisbursementDetails(numberOfRepayments, final Collection<LoanScheduleModelPeriod> periods = createNewLoanScheduleListWithDisbursementDetails(numberOfRepayments,
loanApplicationTerms, chargesDueAtTimeOfDisbursement); loanApplicationTerms, chargesDueAtTimeOfDisbursement);
// 4. Determine the total interest owed over the full loan. // 4. Determine the total interest owed over the full loan for FLAT interest method .
final Money totalInterestChargedForFullLoanTerm = loanApplicationTerms.calculateTotalInterestCharged( Money totalInterestChargedForFullLoanTerm = loanApplicationTerms.calculateTotalInterestCharged(
this.paymentPeriodsInOneYearCalculator, mc); this.paymentPeriodsInOneYearCalculator, mc);
LocalDate periodStartDate = loanApplicationTerms.getExpectedDisbursementDate(); LocalDate periodStartDate = loanApplicationTerms.getExpectedDisbursementDate();
@@ -150,13 +150,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
Money feeChargesForInstallment = principalDisbursed.zero(); Money feeChargesForInstallment = principalDisbursed.zero();
Money penaltyChargesForInstallment = principalDisbursed.zero(); Money penaltyChargesForInstallment = principalDisbursed.zero();
if (!(loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getFixedEmiAmount() != null)) {
// 7. determine fees and penalties
feeChargesForInstallment = cumulativeFeeChargesDueWithin(periodStartDate, scheduledDueDate, loanCharges, currency,
principalInterestForThisPeriod, principalDisbursed, totalInterestChargedForFullLoanTerm, numberOfRepayments);
penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(periodStartDate, scheduledDueDate, loanCharges, currency,
principalInterestForThisPeriod, principalDisbursed, totalInterestChargedForFullLoanTerm, numberOfRepayments);
}
// 8. sum up real totalInstallmentDue from components // 8. sum up real totalInstallmentDue from components
final Money totalInstallmentDue = principalInterestForThisPeriod.principal() // final Money totalInstallmentDue = principalInterestForThisPeriod.principal() //
.plus(principalInterestForThisPeriod.interest()) // .plus(principalInterestForThisPeriod.interest()) //
@@ -187,22 +181,20 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
throw new MultiDisbursementDisbursementDateException(errorMsg); throw new MultiDisbursementDisbursementDateException(errorMsg);
} }
if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getFixedEmiAmount() != null && !loanCharges.isEmpty()) { // 7. determine fees and penalties
// 7. determine fees and penalties for (LoanScheduleModelPeriod loanScheduleModelPeriod : periods) {
for (LoanScheduleModelPeriod loanScheduleModelPeriod : periods) { if (loanScheduleModelPeriod.isRepaymentPeriod()) {
if (loanScheduleModelPeriod.isRepaymentPeriod()) { PrincipalInterest principalInterest = new PrincipalInterest(Money.of(currency, loanScheduleModelPeriod.principalDue()),
PrincipalInterest principalInterest = new PrincipalInterest(Money.of(currency, loanScheduleModelPeriod.principalDue()), Money.of(currency, loanScheduleModelPeriod.interestDue()), null);
Money.of(currency, loanScheduleModelPeriod.interestDue()), null); Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(loanScheduleModelPeriod.periodFromDate(),
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(loanScheduleModelPeriod.periodFromDate(), loanScheduleModelPeriod.periodDueDate(), loanCharges, currency, principalInterest, principalDisbursed,
loanScheduleModelPeriod.periodDueDate(), loanCharges, currency, principalInterest, principalDisbursed, totalCumulativeInterest, numberOfRepayments);
totalCumulativeInterest, numberOfRepayments); Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(loanScheduleModelPeriod.periodFromDate(),
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(loanScheduleModelPeriod.periodFromDate(), loanScheduleModelPeriod.periodDueDate(), loanCharges, currency, principalInterest, principalDisbursed,
loanScheduleModelPeriod.periodDueDate(), loanCharges, currency, principalInterest, principalDisbursed, totalCumulativeInterest, numberOfRepayments);
totalCumulativeInterest, numberOfRepayments); totalFeeChargesCharged = totalFeeChargesCharged.add(feeChargesForInstallment.getAmount());
totalFeeChargesCharged = totalFeeChargesCharged.add(feeChargesForInstallment.getAmount()); totalPenaltyChargesCharged = totalPenaltyChargesCharged.add(penaltyChargesForInstallment.getAmount());
totalPenaltyChargesCharged = totalPenaltyChargesCharged.add(penaltyChargesForInstallment.getAmount()); loanScheduleModelPeriod.addLoanCharges(feeChargesForInstallment.getAmount(), penaltyChargesForInstallment.getAmount());
loanScheduleModelPeriod.addLoanCharges(feeChargesForInstallment.getAmount(), penaltyChargesForInstallment.getAmount());
}
} }
} }
@@ -16,6 +16,8 @@ import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.common.domain.DaysInMonthType;
import org.mifosplatform.portfolio.common.domain.DaysInYearType;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData; import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTermVariationsData; import org.mifosplatform.portfolio.loanaccount.data.LoanTermVariationsData;
@@ -102,6 +104,10 @@ public final class LoanApplicationTerms {
private List<LoanTermVariationsData> emiAmountVariations; private List<LoanTermVariationsData> emiAmountVariations;
private final DaysInMonthType daysInMonthType;
private final DaysInYearType daysInYearType;
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency, public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency,
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery, final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
final PeriodFrequencyType repaymentPeriodFrequencyType, final AmortizationMethod amortizationMethod, final PeriodFrequencyType repaymentPeriodFrequencyType, final AmortizationMethod amortizationMethod,
@@ -113,22 +119,23 @@ public final class LoanApplicationTerms {
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate,
final Money inArrearsTolerance, final boolean multiDisburseLoan, final BigDecimal emiAmount, final Money inArrearsTolerance, final boolean multiDisburseLoan, final BigDecimal emiAmount,
final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance, final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
final List<LoanTermVariationsData> emiAmountVariations, final Integer graceOnArrearsAgeing) { final List<LoanTermVariationsData> emiAmountVariations, final Integer graceOnArrearsAgeing,
final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType) {
return new LoanApplicationTerms(currency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, repaymentEvery, return new LoanApplicationTerms(currency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, repaymentEvery,
repaymentPeriodFrequencyType, amortizationMethod, interestMethod, interestRatePerPeriod, interestRatePeriodFrequencyType, repaymentPeriodFrequencyType, amortizationMethod, interestMethod, interestRatePerPeriod, interestRatePeriodFrequencyType,
annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney, expectedDisbursementDate, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney, expectedDisbursementDate,
repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment,
graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas,
maxOutstandingBalance, emiAmountVariations, graceOnArrearsAgeing); maxOutstandingBalance, emiAmountVariations, graceOnArrearsAgeing, daysInMonthType, daysInYearType);
} }
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency, public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
final PeriodFrequencyType loanTermPeriodFrequencyType, final LocalDate expectedDisbursementDate, final PeriodFrequencyType loanTermPeriodFrequencyType, final LocalDate expectedDisbursementDate,
final LocalDate repaymentsStartingFromDate, final LocalDate calculatedRepaymentsStartingFromDate, final LocalDate repaymentsStartingFromDate, final LocalDate calculatedRepaymentsStartingFromDate,
final Money inArrearsTolerance, final LoanProductRelatedDetail loanProductRelatedDetail, final Money inArrearsTolerance, final LoanProductRelatedDetail loanProductRelatedDetail, final boolean multiDisburseLoan,
final boolean multiDisburseLoan,final BigDecimal emiAmount,final List<DisbursementData> disbursementDatas, final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
final BigDecimal maxOutstandingBalance,final List<LoanTermVariationsData> emiAmountVariations, final LocalDate interestChargedFromDate) { final List<LoanTermVariationsData> emiAmountVariations, final LocalDate interestChargedFromDate) {
final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments(); final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery(); final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
@@ -143,8 +150,8 @@ public final class LoanApplicationTerms {
final Money principalMoney = loanProductRelatedDetail.getPrincipal(); final Money principalMoney = loanProductRelatedDetail.getPrincipal();
// //
final Integer graceOnPrincipalPayment = loanProductRelatedDetail.graceOnPrincipalPayment() ; final Integer graceOnPrincipalPayment = loanProductRelatedDetail.graceOnPrincipalPayment();
final Integer graceOnInterestPayment = loanProductRelatedDetail.graceOnInterestPayment() ; final Integer graceOnInterestPayment = loanProductRelatedDetail.graceOnInterestPayment();
final Integer graceOnInterestCharged = loanProductRelatedDetail.graceOnInterestCharged(); final Integer graceOnInterestCharged = loanProductRelatedDetail.graceOnInterestCharged();
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
@@ -152,7 +159,8 @@ public final class LoanApplicationTerms {
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney,
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment,
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
disbursementDatas, maxOutstandingBalance, emiAmountVariations, loanProductRelatedDetail.getGraceOnDueDate()); disbursementDatas, maxOutstandingBalance, emiAmountVariations, loanProductRelatedDetail.getGraceOnDueDate(),
loanProductRelatedDetail.fetchDaysInMonthType(), loanProductRelatedDetail.fetchDaysInYearType());
} }
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency, private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
@@ -165,7 +173,8 @@ public final class LoanApplicationTerms {
final LocalDate calculatedRepaymentsStartingFromDate, final Integer principalGrace, final Integer interestPaymentGrace, final LocalDate calculatedRepaymentsStartingFromDate, final Integer principalGrace, final Integer interestPaymentGrace,
final Integer interestChargingGrace, final LocalDate interestChargedFromDate, final Money inArrearsTolerance, final Integer interestChargingGrace, final LocalDate interestChargedFromDate, final Money inArrearsTolerance,
final boolean multiDisburseLoan, final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas, final boolean multiDisburseLoan, final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas,
final BigDecimal maxOutstandingBalance, final List<LoanTermVariationsData> emiAmountVariations, final Integer graceOnArrearsAgeing) { final BigDecimal maxOutstandingBalance, final List<LoanTermVariationsData> emiAmountVariations,
final Integer graceOnArrearsAgeing, final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType) {
this.currency = currency; this.currency = currency;
this.loanTermFrequency = loanTermFrequency; this.loanTermFrequency = loanTermFrequency;
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType; this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
@@ -197,6 +206,8 @@ public final class LoanApplicationTerms {
this.maxOutstandingBalance = maxOutstandingBalance; this.maxOutstandingBalance = maxOutstandingBalance;
this.emiAmountVariations = emiAmountVariations; this.emiAmountVariations = emiAmountVariations;
this.graceOnArrearsAgeing = graceOnArrearsAgeing; this.graceOnArrearsAgeing = graceOnArrearsAgeing;
this.daysInMonthType = daysInMonthType;
this.daysInYearType = daysInYearType;
} }
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate, public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
@@ -273,12 +284,6 @@ public final class LoanApplicationTerms {
totalInterestCharged = totalInterestChargedForLoanTerm.minus(totalGraceOnInterestCharged); totalInterestCharged = totalInterestChargedForLoanTerm.minus(totalGraceOnInterestCharged);
break; break;
case DECLINING_BALANCE: case DECLINING_BALANCE:
final BigDecimal periodicInterestRateForRepaymentPeriod = periodicInterestRate(calculator, mc);
final Money totalRepaymentDueForLoanTerm = calculateTotalDueForEqualInstallmentLoan(periodicInterestRateForRepaymentPeriod);
totalInterestCharged = totalRepaymentDueForLoanTerm.minus(this.principal);
break;
case INVALID: case INVALID:
break; break;
} }
@@ -303,7 +308,10 @@ public final class LoanApplicationTerms {
case EQUAL_INSTALLMENTS: case EQUAL_INSTALLMENTS:
// equal installments // equal installments
final int periodsElapsed = periodNumber - 1; final int periodsElapsed = periodNumber - 1;
final BigDecimal periodicInterestRateForRepaymentPeriod = periodicInterestRate(calculator, mc); // with periodic interest for default month and year for
// equal installment
final BigDecimal periodicInterestRateForRepaymentPeriod = periodicInterestRate(calculator, mc, daysInPeriod,
DaysInMonthType.DAYS_30, DaysInYearType.DAYS_365);
Money totalPmtForThisInstallment = calculateTotalDueForEqualInstallmentRepaymentPeriod( Money totalPmtForThisInstallment = calculateTotalDueForEqualInstallmentRepaymentPeriod(
periodicInterestRateForRepaymentPeriod, outstandingBalance, periodsElapsed); periodicInterestRateForRepaymentPeriod, outstandingBalance, periodsElapsed);
principalForInstallment = calculatePrincipalDueForInstallment(calculator, mc, periodNumber, principalForInstallment = calculatePrincipalDueForInstallment(calculator, mc, periodNumber,
@@ -384,15 +392,6 @@ public final class LoanApplicationTerms {
return periodNumber == numberOfRepayments; return periodNumber == numberOfRepayments;
} }
private Money calculateTotalDueForEqualInstallmentLoan(final BigDecimal periodicInterestRate) {
final int periodsElapsed = 0;
final double paymentPerRepaymentPeriod = paymentPerPeriod(periodicInterestRate, this.principal, periodsElapsed);
final double totalRepayment = paymentPerRepaymentPeriod * this.numberOfRepayments;
return Money.of(this.principal.getCurrency(), BigDecimal.valueOf(totalRepayment));
}
/** /**
* general method to calculate totalInterestDue discounting any grace * general method to calculate totalInterestDue discounting any grace
* settings * settings
@@ -521,7 +520,8 @@ public final class LoanApplicationTerms {
return interestForInstallment; return interestForInstallment;
} }
private BigDecimal periodicInterestRate(final PaymentPeriodsInOneYearCalculator calculator, final MathContext mc) { private BigDecimal periodicInterestRate(final PaymentPeriodsInOneYearCalculator calculator, final MathContext mc, final int actualDays,
final DaysInMonthType daysInMonthType, final DaysInYearType daysInYearType) {
final long loanTermPeriodsInOneYear = calculatePeriodsInOneYear(calculator); final long loanTermPeriodsInOneYear = calculatePeriodsInOneYear(calculator);
@@ -535,7 +535,8 @@ public final class LoanApplicationTerms {
break; break;
case DAILY: case DAILY:
// For daily work out number of days in the period // For daily work out number of days in the period
int numberOfDaysInPeriod = this.repaymentEvery; int numberOfDaysInPeriod = actualDays;
final BigDecimal oneDayOfYearInterestRate = this.annualNominalInterestRate.divide(loanTermPeriodsInYearBigDecimal, mc) final BigDecimal oneDayOfYearInterestRate = this.annualNominalInterestRate.divide(loanTermPeriodsInYearBigDecimal, mc)
.divide(divisor, mc); .divide(divisor, mc);
@@ -547,15 +548,28 @@ public final class LoanApplicationTerms {
periodicInterestRate = oneDayOfYearInterestRate.multiply(loanTermFrequencyBigDecimal, mc); periodicInterestRate = oneDayOfYearInterestRate.multiply(loanTermFrequencyBigDecimal, mc);
break; break;
case WEEKS: case WEEKS:
numberOfDaysInPeriod = this.repaymentEvery * 7;
periodicInterestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(numberOfDaysInPeriod), mc); periodicInterestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(numberOfDaysInPeriod), mc);
break; break;
case MONTHS: case MONTHS:
numberOfDaysInPeriod = this.repaymentEvery * 30; if (daysInMonthType.isDaysInMonth_30()) {
numberOfDaysInPeriod = this.repaymentEvery * 30;
}
periodicInterestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(numberOfDaysInPeriod), mc); periodicInterestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(numberOfDaysInPeriod), mc);
break; break;
case YEARS: case YEARS:
numberOfDaysInPeriod = this.repaymentEvery * 365; switch (daysInYearType) {
case DAYS_360:
numberOfDaysInPeriod = this.repaymentEvery * 360;
break;
case DAYS_364:
numberOfDaysInPeriod = this.repaymentEvery * 364;
break;
case DAYS_365:
numberOfDaysInPeriod = this.repaymentEvery * 365;
break;
default:
break;
}
periodicInterestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(numberOfDaysInPeriod), mc); periodicInterestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(numberOfDaysInPeriod), mc);
break; break;
} }
@@ -655,23 +669,9 @@ public final class LoanApplicationTerms {
Money interestDue = Money.zero(outstandingBalance.getCurrency()); Money interestDue = Money.zero(outstandingBalance.getCurrency());
switch (this.interestCalculationPeriodMethod) { final BigDecimal periodicInterestRate = periodicInterestRate(calculator, mc, daysInPeriod, this.daysInMonthType,
case DAILY: this.daysInYearType);
final BigDecimal dailyInterestRate = this.annualNominalInterestRate.divide(BigDecimal.valueOf(Long.valueOf(365)), mc) interestDue = outstandingBalance.multiplyRetainScale(periodicInterestRate, mc.getRoundingMode());
.divide(BigDecimal.valueOf(Double.valueOf("100.0")), mc);
final BigDecimal equivalentInterestRateForPeriod = dailyInterestRate
.multiply(BigDecimal.valueOf(Long.valueOf(daysInPeriod)));
interestDue = outstandingBalance.multiplyRetainScale(equivalentInterestRateForPeriod, mc.getRoundingMode());
break;
case SAME_AS_REPAYMENT_PERIOD:
final BigDecimal periodicInterestRate = periodicInterestRate(calculator, mc);
interestDue = outstandingBalance.multiplyRetainScale(periodicInterestRate, mc.getRoundingMode());
break;
case INVALID:
break;
}
return interestDue; return interestDue;
} }
@@ -221,7 +221,7 @@ public class LoanScheduleAssembler {
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment,
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsToleranceMoney, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsToleranceMoney,
loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, loanVariationTermsData, loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, loanVariationTermsData,
graceOnArrearsAgeing); graceOnArrearsAgeing, loanProduct.fetchDaysInMonthType(), loanProduct.fetchDaysInYearType());
} }
private List<DisbursementData> fetchDisbursementData(final JsonObject command) { private List<DisbursementData> fetchDisbursementData(final JsonObject command) {
@@ -38,6 +38,8 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.charge.domain.Charge; import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.common.domain.DaysInMonthType;
import org.mifosplatform.portfolio.common.domain.DaysInYearType;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.fund.domain.Fund; import org.mifosplatform.portfolio.fund.domain.Fund;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
@@ -839,4 +841,13 @@ public class LoanProduct extends AbstractPersistable<Long> {
} }
return borrowerCycleVariations; return borrowerCycleVariations;
} }
public DaysInMonthType fetchDaysInMonthType() {
return this.loanProductRelatedDetail.fetchDaysInMonthType();
}
public DaysInYearType fetchDaysInYearType() {
return this.loanProductRelatedDetail.fetchDaysInYearType();
}
} }
@@ -23,6 +23,8 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.common.domain.DaysInMonthType;
import org.mifosplatform.portfolio.common.domain.DaysInYearType;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
@@ -164,15 +166,15 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
public void setPrincipal(BigDecimal principal) { public void setPrincipal(BigDecimal principal) {
this.principal = principal; this.principal = principal;
} }
public Integer graceOnInterestCharged() { public Integer graceOnInterestCharged() {
return this.graceOnInterestCharged; return this.graceOnInterestCharged;
} }
public Integer graceOnInterestPayment() { public Integer graceOnInterestPayment() {
return this.graceOnInterestPayment; return this.graceOnInterestPayment;
} }
public Integer graceOnPrincipalPayment() { public Integer graceOnPrincipalPayment() {
return this.graceOnPrincipalPayment; return this.graceOnPrincipalPayment;
} }
@@ -431,4 +433,12 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
public Integer getGraceOnDueDate() { public Integer getGraceOnDueDate() {
return this.graceOnArrearsAgeing; return this.graceOnArrearsAgeing;
} }
public DaysInMonthType fetchDaysInMonthType() {
return DaysInMonthType.ACTUAL;
}
public DaysInYearType fetchDaysInYearType() {
return DaysInYearType.ACTUAL;
}
} }