# Deposit Policy In Main Enrollment

## What changed

تم تفعيل سياسة العربون داخل مسار التسجيل الرئيسي (`Enrollment flow`) مع أقل تعديل ممكن ودون المساس بمسار `pre-enrollment`.

الآن عند اختيار طريقة الدفع في التسجيل العام:

- يقرأ النظام سياسة الدفع من الفوج (`course_sessions`)
- مصدر الحقيقة للحساب أصبح `BillingPlanFactory::quoteForCourseSession()`
- يحسب:
  - `total_amount_dzd`
  - `deposit_required_dzd`
  - `balance_due_dzd`
- يحفظ snapshot ثابتًا على `enrollments`
- ينشئ `payment` أولى بالمبلغ المطلوب الآن فقط:
  - `purpose = deposit` إذا كان هناك رصيد لاحق
  - `purpose = full` إذا كانت السياسة دفعًا كاملاً

## Snapshot fields on enrollments

أضيفت الحقول التالية إلى `enrollments`:

- `total_amount_dzd`
- `deposit_required_dzd`
- `deposit_paid_dzd`
- `balance_due_dzd`
- `payment_stage`
- `balance_due_at`

هذه الحقول تحفظ الأرقام كما كانت عند التسجيل، حتى لو تغيّرت سياسة الفوج لاحقًا.

## Payment purpose

أضيف إلى `payments`:

- `purpose = deposit | balance | full`

الهدف من ذلك:

- تمييز دفعة العربون عن الدفعة الكاملة
- تجهيز النظام لاحقًا لإدخال `balance` بدون إعادة بناء منطق الدفع كله

## Confirmation behavior

عند اعتماد/تأكيد أول دفعة:

- إذا كانت `purpose = deposit`
  - يصبح التسجيل `confirmed`
  - يصبح `payment_stage = deposit_paid`
  - يبقى `balance_due_dzd` محفوظًا كرصيد لاحق

- إذا كانت `purpose = full`
  - يصبح التسجيل `confirmed`
  - يصبح `payment_stage = fully_paid`
  - يصبح `balance_due_dzd = 0`

## UI

واجهة اختيار الدفع تعرض الآن بوضوح:

- المبلغ الإجمالي
- تدفع الآن (العربون)
- المتبقي لاحقًا
- نسبة العربون عندما تكون السياسة بالنسبة المئوية

كما تم توحيد نفس الـ breakdown داخل:

- `ChoosePaymentPage`
- `RegistrationStepper` (خطوة اختيار الدفع والـ sidebar)

كما تعرض لوحة الإدارة في تفاصيل التسجيل:

- الإجمالي
- العربون المطلوب
- المتبقي
- مرحلة الدفع

## Current scope

هذا التعديل يفعّل العربون في **التسجيل العام فقط**.

لم يتم في هذه المرحلة:

- تعديل `pre-enrollment`
- بناء balance collection flow كامل
- إنشاء دفعات balance تلقائيًا في كل الحالات

لكن الكود أصبح جاهزًا لذلك بوجود:

- enrollment snapshot
- payment purpose
- payment stage progression

## Policy resolution rules

حاليًا يحل النظام سياسة الدفعة الأولى بهذا الترتيب:

1. `distance_full_upfront` => يدفع كامل المبلغ الآن
2. `deposit_fixed_dzd` إذا كان مضبوطًا على الفوج => يدفع المبلغ الثابت الآن
3. سياسات العربون المعتمدة بالنسبة (`deposit_percent`) => يحسب العربون من السعر النهائي للفوج
4. إذا غابت السياسة أو كانت غير صالحة => fallback إلى `full` مع `warning` في logs

## Files touched conceptually

- pricing snapshot on `Enrollment`
- first payment creation in `SelectPaymentMethod*`
- approval sync in `PaymentStateMachine` + `PaymentObserver` + `SyncEnrollmentAfterPaymentConfirmed`
- public payment summary UI
- admin registration detail breakdown

## Verification

تمت تغطية التعديل باختبارات رجوعية تشمل:

- cohort policy 10% => first payment is deposit
- full upfront => first payment is full
- deposit approval confirms enrollment
- snapshot remains stable if cohort policy changes later
