- 09 Aug, 2026 9 commits
-
-
Mahmoud Aglan authored
The print receipt was always showing only the total amount, even when the transaction was a partial payment (deposit). Now shows paid amount, remaining balance, and a "مدفوع جزئياً" badge when the linked invoice has outstanding balance. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The payment summary panel was only counting inbound payments, ignoring outbound refunds entirely. Now shows net amounts (inbound - refunds) per method, and displays a refund line when refunds exist in the selected period. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Shows most recently paid invoices at the top so the user sees the latest actual money collected, not just the latest generated. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
CollectPaymentWizard and ReconciliationWizard were creating payments without payer_type/payer_id, making them invisible on participant profiles. Now PaymentService inherits payer from the invoice's billable when callers omit it. Also auto-generates reference if empty. Fixed 113 orphaned payments in production. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Auto-generated renewal invoices are created by the system, but collected_by records the real person who collected the money from the participant. Set on every payment collection via updatePaidAmount. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The old code tried to find 'system@oc-sport.com' then fell back to User::first() which silently attributed 222 invoices to a random Head Trainer. Now uses enrollment.created_by as the actor — if that user no longer exists, the invoice is skipped with an error log. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Bug 1: Attendance threshold was counting 'expected' records in the denominator, causing any player with future sessions to have a low attendance rate and get auto-suspended. Fixed by excluding 'expected' status from rate calculation and requiring minimum 5 evaluated records before triggering threshold enforcement. Bug 2: Registration wizard and POS receipt always showed full amount as "paid" even for partial/deposit payments. Fixed to show actual paid_amount and due_amount from the invoice, with distinct badge for partial payment state. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Add 4 dashboard/financial features: compact renewals, retroactive wizard fix, club revenue, expense shortcuts - Compact overdue renewals alert into summary card with toggle detail list - Rewrite retroactive enrollment wizard to CREATE new participants (not search existing) - Add external revenue import form for club lump-sum payments - Add quick-action buttons to financial overview for expenses/revenue - Migration adds external_revenue to expenses category CHECK constraint Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Fix super admin assignment: sync is_super_admin flag when assigning role - Replace is_system block with level-based guard (edit roles below your level) - Add role deletion for non-system custom roles - Allow editing system role permissions and metadata (name_ar, description) - Add role comparison page (/roles/compare) with differences-only filter - Add permissions:sync artisan command for syncing seeder to DB - Add events permissions to seeder, make getPermissionsList() static Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 08 Aug, 2026 1 commit
-
-
Mahmoud Aglan authored
The transfer wizard was querying is_active which doesn't exist on training_programs table — the column is status with CHECK constraint. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 06 Aug, 2026 1 commit
-
-
Mahmoud Aglan authored
4-step wizard: search participant → select invoice → enter correction (new amount, description, reason) → creates remainder invoice if needed. Full audit log trace via Log::channel('audit') and invoice metadata. Accessible from SuperAdmin panel, gated by super_admin.access permission. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 05 Aug, 2026 3 commits
-
-
Mahmoud Aglan authored
Platform fees for ALL retroactive months are charged in the current month (registration date), not backdated. Individual month invoices carry service_fee_amount=0 with a metadata flag, while a single consolidated fee invoice is created dated today covering all months. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New wizard at /receptionist/retroactive-enrollment lets staff enroll participants who started in previous months. Flow: select participant → choose program → set actual start date → mark each month as unpaid or paid-outside-system → optionally pay all outstanding now. Creates individual invoices per month with proper metadata. Supports admin price override for the total. Accessible from receptionist dashboard with enrollments.create permission. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New /roles/matrix page shows all permissions as rows grouped by module with Arabic labels, all roles as columns, and color-coded scope badges (own/branch/academy/all). Includes module and role filtering, stats per role, and click-to-cycle scope for custom roles. System roles are read-only. Accessible from the roles list page via "المصفوفة" button. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 04 Aug, 2026 6 commits
-
-
Mahmoud Aglan authored
Super admins can now override the invoice amount directly from step 2 of the collect payment flow. The override updates the invoice total, stores a full audit trail in invoice metadata (who, when, original amount, new amount, reason, participant), and logs to the audit channel. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Membership is only for participants who explicitly registered with a membership_id. Non-members pay 900, members pay 650 — determined at registration time, not at enrollment. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Participants were staying as 'non_member' after enrollment, causing renewals to be priced at 900 (non-member) instead of 650 (member). EnrollmentService now sets membership_type='member' on enrollment. DB fix: updated 178 participants to 'member', corrected 124 unpaid renewal invoices from 90000 to 65000 piasters. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New billing rule: everyone renews on the 1st, full program price. New enrollees pay pro-rata for remainder of first month, then renew normally on the 1st going forward. - advanceEnrollmentBillingDate() always sets next_billing_date to 1st of next month - calculateFirstBillingDate() same: 1st of next month - DB: set 44 un-renewed enrollments to 2026-08-01 (left 207 already- renewed at 2026-09-01 untouched) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The wizard only generated renewal invoices when next_billing_date had already passed. Now it generates them for any billing date within the current month, so participants can renew as soon as the month starts rather than waiting for the exact billing day. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Participants stayed in 'registered' status even after being enrolled in active groups. The collect payment wizard filters by status='active', making them invisible. Now EnrollmentService transitions registered→active on enrollment. Also fixed 70 existing participants in oc_sport DB. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 03 Aug, 2026 1 commit
-
-
Mahmoud Aglan authored
1. Financial Overview: add subscription vs product revenue split, top programs by revenue, per-product totals, and 12 key financial metrics (churn rate, avg revenue per participant, profit margin, avg days to collect, etc.) All respect the existing period + branch filters. 2. Attendance views (TakeAttendance + QuickAttendance): detect participants with unpaid invoices or overdue renewals and highlight them in red with "غير مدفوع" badge so trainers can see payment status at a glance. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 02 Aug, 2026 17 commits
-
-
Mahmoud Aglan authored
Livewire mount() doesn't automatically receive query params unless the route defines them. Added request()->query('participant') fallback so the "جدّد" button from overdue renewals alert correctly pre-fills the participant and skips to step 2. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
NewRegistrationWizard was setting contact_name to guardian_name_ar which made invoices appear under the parent's name instead of the participant (child). Now uses participant's own person name_ar. Also fixed 75 existing invoices in production via direct DB update. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The radio input uses wire:model.live which only sets the property but doesn't call selectInvoice(). Added updatedSelectedInvoiceId hook so the amount defaults to the full balance due whenever an invoice is picked. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
If migrations fail (e.g. table ownership mismatch), log a helpful fix command and continue startup instead of crashing the container. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Products can now be configured to accept partial payment (deposit/عربون) at checkout. When enabled, the cashier can collect a minimum deposit now and the remaining balance stays on the invoice for later collection. - Migration adds allows_partial_payment + minimum_deposit_percent to products - Product form has toggle with configurable minimum % (10-90%) - POS terminal shows deposit option when cart contains eligible products - POSService creates full invoice but records only the deposit as payment - POS transaction marked 'partially_paid' when deposit is used - Products with deposit enabled show "عربون" badge in POS catalog Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Shows "مدفوع" (green) or "لم يدفع" (red) per participant. Row is highlighted red if participant has unpaid/overdue invoices or their enrollment billing date is past without payment. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Adds two new filters to the activity log: - Reference search: searches inside JSON old_values/new_values for invoice numbers (INV-...) or payment references (PAY-...) - Entity type filter: quickly narrow to invoices, payments, etc. Uses PostgreSQL jsonb::text ILIKE for the deep JSON search. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
SuperAdmin tool that finds enrolled participants with zero invoices in the system, then offers two reconciliation paths: - Two invoices: last month (auto-paid) + current month renewal - One invoice: combined amount for both months After reconciliation, participant is on the normal billing cycle. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The assignments table has a NOT NULL constraint on created_by. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When a trainer opens a session for attendance, if no attendance_records exist (e.g. sessions created before enrollments were activated), the system now auto-generates 'expected' records from active enrollments. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
1. Program delete: - Removed delete button from program list (was broken) - Added red "حذف البرنامج" button inside program show page - Cascade deletes: sessions, schedules, enrollments, waitlists, assignments, groups — all force-deleted in one transaction 2. Trainer-group assignment: - GroupShow: assign/remove trainers via polymorphic assignments table - TrainerShow: assign/remove groups, shows all assigned groups (both head_trainer_id and assignments-based) - A trainer can be assigned to multiple groups - A group can have multiple trainers assigned Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- cash, card, bank_transfer, wallet, online, cheque, other - Each with distinct color and icon in a responsive 4-col grid - Confirmation step uses PaymentMethod enum label() for display Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- OverdueRenewalsAlert now shows participants with unpaid renewal invoices (not just those missing invoices), with amounts and program names - EnrollmentService gates proration behind isEnabled() check - calculateFirstBillingDate defaults to monthly day-1 when billing_cycle is NULL - Alert shows total amount owed and links each participant to payment wizard Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Without this, invoices stay in 'draft' and don't appear in the payment wizard (which only queries sent/partially_paid/overdue). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- ProgramForm defaults: billing_cycle='monthly', billing_day=1 - PricingService.findBasePrice now resolves correct base price by participant.membership_type (member → member price, else → non_member price) - Resolution order: branch+membership > branch+any > global+membership > global - NULL membership_type defaults to non_member pricing Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Big red alert at the top of the dashboard showing participants who haven't renewed their subscription. Each row links directly to the payment wizard with participant pre-selected, auto-generating the renewal invoice. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Search now shows ALL active participants (not just those with existing invoices) - Auto-generates renewal invoices on-the-fly when participant has overdue billing - Radio buttons use wire:model.live for immediate state update (fixes Next button) - Upcoming renewals section shows "Generate Invoice" button as fallback - Next button always visible (disabled until invoice selected) - Advances next_billing_date after generating renewal invoice Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 01 Aug, 2026 2 commits
-
-
Mahmoud Aglan authored
Soft-deleted participants return null from the relationship, causing route('participants.show', null) to throw a missing parameter exception. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- TrainerShow: period_start→date, total_amount→amount, status 'pending'→'active' - trainer-show.blade: period_start→date, sessions_count→quantity, total_amount→amount - AttendanceResource: actual_check_in→check_in_at, date→session.session_date - InvoiceResource: invoice_number→number, balance_due→due_amount, remove description_ar - ReportService: paid_amount→status check, cancellation_reason→withdrawal_reason, wallet status→is_active, remove frozen_amount - SendDailySummary: Organization→Academy, is_active→status='active' - SendParentWeeklyReport: fix morph type + join through session_date - DeactivateExpiredEnrollments: expiry_date→end_date - CertificateController + NotifyGuardianOfAbsence + RemoveAttendanceRecords: morph type 'participant'→Participant::class - SendInvoiceCancelledNotification: cancellation_reason→notes - DeleteParticipant: remove phantom refunded_amount reference Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-