Commit cc10c16d authored by Mahmoud Aglan's avatar Mahmoud Aglan

xfgdf

parent da42f02a
......@@ -16,7 +16,9 @@
"Bash(ls /Users/mahmoudaglan/clubphp/database/seeds/Phase_22*)",
"Bash(ls database/migrations/Phase_1[7-9]_* database/migrations/Phase_2[0-3]_*)",
"Bash(ls database/seeds/Phase_1[7-9]_* database/seeds/Phase_2[0-2]_*)",
"Bash(ls cron/jobs/*Job.php)"
"Bash(ls cron/jobs/*Job.php)",
"Bash(ls /Users/mahmoudaglan/clubphp/database/migrations/Phase_24_*)",
"Bash(ls -la /Users/mahmoudaglan/clubphp/database/migrations/Phase_24_*)"
]
}
}
......@@ -27,6 +27,9 @@ return [
`notes` TEXT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_archived` TINYINT(1) NOT NULL DEFAULT 0,
`archived_at` TIMESTAMP NULL DEFAULT NULL,
`archived_by` BIGINT UNSIGNED NULL,
`created_by` BIGINT UNSIGNED NULL,
UNIQUE KEY `uq_reservations_number` (`reservation_number`),
INDEX `idx_reservations_facility` (`facility_id`),
......
......@@ -25,6 +25,9 @@ return [
`notes` TEXT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_archived` TINYINT(1) NOT NULL DEFAULT 0,
`archived_at` TIMESTAMP NULL DEFAULT NULL,
`archived_by` BIGINT UNSIGNED NULL,
`created_by` BIGINT UNSIGNED NULL,
INDEX `idx_as_player` (`player_id`),
INDEX `idx_as_enrollment` (`enrollment_id`),
......
<?php
declare(strict_types=1);
return [
'up' => "ALTER TABLE `reservations`
ADD COLUMN `is_archived` TINYINT(1) NOT NULL DEFAULT 0 AFTER `created_by`,
ADD COLUMN `archived_at` TIMESTAMP NULL DEFAULT NULL AFTER `is_archived`,
ADD COLUMN `archived_by` BIGINT UNSIGNED NULL AFTER `archived_at`;
ALTER TABLE `activity_subscriptions`
ADD COLUMN `is_archived` TINYINT(1) NOT NULL DEFAULT 0 AFTER `created_by`,
ADD COLUMN `archived_at` TIMESTAMP NULL DEFAULT NULL AFTER `is_archived`,
ADD COLUMN `archived_by` BIGINT UNSIGNED NULL AFTER `archived_at`",
'down' => "ALTER TABLE `reservations`
DROP COLUMN `archived_by`,
DROP COLUMN `archived_at`,
DROP COLUMN `is_archived`;
ALTER TABLE `activity_subscriptions`
DROP COLUMN `archived_by`,
DROP COLUMN `archived_at`,
DROP COLUMN `is_archived`",
];
......@@ -12,14 +12,14 @@ return function (Database $db): void {
if (!$row) {
throw new \RuntimeException("Sport discipline '{$code}' not found. Run Phase 17 seeds first.");
}
return (int) $row->id;
return (int) $row['id'];
};
// ── Helper: insert academy idempotently, return its ID ──
$ensureAcademy = function (array $data) use ($db, $ts): int {
$existing = $db->selectOne("SELECT id FROM academies WHERE code = ?", [$data['code']]);
if ($existing) {
return (int) $existing->id;
return (int) $existing['id'];
}
$db->insert('academies', array_merge($data, [
'is_active' => 1,
......@@ -27,7 +27,7 @@ return function (Database $db): void {
'updated_at' => $ts,
]));
$inserted = $db->selectOne("SELECT id FROM academies WHERE code = ?", [$data['code']]);
return (int) $inserted->id;
return (int) $inserted['id'];
};
// ── Helper: insert level idempotently ──
......
......@@ -8,13 +8,11 @@ return function (Database $db): void {
$schemas = [
[
'schema_code' => 'SPORTS_REGISTRATION_MEMBER',
'name_ar' => 'تسجيل لاعب عضو في الأنشطة الرياضية',
'name_en' => 'Sports Registration - Member',
'description_ar' => 'استمارة تسجيل لاعب عضو بالنادي في الأنشطة الرياضية والأكاديميات',
'fee_amount' => '50.00',
'related_service' => 'SVC_SPORTS_REG_MEMBER',
'fields_json' => json_encode([
'form_code' => 'SPORTS_REGISTRATION_MEMBER',
'name_ar' => 'تسجيل لاعب عضو في الأنشطة الرياضية',
'name_en' => 'Sports Registration - Member',
'form_fee' => '50.00',
'schema_json' => json_encode([
['key' => 'member_id', 'type' => 'hidden', 'label_ar' => 'رقم العضو', 'required' => true, 'auto_populated' => true, 'order' => 1],
['key' => 'discipline_ids', 'type' => 'multi_select', 'label_ar' => 'الأنشطة الرياضية المطلوبة', 'required' => true, 'data_source' => 'sport_disciplines', 'order' => 2],
['key' => 'academy_id', 'type' => 'select', 'label_ar' => 'الأكاديمية', 'required' => false, 'data_source' => 'academies', 'order' => 3],
......@@ -27,22 +25,20 @@ return function (Database $db): void {
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
],
[
'schema_code' => 'SPORTS_REGISTRATION_NONMEMBER',
'name_ar' => 'تسجيل لاعب غير عضو في الأنشطة الرياضية',
'name_en' => 'Sports Registration - Non-Member',
'description_ar' => 'استمارة تسجيل لاعب من خارج النادي في الأنشطة الرياضية والأكاديميات',
'fee_amount' => '100.00',
'related_service' => 'SVC_SPORTS_REG_NONMEMBER',
'fields_json' => json_encode([
'form_code' => 'SPORTS_REGISTRATION_NONMEMBER',
'name_ar' => 'تسجيل لاعب غير عضو في الأنشطة الرياضية',
'name_en' => 'Sports Registration - Non-Member',
'form_fee' => '100.00',
'schema_json' => json_encode([
['key' => 'full_name_ar', 'type' => 'text', 'label_ar' => 'الاسم الكامل بالعربي', 'required' => true, 'validation' => 'required|string|min:10|max:200', 'order' => 1, 'width' => 'full'],
['key' => 'full_name_en', 'type' => 'text', 'label_ar' => 'الاسم بالإنجليزي', 'required' => false, 'validation' => 'nullable|string|max:200', 'order' => 2, 'width' => 'half'],
['key' => 'national_id', 'type' => 'text', 'label_ar' => 'الرقم القومي', 'required' => true, 'validation' => 'required|digits:14', 'order' => 3, 'width' => 'half'],
['key' => 'date_of_birth', 'type' => 'date', 'label_ar' => 'تاريخ الميلاد', 'required' => true, 'validation' => 'required|date', 'order' => 4, 'width' => 'half'],
['key' => 'gender', 'type' => 'select', 'label_ar' => 'النوع', 'required' => true, 'validation' => 'required|in:male,female', 'options' => [['value' => 'male', 'label_ar' => 'ذكر'], ['value' => 'female', 'label_ar' => 'أنثى']], 'order' => 5, 'width' => 'half'],
['key' => 'gender', 'type' => 'select', 'label_ar' => 'النوع', 'required' => true, 'options' => [['value' => 'male', 'label_ar' => 'ذكر'], ['value' => 'female', 'label_ar' => 'أنثى']], 'order' => 5, 'width' => 'half'],
['key' => 'phone', 'type' => 'text', 'label_ar' => 'الهاتف', 'required' => true, 'validation' => 'required|string|max:20', 'order' => 6, 'width' => 'half'],
['key' => 'guardian_name', 'type' => 'text', 'label_ar' => 'اسم ولي الأمر', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'validation' => 'required_if:age_lt_18|string|max:200', 'order' => 7, 'width' => 'half'],
['key' => 'guardian_phone', 'type' => 'text', 'label_ar' => 'هاتف ولي الأمر', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'validation' => 'required_if:age_lt_18|string|max:20', 'order' => 8, 'width' => 'half'],
['key' => 'guardian_national_id', 'type' => 'text', 'label_ar' => 'الرقم القومي لولي الأمر', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'validation' => 'nullable|digits:14', 'order' => 9, 'width' => 'half'],
['key' => 'guardian_name', 'type' => 'text', 'label_ar' => 'اسم ولي الأمر', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'order' => 7, 'width' => 'half'],
['key' => 'guardian_phone', 'type' => 'text', 'label_ar' => 'هاتف ولي الأمر', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'order' => 8, 'width' => 'half'],
['key' => 'guardian_national_id', 'type' => 'text', 'label_ar' => 'الرقم القومي لولي الأمر', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'order' => 9, 'width' => 'half'],
['key' => 'guardian_relationship', 'type' => 'select', 'label_ar' => 'صلة القرابة', 'required' => false, 'conditional' => true, 'show_if' => ['field' => 'age', 'operator' => 'lt', 'value' => 18], 'options' => [['value' => 'father', 'label_ar' => 'الأب'], ['value' => 'mother', 'label_ar' => 'الأم'], ['value' => 'brother', 'label_ar' => 'الأخ'], ['value' => 'sister', 'label_ar' => 'الأخت'], ['value' => 'other', 'label_ar' => 'أخرى']], 'order' => 10, 'width' => 'half'],
['key' => 'discipline_ids', 'type' => 'multi_select', 'label_ar' => 'الأنشطة الرياضية المطلوبة', 'required' => true, 'data_source' => 'sport_disciplines', 'order' => 11],
['key' => 'academy_id', 'type' => 'select', 'label_ar' => 'الأكاديمية', 'required' => false, 'data_source' => 'academies', 'order' => 12],
......@@ -54,24 +50,20 @@ return function (Database $db): void {
];
foreach ($schemas as $s) {
$existing = $db->selectOne("SELECT id FROM form_schemas WHERE schema_code = ?", [$s['schema_code']]);
$existing = $db->selectOne("SELECT id FROM form_schemas WHERE form_code = ?", [$s['form_code']]);
if ($existing) {
continue;
}
$db->insert('form_schemas', [
'schema_code' => $s['schema_code'],
'name_ar' => $s['name_ar'],
'name_en' => $s['name_en'],
'description_ar' => $s['description_ar'],
'fields_json' => $s['fields_json'],
'validation_json' => null,
'fee_amount' => $s['fee_amount'],
'related_service' => $s['related_service'],
'config_json' => null,
'is_active' => 1,
'version' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'form_code' => $s['form_code'],
'name_ar' => $s['name_ar'],
'name_en' => $s['name_en'],
'form_fee' => $s['form_fee'],
'schema_json' => $s['schema_json'],
'is_active' => 1,
'version' => 1,
'created_at' => $ts,
'updated_at' => $ts,
]);
}
};
......@@ -8,53 +8,67 @@ return function (Database $db): void {
$templates = [
[
'template_code' => 'SMS_SPORTS_REGISTRATION',
'name_ar' => 'تسجيل في الأنشطة الرياضية',
'event_trigger' => 'player.registered',
'message_template' => 'مرحباً {player_name}، تم تسجيلك بنجاح في الأنشطة الرياضية. رقم التسجيل: {registration_serial}',
'variables_json' => json_encode(['player_name', 'registration_serial'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_SPORTS_REGISTRATION',
'name_ar' => 'تسجيل في الأنشطة الرياضية',
'name_en' => 'Sports Registration',
'trigger_event' => 'player.registered',
'message_template_ar' => 'مرحباً {player_name}، تم تسجيلك بنجاح في الأنشطة الرياضية. رقم التسجيل: {registration_serial}',
'message_template_en' => 'Hello {player_name}, you have been registered successfully. Registration #: {registration_serial}',
'variables_json' => json_encode(['player_name', 'registration_serial'], JSON_UNESCAPED_UNICODE),
],
[
'template_code' => 'SMS_SPORTS_SUB_DUE',
'name_ar' => 'استحقاق اشتراك النشاط الرياضي',
'event_trigger' => 'activity_sub.generated',
'message_template' => 'عزيزي {player_name}، اشتراك شهر {month} بمبلغ {amount} ج.م مستحق. الرجاء السداد قبل {due_date}',
'variables_json' => json_encode(['player_name', 'month', 'amount', 'due_date'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_SPORTS_SUB_DUE',
'name_ar' => 'استحقاق اشتراك النشاط الرياضي',
'name_en' => 'Activity Subscription Due',
'trigger_event' => 'activity_sub.generated',
'message_template_ar' => 'عزيزي {player_name}، اشتراك شهر {month} بمبلغ {amount} ج.م مستحق. الرجاء السداد قبل {due_date}',
'message_template_en' => 'Dear {player_name}, subscription for {month} of {amount} EGP is due. Please pay before {due_date}',
'variables_json' => json_encode(['player_name', 'month', 'amount', 'due_date'], JSON_UNESCAPED_UNICODE),
],
[
'template_code' => 'SMS_SPORTS_SUB_OVERDUE',
'name_ar' => 'تأخر اشتراك النشاط الرياضي',
'event_trigger' => 'activity_sub.overdue',
'message_template' => 'تنبيه: اشتراك {player_name} لشهر {month} متأخر. المبلغ: {amount} ج.م. سيتم إيقاف الكارنيه في حالة عدم السداد',
'variables_json' => json_encode(['player_name', 'month', 'amount'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_SPORTS_SUB_OVERDUE',
'name_ar' => 'تأخر اشتراك النشاط الرياضي',
'name_en' => 'Activity Subscription Overdue',
'trigger_event' => 'activity_sub.overdue',
'message_template_ar' => 'تنبيه: اشتراك {player_name} لشهر {month} متأخر. المبلغ: {amount} ج.م. سيتم إيقاف الكارنيه في حالة عدم السداد',
'message_template_en' => 'Alert: {player_name} subscription for {month} is overdue. Amount: {amount} EGP. Card will be suspended if unpaid',
'variables_json' => json_encode(['player_name', 'month', 'amount'], JSON_UNESCAPED_UNICODE),
],
[
'template_code' => 'SMS_SPORTS_CARD_REVOKED',
'name_ar' => 'إيقاف كارنيه النشاط الرياضي',
'event_trigger' => 'player.card_revoked',
'message_template' => 'تم إيقاف كارنيه النشاط الرياضي للاعب {player_name} بسبب عدم سداد الاشتراك. للاستفسار: اتصل بإدارة النادي',
'variables_json' => json_encode(['player_name'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_SPORTS_CARD_REVOKED',
'name_ar' => 'إيقاف كارنيه النشاط الرياضي',
'name_en' => 'Activity Card Revoked',
'trigger_event' => 'player.card_revoked',
'message_template_ar' => 'تم إيقاف كارنيه النشاط الرياضي للاعب {player_name} بسبب عدم سداد الاشتراك. للاستفسار: اتصل بإدارة النادي',
'message_template_en' => 'Activity card for {player_name} has been revoked due to unpaid subscription. Contact club administration for inquiries',
'variables_json' => json_encode(['player_name'], JSON_UNESCAPED_UNICODE),
],
[
'template_code' => 'SMS_RESERVATION_CONFIRMED',
'name_ar' => 'تأكيد حجز ملعب',
'event_trigger' => 'reservation.confirmed',
'message_template' => 'تم تأكيد حجز {facility_name} بتاريخ {date} من {start_time} إلى {end_time}. رقم الحجز: {reservation_number}',
'variables_json' => json_encode(['facility_name', 'date', 'start_time', 'end_time', 'reservation_number'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_RESERVATION_CONFIRMED',
'name_ar' => 'تأكيد حجز ملعب',
'name_en' => 'Reservation Confirmed',
'trigger_event' => 'reservation.confirmed',
'message_template_ar' => 'تم تأكيد حجز {facility_name} بتاريخ {date} من {start_time} إلى {end_time}. رقم الحجز: {reservation_number}',
'message_template_en' => 'Reservation confirmed for {facility_name} on {date} from {start_time} to {end_time}. Ref: {reservation_number}',
'variables_json' => json_encode(['facility_name', 'date', 'start_time', 'end_time', 'reservation_number'], JSON_UNESCAPED_UNICODE),
],
[
'template_code' => 'SMS_RESERVATION_REMINDER',
'name_ar' => 'تذكير بحجز ملعب',
'event_trigger' => 'reservation.reminder',
'message_template' => 'تذكير: لديك حجز {facility_name} غداً {date} الساعة {start_time}. رقم الحجز: {reservation_number}',
'variables_json' => json_encode(['facility_name', 'date', 'start_time', 'reservation_number'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_RESERVATION_REMINDER',
'name_ar' => 'تذكير بحجز ملعب',
'name_en' => 'Reservation Reminder',
'trigger_event' => 'reservation.reminder',
'message_template_ar' => 'تذكير: لديك حجز {facility_name} غداً {date} الساعة {start_time}. رقم الحجز: {reservation_number}',
'message_template_en' => 'Reminder: You have a reservation at {facility_name} tomorrow {date} at {start_time}. Ref: {reservation_number}',
'variables_json' => json_encode(['facility_name', 'date', 'start_time', 'reservation_number'], JSON_UNESCAPED_UNICODE),
],
[
'template_code' => 'SMS_MEDICAL_EXPIRY',
'name_ar' => 'تنبيه انتهاء الشهادة الطبية',
'event_trigger' => 'player.medical_expiry',
'message_template' => 'تنبيه: شهادتك الطبية ستنتهي بتاريخ {expiry_date}. يرجى تجديدها لاستمرار التسجيل في الأنشطة الرياضية',
'variables_json' => json_encode(['player_name', 'expiry_date'], JSON_UNESCAPED_UNICODE),
'template_code' => 'SMS_MEDICAL_EXPIRY',
'name_ar' => 'تنبيه انتهاء الشهادة الطبية',
'name_en' => 'Medical Certificate Expiry',
'trigger_event' => 'player.medical_expiry',
'message_template_ar' => 'تنبيه: شهادتك الطبية ستنتهي بتاريخ {expiry_date}. يرجى تجديدها لاستمرار التسجيل في الأنشطة الرياضية',
'message_template_en' => 'Alert: Your medical certificate expires on {expiry_date}. Please renew to continue sports activities',
'variables_json' => json_encode(['player_name', 'expiry_date'], JSON_UNESCAPED_UNICODE),
],
];
......@@ -64,14 +78,16 @@ return function (Database $db): void {
continue;
}
$db->insert('sms_templates', [
'template_code' => $t['template_code'],
'name_ar' => $t['name_ar'],
'event_trigger' => $t['event_trigger'],
'message_template' => $t['message_template'],
'variables_json' => $t['variables_json'],
'is_active' => 1,
'created_at' => $ts,
'updated_at' => $ts,
'template_code' => $t['template_code'],
'name_ar' => $t['name_ar'],
'name_en' => $t['name_en'],
'trigger_event' => $t['trigger_event'],
'message_template_ar' => $t['message_template_ar'],
'message_template_en' => $t['message_template_en'],
'variables_json' => $t['variables_json'],
'is_active' => 1,
'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