# 05 — الحضور والغياب

## نظرة عامة

نظام الحضور يتتبع حضور المشتركين والمدربين في كل حصة تدريبية. يتكون من:
1. **توليد تلقائي** — عند إنشاء حصة، تُنشأ سجلات "متوقع" لكل مشترك/مدرب
2. **تسجيل يدوي** — المدرب أو الإدارة يسجّل الحضور فعلياً
3. **غياب تلقائي** — بعد انتهاء الحصة بساعتين، المتوقعون يُحوّلون لـ "غائب"
4. **إنفاذ** — 5 غيابات متتالية = إيقاف تلقائي

---

## الشاشات المنفذة

### 1. قائمة الحضور (`/attendance`)

**من يراها:** من لديه صلاحية `attendance.list`

**الفلاتر:**
- بحث بالاسم
- تصفية بالمجموعة
- تصفية بالتاريخ
- تصفية بالحالة

**أعمدة الجدول:**
| العمود | الوصف |
|--------|-------|
| الاسم | اسم المشترك/المدرب |
| النوع | مشترك أو مدرب |
| الحصة | تاريخ ووقت الحصة |
| المجموعة | اسم المجموعة |
| الحالة | شارة ملونة |
| وقت الحضور الفعلي | actual_check_in |
| دقائق التأخير | late_minutes |
| ملاحظات | notes |

---

### 2. تسجيل حضور حصة (`/attendance/{session}`)

**من يراها:** من لديه صلاحية `attendance.mark`

**الوصف:** شاشة تعرض جميع السجلات المتوقعة لحصة معينة مع أزرار تسجيل الحضور.

**المعلومات:**
- اسم المجموعة
- التاريخ والوقت
- المدرب
- ملاحظات الحصة (قابلة للتعديل)

**لكل سجل:**
| العنصر | الوصف |
|--------|-------|
| اسم المشترك/المدرب | + صورة إن وُجدت |
| الحالة الحالية | شارة ملونة |
| أزرار التغيير | حاضر، متأخر، غائب، مستأذن، جزئي |
| ملاحظة فردية | حقل نص — يُحفظ منفرداً |

**الأزرار العامة:**
- "الكل حاضر" — يسجّل حضور كل المتوقعين دفعة واحدة
- حفظ ملاحظات الحصة

**السلوك عند تسجيل "حاضر":**
1. وقت الحضور الفعلي = الآن
2. إذا الوقت الحالي > وقت بدء الحصة + فترة السماح → "متأخر" تلقائياً
3. يُحسب `late_minutes`

```mermaid
flowchart TD
    A[المدرب يضغط 'حاضر'] --> B{الوقت الحالي}
    B -->|قبل أو خلال فترة السماح| C[حالة: حاضر]
    B -->|بعد فترة السماح| D[حالة: متأخر]
    D --> E[حساب دقائق التأخير]
    C --> F[تسجيل actual_check_in = now]
    E --> F
```

---

### 3. تسجيل حضور سريع (`/attendance/quick`)

**من يراها:** من لديه صلاحية `attendance.mark`

**الوصف:** واجهة مختصرة لتسجيل الحضور بسرعة — اختيار الحصة ثم التسجيل.

**مناسبة لـ:** المدرب الذي لديه عدة حصص في اليوم ويريد تسجيل سريع.

---

### 4. لوحة المدرب (`/trainer`)

**من يراها:** المدرب ورئيس المدربين

**المحتوى:**
- حصص اليوم الخاصة بهذا المدرب
- زر "تسجيل الحضور" لكل حصة
- ملخص: كم حصة اليوم، كم مشترك، كم أنهيت

---

## حالات الحضور (10 حالات)

```mermaid
stateDiagram-v2
    [*] --> متوقع : عند إنشاء الحصة
    متوقع --> حاضر : تسجيل حضور
    متوقع --> متأخر : حضور بعد فترة السماح
    متوقع --> مستأذن : إذن مسبق
    متوقع --> غائب : تلقائي بعد ساعتين أو يدوي
    متوقع --> لم_يحضر : غياب بدون إخطار
    متوقع --> انصرف_مبكراً : حضر ثم غادر
    متوقع --> جزئي : حضر جزء من الحصة
    متوقع --> ملغى : الحصة أُلغيت
    متوقع --> معفى : إعفاء خاص
```

| الحالة | بالإنجليزية | المعنى | يُحسب إيجاباً؟ |
|--------|------------|--------|----------------|
| متوقع | expected | لم يُسجّل بعد | — |
| حاضر | present | حضر في الموعد | ✓ |
| متأخر | late | حضر بعد فترة السماح | ✓ |
| مستأذن | excused | إذن مسبق (مرض، ظرف) | لا يُحسب |
| غائب | absent | لم يحضر | ✗ |
| لم يحضر | no_show | غياب بدون إخطار مسبق | ✗ |
| انصرف مبكراً | left_early | حضر ثم غادر | يعتمد |
| جزئي | partial | حضر جزء | ✓ |
| ملغى | cancelled | الحصة ملغاة | لا يُحسب |
| معفى | exempt | إعفاء خاص | لا يُحسب |

---

## فترات السماح (Grace Periods)

| الدور | الافتراضي | قابل للتعديل |
|-------|-----------|-------------|
| مشتركين | 15 دقيقة | ✓ (إعدادات النظام) |
| مدربين | 10 دقائق | ✓ (إعدادات النظام) |

**مثال:**
> الحصة تبدأ 16:00. فترة السماح 15 دقيقة.
> - حضور 16:14 → "حاضر"
> - حضور 16:16 → "متأخر" + late_minutes = 16

---

## الغياب التلقائي

**المهمة المجدولة:** `attendance:auto-absent` (كل ساعة)

**الآلية:**
```
السجلات حيث:
- الحالة = "متوقع"
- وقت انتهاء الحصة + ساعتين < الآن
- لم يُسجّل يدوياً

→ تُحوّل إلى "غائب"
→ تُعلّم كـ "يحتاج مراجعة إدارية"
```

---

## إنفاذ حدود الحضور

**المهمة المجدولة:** `attendance:enforce-thresholds` (يومياً 06:00)

**القواعد:**

### 1. غيابات متتالية (افتراضي: 5)
```
إذا آخر 5 سجلات متتالية = "غائب" أو "لم يحضر"
→ المشترك يُوقف تلقائياً (status → suspended)
→ إشعار لولي الأمر
→ إشعار للإدارة
```

### 2. نسبة حضور أقل من الحد (افتراضي: 75%)
```
إذا نسبة الحضور < 75%
→ إشعار تحذيري لولي الأمر
→ إشعار للإدارة
→ لا يُوقف (تحذير فقط)
```

```mermaid
flowchart TD
    A[مهمة يومية 06:00] --> B[لكل مشترك نشط]
    B --> C{5 غيابات متتالية؟}
    C -->|نعم| D[إيقاف تلقائي]
    D --> E[إشعار ولي الأمر]
    D --> F[إشعار الإدارة]
    C -->|لا| G{نسبة الحضور < 75%؟}
    G -->|نعم| H[إشعار تحذيري]
    G -->|لا| I[لا إجراء]
```

---

## تنبيهات الحضور

**المهمة المجدولة:** `attendance:send-alerts` (يومياً 20:00)

**الوصف:** إرسال تنبيهات لأولياء الأمور عن حضور/غياب أبنائهم اليوم.

---

## توليد سجلات الحضور

**متى يحدث:**
1. عند إنشاء حصة جديدة (يومياً بواسطة session generator)
2. عند تفعيل اشتراك جديد (لجميع الحصص المستقبلية)
3. عند إنشاء تعيين مدرب جديد

**ماذا يُولّد:**
- سجل واحد لكل مشترك نشط في المجموعة
- سجل واحد لكل مدرب مُعيّن للمجموعة/الحصة
- الحالة الابتدائية: "expected"

**متى تُحذف:**
- عند إلغاء اشتراك (حصص مستقبلية فقط — الماضي يبقى)
- عند إلغاء حصة (جميع سجلاتها → "cancelled")
- عند إنهاء تعيين مدرب

---

## معادلة نسبة الحضور

```
نسبة الحضور = (حاضر + متأخر + جزئي) ÷ (الإجمالي - ملغى - معفى) × 100
```

**ملاحظات:**
- "مستأذن" (excused) لا يُحسب لا إيجاباً ولا سلباً
- "غائب" و"لم يحضر" يُحسبان سلباً
- "ملغى" و"معفى" يُستبعدان من القسمة

---

## تقرير الحضور (`/reports/attendance`)

**من يراها:** من لديه صلاحية `reports.attendance`

**الفلاتر:**
- الفترة الزمنية (من - إلى)
- المجموعة
- المشترك
- المدرب

**المخرجات:**
- نسبة الحضور لكل مشترك
- عدد أيام الغياب
- عدد أيام التأخير
- ترتيب حسب الحضور

---

## دورة الحضور الكاملة

```mermaid
sequenceDiagram
    participant Job as مهمة مجدولة
    participant S as النظام
    participant T as المدرب
    participant G as ولي الأمر

    Job->>S: توليد حصة يوم السبت 16:00
    S->>S: إنشاء 18 سجل حضور "متوقع"

    Note over T: يوم السبت 15:55 - المدرب يبدأ

    T->>S: فتح شاشة تسجيل الحضور
    S-->>T: قائمة 18 مشترك (كلهم "متوقع")
    T->>S: "أحمد" → حاضر (15:58)
    S->>S: قبل فترة السماح → "حاضر"
    T->>S: "سارة" → حاضر (16:18)
    S->>S: بعد فترة السماح → "متأخر" + 18 دقيقة
    T->>S: "محمد" → مستأذن (مريض)
    S->>S: حالة: "مستأذن"
    T->>S: الباقي لم يأتوا

    Note over S: بعد ساعتين (18:00)
    Job->>S: مهمة الغياب التلقائي
    S->>S: من بقي "متوقع" → "غائب"

    Note over S: اليوم التالي 06:00
    Job->>S: فحص حدود الحضور
    S->>S: "خالد" — 5 غيابات متتالية!
    S->>S: إيقاف "خالد" تلقائياً
    S->>G: إشعار: ابنك أُوقف بسبب الغياب
```

---

## أمثلة عملية

### مثال 1: مدرب يسجّل حضور مجموعة 15 مشترك
> 1. يفتح `/trainer` → يرى حصته الساعة 16:00
> 2. يضغط "تسجيل الحضور"
> 3. يرى 15 اسم (كلهم "متوقع")
> 4. يضغط "الكل حاضر" ← 15 سجل → "حاضر"
> 5. يُعدّل "محمد" إلى "غائب" لأنه لم يأتِ
> 6. يُعدّل "سارة" إلى "مستأذن" (قال والدها مريضة)
> 7. النتيجة: 13 حاضر، 1 غائب، 1 مستأذن

### مثال 2: تأخير مع حساب الدقائق
> - الحصة تبدأ 16:00، فترة السماح 15 دقيقة
> - "عمر" يُسجّل حضوره 16:25
> - النظام: حالة = "متأخر"، late_minutes = 25

### مثال 3: حصة ملغاة
> 1. المدير يُلغي حصة الأربعاء (بسبب المطر)
> 2. جميع سجلات الحضور → "ملغى"
> 3. لا تؤثر على نسبة الحضور
> 4. إشعار للمشتركين وأولياء الأمور

### مثال 4: إيقاف تلقائي
> - "خالد" غاب 5 حصص متتالية (سبت، اثنين، أربعاء، سبت، اثنين)
> - المهمة المجدولة تكتشف ذلك
> - حالة المشترك → "موقوف"
> - رسالة لوالده: "تم إيقاف خالد مؤقتاً بسبب الغياب المتكرر. يرجى التواصل مع الإدارة."
> - للعودة: يجب أن يتواصل ولي الأمر ويُرفع الإيقاف يدوياً

### مثال 5: مشترك حضوره 60% (تحذير)
> - نسبة الحضور الأدنى = 75%
> - "لينا" حضرت 9 من 15 حصة = 60%
> - رسالة تحذيرية لولي الأمر: "نسبة حضور لينا أقل من الحد المطلوب"
> - لا يُوقف — فقط تحذير

---

## لماذا يحتاج عملك هذا

| الميزة | الفائدة |
|--------|---------|
| توليد تلقائي | لا حاجة لإنشاء سجلات يدوياً لكل مشترك |
| الغياب التلقائي | لا يُنسى أحد — إذا المدرب لم يسجّل، النظام يُغيّب الجميع بعد ساعتين |
| الإيقاف التلقائي | يحفّز الالتزام بدون تدخل يدوي يومي |
| التنبيهات | ولي الأمر يعرف فوراً إذا ابنه لم يحضر |
| نسبة الحضور | مؤشر واضح لكل مشترك — يُستخدم في التقييم والشهادات |
| فترة السماح | عدالة — تأخير 5 دقائق لا يُعتبر غياب |
| سجل التأخير | يكشف الأنماط (هل هذا المشترك دائماً متأخر؟) |

---

## التكاملات

| الوحدة | العلاقة |
|--------|---------|
| البرامج والمجموعات | الحصة مصدر سجلات الحضور |
| التسجيل | تفعيل/إلغاء اشتراك → توليد/حذف سجلات |
| المشتركين | الإيقاف التلقائي يغيّر حالة المشترك |
| التعيينات | تعيين مدرب → سجل حضور للمدرب |
| الإشعارات | تنبيهات لأولياء الأمور والإدارة |
| التقارير | تقرير حضور شامل |
| الشهادات | نسبة الحضور تظهر في شهادة المشترك |
| الموارد البشرية | حضور المدرب → حساب المكافأة |
