FINERACT-2389: Negative amount is shown on repayment schedule

This commit is contained in:
Jose Alberto Hernandez
2025-11-18 14:28:20 +01:00
committed by Adam Saghy
parent 9a16a26d5f
commit 60526f0ce9
7 changed files with 218 additions and 9 deletions
@@ -175,6 +175,8 @@ public enum DefaultLoanProduct implements LoanProduct {
LP1_NO_OVERRIDES, // LP1_NO_OVERRIDES, //
LP2_ADV_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OF_ACCRUAL, // LP2_ADV_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OF_ACCRUAL, //
LP2_ADV_CUSTOM_PMT_ALLOC_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OFF_ACCRUAL, // LP2_ADV_CUSTOM_PMT_ALLOC_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OFF_ACCRUAL, //
LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES, //
LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES, //
; ;
@Override @Override
@@ -4196,6 +4196,48 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
TestContext.INSTANCE.set( TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OF_ACCRUAL, TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OF_ACCRUAL,
responseLoanProductsResponseAdvCustomPaymentAllocationProgressiveLoanInterestDailyEmiActualInterestRecalcZeroChargeOffChargebackAccruals); responseLoanProductsResponseAdvCustomPaymentAllocationProgressiveLoanInterestDailyEmiActualInterestRecalcZeroChargeOffChargebackAccruals);
// LP1 with 12% Flat interest, interest period: Daily, Interest recalculation- Same as repayment
// Multi-disbursement that expects tranches
PostLoanProductsRequest loanProductsRequestInterestFlatSaRRecalculationSameAsRepaymentMultiDisbursementExpectsTranches = loanProductsRequestFactory
.defaultLoanProductsRequestLP1InterestDecliningBalanceDailyRecalculationCompoundingNone()//
.name(DefaultLoanProduct.LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES.getName())//
.interestType(INTEREST_TYPE_FLAT)//
.interestCalculationPeriodType(InterestCalculationPeriodTime.DAILY.value)//
.allowPartialPeriodInterestCalcualtion(false)//
.recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT.value)//
.recalculationRestFrequencyInterval(1)//
.installmentAmountInMultiplesOf(null)//
.multiDisburseLoan(true)//
.disallowExpectedDisbursements(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0);//
Response<PostLoanProductsResponse> responseLoanProductsRequestInterestFlatSaRRecalculationSameAsRepaymentMultiDisbursementExpectsTranches = loanProductsApi
.createLoanProduct(loanProductsRequestInterestFlatSaRRecalculationSameAsRepaymentMultiDisbursementExpectsTranches)
.execute();
TestContext.INSTANCE.set(TestContextKey.LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES,
responseLoanProductsRequestInterestFlatSaRRecalculationSameAsRepaymentMultiDisbursementExpectsTranches);
// LP1 with 12% Flat interest, interest period: Daily, Interest recalculation- Actual
// Multi-disbursement that expects tranches
PostLoanProductsRequest loanProductsRequestInterestFlatActualActualMultiDisbursementExpectsTranches = loanProductsRequestFactory
.defaultLoanProductsRequestLP1InterestFlat()//
.name(DefaultLoanProduct.LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES.getName())//
.interestType(INTEREST_TYPE_FLAT)//
.interestCalculationPeriodType(InterestCalculationPeriodTime.DAILY.value)//
.allowPartialPeriodInterestCalcualtion(false)//
.recalculationRestFrequencyType(RecalculationRestFrequencyType.DAILY.value)//
.interestRecalculationCompoundingMethod(0)//
.recalculationRestFrequencyInterval(1)//
.installmentAmountInMultiplesOf(null)//
.multiDisburseLoan(true)//
.disallowExpectedDisbursements(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0);//
Response<PostLoanProductsResponse> responseLoanProductsRequestInterestFlatActualActualMultiDisbursementExpectsTranches = loanProductsApi
.createLoanProduct(loanProductsRequestInterestFlatActualActualMultiDisbursementExpectsTranches).execute();
TestContext.INSTANCE.set(TestContextKey.LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES,
responseLoanProductsRequestInterestFlatActualActualMultiDisbursementExpectsTranches);
} }
public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule, public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule,
@@ -282,4 +282,6 @@ public abstract class TestContextKey {
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_NO_OVERRIDES = "loanProductCreateResponseLP1NoOverrides"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_NO_OVERRIDES = "loanProductCreateResponseLP1NoOverrides";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OF_ACCRUAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualInterestRecalcChargeOffAccruals"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OF_ACCRUAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualInterestRecalcChargeOffAccruals";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_CUSTOM_PMT_ALLOC_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OFF_ACCRUAL = "loanProductCreateResponseLP2AdvancedPaymentCustomAllocationInterestDailyEmiActualInterestRecalcChargeOffAccruals"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_CUSTOM_PMT_ALLOC_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OFF_ACCRUAL = "loanProductCreateResponseLP2AdvancedPaymentCustomAllocationInterestDailyEmiActualInterestRecalcChargeOffAccruals";
public static final String LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES = "loanProductCreateResponseLP1InterestFlatDailyRecalculationSameAsRepaymentMultiDisbursementExpectTranches";
public static final String LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES = "loanProductCreateResponseLP1InterestFlatDailyActualActualMultiDisbursementExpectTranches";
} }
@@ -8861,3 +8861,164 @@ Feature: Loan
| 06 November 2025 | Accrual | 1.21 | 0.0 | 1.21 | 0.0 | 0.0 | 0.0 | false | false | | 06 November 2025 | Accrual | 1.21 | 0.0 | 1.21 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "06 November 2025" with 35.28 EUR transaction amount And Customer makes "AUTOPAY" repayment on "06 November 2025" with 35.28 EUR transaction amount
Then Loan status will be "CLOSED_OBLIGATIONS_MET" Then Loan status will be "CLOSED_OBLIGATIONS_MET"
@TestRailId:C4124
Scenario: Verify cumulative multidisbursal loan that expects tranches with flat interest type and daily interest calculation period - UC7
When Admin sets the business date to "01 January 2025"
When Admin creates a client with random data
When Admin creates a fully customized loan with disbursements details and following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | 1st_tranche_disb_expected_date |1st_tranche_disb_principal | 2nd_tranche_disb_expected_date |2nd_tranche_disb_principal |
| LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES | 01 January 2025 | 1500 | 7 | FLAT | DAILY | EQUAL_INSTALLMENTS | 3 | MONTHS | 1 | MONTHS | 3 | 0 | 0 | 0 | PENALTIES_FEES_INTEREST_PRINCIPAL_ORDER | 01 January 2025 | 1000.0 | 15 January 2025 | 500.0 |
And Admin successfully approves the loan on "01 January 2025" with "1500" amount and expected disbursement date on "01 January 2025"
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 25.89 | 0.0 | 0.0 | 1525.89 | 0.0 | 0.0 | 0.0 | 1525.89 |
Then Loan Transactions tab has none transaction
When Admin successfully disburse the loan on "01 January 2025" with "1000" EUR transaction amount
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 5.76 | 0.0 | 0.0 | 505.76 | 0.0 | 0.0 | 0.0 | 505.76 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 17.26 | 0.0 | 0.0 | 1517.26 | 0.0 | 0.0 | 0.0 | 1517.26 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2025 | 01 January 2025 | 1000.0 | |
| 15 January 2025 | | 500.0 | |
# -- 2nd disb - on Jan, 15, 2025 --#
When Admin sets the business date to "15 January 2025"
When Admin successfully disburse the loan on "15 January 2025" with "500" EUR transaction amount
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 25.89 | 0.0 | 0.0 | 1525.89 | 0.0 | 0.0 | 0.0 | 1525.89 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
| 15 January 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2025 | 01 January 2025 | 1000.0 | |
| 15 January 2025 | 15 January 2025 | 500.0 | |
When Loan Pay-off is made on "15 January 2025"
Then Loan's all installments have obligations met
@TestRailId:4227
Scenario: Verify cumulative multidisbursal loan that expects tranches with flat interest type and no interest calculation period - UC7.1
When Admin sets the business date to "01 January 2025"
When Admin creates a client with random data
When Admin creates a fully customized loan with disbursements details and following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | 1st_tranche_disb_expected_date |1st_tranche_disb_principal | 2nd_tranche_disb_expected_date |2nd_tranche_disb_principal |
| LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES | 01 January 2025 | 1500 | 7 | FLAT | DAILY | EQUAL_INSTALLMENTS | 3 | MONTHS | 1 | MONTHS | 3 | 0 | 0 | 0 | PENALTIES_FEES_INTEREST_PRINCIPAL_ORDER | 01 January 2025 | 1000.0 | 15 January 2025 | 500.0 |
And Admin successfully approves the loan on "01 January 2025" with "1500" amount and expected disbursement date on "01 January 2025"
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 25.89 | 0.0 | 0.0 | 1525.89 | 0.0 | 0.0 | 0.0 | 1525.89 |
Then Loan Transactions tab has none transaction
When Admin successfully disburse the loan on "01 January 2025" with "1000" EUR transaction amount
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 5.76 | 0.0 | 0.0 | 505.76 | 0.0 | 0.0 | 0.0 | 505.76 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 17.26 | 0.0 | 0.0 | 1517.26 | 0.0 | 0.0 | 0.0 | 1517.26 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2025 | 01 January 2025 | 1000.0 | |
| 15 January 2025 | | 500.0 | |
When Admin sets the business date to "16 January 2025"
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 5.76 | 0.0 | 0.0 | 505.76 | 0.0 | 0.0 | 0.0 | 505.76 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 17.26 | 0.0 | 0.0 | 1517.26 | 0.0 | 0.0 | 0.0 | 1517.26 |
When Admin sets the business date to "01 February 2025"
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 15 January 2025 | | 500.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 5.75 | 0.0 | 0.0 | 505.75 | 0.0 | 0.0 | 0.0 | 505.75 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 5.76 | 0.0 | 0.0 | 505.76 | 0.0 | 0.0 | 0.0 | 505.76 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 17.26 | 0.0 | 0.0 | 1517.26 | 0.0 | 0.0 | 0.0 | 1517.26 |
# -- 2nd disb - on Feb, 1, 2025 --#
When Admin successfully disburse the loan on "01 February 2025" with "500" EUR transaction amount
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 01 February 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2025 | | 1000.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 2 | 28 | 01 March 2025 | | 500.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
| 3 | 31 | 01 April 2025 | | 0.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 0.0 | 0.0 | 0.0 | 508.63 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 25.89 | 0.0 | 0.0 | 1525.89 | 0.0 | 0.0 | 0.0 | 1525.89 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
| 01 February 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2025 | 01 January 2025 | 1000.0 | |
| 15 January 2025 | 01 February 2025 | 500.0 | |
When Loan Pay-off is made on "01 February 2025"
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
Then Loan Repayment schedule has 3 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| | | 01 February 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2025 | 01 February 2025 | 1000.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 508.63 | 0.0 | 0.0 | 0.0 |
| 2 | 28 | 01 March 2025 | 01 February 2025 | 500.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 508.63 | 508.63 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2025 | 01 February 2025 | 0.0 | 500.0 | 8.63 | 0.0 | 0.0 | 508.63 | 508.63 | 508.63 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1500.0 | 25.89 | 0.0 | 0.0 | 1525.89 | 1525.89 | 1017.26 | 0.0 | 0.0 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
| 01 February 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
| 01 February 2025 | Repayment | 1525.89 | 1500.0 | 25.89 | 0.0 | 0.0 | 0.0 | false | false |
| 01 February 2025 | Accrual | 25.89 | 0.0 | 25.89 | 0.0 | 0.0 | 0.0 | false | false |
@@ -29,4 +29,5 @@ public class LoanSchedulePeriodDataWrapper {
private final LoanPrincipalRelatedDataHolder data; private final LoanPrincipalRelatedDataHolder data;
private final LocalDate date; private final LocalDate date;
private final boolean isDisbursement; private final boolean isDisbursement;
private final boolean isDisbursed;
} }
@@ -70,8 +70,7 @@ public class LoanRepaymentScheduleService {
final BigDecimal totalFeeChargesDueAtDisbursement = repaymentScheduleRelatedLoanData.getTotalFeeChargesAtDisbursement(); final BigDecimal totalFeeChargesDueAtDisbursement = repaymentScheduleRelatedLoanData.getTotalFeeChargesAtDisbursement();
LocalDate lastDueDate = disbursement.disbursementDate(); LocalDate lastDueDate = disbursement.disbursementDate();
BigDecimal outstandingLoanPrincipalBalance = disbursement.getPrincipal(); BigDecimal outstandingLoanPrincipalBalance = disbursement.getPrincipal();
boolean excludePastUnDisbursed = isInterestRecalculationEnabled; boolean excludePastUnDisbursed = LoanScheduleType.PROGRESSIVE.equals(loanScheduleType) && isInterestRecalculationEnabled;
BigDecimal waivedChargeAmount = BigDecimal.ZERO; BigDecimal waivedChargeAmount = BigDecimal.ZERO;
for (DisbursementData disbursementDetail : disbursementData) { for (DisbursementData disbursementDetail : disbursementData) {
waivedChargeAmount = waivedChargeAmount.add(disbursementDetail.getWaivedChargeAmount()); waivedChargeAmount = waivedChargeAmount.add(disbursementDetail.getWaivedChargeAmount());
@@ -295,16 +294,18 @@ public class LoanRepaymentScheduleService {
if (!disbursedTranches.isEmpty()) { if (!disbursedTranches.isEmpty()) {
for (DisbursementData data : disbursedTranches) { for (DisbursementData data : disbursedTranches) {
disbursementDataList.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true)); disbursementDataList
.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true, data.isDisbursed()));
} }
} else { } else {
for (DisbursementData data : sameDateDisbursements) { for (DisbursementData data : sameDateDisbursements) {
disbursementDataList.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true)); disbursementDataList
.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true, data.isDisbursed()));
} }
} }
} else { } else {
DisbursementData data = sameDateDisbursements.get(0); DisbursementData data = sameDateDisbursements.get(0);
disbursementDataList.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true)); disbursementDataList.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true, data.isDisbursed()));
} }
} }
} else { } else {
@@ -316,7 +317,7 @@ public class LoanRepaymentScheduleService {
&& !disbursementPeriodIds.contains(data.getId()); && !disbursementPeriodIds.contains(data.getId());
if (isEligible) { if (isEligible) {
disbursementDataList.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true)); disbursementDataList.add(new LoanSchedulePeriodDataWrapper(data, data.disbursementDate(), true, data.isDisbursed()));
disbursementPeriodIds.add(data.getId()); disbursementPeriodIds.add(data.getId());
} }
} }
@@ -343,7 +344,7 @@ public class LoanRepaymentScheduleService {
&& !disbursementPeriodIds.contains(data.getTransactionId()); && !disbursementPeriodIds.contains(data.getTransactionId());
if (isEligible) { if (isEligible) {
capitalizedIncomeDataList.add(new LoanSchedulePeriodDataWrapper(data, data.getDate(), false)); capitalizedIncomeDataList.add(new LoanSchedulePeriodDataWrapper(data, data.getDate(), false, false));
disbursementPeriodIds.add(data.getTransactionId()); disbursementPeriodIds.add(data.getTransactionId());
} }
} }
@@ -312,11 +312,11 @@ public class LoanReschedulingWithinCenterTest extends BaseLoanIntegrationTest {
ArrayList loanRepaymnetSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, generalResponseSpec, loanID); ArrayList loanRepaymnetSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, generalResponseSpec, loanID);
// VERIFY RESCHEDULED DATE // VERIFY RESCHEDULED DATE
ArrayList dueDateLoanSchedule = (ArrayList) ((HashMap) loanRepaymnetSchedule.get(2)).get("dueDate"); ArrayList dueDateLoanSchedule = (ArrayList) ((HashMap) loanRepaymnetSchedule.get(3)).get("dueDate");
assertEquals(getDateAsArray(todaysdate, 0), dueDateLoanSchedule); assertEquals(getDateAsArray(todaysdate, 0), dueDateLoanSchedule);
// VERIFY THE INTEREST // VERIFY THE INTEREST
Float interestDue = (Float) ((HashMap) loanRepaymnetSchedule.get(2)).get("interestDue"); Float interestDue = (Float) ((HashMap) loanRepaymnetSchedule.get(3)).get("interestDue");
assertEquals("41.05", String.valueOf(interestDue)); assertEquals("41.05", String.valueOf(interestDue));
// DISBURSE THE SECOND TRANCHE (for let the loan test lifecycle callback to close the loan // DISBURSE THE SECOND TRANCHE (for let the loan test lifecycle callback to close the loan