- 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 5 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>
-
Fares authored
1. searchable-select.js: mouseover was calling renderList() which replaced innerHTML and destroyed the click target DOM node, making options unclickable. Now mouseover only toggles inline styles without re-rendering. 2. ProgramController: auto-creates a default group (code-G1) when a new program is created, using the first available coach for that discipline. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 26 Jul, 2026 5 commits
-
-
Fares authored
The medical board page reads from player_medical_records table. Without this insert, uploaded certificates would not appear in /medical-board for approval, and the player status would stay 'pending' forever. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
- Membership number field with live search that auto-fills all player data - National ID field auto-extracts DOB, gender, and age (Egyptian 14-digit NID parsing) - NID also checks membership status automatically - Added date_of_birth, gender, age, and address fields - Matches the UX pattern of the existing SA registration wizard Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Adds /sa/swimming/* routes with a swimming-specific dashboard, player registration wizard (with mandatory medical certificate upload), and group assignment wizard that sends fees to the SA treasury. Players are stored in existing sa_players table and reuse EnrollmentService. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 23 Jul, 2026 3 commits
-
-
Fares authored
- Fix critical SQL error: ArchiveService queried installment_cheques ORDER BY due_date but actual column is cheque_date (broke auto-completion flow) - Include development_fee in debt table calculation (was missing 35 EGP per sub) - Add form_number field to waiver requests (migration + create/show views) - Block children over 21 from being transferred as children (must be temporary) - Add board approval and age checks to auto-complete status indicator - Update architecture map to reflect that dependents ARE transferred Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Retroactive fix for child that was separated but not archived from the parent's family tree due to the old code not setting is_archived=1. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
When a child separation completes, the child record now gets is_archived=1 so it no longer appears in the parent's family tree. Previously only status was changed to 'separated' but the record remained visible. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 22 Jul, 2026 6 commits
-
-
Fares authored
Removed membership_type gates that restricted the family tree section, add-family buttons, and related messaging to only working/foreign members. All types now see their dependents with payment status on the profile page. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Inline family member forms now collect all fields matching standalone creation forms (NID with auto-parsing, passport, DOB, gender, nationality, qualification, contact info, etc.) instead of just names. Also adds temporary member inline creation. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
The seasonal membership form now allows adding spouses and children directly during registration (not just selecting pre-existing ones). New family members are created as actual spouse/child records and included in the pricing calculation. The price preview API also reflects inline additions in real-time. All discounts work correctly with inline members: - Parent + child <15: 500 EGP off - Husband + wife: 1000 EGP off - Family of 5+: 1000 EGP off - No qualification: 10% off - VAT applied on all amounts Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Sports, seasonal, and honorary members were blocked from adding spouses, children, and temporary members because allows_dependents was set to false. All membership types now allow dependents. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Sports membership fee is 50% of the membership price tier which is determined by the qualification. Added a qualification dropdown that appears when membership type is 'sports', with server-side validation requiring it. The qualification_id is saved on the member record so the billing and sports registration can correctly calculate the fee. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Fares authored
Three fixes applied across all non-working membership types: 1. Sports registration now calculates 50% fee and sends payment request to treasury automatically (like Seasonal already did). Also fixed billing fallback to find branch pricing without qualification_id. 2. Type-specific CTA now checks if registration record already exists in the DB (foreign_member_details, sports_members, etc.) — won't reappear after filling the form regardless of billing state. 3. Added duplicate-registration guards to all four type controllers (foreign, sports, seasonal, honorary) so users can't accidentally submit the registration form twice. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-