• Mahmoud Aglan's avatar
    feat(registration): register a whole family in one visit, priced as a family · 50f3a2bd
    Mahmoud Aglan authored
    The reception wizard took exactly one child. That was not merely inconvenient:
    the sibling discount is priced off how many children a family has, and a child
    registered alone always looked like a family of one. The first child could
    never qualify, and by the time the second was entered the first one's invoice
    was frozen — invoices are immutable — so it could not be put right afterwards
    either. The only way to get the discount was to know to register the younger
    child first, which is not a system, it is folklore.
    
    Step 1 is a roster now. The `participant_*` properties stay as the draft form
    for the child being typed, so every existing rule, the NID decoder and the
    membership-id sibling warning are untouched; `players[]` is the committed list
    and the only thing confirm() reads. Each child picks their own programme on
    step 4, because siblings are rarely the same age.
    
    resolveSiblingPosition() counts the children already on the books AND the ones
    being registered alongside — that one change is what makes the discount fire
    for a family arriving together.
    
    The money is written the way the rest of the system writes it: one participant,
    one enrolment and one invoice per child, which is also how the renewal cron
    finds them next month. What is new is that the desk takes a single sum and it
    is allocated across those invoices in roster order, so an underpayment leaves a
    visible balance on the last child rather than a shortfall smeared over all of
    them. The platform fee and a super-admin override are split by value with the
    rounding remainder on the last child, so the invoices always add back up to
    exactly what was quoted. Cart lines carry a player index — a kit is issued to
    a person — and removing a child takes their lines with them and renumbers the
    rest, or the items would silently reattach to whoever slid into that slot.
    
    SiblingRegistrationTest pins the parts that can lose money: two children get
    two invoices summing to the quoted total, one payment lands on them in full,
    and a part payment settles the first child and leaves one visible balance.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    50f3a2bd
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...