تصميم أول Feature في الـ HIS — مبني على فكرتك
ملف المريض + الحجز + الخدمات والتسعير وعمولات الأطباء
تحويل فكرتك لتصميم ملموس: ملف مريض كبير قابل للإخفاء لكل مركز، وشاشة حجز تبدأ بالمريض ثم الخدمات (كشف → تخصص → دكتور → قيمة)، مع محرّك تسعير وعمولات أطباء.
2026-06-15 · Feature 1 of Moon ERP HIS · يكمّل his-module-blueprint.html
- ملف المريض أساسي وكبير، فيه كل البيانات الممكنة، مع إعدادات لكل مركز تخفي/تظهر أي حقل.
- النظام يشتغل لـ عيادة واحدة أو عدة عيادات أو مستشفى (بعمليات وكل حاجة) — نفس النظام، إعدادات مختلفة.
- نبدأ بالحجز/الزيارة: أضف/اختر مريض → اختر خدمة (أو أكثر) من الخدمات المرتبطة بالعيادات الخارجية.
- مثال "كشف": اختياره يطلّع التخصصات → اختيار تخصص يطلّع الأطباء → اختيار الدكتور → قيمة الكشف.
- إعدادات الخدمات: الخدمة لها اسم + نوع. النوع "عيادات" يربطها بالتخصصات. التسعير: سعر موحّد أو سعر لكل دكتور.
- عمولة الدكتور: لكل دكتور في الخدمة — مبلغ كـ أساسي، مبلغ كـ مساعد، مبلغ على التحويل → لتوليد القيم المالية.
كل مركز = company_id (multi-tenant موجود أصلاً في Moon ERP) + جدول إعدادات his_center_settings يحدّد الوضع والميزات المفعّلة. ده اللي بيخلّي نفس النظام يخدم عيادة صغيرة أو مستشفى.
| الإعداد | القيم / المثال |
mode | single_clinic multi_clinic hospital |
features (JSON) | {opd:true, ipd:false, or:false, pharmacy:true, lab:true, insurance:true} — يظهر/يخفي موديولات كاملة |
branches | multi_clinic/hospital → عيادات/فروع متعددة تحت نفس المركز |
patient_profile_config | أي حقول في ملف المريض ظاهرة/مطلوبة (القسم التالي) |
ملف المريض فيه كل الحقول الممكنة مجمّعة في أقسام، لكن العرض metadata-driven: جدول his_field_configs لكل مركز يقول كل حقل ظاهر؟ مطلوب؟ ترتيبه؟ اسمه المخصّص؟ — فالمركز يقدر يخلّي الملف بسيط أو شامل.
| قسم الحقول | أمثلة (كلها قابلة للإخفاء لكل مركز) |
| الهوية الأساسية (دايماً ظاهر) | الاسم (ع/EN)، النوع، تاريخ الميلاد/العمر، الموبايل، MRN |
| الهوية الرسمية | الرقم القومي/الإقامة، الجنسية، نوع الإثبات |
| التواصل والعنوان | عناوين، مدينة، منطقة، إيميل، تواصل طوارئ |
| اجتماعي | الحالة الاجتماعية، المهنة، التعليم، بيانات الزوج/الزوجة (للنساء والتوليد) |
| طبي أساسي | فصيلة الدم، الحساسيات، الأمراض المزمنة، الأدوية الحالية |
| نساء وتوليد (اختياري) | تاريخ الطمث، G/P، تاريخ آخر دورة، الحمل الحالي |
| التأمين/الدافع | شركة التأمين، رقم البوليصة، الفئة، نسبة التحمّل |
| التسويق | مصدر المعرفة، الطبيب المحوِّل، ملاحظات |
الآلية: الملف يقرأ his_field_configs(company_id, field_key) → {visible, required, order, label}. الـ frontend يرسم الأقسام والحقول الظاهرة فقط ديناميكياً. شاشة إعدادات بسيطة (toggle لكل حقل) للمركز. كده ملف واحد شامل يخدم كل المراكز.
| الحقل | الشرح |
name_ar / name_en | اسم الخدمة (كشف، استشارة، سونار، إجراء…) |
service_type | consultation (عيادات) procedure lab radiology package — النوع يحدّد السلوك |
requires_specialty | لو النوع "عيادات" → true: يربط الخدمة بالتخصصات ويطلب اختيار تخصص ثم دكتور |
requires_doctor | هل الخدمة محتاجة اختيار دكتور (الكشف = نعم؛ بعض الإجراءات = لا) |
pricing_mode | flat (سعر موحّد) أو per_doctor (سعر لكل دكتور) |
default_price | السعر الافتراضي (يُستخدم في وضع flat، أو كمبدئي) |
linked_module | lab→LIS، radiology→RIS (الخدمة تطلّق طلب في الموديول المتكامل) |
منطق فكرتك بالظبط: الخدمة "كشف" نوعها consultation وrequires_specialty=true → في الحجز تطلّع التخصصات → اختيار تخصص يطلّع أطباءه → اختيار الدكتور يجيب القيمة (من pricing_mode).
أ — سعر الخدمة
- flat: الخدمة لها
default_price واحد بغض النظر عن الدكتور.
- per_doctor: جدول
his_service_doctor_pricing فيه سعر لكل (خدمة × دكتور). لما تختار الدكتور → القيمة تتجاب منه تلقائياً.
ب — عمولة الدكتور (للقيم المالية)
لكل (خدمة × دكتور) في نفس جدول التسعير، نحفظ ما يستحقه الدكتور — وده اللي يطلّع القيم المالية من الكشف:
| الدور | الحقل | المعنى |
| الطبيب الأساسي | primary_fee | ما يأخذه لو هو طبيب الكشف الأساسي |
| الطبيب المساعد | assistant_fee | ما يأخذه لو هو مساعد |
| على التحويل | referral_fee | ما يأخذه الطبيب المحوِّل عند تحويل المريض |
قابل للتوسّع: كل قيمة ممكن تكون مبلغ ثابت (زي ما وصفت) أو نسبة % من سعر الخدمة (fee_type: amount|percent) — عشان لو مركز يفضّل النسبة. الافتراضي مبلغ.
التكامل: سعر الخدمة → فاتورة في Accounting. عمولة الدكتور → نفس نمط LabDoctorCommission الموجود في موديول LIS (نعيد استخدام الفكرة) → تسوية عمولات دورية.
| # | الخطوة |
| 1 | المريض: بحث (اسم/موبايل/رقم قومي/MRN) → اختيار، أو "مريض جديد" (يفتح ملف المريض القابل للتهيئة) |
| 2 | إضافة خدمة: ابحث/اختر خدمة. لو نوعها consultation: |
| ↳ يظهر التخصص → اختياره يظهر قائمة الأطباء → اختيار الدكتور |
| ↳ القيمة تتعبّى تلقائياً (per_doctor → سعر الدكتور، flat → سعر الخدمة) — قابلة للتعديل بصلاحية |
| ↳ اختياري: طبيب مساعد + طبيب محوِّل (لحساب العمولات) |
| 3 | كرّر: أضف عدة خدمات (سلّة الخدمات) — كل سطر بقيمته |
| 4 | الإجمالي يتحسب، الدافع (نقدي/تأمين)، ثم حفظ الحجز |
| 5 | الحفظ يولّد: فاتورة (Accounting) + سطور عمولة لكل دكتور + المريض يدخل طابور العيادة |
سطر الحجز (كشف، تخصص=نساء، دكتور=د.أحمد، مساعد=د.سارة، محوِّل=د.خالد)
├─ سعر الخدمة = 300 (per_doctor: سعر د.أحمد) ───────► فاتورة المريض (Accounting)
└─ عمولات (snapshot وقت الحجز من جدول التسعير):
د.أحمد primary_fee = 180 ─┐
د.سارة assistant_fee = 40 ─┼──► سطور عمولة أطباء ──► تسوية دورية
د.خالد referral_fee = 30 ─┘ (نمط LabDoctorCommission)
صافي المركز = 300 − (180+40+30) = 50
مهم: القيم تتخزّن كـ snapshot وقت الحجز (مش reference حي) — عشان لو غيّرت الأسعار بعدين، الحجوزات القديمة تفضل بقيمها الصحيحة. (درس من تدقيق الموديولات: تجنّب الـ reference الحي للأسعار التاريخية).
— الهوية —
his_parties · his_patients(party_id, mrn) · his_practitioners(party_id, hrm_employee_id)
his_specialties(name_ar/en)
his_practitioner_specialty(practitioner_id, specialty_id) — دكتور ← تخصص
— إعدادات المركز وملف المريض —
his_center_settings(company_id, mode, features json)
his_field_configs(company_id, entity, field_key, visible, required, sort, label_override)
— الخدمات والتسعير —
his_services(company_id, name_ar/en, service_type, requires_specialty,
requires_doctor, pricing_mode[flat|per_doctor], default_price,
specialty_id?, linked_module?)
his_service_doctor_pricing(service_id, practitioner_id, price,
primary_fee, assistant_fee, referral_fee, fee_type[amount|percent])
— الحجز —
his_bookings(company_id, branch_id, patient_id, booking_date, status,
payer_type[cash|insurance], total, created_by)
his_booking_services(booking_id, service_id, specialty_id?, practitioner_id?,
assistant_id?, referring_doctor_id?, price,
doctor_primary_fee, doctor_assistant_fee, referral_fee) — snapshot
his_doctor_commissions(booking_service_id, practitioner_id, role, amount, settlement_id?)
ملاحظة: الحجز هنا = نقطة البداية اللي عند الـ check-in تتحوّل لـ encounter (الكشف الإكلينيكي) — زي ما في الـ blueprint الأساسي. فالـ booking-services بتغذّي الفوترة، والـ encounter بيغذّي السجل الطبي.
شاشة الحجز الجديد
حجز جديد / زيارةCtrl+S حفظ
🔍 المريض: بحث بالاسم/الموبايل/الرقم القومي… أو [+ مريض جديد]
المريض المختار: سارة محمد · ٢٨ سنة · MRN 10432 حساسية: بنسلين
+ إضافة خدمة: [كشف ▾]
التخصص: [نساء وتوليد ▾]
الدكتور: [د. أحمد ▾]
القيمة: 300
اختياري: مساعد [د. سارة ▾] · محوِّل [— ▾]
١· كشف نساء — د. أحمد (مساعد: د.سارة)
300
٢· سونار توليدي — د. أحمد
200
الإجمالي · الدافع: نقدي
500
شاشة إعدادات الخدمة + تسعير الأطباء
خدمة: كشف نساءنوع: عيادات
النوع: عيادات (consultation)
التخصص: نساء وتوليد
نمط التسعير: لكل دكتور
الدكتور
السعر
أساسي
مساعد
تحويل
الشاشتين يستخدموا الـ primitives من الـ blueprint: PatientBanner (مع الحساسية)، WorklistGrid لسلّة الخدمات وجدول التسعير، ScanInput للبحث، OnPush + keyboard.
| الخطوة | الشغل |
| ١ | الأساس: parties/patients/practitioners/specialties + MPI (بحث/إضافة مريض) + ملف المريض القابل للتهيئة + field_configs |
| ٢ | كتالوج الخدمات + إعداداتها + التخصصات + ربط الأطباء بالتخصصات |
| ٣ | محرّك التسعير: service_doctor_pricing (سعر + عمولات) + شاشة الإعداد |
| ٤ | شاشة الحجز: مريض → خدمات → تخصص → دكتور → قيمة → حفظ (snapshot) |
| ٥ | التكامل: فاتورة → Accounting، عمولات → نمط LabDoctorCommission، المريض → طابور العيادة |
الخطوة الجاية المقترحة: أعمل لك الـ migrations + Models + شاشة الحجز فعلياً (TDD) كأول feature شغّالة، أو نزوّد تفاصيل أكتر في أي جزء حابب.