- 11 Aug, 2026 2 commits
-
-
Mahmoud Aglan authored
- Add transferred_from_transfer_id column to track child separation origin - TransferProcessor sets the field when completing child separations - Member profile detects separation transfers and shows: parent name, separation date, actual paid fees (not full membership_value) - Financial summary shows "رسوم الفصل المدفوعة" for separated children - Transfer status labels: "requested" now shows "في انتظار الدفع" - AuditService: comprehensive Arabic labels for statuses, fields, and formatted values (payment_method, membership_type, classification, etc.) - Backfill migration links existing completed transfers to their target members Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Retroactive payments now fire payment.completed event so DailyCashMovementService records them in daily_cash_movements (treasury). Zero-amount installments (from bad data where down_payment = total_amount) no longer create empty payment records. Also simplifies overdue subscriptions section on member profile to a warning banner. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 10 Aug, 2026 1 commit
-
-
Mahmoud Aglan authored
1. Subscription badge: shows if active (paid), overdue, or awaiting renewal 2. Overdue table: lists all unpaid subscriptions with amounts needed to renew 3. Transfer origin card: shows who transferred, when, and actual amount paid 4. Financial summary: shows actual paid amount (not original membership_value) for transferred members 5. Payment history link for deceased member (accessible from transferee's page) 6. Redirect /members/{id} to archive page if member is archived Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 09 Aug, 2026 5 commits
-
-
Mahmoud Aglan authored
The subscriptions table has no is_voided column — the status filter ('pending', 'overdue') is sufficient. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Adds a calc_breakdown to the fee response showing acquisition_date, effective_transfer_date, exact diff (years/months/days), and each year range so staff can verify the calculation is correct. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The date under the status badge now uses membership_origin_date (the original first-ever date of the membership) instead of created_at (which for death/waiver transfers is just when the new record was created). Falls back to activated_at then created_at. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Shows a modal popup on death/create page listing overdue years and amounts. The user must go to subscriptions and settle outstanding balances before registering a death case. The death fee calculation itself remains unchanged. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When membership transfers via death/waiver, the fee calculator now uses the original membership creation date instead of the transfer date. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 08 Aug, 2026 28 commits
-
-
Mahmoud Aglan authored
Creates a complete reservation system for freelance coaches and individuals booking pool lanes or session cards. Includes: - 3-step wizard (booker info → package selection → confirmation) - Overflow handling when participant count exceeds lane capacity - Reservations create real sa_groups records for Mirror grid integration - Session tracking (used/remaining) with manual + automatic decrement - Payment request integration with cashier module - List view with search/filter and detail view with progress tracker New tables: sa_pool_reservations, sa_groups.source_type/pool_reservation_id New programs: SWIM-LANE-RENTAL, SWIM-CARDS (program_type='rental') Updated pricing in sa_academy_pricing for lanes and cards Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
fix(sports): redesign assessment wizard — programs as expandable list with inline groups & centered modal - Programs display as vertical list items with chevron toggle - Clicking a program expands its groups panel directly beneath it - Group creation opens a centered modal popup instead of inline section - Fixed GroupQuickCreateApiController to return full group data (fees, coach, discipline) - Groups render with progress bars and proper fee display after creation Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Classification now shows: Discipline tabs → Program cards → Groups - Each group card shows progress bar (capacity %), coach, price, remaining slots - "Add Group" button creates a new group inline via API without leaving the page - New API: POST /api/sa/groups/quick-create for inline group creation - Controller now passes programs data to the view Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Route is POST /sa/groups/{id}, not /sa/groups/{id}/update. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Teams (Prep–General, 90-120min): 3-6x/week - Member: 750–900 EGP | Non-member: 1500–1800 EGP Masters (25+, 60-120min): 2-5x/week - Member: 800–1450 EGP | Non-member: 1600–2900 EGP Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Kids Academy (6mo–12y): Groups 5-1, Private, and Babys - Member: 480–1600 EGP | Non-member: 960–3200 EGP Adults Academy (13+): Groups 5-1 - Member: 600–1000 EGP | Non-member: 1200–2000 EGP Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Adds lane rental pricing for the Olympic pool per the official pricing table: - 25m lane: 500-1400 EGP (max 8 players) by entity type - 50m lane: 800-1700 EGP (max 12 players) by entity type Entity types: schools/gov, clubs/federations, other entities, foreign entities Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- SaMonthlySubscriptionJob: runs on days 1-3 of each month, auto-generates subscriptions for all active players using SubscriptionGeneratorService - Subscriptions index page now shows stats bar (total, paid, unpaid, overdue, collected amount, pending amount) for the selected month Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Shows player name, group, discipline, program, level, and monthly fee amount in a modal before the coach confirms the submission. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The classification query required status='completed' AND payment_status= 'paid', but the correct flow is: form fee → photo → disciplines → THEN coach classifies. Players were invisible because they're still 'in_progress' at that point. Fixed to: form_payment_status='paid' AND selected_disciplines not empty AND status IN ('in_progress','completed'). Also fixed the assess() method's guard from payment_status to form_payment_status. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
handleSubscriptionPaid() now finds the player's assessed registration and marks it as completed (payment_status='paid', status='completed'). Previously, paying the subscription only updated sa_subscriptions but never flowed back to sa_registrations, leaving the wizard card button permanently disabled. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
1. Player profile now shows a "طباعة الكارت" button (green) if the player has an active card, or "إنشاء الكارت" (outline) if they have a paid registration without a card yet. This provides a direct path to print/generate cards without re-entering the wizard. 2. Medical Board list (/medical-board) now has clickable player names that link to the player's profile (SA players → /sa/players/{id}, membership players → /members/{id}). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
1. Renamed "تقييم اللاعبين" to "تصنيف وتعيين اللاعبين" throughout (sidebar, page titles, buttons) — better describes the actual action of classifying players into groups. 2. Assessment page now shows discipline tabs — clicking a discipline filters groups to only show those belonging to that activity. Player's selected disciplines are already visible at top. 3. Fixed medical certificate bug: when approving via the player profile edit form (updateMedical), the document's approval_status was not being synced. Now setting player to fit/conditional also marks the latest document as approved, and unfit marks it as rejected. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Step 4 now shows contextual messages: - Default: "waiting for coach assessment" - After assessment: "waiting for subscription payment" - After payment: enables card generation button Also refines the lookup block: only refuse entry when status is completed/assessed AND card_generated=1 (fully done). Players who still need to finish steps are redirected to resume. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Players who already completed the full registration (status=completed/assessed) are now refused at the first lookup screen with an error message instead of being redirected to their existing registration. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Two fixes: 1. handleRegistrationFormPaid now also sets registration_fee_paid=1 on sa_players, so next time the system knows they already paid. 2. lookupPlayer checks for existing in-progress/completed registration and redirects to it instead of creating a duplicate. This means a returning player who already completed all steps goes back to step 4 (their finished registration), not a new step 1. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Root cause: submitFormPayment used entity_type 'sa_registrations' which triggered completeRegistration() on payment — jumping straight to step 4. Fixes: - Use entity_type 'sa_registration_form' so only form_payment_status is updated (not status/payment_status) - Remove status='completed' for returning players — they still need photo + disciplines steps - Fix determineStep: only jump to 4 on actual status=completed/assessed, not on payment_status=paid - Lookup API now returns is_existing_player + registration_fee_paid flags - Wizard badges show "لاعب مسجل بالفعل" and "الاستمارة مدفوعة" indicators Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Covers: registration desk, coach assessment, group coaches, training attendance, swimming coaches/lanes, medical certificates, monthly subscription renewal, and payment flow after assessment. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
After coach assesses and assigns player to group, the monthly subscription payment request is now sent to the cashier queue (payment_type=sports_subscription, entity_type=sa_subscriptions). When cashier completes it, the event listener auto-marks the subscription as paid. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Controller detects logged-in coach's disciplines via employee_id → sa_coaches - Pending players filtered to those whose selected_disciplines overlap with coach's disciplines (or manual dropdown filter) - Available groups in assess form filtered by player's selected disciplines intersected with coach's disciplines - Added discipline filter dropdown to assessment index page Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When registration_fee_paid=1, the player already paid before. Set both status='completed' and payment_status='paid' at creation so generateCard() works without the cashier needing to process a 0 EGP payment. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When registration_fee_paid=1 on the player, set form_payment_status='paid' at registration creation so determineStep() jumps to photo (step 2) directly. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Move PHP reference to total_fees into a JS variable that's safely set with isset() check, fixing the undefined variable error on the registration list page. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
description → description_ar, add group_name (required non-null column) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Members pay 50 EGP, non-members pay 100 EGP (was flat 100 for all) - If membership_number found in DB, player_type='member' regardless of annual subscription status - Add 'sa_registration_fee' to SUB_SA treasury whitelist so cashier sees it - Add sa_registration_fee to member-not-required whitelist in PaymentRequestService - Add Arabic label for sa_registration_fee type - Wizard view shows dynamic fee from registration data instead of hardcoded 100 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Registration wizard simplified: flat 100 EGP per person (no card/form fees) - Desk flow: enter data → pay → photo → select disciplines → print form - Group assignment removed from registration (done by coaches now) - New Coach Assessment Wizard at /sa/coach-assessment for skill evaluation - New Swimming Coaches section at /sa/swimming/coaches (freelance-focused) - Added assessment columns (skill_level, notes, assessed_at) to sa_group_players - Added selected_disciplines JSON to sa_registrations Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
JS form sends 1-based person_index (child_1, child_2) but PHP used it directly as a 0-based array subscript into personIdMap, causing child_1 to get child_2's ID and child_2 to fall through to name-based resolution (which could fail or duplicate). Convert to 0-based before array lookup. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 06 Aug, 2026 4 commits
-
-
Mahmoud Aglan authored
The registration form fee (استمارة) is a one-time payment per human. When a player who already paid it starts a new registration, the wizard now skips directly to the photo step instead of showing a 0-fee payment. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Add phone_mobile format validation in MemberController::update() (was only validated in store(), allowing invalid data via edit) - Add missing SpouseController::calculateFee() method that the route /api/spouses/calculate-fee pointed to (returned 500) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Reflect changes from display completeness and logic fixes commit. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Death show: display deceased person's actual name (not just membership owner), show original membership creation/activation dates, new member acquisition date, and subscription status after completion. Fix index status labels. - Death subscriptions: dedup-safe createNewSubscriptions prevents double-demand when subscription rows already exist (marks existing pending rows as paid). - Waiver index: add target member column, fix missing status labels (fee_paid/rejected), add date column. Show view: add payment request tracking display. - Transfers: allow males under 25 to be selected for child separation if employed+graduated (previously blocked by both frontend JS and backend age gate). Add marriage date validation to reject dates before membership creation date. - Subscriptions: call refreshForMember on member-subscriptions page load to auto-fill missing subscription rows for active dependents in current FY. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-