• Mahmoud Aglan's avatar
    fix(settlement): the card's price is the debt, not the sum of everything typed toward it · 396f19ac
    Mahmoud Aglan authored
    Participant 128 on OC-Sport: an 8,000 registration card, 2,500 paid in
    July and 2,500 in August. The settlement screen told the operator he had
    paid 5,000 of 10,500 and still owed 5,500, and offered a button to bill
    him that 5,500 on top.
    
    The 10,500 is real, and that is the problem. INV-000310 carried the first
    instalment on 2 July. On 5 August the full 8,000 card was invoiced again
    as INV-000588, 2,500 was collected against it, and the next day it was
    split — reduced to 2,500 with a 5,500 remainder as INV-000593 — by
    someone who never saw the July instalment. Three lines, 10,500, for a
    card that costs 8,000.
    
    bundleStatus() then read `max(billed, price)`. That reading treats
    hand-typed lines as if they defined the obligation, so every duplicate
    and every correction raised the debt, and the excess disappeared into a
    larger number instead of being noticed. But a hand-typed line is an
    instalment TOWARD a card whose price the product record still holds: the
    card is what is owed. A real product sale is different — its price froze
    at the till — so that keeps billing as the obligation.
    
    So: expected is the frozen sale price for a real sale, and the card's
    price otherwise. Anything typed past it is the same money entered twice
    and is reported as `over_billed_bundle` rather than absorbed. #128 now
    reads 5,000 of 8,000 with 3,000 left, flagged for a 2,500 double entry.
    A scan of the restored tenant finds exactly one such account: his.
    
    Two guards on the tool that produced it. The correction wizard clamped
    paid_amount down to the new total and rewrote the payment rows
    themselves, so cutting an invoice below what had been collected against
    it destroyed real money — the payment row said one thing and its
    double-entry transaction still said another, and nobody was told. It now
    refuses and names the settlement wizard, which can move the payment or
    credit it to a wallet. And the split step lists what the account already
    carries, so a second "first instalment" is visible before it is created
    rather than three weeks after.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    396f19ac
Name
Last commit
Last update
..
Activities Loading commit data...
Admin Loading commit data...
Assignments Loading commit data...
Attendance Loading commit data...
Audit Loading commit data...
Auth Loading commit data...
Branches Loading commit data...
CashSessions Loading commit data...
Components Loading commit data...
Concerns Loading commit data...
Dashboard Loading commit data...
Documents Loading commit data...
Enrollments Loading commit data...
Evaluations Loading commit data...
Events Loading commit data...
Facilities Loading commit data...
Financial Loading commit data...
Groups Loading commit data...
Guardian Loading commit data...
HR Loading commit data...
Inventory Loading commit data...
Invoices Loading commit data...
Messaging Loading commit data...
Notifications Loading commit data...
POS Loading commit data...
Parent Loading commit data...
Participants Loading commit data...
People Loading commit data...
Portal Loading commit data...
Pricing Loading commit data...
Profile Loading commit data...
Programs Loading commit data...
Public Loading commit data...
Receptionist Loading commit data...
Reports Loading commit data...
Requests Loading commit data...
Roles Loading commit data...
Schedule Loading commit data...
Settings Loading commit data...
Trainer Loading commit data...
Training Loading commit data...
Users Loading commit data...
Wallets Loading commit data...
Website Loading commit data...
WhatsApp Loading commit data...
Wizards Loading commit data...
BranchSwitcher.php Loading commit data...
Dashboard.php Loading commit data...
GlobalSearch.php Loading commit data...