[
https://issues.apache.org/jira/browse/FINERACT-2891?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Foo Developer updated FINERACT-2891:
------------------------------------
Description:
h3. Steps to reproduce
# Create a savings product and activate an account on it. Add a weekly fee
charge of 45.00 due on the activation date.
# Deposit 10.00.
# Pay the charge twice, 2.00 each: {{POST
/v1/savingsaccounts/\{accountId\}/charges/\{chargeId\}?command=paycharge}}
{code:json}
{"amount": 2, "dueDate": "<date>", "dateFormat": "dd MMMM yyyy", "locale": "en"}
{code}
The charge now shows paid 4.00, outstanding 41.00, and the same due date.
# Undo the second payment: {{POST
/v1/savingsaccounts/\{accountId\}/transactions/\{transactionId\}?command=undo}}
h3. Expected
Paid 2.00, outstanding 43.00, due date unchanged.
h3. Actual
Paid 2.00, outstanding 45.00, and the due date moves back one week. Paid plus
outstanding is more than the fee amount.
h3. Root cause
{{SavingsAccountCharge.pay()}} closes a recurring fee's cycle (advances the due
date, resets the outstanding) only when the outstanding reaches zero, so a
partial payment leaves the cycle open. {{SavingsAccountCharge.undoPayment()}}
always does the reverse: it calls {{resetPropertiesForRecurringFees()}} and
{{updateToPreviousDueDate()}} unconditionally. That is only right when the
undone payment closed the cycle. Even then the cycle's outstanding is reset to
the whole fee, which loses its other partial payments. {{undoWaiver()}} has the
same problem for a waiver that closed a partly paid cycle.
h3. Proposed fix
{{SavingsAccount}} works out what the charge received after the undone
transaction (later non-reversed payments and waivers on the same charge) and
passes it to the charge. The fee's transactions are undone latest first:
* a payment on the open cycle goes back to that cycle, and the due date stays;
* the latest payment that closed the previous cycle reopens that cycle with the
undone amount outstanding, and the due date moves back one interval;
* undoing a payment or waiver of an earlier cycle while later ones exist is
refused with a validation error; the later ones have to be undone first.
Non-recurring charges are unchanged.
h3. Tests
Unit tests in {{SavingsAccountChargeUndoPaymentTest}} ({{fineract-savings}})
for each case above.
was:
When user clicks on settle receivable, all charges should be settled
Summary
Clicking Settle Receivables on a Hold and Post account has no effect. The
account has two Active receivable holds that are fully funded by the ledger
balance, but after confirming the action both holds stay Active, no Pay Charge
transaction is posted, and the balances do not change.
Per the ticket description: "When user clicks on settle receivable, all charges
should be settled."
Starting State (Holds Details tab)
Account Overview: Ledger Balance = AED 3.00, Available Balance = AED 0.00,
Total Held Amount = AED 3.00
Hold ID
Created
Status
Hold Type
Linked Charge
Initial Amount
Remaining Amount
1025189
02/10/2026
Active
Receivable
7211 - Weekly charge
2.00
2.00
1025185
02/10/2026
Released (struck through)
Receivable
7211 - Weekly charge
4.00
0.00
1025183
02/10/2026
Active
Receivable
7211 - Weekly charge
1.00
1.00
The two Active holds total AED 3.00, which exactly matches both the Total Held
Amount and the Ledger Balance. The funds are already reserved and fully cover
the held amount, so nothing should block settlement.
Steps to Reproduce
Open account 000010845 → Holds Details tab and confirm the starting state above.
Open the account action menu (☰) → Settle Receivables.
In the "Are you sure you want to settle receivables?" dialog, click Confirm.
The page reloads (URL gets ?_r=…). Review the Holds Details tab and Account
Overview.
Actual Result
The screen after confirming is identical to the screen before:
Holds 1025189 (2.00) and 1025183 (1.00) are both still Active, with their full
Remaining Amount unchanged.
Ledger Balance is still AED 3.00, Available Balance is still AED 0.00, and
Total Held Amount is still AED 3.00.
There is no error message and no visible confirmation.
Expected Result
Both Active holds should be Posted, with Remaining Amount = 0.00.
AED 3.00 should be posted against charge 7211 (Weekly charge) as Pay Charge
transaction(s), and the charge's Paid/Outstanding figures should update to
match.
The account should end with Ledger Balance AED 0.00, Total Held Amount AED
0.00, and Available Balance AED 0.00.
Suspected Area
Silent no-op. The action completes without an error but changes nothing. It's
worth checking whether the Settle Receivables endpoint actually selects these
hold records, for example whether its query filters them out by status, due
date, or charge state, and whether it returns success without processing
anything.
Partial holds against one charge. All three holds belong to the same charge
(7211). One was released, and two small partial holds (2.00 and 1.00) are still
active. If settlement only runs when the held amount covers the charge's full
outstanding amount, then partial holds like these would never be posted. That
would contradict the requirement that all held charges get settled.
> Undoing a partial payment of a recurring savings fee resets the outstanding
> to the full fee and moves the due date back a cycle
> -------------------------------------------------------------------------------------------------------------------------------
>
> Key: FINERACT-2891
> URL: https://issues.apache.org/jira/browse/FINERACT-2891
> Project: Apache Fineract
> Issue Type: Bug
> Components: Organization
> Reporter: Foo Developer
> Assignee: Foo Developer
> Priority: Major
>
> h3. Steps to reproduce
> # Create a savings product and activate an account on it. Add a weekly fee
> charge of 45.00 due on the activation date.
> # Deposit 10.00.
> # Pay the charge twice, 2.00 each: {{POST
> /v1/savingsaccounts/\{accountId\}/charges/\{chargeId\}?command=paycharge}}
> {code:json}
> {"amount": 2, "dueDate": "<date>", "dateFormat": "dd MMMM yyyy", "locale":
> "en"}
> {code}
> The charge now shows paid 4.00, outstanding 41.00, and the same due date.
> # Undo the second payment: {{POST
> /v1/savingsaccounts/\{accountId\}/transactions/\{transactionId\}?command=undo}}
> h3. Expected
> Paid 2.00, outstanding 43.00, due date unchanged.
> h3. Actual
> Paid 2.00, outstanding 45.00, and the due date moves back one week. Paid plus
> outstanding is more than the fee amount.
> h3. Root cause
> {{SavingsAccountCharge.pay()}} closes a recurring fee's cycle (advances the
> due date, resets the outstanding) only when the outstanding reaches zero, so
> a partial payment leaves the cycle open.
> {{SavingsAccountCharge.undoPayment()}} always does the reverse: it calls
> {{resetPropertiesForRecurringFees()}} and {{updateToPreviousDueDate()}}
> unconditionally. That is only right when the undone payment closed the cycle.
> Even then the cycle's outstanding is reset to the whole fee, which loses its
> other partial payments. {{undoWaiver()}} has the same problem for a waiver
> that closed a partly paid cycle.
> h3. Proposed fix
> {{SavingsAccount}} works out what the charge received after the undone
> transaction (later non-reversed payments and waivers on the same charge) and
> passes it to the charge. The fee's transactions are undone latest first:
> * a payment on the open cycle goes back to that cycle, and the due date stays;
> * the latest payment that closed the previous cycle reopens that cycle with
> the undone amount outstanding, and the due date moves back one interval;
> * undoing a payment or waiver of an earlier cycle while later ones exist is
> refused with a validation error; the later ones have to be undone first.
> Non-recurring charges are unchanged.
> h3. Tests
> Unit tests in {{SavingsAccountChargeUndoPaymentTest}} ({{fineract-savings}})
> for each case above.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)