ملاحظات شحن خدمة / منتج CRM
::: note ::: title ملاحظة :::
للحصول على دليل شامل يغطي تعريف المنتج، التوفير، الإضافات، وإلغاء التوفير مع أمثلة تفصيلية باستخدام Ansible واستراتيجية التسعير، راجع دليل دورة حياة المنتج الكامل. :::
نظرة عامة على المنتجات والخدمات
المنتج (عنصر القائمة):
المنتج يشبه طبقًا معينًا في قائمة مطعم، مثل "سباغيتي كاربونارا".
لديه وصف واضح، قائمة بالمكونات (مثل المعكرونة، الكريمة، البيض، الجبن، واللحم المقدد)، وسعر.
في OmniCRM، يحتوي المنتج بالمثل على تفاصيل ما هو متضمن --- الميزات، المواصفات، والتسعير.
غالبًا، قد يرغب العملاء في تعديلات، مثل "لا بصل" أو "أضف جبن إضافي" إلى وجبتهم. داخل OmniCRM، يتوافق هذا مع تخصيص خدمة قبل الإنشاء. مستوى التخصيصات أو التعديلات على الخدمة متروك لك (المشغل) لتعريفه.
في OmniCRM، قد يقوم العملاء أو الموظفون بتعديل منتج ليتناسب بشكل أفضل مع احتياجات عميل معين، مثل ترقية سرعة الإنترنت الخاصة بهم أو إضافة ميزات معينة. يتم عكس هذا التخصيص في الخدمة المحددة المقدمة.
المنتج هو في الأساس عرض يمكن للعملاء اختياره للطلب منه، مشابه لقراءة واختيار طبق من القائمة.

كتالوج المنتجات (قائمة المطعم):
كتالوج المنتجات يشبه القائمة الكاملة في مطعم، التي تسرد جميع الأطباق المتاحة --- من المقبلات إلى الحلويات.
إنه المجموعة الكاملة لكل ما يقدمه المطعم (أو في حالتك، مزود الخدمة).
في سياق الأعمال، يوفر كتالوج المنتجات للعملاء جميع المنتجات المتاحة، حتى يتمكنوا من اختيار ما ين��سب احتياجاتهم بشكل أفضل.


الخدمة (الطبق المحضر):
عندما يطلب عميل عنصرًا من القائمة، يتم تحضير الطبق في المطبخ. هذا يشبه إنشاء خدمة من منتج.
في OmniCRM، عندما يختار عميل منتجًا، يتم إنشاء نسخة من ذلك المنتج وتسليمه كخدمة.
يتم تخصيصه وتحضيره خصيصًا لذلك العميل، تمامًا مثل وجبة تم إعدادها لزبون.
على سبيل المثال، عندما يختار شخص ما "خطة الإنترنت البرونزية" من كتالوج المنتجات، يقوم نظام التوفير "بطهي" نسخة من تلك الخطة من المكونات (عناوين IP، المودمات والمنافذ) --- أي، ينشط الخطة ويسلمها إلى العميل المحدد.
المنتجات المجمعة (وجبات كومبو):
قد يقدم كتالوج المنتجات أيضًا حزم، مثل وجبة كومبو تشمل مقبلات، طبق رئيسي، وحلوى معًا بسعر خاص.
في OmniCRM، تجمع المنتجات المجمعة بين عدة منتجات فردية في حزمة مريحة واحدة --- مثل "حزمة مستلزمات المنزل" التي تشمل خدمات الإنترنت، الكابل، والهاتف بسعر مخفض.
بمجرد اختيارها، تتحول هذه الحزمة إلى خدمات متعددة مصممة خصيصًا للعميل.
تعريفات المنتجات
المنتج هو قالب يُستخدم لإنشاء خدمة / إضافة / خصم / ملحق، إلخ.
داخل التعريف ندرج:
-
معلومات حول المنتج (الميزات، المكونات، الشروط والأحكام، مدة العقد، الرمز، إلخ) التي يتم عرضها على مستخدم CRM (العميل أو الموظف).
-
المنطق التجاري حول من يمكنه شراء المنتج (تجاري أو سكني)، إذا كان يعتمد على وجود خدمة رئيسية موفرة (مثل الإضافات المحمولة المتاحة فقط للعملاء الذين لديهم خدمة محمولة)، إذا كان يمكن طلبه مباشرة من قبل عميل عبر الرعاية الذاتية أو فقط من قبل وكيل خدمة العملاء، ومتى يمكن شراء المنتج (السماح لمنتج بأن يكون متاحًا فقط لفترة زمنية محددة).
-
عند تضمين عناصر المخزون (مثل المودمات أو بطاقات SIM) يتم تحديدها كقائمة عناصر المخزون، على سبيل المثال الخدمة أدناه تتطلب بطاقة SIM ورقم هاتف ليتم تعيينه:
['SIM Card', 'Phone Number']هذه تتوافق مع عناصر المخزون المعرفة في CRM. -
الإشارة إلى كتاب Ansible لتوفير الخدمة لعب التوفير بالإضافة إلى المتغيرات التي يجب تمريرها إلى Ansible. هذه المتغيرات التي يجب تمريرها سحرية، حيث قد تكون متغيرات مثل
service_idالتي يتم تعريفها بواسطة المنتج الذي نضيفه إليه، أو قد تكون مثلICCIDوMSISDNحيث اخترنا عناصر المخزون التي يتم تمريرها عند تعيين المخزون. يتم التعامل مع التجميع في لعب التوفير لاحتواء خدمات متعددة، على سبيل المثال، قد توفر منتج إنترنت منزلي مجمع، تلفاز وصوت، خدم�� لكل منها.

فئات المنتجات وأنواع الخدمات
تستخدم المنتجات حقلين تصنيفيين للمساعدة في تنظيم وتصنيف العروض:
فئات المنتجات
يحدد حقل category مكان عرض المنتجات في واجهة المستخدم.
تشمل القيم الشائعة:
- مستقل - يظهر كخيار خدمة أساسي عند إنشاء خدمة جديدة
- إضافة - يظهر عند الإضافة إلى خدمة موجودة
- حزمة - يظهر كخيار خدمة مجمعة (موفرة مثل إضافة للخدمات الموجودة)
- ترويج - عروض ترويجية خاصة
هذه الفئات تنظيمية بحتة ولا تحدد ما يتم
توفيره. يتم تحديد سلوك التوفير الفعلي بالكامل بواسطة
كتاب Ansible المشار إليه في provisioning_play.
على سبيل المثال: - عادةً ما ينشئ منتج مستقل كائن خدمة جديدة - عادةً ما تتم إضافة منتج إضافة أو حزمة إلى خدمة موجودة - لكن هذا متروك للمطور الذي يكتب
الكتاب - يمكنك إنشاء عدة كائنا�� خدمة من إضافة، أو
تعديل الخدمات الموجودة من منتج مستقل إذا لزم الأمر
تتحكم الفئة ببساطة في تدفق واجهة المستخدم وأين يرى العملاء/الموظفون خيار المنتج.
أنواع الخدمات
يحدد حقل service_type نوع الخدمة المقدمة.
هذه محددة بالكامل بواسطة المستخدم، لكن القيم الشائعة تشمل:
- محمول - خدمات الهاتف المحمول مع الصوت، الرسائل القصيرة، والبيانات
- ثابت - خدمات الإنترنت الثابتة اللاسلكية أو السلكية
- صوت ثابت - خدمات الصوت الثابت (VoIP، خط أرضي)
- نقطة اتصال - أجهزة نقطة اتصال محمولة أو مستأجرة
- دونجل - خدمات مودم USB أو دونجل
- صوت - خدمات الصوت فقط
- بيانات - خدمات البيانات فقط
مثل الفئات، يمكن تخصيص أنواع الخدمات بناءً على عروضك. تساعد في:
- تصفية أي إضافات تنطبق على أي خدمات أساسية
- تنظيم المنتجات في بوابة العملاء
- مطابقة متطل��ات المخزون
- تحديد تدفقات العمل للتوفير
مثال: يمكن للعميل الذي لديه خدمة محمول رؤية الإضافات المحمولة، بينما
يرى العميل الذي لديه خدمة ثابت الإضافات الثابتة.
إدارة المنتجات
تتم إدارة المنتجات من خلال صفحة إدارة المنتجات، حيث يمكنك عرض، البحث، تصفية، وتحرير جميع المنتجات المتاحة.
{.align-center
width="800px"}
واجهة نموذج المنتج
النقر على أي منتج يفتح واجهة محسنة مع علامات تبويب تنظم جميع إعدادات المنتج في مجموعات منطقية لتسهيل التنقل والتحرير.
{.align-center
width="800px"}
تتميز نافذة إدارة المنتج بخمس علامات تبويب منظمة:
- 📋 المعلومات الأساسية - معلومات المنتج الأساسية (الاسم، الشعار، الفئة، الرمز، الميزات، الشروط)
- 💰 التسعير - جميع الحقول المتعلقة بالتكلفة بما في ذلك التكاليف المتكررة، تكاليف الإعداد، ونسبة الضريبة
- ⚙️ التكوين - إعدادات التجديد، أنواع العملاء، والاعتمادات
- 🔧 التوفير - تكوين كتاب Ansible ومتطلبات المخزون
- 📅 التوفر - نطاقات التاريخ والطوابع الزمنية للنظام
{.align-center
width="800px"}
تنظيم علامة تبويب التسعير:
تجمع علامة تبويب التسعير حقول التكلفة في أقسام منطقية:
- التكاليف المتكررة - التكاليف الشهرية للبيع بالتجزئة والجملة جنبًا إلى جنب
- تكاليف الإعداد - رسوم التفعيل لمرة واحدة للبيع بالتجزئة والجملة
- الضريبة - تكوين نسبة الضريبة مع الحساب التلقائي
ميزات وضع التحرير:
- اختيار الرمز - البحث واختيار رموز FontAwesome بصريًا
- اختيار عناصر المخزون - اختيار من أنواع عناصر المخزون المتاحة
- اختيار التاريخ/الوقت - اختيار سهل لنوافذ التوفر
- تنسيق العملة - بادئة $ تلقائية لحقول التكلفة
- محددات منسدلة - خيارات محددة مسبقًا للفئات والحقول المنطقية
{.align-center
width="800px"}
اختيار الرمز:
عند تحرير حقل الرمز، تظهر واجهة اختيار رمز قابلة للبحث تسمح لك بالتصفح بصريًا واختيار من بين آلاف رموز FontAwesome.
{.align-center
width="800px"}
الميزات: * البحث عن الرموز حسب الكلمة الرئيسية (مثل "مفتاح"، "محمول"، "واي فاي") * معاينة مظهر الرمز في الوقت الحقيقي * عرض اسم فئة الرمز للرجوع * اختيار منسدل للوصول السريع
علامة تبويب التكوين:
تنظم علامة تبويب التكوين إعدادات سلوك ��لمنتج في مجموعات منطقية.
{.align-center
width="800px"}
أقسام التكوين:
- إعدادات التجديد:
- التجديد التلقائي - سلوك التجديد الافتراضي (مطالبة/نعم/لا)
- السماح بالتجديد التلقائي - ما إذا كان يمكن للعملاء تمكين التجديد التلقائي
- أيام العقد - الحد الأدنى لمدة العقد (مثل 30 لشهري، 365 سنوي)
- أنواع العملاء:
- سكني - متاح للعملاء المستهلكين
- تجاري - متاح للعملاء التجاريين
- الاعتمادات:
- يعتمد على القائمة - معرفات المنتجات أو أنواع الخدمات المطلوبة قبل يمكن إضافة هذا المنتج
- تستخدم للاعتمادات الإضافية (مثل، تتطلب الإضافات المحمولة خدمة محمولة نشطة)
علامة تبويب التوفير:
تتعامل علامة تبويب التوفير مع أتمتة Ansible ومتطلبات المخزون.
{.align-center
width="800px"}
حقول التوفير:
- لعب التوفير:
- اسم كتاب Ansible (بدون امتداد .yaml)
- يجب أن يوجد في دليل OmniCRM-API/Provisioners/plays/
- يتم استدعاؤه عند إنشاء الخدمة أو تحديثها أو إلغاء توفيرها
- متغيرات JSON للتوفير:
- المتغيرات الافتراضية المرسلة إلى كتاب Ansible كـ JSON
- يمكن تجاوزها أثناء التوفير
- يتلقى الكتاب هذه بالإضافة إلى customer_id، product_id، service_id، access_token
- قائمة عناصر المخزون:
- محدد متعدد يظهر أنواع عناصر المخزون المتاحة
- أمثلة: بطاقة SIM، رقم الهاتف، مودم راوتر، عنوان IPv4
- يختار العميل/الموظف عناصر محددة من المخزون المتاح أثناء الطلب
- يتم تمرير معرفات المخزون المحددة إلى الكتاب مع نوع المخزون كاسم المتغير
علامة تبويب التوفر:
تتحكم علامة تبويب التوفر في متى يمكن شراء المنتج وتعرض بيانات التعريف الخاصة بالنظام.
{.align-center
width="800px"}
إعدادات التوفر:
- متاح من:
- التاريخ/الوقت عندما يصبح المنتج متاحًا للشراء
- اتركه فارغًا للتوفر الفوري
- مفيد للإعلان مسبقًا عن المنتجات الجديدة
- متاح حتى:
- التاريخ/الوقت عندما لم يعد المنتج متاحًا للشراء
- اتركه فارغًا للتوفر غير المحدود
- مثالي للعروض المحدودة أو المنتجات التي انتهت صلاحيتها
- بيانات التعريف الخاصة بالنظام (للقراءة فقط):
- تم الإنشاء - الطابع الزمني عندما تم إنشاء المنتج لأول مرة
- آخر تعديل - الطابع الزمني لأحدث تحديث
- يتم الحفاظ عليها تلقائيًا بواسطة النظام
إجراءات النموذج:
- وضع العرض:
- إغلاق - إلغاء النموذج
- نسخ المنتج - إنشا�� نسخة مع لاحقة "_clone"
- تحرير المنتج - التبديل إلى وضع التحرير
- وضع التحرير/الإنشاء:
- إلغاء - discard التغييرات وإغلاق
- حفظ التغييرات - إنشاء أو تحديث المنتج (زر كبير للتأكيد)
حقول المنتج
يحتوي نموذج المنتج على جميع المعلومات اللازمة لتعريف عرض وكيف يجب توفيره. تتم إدارة هذه الحقول من خلال واجهة نموذج إدارة المنتج الموضحة أعلاه.
المعلومات الأساسية
- product_id - معرف فريد يتم تعيينه تلقائيًا بواسطة النظام
- product_name - الاسم المعروض للعملاء والموظفين في واجهة المستخدم
- product_slug - معرف فريد يستخدم في عناوين URL وطلبات API (حروف صغيرة، بدون مسافات، استخدم الشرطات)
- category - يتحكم في مكان ظهور هذا المنتج في واجهة المستخدم:
مستقل- يظهر كخيار خدمة أساسي عند إنشاء خدمة جديدةإضافة- يظهر عند الإضافة إلى خدمة موجودةحزمة- يظهر كخيار خدمة مجمعةترويج- عروض ترويجية خاصة
- service_type - نوع الخدمة المقدمة (مثل، محمول، ثابت، صوت ثابت، نقطة اتصال، دونجل، صوت، بيانات). تستخدم لتصفية أي إضافات تنطبق على أي خدمات.
- comment - ملاحظات داخلية حول المنتج للرجوع إليها من قبل الموظفين فقط (لا تظهر للعملاء)
- icon - فئة رمز FontAwesome المعروضة في واجهة المستخدم (مثل،
fa-solid fa-sim-card)
حقول التسعير
- retail_cost - الرسوم الشهرية المتكررة المفروضة على العميل (تعيين إلى 0 للطلبات لمرة واحدة أو المنتجات المدفوعة مسبقًا)
- wholesale_cost - تكلفة الشهرية الخاصة بك لتوفير هذه الخدمة (تستخدم لحساب الهوامش)
- retail_setup_cost - رسوم التفعيل أو الإعداد لمرة واحدة المفروضة على العميل
- wholesale_setup_cost - تكلفتك لمرة واحدة لإعداد الخدمة
- tax_percentage - نسبة الضريبة المطبقة على ��ذا المنتج (مثل، 10 لـ 10%، 12.5 لـ 12.5%). تعيين إلى 0 للمنتجات المعفاة من الضرائب. يتم تطبيق معدل الضريبة هذا تلقائيًا على المعاملات التي تم إنشاؤها من هذا المنتج.
{.align-center
width="800px"}
تطبيق الضريبة:
عند إنشاء معاملة من هذا المنتج، يتم نسخ نسبة الضريبة تلقائيًا إلى المعاملة ويتم حساب مبلغ الضريبة. على سبيل المثال:
- منتج مع 10% ضريبة، $50.00 تكلفة التجزئة → المعاملة بها $5.00 ضريبة
- منتج مع 0% ضريبة (معفى من الضريبة) → المعاملة بها $0.00 ضريبة
- تجاوز المعاملة اليدوية → يمكن للموظف تغيير نسبة الضريبة لكل معاملة
رؤية العميل والوصول
- enabled - ما إذا كان هذا المنتج نشطًا ومتاحًا للشراء (تعيين إلى false للاختفاء دون الحذف)
- residential - ما إذا كان يمكن للعملاء السكنيين (المستهلكين) شراء هذا المنتج
- business - ما إذا كان يمكن للعملاء التجاريين شراء هذا المنتج
- customer_can_purchase - ما إذا كان يمكن للعملاء الشراء الذاتي عبر البوابة (true) أو إذا كان يمكن للموظفين فقط إضافته (false)
- available_from - التاريخ/الوقت عندما يصبح هذا المنتج متاحًا للشراء (اختياري)
- available_until - التاريخ/الوقت عندما لم يعد هذا المنتج متاحًا للشراء (اختياري، مفيد للعروض المحدودة)
العقد والتجديد
- contract_days - الحد الأدنى لمدة العقد بالأيام (مثل، 30 لشهري، 365 سنوي، 0 لعدم وجود حد أدنى للعقد)
- auto_renew - سلوك التجديد الافتراضي:
prompt- يسأل العميل في كل مرة ما إذا كان يريد التجديدtrue- يتم التجديد تلقائيًا دون سؤالfalse- يتطلب التجديد اليدوي
- allow_auto_renew - ما إذا كان يمكن للعملاء تمكين التجديد التلقائي (تعيين إلى false للطلبات لمرة واحدة)
المحتوى الموجه للعملاء
- terms - الشروط والأحكام المعروضة للعملاء قبل الشراء (تتضمن القيود، قواعد انتهاء الصلاحية، شروط الاستخدام)
- features_list - قائمة الميزات والمكونات المعروضة للعملاء (تنسيق قائمة Python:
['الميزة 1', 'الميزة 2'])
تكوين التوفير
- provisioning_play - اسم كتاب Ansible الذي يوفر
هذه الخدمة (بدون امتداد .yaml). يجب أن يوجد في
OmniCRM-API/Provisioners/plays/الدليل. - provisioning_json_vars - المتغيرات الافتراضية المرسلة إلى كتاب Ansible كـ JSON. يمكن تجاوزها عند التوفير. يتلقى الكتاب هذه مع
customer_id،product_id،service_id، وaccess_token. - inventory_items_list - قائمة عناصر المخزون المطلوبة لهذا
المنتج (مثل،
['SIM Card', 'Mobile Number']). عندما يطلب العميل سيتم تحفيزه لاختيار عناصر محددة من المخزون المتاح. يتم تمرير معرفات المخزون المحددة إلى كتاب التوفير مع نوع المخزون كاسم المتغير. - relies_on_list - قائمة معرفات المنتجات أو أنواع الخدمات التي يجب أن توجد قبل إضافة هذا المنتج. تُستخدم للاعتمادات الإضافية (مثل، تتطلب الإضافات المحمولة وجود خدمة محمولة نشطة).
بيانات التعريف الخاصة بالنظام
- created - الطابع الزمني عندما تم إنشاء المنتج (يتم تعيينه تلقائيًا)
- last_modified - الطابع الزمني عندما تم تحديث المنتج آخر مرة (يتم تحديثه تلقائيًا)
أمثلة على تعريفات المنتجات
منتج مستقل (بطاقة SIM المحمولة)

{
"product_id": 1,
"product_slug": "Mobile-SIM",
"product_name": "بطاقة SIM المحمولة فقط",
"category": "مستقل",
"service_type": "محمول",
"provisioning_play": "play_psim_only",
"provisioning_json_vars": "{\"iccid\": \"\", \"msisdn\": \"\"}",
"inventory_items_list": "['SIM Card', 'Mobile Number']",
"retail_cost": 0,
"retail_setup_cost": 0,
"wholesale_cost": 3,
"wholesale_setup_cost": 1,
"contract_days": 0,
"residential": true,
"business": true,
"enabled": true,
"customer_can_purchase": true,
"icon": "fa-solid fa-sim-card",
"features_list": "['رقم هاتف أسترالي (04xxx)', 'أسرع السرعات', 'أفضل تغطية', 'التجوال على البر الرئيسي']",
"terms": "يجب تفعيلها خلال 6 أشهر. يتم فقدان جميع الرصيد إذا لم يتم استخدام الخدمة لمدة 12 شهرًا.",
"comment": "بطاقة SIM فعلية للاستخدام مع الهواتف المحمولة"
}
يتطلب هذا المنتج المستقل عنصرين من المخزون (بطاقة SIM ورقم الهاتف) وينشئ خدمة جديدة عند توفيره.
منتج إضافة (خطة بيانات شهرية)
{
"product_slug": "norfone-mobile-prepaid-mini",
"product_name": "خطة نورفون ميني",
"category": "إضافة",
"service_type": "محمول",
"provisioning_play": "play_topup_charge_then_action",
"provisioning_json_vars": "",
"inventory_items_list": "[]",
"retail_cost": 30,
"retail_setup_cost": 0,
"wholesale_cost": 5.84,
"contract_days": 30,
"residential": true,
"business": false,
"enabled": true,
"customer_can_purchase": true,
"auto_renew": "prompt",
"icon": "fa-solid fa-sim-card",
"features_list": "['8 جيجابايت من البيانات فائقة السرعة', 'مكالمات ورسائل نصية غير محدودة لمستخدمي نورفون', '100 دقيقة مكالمات إلى أستراليا', '100 رسالة نصية إلى أستراليا', 'تاريخ انتهاء 30 يومًا']",
"terms": "تنتهي صلاحية الرصيد بعد 30 يومًا. بمجرد استهلاك البيانات أو الصوت أو الرسائل النصية، ستحتاج إلى إعادة الشحن للاستمرار في استخدام الخدمة.",
"comment": "أصغر خطة لدينا للمستخدمين الخفيفين"
}
لا يتطلب هذا المنتج الإضافي مخزونًا ويطبق على خدمة موجودة. يقوم بشحن العميل ويضيف أرصدة/رصيد إلى خدمتهم.
منتج حزمة (حزمة كبار السن)
{
"product_slug": "Bundle-Seniors",
"product_name": "حزمة كبار السن",
"category": "حزمة",
"service_type": "ثابت",
"provisioning_play": "play_seniors_package",
"provisioning_json_vars": "{\"IPTV_Service_ID\": \"SeniorBundle\"}",
"inventory_items_list": "['مودم راوتر']",
"retail_cost": 30,
"retail_setup_cost": 0,
"wholesale_cost": 10,
"wholesale_setup_cost": 11,
"contract_days": 180,
"residential": true,
"business": false,
"enabled": true,
"icon": "fa-solid fa-person-walking-with-cane",
"features_list": "['20 ميغابت في الثانية تنزيل', '5 ميغابت في الثانية رفع', 'بيانات غير محدودة', 'صوت منزلي', 'تلفاز: إضافي +5 جنيه إسترليني شهريًا', 'رسوم تركيب 60 جنيه إسترليني']",
"terms": "عقد لمدة 6 أشهر، يجب إظهار بطاقة المواطن المسن للتأهل",
"comment": "خدمة GPON بسرعة 20 ميغابت/2 ميغابت + IPTV + هاتف"
}
يوفر هذا المنتج المجمّع خدمات متعددة (إنترنت + IPTV + هاتف) باستخدام كتاب واحد. يتطلب عنصرًا واحدًا من المخزون (مودم راوتر).
منتج إضافة (إعادة شحن بسيطة)
{
"product_slug": "Mobile-Topup-5",
"product_name": "إعادة شحن PAYG بقيمة 5 جنيه إسترليني",
"category": "إضافة",
"service_type": "محمول",
"provisioning_play": "play_topup_monetary",
"provisioning_json_vars": "{\"service_id\": \"\"}",
"inventory_items_list": "[]",
"retail_cost": 5,
"retail_setup_cost": 0,
"wholesale_cost": 0,
"contract_days": 0,
"residential": true,
"business": false,
"enabled": true,
"customer_can_purchase": true,
"icon": "fa-solid fa-coins",
"features_list": "['رصيد 5 جنيه إسترليني', 'صالح لمدة 180 يومًا']",
"terms": "صالح لمدة 180 يومًا أو حتى يتم استخدام جميع الرصيد. راجع موقعنا للحصول على الأسعار الكاملة",
"comment": "5 جنيه إسترليني للاستخدام في المكالمات، الرسائل النصية والبيانات"
}
تضيف هذه الإضافة ببساطة رصيدًا نقديًا إلى خدمة موجودة. لا يتطلب مخزونًا، ويستخدم service_id لتحديد الخدمة
التي يجب إعادة شحنها.
كيفية تمرير المتغيرات إلى Ansible
فهم كيفية تدفق المتغيرات من تعريف المنتج عبر API إلى كتاب Ansible أمر حاسم لكتابة كتب التوفير الفعالة.
مصادر المتغيرات والدمج
عند إنشاء مهمة توفير، تأتي المتغيرات من مصادر متعددة وتدمج معًا بهذا الترتيب (المصادر اللاحقة تتجاوز السابقة):
- متغيرات provisioning_json_vars للمنتج - المتغيرات الافتراضية من تعريف المنتج
- جسم الطلب - المتغيرات المرسلة في مكالمة API (يمكن أن تتجاوز الافتراضات الخاصة بالمنتج)
- المتغيرات المضافة بواسطة النظام - تتم إضافتها تلقائيًا بواسطة نظام التوفير
- اختيارات المخزون - معرفات عناصر المخزون المحددة (إذا
كانت
inventory_items_listليست فارغة)
عملية دمج المتغيرات
تدمج النظام المتغيرات من جميع المصادر، مع تجاوز المصادر اللاحقة المصادر السابقة. هذا يسمح بتخصيص مرن في وقت التوفير.
على سبيل المثال، إذا كان منتجك يحتوي على:
"provisioning_json_vars": "{\"monthly_cost\": 50, \"data_gb\": 100}"
وكان طلب API الخاص بك يتضمن:
{
"product_id": 10,
"customer_id": 456,
"monthly_cost": 45,
"custom_param": "value"
}
ستكون المتغيرات النهائية extra_vars المرسلة إلى Ansible:
{
"monthly_cost": 45, # تم تجاوزها من الطلب
"data_gb": 100, # من provisioning_json_vars
"product_id": 10, # من الطلب
"customer_id": 456, # من الطلب
"custom_param": "value", # من الطلب
"access_token": "eyJ..." # أضيفت بواسطة النظام
}
المتغيرات المضافة بواسطة النظام
يضيف نظام التوفير تلقائيًا:
access_token- رمز JWT لمصادقة مكالمات API مرة أخرى إلى CRM (منg.access_tokenلمصادقة IP/API key، أو تم إنشاؤه منrefresh_tokenلمصادقة المستخدم)initiating_user- معرف المستخدم الذي قام بتحفيز التوفير (أو أول مشرف للأنظمة الآلية)- أي حقول من جسم الطلب (
product_id،customer_id،service_id، إلخ.)
متغيرات المخزون
عندما يتطلب منتج عناصر مخزون (مثل،
inventory_items_list: "['SIM Card', 'Mobile Number']")، تعمل العملية كما يلي:
- واجهة المستخدم/API تطلب الاختيار - يختار المستخدم عناصر المخزون المحددة من المخزون المتاح
- تتم إضافة معرفات المخزون إلى المتغيرات - تتم إضافة معرفات عناصر المخزون المحددة مع نوع المخزون كاسم المتغير
- يمكن للكتاب الوصول إلى معرفات المخزون - يمكن لكتاب التوفير بعد ذلك استرداد تفاصيل المخزون الكاملة من API CRM
على سبيل المثال، إذا اختار المستخدم: - بطاقة SIM مع inventory_id: 789 - رقم الهاتف مع inventory_id: 101
تتضمن المتغيرات المرسلة إلى الكتاب: - SIM Card: 789 - Mobile Number: 101
يمكن للكتاب بعد ذلك استخدام هذه المعرفات لاسترداد سجلات المخزون الكاملة (ICCID، IMSI، MSISDN، إلخ.) من API CRM واستخدام تلك المعلومات لتوفير الخدمة على المعدات الشبكية.
كيفية استلام Ansible للمتغيرات
يمرر نظام التوفير جميع المتغيرات المدمجة إلى كتاب Ansible كـ extravars. داخل الكتاب، تكون هذه المتغيرات
متاحة من خلال نظام المتغيرات القياسي في Ansible ويمكن استخدامها في
المهام.
يمكن الإشارة إلى المتغيرات مباشرة في مهام الكتاب باستخدام
الصيغة {{ variable_name }}. على سبيل المثال، {{ product_id }},
{{ customer_id }}, {{ monthly_cost }}، إلخ.
المتغيرات المرسلة إلى المنتجات الإضافية
عند توفير منتج إضافي، يمرر النظام تلقائيًا:
product_id- معرف المنتج الإضافي الذي يتم توفيرهcustomer_id- العميل الذي يمتلك الخدمةservice_id- معرف الخدمة التي تتم إضافة هذه الإضافة إليها (حاسم للإضافات)access_token- رمز المصادقة لمكالمات API- أي متغيرات من
provisioning_json_vars - أي متغيرات إضافية من طلب API
مثال على تدفق توفير الإضافات
عندما يضيف عميل إضافة "إعادة شحن بقيمة 5 جنيه إسترليني" إلى خدمة الهاتف المحمول الخاصة بهم
(service_id: 123)، يتلقى الكتاب متغيرات تشمل:
product_id: 45 (منتج إعادة الشحن)customer_id: 456 (العميل)service_id: 123 (الخدمة لإضافة الرصيد إليها)access_token: رمز المصادقة- بالإضافة إلى أي متغيرات من
provisioning_json_varsللمنتج
يستخدم الكتاب بعد ذلك هذه المتغيرات لـ:
- استرداد تفاصيل الخدمة من API CRM باستخدام
service_id - استخراج UUID الخدمة ومعلومات أخرى من سجل الخدمة
- إضافة رصيد إلى نظام الفوترة (OCS) باستخدام UUID الخدمة
- تسجيل المعاملة في CRM لأغراض الفوترة
يسمح هذا التدفق للإضافة بتحديد بالضبط أي خدمة يجب تعديلها وتطبيق التغييرات بشكل مناسب.
الفرق بين المتغيرات المستقلة والإضافات
المنتجات المستقلة تتلقى:
product_id- المنتج الذي يتم توفيرهcustomer_id- العميل الذي يطلب الخدمة- معرفات عناصر المخزون (مثل،
SIM Card،Mobile Number) إذا كان المنتج يتطلبها access_token- لمصادقة API
المنتجات الإضافية تتلقى:
product_id- المنتج الإضافي الذي يتم توفيرهcustomer_id- ال��ميل الذي يمتلك الخدمةservice_id- معرف الخدمة الموجودة التي يجب تعديلها (هذا هو الفرق الرئيسي)access_token- لمصادقة API
الفرق الرئيسي هو service_id - هذا يخبر الكتاب أي
خدمة موجودة يجب تعديلها أو إضافة إليها.
المنتجات المجمعة
تُوفر المنتجات المجمعة مثل الإضافات ولكن قد ينشئ كتابها سجلات خدمات متعددة. تتلقى نفس المتغيرات مثل الإضافات، بما في ذلك:
product_id- المنتج المجمّعcustomer_id- العميلservice_id- الخدمة الرئيسية (إذا كان ذلك مناسبًا)- معرفات عناصر المخزون (مثل،
مودم راوتر) إذا كانت مطلوبة access_token- لمصادقة API
ثم ينشئ كتاب الحزمة (مثل، play_seniors_package) خدمات متعددة ذات صلة (إنترنت، IPTV، هاتف) ويربطها معًا.
الخدمات
الخدمة هي نسخة من منتج تنتمي إلى عميل، يتم تحصيل الرسوم عليها.
إنها في الأساس رابط إلى حساب OCS (نظام الشحن ع��ر الإنترنت) الذي يتعامل مع توليد الشحن والأرصدة والاستخدامات الفعلية للحساب. يتم تشغيل OCS بواسطة CGRateS ويدير الأرصدة النقدية، الأرصدة الوحدوية (البيانات، الصوت، الرسائل القصيرة)، خطط العمل للتجديد التلقائي، وThresholdS لحدود الإنفاق.
إضافة خدمة: اختيار المنتج والتصفية
عند إضافة خدمة إلى عميل (إما خدمة مستقلة جديدة أو إضافة إلى خدمة موجودة)، تعرض النظام المنتجات المتاحة في واجهة دوارة. يتم تصفية المنتجات المعروضة بناءً على عدة معايير:
تصفية المنتجات للخدمات المستقلة
عند إنشاء خدمة جديدة لعميل، تعرض واجهة المستخدم المنتجات المصفاة حسب:
- نوع العميل - يتم تصنيف المنتجات على أنها:
- فردية (سكنية): المنتجات حيث
residential = trueأوbusiness = false - تجارية: المنتجات حيث
business = true
- فردية (سكنية): المنتجات حيث
- الفئة - يتم فصل المنتجات إلى:
- خطط الخدمة: ا��منتجات التي تكون
category=مستقلأوحزمة - الإضافات: المنتجات التي تكون
category=إضافة(تظهر في دوارة منفصلة)
- خطط الخدمة: ا��منتجات التي تكون
- التوفر - يتم عرض المنتجات فقط إذا:
enabled = true- المنتج نشط وليس معطلاً- التاريخ الحالي بين
available_fromوavailable_until- المنتج ضمن نافذة توفره customer_can_purchase = true(إذا كان العميل يشتري بنفسه) - يسمح المنتج بالشراء المباشر من العميل
::: note ::: title ملاحظة :::
تصفية على مستوى API: يقوم API تلقائيًا بتصفية المنتجات حسب حالة التمكين وتواريخ التوفر على مستويين:
- نقاط نهاية الشراء/الاختيار (
/crm/product/) - تستخدم بواسطة نموذج الإضافات وقائمة الخطط لاختيار المنتج. يتم تصفيتها تلقائيًا لعرض المنتجات المفعلة فقط ضمن نطاق تواريخ توفرها. يضمن ذلك أن العملاء والموظفين يمكنهم فقط اختيار المنتجات المتاحة حاليًا للشراء. - نقاط نهاية الإدارة (
/crm/product/paginated) - تستخدم بواسطة صفحة إدارة المنتجات. تعرض جميع المنتجات بما في ذلك المعطلة و خارج تواريخ التوفر، مما يسمح للمسؤولين بإدارة كتالوج المنتجات الكامل بما في ذلك المنتجات غير النشطة.
مرر include_disabled=true إلى نقطة نهاية المنتج الأساسية لتجاوز
التصفية (فقط للاستخدام الإداري).
:::
تعرض واجهة المستخدم دوارات منفصلة لـ:
- خطط الخدمة الفردية - المنتجات السكنية للعملاء المستهلكين
- خطط الخدمة التجارية - المنتجات التجارية للعملاء التجاريين
- الإضافات الفردية - حزم الإضافات السكنية
- الإضافات التجارية - حزم الإضافات التجارية
تصفية المنتجات لخدمات الإضافات
عند إضافة إضافة إلى خدمة موجودة، يتم تطبيق تصفية إضافية:
- مطابقة نوع الخدمة - يتم عرض الإضافات فقط التي تتطابق مع
service_type:- إذا كانت الخدمة الموجودة لديها
service_type = "محمول"، يتم عرض الإضافات فقط التي لديهاservice_type = "محمول" - يضمن ذلك أن العملاء المحمولين يرون فقط الإضافات المحمولة، وعملاء الإنترنت يرون فقط الإضافات الإنترنت، إلخ.
- إذا كانت الخدمة الموجودة لديها
- التحقق من الاعتمادات - إذا كانت الإضافة تحتوي على
relies_on_list:- يتحقق النظام مما إذا كان العميل لديه المنتجات/الخدمات المطلوبة
- يتم عرض الإضافات التي تم استيفاء اعتماداتها فقط
- تصفية نفس نوع العميل - لا تزال الإضافات مصفاة حسب
residentialمقابلbusinessلمطابقة نوع العميل
سيناريو تصفية مثال
لعميل تجاري لديه خدمة محمولة موجودة
(service_type = "محمول"):
- المنتجات المستقلة المعروضة: جميع المنتجات المستقلة/المجمعة التجارية
(
business = true،category != "إضافة") - المنتجات الإضافية المعروضة: فقط الإضافات المحمولة التجارية
(
business = true،category = "إضافة"،service_type = "محمول") - المنتجات المخفية: المنتجات السكنية، الإضافات لأنواع خدمات أخرى (الإنترنت، الصوت، إلخ)، المنتجات المعطلة
حقول الخدمة
يحتوي نموذج الخدمة على حقول تتبع نسخة الخدمة الموفرة وعلاقتها بالعميل، المنتج، ونظام الفوترة.
المعلومات الأساسية للخدمة
- service_id - معرف فريد يتم تعيينه تلقائيًا بواسطة النظام (للقراءة فقط)
- customer_id - رابط إلى العميل الذي يمتلك هذه الخدمة (للقراءة فقط بعد الإنشاء)
- product_id - رابط إلى المنتج الذي تم إنشاء هذه الخدمة منه (للقراءة فقط بعد الإنشاء)
- service_name - الاسم المعروض للعملاء (قابل للتحرير)
- service_type - نوع الخدمة: محمول، إنترنت، VoIP، IPTV، حزمة، إلخ. (قابل للتحرير)
- service_uuid - معرف فريد يستخدم في OCS/CGRateS للفوترة (للقراءة فقط، يتم إنشاؤه تلقائيًا)
- icon - فئة رمز FontAwesome للعرض في بوابة الرعاية الذاتية (قابل للتحرير)
حالة الخدمة والتواريخ
- service_status - الحالة الحالية: نشطة، غير نشطة، معلقة، إلخ. (قابل للتحرير)
- service_provisioned_date - عندما تم توفير الخدمة لأول مرة (يتم تعيينه تلقائيًا، للقراءة فقط)
- service_active_date - عندما أصبحت الخدمة نشطة (قابل للتحرير)
- service_deactivate_date - عندما تنتهي صلاحية الخدمة أو سيتم إلغاء تنشيطها (قابل للتحرير)
- contract_end_date - تاريخ انتهاء الالتزام بالعقد (قابل للتحرير)
الفوترة والتسعير
- retail_cost - الرسوم الشهرية المتكررة على العميل (قابل للتحرير)
- wholesale_cost - تكلفتك لتوفير الخدمة (قابل للتحرير)
- service_billed - ما إذا كانت هذه الخدمة تظهر في الفواتير (قابل للتحرير، الافتراضي: true)
- service_taxable - ما إذا كانت الضرائب تنطبق على هذه الخدمة (قابل للتحرير، الافتراضي: true)
- invoiced - ما إذا كانت الخدمة قد تم فوترتها (يتم تعيينها تلقائيًا بواسطة نظام الفوترة)
- promo_code - الرمز الترويجي المستخدم عند إنشاء الخدمة (قابل للتحرير)
رؤية العميل
- service_visible_to_customer - ما إذا كان يمكن للعميل رؤية هذه الخدمة في بوابة الرعاية الذاتية (قابل للتحرير، الافتراضي: true)
- service_usage_visible_to_customer - ما إذا كان يمكن للعميل عرض تفاصيل الاستخدام/الرصيد (قابل للتحرير، الافتراضي: true)
تكوين التوفير
- provisioning_play - كتاب Ansible المستخدم لتوفير هذه الخدمة (موروث من المنتج، للقراءة فقط)
- provisioning_json_vars - المتغيرات المرسلة إلى كتاب التوفير (موروثة من المنتج، للقراءة فقط)
- deprovisioning_play - كتاب Ansible الذي يتم تشغيله عند إلغاء توفير الخدمة (للقراءة فقط)
- deprovisioning_json_vars - المتغيرات لكتاب إلغاء التوفير (للقراءة فقط)
علاقات الخدمة
- bundled_parent - إذا كانت هذه الخدمة جزءًا من حزمة، معرف الخدمة للخدمة الرئيسية (للقراءة فقط)
- site_id - رابط إلى الموقع/المكان الفعلي حيث يتم تسليم الخدمة (قابل للتحرير)
الملاحظات وبيانات التعريف
- service_notes - ملاحظات داخلية حول الخدمة للرجوع إليها من قبل الموظفين (قابل للتحرير)
- created - الطابع الزمني عندما تم إنشاء الخدمة (يتم تعيينه تلقائيًا، للقراءة فقط)
- last_modified - الطابع الزمني لأحدث تحديث (يتم تحديثه تلقائيًا، للقراءة فقط)
الحقول القابلة للتحرير مقابل الحقول للقراءة فقط
قابل للتحرير عبر API/UI:
يمكن تحديث الخدمات عبر PATCH /crm/service/{service_id} مع هذه
الحقول:
- service_name، service_type، service_status
- service_notes
- retail_cost، wholesale_cost
- service_billed، service_taxable
- service_visible_to_customer، service_usage_visible_to_customer
- service_active_date، service_deactivate_date، contract_end_date
- icon، promo_code، site_id
للقراءة فقط (يتم تعيينها تلقائيًا):
لا يمكن تعديل هذه الحقول مباشرة بعد الإنشاء:
- service_id، customer_id، product_id
- service_uuid (يتم إنشاؤه أثناء التوفير)
- service_provisioned_date
- provisioning_play، provisioning_json_vars
- deprovisioning_play، deprovisioning_json_vars
- bundled_parent
- invoiced (يدار بواسطة نظام الفوترة)
- created، last_modified (يدار تلقائيًا)
توفير المنتجات في خدمات
تقوم عملية التوفير بتحويل منتج (قالب) إلى خدمة (نسخة محددة للعميل) من خلال سلسلة من الخطوات المنسقة التي تشمل واجهة الويب، API، وكتب Ansible.
تدفق التوفير على مستوى عالٍ
- إعداد ما قبل التوفير - يتم إنشاء المنتج في API مع تكوين التوفير، وكتابات كتب Ansible المقابلة واختبارها
- اختيار الخدمة - من صفحة العميل، يختار الموظف أو العميل "إضافة خدمة"
- تصفية المنتجات - يتم تصفية المنتجات المعروضة بناءً على:
- نوع العميل (سكني/تجاري)
- الخدمات الموجودة (للاستيفاء في
relies_on_list) - تواريخ التوفر (
available_from/available_until) - علامات
enabledوcustomer_can_purchase
- التخصيص - خيار لتجاوز متغيرات التوفير (لتعديلات الأسعار، التكوينات المخصصة، إلخ.)
- اختيار المخزون - إذا كان المنتج يتطلب المخزون
(
inventory_items_listليست فارغة)، يختار المستخدم عناصر محددة (مثل، أي بطاقة SIM، أي رقم هاتف) - بدء التوفير - عند النقر على زر "توفير"، ينشئ API مهمة توفير
تدفق تكامل API وAnsible بالتفصيل
عند توفير خدمة، تحدث التسلسل التالي:
الخطوة 1: إنشاء مهمة التوفير (/routes/service.py)
يتلقى API طلب التوفير ويستدعي
create_provisioning_job() من services/provisioning_service.py
مع:
provisioning_play- اسم كتاب Ansible (مثل،play_psim_only)provisioning_json_vars- سلسلة JSON من المتغيرات من المنتج أو التي تم تجاوزها بواس��ة الطلبcustomer_id- معرف العميل الذي يطلب الخدمةproduct_id- معرف المنتج الذي يتم توفيرهservice_id- (اختياري) معرف الخدمة الموجودة للإضافات- اختيارات المخزون - معرفات عناصر المخزون المحددة
الخطوة 2: تجميع المتغيرات (services/provisioning_service.py)
تدمج خدمة التوفير المتغيرات من مصادر متعددة بهذا الترتيب:
- متغيرات
provisioning_json_varsللمنتج (الافتراضات من تعريف المنتج) - معلمات جسم الطلب (يمكن أن تتجاوز الافتراضات الخاصة بالمنتج)
- المتغيرات المضافة بواسطة النظام:
access_token- رمز JWT لمصادقة API مرة أخرى إلى CRMinitiating_user- معرف المستخدم الذي قام بتحفيز التوفيرcustomer_id،product_id،service_id
- اختيارات المخزون - تتم إضافتها كأزواج
{inventory_type: inventory_id}
مثال على المتغيرات المدمجة:
{
"customer_id": 123,
"product_id": 456,
"service_id": 789, # فقط للإضافات
"SIM Card": 1001, # من اختيار المخزون
"Mobile Number": 1002, # من اختيار المخزون
"monthly_cost": 30, # من provisioning_json_vars
"data_gb": 50, # من provisioning_json_vars
"access_token": "eyJ...", # تمت إضافته للنظام لمكالمات API
"initiating_user": 5 # تمت إضافته للنظام
}
الخطوة 3: إنشاء سجل التوفير (models.py - نموذج التوفير)
يتم إنشاء سجل Provision في قاعدة البيانات مع:
provision_id- معرف فريد للتتبعprovisioning_play- اسم ملف الكتابprovisioning_json_vars- المتغيرات المدمجة كسلسلة JSONtask_count- عدد المهام في الكتاب (مستخرج من YAML)provisioning_status- رمز الحالة (يتم تعيينه مبدئيًا إلى 1 = قيد التشغيل، ثم يتم تحديثه إلى 0 = نجاح، 2 = فشل، أو قد يبقى 1 إذا كان لا يزال في التقدم)product_id،customer_id،service_id- مراجع السياق
الخطوة 4: تنفيذ الكتاب في الخلفية
(Provisioners/playbook_runner_v2.py)
يولد API خيطًا في الخلفية يقوم بـ:
- تحميل YAML الكتاب من
OmniCRM-API/Provisioners/plays/{playbook_name}.yaml - يستدعي
ansible_runner.run()مع:playbook- مسار ملف YAML المحملextravars- جميع المتغيرات المدمجة (تمريرها إلى Ansible)inventory- تعيين إلى'localhost,'(تنفيذ محلي)event_handler- معالج مخصص لالتقاط أحداث تنفيذ المهمة
- مراقبة تنفيذ الكتاب في الوقت الحقيقي
الخطوة 5: التقاط الأحداث والتسجيل (ProvisioningEventHandler)
عند تنفيذ كل مهمة Ansible، يتم التقاط الأحداث وتخزينها كـ
سجلات Provision_Event:
event_name- اسم المهمة من الكتابevent_number- رقم التسلسلprovisioning_status- رمز الحالة الذي يشير إلى نتيجة المهمة:- 0 = نجاح - اكتملت المهمة بنجاح
- 1 = قيد التشغيل - المهمة قيد التنفيذ حاليًا
- 2 = فشل - فشل حرج يوقف التوفير
- 3 = فشل (تم تجاهله) - فشلت المهمة ولكن تم تجاهل الأخطاء
(
ignore_errors: trueفي الكتاب)
provisioning_result_json- نتائج المهمة مع البيانات الحساسة محجوبة
يقوم معالج الأحداث تلقائيًا بإزالة كلمات المرور، المفاتيح، الأسرار، و البيانات الحساسة الأخرى من السجلات.
الخطوة 6: تنفيذ كتاب Ansible (Provisioners/plays/*.yaml)
يعمل كتاب Ansible محليًا وعادةً ما يقوم بهذه الإجراءات:
a. استرداد تعريف المنتج - طلب GET إلى
/crm/product/product_id/{{ product_id }} باستخدام
{{ access_token }}
b. استرداد معلومات العميل - طلب GET إلى
/crm/customer/customer_id/{{ customer_id }}
c. معالجة عناصر المخزون (إذا لزم الأمر) - طلب GET إلى
/crm/inventory/inventory_id/{{ inventory_id }} لكل عنصر محدد لاسترداد التفاصيل الكاملة (ICCID، MSISDN، أرقام السلاسل، إلخ.)
d. تكوين الأنظمة الخارجية - إجراء مكالمات API إلى:
- HSS (خادم المشتركين المنزلي) لتوفير المشتركين
- IMS (نظام الوسائط المتعددة IP) لتسجيل الصوت
- CGRateS/OCS لإنشاء الحساب، تكوين الشحن، خطط الأسعار
- خوادم ENUM لتخطيط أرقام اله��اتف
- المعدات الشبكية (الموجهات، المفاتيح، إلخ.)
e. إضافة تكاليف الإعداد (إذا لزم الأمر) - POST إلى /crm/transaction/ لتسجيل الرسوم لمرة واحدة
f. تحصيل الرسوم من العميل - POST إلى OCS/CGRateS لتحصيل retail_setup_cost إذا تم تكوينه
g. إنشاء حساب OCS - POST إلى OCS/CGRateS لإنشاء حساب فوترة مع UUID
h. تكوين الرسوم المتكررة - إنشاء إجراءات وخطط إجراءات في OCS/CGRateS للرسوم الشهرية المتكررة
i. إنشاء سجل الخدمة - PUT/POST إلى /crm/service/ لإنشاء
سجل الخدمة في CRM:
{
"customer_id": 123,
"product_id": 456,
"service_name": "بطاقة SIM المحمولة - 0412345678",
"service_uuid": "generated-uuid-for-ocs",
"service_status": "نشط",
"service_type": "محمول",
"retail_cost": 30,
"wholesale_cost": 5,
"provisioning_play": "play_psim_only",
"provisioning_json_vars": "{...}"
}
j. تعيين المخزون - PATCH إلى
/crm/inventory/inventory_id/{{ inventory_id }} لوضع علامة على المخزون
كـ "مخصص" للخدمة
k. إرسال الإشعارات (اختياري) - بريد إلكتروني أو رسالة نصية للعميل مع تفاصيل الخدمة
الخطوة 7: الانتهاء وتحديث الحالة
عند اكتمال الكتاب:
- نجاح: يتم تحديث
Provision.provisioning_statusإلى 0 (نجاح) - فشل حرج: يتم تحديث
Provision.provisioning_statusإلى 2 (فشل)، ويتم إرسال بريد إلكتروني بالفشل إلىcrm_config.provisioning.failure_list - الفشل غير الحرج: المهام التي تفشل مع
ignore_errors: trueيتم وضع علامة عليها بالحالة 3 (فشل ولكن تم تجاهله) ولا توقف التوفير
الخدمة الموفرة الآن مرئية في CRM ونشطة للعميل (إذا نجح التوفير).
الاختلافات الرئيسية: التوفير المستقل مقابل الإضافات مقابل التوفير المجمّع
المنتجات المستقلة (category: مستقل):
- تتلقى
customer_idوproduct_id - تتطلب عادةً عناصر المخزون (بطاقات SIM، أرقام الهواتف، المودمات)
- تنشئ سجل خدمة جديد عبر API PUT
/crm/service/ - توفر موارد جديدة على الأنظمة الخارجية (HSS، OCS، المعدات الشبكية)
- مثال: تفعيل بطاقة SIM جديدة، اتصال إنترنت جديد
المنتجات الإضافية (category: إضافة):
- تتلقى
customer_id،product_idوservice_id(الخدمة الموجودة لتعديلها) - عادةً لا تتطلب المخزون (أو مخزونًا ضئيلًا)
- تعدل خدمة موجودة أو تضيف رسومًا إلى حساب OCS الموجود
- قد تنفذ إجراءات على OCS (إضافة حزمة بيانات، إضافة رصيد، تمكين ميزة)
- لا تنشئ سجلات خدمات جديدة (أو تنشئ سجلات خدمات فرعية مرتبطة بالأصل)
- مثال: إعادة شحن خطة بيانات شهرية، حزمة تجوال دولية، رصيد إضافي
المنتجات المجمعة (category: حزمة):
- مشابهة للإضافات من حيث المتغيرات المستلمة
- قد تتطلب بعض عناصر المخزون (مثل، مودم لحزمة المنزل)
- تنشئ سجلات خدمات متعددة ذات صلة (إنترنت + تلفاز + هاتف)
- توفر موارد متعددة عبر أنظمة مختلفة
- تربط الخدمات معًا في CRM للفوترة/الإدارة الموحدة
- مثال: حزمة منزلية (إنترنت + IPTV + هاتف VoIP)
متطلبات كتاب التوفير
لكي يعمل الكتاب بشكل صحيح، يجب أن:
- يكون موجودًا في
OmniCRM-API/Provisioners/plays/{playbook_name}.yaml - يقبل المتغيرات عبر
extravarsفي Ansible (يتم الوصول إليها كـ{{ variable_name }}) - يصادق على مكالمات API باستخدام
Authorization: Bearer {{ access_token }}header - يتعامل مع الأخطاء بشكل جيد باستخدام كتل
rescueوignore_errorsحيثما كان ذلك مناسبًا - ينشئ سجل الخدمة للمنتجات المستقلة، أو يعدل الخدمة الموجودة للإضافات
- يخصص المخزون إذا تم اختيار عناصر المخزون
- يعود برسائل خطأ ذات مغزى عبر وحدة
failعند حدوث أخطاء حرجة
المتغيرات الشائعة المتاحة في الكتب
تتلقى كل كتاب هذه المتغيرات:
customer_id- عدد صحيح، العميل الذي يطلب الخدمةproduct_id- عدد صحيح، المنتج الذي يتم توفيرهservice_id- عدد صحيح (فقط للإضافات/الحزم)، الخدمة الموجودة لتعديلهاaccess_token- سلسلة، رمز JWT لمصادقة API CRMinitiating_user- عدد صحيح، المستخدم الذي قام بتحفيز التوفير- بالإضافة إلى أي معرفات عناصر المخزون:
{{ inventory_type }}: inventory_id - بالإضافة إلى أي متغيرات من
provisioning_json_vars - بالإضافة إلى أي متغيرات تم تمريرها في طلب التوفير
يمكن للكتب استخدام هذه لـ:
- استرداد تفاصيل المنتج الكاملة:
GET /crm/product/product_id/{{ product_id }} - استرداد تفاصيل العميل:
GET /crm/customer/customer_id/{{ customer_id }} - استرداد تفاصيل المخزون:
GET /crm/inventory/inventory_id/{{ SIM_Card }} - إنشاء المعاملات:
POST /crm/transaction/ - إنشاء الخدمات:
PUT /crm/service/ - تحديث الخدمات:
PATCH /crm/service/{{ service_id }} - تخصيص المخزون:
PATCH /crm/inventory/inventory_id/{{ inventory_id }}
مثال: تدفق كتاب إضافة بسيطة
لإعادة شحن بيانات محمولة:
- يتلقى الكتاب:
customer_id،product_id،service_id،access_token - استرداد تفاصيل الخدمة:
GET /crm/service/{{ service_id }}للحصول علىservice_uuid - استرداد تفاصيل المنتج:
GET /crm/product/product_id/{{ product_id }}للحصول على التسعير و كمية البيانات - تحصيل الرسوم من العميل في OCS:
POST إلى CGRateSلخصم retail_cost من الرصيد - إضافة رصيد بيانات في OCS:
POST إلى CGRateSلإضافة رصيد البيانات مع تاريخ انتهاء - تسجيل المعاملة في CRM:
POST /crm/transaction/مع تفاصيل الشحن - الاكتمال بنجاح
يتم تتبع العملية بأكملها في جداول Provision وProvision_Event
لأغراض التصحيح والتدقيق.
مشاركة OCS
يتعامل OCS (نظام الشحن عبر الإنترنت)، الذي تم تنفيذه عبر CGRateS، مع جميع
الشحنات في الوقت الحقيقي وتتبع الاستخدام للخدمات. يسجل خدمة CRM
يعمل كمرجع لحساب OCS، الذي يدير:
- الرسوم المتكررة - الرسوم الشهرية، إيجار DID، رسوم الاشتراك
- الشحن القائم على الاستخدام - مكالمات صوتية بالدقيقة، بيانات لكل ميغابايت، رسوم لكل رسالة نصية
- إدارة الأرصدة - الأرصدة النقدية (رصيد مدفوع مسبقًا) والأرصدة الوحدوية (بيانات GB، دقائق الصوت، عدد الرسائل النصية)
- تحويل الأرصدة - تحويل الأرصدة النقدية إلى أرصدة وحدوية (مثل إنفاق $30 للحصول على حزمة بيانات 10GB)
- حالة الحساب - نشط، معلق، معطل بناءً على حدود الائتمان والعتبات
تحتوي سجل خدمة CRM على بيانات التعريف والتكوين (العميل، المنتج، التسعير، الرؤية)، بينما يحتوي OCS على حالة الفوترة الحية (الأرصدة، الاستخدام، الرسوم).
استرداد استخدام الخدمة والأرصدة
يتم استرداد معلومات استخدام الخدمة من OCS/CGRateS وعرضها على العملاء والموظفين في الوقت الحقيقي.
كيفية استرداد الاستخدام
عند طلب استخدام خدمة (عبر واجهة المستخدم أو API)، تحدث التدفق التالي:
-
طلب API - يستدعي الواجهة الأمامية
GET /crm/service/{service_id}أو يعرض تفاصيل الخدمة في واجهة المستخدم -
بحث الخدمة - يسترد API سجل الخدمة من قاعدة البيانات، يستخرج
service_uuid -
مكالمات API CGRateS - يقوم وحدة
cgrates_service.pyبإجراء مكالمتين إلى CGRateS:a. Get_Balance(service_uuid) - يسترد رصيد الحساب مع
BalanceMap- يعيد الأرصدة المنظمة حسب النوع: بيانات، صوت، رسائل نصية، نقدية، بيانات دنجلة
- يتضمن كل رصيد: ID، القيمة، تاريخ انتهاء الصلاحية، الوزن، معرفات الوجهة
- يضيف النظام حقولًا قابلة للقراءة البشرية:
custom_Name_hr,custom_Expiration,custom_Description_Stringb. Get_ActionPlans(service_uuid) - يسترد خطط الإجراءات النشطة للتجديد التلقائي (المغطاة في القسم التالي)
-
دمج الاستجابة - يتم دمج بيانات CGRateS في استجابة الخدمة:
{
"service_id": 123,
"service_name": "خدمة المحمول",
"service_uuid": "abc-123-def",
"cgrates": {
"BalanceMap": {
"DATA": [{
"ID": "DATA_10GB",
"Value": 5368709120,
"ExpirationDate": "2025-02-01T00:00:00Z",
"custom_Name_hr": "حزمة بيانات 10 جيجابايت",
"custom_Expiration": "1 فبراير 2025",
"custom_Description_String": "5 جيجابايت المتبقية"
}],
"VOICE": [{
"ID": "VOICE_UNLIMITED",
"Value": 999999999,
"custom_Name_hr": "مكالمات غير محدودة",
"custom_Description_String": "دقائق غير محدودة"
}],
"MONETARY": [{
"ID": "PREPAID_CREDIT",
"Value": 25.50,
"custom_Description_String": "رصيد 25.50 دولار"
}]
},
"ActionPlans": [...]
}
} -
عرض واجهة المستخدم - تعرض مكونات الواجهة الأمامية بيانات الاستخدام:
- ServiceUsage.js - المكون الرئيسي لعرض الاستخدام مع تحديث تلقائي كل 3 ثوانٍ
- UsageCard.js - بطاقات ملخص لكل نوع رصيد
- UsageProgress.js - أشرطة التقدم التي تظهر النسبة المستخدمة/المتبقية
- يتم ترميز الأرصدة ��الألوان وتنسيقها لسهولة القراءة
هيكل بيانات الاستخدام
يحتوي كل رصيد في BalanceMap على:
حقول CGRateS الأصلية:
ID- معرف فريد للرصيد (مثل، "DATA_10GB_2025_01")Value- مبلغ الرصيد:- للبيانات: بايت (5368709120 = 5 جيجابايت)
- للصوت: ثوانٍ (3600 = 1 ساعة)
- للرسائل النصية: عدد (100 = 100 رسالة)
- للنقد: وحدات العملة (25.50 = $25.50)
ExpirationDate- الطابع الزمني ISO 8601 عندما تنتهي صلاحية الرصيدWeight- الأولوية لاستهلاك الرصيد (يتم استهلاك الوزن الأعلى أولاً)DestinationIDs- الوجهات التي ينطبق عليها هذا الرصيد (مثل، ["AU"، "INTERNATIONAL"])
الحقول القابلة للقراءة البشرية (تمت إضافتها بواسطة CRM):
custom_Name_hr- اسم قابل للقراءة البشرية مستخرج من IDcustom_Expiration- تاريخ انتهاء الصلاحية المنسق (مثل "15 يناير، 2025" أو "في 11 يومًا")custom_Description_String- وصف رصيد قابل للقراءة البشرية:- البيانات: "5 جيجابايت المتبقية" أو "10 جيجابايت إجمالي"
- الصوت: "60 دقيقة المتبقية" أو "غير محدود"
- الرسائل النصية: "50 رسالة نصية المتبقية"
- النقد: "رصيد 25.50 دولار"
التحكم في رؤية الاستخدام
يتم التحكم في رؤية استخدام الخدمة بواسطة حقلين:
- service_visible_to_customer - إذا كانت false، يتم إخفاء الخدمة تمامًا من بوابة الرعاية الذاتية للعميل
- service_usage_visible_to_customer - إذا كانت false، تكون الخدمة مرئية ولكن يتم إخفاء تفاصيل الاستخدام/الرصيد (يمكن للعميل رؤية أن لديهم الخدمة، ولكن ليس مقدار ما استخدموه)
يسمح ذلك للمشغلين بـ:
- إخفاء الخدمات الداخلية/التجريبية عن العملاء
- عرض وجود الخدمة دون الكشف عن الاستخدام (مفيد للخطط غير المحدودة أو الخدمات الحساسة)
- عرض الاستخدام بشكل شفاف تمامًا (افتراضي)
تحديثات الاستخدام في الوقت الحقيقي
تقوم واجهة الويب بتحديث بيانات الاستخدام تلقائيًا:
- الفاصل الزمني: كل 3 ثوانٍ (قابل للتكوين في مكون ServiceUsage)
- الطريقة: تستدعي
GET /crm/service/{service_id}التي تسترد البيانات الحية من CGRateS - الكفاءة: يتم تحديث فقط عرض الخدمات النشطة؛ تستخدم قوائم العرض البيانات المخزنة
يضمن ذلك أن العملاء والموظفين يرون تحديثات الأرصدة في الوقت القريب عند حدوث الاستخدام.
الرسوم المتكررة / التجديد التلقائي
تُنشأ الرسوم المتكررة، مثل رسوم الخدمة الشهرية، أو رسوم لكل DID
أولاً كإجراءات داخل OCS وتأخذ الشكل
Action_ServiceUUID_ServiceName_WhatitDoes.
لنفترض خدمة GPON بقيمة 60 دولار شهريًا تتضمن 1 تيرابايت من الاستخدام، ستبدو الإجراء كما يلي:
Action_kj49-adsf-1234-9742_60_GPON_1TB_MonthlyExpiry
- إعادة تعيين الرصيد النقدي إلى 0 دولار
- إرسال POST HTTP إلى
/simple_provisionعلى CRM لتوفير شيء ما - إضافة رصيد لاستخدام 1 تيرابايت تنتهي صلاحيتها في شهر واحد
إذا أردنا ��عل MRC متكررًا (نحن نفعل) فسوف ننشئ
ActionPlan باسم ActionPlan_{{ service_uuid }}_Monthly_Charge والذي
سيتعين ضبطه على شهري ليتم تشغيله كل شهر، وتعيين
ActionPlan للحساب.
يمكننا تعيين تاريخ انتهاء بناءً على معلمة السنة/الشهور/الأيام للتاريخ الذي سيتوقف فيه MRC أيضًا، على سبيل المثال لخدمة ثابتة لمدة 12 شهرًا تتوقف بعد هذه النقطة.
نظرًا لأن الإجراءات وActionPlans فريدة لكل خدمة،
فإنها لا تشارك أي شيء مع أي خدمات أخرى.
هذا يعني أنه يمكننا توفيرها بقيم معدلة، ولن يؤثر ذلك على أي خدمات أخرى.
الإضافات والملحقات
تتم معالجة الإضافات / الملحقات مثل شراء بيانات إضافية، حزم التجوال، دقائق دولية، إلخ، بنفس الطريقة تقريبًا. يتم إنشاء إجراء للقيام بما هو مطلوب، مثل فرض قيمة نقدية ثم منح رصيد وحدوي مع انتهاء محدد.
بدلاً من استخدام ActionPlans لإضافتها تلقائيًا إلى الحساب، نقوم فقط بتحفيز ExecuteAction للإجراء الذي أنشأناه للتو مرة واحدة من داخل Ansible.
إضافة أرصدة نقدية مدفوعة مسبقًا
بالنسبة للأرصدة النقدية المدفوعة مسبقًا، مثل خطة PAYG بقيمة 10 دولارات، تتم إضافتها كرصيد نقدي، ولكن مع أولوية أعلى.
سيكون حد الائتمان على هذه الخدمات للرصيد الافتراضي 0 دولار.
حدود الائتمان / منع الإنفاق المفرط
تُستخدم ThresholdS على كل حساب لتعيين الحد الأقصى للإنفاق لفترة زمنية معينة.
بالنسبة للعملاء المدفوعين مسبقًا / PAYG، يكون هذا 0 دولار.
التفاعل مع OCS عبر CRM
لكل خدمة يمكنك رؤية Balances وActionPlans وActions
وThresholdS من OCS من داخل API CRM.
يمكن إزالة ActionPlans حسب الحاجة من API CRM، وتنفيذها عبر
كتب Ansible. يمكن إضافة ActionPlans حسب الحاجة، من CRM،
عن طريق إضافة إضافة/خدمة وتنفيذها عبر كتب Ansible.
يمكن تعطيل حسابات OCS، مما سيوقف تنفيذ ActionPlans ومنع الخدمات من أن تكون قابلة للاستهلاك.
بالنسبة لحدود الائتمان، يتم تعيين قيمة ThresholdS وفقًا للسياسة الخاصة بالمنتج.
عرض وإدارة ActionPlans في CRM
يتم عرض وإدارة ActionPlans (تكوينات التجديد التلقائي) من خلال واجهة CRM، مما يسمح للموظفين والعملاء برؤية التجديدات التلقائية القادمة وإدارتها.
كيفية استرداد ActionPlans وعرضها
عند عرض خدمة في CRM، يتم استرداد ActionPlans تلقائيًا وعرضها:
-
مكالمة API - عند استدعاء
GET /crm/service/{service_id}، يقوم API:- باسترداد سجل الخدمة من قاعدة البيانات
- استخراج
service_uuid(معرف حساب OCS) - استدعاء
get_cgrates_action_plans_by_service_uuid(service_uuid)منcgrates_service.py - يستدعي هذا داخليًا
ocs.Get_ActionPlans(service_uuid)لاسترداد ActionPlans من CGRateS
-
هيكل بيانات ActionPlan - يحتوي كل ActionPlan تم إرجاعه على:
{
"ActionPlanId": "ServiceID_abc-123-def__ProductID_456__...",
"PlanName": "خطة التجديد الشهرية",
"NextExecTime": "2025-02-01T00:00:00Z",
"custom_NextExecTime_hr": "في 11 يومًا",
"ActionPlanId_split_dict": {
"ServiceID": "abc-123-def",
"ProductID": 456,
"CustomerID": 789,
...
}
}ActionPlanId- معرف فريد يحتوي على معلومات مشفرة عن الخدمة/المنتج/العميلPlanName- اسم خطة العمل (عادةً اسم كتاب التجديد)NextExecTime- الطابع الزمني ISO عندما ستنفذ خطة العمل التاليةcustom_NextExecTime_hr- الوقت القابل للقراءة البشرية حتى التنفيذ (مثل "في 11 يومًا"، "غدًا"، "1 فبراير 2025")ActionPlanId_split_dict- قاموس بمكونات مفككة من ActionPlanId
-
عرض واجهة المستخدم - يتم عرض ActionPlans في مكون ActionPlansTable:
أعمدة الجدول:
- اسم المنتج - يتم استرداده من خلال البحث عن
ProductIDمن ActionPlanId - التكلفة - يظهر
retail_costمن تعريف المنتج - تاريخ التجديد - يعرض
custom_NextExecTime_hr(قابل للقراءة البشرية) - الإجراءات - زران:
- اسم المنتج - يتم استرداده من خلال البحث عن