3.0 KiB
Member-summary dues corrections and payment reversals
Administrators can now open Correct dues beside a member's season dues and Reverse incorrect payment beside an unreversed receipt on the member summary. The correction dialog prefills the current effective dues total and requires a reason. The reversal dialog identifies the member and receipt, requires a reason and confirmation, and explains that reversal does not issue a refund.
Successful actions return to the same member summary and preserve paging. Totals, balances, correction history and payment status refresh immediately. Cancel does not change the ledger. Reversed receipts remain visible with their reason and no longer offer a reversal button. Members and archived clubs retain their existing read-only behavior.
classes/MemberSummary.php adds the two dialogs and the explicit adjust and
reverse POST actions. They use the existing CSRF and club-management checks and
the existing modal validation/error handling. The summary remains free of inline
editing fields.
classes/LedgerService.php adds optional membership constraints to corrections
and reversals. These are checked against the locked dues record inside each
transaction, before writes or idempotent success. Forged requests cannot correct
another member's dues or reverse another member's receipt, including within the
same club. Existing club-page callers remain compatible.
Corrections still cannot reduce dues below payments received. Both operations append records and require a successful audit write in the same transaction. Duplicate request keys remain idempotent; already-reversed payments reject a new reversal request. No financial history is deleted and no external payment or refund is initiated. No schema change, dependency or migration is required.
Regression coverage includes prefilled correction values, successful browser correction/reversal, cancellation, updated totals, removal of reversal buttons, wrong-member and foreign-club requests, member access restrictions, correction limits, duplicate requests, audit rollback and preserved reasons. The history paging test counts actual payment-table records separately from hidden dialog context, which now also identifies the selected receipt.
Validation passed 186 targeted checks: 35 member-action HTTP, 22 member-summary HTTP, 28 tenant browser, 33 general browser, 41 security/capacity service, 11 paging/export HTTP and 16 deployment tooling checks. Source validation passed for 67 PHP files, 58 JavaScript files and 39 XSL stylesheets.
The two application files were deployed to development and hash verified. A
protected temporary runtime probe confirmed the membership-scoped correction
and reversal methods, then was removed. Prior files were saved under
.tools/deployment-backups/member-corrections-7f0ba3ed47d24a3789f30bc116f8a8a8.
No development database records were changed. Tests used disposable data with
external email disabled; the isolated database server was stopped after cleanup.