DecliningBalanceEqualPrincipalWithInterestGenerator implements PrincipalWithInterestGenerator { @Override public List<InstallmentPrincipalAndInterest> generateEqualInstallments(LoanInterestCalculationDetails loanInterestCalculationDetails) { Money loanAmount = loanInterestCalculationDetails.getLoanAmount(); Integer numberOfInstallments = loanInterestCalculationDetails.getNumberOfInstallments(); Double interestFractionalRatePerInstallment = loanInterestCalculationDetails.getInterestFractionalRatePerInstallment(); GraceType graceType = loanInterestCalculationDetails.getGraceType(); Integer gracePeriodDuration = loanInterestCalculationDetails.getGracePeriodDuration(); int prorateValue = 0; List<InstallmentPrincipalAndInterest> lstInstallmntPricplIntrst = null; LocalDate disbursalDateInLocalDate=loanInterestCalculationDetails.getDisbursementDate(); DateTime disbursalDate=disbursalDateInLocalDate.toDateTimeAtStartOfDay(); List<DateTime> scheduledDates=loanInterestCalculationDetails.getLoanScheduleDates(); if(scheduledDates.size() > 2){ DateTime firstRepaymentDay=scheduledDates.get(0); long differenceOfTwoDatesinMilliseconds=(firstRepaymentDay.toDate().getTime()-disbursalDate.toDate().getTime()); long noOfDays=differenceOfTwoDatesinMilliseconds/(1000*60*60*24); int noOfDaysBetweenFirstRepaymentDayAndDisbursalDate=(int)noOfDays; DateTime secondRepaymentDay=scheduledDates.get(1); long duration=(secondRepaymentDay.toDate().getTime()-firstRepaymentDay.toDate().getTime())/(1000*60*60*24); int noOfDaysInOneSchedule=(int)duration; prorateValue = new ConfigurationPersistence().getConfigurationValueInteger(PRORATE_RULE); if (prorateValue==1) lstInstallmntPricplIntrst = allDecliningEPIInstallments_v2(loanAmount, numberOfInstallments, interestFractionalRatePerInstallment, graceType, gracePeriodDuration,noOfDaysBetweenFirstRepaymentDayAndDisbursalDate,noOfDaysInOneSchedule); } if (prorateValue != 1){ lstInstallmntPricplIntrst = allDecliningEPIInstallments_v2(loanAmount, numberOfInstallments, interestFractionalRatePerInstallment, graceType, gracePeriodDuration); } return lstInstallmntPricplIntrst;}  @Override List<InstallmentPrincipalAndInterest> generateEqualInstallments(LoanInterestCalculationDetails loanInterestCalculationDetails);  }
@Test public void shouldReturnPrincipalAndInterestDetailsForMatchingNumberOfInstallments() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.NONE) .withGraceDurationOf(0) .withNumberOfInstallments(1) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(equalInstallments.size(), is(1)); }
@Test public void shouldReturnPrincipalAndInterestDetailsForMatchingNumberOfInstallments_larger() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.NONE) .withGraceDurationOf(0) .withNumberOfInstallments(20) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(equalInstallments.size(), is(20)); }
@Test public void givenNoGraceOnAnyInstallmentShouldReturnPrincipalAndInterestDueForEachInstallment() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.NONE) .withGraceDurationOf(0) .withNumberOfInstallments(1) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getPrincipal()), is(TestMoneyUtil.moneyOf("100"))); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getInterest()), is(TestMoneyUtil.moneyOf("16.0"))); }
@Test public void givenGraceOnAllRepaymentsShouldReturnPrincipalAndInterestDueForEachInstallment() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.GRACEONALLREPAYMENTS) .withGraceDurationOf(0) .withNumberOfInstallments(1) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getPrincipal()), is(TestMoneyUtil.moneyOf("100"))); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getInterest()), is(TestMoneyUtil.moneyOf("16.0"))); }
@Test public void givenGraceOnAllRepaymentsShouldReturnPrincipalAndInterestDueForEachInstallmentRelativeToLoanAmount() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.GRACEONALLREPAYMENTS) .withGraceDurationOf(0) .withNumberOfInstallments(10) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getPrincipal()), is(TestMoneyUtil.moneyOf("10.0"))); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getInterest()), is(TestMoneyUtil.moneyOf("16.0"))); }
@Test public void givenPrincipalOnlyGraceShouldReturnPrincipalAndInterestDueForEachInstallmentRelativeToLoanAmount() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.PRINCIPALONLYGRACE) .withGraceDurationOf(0) .withNumberOfInstallments(10) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getPrincipal()), is(TestMoneyUtil.moneyOf("10.0"))); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getInterest()), is(TestMoneyUtil.moneyOf("16.0"))); }
@Test public void givenPrincipalOnlyGraceForFourInstallmentsShouldReturnPrincipalAndInterestDueForEachInstallmentRelativeToLoanAmount() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.PRINCIPALONLYGRACE) .withGraceDurationOf(4) .withNumberOfInstallments(10) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("10.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getPrincipal()), is(TestMoneyUtil.moneyOf("0.0"))); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getInterest()), is(TestMoneyUtil.moneyOf("16.0"))); }
@Test public void givenNoGraceWithZeroInterestShouldReturnPrincipalAndInterestDueForEachInstallmentRelativeToLoanAmount() { LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetailsBuilder().withLoanAmount("100.0") .withGraceType(GraceType.NONE) .withGraceDurationOf(0) .withNumberOfInstallments(10) .withInterestFractionalRatePerInstallmentOf("0.16") .withInterestRate("0.0") .build(); List<InstallmentPrincipalAndInterest> equalInstallments = principalWithInterestGenerator.generateEqualInstallments(loanInterestCalculationDetails); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getPrincipal()), is(TestMoneyUtil.moneyOf("10.0"))); assertThat(TestMoneyUtil.moneyOf(equalInstallments.get(0).getInterest()), is(TestMoneyUtil.moneyOf("16.0"))); }