FINERACT-2348: Refactor Capitalized income / Buydown fee amortization allocation calculation

This commit is contained in:
mariiaKraievska
2025-09-10 12:30:38 +02:00
committed by Adam Saghy
parent 719cba74c2
commit 8da0842f87
7 changed files with 490 additions and 112 deletions
@@ -3553,4 +3553,222 @@ Feature:Feature: Buy Down Fees
| 03 January 2024 | AM | 1.11 |
| 04 January 2024 | AM | 1.11 |
| 05 January 2024 | AM_ADJ | 0.25 |
| 06 January 2024 | AM | 0.43 |
| 06 January 2024 | AM | 0.43 |
@TestRailId:C4040
Scenario: Verify Buy Down Fee amortization allocation mapping when already amortized amount is greater than should be after buy down fee adjustment
When Admin sets the business date to "1 January 2024"
And Admin creates a client with random data
When Admin creates a fully customized loan with the 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 |
| LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 30 | DAYS | 1 | DAYS | 30 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024"
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
Then Loan status will be "ACTIVE"
And Admin runs inline COB job for Loan
And Admin adds buy down fee with "AUTOPAY" payment type to the loan on "1 January 2024" with "1" EUR transaction amount
When Admin sets the business date to "15 January 2024"
And Admin runs inline COB job for Loan
And Loan Amortization Allocation Mapping for "BUY_DOWN_FEE" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
And Buy down fee by external-id contains the following data:
| Date | Fee Amount | Amortized Amount | Not Yet Amortized Amount | Adjusted Amount | Charged Off Amount |
| 01 January 2024 | 1.0 | 0.47 | 0.53 | 0.0 | 0.0 |
And Admin adds buy down fee adjustment with "AUTOPAY" payment type to the loan on "15 January 2024" with "0.7" EUR transaction amount
When Admin sets the business date to "16 January 2024"
And Admin runs inline COB job for Loan
And Loan Amortization Allocation Mapping for "BUY_DOWN_FEE" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM_ADJ | 0.17 |
And Buy down fee by external-id contains the following data:
| Date | Fee Amount | Amortized Amount | Not Yet Amortized Amount | Adjusted Amount | Charged Off Amount |
| 01 January 2024 | 1.0 | 0.3 | 0.0 | 0.7 | 0.0 |
When Admin sets the business date to "25 January 2024"
And Admin runs inline COB job for Loan
And Loan Amortization Allocation Mapping for "BUY_DOWN_FEE" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM_ADJ | 0.17 |
And Buy down fee by external-id contains the following data:
| Date | Fee Amount | Amortized Amount | Not Yet Amortized Amount | Adjusted Amount | Charged Off Amount |
| 01 January 2024 | 1.0 | 0.3 | 0.0 | 0.7 | 0.0 |
@TestRailId:C4043
Scenario: Verify Buy Down Fee amortization allocation mapping when after buy down fee adjustment and charge-off
When Admin sets the business date to "1 January 2024"
And Admin creates a client with random data
When Admin creates a fully customized loan with the 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 |
| LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 30 | DAYS | 1 | DAYS | 30 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024"
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
Then Loan status will be "ACTIVE"
And Admin runs inline COB job for Loan
And Admin adds buy down fee with "AUTOPAY" payment type to the loan on "1 January 2024" with "1" EUR transaction amount
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
| 01 January 2024 | Buy Down Fee | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
When Admin sets the business date to "15 January 2024"
And Admin runs inline COB job for Loan
And Admin adds buy down fee adjustment with "AUTOPAY" payment type to the loan on "15 January 2024" with "0.3" EUR transaction amount
When Admin sets the business date to "16 January 2024"
And Admin runs inline COB job for Loan
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
| 01 January 2024 | Buy Down Fee | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
| 01 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Buy Down Fee Adjustment | 0.3 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Buy Down Fee Amortization | 0.01 | 0.0 | 0.01 | 0.0 | 0.0 | 0.0 | false |
And Loan Amortization Allocation Mapping for "BUY_DOWN_FEE" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM | 0.01 |
And Buy down fee by external-id contains the following data:
| Date | Fee Amount | Amortized Amount | Not Yet Amortized Amount | Adjusted Amount | Charged Off Amount |
| 01 January 2024 | 1.0 | 0.48 | 0.22 | 0.3 | 0.0 |
And Admin does charge-off the loan on "16 January 2024"
Then Loan status will be "ACTIVE"
And Loan marked as charged-off on "16 January 2024"
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
| 01 January 2024 | Buy Down Fee | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
| 01 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Buy Down Fee Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Buy Down Fee Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Buy Down Fee Adjustment | 0.3 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Buy Down Fee Amortization | 0.01 | 0.0 | 0.01 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Buy Down Fee Amortization | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Charge-off | 100.38 | 100.0 | 0.38 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Buy Down Fee Amortization | 0.2 | 0.0 | 0.2 | 0.0 | 0.0 | 0.0 | false |
And Loan Amortization Allocation Mapping for "BUY_DOWN_FEE" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM | 0.01 |
| 16 January 2024 | AM | 0.02 |
| 16 January 2024 | AM | 0.2 |
And Buy down fee by external-id contains the following data:
| Date | Fee Amount | Amortized Amount | Not Yet Amortized Amount | Adjusted Amount | Charged Off Amount |
| 01 January 2024 | 1.0 | 0.5 | 0.0 | 0.3 | 0.2 |
@@ -7883,3 +7883,221 @@ Feature: Capitalized Income
| 04 January 2024 | AM | 1.11 |
| 05 January 2024 | AM_ADJ | 0.25 |
| 06 January 2024 | AM | 0.43 |
@TestRailId:C4041
Scenario: Verify Capitalized Income amortization allocation mapping when already amortized amount is greater than should be after capitalized income adjustment
When Admin sets the business date to "1 January 2024"
And Admin creates a client with random data
When Admin creates a fully customized loan with the 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 |
| LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC | 01 January 2024 | 200 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 30 | DAYS | 1 | DAYS | 30 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "1 January 2024" with "200" amount and expected disbursement date on "1 January 2024"
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
Then Loan status will be "ACTIVE"
And Admin runs inline COB job for Loan
And Admin adds capitalized income with "AUTOPAY" payment type to the loan on "1 January 2024" with "1" EUR transaction amount
When Admin sets the business date to "15 January 2024"
And Admin runs inline COB job for Loan
And Loan Amortization Allocation Mapping for "CAPITALIZED_INCOME" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
And Deferred Capitalized Income by external-id contains the following data:
| Amount | Amortized Amount | Unrecognized Amount | Adjusted Amount | Charged Off Amount |
| 1.0 | 0.47 | 0.53 | 0.0 | 0.0 |
And Admin adds capitalized income adjustment with "AUTOPAY" payment type to the loan on "15 January 2024" with "0.7" EUR transaction amount
When Admin sets the business date to "16 January 2024"
And Admin runs inline COB job for Loan
And Loan Amortization Allocation Mapping for "CAPITALIZED_INCOME" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM_ADJ | 0.17 |
And Deferred Capitalized Income by external-id contains the following data:
| Amount | Amortized Amount | Unrecognized Amount | Adjusted Amount | Charged Off Amount |
| 1.0 | 0.3 | 0.0 | 0.7 | 0.0 |
When Admin sets the business date to "25 January 2024"
And Admin runs inline COB job for Loan
And Loan Amortization Allocation Mapping for "CAPITALIZED_INCOME" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM_ADJ | 0.17 |
And Deferred Capitalized Income by external-id contains the following data:
| Amount | Amortized Amount | Unrecognized Amount | Adjusted Amount | Charged Off Amount |
| 1.0 | 0.3 | 0.0 | 0.7 | 0.0 |
@TestRailId:C4042
Scenario: Verify Capitalized Income amortization allocation mapping when after capitalized income adjustment and charge-off
When Admin sets the business date to "1 January 2024"
And Admin creates a client with random data
When Admin creates a fully customized loan with the 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 |
| LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC | 01 January 2024 | 200 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 30 | DAYS | 1 | DAYS | 30 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "1 January 2024" with "200" amount and expected disbursement date on "1 January 2024"
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
Then Loan status will be "ACTIVE"
And Admin runs inline COB job for Loan
And Admin adds capitalized income with "AUTOPAY" payment type to the loan on "1 January 2024" with "1" EUR transaction amount
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
| 01 January 2024 | Capitalized Income | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 101.0 | false |
When Admin sets the business date to "15 January 2024"
And Admin runs inline COB job for Loan
And Admin adds capitalized income adjustment with "AUTOPAY" payment type to the loan on "15 January 2024" with "0.3" EUR transaction amount
When Admin sets the business date to "16 January 2024"
And Admin runs inline COB job for Loan
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
| 01 January 2024 | Capitalized Income | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 101.0 | false |
| 01 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Capitalized Income Adjustment | 0.3 | 0.3 | 0.0 | 0.0 | 0.0 | 100.7 | false |
| 15 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Capitalized Income Amortization | 0.01 | 0.0 | 0.01 | 0.0 | 0.0 | 0.0 | false |
And Loan Amortization Allocation Mapping for "CAPITALIZED_INCOME" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM | 0.01 |
And Deferred Capitalized Income by external-id contains the following data:
| Amount | Amortized Amount | Unrecognized Amount | Adjusted Amount | Charged Off Amount |
| 1.0 | 0.48 | 0.22 | 0.3 | 0.0 |
And Admin does charge-off the loan on "16 January 2024"
Then Loan status will be "ACTIVE"
And Loan marked as charged-off on "16 January 2024"
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
| 01 January 2024 | Capitalized Income | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 101.0 | false |
| 01 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 02 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 03 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 04 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 05 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 06 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 07 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 08 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 09 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 10 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 11 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 12 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 13 January 2024 | Capitalized Income Amortization | 0.03 | 0.0 | 0.03 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 14 January 2024 | Capitalized Income Amortization | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Capitalized Income Adjustment | 0.3 | 0.3 | 0.0 | 0.0 | 0.0 | 100.7 | false |
| 15 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 15 January 2024 | Capitalized Income Amortization | 0.01 | 0.0 | 0.01 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Capitalized Income Amortization | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Charge-off | 101.08 | 100.7 | 0.38 | 0.0 | 0.0 | 0.0 | false |
| 16 January 2024 | Capitalized Income Amortization | 0.2 | 0.0 | 0.2 | 0.0 | 0.0 | 0.0 | false |
And Loan Amortization Allocation Mapping for "CAPITALIZED_INCOME" transaction created on "01 January 2024" contains the following data:
| Date | Type | Amount |
| 01 January 2024 | AM | 0.03 |
| 02 January 2024 | AM | 0.04 |
| 03 January 2024 | AM | 0.03 |
| 04 January 2024 | AM | 0.03 |
| 05 January 2024 | AM | 0.04 |
| 06 January 2024 | AM | 0.03 |
| 07 January 2024 | AM | 0.03 |
| 08 January 2024 | AM | 0.04 |
| 09 January 2024 | AM | 0.03 |
| 10 January 2024 | AM | 0.03 |
| 11 January 2024 | AM | 0.04 |
| 12 January 2024 | AM | 0.03 |
| 13 January 2024 | AM | 0.03 |
| 14 January 2024 | AM | 0.04 |
| 15 January 2024 | AM | 0.01 |
| 16 January 2024 | AM | 0.02 |
| 16 January 2024 | AM | 0.2 |
And Deferred Capitalized Income by external-id contains the following data:
| Amount | Amortized Amount | Unrecognized Amount | Adjusted Amount | Charged Off Amount |
| 1.0 | 0.5 | 0.0 | 0.3 | 0.2 |
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.portfolio.loanaccount.domain;
import java.math.BigDecimal;
import java.util.List;
import org.apache.fineract.portfolio.loanaccount.data.AmortizationAllocationMappingDTO;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -33,11 +34,31 @@ import org.springframework.stereotype.Repository;
public interface LoanAmortizationAllocationMappingRepository
extends JpaRepository<LoanAmortizationAllocationMapping, Long>, JpaSpecificationExecutor<LoanAmortizationAllocationMapping> {
@Query(value = "SELECT new org.apache.fineract.portfolio.loanaccount.data.AmortizationAllocationMappingDTO("
+ "laam.amortizationLoanTransactionId, at.externalId, laam.date, laam.amortizationType, laam.amount) "
+ "FROM LoanAmortizationAllocationMapping laam " + "JOIN LoanTransaction at ON laam.amortizationLoanTransactionId = at.id "
+ "WHERE laam.baseLoanTransactionId = :baseLoanTransactionId AND laam.loanId = :loanId "
+ "ORDER BY laam.date, laam.amortizationLoanTransactionId")
@Query("""
SELECT new org.apache.fineract.portfolio.loanaccount.data.AmortizationAllocationMappingDTO(
laam.amortizationLoanTransactionId,
at.externalId,
laam.date,
laam.amortizationType,
laam.amount
) FROM LoanAmortizationAllocationMapping laam
JOIN LoanTransaction at ON laam.amortizationLoanTransactionId = at.id
WHERE laam.baseLoanTransactionId = :baseLoanTransactionId AND laam.loanId = :loanId
ORDER BY laam.date, laam.amortizationLoanTransactionId
""")
List<AmortizationAllocationMappingDTO> findAmortizationMappingsByBaseTransactionAndLoan(
@Param("baseLoanTransactionId") Long baseLoanTransactionId, @Param("loanId") Long loanId);
@Query("""
SELECT COALESCE(SUM(
CASE
WHEN laam.amortizationType = org.apache.fineract.portfolio.loanaccount.domain.AmortizationType.AM THEN laam.amount
WHEN laam.amortizationType = org.apache.fineract.portfolio.loanaccount.domain.AmortizationType.AM_ADJ THEN -laam.amount
ELSE 0
END
), 0)
FROM LoanAmortizationAllocationMapping laam
WHERE laam.baseLoanTransactionId = :baseLoanTransactionId AND laam.loanId = :loanId
""")
BigDecimal calculateAlreadyAmortizedAmount(@Param("baseLoanTransactionId") Long baseLoanTransactionId, @Param("loanId") Long loanId);
}
@@ -36,6 +36,8 @@ public interface LoanAmortizationAllocationService {
*/
LoanAmortizationAllocationData retrieveLoanAmortizationAllocationsForCapitalizedIncomeTransaction(Long loanTransactionId, Long loanId);
BigDecimal calculateAlreadyAmortizedAmount(Long loanTransactionId, Long loanId);
LoanAmortizationAllocationMapping createAmortizationAllocationMappingWithBaseLoanTransaction(LoanTransaction loanTransaction,
BigDecimal amount, AmortizationType amortizationType);
@@ -69,6 +69,11 @@ public class LoanAmortizationAllocationServiceImpl implements LoanAmortizationAl
return retrieveLoanAmortizationAllocationData(loanTransaction, loanId);
}
@Override
public BigDecimal calculateAlreadyAmortizedAmount(final Long loanTransactionId, final Long loanId) {
return loanAmortizationAllocationMappingRepository.calculateAlreadyAmortizedAmount(loanTransactionId, loanId);
}
private LoanAmortizationAllocationData retrieveLoanAmortizationAllocationData(final LoanTransaction loanTransaction,
final Long loanId) {
try {
@@ -34,7 +34,6 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.transaction
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanBuyDownFeeAmortizationTransactionCreatedBusinessEvent;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.portfolio.loanaccount.data.LoanAmortizationAllocationData;
import org.apache.fineract.portfolio.loanaccount.domain.AmortizationType;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanAmortizationAllocationMapping;
@@ -75,7 +74,6 @@ public class LoanBuyDownFeeAmortizationProcessingServiceImpl implements LoanBuyD
final List<LoanAmortizationAllocationMapping> loanAmortizationAllocationMappings = new ArrayList<>();
Money totalAmortization = Money.zero(loan.getCurrency());
final BigDecimal totalAmortized = loanTransactionRepository.getAmortizedAmountBuyDownFee(loan);
BigDecimal totalAmortizedAccumulator = totalAmortized;
for (LoanBuyDownFeeBalance balance : balances) {
BigDecimal amortizationAmount;
AmortizationType amortizationType;
@@ -84,46 +82,26 @@ public class LoanBuyDownFeeAmortizationProcessingServiceImpl implements LoanBuyD
final Money amortizationTillDate = BuyDownFeeAmortizationUtil.calculateTotalAmortizationTillDate(balance, adjustments,
maturityDate, loan.getLoanProductRelatedDetail().getBuyDownFeeStrategy(), tillDatePlusOne, loan.getCurrency());
totalAmortization = totalAmortization.add(amortizationTillDate);
final BigDecimal alreadyAmortizedAmount = loanAmortizationAllocationService
.calculateAlreadyAmortizedAmount(balance.getLoanTransaction().getId(), loan.getId());
if (!adjustments.isEmpty()) {
BigDecimal alreadyAmortizedAmount = balance.getAmount().subtract(MathUtil.nullToZero(balance.getAmountAdjustment()))
.subtract(MathUtil.nullToZero(balance.getChargedOffAmount())).subtract(balance.getUnrecognizedAmount());
if (alreadyAmortizedAmount.compareTo(BigDecimal.ZERO) == 0) {
final LoanAmortizationAllocationData loanAmortizationAllocationData = loanAmortizationAllocationService
.retrieveLoanAmortizationAllocationsForBuyDownFeeTransaction(balance.getLoanTransaction().getId(),
loan.getId());
BigDecimal amortizedAmount = BigDecimal.ZERO;
for (LoanAmortizationAllocationData.AmortizationMappingData loanAmortizationMapping : loanAmortizationAllocationData
.getAmortizationMappings()) {
if (AmortizationType.AM.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.add(loanAmortizationMapping.getAmount());
} else if (AmortizationType.AM_ADJ.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.subtract(loanAmortizationMapping.getAmount());
}
}
amortizationAmount = amortizedAmount;
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
amortizationAmount = alreadyAmortizedAmount.subtract(amortizationTillDate.getAmount());
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else {
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
} else {
amortizationAmount = totalAmortization.getAmount().subtract(totalAmortizedAccumulator);
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
balance.setUnrecognizedAmount(balance.getAmount().subtract(MathUtil.nullToZero(balance.getAmountAdjustment()))
.subtract(amortizationTillDate.getAmount()));
balance.setUnrecognizedAmount(
MathUtil.subtract(balance.getAmount(), balance.getAmountAdjustment(), amortizationTillDate.getAmount()));
} else {
amortizationAmount = balance.getAmount().subtract(balance.getUnrecognizedAmount());
amortizationType = AmortizationType.AM_ADJ;
balance.setClosed(true);
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
}
if (amortizationAmount.compareTo(BigDecimal.ZERO) > 0) {
final LoanAmortizationAllocationMapping loanAmortizationAllocationMapping = loanAmortizationAllocationService
@@ -236,7 +214,6 @@ public class LoanBuyDownFeeAmortizationProcessingServiceImpl implements LoanBuyD
BigDecimal totalAmortization = BigDecimal.ZERO;
final BigDecimal totalAmortized = loanTransactionRepository.getAmortizedAmountBuyDownFee(loan);
BigDecimal totalAmortizedAccumulator = totalAmortized;
for (LoanBuyDownFeeBalance balance : balances) {
BigDecimal amortizationAmount;
AmortizationType amortizationType;
@@ -246,38 +223,19 @@ public class LoanBuyDownFeeAmortizationProcessingServiceImpl implements LoanBuyD
final Money amortizationTillDate = BuyDownFeeAmortizationUtil.calculateTotalAmortizationTillDate(balance, adjustments,
maturityDate, loan.getLoanProductRelatedDetail().getBuyDownFeeStrategy(), maturityDate, loan.getCurrency());
totalAmortization = totalAmortization.add(amortizationTillDate.getAmount());
final BigDecimal alreadyAmortizedAmount = loanAmortizationAllocationService
.calculateAlreadyAmortizedAmount(balance.getLoanTransaction().getId(), loan.getId());
if (!adjustments.isEmpty()) {
BigDecimal alreadyAmortizedAmount = balance.getAmount().subtract(MathUtil.nullToZero(balance.getAmountAdjustment()))
.subtract(MathUtil.nullToZero(balance.getChargedOffAmount())).subtract(balance.getUnrecognizedAmount());
if (alreadyAmortizedAmount.compareTo(BigDecimal.ZERO) == 0) {
final LoanAmortizationAllocationData loanAmortizationAllocationData = loanAmortizationAllocationService
.retrieveLoanAmortizationAllocationsForBuyDownFeeTransaction(balance.getLoanTransaction().getId(),
loan.getId());
BigDecimal amortizedAmount = BigDecimal.ZERO;
for (LoanAmortizationAllocationData.AmortizationMappingData loanAmortizationMapping : loanAmortizationAllocationData
.getAmortizationMappings()) {
if (AmortizationType.AM.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.add(loanAmortizationMapping.getAmount());
} else if (AmortizationType.AM_ADJ.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.subtract(loanAmortizationMapping.getAmount());
}
}
amortizationAmount = amortizedAmount;
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
amortizationAmount = alreadyAmortizedAmount.subtract(amortizationTillDate.getAmount());
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else {
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
} else {
amortizationAmount = totalAmortization.subtract(totalAmortizedAccumulator);
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
if (isChargeOff) {
balance.setChargedOffAmount(balance.getUnrecognizedAmount());
@@ -287,7 +245,6 @@ public class LoanBuyDownFeeAmortizationProcessingServiceImpl implements LoanBuyD
amortizationAmount = balance.getAmount().subtract(balance.getUnrecognizedAmount());
amortizationType = AmortizationType.AM_ADJ;
balance.setClosed(true);
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
}
if (amortizationAmount.compareTo(BigDecimal.ZERO) > 0) {
final LoanAmortizationAllocationMapping loanAmortizationAllocationMapping = loanAmortizationAllocationService
@@ -35,7 +35,6 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.transaction
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanCapitalizedIncomeAmortizationTransactionCreatedBusinessEvent;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.portfolio.loanaccount.data.LoanAmortizationAllocationData;
import org.apache.fineract.portfolio.loanaccount.domain.AmortizationType;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanAmortizationAllocationMapping;
@@ -119,7 +118,6 @@ public class LoanCapitalizedIncomeAmortizationProcessingServiceImpl implements L
BigDecimal totalAmortization = BigDecimal.ZERO;
final BigDecimal totalAmortized = loanTransactionRepository.getAmortizedAmountCapitalizedIncome(loan);
BigDecimal totalAmortizedAccumulator = totalAmortized;
for (LoanCapitalizedIncomeBalance balance : balances) {
BigDecimal amortizationAmount;
AmortizationType amortizationType;
@@ -130,38 +128,19 @@ public class LoanCapitalizedIncomeAmortizationProcessingServiceImpl implements L
adjustments, maturityDate, loan.getLoanProductRelatedDetail().getCapitalizedIncomeStrategy(), maturityDate,
loan.getCurrency());
totalAmortization = totalAmortization.add(amortizationTillDate.getAmount());
final BigDecimal alreadyAmortizedAmount = loanAmortizationAllocationService
.calculateAlreadyAmortizedAmount(balance.getLoanTransaction().getId(), loan.getId());
if (!adjustments.isEmpty()) {
BigDecimal alreadyAmortizedAmount = balance.getAmount().subtract(MathUtil.nullToZero(balance.getAmountAdjustment()))
.subtract(MathUtil.nullToZero(balance.getChargedOffAmount())).subtract(balance.getUnrecognizedAmount());
if (alreadyAmortizedAmount.compareTo(BigDecimal.ZERO) == 0) {
final LoanAmortizationAllocationData loanAmortizationAllocationData = loanAmortizationAllocationService
.retrieveLoanAmortizationAllocationsForCapitalizedIncomeTransaction(balance.getLoanTransaction().getId(),
loan.getId());
BigDecimal amortizedAmount = BigDecimal.ZERO;
for (LoanAmortizationAllocationData.AmortizationMappingData loanAmortizationMapping : loanAmortizationAllocationData
.getAmortizationMappings()) {
if (AmortizationType.AM.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.add(loanAmortizationMapping.getAmount());
} else if (AmortizationType.AM_ADJ.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.subtract(loanAmortizationMapping.getAmount());
}
}
amortizationAmount = amortizedAmount;
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
amortizationAmount = alreadyAmortizedAmount.subtract(amortizationTillDate.getAmount());
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else {
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
} else {
amortizationAmount = totalAmortization.subtract(totalAmortizedAccumulator);
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
if (isChargeOff) {
balance.setChargedOffAmount(balance.getUnrecognizedAmount());
@@ -171,7 +150,6 @@ public class LoanCapitalizedIncomeAmortizationProcessingServiceImpl implements L
amortizationAmount = balance.getAmount().subtract(balance.getUnrecognizedAmount());
amortizationType = AmortizationType.AM_ADJ;
balance.setClosed(true);
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
}
if (amortizationAmount.compareTo(BigDecimal.ZERO) > 0) {
final LoanAmortizationAllocationMapping loanAmortizationAllocationMapping = loanAmortizationAllocationService
@@ -246,7 +224,6 @@ public class LoanCapitalizedIncomeAmortizationProcessingServiceImpl implements L
final List<LoanAmortizationAllocationMapping> loanAmortizationAllocationMappings = new ArrayList<>();
Money totalAmortization = Money.zero(loan.getCurrency());
final BigDecimal totalAmortized = loanTransactionRepository.getAmortizedAmountCapitalizedIncome(loan);
BigDecimal totalAmortizedAccumulator = totalAmortized;
for (LoanCapitalizedIncomeBalance balance : balances) {
BigDecimal amortizationAmount;
AmortizationType amortizationType;
@@ -256,46 +233,26 @@ public class LoanCapitalizedIncomeAmortizationProcessingServiceImpl implements L
adjustments, maturityDate, loan.getLoanProductRelatedDetail().getCapitalizedIncomeStrategy(), tillDatePlusOne,
loan.getCurrency());
totalAmortization = totalAmortization.add(amortizationTillDate);
final BigDecimal alreadyAmortizedAmount = loanAmortizationAllocationService
.calculateAlreadyAmortizedAmount(balance.getLoanTransaction().getId(), loan.getId());
if (!adjustments.isEmpty()) {
BigDecimal alreadyAmortizedAmount = balance.getAmount().subtract(MathUtil.nullToZero(balance.getAmountAdjustment()))
.subtract(MathUtil.nullToZero(balance.getChargedOffAmount())).subtract(balance.getUnrecognizedAmount());
if (alreadyAmortizedAmount.compareTo(BigDecimal.ZERO) == 0) {
final LoanAmortizationAllocationData loanAmortizationAllocationData = loanAmortizationAllocationService
.retrieveLoanAmortizationAllocationsForCapitalizedIncomeTransaction(balance.getLoanTransaction().getId(),
loan.getId());
BigDecimal amortizedAmount = BigDecimal.ZERO;
for (LoanAmortizationAllocationData.AmortizationMappingData loanAmortizationMapping : loanAmortizationAllocationData
.getAmortizationMappings()) {
if (AmortizationType.AM.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.add(loanAmortizationMapping.getAmount());
} else if (AmortizationType.AM_ADJ.equals(loanAmortizationMapping.getType())) {
amortizedAmount = amortizedAmount.subtract(loanAmortizationMapping.getAmount());
}
}
amortizationAmount = amortizedAmount;
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
if (alreadyAmortizedAmount.compareTo(amortizationTillDate.getAmount()) > 0) {
amortizationAmount = alreadyAmortizedAmount.subtract(amortizationTillDate.getAmount());
amortizationType = AmortizationType.AM_ADJ;
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
} else {
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
} else {
amortizationAmount = totalAmortization.getAmount().subtract(totalAmortizedAccumulator);
amortizationAmount = amortizationTillDate.getAmount().subtract(alreadyAmortizedAmount);
amortizationType = AmortizationType.AM;
totalAmortizedAccumulator = totalAmortizedAccumulator.add(amortizationAmount);
}
balance.setUnrecognizedAmount(balance.getAmount().subtract(MathUtil.nullToZero(balance.getAmountAdjustment()))
.subtract(amortizationTillDate.getAmount()));
balance.setUnrecognizedAmount(
MathUtil.subtract(balance.getAmount(), balance.getAmountAdjustment(), amortizationTillDate.getAmount()));
} else {
amortizationAmount = balance.getAmount().subtract(balance.getUnrecognizedAmount());
amortizationType = AmortizationType.AM_ADJ;
balance.setClosed(true);
totalAmortizedAccumulator = totalAmortizedAccumulator.subtract(amortizationAmount);
}
if (amortizationAmount.compareTo(BigDecimal.ZERO) > 0) {
final LoanAmortizationAllocationMapping loanAmortizationAllocationMapping = loanAmortizationAllocationService