-
Mahmoud Aglan authored
The roster's الدفع column answered a different question from the one it appeared to answer, in three compounding ways. It showed a LIFETIME subscription total beside a monthly bill. A player who paid 650 in July, 1,200 for a kit bag and 650 in August read as "2,500" for the current month. Two months of subscriptions were simply added together. "Subscription" was defined as "an invoice line with no product link" — a negative definition, so every hand-typed line became subscription money. That kit bag was typed as free text, so it landed in the subscription figure, was missing from product revenue, and left the same screen reporting the player had never bought the kit they had paid for. The red "has not paid" flag came from an unrelated calculation: matching invoice text with ilike %اشتراك% plus the programme name. Substring matching on Arabic also decides that تجهيزي contains زي. On live data the flag and the amount disagreed on 28 of 247 active enrolments — red rows showing a green figure. The template's "show unpaid only if flagged AND the amount is zero" guard was not defensive coding; it was two sources of truth being reconciled where the disagreement stopped being visible. The figure is now this billing cycle only, derived from the programme's own cycle rather than the calendar month, and one computation feeds the amount, the row flag and the header counts — so they cannot contradict each other again. Each figure is colour-coded by WHY it is that number, with a legend above the table: paid in full, pro-rated for a mid-month join, admin discount, line price override, instalment, partial, unpaid, not yet billed, free. All of it was already recorded in invoice and line metadata and never surfaced; the reason, who applied it and the original price now appear on the row. Colour never carries the meaning alone — each amount also shows a glyph, a label and a screen-reader sentence, and every case sits at 4.5:1 against white. The migration links hand-typed product lines to their product where the full trimmed description matches a product name exactly. Substrings are deliberately not matched and ambiguous lines are left alone: 44 lines / 209,200 EGP link safely, 23 lines / 42,800 EGP are reported for a human instead of guessed at. Verified by replaying the real production rows behind both reported screenshots through the service: every figure the user questioned is now explained. Co-Authored-By:Claude Opus 5 (1M context) <noreply@anthropic.com>
d2f4bf17
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| CreateGroupWizard.php | ||
| GroupForm.php | ||
| GroupList.php | ||
| GroupShow.php |