Skip to content

Commit f0eff02

Browse files
committed
FINERACT-2520: Add disbursement charges to total repayment expected
Signed-off-by: Wiki05 <vigneshdev1022@gmail.com>
1 parent 9eb94dd commit f0eff02

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer
144144
scheduleParams.incrementPeriodNumber();
145145
}
146146

147+
if (chargesDueAtTimeOfDisbursement.compareTo(BigDecimal.ZERO) > 0) {
148+
scheduleParams.addTotalRepaymentExpected(Money.of(currency, chargesDueAtTimeOfDisbursement, mc));
149+
}
150+
147151
if (loanApplicationTerms.isMultiDisburseLoan()) {
148152
processDisbursements(loanApplicationTerms, disbursementDataList, scheduleParams, interestScheduleModel, periods,
149153
chargesDueAtTimeOfDisbursement, true, mc);

fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleGeneratorTest.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020

2121
import static org.junit.jupiter.api.Assertions.assertEquals;
2222
import static org.mockito.Mockito.mock;
23+
import static org.mockito.Mockito.when;
2324

2425
import java.math.BigDecimal;
2526
import java.math.MathContext;
2627
import java.math.RoundingMode;
2728
import java.time.LocalDate;
2829
import org.apache.fineract.organisation.monetary.data.CurrencyData;
2930
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
31+
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
32+
import org.apache.fineract.organisation.monetary.domain.Money;
3033
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
3134
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
3235
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePlan;
@@ -49,6 +52,7 @@ class LoanScheduleGeneratorTest {
4952
private static final CurrencyData CURRENCY = APPLICATION_CURRENCY.toData();
5053
private static final BigDecimal DISBURSEMENT_AMOUNT = BigDecimal.valueOf(192.22);
5154
private static final BigDecimal DISBURSEMENT_AMOUNT_100 = BigDecimal.valueOf(100);
55+
private static final BigDecimal DISBURSEMENT_CHARGE = BigDecimal.valueOf(10.0);
5256
private static final BigDecimal NOMINAL_INTEREST_RATE = BigDecimal.valueOf(9.99);
5357
private static final int NUMBER_OF_REPAYMENTS = 6;
5458
private static final int REPAYMENT_FREQUENCY = 1;
@@ -168,4 +172,37 @@ private void checkDownPaymentPeriod(LoanSchedulePlanDownPaymentPeriod period, in
168172
assertEquals(0, expectedTotalDue.compareTo(period.getTotalDueAmount()));
169173
assertEquals(0, expectedOutstandingLoanBalance.compareTo(period.getOutstandingLoanBalance()));
170174
}
171-
}
175+
176+
@Test
177+
void testGenerateLoanScheduleWithDisbursementCharges() {
178+
LoanRepaymentScheduleModelData modelData = new LoanRepaymentScheduleModelData(LocalDate.of(2024, 1, 1), CURRENCY,
179+
DISBURSEMENT_AMOUNT, DISBURSEMENT_DATE, NUMBER_OF_REPAYMENTS, REPAYMENT_FREQUENCY, REPAYMENT_FREQUENCY_TYPE,
180+
NOMINAL_INTEREST_RATE, false, DaysInMonthType.DAYS_30, DaysInYearType.DAYS_360, null, null, null, false, null,
181+
InterestMethod.DECLINING_BALANCE, true, false);
182+
183+
ScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
184+
ProgressiveLoanScheduleGenerator generator = new ProgressiveLoanScheduleGenerator(scheduledDateGenerator, emiCalculator,
185+
interestScheduleModelRepositoryWrapperMock);
186+
generator.setLoanTransactionProcessingService(loanTransactionProcessingService);
187+
188+
LoanSchedulePlan loanSchedule = generator.generate(mc, modelData);
189+
190+
BigDecimal totalPrincipal = BigDecimal.ZERO;
191+
BigDecimal totalInterest = BigDecimal.ZERO;
192+
BigDecimal totalDueAmount = BigDecimal.ZERO;
193+
194+
for (var period : loanSchedule.getPeriods()) {
195+
if (period instanceof LoanSchedulePlanRepaymentPeriod repayment) {
196+
totalPrincipal = totalPrincipal.add(repayment.getPrincipalAmount());
197+
totalInterest = totalInterest.add(repayment.getInterestAmount());
198+
totalDueAmount = totalDueAmount.add(repayment.getTotalDueAmount());
199+
}
200+
}
201+
202+
BigDecimal expectedTotalWithCharge = totalPrincipal.add(totalInterest).add(DISBURSEMENT_CHARGE);
203+
204+
assertEquals(0, expectedTotalWithCharge.compareTo(totalDueAmount),
205+
"The sum of all period totals should include the disbursement charge");
206+
}
207+
208+
}

0 commit comments

Comments
 (0)