Commit 6b176d1f authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix(migrations): make idempotent + add discounts tutorial

- 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: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 8cf88598
<?php
declare(strict_types=1);
return [
'up' => "
ALTER TABLE workflow_instances ADD COLUMN created_by BIGINT UNSIGNED NULL AFTER completed_at;
ALTER TABLE workflow_transition_log ADD COLUMN created_by BIGINT UNSIGNED NULL AFTER created_at
",
'down' => "
ALTER TABLE workflow_instances DROP COLUMN created_by;
ALTER TABLE workflow_transition_log DROP COLUMN created_by
",
];
return function (\App\Core\Database $db): void {
$exists = $db->selectOne(
"SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'workflow_instances' AND column_name = 'created_by'"
);
if (!$exists) {
$db->raw("ALTER TABLE workflow_instances ADD COLUMN created_by BIGINT UNSIGNED NULL AFTER completed_at");
}
$exists2 = $db->selectOne(
"SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'workflow_transition_log' AND column_name = 'created_by'"
);
if (!$exists2) {
$db->raw("ALTER TABLE workflow_transition_log ADD COLUMN created_by BIGINT UNSIGNED NULL AFTER created_at");
}
};
<?php
declare(strict_types=1);
return [
'up' => "ALTER TABLE violations ADD COLUMN proof_file VARCHAR(255) NULL AFTER evidence_notes",
'down' => "ALTER TABLE violations DROP COLUMN proof_file",
];
return function (\App\Core\Database $db): void {
$exists = $db->selectOne(
"SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'violations' AND column_name = 'proof_file'"
);
if (!$exists) {
$db->raw("ALTER TABLE violations ADD COLUMN proof_file VARCHAR(255) NULL AFTER evidence_notes");
}
};
# العروض والتخفيضات في السيستم — دليل خطوة بخطوة
## 1. إنشاء خصم خاص (التعريف)
**المسار:** القائمة الجانبية ← **التسعير****الخصومات الخاصة**
أو مباشرة: `/pricing/special-discounts`
1. اضغط **"إنشاء خصم جديد"**
2. املأ البيانات:
- **اسم الخصم** (مثال: "خصم أبناء شهداء")
- **النوع**: نسبة مئوية / مبلغ ثابت / سنوات مجانية
- **النسبة أو المبلغ**
- **الشروط**: تاريخ بداية ونهاية، فرع معين، يحتاج مستند إثبات أم لا
- **سنوات مجانية** (bonus): عدد السنوات التي يُعفى فيها العضو من الاشتراك السنوي
3. احفظ ← الخصم يظهر في القائمة ويمكن تفعيله/تعطيله
---
## 2. تطبيق الخصم على عضو
**المسار:** الأعضاء ← اختر العضو ← صفحة العضو
1. افتح صفحة العضو (`/members/{id}`)
2. ابحث عن قسم **"خصم خاص"** (يظهر فقط إذا كان العضو في حالة `accepted` أو `payment_pending`)
3. اختر الخصم من القائمة المنسدلة
4. إذا كان يحتاج مستند ← ارفع ملف الإثبات
5. اضغط **"تطبيق الخصم"**
6. يظهر ✅ باسم الخصم والمبلغ المخصوم — ويمكنك إزالته بزر ❌
---
## 3. عروض مجلس الإدارة (Board Offers)
**الملف:** `app/Modules/Members/Services/BoardOfferService.php`
هذه عروض تُطبق **تلقائياً** على جميع الأعضاء المستوفين خلال فترة العرض.
- تُخزن في جدول `board_offers`
- تحتوي على: رقم القرار، تاريخ القرار، نوع العرض (خصم نقدي / خصم اشتراك / تغيير أقساط)
- تُطبق تلقائياً أثناء الفوترة (عبر `BillingService`)
> ملاحظة: حالياً لا يوجد UI لإدارة عروض مجلس الإدارة — يتم إدخالها في الداتابيز مباشرة.
---
## 4. خصومات الاشتراكات السنوية (سنوية تلقائية)
**المسار:** القائمة الجانبية ← **التسعير****لوحة التسعير** (`/pricing`)
- في لوحة التسعير، يمكنك ضبط **نسبة تعديل سنوية** لكل سنة مالية (مثلاً: خصم 50% لسنة 2023/2024)
- تُطبق تلقائياً عند توليد الاشتراكات السنوية عبر `SubscriptionGenerator`
- يتم تعريفها كـ Rule Engine key: `SUBSCRIPTION_YEAR_ADJUSTMENT_2024_2025`
---
## 5. خصومات الأنشطة الرياضية (الأكاديميات)
تُطبق تلقائياً عند التسجيل في الأكاديميات:
- **خصم الدفع المقدم**: دفع 3+ شهور مقدماً = 15%
- **خصم الأشقاء**: أخ/أخت مسجل في نفس النشاط = خصم محدد
هذه تُدار من جدول `sa_discount_rules` ولا تحتاج تدخل يدوي.
---
## 6. خصومات العضوية الموسمية
تُطبق تلقائياً عند إنشاء عضوية موسمية:
- **خصم عائلي** (أكثر من شخص في نفس العائلة)
- **خصم بدون مؤهل**: 10%
- **خصم عضو مؤهل**: 20%
---
## ملخص المسارات
| العملية | المسار في السيستم |
|---------|------------------|
| إدارة الخصومات الخاصة | التسعير ← الخصومات الخاصة |
| تطبيق خصم على عضو | صفحة العضو ← قسم "خصم خاص" |
| خصومات سنوية (rate adjustment) | التسعير ← لوحة التسعير |
| عروض مجلس الإدارة | (تلقائية — لا يوجد UI حالياً) |
| خصومات الأكاديميات | (تلقائية عند التسجيل) |
| خصومات الموسمي | (تلقائية عند الإنشاء) |
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