Skip to content

Commit 7b66505

Browse files
logoutdhavalvidakovic
authored andcommitted
FINERACT-1781:Interest is wrong for the first instalment. (#2709)
1 parent 23fc45c commit 7b66505

2 files changed

Lines changed: 100 additions & 25 deletions

File tree

fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1867,7 +1867,7 @@ private LocalDate calculateInterestStartDateForPeriod(final LoanApplicationTerms
18671867
&& isInterestChargedFromDateSameAsDisbursalDateEnabled) {
18681868
periodStartDateApplicableForInterest = expectedDisbursementDate;
18691869
} else if (periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())) {
1870-
periodStartDateApplicableForInterest = idealDisbursementDate;
1870+
periodStartDateApplicableForInterest = periodStartDate;
18711871
}
18721872
}
18731873
return periodStartDateApplicableForInterest;

integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java

Lines changed: 99 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4608,15 +4608,16 @@ private Integer createLoanProductWithInterestRecalculationAndCompoundingDetails(
46084608
private Integer createLoanProductWithInterestRecalculationAndCompoundingDetails(final String repaymentStrategy,
46094609
final String interestRecalculationCompoundingMethod, final String rescheduleStrategyMethod,
46104610
final String recalculationRestFrequencyType, final String preCloseInterestCalculationStrategy, final Account[] accounts,
4611-
final String installmentMultipleOf) {
4611+
final String installmentMultipleOf, final String numberOfRepayments, final String principalAmount,
4612+
final String rateOfInterest) {
46124613
final String recalculationCompoundingFrequencyType = null;
46134614
final String recalculationCompoundingFrequencyInterval = null;
46144615
final Integer recalculationCompoundingFrequencyOnDayType = null;
46154616
final Integer recalculationCompoundingFrequencyDayOfWeekType = null;
46164617
return createLoanProductWithInterestRecalculation(repaymentStrategy, interestRecalculationCompoundingMethod,
46174618
rescheduleStrategyMethod, recalculationCompoundingFrequencyType, recalculationCompoundingFrequencyInterval,
46184619
preCloseInterestCalculationStrategy, accounts, null, false, recalculationCompoundingFrequencyOnDayType,
4619-
recalculationCompoundingFrequencyDayOfWeekType, installmentMultipleOf);
4620+
recalculationCompoundingFrequencyDayOfWeekType, installmentMultipleOf, numberOfRepayments, principalAmount, rateOfInterest);
46204621
}
46214622

46224623
private Integer createLoanProductWithInterestRecalculation(final String repaymentStrategy,
@@ -4658,12 +4659,13 @@ private Integer createLoanProductWithInterestRecalculation(final String repaymen
46584659
final String recalculationCompoundingFrequencyType, final String recalculationCompoundingFrequencyInterval,
46594660
final String preCloseInterestCalculationStrategy, final Account[] accounts, final String chargeId,
46604661
boolean isArrearsBasedOnOriginalSchedule, final Integer recalculationCompoundingFrequencyOnDayType,
4661-
final Integer recalculationCompoundingFrequencyDayOfWeekType, final String installmentsMultiplesOf) {
4662+
final Integer recalculationCompoundingFrequencyDayOfWeekType, final String installmentsMultiplesOf,
4663+
final String numberOfRepayments, final String principalAmount, final String rateOfInterest) {
46624664
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
4663-
LoanProductTestBuilder builder = new LoanProductTestBuilder().withPrincipal("10000.00").withNumberOfRepayments("12")
4664-
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("19.9")
4665-
.withInterestRateFrequencyTypeAsMonths().withRepaymentStrategy(repaymentStrategy).withAmortizationTypeAsEqualInstallments()
4666-
.withInterestTypeAsDecliningBalance().withInterestCalculationPeriodTypeAsDays()
4665+
LoanProductTestBuilder builder = new LoanProductTestBuilder().withPrincipal(principalAmount)
4666+
.withNumberOfRepayments(numberOfRepayments).withRepaymentAfterEvery("1").withRepaymentTypeAsMonth()
4667+
.withinterestRatePerPeriod(rateOfInterest).withInterestRateFrequencyTypeAsMonths().withRepaymentStrategy(repaymentStrategy)
4668+
.withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance().withInterestCalculationPeriodTypeAsDays()
46674669
.withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod,
46684670
preCloseInterestCalculationStrategy)
46694671
.withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod,
@@ -4738,7 +4740,8 @@ private Integer applyForLoanApplicationForInterestRecalculation(final Integer cl
47384740
}
47394741

47404742
private Integer applyForLoanApplicationForInterestRecalculation(final Integer clientID, final Integer loanProductID,
4741-
final String disbursementDate, final String repaymentStrategy, final String firstRepaymentDate) {
4743+
final String disbursementDate, final String repaymentStrategy, final String firstRepaymentDate, final String numberOfRepayments,
4744+
final String principalAmount, final String rateOfInterest) {
47424745
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
47434746
final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
47444747
Assertions.assertNotNull(collateralId);
@@ -4750,13 +4753,13 @@ private Integer applyForLoanApplicationForInterestRecalculation(final Integer cl
47504753
addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
47514754

47524755
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
4753-
.withPrincipal("10000.00") //
4756+
.withPrincipal(principalAmount) //
47544757
.withLoanTermFrequency("12") //
47554758
.withLoanTermFrequencyAsMonths() //
4756-
.withNumberOfRepayments("12") //
4759+
.withNumberOfRepayments(numberOfRepayments) //
47574760
.withRepaymentEveryAfter("1") //
47584761
.withLoanTermFrequencyAsMonths() //
4759-
.withInterestRatePerPeriod("19.9") //
4762+
.withInterestRatePerPeriod(rateOfInterest) //
47604763
.withAmortizationTypeAsEqualInstallments() //
47614764
.withInterestTypeAsDecliningBalance() //
47624765
.withInterestCalculationPeriodTypeAsDays() //
@@ -5770,15 +5773,20 @@ public void testLoanScheduleWithInterestRecalculationMakePrepaymentAfterRepaymen
57705773
final String loanDisbursementDate = dateFormat.format(startDate.getTime());
57715774
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
57725775
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
5776+
String principalAmount = "10000.00";
5777+
String rateOfInterest = "19.9";
5778+
String numberOfRepayments = "12";
57735779
final Integer loanProductID = createLoanProductWithInterestRecalculationAndCompoundingDetails(
57745780
LoanProductTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY,
57755781
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
57765782
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
57775783
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD,
5778-
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12");
5784+
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12", numberOfRepayments, principalAmount,
5785+
rateOfInterest);
57795786

57805787
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, loanDisbursementDate,
5781-
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment);
5788+
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment, numberOfRepayments,
5789+
principalAmount, rateOfInterest);
57825790

57835791
Assertions.assertNotNull(loanID);
57845792
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
@@ -5831,15 +5839,20 @@ public void testLoanScheduleWithInterestRecalculationMakeAdvancePaymentTillSettl
58315839
final String loanDisbursementDate = dateFormat.format(startDate.getTime());
58325840
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
58335841
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
5842+
String principalAmount = "10000.00";
5843+
String rateOfInterest = "19.9";
5844+
String numberOfRepayments = "12";
58345845
final Integer loanProductID = createLoanProductWithInterestRecalculationAndCompoundingDetails(
58355846
LoanProductTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY,
58365847
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
58375848
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
58385849
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD,
5839-
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12");
5850+
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12", numberOfRepayments, principalAmount,
5851+
rateOfInterest);
58405852

58415853
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, loanDisbursementDate,
5842-
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment);
5854+
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment, numberOfRepayments,
5855+
principalAmount, rateOfInterest);
58435856

58445857
Assertions.assertNotNull(loanID);
58455858
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
@@ -5869,7 +5882,9 @@ public void testLoanScheduleWithInterestRecalculationMakeAdvancePaymentTillSettl
58695882
for (int i = 1; i < loanSchedule.size(); i++) {
58705883

58715884
retrieveDueDate = dateFormat.format(repaymentDate.getTime());
5872-
amount = (Float) loanSchedule.get(i).get("principalOriginalDue") + (Float) loanSchedule.get(i).get("interestOriginalDue");
5885+
String principal = String.valueOf(loanSchedule.get(i).get("principalOriginalDue"));
5886+
String interest = String.valueOf(loanSchedule.get(i).get("interestOriginalDue"));
5887+
amount = Float.parseFloat(principal) + Float.parseFloat(interest);
58735888
if (currentDate.after(repaymentDate)) {
58745889
this.loanTransactionHelper.makeRepayment(retrieveDueDate, amount, loanID);
58755890
} else {
@@ -5894,15 +5909,20 @@ public void testLoanScheduleWithInterestRecalculationAfterLatePayment() {
58945909
String firstRepayment = "01 March 2021";
58955910
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
58965911
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
5912+
String principalAmount = "10000.00";
5913+
String rateOfInterest = "19.9";
5914+
String numberOfRepayments = "12";
58975915
final Integer loanProductID = createLoanProductWithInterestRecalculationAndCompoundingDetails(
58985916
LoanProductTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY,
58995917
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
59005918
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
59015919
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD,
5902-
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12");
5920+
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12", numberOfRepayments, principalAmount,
5921+
rateOfInterest);
59035922

59045923
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, loanDisbursementDate,
5905-
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment);
5924+
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment, numberOfRepayments,
5925+
principalAmount, rateOfInterest);
59065926

59075927
Assertions.assertNotNull(loanID);
59085928
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
@@ -5923,20 +5943,75 @@ public void testLoanScheduleWithInterestRecalculationAfterLatePayment() {
59235943
Assertions.assertNotNull(loanSchedule);
59245944

59255945
List<Map<String, Object>> expectedvalues = new ArrayList<>();
5926-
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 March 2021"), 0, false, "388.11", "1831.89", "0.0", "0.0");
5946+
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 March 2021"), 0, false, "126.41", "2093.59", "0.0", "0.0");
59275947
this.loanTransactionHelper.makeRepayment("01 March 2021", 2220.0F, loanID);
59285948

5929-
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 April 2021"), 0, false, "270.55", "1949.45", "0.0", "0.0");
5949+
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 April 2021"), 0, false, "217.47", "2002.53", "0.0", "0.0");
59305950
this.loanTransactionHelper.makeRepayment("01 April 2021", 2220.0F, loanID);
59315951

5932-
addRepaymentValues(expectedvalues, convertStringDateToCalender("03 May 2021"), 0, false, "264.31", "1955.69", "0.0", "0.0");
5952+
addRepaymentValues(expectedvalues, convertStringDateToCalender("03 May 2021"), 0, false, "198.41", "2021.59", "0.0", "0.0");
59335953
this.loanTransactionHelper.makeRepayment("04 May 2021", 2220.0F, loanID);
59345954

5935-
addRepaymentValues(expectedvalues, convertStringDateToCalender("04 May 2021"), 0, false, "0.0", "61.12", "0.0", "0.0");
5955+
addRepaymentValues(expectedvalues, convertStringDateToCalender("04 May 2021"), 0, false, "0.0", "63.17", "0.0", "0.0");
59365956
this.loanTransactionHelper.makeRepayment("01 June 2021", 2220.0F, loanID);
59375957

5938-
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 June 2021"), 0, false, "496.07", "1662.81", "0.0", "0.0");
5939-
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 July 2021"), 0, false, "535.78", "1684.22", "0.0", "0.0");
5958+
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 June 2021"), 0, false, "424.28", "1732.55", "0.0", "0.0");
5959+
addRepaymentValues(expectedvalues, convertStringDateToCalender("01 July 2021"), 0, false, "446.97", "1773.03", "0.0", "0.0");
5960+
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
5961+
Assertions.assertNotNull(loanSchedule);
5962+
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
5963+
WorkingDaysHelper.updateWorkingDays(this.requestSpec, this.responseSpec);
5964+
}
5965+
5966+
@Test
5967+
public void testInterestForFirstInstallmentWithInterestRecalculation() {
5968+
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
5969+
WorkingDaysHelper.updateWorkingDaysWeekDays(this.requestSpec, this.responseSpec);
5970+
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
5971+
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
5972+
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "42", true);
5973+
5974+
final String loanDisbursementDate = "06 May 2022";
5975+
String firstRepayment = "27 May 2022";
5976+
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
5977+
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
5978+
String principalAmount = "7800.00";
5979+
String rateOfInterest = "8.9";
5980+
String numberOfRepayments = "12";
5981+
final Integer loanProductID = createLoanProductWithInterestRecalculationAndCompoundingDetails(
5982+
LoanProductTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY,
5983+
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
5984+
LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
5985+
LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD,
5986+
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12", numberOfRepayments, principalAmount,
5987+
rateOfInterest);
5988+
5989+
final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, loanDisbursementDate,
5990+
LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment, numberOfRepayments,
5991+
principalAmount, rateOfInterest);
5992+
5993+
Assertions.assertNotNull(loanID);
5994+
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
5995+
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
5996+
5997+
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
5998+
loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
5999+
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
6000+
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
6001+
6002+
LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
6003+
String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID);
6004+
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate, loanID,
6005+
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
6006+
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
6007+
6008+
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
6009+
Assertions.assertNotNull(loanSchedule);
6010+
6011+
List<Map<String, Object>> expectedvalues = new ArrayList<>();
6012+
addRepaymentValues(expectedvalues, convertStringDateToCalender("27 May 2022"), 0, false, "600.72", "479.28", "0.0", "0.0");
6013+
this.loanTransactionHelper.makeRepayment("27 May 2022", 1080.00F, loanID);
6014+
59406015
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
59416016
Assertions.assertNotNull(loanSchedule);
59426017
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);

0 commit comments

Comments
 (0)