- 16 Aug, 2026 2 commits
-
-
Mahmoud Aglan authored
Replaced every emoji in show.php, edit.php, create.php, search.php, changelog.php, and _partials/profile-header.php with proper Lucide SVG icons for a professional, consistent UI appearance. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When a waiver completes, all dependents on the target member should be marked as active since their fees are included in the waiver fee payment. Previously only activated_by_payment_id was set but status remained 'pending_payment', leaving dependents stuck. Also ensures qualification_id is transferred from source to target member. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 12 Aug, 2026 16 commits
-
-
Mahmoud Aglan authored
The qualification (مؤهل) chosen during separation fee calculation is now locked in the form fill step — it cannot be changed. This ensures the new member gets the correct qualification_id, and all dependent fee calculations (children, spouses) use the full price of that qualification. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Dependents added after July 1st already pay their subscription via the addition fee. Instead of skipping them entirely, create the subscription row with status='paid' so they appear in the subscription list correctly. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Children, spouses, and temporary members added on or after July 1st of the financial year already have their annual subscription included in the addition fee. The generator now excludes them from batch renewal generation for that year to avoid double-charging. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When a separating child's wife is foreign (أجنبي), 15% of the full membership value (based on the chosen qualification) is added per foreign spouse to the separation fee total. - Add foreignSpouseCount param to calculateForChildSeparation - Count foreign spouses from dep_spouses nationality field in controller - Add foreign_spouse_fee column to transfer_requests - Display surcharge in transfer show page breakdown Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Validates that the computed effective transfer date for male dependents cannot be earlier than the parent member's membership start date. Female path already had this check; now both paths enforce the rule. 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
- Rebuild board_offers table with unified schema (cash path + installment path in one record) - Add grace period support (first_n_months and full_free_under_n modes) - Add offer snapshot to payment_requests for persistence across offer expiry - Add offer context (board_offer_id, grace_months) to installment_plans - Refactor BoardOfferService with branch-aware offer resolution - Enhance InstallmentCalculator with grace period math - Full admin CRUD (BoardOfferController + views + routes + permissions) - Integrate offer display in member show page payment section - Snapshot offer at payment request creation, use snapshot in plan creation - Fix BillingService to use new BoardOfferService API Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Member header photo: camera icon to upload/change, X to delete - Spouses: hover avatar to upload/delete photo (routes + controller) - Children: hover avatar to upload/delete photo (routes + controller) - Temporary members: hover avatar to upload/delete photo (routes + controller) - All use existing PhotoUploadService with compression + thumbnails - CSS hover reveals action buttons on dependent avatars Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Member header now has a gradient banner with a large circular photo (or initials fallback). Spouses, children, and temporary members show inline 36px avatar circles with gender-colored gradients when no photo is uploaded. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The treasury queue page filtered by payment_type whitelist and didn't include sa_game_ticket, sa_pool_ticket, or pool_reservation — so those payment requests were created but never appeared in the cashier queue. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The issueTicket response was passing the raw Model object to json(), which could fail serialization. Now returns entry_id instead, and wraps recordEntry in try-catch for proper error reporting. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The service desk ticket form allows issuing tickets to walk-in guests without a carnet or membership, but the carnet_guest_entries table had NOT NULL + FK constraints on both columns, causing a 500 error. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The PoolReservationService already called PaymentRequestService::createRequest() but with member_id=0 and payment_type='pool_reservation' — which was silently rejected because 'pool_reservation' wasn't in the non-member whitelist. - Added 'pool_reservation' to PaymentRequestService whitelist - Added payment type label (حجز حارة سباحة) - Added payment completion handler → marks reservation as paid - Added void handler → reverts reservation to pending Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Game tickets now create payment requests (sa_game_ticket type) sent to the cashier sub-queue, matching pool ticket and booking patterns - Added session lifecycle actions: start, complete, cancel with UI buttons - Fixed session status bug: allow issuing tickets during 'in_progress' sessions - Fixed GuestEntryService crash when no carnet exists (skip UPDATE on id=0) - Added payment completion/void handlers for game and pool tickets - Extended PaymentRequestService whitelist for sa_game_ticket/sa_pool_ticket - Added comprehensive tutorial sections 9-14 covering entertainment workflows Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The ticket form and lookup in service-desk sent '_token' but the CSRF middleware expects '_csrf_token'. This caused HTTP 419 on every ticket issuance attempt. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Critical fixes: - submitFormPayment() now checks sa_players.registration_fee_paid as a safety net before creating any payment request - startRegistration() member_id fallback only used when NID matches the member's actual national_id (prevents NID-swap fee bypass) - lookupPlayer() validates NID-to-member consistency before proceeding - Existing registration lookup now includes 'pending_payment' status - Frontend clears membership_number when NID is manually changed after auto-fill Feature: - Player profile page now shows "Print Form" and "Generate Card" buttons for completing registration steps outside the wizard Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 11 Aug, 2026 12 commits
-
-
Mahmoud Aglan authored
- Convert migrations 103_007 and 103_008 to closures that check column existence before ALTER TABLE (fixes boot failure when columns were already added manually) - Add docs/tutorials/discounts-and-offers-guide.md Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Add file upload field on violation creation (image/PDF/doc, max 5MB) - Store proof_file path in violations table (new column) - Show proof file link (
📎 ) in violations index table - Auto-send monetary fines to cashier queue on imposition - Add manual "طابور الدفع" button on fines index for unpaid fines - Add sendToQueue controller method + route Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The base Model::create() auto-appends created_by when timestamps are enabled, but workflow_instances and workflow_transition_log were missing this column — causing PDOException on fine imposition. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Add qualification dropdown to first screen of child separation — the fee is a percentage of new membership value which varies by qualification - Pass selected qualification_code to SeparationFeeCalculator (was null) - Add /api/members/check-nid endpoint for real-time NID conflict detection - Add client-side NID conflict check on both form_fill and create pages - Block submission when active member has same NID (show clear error) - Warn (orange) when potential/inactive member exists (will auto-archive) - Server-side validation: reject if active NID conflict in store/saveFillForm - Validate qualification_code required for child_separation in store() - Add phone format validation on form_fill submit Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Transfer #14 failed because the national_id already existed on a potential (never-activated) member record. Now archives any conflicting potential/inactive/pending member with the same national_id before inserting the new active member. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When a member dies in the same financial year they already have subscriptions for, don't charge the annual subscription again in the death fee — the man died before using it. Only earlier years' overdue subscriptions must be settled first. Changes: - calculateFamilyAnnualSub returns 0 if current FY member subscription already exists - createNewSubscriptions transfers existing FY subscriptions from deceased to new member instead of creating duplicate paid rows - Overdue check on create page excludes current FY (only blocks for previous years) - Views show "معفى — السنة المالية الحالية مغطاة" when current FY is covered Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Child/spouse death now auto-completes on creation (no manual "complete" click needed), which immediately archives the deceased and deletes their pending/overdue subscription rows - Child separation (TransferProcessor) now deletes the separated child's unpaid subscription rows from the parent's membership when the transfer completes - Spouse separation also removes their subscription rows Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Separation now follows: create → board approval → cashier payment → fill form → complete. After cashier confirms payment, status moves to pending_form_fill. A new form page collects personal data (name, NID, DOB, contact, address, qualification) before executing the transfer. TransferProcessor uses form_data from notes to create the new member record. 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
Children who were separated (فصل) or deceased now remain visible on the parent member's profile instead of disappearing. They appear greyed out with status labels (مفصول / متوفي) and for separated children, a link to their new membership profile with the membership number. The family tree count distinguishes active vs inactive children. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
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 4 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>
-