Skip to content

Commit

Permalink
FINERACT-1745: Loan Schedule Final Installment calculation issue (#2690)
Browse files Browse the repository at this point in the history
  • Loading branch information
logoutdhaval authored and vidakovic committed Nov 28, 2022
1 parent 0d7b7e2 commit 931946e
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2313,6 +2313,7 @@ private LoanScheduleDTO rescheduleNextInstallments(final MathContext mc, final L
int period = periodNumber;
if (!lastInstallmentDate.isEqual(installment.getDueDate())) {
period--;
periodNumber = period;
}
reducePrincipal = fetchEarlyPaidAmount(installment.getPrincipal(currency), principalPortionCalculated, reducePrincipal,
loanApplicationTerms, totalCumulativePrincipal, period, mc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public PrincipalInterest calculatePrincipalInterestComponentsForPeriod(final Pay
final double interestCalculationGraceOnRepaymentPeriodFraction, final Money totalCumulativePrincipal,
@SuppressWarnings("unused") final Money totalCumulativeInterest,
@SuppressWarnings("unused") final Money totalInterestDueForLoan, final Money cumulatingInterestPaymentDueToGrace,
final Money outstandingBalance, final LoanApplicationTerms loanApplicationTerms, final int periodNumber, final MathContext mc,
final Money outstandingBalance, final LoanApplicationTerms loanApplicationTerms, int periodNumber, final MathContext mc,
final TreeMap<LocalDate, Money> principalVariation, final Map<LocalDate, Money> compoundingMap, final LocalDate periodStartDate,
final LocalDate periodEndDate, final Collection<LoanTermVariationsData> termVariations) {

Expand Down Expand Up @@ -157,7 +157,6 @@ public PrincipalInterest calculatePrincipalInterestComponentsForPeriod(final Pay
// update cumulative fields for principal & interest
final Money interestBroughtFowardDueToGrace = cumulatingInterestDueToGrace;
final Money totalCumulativePrincipalToDate = totalCumulativePrincipal.plus(principalForThisInstallment);

// adjust if needed
principalForThisInstallment = loanApplicationTerms.adjustPrincipalIfLastRepaymentPeriod(principalForThisInstallment,
totalCumulativePrincipalToDate, periodNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6091,6 +6091,86 @@ public void testLoanScheduleWithInterestRecalculationForLateRepaymentOfLateRepay
WorkingDaysHelper.updateWorkingDays(this.requestSpec, this.responseSpec);
}

@Test
public void testLoanScheduleWithInterestRecalculationForLastInstallmentAmountNotMoreThanEMI() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
WorkingDaysHelper.updateWorkingDaysWeekDays(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "42", true);
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "43", true);
final String loanDisbursementDate = "06 May 2022";
String firstRepayment = "27 May 2022";
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
String principalAmount = "7800.00";
String rateOfInterest = "8.9";
String numberOfRepayments = "12";
final Integer loanProductID = createLoanProductWithInterestRecalculationAndCompoundingDetails(
LoanProductTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY,
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD,
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12", numberOfRepayments, principalAmount,
rateOfInterest);

final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, loanDisbursementDate,
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment, numberOfRepayments,
principalAmount, rateOfInterest);

Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);

LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);

LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate, loanID,
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);

ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
Assertions.assertNotNull(loanSchedule);

this.loanTransactionHelper.makeRepayment("27 May 2022", 1080.0F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("27 June 2022", 1080.0F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("27 July 2022", 1080.0F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("30 August 2022", 1080.0F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("01 September 2022", 17.01F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("01 September 2022", 34.02F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("27 September 2022", 1080.0F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

this.loanTransactionHelper.makeRepayment("27 October 2022", 1080.0F, loanID);
Assertions.assertTrue(
this.loanTransactionHelper.checkForLastInstallmentLessThanEMI(this.requestSpec, this.responseSpec, loanID, 1080.0F));

WorkingDaysHelper.updateWorkingDays(this.requestSpec, this.responseSpec);
}

private Calendar convertStringDateToCalender(final String stringDate) {
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar date = Calendar.getInstance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,4 +943,13 @@ public String getOutputTemplateLocation(final String importDocumentId) {
return Utils.performServerOutputTemplateLocationGet(requestSpec, responseSpec,
"/fineract-provider/api/v1/imports/getOutputTemplateLocation" + "?" + Utils.TENANT_IDENTIFIER, importDocumentId);
}

public boolean checkForLastInstallmentLessThanEMI(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID, final Float emiAmount) {
ArrayList<HashMap> loanSchedule = this.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
String principal = String.valueOf(loanSchedule.get(loanSchedule.size() - 1).get("principalOriginalDue"));
String interest = String.valueOf(loanSchedule.get(loanSchedule.size() - 1).get("interestOriginalDue"));
Float amount = Float.parseFloat(principal) + Float.parseFloat(interest);
return amount.compareTo(emiAmount) <= 0;
}
}

0 comments on commit 931946e

Please sign in to comment.