- 08 Aug, 2026 9 commits
-
-
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 21 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>
-
Fares authored
For members who received membership via waiver or death transfer, the payment history now shows two separate sections: - "مدفوعات العضوية الحالية" (current membership payments) - "مدفوعات العضوية السابقة (موروثة)" (inherited from previous owner) The split uses ownership_transfer_date (or activated_at as fallback). Also added missing Arabic labels for hourly_booking and early_settlement. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
1. Subscription sync: add refreshForMember() and markCurrentYearPaid() to handle post-transfer subscription creation and payment marking. 2. Event listeners: transfer.completed and death.completed now trigger subscription sync for new members and cleanup for source members. 3. Waiver: stop transferring ALL payments/subscriptions/fines to target. Only pending subscriptions, active installments, and unpaid fines move. Paid history stays with the archived source member. 4. Death: createNewSubscriptions() now marks all rows as 'paid' since the annual fee is collected as part of the death transfer fee. 5. Death dependent: remove pending subscription rows when a spouse/child dies (not the primary member). 6. Members: add ownership_transfer_date column (migration + display) to record when membership ownership was transferred. 7. Archive: group subscriptions by financial year with summary totals. 8. Arabize: archive views (entity_type, snapshot_reason, NULL→فارغ), subscription statuses, and payment type labels. 9. Seasonal: fix duplicate national_id error by checking all members (including archived) during validation. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
The INSERT was using non-existent columns (config_group, label_ar, field_type). The actual table has config_type, group_name, description_ar, is_editable. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Seasonal members don't need the استمارة fee. Set form_fee_paid=true in getSeasonalBill() so the member show page skips the form fee step entirely and goes straight to seasonal fee payment. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Seasonal memberships now require a manually entered temporary membership number (رقم العضوية الموسمية) instead of using the shared auto-increment sequence. The number is validated for uniqueness and assigned to the member record immediately, so the payment guard won't override it with an auto-generated one. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Instead of auto-generating form_number at execution time, require the user to enter it when creating the separation request. Stored in transfer_requests.form_number and used during TransferProcessor execution. Falls back to auto-generation if empty. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
- Remove non-existent facility_unit_id from sa_groups insert in enrollByCoach, add required code column with auto-generated value - Guard schedule copy when no source group exists - Fix old() helper usage for array fields (additional_coaches) by reading directly from session _old_input instead of old() which only returns strings Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Redesign the player assignment page with a 3-step guided workflow (Sport → Program → Trainer) supporting both trainer-based and program-based assignments. Add multi-coach support for groups via sa_group_coaches pivot table. Add per-hour/per-game pricing type to recreational games. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
The medical_grace_deadline column already exists in the live DB from a prior partial run. Converted to a closure-based migration that checks information_schema before altering. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Player Assignment Page (/sa/assignments): - General-purpose assignment flow for all disciplines (not just swimming) - Filter by discipline and unassigned status - Shows player medical status, type, current groups - Assign with capacity check, age validation, force-enroll option - Registered in sidebar menu with sa.player.assign permission Recreational Games (/sa/games): - Full CRUD for games with type/fee/duration/facility config - Game sessions with open/full/in_progress/completed lifecycle - Ticket issuance per session with player name, type, fee tracking - Session detail view with ticket list and payment status - Migration creates sa_games, sa_game_sessions, sa_game_tickets tables - Registered in sidebar with sa.game.view/manage permissions Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
- Medical Level (1-3): added to approval flow, saved to players/sa_players/medical_records, displayed on player detail page with color-coded badge - Medical Grace Period: configurable days (system_config), set on enrollment when medical cert is missing, shown in attendance view, cron auto-suspends expired grace - Booking Postponement: new postpone method with max 3 attempts, change history table, availability check for new slot, UI form on booking detail page - Mirror Recurrence: templates now support daily/weekly/biweekly/monthly/custom patterns, expandTemplate respects recurrence_type, wizard UI updated with pattern selector - Attendance view: grace period deadline shown instead of generic medical warning Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
- CSRF token now uses \App\Core\CSRF::token() to ensure it's always generated, not raw $_SESSION which could be empty - apiPost and loadState now check response.ok before parsing JSON, preventing silent failures when server returns 419/500/HTML - Error messages now include status code or exception details - Added guard for empty SLOTS array (missing operating hours) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 27 Jul, 2026 4 commits
-
-
Fares authored
The zone grid was previously restricted to pool-type facilities only. Now any facility can have a grid configured (rows × cols, max 25 each) via the create/edit forms. Facilities with grid dimensions get the visual grid manager; those without keep the unit-based mirror view. Changes: - Remove facility_type='pool' filter from PoolGridService::getFacility - MirrorController routes by grid dimensions instead of facility type - Facility create/edit forms now include grid rows/cols fields - FacilityController store/update save grid dimensions - Facility model fillable updated with grid columns - Grid size limit increased from 20 to 25 - Facility show page adds "الشبكة" button when grid is configured - MirrorStateService and SlotAvailabilityService check grid dims instead of facility_type for zone booking cross-checks Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
- Player search now shows type (member/non-member), medical status, and serial number in dropdown results for accurate identification - Group player table adds columns for player type and medical status - Pending payment players now show a "الخزينة" button linking to cashier - Enrollment form stays visible when group is full (uses force-enroll) - SearchableSelect prioritizes label field for richer display text Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Display both fee tiers on each group card with the applicable one highlighted based on the player's registration type, preventing pricing confusion. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
The assignment page now shows a dropdown to select which sport's programs/groups to display. Defaults to Swimming but allows switching to any active discipline. Groups are filtered by the selected discipline and show their program names. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-