FINERACT-2413: Add re-amortization documentation
This commit is contained in:
committed by
Adam Saghy
parent
09645e6afb
commit
1a2faa9c62
@@ -10,6 +10,7 @@ include::interest-rate-change-progressive-loans.adoc[leveloffset=+1]
|
||||
include::contract-termination.adoc[leveloffset=+1]
|
||||
include::loan-charges.adoc[leveloffset=+1]
|
||||
include::journal-entry-aggregation.adoc[leveloffset=+1]
|
||||
include::re-ageing.adoc[leveloffset=+1]
|
||||
include::pause-delinquency.adoc[leveloffset=+1]
|
||||
include::asset-externalization.adoc[leveloffset=+1]
|
||||
include::pause-delinquency.adoc[leveloffset=+1]
|
||||
include::re-amortization.adoc[leveloffset=+1]
|
||||
include::re-ageing.adoc[leveloffset=+1]
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
= Loan Re-Amortization
|
||||
|
||||
== Overview
|
||||
|
||||
Re-amortization recalculates EMI (Equal Monthly Installment) amounts for remaining installments based on the outstanding principal balance as of the current business date.
|
||||
|
||||
=== Example
|
||||
|
||||
A customer has a 1000 EUR loan with 4 monthly installments of 250 EUR each. After missing the first two payments (500 EUR overdue), re-amortization redistributes this amount across the remaining 2 installments, resulting in 500 EUR per installment instead of 250 EUR - without changing due dates or adding new installments.
|
||||
|
||||
=== Re-Amortization vs Re-Aging
|
||||
|
||||
[cols="1,2,2",options="header"]
|
||||
|===
|
||||
| Aspect | Re-Amortization | Re-Aging
|
||||
|
||||
| Schedule structure
|
||||
| Preserves existing installment count and due dates
|
||||
| Creates new installments with user-defined count, start date, and frequency
|
||||
|
||||
| User input
|
||||
| Only interest handling type
|
||||
| Start date, number of installments, period type, frequency, interest handling
|
||||
|
||||
| Use case
|
||||
| Redistribute overdue principal across existing future installments
|
||||
| Restructure loan for customers in payment difficulty
|
||||
|===
|
||||
|
||||
== Supported Loan Type
|
||||
|
||||
Re-amortization is only available for:
|
||||
|
||||
* **Progressive** loan schedule type
|
||||
* **Advanced Payment Allocation** strategy
|
||||
* For interest-bearing loans: **interest recalculation must be enabled**
|
||||
|
||||
== Eligibility Criteria
|
||||
|
||||
* Loan must be **active** (disbursed and not closed)
|
||||
* Transaction date must be **before or on maturity date**
|
||||
* Loan must **not** be charged-off
|
||||
* Loan must **not** be contract terminated
|
||||
* Only **one** re-amortization transaction is allowed per business day
|
||||
|
||||
== Interest Handling Types
|
||||
|
||||
For **interest-bearing loans**, re-amortization supports three strategies:
|
||||
|
||||
[cols="1,3",options="header"]
|
||||
|===
|
||||
| Type | Description
|
||||
|
||||
| `DEFAULT`
|
||||
| Standard behavior - outstanding principal is redistributed across remaining installments
|
||||
|
||||
| `EQUAL_AMORTIZATION_INTEREST_SPLIT`
|
||||
| Outstanding principal and interest are split equally across remaining installments
|
||||
|===
|
||||
|
||||
== Business Events
|
||||
|
||||
* `LoanReAmortizeBusinessEvent` - triggered after re-amortization
|
||||
* `LoanReAmortizeTransactionBusinessEvent` - triggered for the transaction
|
||||
* `LoanUndoReAmortizeBusinessEvent` - triggered after undo operation
|
||||
* `LoanUndoReAmortizeTransactionBusinessEvent` - triggered for undo transaction
|
||||
|
||||
== Permissions
|
||||
|
||||
* `REAMORTIZE_LOAN` - required to apply re-amortization
|
||||
* `UNDO_REAMORTIZE_LOAN` - required to undo re-amortization
|
||||
|
||||
== API Endpoints
|
||||
|
||||
=== Apply Re-Amortization
|
||||
|
||||
* *Endpoint*: `POST /loans/{loanId}/transactions?command=reAmortize`
|
||||
* *Alternative*: `POST /loans/external-id/{loanExternalId}/transactions?command=reAmortize`
|
||||
|
||||
==== Request Body
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"externalId": "ext-123",
|
||||
"reAmortizationInterestHandling": "DEFAULT",
|
||||
"reasonCodeValueId": 1
|
||||
}
|
||||
----
|
||||
|
||||
[cols="2,1,4",options="header"]
|
||||
|===
|
||||
| Parameter | Required | Description
|
||||
|
||||
| `locale`
|
||||
| Yes
|
||||
| Locale for parsing
|
||||
|
||||
| `dateFormat`
|
||||
| Yes
|
||||
| Date format pattern
|
||||
|
||||
| `externalId`
|
||||
| No
|
||||
| External identifier for the transaction (max 100 chars)
|
||||
|
||||
| `reAmortizationInterestHandling`
|
||||
| No
|
||||
| Interest handling type: `DEFAULT` or `EQUAL_AMORTIZATION_INTEREST_SPLIT`. Defaults to `DEFAULT`
|
||||
|
||||
| `reasonCodeValueId`
|
||||
| No
|
||||
| Code value ID for re-amortization reason (from `ReamortizationReasons` code)
|
||||
|===
|
||||
|
||||
==== Response Body
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 1,
|
||||
"resourceId": 15,
|
||||
"resourceExternalId": "ext-123",
|
||||
"changes": {
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
=== Undo Re-Amortization
|
||||
|
||||
* *Endpoint*: `POST /loans/{loanId}/transactions?command=undoReAmortize`
|
||||
* *Alternative*: `POST /loans/external-id/{loanExternalId}/transactions?command=undoReAmortize`
|
||||
|
||||
==== Request Body
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"externalId": "reversal-ext-123"
|
||||
}
|
||||
----
|
||||
|
||||
==== Response Body
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 1,
|
||||
"resourceId": 15,
|
||||
"resourceExternalId": "ext-123",
|
||||
"changes": {
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
=== Preview Re-Amortization
|
||||
|
||||
Generates a preview of the re-amortized schedule without modifying the loan.
|
||||
|
||||
* *Endpoint*: `GET /loans/{loanId}/transactions/reamortization-preview`
|
||||
* *Alternative*: `GET /loans/external-id/{loanExternalId}/transactions/reamortization-preview`
|
||||
|
||||
==== Query Parameters
|
||||
|
||||
[cols="2,1,4",options="header"]
|
||||
|===
|
||||
| Parameter | Required | Description
|
||||
|
||||
| `reAmortizationInterestHandling`
|
||||
| Yes
|
||||
| Interest handling type: `DEFAULT` or `EQUAL_AMORTIZATION_INTEREST_SPLIT`
|
||||
|===
|
||||
|
||||
==== Response Body
|
||||
|
||||
Returns the projected loan schedule with recalculated installments:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"decimalPlaces": 2
|
||||
},
|
||||
"loanTermInDays": 60,
|
||||
"totalPrincipalDisbursed": 1000.00,
|
||||
"totalPrincipalExpected": 1000.00,
|
||||
"totalInterestCharged": 50.00,
|
||||
"totalFeeChargesCharged": 0.00,
|
||||
"totalRepaymentExpected": 1050.00,
|
||||
"periods": [
|
||||
{
|
||||
"period": 1,
|
||||
"dueDate": "01 February 2023",
|
||||
"principalDue": 500.00,
|
||||
"interestDue": 25.00,
|
||||
"totalDueForPeriod": 525.00
|
||||
},
|
||||
{
|
||||
"period": 2,
|
||||
"dueDate": "01 March 2023",
|
||||
"principalDue": 500.00,
|
||||
"interestDue": 25.00,
|
||||
"totalDueForPeriod": 525.00
|
||||
}
|
||||
]
|
||||
}
|
||||
----
|
||||
|
||||
=== Transaction Template
|
||||
|
||||
* *Endpoint*: `GET /loans/{loanId}/transactions/template?command=reAmortization`
|
||||
|
||||
== Behavior
|
||||
|
||||
Installments excluded from redistribution:
|
||||
|
||||
* Down-payment installments
|
||||
* Re-aged installments
|
||||
* Additional (N+1) installments
|
||||
|
||||
Outstanding principal from installments with due date ≤ transaction date is redistributed equally across future installments.
|
||||
|
||||
== Implementation Notes
|
||||
|
||||
Creates a `REAMORTIZE` transaction with:
|
||||
|
||||
* `transactionDate` = current business date
|
||||
* `amount` = outstanding principal until transaction date
|
||||
* `principalPortion` = outstanding principal
|
||||
* `interestPortion` = 0
|
||||
* `feeChargesPortion` = 0
|
||||
* `penaltyChargesPortion` = 0
|
||||
|
||||
Non-monetary transaction - no GL entries created.
|
||||
Reference in New Issue
Block a user