• Mahmoud Aglan's avatar
    fix(pricing): count a player's age forwards, and hold the picker to the same ceiling as the engine · 54df3e88
    Mahmoud Aglan authored
    Carbon 3 signs its differences: `$a->diffIn*($b)` answers `$b − $a`. The
    pricing engine asked it the other way round —
    `now()->diffInYears($birthday)` — so every participant it priced arrived
    at the rules with a negative age and a negative membership duration.
    
    The damage ran in both directions at once. A rule with a `min` never
    matched anyone again: the loyalty and annual recipes both ask for twelve
    months, and −25 is not twelve. A rule with a `max` matched the entire
    academy: the juniors recipe is `max: 6`, and −34 is comfortably under
    six, so one click in the rule builder would have taken 10% off every
    price in the club. The registration wizard computed age correctly in its
    own provisional context, which is why the desk saw one price at
    registration and another at renewal.
    
    Age and tenure now read from the older moment forward, through two named
    helpers that say why, and a date in the future is no age rather than a
    negative one.
    
    Alongside it, the discount picker: `selectedDiscountIds` is a public
    Livewire property, so it is a list the browser sends, and the total was
    summed from whatever ids arrived. applyDiscount() refuses a blocked rule
    and diverts an above-ceiling one into an approval request; neither guard
    survived to where the money was worked out. The engine's verdict is
    re-read there now, the academy's global discount ceiling applies to a
    hand-assembled total exactly as it does at step 8, a manual discount
    above the actor's cap reaches neither the total nor the invoice
    snapshot, and the picker's state is #[Locked] — it is driven entirely
    by wire:click, so nothing needed to arrive from the browser at all.
    
    Also here, found while reading for the above:
    
    - POSTerminal::updateQuantity() did not check the index exists, so an
      invented one wrote a cart line made of a quantity and nothing else.
    - The same reversed diff in four other places: overdue invoices and
      renewals reported negative days on the dashboard and in reminder
      messages, expiring memberships reported negative days remaining, and
      a product's months-active pinned to 1, inflating its average monthly
      movement to its entire lifetime sales.
    - validateCoupon() still carried a comment promising academy-wide
      coupons, three commits after branch_owns_the_catalogue removed them.
    
    Verified: 379 tests green on SQLite and against the restored OC-Sport
    tenant. That tenant carries one pricing rule (sibling_order, 4 EGP) and
    no invoice with a discount snapshot, so there is no historical billing
    to correct — the bug was waiting on the first age or loyalty rule.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    54df3e88
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...