FINERACT-2421: Disbursement charge amount incorrect calculation

This commit is contained in:
Jose Alberto Hernandez
2026-02-05 10:41:19 +01:00
committed by Adam Saghy
parent 2620c61afa
commit 1d1876edfd
22 changed files with 136 additions and 116 deletions
@@ -221,4 +221,9 @@ public enum ChargeTimeType {
public boolean isSharesRedeem() { public boolean isSharesRedeem() {
return this.equals(ChargeTimeType.SHARE_REDEEM); return this.equals(ChargeTimeType.SHARE_REDEEM);
} }
public boolean isDisbursementOrTrancheDisbursementCharge() {
return isTimeOfDisbursement() || isTrancheDisbursement();
}
} }
@@ -3590,7 +3590,6 @@ Feature: LoanCharge
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| Disbursement Charge | false | Disbursement | | % Amount | 2.0 | 2.0 | 0.0 | 0.0 | | Disbursement Charge | false | Disbursement | | % Amount | 2.0 | 2.0 | 0.0 | 0.0 |
@Skip
@TestRailId:C3582 @TestRailId:C3582
Scenario: Verify amount+interest disbursement charge for tranche interest bearing progressive loan that doesn't expect tranches with full disbursement - UC8.1.5 Scenario: Verify amount+interest disbursement charge for tranche interest bearing progressive loan that doesn't expect tranches with full disbursement - UC8.1.5
When Admin sets the business date to "01 January 2024" When Admin sets the business date to "01 January 2024"
@@ -3713,7 +3712,6 @@ Feature: LoanCharge
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| Disbursement Charge | false | Disbursement | | % Interest | 0.04 | 0.04 | 0.0 | 0.0 | | Disbursement Charge | false | Disbursement | | % Interest | 0.04 | 0.04 | 0.0 | 0.0 |
@Skip
@TestRailId:C3554 @TestRailId:C3554
Scenario: Verify amount disbursement charge for tranche interest bearing progressive loan that expects one tranche - UC8.2.1 Scenario: Verify amount disbursement charge for tranche interest bearing progressive loan that expects one tranche - UC8.2.1
When Admin sets the business date to "01 January 2024" When Admin sets the business date to "01 January 2024"
@@ -3738,7 +3736,7 @@ Feature: LoanCharge
| 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 70.0 | 1.44 | 1.4 | 0.0 | 72.87 | 1.4 | 0.0 | 0.0 | 71.44 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 1.4 | 0.0 | 0.0 | 71.44 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
@@ -3756,23 +3754,22 @@ Feature: LoanCharge
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 11.91 EUR transaction amount And Customer makes "AUTOPAY" repayment on "01 February 2024" with 11.91 EUR transaction amount
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 70.0 | | | 1.43 | | 1.4 | 1.4 | | | | | | | 01 January 2024 | | 70.0 | | | 1.4 | | 1.4 | 1.4 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 | | 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 46.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 2 | 29 | 01 March 2024 | | 46.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 3 | 31 | 01 April 2024 | | 35.29 | 11.67 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 3 | 31 | 01 April 2024 | | 35.29 | 11.64 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 4 | 30 | 01 May 2024 | | 23.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 4 | 30 | 01 May 2024 | | 23.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 5 | 31 | 01 June 2024 | | 11.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 5 | 31 | 01 June 2024 | | 11.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.44 | 1.4 | 0.0 | 72.84 | 13.31 | 0.0 | 0.0 | 59.53 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 13.31 | 0.0 | 0.0 | 59.53 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
| 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false |
| 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false | | 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false |
@Skip
@TestRailId:C3555 @TestRailId:C3555
Scenario: Verify amount disbursement charge for tranche interest bearing progressive loan that expects two tranches with undo last disbursement - UC8.2.2 Scenario: Verify amount disbursement charge for tranche interest bearing progressive loan that expects two tranches with undo last disbursement - UC8.2.2
When Admin sets the business date to "01 January 2024" When Admin sets the business date to "01 January 2024"
@@ -3783,60 +3780,60 @@ Feature: LoanCharge
| LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE_EXPECT_TRANCHE | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | LOAN_DISBURSEMENT_CHARGE | 2 | 01 January 2024 | 70.0 | 01 February 2024 | 30.0 | | LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE_EXPECT_TRANCHE | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | LOAN_DISBURSEMENT_CHARGE | 2 | 01 January 2024 | 70.0 | 01 February 2024 | 30.0 |
Then Loan Charges tab has the following data: Then Loan Charges tab has the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| Disbursement Charge | false | Disbursement | | % Amount | 2.0 | 0.0 | 0.0 | 2.0 | | Disbursement Charge | false | Disbursement | | % Amount | 1.4 | 0.0 | 0.0 | 1.4 |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024" And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "70" EUR transaction amount When Admin successfully disburse the loan on "01 January 2024" with "70" EUR transaction amount
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 70.0 | | | 2.0 | | 2.0 | 2.0 | | | | | | | 01 January 2024 | | 70.0 | | | 1.4 | | 1.4 | 1.4 | | | |
| 1 | 31 | 01 February 2024 | | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 1 | 31 | 01 February 2024 | | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| | | 01 February 2024 | | 30.0 | | | 0.0 | | 0.0 | 0.0 | | | | | | | 01 February 2024 | | 30.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 2 | 29 | 01 March 2024 | | 46.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 2 | 29 | 01 March 2024 | | 76.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 3 | 31 | 01 April 2024 | | 35.29 | 11.64 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 3 | 31 | 01 April 2024 | | 65.29 | 11.64 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 4 | 30 | 01 May 2024 | | 23.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 4 | 30 | 01 May 2024 | | 53.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 5 | 31 | 01 June 2024 | | 11.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 5 | 31 | 01 June 2024 | | 41.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 30.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 70.0 | 1.44 | 2.0 | 0.0 | 73.44 | 2.0 | 0.0 | 0.0 | 71.44 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 1.4 | 0.0 | 0.0 | 71.44 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
| 01 January 2024 | Repayment (at time of disbursement) | 2.0 | 0.0 | 0.0 | 2.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false |
Then Loan Charges tab has the following data: Then Loan Charges tab has the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| Disbursement Charge | false | Disbursement | | % Loan Amount + Interest | 2.0 | 2.0 | 0.0 | 0.0 | | Disbursement Charge | false | Disbursement | | % Amount | 1.4 | 1.4 | 0.0 | 0.0 |
# -- REPAYMENT_AT_DISBURSEMENT journal entries ---- # -- REPAYMENT_AT_DISBURSEMENT journal entries ----
Then Loan Transactions tab has a "REPAYMENT_AT_DISBURSEMENT" transaction with date "01 January 2024" which has the following Journal entries: Then Loan Transactions tab has a "REPAYMENT_AT_DISBURSEMENT" transaction with date "01 January 2024" which has the following Journal entries:
| Type | Account code | Account name | Debit | Credit | | Type | Account code | Account name | Debit | Credit |
| INCOME | 404007 | Fee Income | | 2.0 | | INCOME | 404007 | Fee Income | | 1.4 |
| LIABILITY | 145023 | Suspense/Clearing account | 2.0 | | | LIABILITY | 145023 | Suspense/Clearing account | 1.4 | |
# --- 1st repayment - 1 February, 2024 --- # --- 1st repayment - 1 February, 2024 ---
When Admin sets the business date to "01 February 2024" When Admin sets the business date to "01 February 2024"
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 11.91 EUR transaction amount And Customer makes "AUTOPAY" repayment on "01 February 2024" with 11.91 EUR transaction amount
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 70.0 | | | 2.0 | | 2.0 | 2.0 | | | | | | | 01 January 2024 | | 70.0 | | | 1.4 | | 1.4 | 1.4 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 | | 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 |
| | | 01 February 2024 | | 30.0 | | | 0.0 | | 0.0 | 0.0 | | | | | | | 01 February 2024 | | 30.0 | | | 0.0 | | 0.0 | | | | 0.0 |
| 2 | 29 | 01 March 2024 | | 76.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 2 | 29 | 01 March 2024 | | 76.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 3 | 31 | 01 April 2024 | | 65.29 | 11.67 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 3 | 31 | 01 April 2024 | | 65.29 | 11.64 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 4 | 30 | 01 May 2024 | | 53.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 4 | 30 | 01 May 2024 | | 53.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 5 | 31 | 01 June 2024 | | 41.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 5 | 31 | 01 June 2024 | | 41.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 6 | 30 | 01 July 2024 | | 30.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 30.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 70.0 | 1.44 | 2.0 | 0.0 | 72.84 | 13.91 | 0.0 | 0.0 | 59.53 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 13.31 | 0.0 | 0.0 | 59.53 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
| 01 January 2024 | Repayment (at time of disbursement) | 2.0 | 0.0 | 0.0 | 2.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false |
| 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false | | 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false |
# --- 2nd disbursement - 1 February, 2024 --- # --- 2nd disbursement - 1 February, 2024 ---
When Admin successfully disburse the loan on "01 February 2024" with "30" EUR transaction amount When Admin successfully disburse the loan on "01 February 2024" with "30" EUR transaction amount
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 70.0 | | | 2.0 | | 2.0 | 2.0 | | | | | | | 01 January 2024 | | 70.0 | | | 1.4 | | 1.4 | 1.4 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 | | 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 |
| | | 01 February 2024 | | 30.0 | | | 0.0 | | 0.0 | 0.0 | | | | | | | 01 February 2024 | | 30.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 2 | 29 | 01 March 2024 | | 71.01 | 17.49 | 0.52 | 0.0 | 0.0 | 18.01 | 0.0 | 0.0 | 0.0 | 18.01 | | 2 | 29 | 01 March 2024 | | 71.01 | 17.49 | 0.52 | 0.0 | 0.0 | 18.01 | 0.0 | 0.0 | 0.0 | 18.01 |
@@ -3846,32 +3843,31 @@ Feature: LoanCharge
| 6 | 30 | 01 July 2024 | | 0.0 | 17.91 | 0.1 | 0.0 | 0.0 | 18.01 | 0.0 | 0.0 | 0.0 | 18.01 | | 6 | 30 | 01 July 2024 | | 0.0 | 17.91 | 0.1 | 0.0 | 0.0 | 18.01 | 0.0 | 0.0 | 0.0 | 18.01 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.96 | 2.0 | 0.0 | 103.96 | 13.91 | 0.0 | 0.0 | 90.05 | | 100.0 | 1.96 | 1.4 | 0.0 | 103.36 | 13.31 | 0.0 | 0.0 | 90.05 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
| 01 January 2024 | Repayment (at time of disbursement) | 2.0 | 0.0 | 0.0 | 2.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false |
| 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false | | 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false |
| 15 February 2024 | Disbursement | 30.0 | 0.0 | 0.0 | 0.0 | 0.0 | 88.5 | false | false | | 01 February 2024 | Disbursement | 30.0 | 0.0 | 0.0 | 0.0 | 0.0 | 88.5 | false | false |
# -- undo last disbursement ---- # -- undo last disbursement ----
When Admin successfully undo last disbursal When Admin successfully undo last disbursal
Then Loan status has changed to "Active"
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 70.0 | | | 2.0 | | 2.0 | 2.0 | | | | | | | 01 January 2024 | | 70.0 | | | 1.4 | | 1.4 | 1.4 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 | | 1 | 31 | 01 February 2024 | 01 February 2024 | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 11.91 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 46.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 2 | 29 | 01 March 2024 | | 46.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 3 | 31 | 01 April 2024 | | 35.29 | 11.67 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 3 | 31 | 01 April 2024 | | 35.29 | 11.64 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 4 | 30 | 01 May 2024 | | 23.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 4 | 30 | 01 May 2024 | | 23.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 5 | 31 | 01 June 2024 | | 11.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 | | 5 | 31 | 01 June 2024 | | 11.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.44 | 2.0 | 0.0 | 73.44 | 13.91 | 0.0 | 0.0 | 59.53 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 13.31 | 0.0 | 0.0 | 59.53 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
| 01 January 2024 | Repayment (at time of disbursement) | 2.0 | 0.0 | 0.0 | 2.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false |
| 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false | | 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false |
@Skip @Skip
@@ -4034,7 +4030,6 @@ Feature: LoanCharge
| 01 January 2024 | Repayment (at time of disbursement) | 1.43 | 0.0 | 0.0 | 1.43 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.43 | 0.0 | 0.0 | 1.43 | 0.0 | 70.0 | false | false |
| 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false | | 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false |
@Skip
@TestRailId:C3558 @TestRailId:C3558
Scenario: Verify interest disbursement charge for tranche interest bearing progressive loan that expects one tranche with undo disbursement - UC8.2.5 Scenario: Verify interest disbursement charge for tranche interest bearing progressive loan that expects one tranche with undo disbursement - UC8.2.5
When Admin sets the business date to "01 January 2024" When Admin sets the business date to "01 January 2024"
@@ -4097,22 +4092,21 @@ Feature: LoanCharge
Then Loan status has changed to "Approved" Then Loan status has changed to "Approved"
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 100.0 | | | 0.04 | | 0.04 | | | | 0.02 | | | | 01 January 2024 | | 70.0 | | | 0.03 | | 0.03 | | | | 0.03 |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 1 | 31 | 01 February 2024 | | 58.5 | 11.5 | 0.41 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 2 | 29 | 01 March 2024 | | 46.93 | 11.57 | 0.34 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 3 | 31 | 01 April 2024 | | 35.29 | 11.64 | 0.27 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 4 | 30 | 01 May 2024 | | 23.59 | 11.7 | 0.21 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 5 | 31 | 01 June 2024 | | 11.82 | 11.77 | 0.14 | 0.0 | 0.0 | 11.91 | 0.0 | 0.0 | 0.0 | 11.91 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | | 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.04 | 0.0 | 102.09 | 0.0 | 0.0 | 0.0 | 102.09 | | 70.0 | 1.44 | 0.03 | 0.0 | 71.47 | 0.00 | 0.0 | 0.0 | 71.47 |
Then Loan Transactions tab has none transaction Then Loan Transactions tab has none transaction
Then Loan Charges tab has the following data: Then Loan Charges tab has the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| Disbursement Charge | false | Disbursement | | % Interest | 0.04 | 0.04 | 0.0 | 0.0 | | Disbursement Charge | false | Disbursement | | % Interest | 0.03 | 0.0 | 0.0 | 0.03 |
@Skip
@TestRailId:C3560 @TestRailId:C3560
Scenario: Verify amount disbursement charge for tranche interest bearing progressive loan that doesn't expect tranches with undo disbursements - UC8.2.6 Scenario: Verify amount disbursement charge for tranche interest bearing progressive loan that doesn't expect tranches with undo disbursements - UC8.2.6
When Admin sets the business date to "01 January 2024" When Admin sets the business date to "01 January 2024"
@@ -4137,7 +4131,7 @@ Feature: LoanCharge
| 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 70.0 | 1.44 | 1.4 | 0.0 | 72.87 | 1.4 | 0.0 | 0.0 | 71.44 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 1.4 | 0.0 | 0.0 | 71.44 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
@@ -4164,7 +4158,7 @@ Feature: LoanCharge
| 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 | | 6 | 30 | 01 July 2024 | | 0.0 | 11.82 | 0.07 | 0.0 | 0.0 | 11.89 | 0.0 | 0.0 | 0.0 | 11.89 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.44 | 1.4 | 0.0 | 72.84 | 13.31 | 0.0 | 0.0 | 59.53 | | 70.0 | 1.44 | 1.4 | 0.0 | 72.84 | 13.31 | 0.0 | 0.0 | 59.53 |
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
@@ -4188,15 +4182,15 @@ Feature: LoanCharge
Then Loan Transactions tab has the following data: Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Disbursement | 70.0 | 0.0 | 0.0 | 0.0 | 0.0 | 70.0 | false | false |
| 01 January 2024 | Repayment (at time of disbursement) | 2.0 | 0.0 | 0.0 | 2.0 | 0.0 | 70.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 1.4 | 0.0 | 0.0 | 1.4 | 0.0 | 70.0 | false | false |
| 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false | | 01 February 2024 | Repayment | 11.91 | 11.5 | 0.41 | 0.0 | 0.0 | 58.5 | false | false |
| 15 February 2024 | Disbursement | 30.0 | 0.0 | 0.0 | 0.0 | 0.0 | 88.5 | false | false | | 01 February 2024 | Disbursement | 30.0 | 0.0 | 0.0 | 0.0 | 0.0 | 88.5 | false | false |
# -- undo disbursement ---- # -- undo disbursement ----
When Admin successfully undo disbursal When Admin successfully undo disbursal
Then Loan status has changed to "Approved" Then Loan status has changed to "Approved"
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 100.0 | | | 2.0 | | 2.0 | | | | 2.0 | | | | 01 January 2024 | | 100.0 | | | 1.4 | | 1.4 | | | | 1.4 |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
@@ -4205,13 +4199,12 @@ Feature: LoanCharge
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 2.0 | 0.0 | 104.05 | 0.0 | 0.0 | 0.0 | 104.05 | | 100.0 | 2.05 | 1.4 | 0.0 | 103.45 | 0.0 | 0.0 | 0.0 | 103.45 |
Then Loan Transactions tab has none transaction Then Loan Transactions tab has none transaction
Then Loan Charges tab has the following data: Then Loan Charges tab has the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| Disbursement Charge | false | Disbursement | | % Interest | 2.0 | 0.0 | 0.0 | 2.0 | | Disbursement Charge | false | Disbursement | | % Amount | 2.0 | 0.0 | 0.0 | 2.0 |
@Skip
@TestRailId:C3561 @TestRailId:C3561
Scenario: Verify amount+interest disbursement charge for tranche interest bearing progressive loan that doesn't expect tranches with undo disbursement - UC8.2.7 Scenario: Verify amount+interest disbursement charge for tranche interest bearing progressive loan that doesn't expect tranches with undo disbursement - UC8.2.7
When Admin sets the business date to "01 January 2024" When Admin sets the business date to "01 January 2024"
@@ -4274,7 +4267,7 @@ Feature: LoanCharge
Then Loan status has changed to "Approved" Then Loan status has changed to "Approved"
Then Loan Repayment schedule has 6 periods, with the following data for periods: Then Loan Repayment schedule has 6 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 | | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2024 | | 100.0 | | | 0.02 | | 0.02 | | | | 0.02 | | | | 01 January 2024 | | 100.0 | | | 2.04 | | 2.04 | | | | 2.04 |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
@@ -4283,7 +4276,7 @@ Feature: LoanCharge
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row: Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.02 | 0.0 | 102.07 | 0.0 | 0.0 | 0.0 | 102.07 | | 100.0 | 2.05 | 2.04 | 0.0 | 104.09 | 0.0 | 0.0 | 0.0 | 104.09 |
Then Loan Transactions tab has none transaction Then Loan Transactions tab has none transaction
Then Loan Charges tab has the following data: Then Loan Charges tab has the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
@@ -216,7 +216,7 @@ public class DelinquencyReadPlatformServiceImpl implements DelinquencyReadPlatfo
// Calculate available amount: (approved + over applied) - expected tranches - disbursed - capitalized income // Calculate available amount: (approved + over applied) - expected tranches - disbursed - capitalized income
if (loan.isMultiDisburmentLoan() && loan.getDisbursementDetails() != null) { if (loan.isMultiDisburmentLoan() && loan.getDisbursementDetails() != null) {
final BigDecimal expectedDisbursementAmount = loan.getDisbursementDetails().stream() final BigDecimal expectedDisbursementAmount = loan.getDisbursementDetails().stream()
.filter(detail -> detail.actualDisbursementDate() == null).map(LoanDisbursementDetails::principal) .filter(detail -> detail.actualDisbursementDate() == null).map(LoanDisbursementDetails::getPrincipal)
.reduce(BigDecimal.ZERO, BigDecimal::add); .reduce(BigDecimal.ZERO, BigDecimal::add);
approvedWithOverApplied = approvedWithOverApplied.subtract(expectedDisbursementAmount); approvedWithOverApplied = approvedWithOverApplied.subtract(expectedDisbursementAmount);
} }
@@ -22,6 +22,8 @@ import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType; import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -30,6 +32,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanSchedul
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
@Accessors(chain = true)
public final class DisbursementData implements LoanPrincipalRelatedDataHolder, Comparable<DisbursementData> { public final class DisbursementData implements LoanPrincipalRelatedDataHolder, Comparable<DisbursementData> {
private final Long id; private final Long id;
@@ -41,6 +44,8 @@ public final class DisbursementData implements LoanPrincipalRelatedDataHolder, C
private final String loanChargeId; private final String loanChargeId;
private final BigDecimal chargeAmount; private final BigDecimal chargeAmount;
private final BigDecimal waivedChargeAmount; private final BigDecimal waivedChargeAmount;
@Setter
private BigDecimal disburseChargeAmount;
// import fields // import fields
private transient Integer rowIndex; private transient Integer rowIndex;
@@ -814,7 +814,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
if (isMultiDisburmentLoan()) { if (isMultiDisburmentLoan()) {
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) { for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
if (disbursementDetail.actualDisbursementDate() != null) { if (disbursementDetail.actualDisbursementDate() != null) {
principal = principal.add(disbursementDetail.principal()); principal = principal.add(disbursementDetail.getPrincipal());
} }
} }
return principal; return principal;
@@ -999,7 +999,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
if (!details.isEmpty()) { if (!details.isEmpty()) {
principal = BigDecimal.ZERO; principal = BigDecimal.ZERO;
for (LoanDisbursementDetails disbursementDetails : details) { for (LoanDisbursementDetails disbursementDetails : details) {
principal = principal.add(disbursementDetails.principal()); principal = principal.add(disbursementDetails.getPrincipal());
} }
} }
return principal; return principal;
@@ -1303,7 +1303,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
public LoanDisbursementDetails getDisbursementDetails(final LocalDate transactionDate, final BigDecimal transactionAmount) { public LoanDisbursementDetails getDisbursementDetails(final LocalDate transactionDate, final BigDecimal transactionAmount) {
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) { for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
if (!disbursementDetail.isReversed() && disbursementDetail.getDisbursementDate().equals(transactionDate) if (!disbursementDetail.isReversed() && disbursementDetail.getDisbursementDate().equals(transactionDate)
&& (disbursementDetail.principal().compareTo(transactionAmount) == 0)) { && (disbursementDetail.getPrincipal().compareTo(transactionAmount) == 0)) {
return disbursementDetail; return disbursementDetail;
} }
} }
@@ -1317,7 +1317,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
Collection<LoanDisbursementDetails> loanDisburseDetails = this.getDisbursementDetails(); Collection<LoanDisbursementDetails> loanDisburseDetails = this.getDisbursementDetails();
for (LoanDisbursementDetails details : loanDisburseDetails) { for (LoanDisbursementDetails details : loanDisburseDetails) {
if (details.actualDisbursementDate() != null) { if (details.actualDisbursementDate() != null) {
principalAmount = principalAmount.add(details.principal()); principalAmount = principalAmount.add(details.getPrincipal());
} }
} }
} else if (isApproved()) { } else if (isApproved()) {
@@ -26,10 +26,12 @@ import jakarta.persistence.Table;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import lombok.Getter;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData; import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
@Getter
@Entity @Entity
@Table(name = "m_loan_disbursement_detail") @Table(name = "m_loan_disbursement_detail")
public class LoanDisbursementDetails extends AbstractPersistableCustom<Long> { public class LoanDisbursementDetails extends AbstractPersistableCustom<Long> {
@@ -107,10 +109,6 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom<Long> {
return this.actualDisbursementDate; return this.actualDisbursementDate;
} }
public BigDecimal principal() {
return this.principal;
}
public void updatePrincipal(BigDecimal principal) { public void updatePrincipal(BigDecimal principal) {
this.principal = principal; this.principal = principal;
} }
@@ -108,7 +108,7 @@ public class LoanRepaymentScheduleProcessingWrapper {
&& loanCharge.getLoan().isMultiDisburmentLoan()) { && loanCharge.getLoan().isMultiDisburmentLoan()) {
for (final LoanDisbursementDetails loanDisbursementDetails : loanCharge.getLoan().getDisbursementDetails()) { for (final LoanDisbursementDetails loanDisbursementDetails : loanCharge.getLoan().getDisbursementDetails()) {
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) { if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) {
amount = amount.add(loanDisbursementDetails.principal()); amount = amount.add(loanDisbursementDetails.getPrincipal());
} }
} }
} else { } else {
@@ -132,7 +132,7 @@ public class SingleLoanChargeRepaymentScheduleProcessingWrapper {
// Then we need to get as of this loan charge due date how much amount disbursed. // Then we need to get as of this loan charge due date how much amount disbursed.
for (final LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) { for (final LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) {
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) { if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) {
baseAmount = MathUtil.add(baseAmount, loanDisbursementDetails.principal()); baseAmount = MathUtil.add(baseAmount, loanDisbursementDetails.getPrincipal());
} }
} }
} else { } else {
@@ -94,7 +94,7 @@ public class LoanMapper {
BigDecimal waivedChargeAmount = null; BigDecimal waivedChargeAmount = null;
disbursementData.add( disbursementData.add(
new DisbursementData(loanDisbursementDetails.getId(), loan.getId(), expectedDisbursementDate, actualDisbursementDate, new DisbursementData(loanDisbursementDetails.getId(), loan.getId(), expectedDisbursementDate, actualDisbursementDate,
loanDisbursementDetails.principal(), loan.getNetDisbursalAmount(), null, null, waivedChargeAmount)); loanDisbursementDetails.getPrincipal(), loan.getNetDisbursalAmount(), null, null, waivedChargeAmount));
} }
return disbursementData; return disbursementData;
@@ -88,7 +88,7 @@ public class LoanApprovedAmountWritePlatformServiceImpl implements LoanApprovedA
changes.put("oldApprovedAmount", loan.getApprovedPrincipal()); changes.put("oldApprovedAmount", loan.getApprovedPrincipal());
BigDecimal expectedDisbursementAmount = loan.getDisbursementDetails().stream().filter(t -> t.actualDisbursementDate() == null) BigDecimal expectedDisbursementAmount = loan.getDisbursementDetails().stream().filter(t -> t.actualDisbursementDate() == null)
.map(LoanDisbursementDetails::principal).reduce(BigDecimal.ZERO, BigDecimal::add); .map(LoanDisbursementDetails::getPrincipal).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal oldAvailableDisbursement = loan.getApprovedPrincipal().subtract(loan.getSummary().getTotalPrincipal()) BigDecimal oldAvailableDisbursement = loan.getApprovedPrincipal().subtract(loan.getSummary().getTotalPrincipal())
.subtract(expectedDisbursementAmount); .subtract(expectedDisbursementAmount);
@@ -187,7 +187,7 @@ public class LoanBalanceService {
charge.resetToOriginal(loan.getCurrency()); charge.resetToOriginal(loan.getCurrency());
} }
} }
loan.getLoanRepaymentScheduleDetail().setPrincipal(loan.getDisbursedAmount().subtract(disbursementDetail.principal())); loan.getLoanRepaymentScheduleDetail().setPrincipal(loan.getDisbursedAmount().subtract(disbursementDetail.getPrincipal()));
disbursementDetail.updateActualDisbursementDate(null); disbursementDetail.updateActualDisbursementDate(null);
disbursementDetail.reverse(); disbursementDetail.reverse();
updateLoanSummaryDerivedFields(loan); updateLoanSummaryDerivedFields(loan);
@@ -251,7 +251,9 @@ public class LoanChargeService {
case PERCENT_OF_AMOUNT_AND_INTEREST -> { case PERCENT_OF_AMOUNT_AND_INTEREST -> {
final BigDecimal totalInterestCharged = loan.getTotalInterest(); final BigDecimal totalInterestCharged = loan.getTotalInterest();
if (loan.isMultiDisburmentLoan() && loanCharge.isDisbursementCharge()) { if (loan.isMultiDisburmentLoan() && loanCharge.isDisbursementCharge()) {
yield getTotalAllTrancheDisbursementAmount(loan).getAmount().add(totalInterestCharged); yield sumMultiDisbursementAmounts(loan, false).getAmount().add(totalInterestCharged);
} else if (loan.isMultiDisburmentLoan() && loanCharge.isTrancheDisbursementCharge()) {
yield sumMultiDisbursementAmounts(loan, true).getAmount().add(totalInterestCharged);
} else { } else {
yield loan.getPrincipal().getAmount().add(totalInterestCharged); yield loan.getPrincipal().getAmount().add(totalInterestCharged);
} }
@@ -259,7 +261,7 @@ public class LoanChargeService {
case PERCENT_OF_INTEREST -> loan.getTotalInterest(); case PERCENT_OF_INTEREST -> loan.getTotalInterest();
case PERCENT_OF_DISBURSEMENT_AMOUNT -> { case PERCENT_OF_DISBURSEMENT_AMOUNT -> {
if (loanCharge.getTrancheDisbursementCharge() != null) { if (loanCharge.getTrancheDisbursementCharge() != null) {
yield loanCharge.getTrancheDisbursementCharge().getloanDisbursementDetails().principal(); yield loanCharge.getTrancheDisbursementCharge().getloanDisbursementDetails().getPrincipal();
} else { } else {
yield loan.getPrincipal().getAmount(); yield loan.getPrincipal().getAmount();
} }
@@ -449,7 +451,7 @@ public class LoanChargeService {
if (loanCharge.getLoan().isMultiDisburmentLoan() && loanCharge.isSpecifiedDueDate()) { if (loanCharge.getLoan().isMultiDisburmentLoan() && loanCharge.isSpecifiedDueDate()) {
for (final LoanDisbursementDetails loanDisbursementDetails : loanCharge.getLoan().getDisbursementDetails()) { for (final LoanDisbursementDetails loanDisbursementDetails : loanCharge.getLoan().getDisbursementDetails()) {
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) { if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) {
amountPercentageAppliedTo = amountPercentageAppliedTo.add(loanDisbursementDetails.principal()); amountPercentageAppliedTo = amountPercentageAppliedTo.add(loanDisbursementDetails.getPrincipal());
} }
} }
} else { } else {
@@ -465,7 +467,7 @@ public class LoanChargeService {
break; break;
case PERCENT_OF_DISBURSEMENT_AMOUNT: case PERCENT_OF_DISBURSEMENT_AMOUNT:
LoanTrancheDisbursementCharge loanTrancheDisbursementCharge = loanCharge.getLoanTrancheDisbursementCharge(); LoanTrancheDisbursementCharge loanTrancheDisbursementCharge = loanCharge.getLoanTrancheDisbursementCharge();
amountPercentageAppliedTo = loanTrancheDisbursementCharge.getloanDisbursementDetails().principal(); amountPercentageAppliedTo = loanTrancheDisbursementCharge.getloanDisbursementDetails().getPrincipal();
break; break;
default: default:
break; break;
@@ -850,14 +852,23 @@ public class LoanChargeService {
} }
} }
private Money getTotalAllTrancheDisbursementAmount(final Loan loan) { private Money sumMultiDisbursementAmounts(final Loan loan, final boolean isTrancheDisbursement) {
Money amount = Money.zero(loan.getCurrency());
if (loan.isMultiDisburmentLoan()) { if (loan.isMultiDisburmentLoan()) {
for (final LoanDisbursementDetails loanDisbursementDetail : loan.getDisbursementDetails()) { final List<LoanDisbursementDetails> loanDisbursementDetails = loan.getDisbursementDetails();
amount = amount.plus(loanDisbursementDetail.principal()); if (loan.isOpen() || !loanDisbursementDetails.isEmpty()) {
if (isTrancheDisbursement) {
return Money.of(loan.getCurrency(), loanDisbursementDetails.stream() //
.map(LoanDisbursementDetails::getPrincipal) //
.reduce(BigDecimal.ZERO, BigDecimal::add));
}
return Money.of(loan.getCurrency(), loanDisbursementDetails.get(0).getPrincipal());
} else if (loan.isSubmittedAndPendingApproval()) {
return Money.of(loan.getCurrency(), loan.getProposedPrincipal());
} else if (loan.isApproved()) {
return Money.of(loan.getCurrency(), loan.getApprovedPrincipal());
} }
} }
return amount; return Money.zero(loan.getCurrency());
} }
private List<Long> fetchAllLoanChargeIds(final Loan loan) { private List<Long> fetchAllLoanChargeIds(final Loan loan) {
@@ -884,15 +895,16 @@ public class LoanChargeService {
private BigDecimal getDerivedAmountForCharge(final Loan loan, final LoanCharge loanCharge) { private BigDecimal getDerivedAmountForCharge(final Loan loan, final LoanCharge loanCharge) {
BigDecimal amount = BigDecimal.ZERO; BigDecimal amount = BigDecimal.ZERO;
if (loan.isMultiDisburmentLoan() && loanCharge.getCharge().getChargeTimeType().equals(ChargeTimeType.DISBURSEMENT.getValue())) { final ChargeTimeType chargeTimeType = ChargeTimeType.fromInt(loanCharge.getCharge().getChargeTimeType());
amount = loan.getApprovedPrincipal(); if (loan.isMultiDisburmentLoan() && chargeTimeType.isDisbursementOrTrancheDisbursementCharge()) {
return sumMultiDisbursementAmounts(loan, chargeTimeType.isTrancheDisbursement()).getAmount();
} else { } else {
// If charge type is specified due date and loan is multi disburment loan. // If charge type is specified due date and loan is multi disburment loan.
// Then we need to get as of this loan charge due date how much amount disbursed. // Then we need to get as of this loan charge due date how much amount disbursed.
if (loanCharge.isSpecifiedDueDate() && loan.isMultiDisburmentLoan()) { if (loanCharge.isSpecifiedDueDate() && loan.isMultiDisburmentLoan()) {
for (final LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) { for (final LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) {
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) { if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) {
amount = amount.add(loanDisbursementDetails.principal()); amount = amount.add(loanDisbursementDetails.getPrincipal());
} }
} }
} else { } else {
@@ -962,7 +962,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
for (LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) { for (LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) {
if (loanDisbursementDetails.actualDisbursementDate() == null) { if (loanDisbursementDetails.actualDisbursementDate() == null) {
totalPrincipal = Money.of(currency, totalPrincipal.getAmount().subtract(loanDisbursementDetails.principal())); totalPrincipal = Money.of(currency, totalPrincipal.getAmount().subtract(loanDisbursementDetails.getPrincipal()));
} }
} }
@@ -175,8 +175,8 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
for (LoanRepaymentScheduleInstallment installment : installments) { for (LoanRepaymentScheduleInstallment installment : installments) {
if (loanDisbursementDetails != null if (loanDisbursementDetails != null
&& !DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDateAsLocalDate(), installment.getDueDate())) { && !DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDateAsLocalDate(), installment.getDueDate())) {
outstanding = outstanding.plus(loanDisbursementDetails.principal()); outstanding = outstanding.plus(loanDisbursementDetails.getPrincipal());
principal = principal.plus(loanDisbursementDetails.principal()); principal = principal.plus(loanDisbursementDetails.getPrincipal());
if (disbursementItr.hasNext()) { if (disbursementItr.hasNext()) {
loanDisbursementDetails = disbursementItr.next(); loanDisbursementDetails = disbursementItr.next();
} else { } else {
@@ -97,7 +97,7 @@ public final class LoanApprovedAmountValidatorImpl implements LoanApprovedAmount
BigDecimal totalPrincipalOnLoan = loan.getSummary().getTotalPrincipal(); BigDecimal totalPrincipalOnLoan = loan.getSummary().getTotalPrincipal();
BigDecimal totalExpectedPrincipal = loan.getDisbursementDetails().stream().filter(t -> t.actualDisbursementDate() == null) BigDecimal totalExpectedPrincipal = loan.getDisbursementDetails().stream().filter(t -> t.actualDisbursementDate() == null)
.map(LoanDisbursementDetails::principal).reduce(BigDecimal.ZERO, BigDecimal::add); .map(LoanDisbursementDetails::getPrincipal).reduce(BigDecimal.ZERO, BigDecimal::add);
if (MathUtil.isLessThan(newApprovedAmount, totalPrincipalOnLoan.add(totalExpectedPrincipal))) { if (MathUtil.isLessThan(newApprovedAmount, totalPrincipalOnLoan.add(totalExpectedPrincipal))) {
baseDataValidator.reset().parameter(LoanApiConstants.amountParameterName) baseDataValidator.reset().parameter(LoanApiConstants.amountParameterName)
.failWithCode("less.than.disbursed.principal.and.capitalized.income"); .failWithCode("less.than.disbursed.principal.and.capitalized.income");
@@ -145,7 +145,7 @@ public final class LoanApprovedAmountValidatorImpl implements LoanApprovedAmount
} }
BigDecimal expectedDisbursementAmount = loan.getDisbursementDetails().stream().filter(t -> t.actualDisbursementDate() == null) BigDecimal expectedDisbursementAmount = loan.getDisbursementDetails().stream().filter(t -> t.actualDisbursementDate() == null)
.map(LoanDisbursementDetails::principal).reduce(BigDecimal.ZERO, BigDecimal::add); .map(LoanDisbursementDetails::getPrincipal).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal maximumAvailableDisbursementThreshold = maximumThresholdForApprovedAmount BigDecimal maximumAvailableDisbursementThreshold = maximumThresholdForApprovedAmount
.subtract(loan.getSummary().getTotalPrincipal()).subtract(expectedDisbursementAmount); .subtract(loan.getSummary().getTotalPrincipal()).subtract(expectedDisbursementAmount);
@@ -174,7 +174,7 @@ public class LoanChargeAssembler {
} else { } else {
if (disbursementDetail.expectedDisbursementDateAsLocalDate().equals(expectedDisbursementDate)) { if (disbursementDetail.expectedDisbursementDateAsLocalDate().equals(expectedDisbursementDate)) {
final LoanCharge loanCharge = createNewWithoutLoan(chargeDefinition, final LoanCharge loanCharge = createNewWithoutLoan(chargeDefinition,
disbursementDetail.principal(), amount, chargeTime, chargeCalculation, disbursementDetail.getPrincipal(), amount, chargeTime, chargeCalculation,
disbursementDetail.expectedDisbursementDateAsLocalDate(), chargePaymentModeEnum, disbursementDetail.expectedDisbursementDateAsLocalDate(), chargePaymentModeEnum,
numberOfRepayments, externalId); numberOfRepayments, externalId);
loanCharges.add(loanCharge); loanCharges.add(loanCharge);
@@ -191,8 +191,8 @@ public class LoanChargeAssembler {
LoanTrancheDisbursementCharge loanTrancheDisbursementCharge = null; LoanTrancheDisbursementCharge loanTrancheDisbursementCharge = null;
for (LoanDisbursementDetails disbursementDetail : disbursementDetails) { for (LoanDisbursementDetails disbursementDetail : disbursementDetails) {
if (ChargeTimeType.TRANCHE_DISBURSEMENT.getValue().equals(chargeDefinition.getChargeTimeType())) { if (ChargeTimeType.TRANCHE_DISBURSEMENT.getValue().equals(chargeDefinition.getChargeTimeType())) {
final LoanCharge loanCharge = createNewWithoutLoan(chargeDefinition, disbursementDetail.principal(), final LoanCharge loanCharge = createNewWithoutLoan(chargeDefinition,
amount, chargeTime, chargeCalculation, disbursementDetail.getPrincipal(), amount, chargeTime, chargeCalculation,
disbursementDetail.expectedDisbursementDateAsLocalDate(), chargePaymentModeEnum, disbursementDetail.expectedDisbursementDateAsLocalDate(), chargePaymentModeEnum,
numberOfRepayments, externalId); numberOfRepayments, externalId);
loanCharges.add(loanCharge); loanCharges.add(loanCharge);
@@ -309,7 +309,7 @@ public class LoanChargeAssembler {
amountPercentageAppliedTo = BigDecimal.ZERO; amountPercentageAppliedTo = BigDecimal.ZERO;
for (final LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) { for (final LoanDisbursementDetails loanDisbursementDetails : loan.getDisbursementDetails()) {
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), dueDate)) { if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), dueDate)) {
amountPercentageAppliedTo = amountPercentageAppliedTo.add(loanDisbursementDetails.principal()); amountPercentageAppliedTo = amountPercentageAppliedTo.add(loanDisbursementDetails.getPrincipal());
} }
} }
} }
@@ -105,7 +105,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachin
import org.apache.fineract.portfolio.loanaccount.domain.LoanOverdueInstallmentCharge; import org.apache.fineract.portfolio.loanaccount.domain.LoanOverdueInstallmentCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTrancheDisbursementCharge; import org.apache.fineract.portfolio.loanaccount.domain.LoanTrancheDisbursementCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
@@ -159,7 +158,6 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService; private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
private final ExternalIdFactory externalIdFactory; private final ExternalIdFactory externalIdFactory;
private final AccountTransferDetailRepository accountTransferDetailRepository; private final AccountTransferDetailRepository accountTransferDetailRepository;
private final LoanChargeAssembler loanChargeAssembler; private final LoanChargeAssembler loanChargeAssembler;
@@ -216,7 +214,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
externalId = externalIdFactory.create(); externalId = externalIdFactory.create();
} }
LocalDate dueDate = disbursementDetail.expectedDisbursementDateAsLocalDate(); LocalDate dueDate = disbursementDetail.expectedDisbursementDateAsLocalDate();
loanCharge = loanChargeAssembler.createNewWithoutLoan(chargeDefinition, disbursementDetail.principal(), null, null, loanCharge = loanChargeAssembler.createNewWithoutLoan(chargeDefinition, disbursementDetail.getPrincipal(), null, null,
null, dueDate, null, null, externalId); null, dueDate, null, null, externalId);
loanTrancheDisbursementCharge = new LoanTrancheDisbursementCharge(loanCharge, disbursementDetail); loanTrancheDisbursementCharge = new LoanTrancheDisbursementCharge(loanCharge, disbursementDetail);
loanCharge.updateLoanTrancheDisbursementCharge(loanTrancheDisbursementCharge); loanCharge.updateLoanTrancheDisbursementCharge(loanTrancheDisbursementCharge);
@@ -138,7 +138,7 @@ public class LoanDisbursementService {
disburseAmount = disburseAmount.zero(); disburseAmount = disburseAmount.zero();
for (LoanDisbursementDetails disbursementDetails : details) { for (LoanDisbursementDetails disbursementDetails : details) {
disbursementDetails.updateActualDisbursementDate(actualDisbursementDate); disbursementDetails.updateActualDisbursementDate(actualDisbursementDate);
disburseAmount = disburseAmount.plus(disbursementDetails.principal()); disburseAmount = disburseAmount.plus(disbursementDetails.getPrincipal());
} }
} }
} else { } else {
@@ -162,7 +162,7 @@ public class LoanDisbursementService {
// First try to find a tranche that exactly matches the requested disbursement amount // First try to find a tranche that exactly matches the requested disbursement amount
for (LoanDisbursementDetails disbursementDetails : details) { for (LoanDisbursementDetails disbursementDetails : details) {
if (disbursementDetails.actualDisbursementDate() == null if (disbursementDetails.actualDisbursementDate() == null
&& disbursementDetails.principal().compareTo(principalDisbursed) == 0) { && disbursementDetails.getPrincipal().compareTo(principalDisbursed) == 0) {
selectedTranche = disbursementDetails; selectedTranche = disbursementDetails;
break; break;
} }
@@ -198,9 +198,9 @@ public class LoanDisbursementService {
BigDecimal setPrincipalAmount = BigDecimal.ZERO; BigDecimal setPrincipalAmount = BigDecimal.ZERO;
for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) { for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) {
if (disbursementDetails.actualDisbursementDate() != null) { if (disbursementDetails.actualDisbursementDate() != null) {
setPrincipalAmount = setPrincipalAmount.add(disbursementDetails.principal()); setPrincipalAmount = setPrincipalAmount.add(disbursementDetails.getPrincipal());
} }
totalAmount = totalAmount.add(disbursementDetails.principal()); totalAmount = totalAmount.add(disbursementDetails.getPrincipal());
} }
loan.getLoanRepaymentScheduleDetail().setPrincipal(setPrincipalAmount); loan.getLoanRepaymentScheduleDetail().setPrincipal(setPrincipalAmount);
} else { } else {
@@ -435,7 +435,7 @@ public class LoanDisbursementService {
LoanDisbursementDetails singleDetail = undisbursedDetails.iterator().next(); LoanDisbursementDetails singleDetail = undisbursedDetails.iterator().next();
BigDecimal loanPrincipal = loan.getLoanRepaymentScheduleDetail().getPrincipal().getAmount(); BigDecimal loanPrincipal = loan.getLoanRepaymentScheduleDetail().getPrincipal().getAmount();
if (singleDetail.principal().compareTo(loanPrincipal) == 0) { if (singleDetail.getPrincipal().compareTo(loanPrincipal) == 0) {
return false; return false;
} }
} }
@@ -452,7 +452,8 @@ public class LoanDisbursementService {
return disbursementDetails.stream() return disbursementDetails.stream()
.sorted(Comparator.comparing(LoanDisbursementDetails::expectedDisbursementDate) .sorted(Comparator.comparing(LoanDisbursementDetails::expectedDisbursementDate)
.thenComparing((LoanDisbursementDetails d1, LoanDisbursementDetails d2) -> d2.principal().compareTo(d1.principal())) .thenComparing(
(LoanDisbursementDetails d1, LoanDisbursementDetails d2) -> d2.getPrincipal().compareTo(d1.getPrincipal()))
.thenComparing(LoanDisbursementDetails::getId)) .thenComparing(LoanDisbursementDetails::getId))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@@ -1666,10 +1666,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
} }
public String schema() { public String schema() {
return "dd.id as id, dd.loan_id as loanId, dd.expected_disburse_date as expectedDisbursementdate, dd.disbursedon_date as actualDisbursementdate,dd.principal as principal,dd.net_disbursal_amount as netDisbursalAmount,sum(lc.amount) chargeAmount, lc.amount_waived_derived waivedAmount, " return "dd.id as id, dd.loan_id as loanId, dd.expected_disburse_date as expectedDisbursementdate, dd.disbursedon_date as actualDisbursementdate, "
+ sqlGenerator.groupConcat("lc.id") + " loanChargeId " + "dd.principal as principal,dd.net_disbursal_amount as netDisbursalAmount, sum(lc.amount) as chargeAmount, coalesce(sum(cad.amount), 0) as disburseChargeAmount, "
+ "from m_loan l inner join m_loan_disbursement_detail dd on dd.loan_id = l.id left join m_loan_tranche_disbursement_charge tdc on tdc.disbursement_detail_id=dd.id " + "lc.amount_waived_derived waivedAmount, coalesce(" + sqlGenerator.groupConcat("lc.id") + ", "
+ "left join m_loan_charge lc on lc.id=tdc.loan_charge_id and lc.is_active=true"; + sqlGenerator.groupConcat("cad.id") + ") loanChargeId "
+ "from m_loan l inner join m_loan_disbursement_detail dd on dd.loan_id = l.id "
+ "left join m_loan_tranche_disbursement_charge tdc on tdc.disbursement_detail_id = dd.id "
+ "left join m_loan_charge lc on lc.id = tdc.loan_charge_id and lc.is_active = true "
+ "left join (select lch.id, lch.loan_id, lch.amount from m_loan_charge lch inner join m_charge ch on ch.id = lch.charge_id and ch.charge_time_enum = 1) cad on cad.loan_id = l.id";
} }
@Override @Override
@@ -1686,8 +1690,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
if (chargeAmount != null && waivedAmount != null) { if (chargeAmount != null && waivedAmount != null) {
chargeAmount = chargeAmount.subtract(waivedAmount); chargeAmount = chargeAmount.subtract(waivedAmount);
} }
BigDecimal disburseChargeAmount = rs.getBigDecimal("disburseChargeAmount");
return new DisbursementData(id, loanId, expectedDisbursementdate, actualDisbursementdate, principal, netDisbursalAmount, return new DisbursementData(id, loanId, expectedDisbursementdate, actualDisbursementdate, principal, netDisbursalAmount,
loanChargeId, chargeAmount, waivedAmount); loanChargeId, chargeAmount, waivedAmount).setDisburseChargeAmount(disburseChargeAmount);
} }
} }
@@ -365,7 +365,12 @@ public class LoanRepaymentScheduleService {
if (dataItem.isDisbursement()) { if (dataItem.isDisbursement()) {
// Process disbursement data // Process disbursement data
DisbursementData data = (DisbursementData) dataItem.getData(); DisbursementData data = (DisbursementData) dataItem.getData();
periodData = createLoanSchedulePeriodData(data, disbursementChargeAmount, waivedChargeAmount); if (periods.isEmpty()) {
periodData = createLoanSchedulePeriodData(data, disbursementChargeAmount, waivedChargeAmount);
} else {
periodData = createLoanSchedulePeriodData(data, disbursementChargeAmount.subtract(data.getDisburseChargeAmount()),
waivedChargeAmount);
}
} else { } else {
// Process capitalized income data // Process capitalized income data
LoanTransactionRepaymentPeriodData data = (LoanTransactionRepaymentPeriodData) dataItem.getData(); LoanTransactionRepaymentPeriodData data = (LoanTransactionRepaymentPeriodData) dataItem.getData();
@@ -2209,7 +2209,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails(); Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) { for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) {
if (disbursementDetails.actualDisbursementDate() != null) { if (disbursementDetails.actualDisbursementDate() != null) {
totalDisbursedAmount = totalDisbursedAmount.add(disbursementDetails.principal()); totalDisbursedAmount = totalDisbursedAmount.add(disbursementDetails.getPrincipal());
} }
} }
if (totalDisbursedAmount.compareTo(loan.getApprovedPrincipal()) == 0) { if (totalDisbursedAmount.compareTo(loan.getApprovedPrincipal()) == 0) {
@@ -314,11 +314,10 @@ public class LoanAccountConfiguration {
LoanWritePlatformService loanWritePlatformService, LoanUtilService loanUtilService, LoanWritePlatformService loanWritePlatformService, LoanUtilService loanUtilService,
LoanChargeReadPlatformService loanChargeReadPlatformService, LoanLifecycleStateMachine loanLifecycleStateMachine, LoanChargeReadPlatformService loanChargeReadPlatformService, LoanLifecycleStateMachine loanLifecycleStateMachine,
AccountAssociationsReadPlatformService accountAssociationsReadPlatformService, FromJsonHelper fromApiJsonHelper, AccountAssociationsReadPlatformService accountAssociationsReadPlatformService, FromJsonHelper fromApiJsonHelper,
ConfigurationDomainService configurationDomainService, ConfigurationDomainService configurationDomainService, ExternalIdFactory externalIdFactory,
LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, AccountTransferDetailRepository accountTransferDetailRepository, LoanChargeAssembler loanChargeAssembler,
ExternalIdFactory externalIdFactory, AccountTransferDetailRepository accountTransferDetailRepository, PaymentDetailWritePlatformService paymentDetailWritePlatformService, NoteRepository noteRepository,
LoanChargeAssembler loanChargeAssembler, PaymentDetailWritePlatformService paymentDetailWritePlatformService, LoanAccrualsProcessingService loanAccrualsProcessingService,
NoteRepository noteRepository, LoanAccrualsProcessingService loanAccrualsProcessingService,
LoanDownPaymentTransactionValidator loanDownPaymentTransactionValidator, LoanChargeValidator loanChargeValidator, LoanDownPaymentTransactionValidator loanDownPaymentTransactionValidator, LoanChargeValidator loanChargeValidator,
LoanScheduleService loanScheduleService, ReprocessLoanTransactionsService reprocessLoanTransactionsService, LoanScheduleService loanScheduleService, ReprocessLoanTransactionsService reprocessLoanTransactionsService,
LoanAccountService loanAccountService, LoanAdjustmentService loanAdjustmentService, LoanChargeService loanChargeService, LoanAccountService loanAccountService, LoanAdjustmentService loanAdjustmentService, LoanChargeService loanChargeService,
@@ -327,10 +326,9 @@ public class LoanAccountConfiguration {
businessEventNotifierService, loanTransactionRepository, accountTransfersWritePlatformService, loanRepositoryWrapper, businessEventNotifierService, loanTransactionRepository, accountTransfersWritePlatformService, loanRepositoryWrapper,
loanAccountDomainService, loanChargeRepository, loanWritePlatformService, loanUtilService, loanChargeReadPlatformService, loanAccountDomainService, loanChargeRepository, loanWritePlatformService, loanUtilService, loanChargeReadPlatformService,
loanLifecycleStateMachine, accountAssociationsReadPlatformService, fromApiJsonHelper, configurationDomainService, loanLifecycleStateMachine, accountAssociationsReadPlatformService, fromApiJsonHelper, configurationDomainService,
loanRepaymentScheduleTransactionProcessorFactory, externalIdFactory, accountTransferDetailRepository, loanChargeAssembler, externalIdFactory, accountTransferDetailRepository, loanChargeAssembler, paymentDetailWritePlatformService, noteRepository,
paymentDetailWritePlatformService, noteRepository, loanAccrualsProcessingService, loanDownPaymentTransactionValidator, loanAccrualsProcessingService, loanDownPaymentTransactionValidator, loanChargeValidator, loanScheduleService,
loanChargeValidator, loanScheduleService, reprocessLoanTransactionsService, loanAccountService, loanAdjustmentService, reprocessLoanTransactionsService, loanAccountService, loanAdjustmentService, loanChargeService, loanJournalEntryPoster);
loanChargeService, loanJournalEntryPoster);
} }
@Bean @Bean