• DevPilot's avatar
    feat(accounting): posting chains + accrual reconciler · 1bc26cc1
    DevPilot authored
    Two gaps closed, both of which let real money go unrecorded.
    
    CHAINS — money moving between accounts across several entries
    
    The allocation wizard splits one amount inside one entry. It had no
    answer for the same money moving through a sequence of entries as
    separate actions happen: cash into a safe, settled to main, banked.
    Each hop must clear the account the previous one filled, and nothing
    enforced that.
    
    Concretely broken: every cash collection debited one global account
    regardless of which safe took it, then the settlement credited an
    unmapped `treasury:sub_cash` pointer that fell back to الصندوق بالدولار
    — an account no collection had ever touched. The sub-safes were also
    pointed at the USD/EUR cash boxes, so 972,791 EGP of pound takings sat
    in foreign-currency accounts.
    
    A chain step now declares where it leaves money and which earlier step
    it clears; the counter side is derived by re-resolving that step's rule
    against the same document, so a chain cannot be authored that fails to
    net to zero. Each safe owns a GL account, resolved through one service
    both the engine and the chain call. Guards refuse a hop whose two sides
    resolve to the same account, or whose type puts both on the same side.
    
    The historic misposting is corrected by a reviewable journal entry —
    not by rewriting posted history — and cannot be posted twice.
    
    ACCRUALS — obligations the ledger was never told about
    
    24 revenue streams were marked `needs_code`. 18 are now booked, finding
    1,316 claims worth 835,167 EGP that were nowhere in the accounts.
    
    Built as a scanner over the source tables rather than event dispatches
    in twelve modules: an event can be missed or misnamed — the coach
    payroll listener was bound to a name nothing dispatched — while a
    scanner is self-healing, retroactive and idempotent.
    
    Critically, collection here posts revenue directly, so accruing without
    releasing would double-count on every future payment. Each accrual is
    released when its document is paid, by mirroring the same rule.
    
    Outflows that had no entry at all are wired too: staff loans (an asset,
    not an expense), end of service, coach fees, goods receipt (against a
    new clearing account, so the invoice does not book inventory twice),
    depreciation per asset category, stock variances, asset disposal, and
    fine waivers.
    
    6 streams are deliberately left unbooked — no amount or no counterparty
    recorded, so any figure would be a guess. They are listed on screen
    with what each one needs.
    
    Verified against a scratch copy of production: trial balance nets to
    0.00, no unbalanced entries, no postings to header accounts, every pass
    idempotent.
    Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
    1bc26cc1
Name
Last commit
Last update
..
Academies Loading commit data...
AcademyContracts Loading commit data...
AccessMatrix Loading commit data...
Accounting Loading commit data...
Achievements Loading commit data...
ActivitySubscriptions Loading commit data...
Alerts Loading commit data...
Archive Loading commit data...
Audit Loading commit data...
Auth Loading commit data...
Branches Loading commit data...
Carnets Loading commit data...
Cashier Loading commit data...
Children Loading commit data...
Coaches Loading commit data...
Dashboard Loading commit data...
Death Loading commit data...
Disciplines Loading commit data...
Divorce Loading commit data...
Documents Loading commit data...
Facilities Loading commit data...
FacilityDashboards Loading commit data...
FacilityGrids Loading commit data...
Fines Loading commit data...
Foreign Loading commit data...
Forms Loading commit data...
HR Loading commit data...
Honorary Loading commit data...
Installments Loading commit data...
Interviews Loading commit data...
Inventory Loading commit data...
MatchCenter Loading commit data...
MedicalBoard Loading commit data...
Members Loading commit data...
News Loading commit data...
Notifications Loading commit data...
ParentPortal Loading commit data...
Payments Loading commit data...
PlayerAffairs Loading commit data...
PlayerApi Loading commit data...
PlayerAuth Loading commit data...
PlaygroundAdmin Loading commit data...
PoolManagement Loading commit data...
Pricing Loading commit data...
Procurement Loading commit data...
Receipts Loading commit data...
Rentals Loading commit data...
Reports Loading commit data...
Reservations Loading commit data...
Roles Loading commit data...
Rules Loading commit data...
Sales Loading commit data...
Scheduling Loading commit data...
Seasonal Loading commit data...
ServiceCatalog Loading commit data...
Sessions Loading commit data...
Settings Loading commit data...
Sports Loading commit data...
SportsActivity Loading commit data...
SportsDashboard Loading commit data...
Spouses Loading commit data...
Subscriptions Loading commit data...
Support Loading commit data...
Temporary Loading commit data...
Tournaments Loading commit data...
TrainerPortal Loading commit data...
Training Loading commit data...
TrainingGroups Loading commit data...
Transfers Loading commit data...
Treasury Loading commit data...
Tutorials Loading commit data...
Users Loading commit data...
Waiver Loading commit data...
Workflow Loading commit data...