[ 
https://issues.apache.org/jira/browse/FINERACT-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Adam Saghy resolved FINERACT-2946.
----------------------------------
    Resolution: Fixed

> Loan reschedule preview with a grace on principal randomly returns a wrong 
> schedule with a balloon last installment
> -------------------------------------------------------------------------------------------------------------------
>
>                 Key: FINERACT-2946
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2946
>             Project: Apache Fineract
>          Issue Type: Bug
>          Components: Loan
>            Reporter: Foo Developer
>            Assignee: Foo Developer
>            Priority: Major
>             Fix For: 1.16.0
>
>
> h3. Summary
> The loan reschedule preview ({{GET 
> /rescheduleloans/\{id\}?command=previewLoanReschedule}}) for a request with a 
> grace on principal returns one of two different schedules for the same 
> request. Which one comes back varies from call to call. One of them is wrong: 
> it amortises the remaining principal over the grace periods too and ends in a 
> large balloon installment, so the preview can disagree with the schedule that 
> approval then applies.
> h3. Steps to reproduce
> # Create and disburse a loan: 12,000 principal, 1% interest per month, 12 
> monthly installments, declining balance, equal installments.
> # Pay the first installment.
> # Create a reschedule request from the next unpaid installment with a grace 
> on principal of 2:
> {code:json}
> {
>   "loanId": <loanId>,
>   "rescheduleFromDate": "<due date of an unpaid installment>",
>   "graceOnPrincipal": 2,
>   "rescheduleReasonId": <code value id>,
>   "submittedOnDate": "<business date>",
>   "dateFormat": "dd MMMM yyyy",
>   "locale": "en"
> }
> {code}
> # {{GET /rescheduleloans/\{requestId\}?command=previewLoanReschedule}}, then 
> reject the request.
> # Repeat steps 3 and 4 several times on the same running server.
> h3. Expected
> Every preview returns the same schedule, the one approval produces: the 
> remaining principal is amortised over the installments after the grace plus 
> the extension (about 1,066.18 per installment in this example).
> h3. Actual
> The installment amount after the grace alternates between the correct annuity 
> and a smaller one (about 897.21 in this example), followed by a balloon last 
> installment (about 2,665.08).
> h3. Root cause
> A grace on principal creates two term variations with the same applicable 
> date: {{GRACE_ON_PRINCIPAL}} and its child {{EXTEND_REPAYMENT_PERIOD}}.
> * {{LoanTermVariationsData.compareTo}} orders only by applicable date (plus 
> due-date/insert-installment first), so it returns 0 for these two. The sort 
> is stable, so the generator sees them in input order.
> * For a preview, the input order is the iteration order of 
> {{LoanRescheduleRequest.loanRescheduleRequestToTermVariationMappings}}, a 
> {{HashSet}} whose element type does not override {{hashCode}}, so the order 
> is effectively random.
> * In 
> {{AbstractCumulativeLoanScheduleGenerator.applyExceptionLoanTermVariations}}, 
> {{EXTEND_REPAYMENT_PERIOD}} calls {{adjustInstallmentOrPrincipalAmount}}, 
> which recalculates the fixed installment from 
> {{calculateNumberOfRemainingPrincipalPaymentPeriods}}. That only discounts 
> the principal-grace periods registered so far. When the extension is 
> processed before its grace, the grace periods are not discounted and the 
> installment is amortised over too many periods.
> Approval builds its variations from {{Loan.loanTermVariations}} 
> ({{@OrderBy("termApplicableFrom, id")}}), where the grace is always first, so 
> approval is deterministic and correct. Only the preview is affected.
> h3. Proposed fix
> Give same-date ties in {{LoanTermVariationsData.compareTo}} a deterministic 
> order:
> # due-date and insert-installment variations (keep their existing first 
> place);
> # grace on principal and grace on interest;
> # extend repayment period;
> # everything else.
> This is the order approval already gets from the id ordering, so preview and 
> approval agree.
> h3. Tests
> A new unit test, {{LoanTermVariationsDataTest}}, covering the same-date 
> tie-breaks (grace before extend in either input order, due-date and 
> insert-installment still first, different dates still ordered by date).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to