- 08 Aug, 2026 25 commits
-
-
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>
-
- 05 Aug, 2026 2 commits
-
-
Mahmoud Aglan authored
- Institution validation redirects back to /create instead of /index - Add sport_type field to discipline create/edit forms (was in model but missing from views) - Add schedule copy + time shift UI panels to daily schedule page Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Phase 0: Schema — training attendance, makeup sessions, institutions tables + sport_type on disciplines - Phase 1: Player lifecycle — pause/resume months, medical grace enforcement with auto-suspend cron - Phase 2: Medical grace integration — grace deadline on enrollment, extend grace endpoint - Phase 3: Training attendance — group-session-based system (separate from booking-based sa_attendance) - Phase 4: Make-up sessions — create from absence, schedule, complete, auto-expire cron - Phase 5: Institution management — full CRUD with booking linkage and contract tracking - Phase 6: Subscription renewal — medical verification flag on auto-generated subscriptions - Phase 7: Treasury auto-sync — already existed via SaEventListenerService (verified) - Phase 8: Recreational differentiation — sport_type enum on disciplines (training/recreational) - Phase 9: Dashboard — added medical grace expiry + makeup session alerts - Phase 10: Schedule copy — copy between groups, shift times, program-wide schedule propagation Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 28 Jul, 2026 9 commits
-
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The employees table has no employee_number or employment_status columns. These controllers should join hr_employee_profiles which has those fields. 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
Model::find() returns a Model object which cannot be used as array in views. Switch to selectOne() which returns associative arrays. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Full admin UI to create/edit/view/archive leave types with all rule fields: entitlement, limits, pay percentage, carry-over, accumulation, gender restriction, service requirements, and legal references. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Adds department_type column (idara/qism) to hr_departments. Idaras are top-level administrations; aqsam (sections) belong to an idara via parent_id. Employees are assigned to a qism. Cascading changes across 14 files: - Migration adds department_type with CHECK constraint - Model: allIdaras(), allAqsam(), getAqsamByIdara() helpers - Controller: type-aware CRUD, validation (qism requires parent) - Views: cascading إدارة→قسم dropdowns in employee form, type badges in department list, grouped optgroups in employee filters - Reports: headcount groups by idara - Routes: new /hr/departments/{id}/aqsam-json endpoint - Bootstrap: updated Arabic labels Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
calculation_type lives on hr_salary_components (sc), not hr_employee_salary_details (sd). Also fixed sc.component_type → sc.type to match actual DB schema. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
The config_type column only accepts: string, integer, float, json. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
- Employee profile: workforce type, fingerprint code, education fields, expanded military status (6 values), comprehensive salary display - Department staffing: authorized positions per job title, capacity tracking - Payroll: martyrs fund, stamp duties, external loan deductions (configurable) - Leave: configurable annual days from system_config, unlimited unpaid, breastfeeding hour tolerance integrated into attendance tardiness - Biometric: device management, punch reception API, attendance integration - Insurance Form S2 (wage adjustment notification), contract work receipt - Overtime fix: employee_id → employee_profile_id throughout - Disciplinary: investigation_result field - Loans: financing_company/bank_loan types with external entity fields - Documents: validity_status tracking, new types (work_stub, insurance_cert) - Label changes: الأجر التأميني, الرقم التأميني, الراتب الشامل - All HR permissions seeded to super_admin role - Architecture Map and Dependency Graph updated Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-