Commit a4373d67 authored by Mahmoud Aglan's avatar Mahmoud Aglan

cool

parent 0b3ff07b
<?php
declare(strict_types=1);
use App\Core\Database;
return function (Database $db): void {
$ts = date('Y-m-d H:i:s');
$today = date('Y-m-d');
// ══════════════════════════════════════════════════════════════════════════
// 1. DISCIPLINES — 10 sports (SWIMMING already exists from Phase_70_001)
// ══════════════════════════════════════════════════════════════════════════
$disciplines = [
['code' => 'FOOTBALL', 'name_ar' => 'كرة القدم', 'name_en' => 'Football', 'category' => 'team', 'icon' => 'football', 'desc' => 'كرة القدم بأنواعها — خماسي وأحد عشر', 'sort' => 2],
['code' => 'SWIMMING', 'name_ar' => 'السباحة', 'name_en' => 'Swimming', 'category' => 'aquatic', 'icon' => 'waves', 'desc' => 'رياضة السباحة بأنواعها — حرة، ظهر، صدر، فراشة', 'sort' => 1],
['code' => 'TENNIS', 'name_ar' => 'التنس الأرضي', 'name_en' => 'Tennis', 'category' => 'racket', 'icon' => 'circle', 'desc' => 'التنس الأرضي على ملاعب كلاي', 'sort' => 3],
['code' => 'PADEL', 'name_ar' => 'البادل تنس', 'name_en' => 'Padel', 'category' => 'racket', 'icon' => 'square', 'desc' => 'البادل تنس — رياضة المضرب الحديثة', 'sort' => 4],
['code' => 'SQUASH', 'name_ar' => 'الاسكواش', 'name_en' => 'Squash', 'category' => 'racket', 'icon' => 'box', 'desc' => 'الاسكواش — رياضة داخلية سريعة', 'sort' => 5],
['code' => 'TABLE_TENNIS', 'name_ar' => 'تنس الطاولة', 'name_en' => 'Table Tennis', 'category' => 'racket', 'icon' => 'minus-square', 'desc' => 'تنس الطاولة — بينج بونج', 'sort' => 6],
['code' => 'BOWLING', 'name_ar' => 'البولينج', 'name_en' => 'Bowling', 'category' => 'leisure', 'icon' => 'target', 'desc' => 'البولينج — رياضة ترفيهية', 'sort' => 7],
['code' => 'GYMNASTICS', 'name_ar' => 'الجمباز', 'name_en' => 'Gymnastics', 'category' => 'individual', 'icon' => 'move', 'desc' => 'الجمباز الفني والإيقاعي', 'sort' => 8],
['code' => 'KARATE', 'name_ar' => 'الكاراتيه', 'name_en' => 'Karate', 'category' => 'combat', 'icon' => 'shield', 'desc' => 'الكاراتيه — فنون قتالية يابانية', 'sort' => 9],
['code' => 'CYCLING', 'name_ar' => 'الدراجات والتزحلق', 'name_en' => 'Cycling & Skating', 'category' => 'leisure', 'icon' => 'bike', 'desc' => 'الدراجات والتزحلق على الجليد', 'sort' => 10],
];
$discIds = [];
foreach ($disciplines as $d) {
$existing = $db->selectOne("SELECT id FROM sa_disciplines WHERE code = ?", [$d['code']]);
if (!$existing) {
$db->insert('sa_disciplines', [
'code' => $d['code'],
'name_ar' => $d['name_ar'],
'name_en' => $d['name_en'],
'category' => $d['category'],
'icon' => $d['icon'],
'description_ar' => $d['desc'],
'config_json' => json_encode([
'skill_levels' => [
['code' => 'beginner', 'label_ar' => 'مبتدئ'],
['code' => 'intermediate', 'label_ar' => 'متوسط'],
['code' => 'advanced', 'label_ar' => 'متقدم'],
],
], JSON_UNESCAPED_UNICODE),
'sort_order' => $d['sort'],
'is_active' => 1,
'is_archived' => 0,
'created_at' => $ts,
'updated_at' => $ts,
]);
$discIds[$d['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$discIds[$d['code']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 2. FACILITIES — 14 facilities (POOL-MAIN already exists from Phase_70_001)
// ══════════════════════════════════════════════════════════════════════════
$opHours = json_encode(['start' => '09:00', 'end' => '23:00', 'slot_minutes' => 60], JSON_UNESCAPED_UNICODE);
$facilities = [
['code' => 'POOL-MAIN', 'name_ar' => 'حمام السباحة الأوليمبي', 'name_en' => 'Olympic Swimming Pool', 'type' => 'pool', 'disc' => 'SWIMMING', 'location' => 'المبنى الرياضي — الطابق الأرضي', 'grid_rows' => 4, 'grid_cols' => 6],
['code' => 'FIELD-MAIN', 'name_ar' => 'ملعب كرة القدم الطبيعي', 'name_en' => 'Main Football Pitch', 'type' => 'pitch', 'disc' => 'FOOTBALL', 'location' => 'الملاعب الخارجية — شمال النادي', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'FIELD-5ASIDE', 'name_ar' => 'ملعب كرة القدم الخماسي', 'name_en' => '5-a-Side Football Pitch', 'type' => 'pitch', 'disc' => 'FOOTBALL', 'location' => 'الملاعب الخارجية — بجوار الملعب الرئيسي', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-TENNIS1', 'name_ar' => 'ملعب التنس الأرضي 1', 'name_en' => 'Tennis Court 1', 'type' => 'court', 'disc' => 'TENNIS', 'location' => 'منطقة ملاعب المضرب — ملعب 1', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-TENNIS2', 'name_ar' => 'ملعب التنس الأرضي 2', 'name_en' => 'Tennis Court 2', 'type' => 'court', 'disc' => 'TENNIS', 'location' => 'منطقة ملاعب المضرب — ملعب 2', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-PADEL1', 'name_ar' => 'ملعب البادل 1', 'name_en' => 'Padel Court 1', 'type' => 'court', 'disc' => 'PADEL', 'location' => 'منطقة ملاعب المضرب — بادل 1', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-PADEL2', 'name_ar' => 'ملعب البادل 2', 'name_en' => 'Padel Court 2', 'type' => 'court', 'disc' => 'PADEL', 'location' => 'منطقة ملاعب المضرب — بادل 2', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-SQUASH1', 'name_ar' => 'ملعب الاسكواش 1', 'name_en' => 'Squash Court 1', 'type' => 'court', 'disc' => 'SQUASH', 'location' => 'المبنى الرياضي — الطابق الأول — اسكواش 1', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-SQUASH2', 'name_ar' => 'ملعب الاسكواش 2', 'name_en' => 'Squash Court 2', 'type' => 'court', 'disc' => 'SQUASH', 'location' => 'المبنى الرياضي — الطابق الأول — اسكواش 2', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'COURT-MULTI', 'name_ar' => 'الملعب المتعدد', 'name_en' => 'Multi-Purpose Court', 'type' => 'court', 'disc' => 'TABLE_TENNIS', 'location' => 'المبنى الرياضي — الطابق الأرضي — الصالة المتعددة', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'HALL-BOWLING', 'name_ar' => 'صالة البولينج', 'name_en' => 'Bowling Hall', 'type' => 'gym', 'disc' => 'BOWLING', 'location' => 'المبنى الترفيهي — الطابق الأرضي', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'HALL-GYM', 'name_ar' => 'صالة الجمنازيوم', 'name_en' => 'Gymnasium Hall', 'type' => 'gym', 'disc' => 'GYMNASTICS', 'location' => 'المبنى الرياضي — الطابق الثاني', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'TRACK-RUN', 'name_ar' => 'تراك الجري', 'name_en' => 'Running Track', 'type' => 'track', 'disc' => 'CYCLING', 'location' => 'المنطقة الخارجية — محيط الملاعب', 'grid_rows' => null, 'grid_cols' => null],
['code' => 'TRACK-CYCLE', 'name_ar' => 'تراك الدراجات والتزحلق', 'name_en' => 'Cycling & Skating Track', 'type' => 'track', 'disc' => 'CYCLING', 'location' => 'المنطقة الخارجية — غرب النادي', 'grid_rows' => null, 'grid_cols' => null],
];
$facIds = [];
foreach ($facilities as $f) {
$existing = $db->selectOne("SELECT id FROM sa_facilities WHERE code = ?", [$f['code']]);
if (!$existing) {
$data = [
'code' => $f['code'],
'name_ar' => $f['name_ar'],
'name_en' => $f['name_en'],
'facility_type' => $f['type'],
'discipline_id' => $discIds[$f['disc']],
'location_description' => $f['location'],
'operating_hours_json' => $opHours,
'pool_grid_rows' => $f['grid_rows'],
'pool_grid_cols' => $f['grid_cols'],
'is_active' => 1,
'is_archived' => 0,
'branch_id' => 1,
'created_at' => $ts,
'updated_at' => $ts,
];
$db->insert('sa_facilities', $data);
$facIds[$f['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$facIds[$f['code']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 3. FACILITY UNITS — one or more bookable units per facility
// (POOL-MAIN lanes already seeded in Phase_70_001 — skip those)
// ══════════════════════════════════════════════════════════════════════════
$units = [
// Football main pitch — 1 unit (full pitch)
['fac' => 'FIELD-MAIN', 'code' => 'PITCH-MAIN', 'name_ar' => 'الملعب الطبيعي كامل', 'name_en' => 'Full Pitch', 'type' => 'pitch', 'mode' => 'exclusive', 'cap' => 22, 'sort' => 1, 'dim' => ['length' => 100, 'width' => 68], 'cfg' => ['surface' => 'natural_grass']],
// Football 5-a-side
['fac' => 'FIELD-5ASIDE', 'code' => 'PITCH-5A', 'name_ar' => 'ملعب خماسي', 'name_en' => '5-a-Side Pitch', 'type' => 'pitch', 'mode' => 'exclusive', 'cap' => 10, 'sort' => 1, 'dim' => ['length' => 40, 'width' => 20], 'cfg' => ['surface' => 'artificial_turf']],
// Tennis courts
['fac' => 'COURT-TENNIS1', 'code' => 'TCOURT-1', 'name_ar' => 'ملعب تنس 1', 'name_en' => 'Tennis Court 1', 'type' => 'court', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 1, 'dim' => ['length' => 23.77, 'width' => 10.97], 'cfg' => ['surface' => 'clay']],
['fac' => 'COURT-TENNIS2', 'code' => 'TCOURT-2', 'name_ar' => 'ملعب تنس 2', 'name_en' => 'Tennis Court 2', 'type' => 'court', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 1, 'dim' => ['length' => 23.77, 'width' => 10.97], 'cfg' => ['surface' => 'clay']],
// Padel courts
['fac' => 'COURT-PADEL1', 'code' => 'PCOURT-1', 'name_ar' => 'ملعب بادل 1', 'name_en' => 'Padel Court 1', 'type' => 'court', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 1, 'dim' => ['length' => 20, 'width' => 10], 'cfg' => ['surface' => 'artificial_turf', 'walls' => 'glass']],
['fac' => 'COURT-PADEL2', 'code' => 'PCOURT-2', 'name_ar' => 'ملعب بادل 2', 'name_en' => 'Padel Court 2', 'type' => 'court', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 1, 'dim' => ['length' => 20, 'width' => 10], 'cfg' => ['surface' => 'artificial_turf', 'walls' => 'glass']],
// Squash courts
['fac' => 'COURT-SQUASH1', 'code' => 'SQCOURT-1', 'name_ar' => 'ملعب اسكواش 1', 'name_en' => 'Squash Court 1', 'type' => 'court', 'mode' => 'exclusive', 'cap' => 2, 'sort' => 1, 'dim' => ['length' => 9.75, 'width' => 6.4], 'cfg' => ['surface' => 'hardwood']],
['fac' => 'COURT-SQUASH2', 'code' => 'SQCOURT-2', 'name_ar' => 'ملعب اسكواش 2', 'name_en' => 'Squash Court 2', 'type' => 'court', 'mode' => 'exclusive', 'cap' => 2, 'sort' => 1, 'dim' => ['length' => 9.75, 'width' => 6.4], 'cfg' => ['surface' => 'hardwood']],
// Multi-purpose — 4 table tennis tables
['fac' => 'COURT-MULTI', 'code' => 'TT-TABLE-1', 'name_ar' => 'طاولة تنس 1', 'name_en' => 'Table Tennis 1', 'type' => 'table', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 1, 'dim' => ['length' => 2.74, 'width' => 1.525], 'cfg' => ['type' => 'competition']],
['fac' => 'COURT-MULTI', 'code' => 'TT-TABLE-2', 'name_ar' => 'طاولة تنس 2', 'name_en' => 'Table Tennis 2', 'type' => 'table', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 2, 'dim' => ['length' => 2.74, 'width' => 1.525], 'cfg' => ['type' => 'competition']],
['fac' => 'COURT-MULTI', 'code' => 'TT-TABLE-3', 'name_ar' => 'طاولة تنس 3', 'name_en' => 'Table Tennis 3', 'type' => 'table', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 3, 'dim' => ['length' => 2.74, 'width' => 1.525], 'cfg' => ['type' => 'practice']],
['fac' => 'COURT-MULTI', 'code' => 'TT-TABLE-4', 'name_ar' => 'طاولة تنس 4', 'name_en' => 'Table Tennis 4', 'type' => 'table', 'mode' => 'exclusive', 'cap' => 4, 'sort' => 4, 'dim' => ['length' => 2.74, 'width' => 1.525], 'cfg' => ['type' => 'practice']],
// Bowling — 6 lanes
['fac' => 'HALL-BOWLING', 'code' => 'BOWL-LANE-1', 'name_ar' => 'حارة بولينج 1', 'name_en' => 'Bowling Lane 1', 'type' => 'lane', 'mode' => 'exclusive', 'cap' => 6, 'sort' => 1, 'dim' => ['length' => 18.29], 'cfg' => ['auto_scoring' => true]],
['fac' => 'HALL-BOWLING', 'code' => 'BOWL-LANE-2', 'name_ar' => 'حارة بولينج 2', 'name_en' => 'Bowling Lane 2', 'type' => 'lane', 'mode' => 'exclusive', 'cap' => 6, 'sort' => 2, 'dim' => ['length' => 18.29], 'cfg' => ['auto_scoring' => true]],
['fac' => 'HALL-BOWLING', 'code' => 'BOWL-LANE-3', 'name_ar' => 'حارة بولينج 3', 'name_en' => 'Bowling Lane 3', 'type' => 'lane', 'mode' => 'exclusive', 'cap' => 6, 'sort' => 3, 'dim' => ['length' => 18.29], 'cfg' => ['auto_scoring' => true]],
['fac' => 'HALL-BOWLING', 'code' => 'BOWL-LANE-4', 'name_ar' => 'حارة بولينج 4', 'name_en' => 'Bowling Lane 4', 'type' => 'lane', 'mode' => 'exclusive', 'cap' => 6, 'sort' => 4, 'dim' => ['length' => 18.29], 'cfg' => ['auto_scoring' => true]],
// Gymnasium — full hall
['fac' => 'HALL-GYM', 'code' => 'GYM-HALL', 'name_ar' => 'صالة الجمباز', 'name_en' => 'Gymnastics Hall', 'type' => 'hall', 'mode' => 'shared', 'cap' => 30, 'sort' => 1, 'dim' => ['length' => 40, 'width' => 25], 'cfg' => ['equipment' => ['vault', 'bars', 'beam', 'floor']]],
// Running track
['fac' => 'TRACK-RUN', 'code' => 'TRACK-RUN-1', 'name_ar' => 'تراك الجري', 'name_en' => 'Running Track', 'type' => 'track', 'mode' => 'shared', 'cap' => 20, 'sort' => 1, 'dim' => ['length' => 400], 'cfg' => ['surface' => 'rubberized', 'lanes' => 6]],
// Cycling/skating track
['fac' => 'TRACK-CYCLE', 'code' => 'TRACK-CYCLE-1', 'name_ar' => 'تراك الدراجات', 'name_en' => 'Cycling Track', 'type' => 'track', 'mode' => 'shared', 'cap' => 15, 'sort' => 1, 'dim' => ['length' => 500], 'cfg' => ['surface' => 'asphalt']],
];
$unitIds = [];
foreach ($units as $u) {
$facId = $facIds[$u['fac']];
$existing = $db->selectOne(
"SELECT id FROM sa_facility_units WHERE facility_id = ? AND code = ?",
[$facId, $u['code']]
);
if (!$existing) {
$db->insert('sa_facility_units', [
'facility_id' => $facId,
'code' => $u['code'],
'name_ar' => $u['name_ar'],
'name_en' => $u['name_en'],
'unit_type' => $u['type'],
'booking_mode' => $u['mode'],
'max_capacity' => $u['cap'],
'sort_order' => $u['sort'],
'dimensions_json' => json_encode($u['dim'], JSON_UNESCAPED_UNICODE),
'config_json' => json_encode($u['cfg'], JSON_UNESCAPED_UNICODE),
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
]);
$unitIds[$u['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$unitIds[$u['code']] = (int) $existing['id'];
}
}
// Also grab pool lane IDs from Phase_70_001
$poolLanes = $db->select("SELECT id, code FROM sa_facility_units WHERE facility_id = ? AND code LIKE 'LANE-%'", [$facIds['POOL-MAIN']]);
foreach ($poolLanes as $lane) {
$unitIds[$lane['code']] = (int) $lane['id'];
}
// ══════════════════════════════════════════════════════════════════════════
// 4. TIME BRACKETS — Morning (off-peak), Evening (peak), Weekend per facility
// (POOL-MAIN already has brackets from Phase_70_001 — skip it)
// ══════════════════════════════════════════════════════════════════════════
$bracketDefs = [
['name_ar' => 'صباحي', 'name_en' => 'Morning', 'type' => 'off_peak', 'start' => '09:00:00', 'end' => '17:00:00', 'days' => [0,1,2,3,4,5,6]],
['name_ar' => 'مسائي', 'name_en' => 'Evening', 'type' => 'peak', 'start' => '17:00:00', 'end' => '23:00:00', 'days' => [0,1,2,3,4,5,6]],
['name_ar' => 'عطلة نهاية الأسبوع', 'name_en' => 'Weekend', 'type' => 'weekend', 'start' => '09:00:00', 'end' => '23:00:00', 'days' => [5,6]],
];
$bracketIds = []; // keyed by "FAC_CODE:bracket_name_ar"
$facilitiesToBracket = ['FIELD-MAIN', 'FIELD-5ASIDE', 'COURT-TENNIS1', 'COURT-TENNIS2', 'COURT-PADEL1', 'COURT-PADEL2', 'COURT-SQUASH1', 'COURT-SQUASH2', 'COURT-MULTI', 'HALL-BOWLING', 'HALL-GYM', 'TRACK-RUN', 'TRACK-CYCLE'];
foreach ($facilitiesToBracket as $facCode) {
$facId = $facIds[$facCode];
foreach ($bracketDefs as $b) {
$key = $facCode . ':' . $b['name_ar'];
$existing = $db->selectOne(
"SELECT id FROM sa_time_brackets WHERE facility_id = ? AND name_ar = ? AND bracket_type = ?",
[$facId, $b['name_ar'], $b['type']]
);
if (!$existing) {
$db->insert('sa_time_brackets', [
'facility_id' => $facId,
'name_ar' => $b['name_ar'],
'name_en' => $b['name_en'],
'bracket_type' => $b['type'],
'start_time' => $b['start'],
'end_time' => $b['end'],
'days_of_week_json' => json_encode($b['days']),
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
]);
$bracketIds[$key] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$bracketIds[$key] = (int) $existing['id'];
}
}
}
// Also get existing pool brackets
$poolBrackets = $db->select("SELECT id, name_ar FROM sa_time_brackets WHERE facility_id = ?", [$facIds['POOL-MAIN']]);
foreach ($poolBrackets as $pb) {
$bracketIds['POOL-MAIN:' . $pb['name_ar']] = (int) $pb['id'];
}
// ══════════════════════════════════════════════════════════════════════════
// 5. PRICING RULES — from the official pricing document
// ══════════════════════════════════════════════════════════════════════════
// Format: [unit_code, fac_code_for_bracket, morning_member, morning_nonmember, evening_member, evening_nonmember]
$pricingData = [
// Football natural
['PITCH-MAIN', 'FIELD-MAIN', 300, 500, 500, 800],
// Football 5-a-side
['PITCH-5A', 'FIELD-5ASIDE', 150, 300, 200, 400],
// Tennis courts
['TCOURT-1', 'COURT-TENNIS1', 75, 100, 100, 150],
['TCOURT-2', 'COURT-TENNIS2', 75, 100, 100, 150],
// Padel (no tools — base price)
['PCOURT-1', 'COURT-PADEL1', 100, 200, 150, 300],
['PCOURT-2', 'COURT-PADEL2', 100, 200, 150, 300],
// Squash
['SQCOURT-1', 'COURT-SQUASH1', 75, 125, 75, 125],
['SQCOURT-2', 'COURT-SQUASH2', 75, 125, 75, 125],
// Table tennis
['TT-TABLE-1', 'COURT-MULTI', 50, 60, 50, 60],
['TT-TABLE-2', 'COURT-MULTI', 50, 60, 50, 60],
['TT-TABLE-3', 'COURT-MULTI', 50, 60, 50, 60],
['TT-TABLE-4', 'COURT-MULTI', 50, 60, 50, 60],
// Bowling (per game, treating as per hour)
['BOWL-LANE-1', 'HALL-BOWLING', 30, 60, 30, 60],
['BOWL-LANE-2', 'HALL-BOWLING', 30, 60, 30, 60],
['BOWL-LANE-3', 'HALL-BOWLING', 30, 60, 30, 60],
['BOWL-LANE-4', 'HALL-BOWLING', 30, 60, 30, 60],
// Gymnasium
['GYM-HALL', 'HALL-GYM', 300, 500, 300, 500],
// Running track
['TRACK-RUN-1', 'TRACK-RUN', 200, 300, 200, 300],
// Cycling track
['TRACK-CYCLE-1', 'TRACK-CYCLE', 100, 200, 100, 200],
];
foreach ($pricingData as $pr) {
[$unitCode, $facForBracket, $mornM, $mornNM, $eveM, $eveNM] = $pr;
$unitId = $unitIds[$unitCode] ?? null;
if (!$unitId) continue;
// Morning (off_peak) pricing
$morningBracket = $bracketIds[$facForBracket . ':صباحي'] ?? null;
if ($morningBracket) {
$existing = $db->selectOne(
"SELECT id FROM sa_pricing_rules WHERE facility_unit_id = ? AND time_bracket_id = ? AND effective_from = ?",
[$unitId, $morningBracket, '2025-01-01']
);
if (!$existing) {
$db->insert('sa_pricing_rules', [
'facility_unit_id' => $unitId,
'time_bracket_id' => $morningBracket,
'group_size_min' => 1,
'group_size_max' => 99,
'price_per_person_member' => $mornM,
'price_per_person_nonmember' => $mornNM,
'effective_from' => '2025-01-01',
'effective_to' => null,
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'created_by' => 1,
]);
}
}
// Evening (peak) pricing
$eveningBracket = $bracketIds[$facForBracket . ':مسائي'] ?? null;
if ($eveningBracket) {
$existing = $db->selectOne(
"SELECT id FROM sa_pricing_rules WHERE facility_unit_id = ? AND time_bracket_id = ? AND effective_from = ?",
[$unitId, $eveningBracket, '2025-01-01']
);
if (!$existing) {
$db->insert('sa_pricing_rules', [
'facility_unit_id' => $unitId,
'time_bracket_id' => $eveningBracket,
'group_size_min' => 1,
'group_size_max' => 99,
'price_per_person_member' => $eveM,
'price_per_person_nonmember' => $eveNM,
'effective_from' => '2025-01-01',
'effective_to' => null,
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'created_by' => 1,
]);
}
}
// Weekend pricing (use evening rates)
$weekendBracket = $bracketIds[$facForBracket . ':عطلة نهاية الأسبوع'] ?? null;
if ($weekendBracket) {
$existing = $db->selectOne(
"SELECT id FROM sa_pricing_rules WHERE facility_unit_id = ? AND time_bracket_id = ? AND effective_from = ?",
[$unitId, $weekendBracket, '2025-01-01']
);
if (!$existing) {
$db->insert('sa_pricing_rules', [
'facility_unit_id' => $unitId,
'time_bracket_id' => $weekendBracket,
'group_size_min' => 1,
'group_size_max' => 99,
'price_per_person_member' => $eveM,
'price_per_person_nonmember' => $eveNM,
'effective_from' => '2025-01-01',
'effective_to' => null,
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'created_by' => 1,
]);
}
}
}
// Also add pool lane pricing (morning/evening from document: 200/300 morning, 300/400 evening per hour per lane)
$poolMorningBracket = null;
$poolEveningBracket = null;
// Find off-peak and peak for the pool
$poolBracketsAll = $db->select("SELECT id, bracket_type FROM sa_time_brackets WHERE facility_id = ?", [$facIds['POOL-MAIN']]);
foreach ($poolBracketsAll as $pb) {
if ($pb['bracket_type'] === 'off_peak' && !$poolMorningBracket) $poolMorningBracket = (int) $pb['id'];
if ($pb['bracket_type'] === 'peak' && !$poolEveningBracket) $poolEveningBracket = (int) $pb['id'];
}
// Pool lane pricing (only if not already set by Phase_70_001 — check first)
for ($i = 1; $i <= 8; $i++) {
$laneCode = 'LANE-' . $i;
$laneId = $unitIds[$laneCode] ?? null;
if (!$laneId) continue;
if ($poolMorningBracket) {
$existing = $db->selectOne(
"SELECT id FROM sa_pricing_rules WHERE facility_unit_id = ? AND time_bracket_id = ? AND group_size_min = 1 AND group_size_max = 99",
[$laneId, $poolMorningBracket]
);
// Only insert simplified pricing if no existing rule with min=1,max=99
// Phase_70_001 uses different group ranges; skip if any rules exist
$anyExisting = $db->selectOne(
"SELECT id FROM sa_pricing_rules WHERE facility_unit_id = ? AND time_bracket_id = ?",
[$laneId, $poolMorningBracket]
);
if (!$anyExisting) {
$db->insert('sa_pricing_rules', [
'facility_unit_id' => $laneId,
'time_bracket_id' => $poolMorningBracket,
'group_size_min' => 1,
'group_size_max' => 99,
'price_per_person_member' => 200,
'price_per_person_nonmember' => 300,
'effective_from' => '2025-01-01',
'effective_to' => null,
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'created_by' => 1,
]);
}
}
if ($poolEveningBracket) {
$anyExisting = $db->selectOne(
"SELECT id FROM sa_pricing_rules WHERE facility_unit_id = ? AND time_bracket_id = ?",
[$laneId, $poolEveningBracket]
);
if (!$anyExisting) {
$db->insert('sa_pricing_rules', [
'facility_unit_id' => $laneId,
'time_bracket_id' => $poolEveningBracket,
'group_size_min' => 1,
'group_size_max' => 99,
'price_per_person_member' => 300,
'price_per_person_nonmember' => 400,
'effective_from' => '2025-01-01',
'effective_to' => null,
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'created_by' => 1,
]);
}
}
}
// ══════════════════════════════════════════════════════════════════════════
// 6. COACHES — 8 coaches (some already exist from Phase_70_001, skip those)
// ══════════════════════════════════════════════════════════════════════════
$coaches = [
['code' => 'COACH-001', 'name_ar' => 'أحمد محمد حسن', 'name_en' => 'Ahmed Mohamed Hassan', 'nid' => '28501011234567', 'phone' => '01001234501', 'email' => 'ahmed.swim@club.com', 'dob' => '1985-01-01', 'gender' => 'male', 'type' => 'staff', 'payment' => 'per_session', 'hourly' => 200, 'session' => 200, 'monthly' => null, 'max_groups' => 6, 'certs' => ['شهادة تدريب سباحة دولية', 'إنقاذ مائي']],
['code' => 'COACH-002', 'name_ar' => 'محمد عبدالله', 'name_en' => 'Mohamed Abdullah', 'nid' => '28703151234567', 'phone' => '01001234505', 'email' => 'mohamed.foot@club.com', 'dob' => '1987-03-15', 'gender' => 'male', 'type' => 'staff', 'payment' => 'per_session', 'hourly' => 250, 'session' => 250, 'monthly' => null, 'max_groups' => 5, 'certs' => ['رخصة تدريب C من الاتحاد المصري', 'دبلوم التربية الرياضية']],
['code' => 'COACH-003', 'name_ar' => 'سارة أحمد', 'name_en' => 'Sara Ahmed', 'nid' => '29005201234567', 'phone' => '01001234506', 'email' => 'sara.gym@club.com', 'dob' => '1990-05-20', 'gender' => 'female', 'type' => 'staff', 'payment' => 'monthly_fixed', 'hourly' => null, 'session' => null, 'monthly' => 8000, 'max_groups' => 4, 'certs' => ['بكالوريوس تربية رياضية — جمباز', 'حكم دولي جمباز']],
['code' => 'COACH-004', 'name_ar' => 'خالد يوسف', 'name_en' => 'Khaled Youssef', 'nid' => '28808101234567', 'phone' => '01001234507', 'email' => 'khaled.racket@club.com', 'dob' => '1988-08-10', 'gender' => 'male', 'type' => 'contract', 'payment' => 'per_session', 'hourly' => 180, 'session' => 180, 'monthly' => null, 'max_groups' => 6, 'certs' => ['مدرب تنس معتمد ITF', 'مدرب بادل معتمد']],
['code' => 'COACH-005', 'name_ar' => 'أميرة فتحي', 'name_en' => 'Amira Fathy', 'nid' => '29112251234567', 'phone' => '01001234508', 'email' => 'amira.swim@club.com', 'dob' => '1991-12-25', 'gender' => 'female', 'type' => 'staff', 'payment' => 'per_session', 'hourly' => 50, 'session' => 50, 'monthly' => null, 'max_groups' => 8, 'certs' => ['شهادة تدريب سباحة أطفال', 'إنقاذ مائي']],
['code' => 'COACH-006', 'name_ar' => 'عمر سعيد', 'name_en' => 'Omar Said', 'nid' => '28604141234567', 'phone' => '01001234509', 'email' => 'omar.karate@club.com', 'dob' => '1986-04-14', 'gender' => 'male', 'type' => 'contract', 'payment' => 'per_session', 'hourly' => 200, 'session' => 200, 'monthly' => null, 'max_groups' => 5, 'certs' => ['حزام أسود دان 4', 'مدرب كاراتيه دولي WKF']],
['code' => 'COACH-007', 'name_ar' => 'يوسف إبراهيم', 'name_en' => 'Youssef Ibrahim', 'nid' => '29207071234567', 'phone' => '01001234510', 'email' => 'youssef.foot@club.com', 'dob' => '1992-07-07', 'gender' => 'male', 'type' => 'freelance', 'payment' => 'per_session', 'hourly' => 300, 'session' => 300, 'monthly' => null, 'max_groups' => 3, 'certs' => ['رخصة تدريب B من الاتحاد المصري', 'لاعب سابق بالدوري الممتاز']],
['code' => 'COACH-008', 'name_ar' => 'نورا حسام', 'name_en' => 'Noura Hossam', 'nid' => '29309181234567', 'phone' => '01001234511', 'email' => 'noura.racket@club.com', 'dob' => '1993-09-18', 'gender' => 'female', 'type' => 'staff', 'payment' => 'per_session', 'hourly' => 150, 'session' => 150, 'monthly' => null, 'max_groups' => 6, 'certs' => ['مدرب تنس ITF Level 1', 'مدرب اسكواش معتمد']],
];
$coachIds = [];
foreach ($coaches as $c) {
$existing = $db->selectOne("SELECT id FROM sa_coaches WHERE code = ?", [$c['code']]);
if (!$existing) {
$db->insert('sa_coaches', [
'code' => $c['code'],
'full_name_ar' => $c['name_ar'],
'full_name_en' => $c['name_en'],
'national_id' => $c['nid'],
'phone' => $c['phone'],
'email' => $c['email'],
'date_of_birth' => $c['dob'],
'gender' => $c['gender'],
'photo_path' => null,
'certifications_json' => json_encode($c['certs'], JSON_UNESCAPED_UNICODE),
'employment_type' => $c['type'],
'employee_id' => null,
'payment_model' => $c['payment'],
'hourly_rate' => $c['hourly'],
'session_rate' => $c['session'],
'monthly_rate' => $c['monthly'],
'max_groups' => $c['max_groups'],
'is_active' => 1,
'is_archived' => 0,
'branch_id' => 1,
'created_at' => $ts,
'updated_at' => $ts,
]);
$coachIds[$c['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$coachIds[$c['code']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 7. ACADEMIES — 4 academies
// ══════════════════════════════════════════════════════════════════════════
$academies = [
['code' => 'ACD-SWIM', 'name_ar' => 'أكاديمية السباحة', 'name_en' => 'Swimming Academy', 'disc' => 'SWIMMING', 'type' => 'internal', 'contact' => 'أحمد محمد حسن', 'phone' => '01001234501', 'email' => 'swim.academy@club.com', 'desc' => 'أكاديمية السباحة الرسمية لنادي الهادي شيراتون — تعليم وتدريب جميع المستويات'],
['code' => 'ACD-FOOT', 'name_ar' => 'أكاديمية كرة القدم', 'name_en' => 'Football Academy', 'disc' => 'FOOTBALL', 'type' => 'internal', 'contact' => 'محمد عبدالله', 'phone' => '01001234505', 'email' => 'football.academy@club.com', 'desc' => 'أكاديمية كرة القدم — تطوير المواهب الشابة'],
['code' => 'ACD-RACKET', 'name_ar' => 'أكاديمية المضرب', 'name_en' => 'Racket Academy', 'disc' => 'TENNIS', 'type' => 'internal', 'contact' => 'خالد يوسف', 'phone' => '01001234507', 'email' => 'racket.academy@club.com', 'desc' => 'أكاديمية رياضات المضرب — تنس، بادل، اسكواش'],
['code' => 'ACD-COMBAT', 'name_ar' => 'أكاديمية الفنون القتالية', 'name_en' => 'Combat Arts Academy', 'disc' => 'KARATE', 'type' => 'external', 'contact' => 'عمر سعيد', 'phone' => '01001234509', 'email' => 'combat.academy@club.com', 'desc' => 'أكاديمية الفنون القتالية — كاراتيه وفنون دفاع عن النفس'],
];
$academyIds = [];
foreach ($academies as $a) {
$existing = $db->selectOne("SELECT id FROM sa_academies WHERE code = ?", [$a['code']]);
if (!$existing) {
$db->insert('sa_academies', [
'code' => $a['code'],
'name_ar' => $a['name_ar'],
'name_en' => $a['name_en'],
'discipline_id' => $discIds[$a['disc']],
'academy_type' => $a['type'],
'contact_person' => $a['contact'],
'contact_phone' => $a['phone'],
'contact_email' => $a['email'],
'description_ar' => $a['desc'],
'logo_path' => null,
'is_active' => 1,
'is_archived' => 0,
'branch_id' => 1,
'created_at' => $ts,
'updated_at' => $ts,
]);
$academyIds[$a['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$academyIds[$a['code']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 8. ACADEMY CONTRACTS — one per academy
// ══════════════════════════════════════════════════════════════════════════
$contracts = [
['academy' => 'ACD-SWIM', 'number' => 'CTR-2025-001', 'type' => 'revenue_share', 'commission' => 20, 'share' => 80, 'rent' => null, 'deposit' => 5000, 'status' => 'active'],
['academy' => 'ACD-FOOT', 'number' => 'CTR-2025-002', 'type' => 'revenue_share', 'commission' => 25, 'share' => 75, 'rent' => null, 'deposit' => 10000, 'status' => 'active'],
['academy' => 'ACD-RACKET', 'number' => 'CTR-2025-003', 'type' => 'revenue_share', 'commission' => 20, 'share' => 80, 'rent' => null, 'deposit' => 5000, 'status' => 'active'],
['academy' => 'ACD-COMBAT', 'number' => 'CTR-2025-004', 'type' => 'fixed_rent', 'commission' => 0, 'share' => 100, 'rent' => 15000, 'deposit' => 30000, 'status' => 'active'],
];
foreach ($contracts as $ctr) {
$academyId = $academyIds[$ctr['academy']] ?? null;
if (!$academyId) continue;
$existing = $db->selectOne("SELECT id FROM sa_academy_contracts WHERE contract_number = ?", [$ctr['number']]);
if (!$existing) {
$db->insert('sa_academy_contracts', [
'contract_number' => $ctr['number'],
'academy_id' => $academyId,
'contract_type' => $ctr['type'],
'start_date' => '2025-01-01',
'end_date' => '2025-12-31',
'club_commission_pct' => $ctr['commission'],
'academy_share_pct' => $ctr['share'],
'fixed_monthly_rent' => $ctr['rent'] ?? 0.00,
'deposit_amount' => $ctr['deposit'],
'deposit_status' => 'paid',
'contract_pdf_path' => '/uploads/contracts/' . $ctr['number'] . '.pdf',
'status' => $ctr['status'],
'terms_json' => json_encode([
'auto_renew' => true,
'notice_period_days' => 30,
'penalty_early_termination' => 'خصم شهر من التأمين',
'payment_due_day' => 5,
], JSON_UNESCAPED_UNICODE),
'notes' => null,
'is_archived' => 0,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
}
// ══════════════════════════════════════════════════════════════════════════
// 9. PROGRAMS — 8 training programs
// ══════════════════════════════════════════════════════════════════════════
$programs = [
['code' => 'PRG-SWIM-BEG', 'name_ar' => 'تعليم سباحة — مبتدئين', 'name_en' => 'Swimming Beginners', 'disc' => 'SWIMMING', 'academy' => 'ACD-SWIM', 'type' => 'training', 'age_from' => 6, 'age_to' => 10, 'gender' => null, 'skill' => 'beginner', 'desc' => 'تعليم أساسيات السباحة للأطفال من سن 6 إلى 10 سنوات', 'duration' => 45, 'per_week' => 3],
['code' => 'PRG-SWIM-ADV', 'name_ar' => 'سباحة متقدم', 'name_en' => 'Swimming Advanced', 'disc' => 'SWIMMING', 'academy' => 'ACD-SWIM', 'type' => 'competitive', 'age_from' => 10, 'age_to' => 16, 'gender' => null, 'skill' => 'advanced', 'desc' => 'تدريب متقدم للسباحين المتميزين — إعداد للبطولات', 'duration' => 90, 'per_week' => 5],
['code' => 'PRG-FOOT-JR', 'name_ar' => 'كرة قدم — ناشئين', 'name_en' => 'Football Juniors', 'disc' => 'FOOTBALL', 'academy' => 'ACD-FOOT', 'type' => 'training', 'age_from' => 8, 'age_to' => 12, 'gender' => 'male', 'skill' => 'beginner', 'desc' => 'تدريب كرة القدم للناشئين — أساسيات اللعب والمهارات', 'duration' => 60, 'per_week' => 3],
['code' => 'PRG-FOOT-YTH', 'name_ar' => 'كرة قدم — شباب', 'name_en' => 'Football Youth', 'disc' => 'FOOTBALL', 'academy' => 'ACD-FOOT', 'type' => 'competitive', 'age_from' => 12, 'age_to' => 18, 'gender' => 'male', 'skill' => 'intermediate', 'desc' => 'فريق الشباب — إعداد بدني وتكتيكي متقدم', 'duration' => 90, 'per_week' => 4],
['code' => 'PRG-TENNIS-FND', 'name_ar' => 'أساسيات التنس', 'name_en' => 'Tennis Fundamentals', 'disc' => 'TENNIS', 'academy' => 'ACD-RACKET', 'type' => 'training', 'age_from' => 8, 'age_to' => 14, 'gender' => null, 'skill' => 'beginner', 'desc' => 'تعليم أساسيات التنس الأرضي — المسكة والضربات الأساسية', 'duration' => 60, 'per_week' => 3],
['code' => 'PRG-PADEL-TRN', 'name_ar' => 'تدريب البادل', 'name_en' => 'Padel Training', 'disc' => 'PADEL', 'academy' => 'ACD-RACKET', 'type' => 'training', 'age_from' => 12, 'age_to' => 18, 'gender' => null, 'skill' => 'intermediate', 'desc' => 'تدريب البادل تنس — تطوير المهارات والخطط', 'duration' => 60, 'per_week' => 2],
['code' => 'PRG-GYM-KIDS', 'name_ar' => 'جمباز أطفال', 'name_en' => 'Gymnastics Kids', 'disc' => 'GYMNASTICS', 'academy' => null, 'type' => 'training', 'age_from' => 5, 'age_to' => 10, 'gender' => null, 'skill' => 'beginner', 'desc' => 'الجمباز الإيقاعي للأطفال — مرونة وتوازن', 'duration' => 45, 'per_week' => 3],
['code' => 'PRG-KARATE-ALL', 'name_ar' => 'كاراتيه جميع المستويات', 'name_en' => 'Karate All Levels', 'disc' => 'KARATE', 'academy' => 'ACD-COMBAT', 'type' => 'training', 'age_from' => 6, 'age_to' => 16, 'gender' => null, 'skill' => 'beginner', 'desc' => 'تدريب الكاراتيه من الحزام الأبيض حتى الأسود — كاتا وكوميتيه', 'duration' => 60, 'per_week' => 3],
];
$programIds = [];
foreach ($programs as $p) {
$existing = $db->selectOne("SELECT id FROM sa_programs WHERE code = ?", [$p['code']]);
if (!$existing) {
$db->insert('sa_programs', [
'code' => $p['code'],
'name_ar' => $p['name_ar'],
'name_en' => $p['name_en'],
'discipline_id' => $discIds[$p['disc']],
'academy_id' => $p['academy'] ? ($academyIds[$p['academy']] ?? null) : null,
'program_type' => $p['type'],
'age_from' => $p['age_from'],
'age_to' => $p['age_to'],
'gender_restriction' => $p['gender'],
'skill_level' => $p['skill'],
'description_ar' => $p['desc'],
'session_duration_minutes' => $p['duration'],
'sessions_per_week' => $p['per_week'],
'is_active' => 1,
'is_archived' => 0,
'created_at' => $ts,
'updated_at' => $ts,
]);
$programIds[$p['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$programIds[$p['code']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 10. GROUPS — 12 training groups across programs
// ══════════════════════════════════════════════════════════════════════════
$groups = [
// Swimming beginners — 2 groups
['code' => 'GRP-SB-A', 'name_ar' => 'مبتدئين سباحة أ', 'name_en' => 'Swim Beginners A', 'program' => 'PRG-SWIM-BEG', 'coach' => 'COACH-001', 'min' => 5, 'max' => 12, 'count' => 10, 'fee_m' => 500, 'fee_nm' => 750],
['code' => 'GRP-SB-B', 'name_ar' => 'مبتدئين سباحة ب', 'name_en' => 'Swim Beginners B', 'program' => 'PRG-SWIM-BEG', 'coach' => 'COACH-005', 'min' => 5, 'max' => 12, 'count' => 8, 'fee_m' => 500, 'fee_nm' => 750],
// Swimming advanced — 1 group
['code' => 'GRP-SA-A', 'name_ar' => 'متقدم سباحة', 'name_en' => 'Swim Advanced', 'program' => 'PRG-SWIM-ADV', 'coach' => 'COACH-001', 'min' => 4, 'max' => 10, 'count' => 7, 'fee_m' => 800, 'fee_nm' => 1200],
// Football juniors — 2 groups
['code' => 'GRP-FJ-A', 'name_ar' => 'ناشئين قدم أ', 'name_en' => 'Football Juniors A', 'program' => 'PRG-FOOT-JR', 'coach' => 'COACH-002', 'min' => 10, 'max' => 20, 'count' => 15, 'fee_m' => 400, 'fee_nm' => 600],
['code' => 'GRP-FJ-B', 'name_ar' => 'ناشئين قدم ب', 'name_en' => 'Football Juniors B', 'program' => 'PRG-FOOT-JR', 'coach' => 'COACH-007', 'min' => 10, 'max' => 20, 'count' => 12, 'fee_m' => 400, 'fee_nm' => 600],
// Football youth — 1 group
['code' => 'GRP-FY-A', 'name_ar' => 'شباب قدم', 'name_en' => 'Football Youth', 'program' => 'PRG-FOOT-YTH', 'coach' => 'COACH-002', 'min' => 12, 'max' => 25, 'count' => 18, 'fee_m' => 600, 'fee_nm' => 900],
// Tennis fundamentals — 1 group
['code' => 'GRP-TF-A', 'name_ar' => 'أساسيات تنس', 'name_en' => 'Tennis Fundamentals', 'program' => 'PRG-TENNIS-FND', 'coach' => 'COACH-004', 'min' => 4, 'max' => 8, 'count' => 6, 'fee_m' => 600, 'fee_nm' => 900],
// Padel training — 1 group
['code' => 'GRP-PD-A', 'name_ar' => 'تدريب بادل', 'name_en' => 'Padel Training', 'program' => 'PRG-PADEL-TRN', 'coach' => 'COACH-008', 'min' => 4, 'max' => 8, 'count' => 5, 'fee_m' => 600, 'fee_nm' => 900],
// Gymnastics kids — 2 groups
['code' => 'GRP-GK-A', 'name_ar' => 'جمباز أطفال أ', 'name_en' => 'Gymnastics Kids A', 'program' => 'PRG-GYM-KIDS', 'coach' => 'COACH-003', 'min' => 6, 'max' => 15, 'count' => 12, 'fee_m' => 500, 'fee_nm' => 800],
['code' => 'GRP-GK-B', 'name_ar' => 'جمباز أطفال ب', 'name_en' => 'Gymnastics Kids B', 'program' => 'PRG-GYM-KIDS', 'coach' => 'COACH-003', 'min' => 6, 'max' => 15, 'count' => 9, 'fee_m' => 500, 'fee_nm' => 800],
// Karate — 2 groups
['code' => 'GRP-KR-A', 'name_ar' => 'كاراتيه مبتدئين', 'name_en' => 'Karate Beginners', 'program' => 'PRG-KARATE-ALL', 'coach' => 'COACH-006', 'min' => 8, 'max' => 20, 'count' => 14, 'fee_m' => 450, 'fee_nm' => 700],
['code' => 'GRP-KR-B', 'name_ar' => 'كاراتيه متقدم', 'name_en' => 'Karate Advanced', 'program' => 'PRG-KARATE-ALL', 'coach' => 'COACH-006', 'min' => 6, 'max' => 15, 'count' => 10, 'fee_m' => 500, 'fee_nm' => 800],
];
$groupIds = [];
foreach ($groups as $g) {
$existing = $db->selectOne("SELECT id FROM sa_groups WHERE code = ?", [$g['code']]);
if (!$existing) {
$db->insert('sa_groups', [
'code' => $g['code'],
'name_ar' => $g['name_ar'],
'name_en' => $g['name_en'],
'program_id' => $programIds[$g['program']],
'coach_id' => $coachIds[$g['coach']],
'min_capacity' => $g['min'],
'max_capacity' => $g['max'],
'current_count' => $g['count'],
'is_full' => $g['count'] >= $g['max'] ? 1 : 0,
'monthly_fee_member' => $g['fee_m'],
'monthly_fee_nonmember' => $g['fee_nm'],
'season_start' => '2025-01-01',
'season_end' => '2025-12-31',
'status' => 'active',
'is_archived' => 0,
'created_at' => $ts,
'updated_at' => $ts,
]);
$groupIds[$g['code']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$groupIds[$g['code']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 11. PLAYERS — 20 players (12 members + 8 non-members)
// ══════════════════════════════════════════════════════════════════════════
$players = [
// Members (12)
['type' => 'member', 'member_id' => 101, 'serial' => 'SA-2025-0001', 'name_ar' => 'يوسف أحمد إبراهيم', 'name_en' => 'Youssef Ahmed Ibrahim', 'nid' => '31503151234567', 'dob' => '2015-03-15', 'gender' => 'male', 'phone' => null, 'guardian' => 'أحمد إبراهيم', 'guardian_phone' => '01012345001', 'guardian_nid' => '28001011234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 102, 'serial' => 'SA-2025-0002', 'name_ar' => 'مريم خالد حسن', 'name_en' => 'Mariam Khaled Hassan', 'nid' => '31407221234567', 'dob' => '2014-07-22', 'gender' => 'female', 'phone' => null, 'guardian' => 'خالد حسن', 'guardian_phone' => '01012345002', 'guardian_nid' => '28201021234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 103, 'serial' => 'SA-2025-0003', 'name_ar' => 'عمر محمود سعيد', 'name_en' => 'Omar Mahmoud Said', 'nid' => '31201101234567', 'dob' => '2012-01-10', 'gender' => 'male', 'phone' => null, 'guardian' => 'محمود سعيد', 'guardian_phone' => '01012345003', 'guardian_nid' => '28301031234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 104, 'serial' => 'SA-2025-0004', 'name_ar' => 'فاطمة علي إبراهيم', 'name_en' => 'Fatma Ali Ibrahim', 'nid' => '31011051234567', 'dob' => '2010-11-05', 'gender' => 'female', 'phone' => '01112345004', 'guardian' => 'علي إبراهيم', 'guardian_phone' => '01012345004', 'guardian_nid' => '28401041234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 105, 'serial' => 'SA-2025-0005', 'name_ar' => 'أحمد حسام الدين', 'name_en' => 'Ahmed Hossam Eldin', 'nid' => '30906181234567', 'dob' => '2009-06-18', 'gender' => 'male', 'phone' => '01112345005', 'guardian' => 'حسام الدين محمد', 'guardian_phone' => '01012345005', 'guardian_nid' => '28501051234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 106, 'serial' => 'SA-2025-0006', 'name_ar' => 'كريم عبدالرحمن', 'name_en' => 'Karim Abdulrahman', 'nid' => '31108121234567', 'dob' => '2011-08-12', 'gender' => 'male', 'phone' => null, 'guardian' => 'عبدالرحمن محمد', 'guardian_phone' => '01012345006', 'guardian_nid' => '28601061234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 107, 'serial' => 'SA-2025-0007', 'name_ar' => 'جنى محمد فوزي', 'name_en' => 'Jana Mohamed Fawzy', 'nid' => '31312251234567', 'dob' => '2013-12-25', 'gender' => 'female', 'phone' => null, 'guardian' => 'محمد فوزي', 'guardian_phone' => '01012345007', 'guardian_nid' => '28701071234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 108, 'serial' => 'SA-2025-0008', 'name_ar' => 'ياسين طارق عبدالله', 'name_en' => 'Yassin Tarek Abdullah', 'nid' => '31502141234567', 'dob' => '2015-02-14', 'gender' => 'male', 'phone' => null, 'guardian' => 'طارق عبدالله', 'guardian_phone' => '01012345008', 'guardian_nid' => '28801081234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 109, 'serial' => 'SA-2025-0009', 'name_ar' => 'سلمى وليد نبيل', 'name_en' => 'Salma Walid Nabil', 'nid' => '31008071234567', 'dob' => '2010-08-07', 'gender' => 'female', 'phone' => '01112345009', 'guardian' => 'وليد نبيل', 'guardian_phone' => '01012345009', 'guardian_nid' => '28901091234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 110, 'serial' => 'SA-2025-0010', 'name_ar' => 'حسن محمد رضا', 'name_en' => 'Hassan Mohamed Reda', 'nid' => '31205201234567', 'dob' => '2012-05-20', 'gender' => 'male', 'phone' => null, 'guardian' => 'محمد رضا', 'guardian_phone' => '01012345010', 'guardian_nid' => '29001101234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 111, 'serial' => 'SA-2025-0011', 'name_ar' => 'ريم أشرف سعد', 'name_en' => 'Reem Ashraf Saad', 'nid' => '30910031234567', 'dob' => '2009-10-03', 'gender' => 'female', 'phone' => '01112345011', 'guardian' => 'أشرف سعد', 'guardian_phone' => '01012345011', 'guardian_nid' => '29101111234567', 'guardian_rel' => 'father'],
['type' => 'member', 'member_id' => 112, 'serial' => 'SA-2025-0012', 'name_ar' => 'عبدالله سمير', 'name_en' => 'Abdullah Samir', 'nid' => '31103281234567', 'dob' => '2011-03-28', 'gender' => 'male', 'phone' => null, 'guardian' => 'سمير أحمد', 'guardian_phone' => '01012345012', 'guardian_nid' => '29201121234567', 'guardian_rel' => 'father'],
// Non-members (8)
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0013', 'name_ar' => 'نور الهدى سامي', 'name_en' => 'Nour Elhuda Sami', 'nid' => '31209301234568', 'dob' => '2012-09-30', 'gender' => 'female', 'phone' => null, 'guardian' => 'سامي حسين', 'guardian_phone' => '01012345013', 'guardian_nid' => '29301131234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0014', 'name_ar' => 'محمد أيمن خالد', 'name_en' => 'Mohamed Ayman Khaled', 'nid' => '31404121234567', 'dob' => '2014-04-12', 'gender' => 'male', 'phone' => null, 'guardian' => 'أيمن خالد', 'guardian_phone' => '01012345014', 'guardian_nid' => '29401141234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0015', 'name_ar' => 'هنا وائل عبدالحميد', 'name_en' => 'Hana Wael Abdulhamid', 'nid' => '31007161234567', 'dob' => '2010-07-16', 'gender' => 'female', 'phone' => '01112345015', 'guardian' => 'وائل عبدالحميد', 'guardian_phone' => '01012345015', 'guardian_nid' => '29501151234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0016', 'name_ar' => 'طارق عبدالعزيز محمد', 'name_en' => 'Tarek Abdelaziz Mohamed', 'nid' => '30906051234568', 'dob' => '2009-06-05', 'gender' => 'male', 'phone' => '01112345016', 'guardian' => 'عبدالعزيز محمد', 'guardian_phone' => '01012345016', 'guardian_nid' => '29601161234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0017', 'name_ar' => 'ليلى فريد أحمد', 'name_en' => 'Laila Farid Ahmed', 'nid' => '31509181234567', 'dob' => '2015-09-18', 'gender' => 'female', 'phone' => null, 'guardian' => 'فريد أحمد', 'guardian_phone' => '01012345017', 'guardian_nid' => '29701171234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0018', 'name_ar' => 'مصطفى جمال حسن', 'name_en' => 'Mostafa Gamal Hassan', 'nid' => '31112011234567', 'dob' => '2011-12-01', 'gender' => 'male', 'phone' => null, 'guardian' => 'جمال حسن', 'guardian_phone' => '01012345018', 'guardian_nid' => '29801181234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0019', 'name_ar' => 'دينا محمود سالم', 'name_en' => 'Dina Mahmoud Salem', 'nid' => '31304141234567', 'dob' => '2013-04-14', 'gender' => 'female', 'phone' => null, 'guardian' => 'محمود سالم', 'guardian_phone' => '01012345019', 'guardian_nid' => '29901191234567', 'guardian_rel' => 'father'],
['type' => 'non_member', 'member_id' => null, 'serial' => 'SA-2025-0020', 'name_ar' => 'زياد عماد الدين', 'name_en' => 'Ziad Emad Eldin', 'nid' => '31206251234567', 'dob' => '2012-06-25', 'gender' => 'male', 'phone' => null, 'guardian' => 'عماد الدين', 'guardian_phone' => '01012345020', 'guardian_nid' => '30001201234567', 'guardian_rel' => 'father'],
];
$playerIds = [];
foreach ($players as $p) {
$existing = $db->selectOne("SELECT id FROM sa_players WHERE registration_serial = ?", [$p['serial']]);
if (!$existing) {
$dob = $p['dob'];
$age = (int) date('Y') - (int) substr($dob, 0, 4);
$needsGuardian = $age < 14;
$db->insert('sa_players', [
'player_type' => $p['type'],
'member_id' => $p['member_id'],
'registration_serial' => $p['serial'],
'full_name_ar' => $p['name_ar'],
'full_name_en' => $p['name_en'],
'national_id' => $p['nid'],
'date_of_birth' => $p['dob'],
'gender' => $p['gender'],
'phone' => $p['phone'],
'email' => null,
'guardian_name' => $needsGuardian ? $p['guardian'] : null,
'guardian_phone' => $needsGuardian ? $p['guardian_phone'] : null,
'guardian_national_id' => $needsGuardian ? $p['guardian_nid'] : null,
'guardian_relationship' => $needsGuardian ? $p['guardian_rel'] : null,
'photo_path' => null,
'medical_status' => 'fit',
'medical_expiry_date' => '2025-12-31',
'card_status' => 'active',
'registration_fee_paid' => 1,
'notes' => null,
'branch_id' => 1,
'is_archived' => 0,
'created_at' => $ts,
'updated_at' => $ts,
]);
$playerIds[$p['serial']] = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id", [])['id'];
} else {
$playerIds[$p['serial']] = (int) $existing['id'];
}
}
// ══════════════════════════════════════════════════════════════════════════
// 12. GROUP PLAYERS — 30 enrollments distributing 20 players across groups
// ══════════════════════════════════════════════════════════════════════════
$enrollments = [
// Swimming beginners A — players 1-5
['group' => 'GRP-SB-A', 'players' => ['SA-2025-0001', 'SA-2025-0002', 'SA-2025-0007', 'SA-2025-0008', 'SA-2025-0017']],
// Swimming beginners B — players 6-8
['group' => 'GRP-SB-B', 'players' => ['SA-2025-0013', 'SA-2025-0014', 'SA-2025-0019', 'SA-2025-0020']],
// Swimming advanced — players 3,4,5
['group' => 'GRP-SA-A', 'players' => ['SA-2025-0003', 'SA-2025-0004', 'SA-2025-0005', 'SA-2025-0009']],
// Football juniors A — players 3,5,6,10,12
['group' => 'GRP-FJ-A', 'players' => ['SA-2025-0003', 'SA-2025-0005', 'SA-2025-0006', 'SA-2025-0010', 'SA-2025-0012']],
// Football juniors B — players 14,16,18
['group' => 'GRP-FJ-B', 'players' => ['SA-2025-0014', 'SA-2025-0016', 'SA-2025-0018']],
// Football youth — players 4,5,11
['group' => 'GRP-FY-A', 'players' => ['SA-2025-0004', 'SA-2025-0005', 'SA-2025-0011']],
// Tennis fundamentals — players 9,10,15
['group' => 'GRP-TF-A', 'players' => ['SA-2025-0009', 'SA-2025-0010', 'SA-2025-0015']],
// Padel — players 5,11,16
['group' => 'GRP-PD-A', 'players' => ['SA-2025-0005', 'SA-2025-0011', 'SA-2025-0016']],
// Gymnastics kids A — players 1,2,7,8,17
['group' => 'GRP-GK-A', 'players' => ['SA-2025-0001', 'SA-2025-0002', 'SA-2025-0007', 'SA-2025-0008', 'SA-2025-0017']],
// Karate beginners — players 3,6,10,12,13,18,20
['group' => 'GRP-KR-A', 'players' => ['SA-2025-0003', 'SA-2025-0006', 'SA-2025-0010', 'SA-2025-0012', 'SA-2025-0013', 'SA-2025-0018', 'SA-2025-0020']],
];
foreach ($enrollments as $e) {
$gId = $groupIds[$e['group']] ?? null;
if (!$gId) continue;
foreach ($e['players'] as $serial) {
$pId = $playerIds[$serial] ?? null;
if (!$pId) continue;
$existing = $db->selectOne(
"SELECT id FROM sa_group_players WHERE group_id = ? AND player_id = ? AND status = 'active'",
[$gId, $pId]
);
if (!$existing) {
$db->insert('sa_group_players', [
'group_id' => $gId,
'player_id' => $pId,
'enrolled_at' => '2025-01-15',
'left_at' => null,
'status' => 'active',
'notes' => null,
]);
}
}
}
// ══════════════════════════════════════════════════════════════════════════
// 13. GROUP SCHEDULE — 24 schedule entries (each group meets 2-3 times/week)
// ══════════════════════════════════════════════════════════════════════════
// Day: 0=Sunday, 1=Monday, 2=Tuesday, 3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday
$schedules = [
// Swimming beginners A — Sun, Tue, Thu 09:00-09:45 on LANE-1
['group' => 'GRP-SB-A', 'unit' => 'LANE-1', 'day' => 0, 'start' => '09:00:00', 'end' => '09:45:00'],
['group' => 'GRP-SB-A', 'unit' => 'LANE-1', 'day' => 2, 'start' => '09:00:00', 'end' => '09:45:00'],
['group' => 'GRP-SB-A', 'unit' => 'LANE-1', 'day' => 4, 'start' => '09:00:00', 'end' => '09:45:00'],
// Swimming beginners B — Mon, Wed, Sat 10:00-10:45 on LANE-2
['group' => 'GRP-SB-B', 'unit' => 'LANE-2', 'day' => 1, 'start' => '10:00:00', 'end' => '10:45:00'],
['group' => 'GRP-SB-B', 'unit' => 'LANE-2', 'day' => 3, 'start' => '10:00:00', 'end' => '10:45:00'],
['group' => 'GRP-SB-B', 'unit' => 'LANE-2', 'day' => 6, 'start' => '10:00:00', 'end' => '10:45:00'],
// Swimming advanced — Sun-Thu 06:00-07:30 on LANE-4,5
['group' => 'GRP-SA-A', 'unit' => 'LANE-4', 'day' => 0, 'start' => '06:00:00', 'end' => '07:30:00'],
['group' => 'GRP-SA-A', 'unit' => 'LANE-4', 'day' => 2, 'start' => '06:00:00', 'end' => '07:30:00'],
['group' => 'GRP-SA-A', 'unit' => 'LANE-4', 'day' => 4, 'start' => '06:00:00', 'end' => '07:30:00'],
// Football juniors A — Sun, Tue, Thu 16:00-17:00 on main pitch
['group' => 'GRP-FJ-A', 'unit' => 'PITCH-MAIN', 'day' => 0, 'start' => '16:00:00', 'end' => '17:00:00'],
['group' => 'GRP-FJ-A', 'unit' => 'PITCH-MAIN', 'day' => 2, 'start' => '16:00:00', 'end' => '17:00:00'],
['group' => 'GRP-FJ-A', 'unit' => 'PITCH-MAIN', 'day' => 4, 'start' => '16:00:00', 'end' => '17:00:00'],
// Football juniors B — Mon, Wed 17:00-18:00 on 5-a-side
['group' => 'GRP-FJ-B', 'unit' => 'PITCH-5A', 'day' => 1, 'start' => '17:00:00', 'end' => '18:00:00'],
['group' => 'GRP-FJ-B', 'unit' => 'PITCH-5A', 'day' => 3, 'start' => '17:00:00', 'end' => '18:00:00'],
// Football youth — Mon, Wed, Sat 18:00-19:30 on main pitch
['group' => 'GRP-FY-A', 'unit' => 'PITCH-MAIN', 'day' => 1, 'start' => '18:00:00', 'end' => '19:30:00'],
['group' => 'GRP-FY-A', 'unit' => 'PITCH-MAIN', 'day' => 3, 'start' => '18:00:00', 'end' => '19:30:00'],
['group' => 'GRP-FY-A', 'unit' => 'PITCH-MAIN', 'day' => 6, 'start' => '18:00:00', 'end' => '19:30:00'],
// Tennis fundamentals — Sun, Tue, Thu 17:00-18:00 on court 1
['group' => 'GRP-TF-A', 'unit' => 'TCOURT-1', 'day' => 0, 'start' => '17:00:00', 'end' => '18:00:00'],
['group' => 'GRP-TF-A', 'unit' => 'TCOURT-1', 'day' => 2, 'start' => '17:00:00', 'end' => '18:00:00'],
// Padel training — Tue, Thu 18:00-19:00 on padel court 1
['group' => 'GRP-PD-A', 'unit' => 'PCOURT-1', 'day' => 2, 'start' => '18:00:00', 'end' => '19:00:00'],
['group' => 'GRP-PD-A', 'unit' => 'PCOURT-1', 'day' => 4, 'start' => '18:00:00', 'end' => '19:00:00'],
// Gymnastics kids A — Sun, Tue, Thu 15:00-15:45 in gym hall
['group' => 'GRP-GK-A', 'unit' => 'GYM-HALL', 'day' => 0, 'start' => '15:00:00', 'end' => '15:45:00'],
['group' => 'GRP-GK-A', 'unit' => 'GYM-HALL', 'day' => 2, 'start' => '15:00:00', 'end' => '15:45:00'],
['group' => 'GRP-GK-A', 'unit' => 'GYM-HALL', 'day' => 4, 'start' => '15:00:00', 'end' => '15:45:00'],
// Gymnastics kids B — Mon, Wed, Sat 15:00-15:45 in gym hall
['group' => 'GRP-GK-B', 'unit' => 'GYM-HALL', 'day' => 1, 'start' => '15:00:00', 'end' => '15:45:00'],
['group' => 'GRP-GK-B', 'unit' => 'GYM-HALL', 'day' => 3, 'start' => '15:00:00', 'end' => '15:45:00'],
// Karate beginners — Sun, Tue, Thu 18:00-19:00 in gym hall
['group' => 'GRP-KR-A', 'unit' => 'GYM-HALL', 'day' => 0, 'start' => '18:00:00', 'end' => '19:00:00'],
['group' => 'GRP-KR-A', 'unit' => 'GYM-HALL', 'day' => 2, 'start' => '18:00:00', 'end' => '19:00:00'],
['group' => 'GRP-KR-A', 'unit' => 'GYM-HALL', 'day' => 4, 'start' => '18:00:00', 'end' => '19:00:00'],
// Karate advanced — Mon, Wed 19:00-20:00 in gym hall
['group' => 'GRP-KR-B', 'unit' => 'GYM-HALL', 'day' => 1, 'start' => '19:00:00', 'end' => '20:00:00'],
['group' => 'GRP-KR-B', 'unit' => 'GYM-HALL', 'day' => 3, 'start' => '19:00:00', 'end' => '20:00:00'],
];
foreach ($schedules as $s) {
$gId = $groupIds[$s['group']] ?? null;
$uId = $unitIds[$s['unit']] ?? null;
if (!$gId || !$uId) continue;
$existing = $db->selectOne(
"SELECT id FROM sa_group_schedule WHERE group_id = ? AND facility_unit_id = ? AND day_of_week = ? AND start_time = ?",
[$gId, $uId, $s['day'], $s['start']]
);
if (!$existing) {
$db->insert('sa_group_schedule', [
'group_id' => $gId,
'facility_unit_id' => $uId,
'day_of_week' => $s['day'],
'start_time' => $s['start'],
'end_time' => $s['end'],
'is_active' => 1,
]);
}
}
// ══════════════════════════════════════════════════════════════════════════
// 14. POOL ZONE BOOKINGS — sample bookings for today on the 4x6 grid
// ══════════════════════════════════════════════════════════════════════════
$poolId = $facIds['POOL-MAIN'];
// Check if Phase_70_002 already seeded zone bookings for today
$existingZoneBookings = $db->selectOne(
"SELECT id FROM sa_pool_zone_bookings WHERE facility_id = ? AND booking_date = ? AND start_time = '10:00:00'",
[$poolId, $today]
);
if (!$existingZoneBookings) {
// Slot 10:00-11:00 — Swimming beginners A training (top-left 2x3 block)
$grpSbA = $groupIds['GRP-SB-A'] ?? null;
$coachSbA = $coachIds['COACH-001'] ?? null;
if ($grpSbA) {
for ($r = 0; $r < 2; $r++) {
for ($c = 0; $c < 3; $c++) {
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '10:00:00',
'end_time' => '11:00:00',
'zone_row' => $r,
'zone_col' => $c,
'assignment_type' => 'training',
'group_id' => $grpSbA,
'coach_id' => $coachSbA,
'label' => 'مبتدئين سباحة أ',
'notes' => null,
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
}
}
// Slot 10:00-11:00 — Hourly booking (row 2, cols 3-5)
for ($c = 3; $c < 6; $c++) {
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '10:00:00',
'end_time' => '11:00:00',
'zone_row' => 2,
'zone_col' => $c,
'assignment_type' => 'hourly',
'group_id' => null,
'coach_id' => null,
'label' => 'حجز ساعة — عائلة كمال',
'notes' => 'حجز عائلي',
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
// Slot 10:00-11:00 — Maintenance (row 3, col 5)
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '10:00:00',
'end_time' => '11:00:00',
'zone_row' => 3,
'zone_col' => 5,
'assignment_type' => 'maintenance',
'group_id' => null,
'coach_id' => null,
'label' => 'صيانة فلتر',
'notes' => 'تنظيف فلتر الزاوية',
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
// Slot 11:00-12:00 — Swimming advanced training (rows 0-3, cols 0-2)
$grpSaA = $groupIds['GRP-SA-A'] ?? null;
if ($grpSaA) {
for ($r = 0; $r < 4; $r++) {
for ($c = 0; $c < 3; $c++) {
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '11:00:00',
'end_time' => '12:00:00',
'zone_row' => $r,
'zone_col' => $c,
'assignment_type' => 'training',
'group_id' => $grpSaA,
'coach_id' => $coachSbA,
'label' => 'متقدم سباحة',
'notes' => null,
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
}
}
// Slot 11:00-12:00 — Blocked zone (row 3, cols 4-5)
for ($c = 4; $c < 6; $c++) {
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '11:00:00',
'end_time' => '12:00:00',
'zone_row' => 3,
'zone_col' => $c,
'assignment_type' => 'blocked',
'group_id' => null,
'coach_id' => null,
'label' => 'محجوب — حدث خاص',
'notes' => 'تجهيز لحفل مسائي',
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
// Slot 14:00-15:00 — Hourly bookings (scattered)
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '14:00:00',
'end_time' => '15:00:00',
'zone_row' => 0,
'zone_col' => 0,
'assignment_type' => 'hourly',
'group_id' => null,
'coach_id' => null,
'label' => 'حجز فردي — محمد',
'notes' => null,
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '14:00:00',
'end_time' => '15:00:00',
'zone_row' => 0,
'zone_col' => 1,
'assignment_type' => 'hourly',
'group_id' => null,
'coach_id' => null,
'label' => 'حجز فردي — محمد',
'notes' => null,
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
// Slot 17:00-18:00 — Swimming beginners B evening (rows 0-1, cols 0-3)
$grpSbB = $groupIds['GRP-SB-B'] ?? null;
$coachSbB = $coachIds['COACH-005'] ?? null;
if ($grpSbB) {
for ($r = 0; $r < 2; $r++) {
for ($c = 0; $c < 4; $c++) {
$db->insert('sa_pool_zone_bookings', [
'facility_id' => $poolId,
'booking_date' => $today,
'start_time' => '17:00:00',
'end_time' => '18:00:00',
'zone_row' => $r,
'zone_col' => $c,
'assignment_type' => 'training',
'group_id' => $grpSbB,
'coach_id' => $coachSbB,
'label' => 'مبتدئين سباحة ب',
'notes' => null,
'status' => 'active',
'created_by' => 1,
'cancelled_by' => null,
'cancelled_at' => null,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
}
}
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment