This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git

commit cb82af119b3005a2f3f7cb26cd1d8b3c674454ce
Author: CsengeSóti <[email protected]>
AuthorDate: Sat Jun 14 01:46:09 2025 +0200

    FINERACT-2181: fix prepayment functionality when prepayment happens in the 
first month of loan
---
 .../loanaccount/data/ScheduleGeneratorDTO.java     |  10 +-
 .../AbstractCumulativeLoanScheduleGenerator.java   |   3 +-
 .../loanschedule/domain/LoanScheduleGenerator.java |   4 +
 .../domain/ProgressiveLoanScheduleGenerator.java   |   8 +
 .../domain/LoanAccountDomainServiceJpa.java        |  17 ++-
 .../LoanTransactionProcessingServiceImpl.java      |   2 +-
 .../loanaccount/service/LoanUtilService.java       |  10 +-
 .../loan/repayment/LoanRepaymentTest.java          | 167 +++++++++++++++++++++
 8 files changed, 213 insertions(+), 8 deletions(-)

diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/ScheduleGeneratorDTO.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/ScheduleGeneratorDTO.java
index 6d85063bc9..3bea4792bf 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/ScheduleGeneratorDTO.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/ScheduleGeneratorDTO.java
@@ -35,6 +35,7 @@ public class ScheduleGeneratorDTO {
     final CalendarInstance calendarInstanceForInterestRecalculation;
     final CalendarInstance compoundingCalendarInstance;
     LocalDate recalculateFrom;
+    LocalDate recalculateTill;
     final Long overdurPenaltyWaitPeriod;
     final FloatingRateDTO floatingRateDTO;
     final Calendar calendar;
@@ -50,8 +51,8 @@ public class ScheduleGeneratorDTO {
     public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory 
loanScheduleFactory, final CurrencyData currency,
             final LocalDate calculatedRepaymentsStartingFromDate, final 
HolidayDetailDTO holidayDetailDTO,
             final CalendarInstance calendarInstanceForInterestRecalculation, 
final CalendarInstance compoundingCalendarInstance,
-            final LocalDate recalculateFrom, final Long 
overdurPenaltyWaitPeriod, final FloatingRateDTO floatingRateDTO,
-            final Calendar calendar, final CalendarHistoryDataWrapper 
calendarHistoryDataWrapper,
+            final LocalDate recalculateFrom, final LocalDate recalculateTill, 
final Long overdurPenaltyWaitPeriod,
+            final FloatingRateDTO floatingRateDTO, final Calendar calendar, 
final CalendarHistoryDataWrapper calendarHistoryDataWrapper,
             final Boolean isInterestChargedFromDateAsDisbursementDateEnabled, 
final Integer numberOfdays,
             final boolean isSkipRepaymentOnFirstDayofMonth, final Boolean 
isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled,
             final boolean isFirstRepaymentDateAllowedOnHoliday, final boolean 
isInterestToBeRecoveredFirstWhenGreaterThanEMI,
@@ -63,6 +64,7 @@ public class ScheduleGeneratorDTO {
         this.calendarInstanceForInterestRecalculation = 
calendarInstanceForInterestRecalculation;
         this.compoundingCalendarInstance = compoundingCalendarInstance;
         this.recalculateFrom = recalculateFrom;
+        this.recalculateTill = recalculateTill;
         this.overdurPenaltyWaitPeriod = overdurPenaltyWaitPeriod;
         this.holidayDetailDTO = holidayDetailDTO;
         this.floatingRateDTO = floatingRateDTO;
@@ -97,6 +99,10 @@ public class ScheduleGeneratorDTO {
         return this.recalculateFrom;
     }
 
+    public LocalDate getRecalculateTill() {
+        return this.recalculateTill;
+    }
+
     public Long getOverdurPenaltyWaitPeriod() {
         return this.overdurPenaltyWaitPeriod;
     }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
index f92112531d..7ebfb54db9 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
@@ -2186,7 +2186,8 @@ public abstract class 
AbstractCumulativeLoanScheduleGenerator implements LoanSch
 
     }
 
-    private LoanScheduleDTO rescheduleNextInstallments(final MathContext mc, 
final LoanApplicationTerms loanApplicationTerms, Loan loan,
+    @Override
+    public LoanScheduleDTO rescheduleNextInstallments(final MathContext mc, 
final LoanApplicationTerms loanApplicationTerms, Loan loan,
             final HolidayDetailDTO holidayDetailDTO,
             final LoanRepaymentScheduleTransactionProcessor 
loanRepaymentScheduleTransactionProcessor, LocalDate rescheduleFrom,
             final LocalDate scheduleTillDate) {
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleGenerator.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleGenerator.java
index 33666a7976..abe62c20e2 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleGenerator.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleGenerator.java
@@ -41,6 +41,10 @@ public interface LoanScheduleGenerator {
             HolidayDetailDTO holidayDetailDTO, 
LoanRepaymentScheduleTransactionProcessor 
loanRepaymentScheduleTransactionProcessor,
             LocalDate rescheduleFrom);
 
+    LoanScheduleDTO rescheduleNextInstallments(MathContext mc, 
LoanApplicationTerms loanApplicationTerms, Loan loan,
+            HolidayDetailDTO holidayDetailDTO, 
LoanRepaymentScheduleTransactionProcessor 
loanRepaymentScheduleTransactionProcessor,
+            LocalDate rescheduleFrom, LocalDate rescheduleTill);
+
     OutstandingAmountsDTO calculatePrepaymentAmount(MonetaryCurrency currency, 
LocalDate onDate, LoanApplicationTerms loanApplicationTerms,
             MathContext mc, Loan loan, HolidayDetailDTO holidayDetailDTO,
             LoanRepaymentScheduleTransactionProcessor 
loanRepaymentScheduleTransactionProcessor);
diff --git 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
index 5e3f85ffd9..4ce430ccf8 100644
--- 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
+++ 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
@@ -175,6 +175,14 @@ public class ProgressiveLoanScheduleGenerator implements 
LoanScheduleGenerator {
         return LoanScheduleDTO.from(null, model);
     }
 
+    @Override
+    public LoanScheduleDTO rescheduleNextInstallments(MathContext mc, 
LoanApplicationTerms loanApplicationTerms, Loan loan,
+            HolidayDetailDTO holidayDetailDTO, 
LoanRepaymentScheduleTransactionProcessor 
loanRepaymentScheduleTransactionProcessor,
+            LocalDate rescheduleFrom, LocalDate rescheduleTill) {
+        return rescheduleNextInstallments(mc, loanApplicationTerms, loan, 
holidayDetailDTO, loanRepaymentScheduleTransactionProcessor,
+                rescheduleFrom);
+    }
+
     @Override
     public OutstandingAmountsDTO calculatePrepaymentAmount(MonetaryCurrency 
currency, LocalDate onDate,
             LoanApplicationTerms loanApplicationTerms, MathContext mc, Loan 
loan, HolidayDetailDTO holidayDetailDTO,
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
index 8cf7b662e4..e3e25ce8cc 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
@@ -242,11 +242,24 @@ public class LoanAccountDomainServiceJpa implements 
LoanAccountDomainService {
         }
 
         LocalDate recalculateFrom = null;
-        if (loan.isInterestBearingAndInterestRecalculationEnabled()) {
+        if (loan.isInterestBearingAndInterestRecalculationEnabled() && 
loan.getLoanProduct().getProductInterestRecalculationDetails()
+                
.getPreCloseInterestCalculationStrategy().calculateTillPreClosureDateEnabled()) 
{
             recalculateFrom = transactionDate;
         }
+        final ScheduleGeneratorDTO scheduleGeneratorDTOForPrepay = 
this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom,
+                transactionDate, holidayDetailDto);
+
+        Money outstanding = 
loanTransactionProcessingService.fetchPrepaymentDetail(scheduleGeneratorDTOForPrepay,
 transactionDate, loan)
+                .getTotalOutstanding();
+        LocalDate recalculateTill = null;
+        if (repaymentAmount.isGreaterThanOrEqualTo(outstanding) && 
loan.isInterestBearingAndInterestRecalculationEnabled()
+                && 
loan.getLoanProduct().getProductInterestRecalculationDetails().getPreCloseInterestCalculationStrategy()
+                        .calculateTillPreClosureDateEnabled()) {
+            recalculateTill = transactionDate;
+        }
+
         final ScheduleGeneratorDTO scheduleGeneratorDTO = 
this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom,
-                holidayDetailDto);
+                recalculateTill, holidayDetailDto);
 
         if (!isHolidayValidationDone) {
             final HolidayDetailDTO holidayDetailDTO = 
scheduleGeneratorDTO.getHolidayDetailDTO();
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanTransactionProcessingServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanTransactionProcessingServiceImpl.java
index d9d53a6ca7..a8a358a3f8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanTransactionProcessingServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanTransactionProcessingServiceImpl.java
@@ -200,7 +200,7 @@ public class LoanTransactionProcessingServiceImpl 
implements LoanTransactionProc
                 loan.getTransactionProcessingStrategyCode());
 
         return loanScheduleGenerator.rescheduleNextInstallments(mc, 
loanApplicationTerms, loan, generatorDTO.getHolidayDetailDTO(),
-                loanRepaymentScheduleTransactionProcessor, 
generatorDTO.getRecalculateFrom());
+                loanRepaymentScheduleTransactionProcessor, 
generatorDTO.getRecalculateFrom(), generatorDTO.getRecalculateTill());
     }
 
     @Override
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java
index 123d717987..d924132b43 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java
@@ -76,10 +76,16 @@ public class LoanUtilService {
 
     public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan, 
final LocalDate recalculateFrom) {
         final HolidayDetailDTO holidayDetailDTO = null;
-        return buildScheduleGeneratorDTO(loan, recalculateFrom, 
holidayDetailDTO);
+        return buildScheduleGeneratorDTO(loan, recalculateFrom, null, 
holidayDetailDTO);
     }
 
     public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan, 
final LocalDate recalculateFrom,
+            final LocalDate rescheduleTill) {
+        final HolidayDetailDTO holidayDetailDTO = null;
+        return buildScheduleGeneratorDTO(loan, recalculateFrom, 
rescheduleTill, holidayDetailDTO);
+    }
+
+    public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan, 
final LocalDate recalculateFrom, final LocalDate recalculateTill,
             final HolidayDetailDTO holidayDetailDTO) {
         HolidayDetailDTO holidayDetails = holidayDetailDTO;
         if (holidayDetailDTO == null) {
@@ -133,7 +139,7 @@ public class LoanUtilService {
 
         ScheduleGeneratorDTO scheduleGeneratorDTO = new 
ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency.toData(),
                 calculatedRepaymentsStartingFromDate, holidayDetails, 
restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
-                overdurPenaltyWaitPeriod, floatingRateDTO, calendar, 
calendarHistoryDataWrapper,
+                recalculateTill, overdurPenaltyWaitPeriod, floatingRateDTO, 
calendar, calendarHistoryDataWrapper,
                 isInterestChargedFromDateAsDisbursementDateEnabled, 
numberOfDays, isSkipRepaymentOnFirstMonth,
                 isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled, 
isFirstRepaymentDateAllowedOnHoliday,
                 isInterestToBeRecoveredFirstWhenGreaterThanEMI, 
isPrincipalCompoundingDisabledForOverdueLoans);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/repayment/LoanRepaymentTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/repayment/LoanRepaymentTest.java
index ea4d852b1b..3bcde40ee5 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/repayment/LoanRepaymentTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/repayment/LoanRepaymentTest.java
@@ -134,4 +134,171 @@ public class LoanRepaymentTest extends 
BaseLoanIntegrationTest {
             );
         });
     }
+
+    @Test
+    public void 
test_LoanRepaymentWorks_WhenOnlyOneInstallment_AndAccrualAccounting_AndMonthlyRecalculateInterest_AndMonthlyInterestCalculationPeriod_AllowPartial()
 {
+
+        runAt("31 January 2023", () -> {
+            // Create Client
+            Long clientId = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+
+            int numberOfRepayments = 1;
+            int repaymentEvery = 1;
+
+            // Create Loan Product
+            PostLoanProductsRequest product = 
createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() //
+                    .numberOfRepayments(numberOfRepayments) //
+                    .repaymentEvery(repaymentEvery) //
+                    .installmentAmountInMultiplesOf(null) //
+                    
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue()) //
+                    .interestType(InterestType.DECLINING_BALANCE)//
+                    
.interestCalculationPeriodType(InterestCalculationPeriodType.SAME_AS_REPAYMENT_PERIOD)//
+                    
.interestRecalculationCompoundingMethod(InterestRecalculationCompoundingMethod.NONE)//
+                    
.rescheduleStrategyMethod(RescheduleStrategyMethod.ADJUST_LAST_UNPAID_PERIOD)//
+                    .isInterestRecalculationEnabled(true)//
+                    .recalculationRestFrequencyInterval(1)//
+                    
.recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD)//
+                    
.rescheduleStrategyMethod(RescheduleStrategyMethod.REDUCE_EMI_AMOUNT)//
+                    .allowPartialPeriodInterestCalcualtion(true)//
+                    
.preClosureInterestCalculationStrategy(1).disallowExpectedDisbursements(false)//
+                    .allowApprovedDisbursedAmountsOverApplied(false)//
+                    .overAppliedNumber(null)//
+                    .overAppliedCalculationType(null)//
+                    .interestRatePerPeriod(10.0)//
+                    .multiDisburseLoan(null);//
+
+            PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(product);
+            Long loanProductId = loanProductResponse.getResourceId();
+
+            // Apply and Approve Loan
+            double amount = 1000.0;
+
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, 
loanProductId, "01 January 2023", amount, numberOfRepayments)//
+                    .repaymentEvery(repaymentEvery)//
+                    .loanTermFrequency(numberOfRepayments)//
+                    .repaymentFrequencyType(RepaymentFrequencyType.MONTHS)//
+                    .loanTermFrequencyType(RepaymentFrequencyType.MONTHS)//
+                    .interestType(InterestType.DECLINING_BALANCE)//
+                    .interestRatePerPeriod(BigDecimal.valueOf(10.0))//
+                    
.interestCalculationPeriodType(InterestCalculationPeriodType.SAME_AS_REPAYMENT_PERIOD);//
+
+            PostLoansResponse postLoansResponse = 
loanTransactionHelper.applyLoan(applicationRequest);
+
+            PostLoansLoanIdResponse approvedLoanResult = 
loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
+                    approveLoanRequest(amount, "01 January 2023"));
+
+            Long loanId = approvedLoanResult.getLoanId();
+
+            // disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(1000.0), "01 January 
2023");
+
+            // verify transactions
+            verifyTransactions(loanId, //
+                    transaction(1000.0, "Disbursement", "01 January 2023")//
+            );
+
+            verifyPrepayAmountByRepayment(loanId, "15 January 2023");
+
+            // verify transactions
+            verifyTransactions(loanId, //
+                    transaction(1000.0, "Disbursement", "01 January 2023"), //
+                    transaction(1045.16, "Repayment", "15 January 2023"), //
+                    transaction(45.16, "Accrual", "15 January 2023") //
+            );
+
+            // verify journal entries
+            verifyJournalEntries(loanId,
+
+                    journalEntry(1000.0, loansReceivableAccount, "DEBIT"), 
journalEntry(1000.0, fundSource, "CREDIT"),
+                    journalEntry(1045.16, fundSource, "DEBIT"), 
journalEntry(45.16, interestReceivableAccount, "CREDIT"),
+                    journalEntry(45.16, interestReceivableAccount, "DEBIT"), 
journalEntry(45.16, interestIncomeAccount, "CREDIT"),
+                    journalEntry(1000.0, fundSource, "CREDIT")
+
+            );
+        });
+    }
+
+    @Test
+    public void 
test_LoanRepaymentWorks_WhenOnlyOneInstallment_AndAccrualAccounting_AndDailyRecalculateInterest_AndMonthlyInterestCalculationPeriod_NotAllowPartial()
 {
+
+        runAt("31 January 2023", () -> {
+            // Create Client
+            Long clientId = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+
+            int numberOfRepayments = 1;
+            int repaymentEvery = 1;
+
+            // Create Loan Product
+            PostLoanProductsRequest product = 
createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() //
+                    .numberOfRepayments(numberOfRepayments) //
+                    .repaymentEvery(repaymentEvery) //
+                    .installmentAmountInMultiplesOf(null) //
+                    
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue()) //
+                    .interestType(InterestType.DECLINING_BALANCE)//
+                    
.interestCalculationPeriodType(InterestCalculationPeriodType.SAME_AS_REPAYMENT_PERIOD)//
+                    
.interestRecalculationCompoundingMethod(InterestRecalculationCompoundingMethod.NONE)//
+                    
.rescheduleStrategyMethod(RescheduleStrategyMethod.ADJUST_LAST_UNPAID_PERIOD)//
+                    .isInterestRecalculationEnabled(true)//
+                    .recalculationRestFrequencyInterval(1)//
+                    
.recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD)//
+                    
.rescheduleStrategyMethod(RescheduleStrategyMethod.REDUCE_EMI_AMOUNT)//
+                    .allowPartialPeriodInterestCalcualtion(true)//
+                    
.preClosureInterestCalculationStrategy(2).disallowExpectedDisbursements(false)//
+                    .allowApprovedDisbursedAmountsOverApplied(false)//
+                    .overAppliedNumber(null)//
+                    .overAppliedCalculationType(null)//
+                    .interestRatePerPeriod(10.0)//
+                    .multiDisburseLoan(null);//
+
+            PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(product);
+            Long loanProductId = loanProductResponse.getResourceId();
+
+            // Apply and Approve Loan
+            double amount = 1000.0;
+
+            PostLoansRequest applicationRequest = applyLoanRequest(clientId, 
loanProductId, "01 January 2023", amount, numberOfRepayments)//
+                    .repaymentEvery(repaymentEvery)//
+                    .loanTermFrequency(numberOfRepayments)//
+                    .repaymentFrequencyType(RepaymentFrequencyType.MONTHS)//
+                    .loanTermFrequencyType(RepaymentFrequencyType.MONTHS)//
+                    .interestType(InterestType.DECLINING_BALANCE)//
+                    .interestRatePerPeriod(BigDecimal.valueOf(10.0))//
+                    
.interestCalculationPeriodType(InterestCalculationPeriodType.SAME_AS_REPAYMENT_PERIOD);//
+
+            PostLoansResponse postLoansResponse = 
loanTransactionHelper.applyLoan(applicationRequest);
+
+            PostLoansLoanIdResponse approvedLoanResult = 
loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
+                    approveLoanRequest(amount, "01 January 2023"));
+
+            Long loanId = approvedLoanResult.getLoanId();
+
+            // disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(1000.0), "01 January 
2023");
+
+            // verify transactions
+            verifyTransactions(loanId, //
+                    transaction(1000.0, "Disbursement", "01 January 2023")//
+            );
+
+            verifyPrepayAmountByRepayment(loanId, "15 January 2023");
+
+            // verify transactions
+            verifyTransactions(loanId, //
+                    transaction(1000.0, "Disbursement", "01 January 2023"), //
+                    transaction(1100.0, "Repayment", "15 January 2023"), //
+                    transaction(100.0, "Accrual", "15 January 2023") //
+            );
+
+            // verify journal entries
+            verifyJournalEntries(loanId,
+
+                    journalEntry(1000.0, loansReceivableAccount, "DEBIT"), 
journalEntry(1000.0, fundSource, "CREDIT"),
+                    journalEntry(1100.0, fundSource, "DEBIT"), 
journalEntry(100.0, interestReceivableAccount, "CREDIT"),
+                    journalEntry(100.0, interestReceivableAccount, "DEBIT"), 
journalEntry(100.0, interestIncomeAccount, "CREDIT"),
+                    journalEntry(1000.0, fundSource, "CREDIT")
+
+            );
+        });
+    }
+
 }

Reply via email to