• Mahmoud Aglan's avatar
    fix(financial): attribute revenue to what was actually sold · 35200985
    Mahmoud Aglan authored
    Measured against the live oc-sport database, subscription revenue read
    457,970 EGP against a genuine 345,257 — overstated by 32.6% — while the
    per-programme breakdown summed to 39,873, about 12% of reality.
    
    Three distinct causes:
    
    POSService::buildInvoiceItems() discarded the item_type/item_id it was
    handed, so every POS line landed with a NULL itemable_type. Reporting
    reads NULL as "programme subscription", which moved 102,000 EGP of
    product sales into subscription revenue — 90% of the error — and meant
    no product-ownership check could ever pass. Lines now carry their
    Product or Kit. A migration backfills history by matching invoice lines
    to their POS lines, filling only NULL rows and only where the match is
    unambiguous; a production dry run matched 44 of 45 with 0 ambiguous.
    
    Pro-rata allocation divided by invoices.total_amount, but line totals
    sum to subtotal_amount — total_amount also carries discount, tax and
    service fees. Every bundled invoice was therefore split on the wrong
    denominator (10,713 EGP).
    
    topPrograms joined enrolments to invoices and dropped anything without
    an invoice_id. Only 88 of 350 enrolments have one, so 75% of programmes
    reported zero. Now a UNION: the exact link where it exists, participant
    fallback where it does not, split evenly across a participant's
    programmes. Reconciles at 333,105 EGP.
    
    Also: the mounted revenue widgets and the receptionist dashboard omitted
    direction='inbound', counting refunds as income, and the widgets' raw
    queries bypassed SoftDeletes and cancelled invoices.
    
    EnrollExistingWizard read BasePrice directly, ignoring membership type
    and every pricing rule, so it quoted a different figure than the
    registration wizard for the same player. Both now go through
    PricingService.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    35200985
Name
Last commit
Last update
..
CollectPaymentWizard.php Loading commit data...
EnrollExistingWizard.php Loading commit data...
NewRegistrationWizard.php Loading commit data...
ReceptionistDashboard.php Loading commit data...
RetroactiveEnrollmentWizard.php Loading commit data...