Foo Developer created FINERACT-2998:
---------------------------------------
Summary: Periodic accrual catch-up is back-dated to each
installment's due date and fails when those dates are in a closed accounting
period
Key: FINERACT-2998
URL: https://issues.apache.org/jira/browse/FINERACT-2998
Project: Apache Fineract
Issue Type: Bug
Components: Loan
Reporter: Foo Developer
Assignee: Foo Developer
h3. Summary
On a cumulative (non-progressive) loan with periodic accrual accounting, a
periodic accrual run that catches up several installments posts one accrual per
installment, each back-dated to that installment's due date, instead of one
accrual dated on the run date. This happens whenever accrual runs were missed,
for example a skipped job or a loan that leaves NPA (where accrual is
suspended). If an accounting closure exists between those due dates and the run
date, the back-dated accruals fall inside the closed period and the run fails
for that loan, so none of its income is recognised.
h3. Steps to reproduce
# Create a loan product with accounting "Accrual (periodic)", an interest rate
and daily repayments (for example 12 daily installments, cumulative schedule).
# With the business date feature enabled, disburse a loan on day 0.
# Move the business date to day 4 without running "Add Periodic Accrual
Transactions", then run it once.
# Repeat with a second loan, but before running the job create an accounting
closure for the office dated day 2.
h3. Expected
* Step 3: one accrual transaction dated on the run date covering the interest
of the installments due so far.
* Step 4: the same single accrual, dated on the run date (after the closure),
posts successfully.
h3. Actual
* Step 3: one accrual per installment, dated on each installment's due date
(day 1, day 2, day 3, day 4).
* Step 4: the accruals dated on or before day 2 fall inside the closed period,
the job fails with "Journal entry cannot be made prior to last account closing
date for the branch" and the loan gets no accrual at all; it keeps failing for
as long as the closure stands, because the missed accruals are still dated
before it.
h3. Root cause
In {{LoanAccrualsProcessingServiceImpl.addAccruals}} the cumulative path posts
one accrual per period dated {{min(dueDate, accrualDate)}}, unlike the final
and progressive paths, which merge into one accrual dated on the run date. The
back-dating exists because the cumulative reprocessing has no link from an
accrual to its installment except its date:
* {{calcInterestAccruedAmount}} reads a partial period's accrued interest by
summing accruals dated in the installment's window
({{findAccrualInterestInPeriod}}).
* {{reprocessPeriodicAccruals}} attributes accruals to installments by
transaction date and reverses any whose installment looks over-accrued
({{checkAndUpdateAccrualsForInstallment}} /
{{hasIncomeAmountChangedForInstallment}}).
So a single catch-up dated on the run date would be attributed entirely to the
installment containing that date and reversed on the next reprocess
(reschedule, charge change, transaction adjustment).
h3. Proposed fix
* {{addAccruals}}: a cumulative run posts one accrual dated on the run date,
merged like the final and progressive paths. Merged interest portions are
floored at zero so one installment's over-accrual never offsets another's
accrual.
* {{calcInterestAccruedAmount}}: the cumulative path reads the installment's
own {{interestAccrued}} instead of summing accruals dated in its window.
* {{reprocessPeriodicAccruals}} (cumulative): instead of attributing by date,
fill the accrued interest, fees and penalties into the installments in
installment order, each up to what it charges (as the progressive path does),
and reverse the latest accruals only on real over-accrual: interest above what
is accruable up to the business date (installments due by then net of waivers,
plus the in-progress installment's interest to date), or fees/penalties above
what the schedule charges. Accruals after the last due date stay with
{{adjustAccrualsAfter}}.
Tests: unit tests in {{LoanAccrualsProcessingServiceImplTest}} for reallocating
a catch-up to earlier installments without reversing it, netting accrual
adjustments, and reversing the latest accrual only on real over-accrual.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)