Foo Developer created FINERACT-2869:
---------------------------------------
Summary: Post Interest For Savings job stops posting interest on
idle savings accounts after the first posting (pivot-date mode)
Key: FINERACT-2869
URL: https://issues.apache.org/jira/browse/FINERACT-2869
Project: Apache Fineract
Issue Type: Bug
Components: Savings
Reporter: Foo Developer
Assignee: Foo Developer
h3. Summary
When the global configuration
{{allow-backdated-transaction-before-interest-posting}} is *disabled*
(pivot-date mode), the _Post Interest For Savings_ job posts interest on a
savings account only once. Every later run silently posts nothing for that
account for as long as it has no new deposit or withdrawal, however many
posting periods have passed: the job succeeds, no interest transaction is
created and {{interestPostedTillDate}} does not move.
h3. Steps to reproduce (stock Fineract, {{develop}})
# Enable {{enable-business-date}} and *disable*
{{allow-backdated-transaction-before-interest-posting}} ({{PUT
/v1/configurations/{id}}} with {{{"enabled": false}}}).
# Set the business date (and COB date) to {{2026-08-15}}.
# Savings product: 5% nominal annual interest, daily compounding, monthly
posting, daily balance, 365 days, no accounting.
# Create, approve and activate a savings account on {{2026-06-01}} and deposit
{{1000}} on {{2026-06-01}}.
# Run the job: {{POST /v1/jobs/short-name/SA_PINT?command=executeJob}}.
Interest is posted for June and July (transactions on {{2026-07-01}} and
{{2026-08-01}}), {{interestPostedTillDate}} becomes {{2026-08-01}}.
# Without any other activity on the account, move the business date (and COB
date) to {{2026-10-15}} and run the job again.
h3. Expected
Interest is posted for August and September (transactions on {{2026-09-01}} and
{{2026-10-01}}) on the carried-forward balance, and {{interestPostedTillDate}}
advances.
h3. Actual
The second run posts nothing: no new interest transaction,
{{interestPostedTillDate}} stays at {{2026-08-01}}, no error. The account never
earns interest again until a new deposit or withdrawal is made.
h3. Root cause
In pivot-date mode
{{SavingsAccountReadPlatformServiceImpl#retrieveAllSavingsDataForInterestPosting}}
only loads the transactions dated on or after {{interest_posted_till_date}},
and the earlier history is carried in as {{runningBalanceOnPivotDate}}, which
{{SavingsAccountInterestPostingServiceImpl#calculateInterestUsing}} uses as the
starting balance of the first period. For an account with no activity since the
last posting, the non-interest-posting transaction list is therefore empty.
{{SavingsAccountInterestPostingServiceImpl#appendPostingPeriodIfAny}} returns
early when its transaction list is empty, without creating a {{PostingPeriod}}.
The carried-forward balance never earns interest, although
{{PostingPeriod#createFromDTO}} already handles an empty list: it builds one
end-of-day balance at the opening balance spanning the whole period. The first
posting is not affected only because {{interest_posted_till_date}} is still
null then, so the full history is loaded.
h3. Proposed fix
In {{appendPostingPeriodIfAny}}, skip a period without transactions only when
the balance carried into it is also zero; otherwise create the
{{PostingPeriod}} with the empty list and let its flat-balance fallback compute
the interest. The overdraft split calls (primary/secondary lists filtered per
month) keep the current early return, because there an empty list means "this
side does not apply in the period" and building a period from the carried
balance would count interest twice.
h3. Test
A unit test for
{{SavingsAccountInterestPostingServiceImpl#calculateInterestUsing}}: an account
in pivot-date mode with no transactions after the pivot date and a non-zero
{{runningBalanceOnPivotDate}} must get one posting period per elapsed posting
period with non-zero interest; with a zero carried balance no period is
produced.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)