انتقل إلى المحتوى الرئيسي

التخصيص والتكوين

تشرح هذه الدليل كيفية تخصيص وتكوين OmniCRM ليتناسب مع هوية علامتك التجارية ومتطلبات التشغيل واحتياجات التكامل.

متغيرات البيئة (.env)

يستخدم OmniCRM متغيرات البيئة لتكوين كل من واجهة برمجة التطبيقات الخلفية وواجهة المستخدم الأمامية. هناك ملفان منفصلان .env يتحكمان في جوانب مختلفة من النظام.

تكوين واجهة برمجة التطبيقات الخلفية (.env)

يقع في جذر دليل OmniCRM، يقوم هذا الملف بتكوين اتصالات قاعدة البيانات وتكامل CGRates.

الموقع: /OmniCRM/.env

تكوين قاعدة البيانات:

# قاعدة بيانات MySQL/MariaDB (بيانات CRM)
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_USER=omnitouch
MYSQL_PASSWORD=your_database_password
MYSQL_DATABASE=crm
DB_SERVER=db

# قاعدة بيانات PostgreSQL (بيانات CGRates)
POSTGRES_USER=cgrates
POSTGRES_PASSWORD=cgrates_password
POSTGRES_DB=cgrates_db

تكوين CGRates:

# بيانات اعتماد واجهة برمجة تطبيقات CGRates
CGRATES_API_USER=admin
CGRATES_API_PASS=secret
CGRATES_DB_USER=cgrates
CGRATES_DB_PASS=cgrates_password
CGRATES_DB_NAME=cgrates_db
CGRATES_DB_PORT=5432

اعتبارات الأمان:

  • لا تقم أبداً بإضافة ملفات .env إلى التحكم في الإصدارات - استخدم .env.example كقالب
  • استخدم كلمات مرور قوية - الحد الأدنى 16 حرفًا مع أحرف مختلطة، وأرقام، ورموز
  • قم بتدوير بيانات الاعتماد بانتظام - خاصةً للتوزيعات الإنتاجية
  • تقييد الوصول إلى قاعدة البيانات - استخدم قائمة بيضاء لعناوين IP وقواعد جدار الحماية

تكوين واجهة المستخدم الأمامية (.env)

يقع في دليل OmniCRM-UI، يتحكم هذا الملف في العلامة التجارية والمظهر والتكاملات وعلامات الميزات.

الموقع: /OmniCRM/OmniCRM-UI/.env

مفاتيح واجهة برمجة التطبيقات والتكامل:

# واجهة برمجة تطبيقات خرائط Google (لإكمال العنوان والتشفير الجغرافي)
REACT_APP_GOOGLE_API_KEY=your_google_api_key

# بوابة دفع Stripe
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx

# تعطيل تشغيل المتصفح التلقائي عند بدء npm
BROWSER=none

العلامة التجارية ومعلومات الشركة:

# العلامة التجارية للشركة
REACT_APP_COMPANY_NAME="ShellFone"
REACT_APP_PORTAL_NAME="ShellManager"
REACT_APP_SELF_CARE_NAME="ShellCare"
REACT_APP_COMPANY_TAGLINE="Phones with Shells"

تظهر هذه القيم في جميع أنحاء واجهة المستخدم:

  • COMPANY_NAME - تظهر في عناوين الصفحات، والبريد الإلكتروني، والاتصالات مع العملاء
  • PORTAL_NAME - اسم بوابة الإدارة/الموظفين (مثل، "ShellManager")
  • SELF_CARE_NAME - اسم بوابة الخدمة الذاتية للعملاء (مثل، "ShellCare")
  • COMPANY_TAGLINE - تظهر في شاشات تسجيل الدخول والمواد التسويقية

الإعدادات الإقليمية والتوطين:

# اللغة واللغة المحلية
# اللغات المدعومة: ar, ch, en, fr, gr, it, ru, sp
REACT_APP_DEFAULT_LANGUAGE=en
REACT_APP_LOCALE="en-GB"

# الموقع الافتراضي (لإكمال العنوان)
REACT_APP_DEFAULT_LOCATION="Sydney, Australia"
REACT_APP_DEFAULT_COUNTRY="Australia"

# إعدادات العملة
REACT_APP_CURRENCY_CODE="GBP"
REACT_APP_CURRENCY_SYMBOL="£"

تخصيص نظام الألوان:

# اللون الأساسي (اللون الرئيسي للعلامة التجارية)
REACT_APP_PRIMARY_COLOR=#405189

# خيارات الألوان الإضافية (أمثلة معلق عليها)
# REACT_APP_SECONDARY_COLOR=#2bFFcf
# REACT_APP_TERTIARY_COLOR=#1a9fbf
# REACT_APP_SUCCESS_COLOR=#28a745
# REACT_APP_INFO_COLOR=#17a2b8
# REACT_APP_WARNING_COLOR=#ffc107
# REACT_APP_DANGER_COLOR=#dc3545

يتم تطبيق اللون الأساسي على:

  • رؤوس التنقل
  • أزرار العمل
  • الروابط والتسليط
  • الحالات النشطة
  • عناصر العلامة التجارية

التكاملات مع تطبيقات الويب:

قم بتكوين ما يصل إلى 6 تطبيقات ويب سريعة الوصول تظهر في لوحة الإدارة:

# تطبيق الويب 1: GitHub
REACT_APP_WEB_APP_1_NAME="GitHub"
REACT_APP_WEB_APP_1_URL="https://github.com"
REACT_APP_WEB_APP_1_ICON_PATH="resources/webapp_icons/github.png"

# تطبيق الويب 2: Xero
REACT_APP_WEB_APP_2_NAME="Xero"
REACT_APP_WEB_APP_2_URL="https://go.xero.com/"
REACT_APP_WEB_APP_2_ICON_PATH="resources/webapp_icons/xero.png"

# تطبيق الويب 3-6: تكاملات إضافية
# (قم بالتكوين بشكل مشابه مع NAME و URL و ICON_PATH)

المراقبة والتحليلات:

# تكامل لوحة معلومات Grafana
REACT_APP_GRAFANA_URLS=url1,url2,url3
REACT_APP_GRAFANA_LABELS=label1,label2,label3
REACT_APP_GRAFANA_API_KEY=your-api-key

علامات الميزات:

# روابط الدعم والوثائق
REACT_APP_FAQS_URL=https://docs.yourcompany.com/faqs
REACT_APP_SUPPORT_URL=https://support.yourcompany.com

# تسجيل الدخول الاجتماعي (Google، Facebook، إلخ.)
REACT_APP_ALLOW_SOCIAL_LOGINS=yes

تخصيص الشعار وصورة البداية

يسمح لك OmniCRM باستبدال صور العلامة التجارية الافتراضية بشعار شركتك وشاشات البداية دون تعديل الكود.

ملفات الشعار

يتم تخزين الشعارات في /OmniCRM-UI/src/assets/images/omnitouch/ وتستخدم نظام احتياطي:

الشعارات الافتراضية (دائمًا موجودة):

  • DefaultLogoDark.png - شعار الوضع الداكن (يستخدم على الخلفيات الفاتحة)
  • DefaultLogoLight.png - شعار الوضع الفاتح (يستخدم على الخلفيات الداكنة)

الشعارات المخصصة (اختياري، تأخذ الأولوية عند وجودها):

  • logoSm.png - شعار صغير لشريط جانبي مطوي (موصى به: 100x100px)
  • logoDark.png - شعار داكن بالحجم الكامل للرؤوس (موصى به: 200x50px)
  • logoLight.png - شعار فاتح بالحجم الكامل لشاشات المصادقة (موصى به: 200x50px)

كيف يعمل نظام احتياطي الشعار:

يحاول النظام تحميل الشعارات المخصصة أولاً. إذا لم يكن ملف الشعار المخصص موجودًا، فإنه يعود إلى الافتراضي:

// من Header.js
const tryImport = (filename) => {
try {
return require(`../assets/images/omnitouch/${filename}`);
} catch (err) {
return null; // يعود إلى الافتراضي
}
};

const userLogoSm = tryImport("logoSm.png");
const userLogoDark = tryImport("logoDark.png");
const userLogoLight = tryImport("logoLight.png");

أين تظهر الشعارات:

  • logoSm.png - الشريط الجانبي المطوي، التنقل على الهواتف المحمولة، عرض الرأس الصغير
  • logoDark.png - شريط الرأس الرئيسي (الوضع الفاتح)، رأس لوحة الإدارة
  • logoLight.png - شاشات تسجيل الدخول/التسجيل، الخلفيات الداكنة، دوار المصادقة

استبدال الشعارات:

  1. قم بإنشاء ملفات الشعار الخاصة بك:

    • استخدم تنسيق PNG لدعم الشفافية
    • تطابق الأبعاد الموصى بها أعلاه
    • تأكد من أن الشعارات واضحة في كل من الدقة العادية و retina
  2. أضف إلى OmniCRM:

    # انسخ م��فات الشعار الخاصة بك إلى دليل صور omnitouch
    cp /path/to/your/logoSm.png OmniCRM-UI/src/assets/images/omnitouch/
    cp /path/to/your/logoDark.png OmniCRM-UI/src/assets/images/omnitouch/
    cp /path/to/your/logoLight.png OmniCRM-UI/src/assets/images/omnitouch/
  3. إعادة بناء واجهة المستخدم:

    cd OmniCRM-UI
    npm run build
  4. تحقق من التغييرات:

    • تحقق من رأس الوضع الفاتح (يجب أن يظهر logoDark.png)
    • تحقق من رأس الوضع الداكن (يجب أن يظهر logoLight.png)
    • تحقق من الشريط الجانبي المطوي (يجب أن يظهر logoSm.png)
    • تحقق من شاشة تسجيل الدخول (يجب أن تظهر logoLight.png)

أفضل الممارسات لتصميم الشعار:

  • التباين - تأكد من أن الشعارات مرئية على كل من الخلفيات الفاتحة والداكنة
  • البساطة - يجب أن تكون الشعارات قابلة للتعرف عليها في الأحجام الصغيرة
  • التنسيق - استخدم PNG مع خلفيات شفافة
  • Retina - قدم دقة 2x للشاشات عالية DPI
  • الاتساق - استخدم نفس ألوان العلامة التجارية عبر جميع متغيرات الشعار

شاشات البداية وخلفيات المصادقة

تستخدم شاشات المصادقة (تسجيل الدخول، التسجيل، إعادة تعيين كلمة المرور) خلفية دوارة مع صور قابلة للتخصيص.

الموقع: /OmniCRM-UI/src/pages/AuthenticationInner/authCarousel.js

التكوين الافتراضي:

import logoLight from "../../assets/images/logo-light.png";

// الشعار المعروض على شاشات المصادقة
<img src={logoLight} alt="" height="18" />

تخصيص شاشات المصادقة:

  1. استبدل logo-light.png في /OmniCRM-UI/src/assets/images/
  2. أضف CSS خلفية مخصصة إلى فئة .auth-one-bg
  3. عدل الاقتباسات الدوارة في authCarousel.js لتتناسب مع صوت علامتك التجارية

مثال على التخصيص:

/* أضف إلى CSS المخصص الخاص بك */
.auth-one-bg {
background-image: url('/assets/images/custom-auth-bg.jpg');
background-size: cover;
background-position: center;
}

ملف تكوين CRM (crm_config.yaml)

يعد ملف crm_config.yaml هو التكوين المركزي لواجهة برمجة تطبيقات OmniCRM، ويتحكم في التكاملات، والتوفير، وقوالب البريد الإلكتروني، والخدمات الخارجية.

الموقع: /OmniCRM/OmniCRM-API/crm_config.yaml

تكوين قاعدة البيانات

database:
username: omnitouch
password: omnitouch2024
server: localhost

ملاحظة: يجب أن يتطابق هذا مع بيانات اعتماد قاعدة البيانات الخاصة بك في .env. في التوزيعات الحاوية، يكون الخادم عادةً db (اسم خدمة Docker).

أنواع الخدمات

حدد أنواع الخدمات الصالحة لتوزيعك:

service_types:
- omnicharge
- mobile
- fixed
- fixed-voice
- hotspot
- dongle

تستخدم هذه الأنواع في جميع أنحاء النظام لـ:

  • تصنيف المنتجات
  • تصفية الإضافات (تتطابق الإضافات مع أنواع الخدمات)
  • سير العمل في التوفير
  • التقارير والتحليلات

تكامل HSS (خادم المشترك المنزلي)

لمشغلي الشبكات المحمولة مع تكامل HSS:

hss:
hss_peers:
- 'http://10.179.2.140:8080'
apn_list: "1,2,3,4,5,6"

التكوين:

  • hss_peers - قائمة بنقاط نهاية HSS لتوفير المشتركين
  • apn_list - قائمة مفصولة بفواصل من معرفات APN المتاحة للتوفير

تكوين قالب بريد Mailjet

يستخدم OmniCRM Mailjet للبريد الإلكتروني المعاملاتي. يحتوي كل نوع بريد إلكتروني على تكوين قالب خاص به:

mailjet:
api_key: your_mailjet_api_key
api_secret: your_mailjet_api_secret

# بريد الترحيب بالعميل
api_crmCommunicationCustomerWelcome:
from_email: "support@yourcompany.com"
from_name: "Your Company Support"
template_id: 5977509
subject: "Welcome to YourCompany"

# بريد فاتورة العميل
api_crmCommunicationCustomerInvoice:
from_email: "billing@yourcompany.com"
from_name: "Your Company Billing"
template_id: 6759851
subject: "Your Invoice - "

# تذكير بالفاتورة
api_crmCommunicationCustomerInvoiceReminder:
from_email: "billing@yourcompany.com"
from_name: "Your Company Billing"
template_id: 5977570
subject: "Invoice Payment Reminder"

# بريد الترحيب بالمستخدم (الموظف/الإداري)
api_crmCommunicationUserWelcome:
from_email: "admin@yourcompany.com"
from_name: "Your Company Admin"
template_id: 6118112
subject: "Welcome to the Team"

# طلب إعادة تعيين كلمة المرور
api_crmCommunicationUserPasswordReset:
from_email: "security@yourcompany.com"
from_name: "Your Company Security"
template_id: 6735666
subject: "Password Reset Request"

# تأكيد نجاح إعادة تعيين كلمة المرور
api_crmCommunicationUserPasswordResetSuccess:
from_email: "security@yourcompany.com"
from_name: "Your Company Security"
template_id: 6118378
subject: "Password Reset Successful"

# إشعار تغيير كلمة المرور
api_crmCommunicationUserPasswordChange:
from_email: "security@yourcompany.com"
from_name: "Your Company Security"
template_id: 6118423
subject: "Password Changed"

# تحقق من البريد الإلكتروني
api_crmCommunicationEmailVerification:
from_email: "verify@yourcompany.com"
from_name: "Your Company Verification"
template_id: 6267350
subject: "Verify Your Email Address"

# إشعار انتهاء الرصيد
api_crmCommunicationsBalanceExpired:
from_email: "alerts@yourcompany.com"
from_name: "Your Company Alerts"
template_id: 7238252
subject: "Service Balance Expired"

# تحذير من رصيد منخفض
api_crmCommunicationsBalanceLow:
from_email: "alerts@yourcompany.com"
from_name: "Your Company Alerts"
template_id: 7238263
subject: "Low Balance Warning"

إنشاء قوالب Mailjet:

  1. قم بتسجيل الدخول إلى لوحة معلومات Mailjet (<https://app.mailjet.com>)
  2. انتقل إلى TransactionalTemplates
  3. أنشئ قالبًا جديدًا أو استنسخ قالبًا موجودًا
  4. لاحظ معرف القالب (قيمة عددية)
  5. أضف متغيرات القالب التي تتطابق مع هيكل بيانات OmniCRM
  6. قم بتحديث crm_config.yaml بمعرف القالب

متغيرات القالب المتاحة:

يتلقى كل نوع بريد إلكتروني متغيرات محددة. أمثلة شائعة:

  • {{customer_name}} - اسم العميل أو المستخدم
  • {{service_name}} - اسم الخدمة أو المنتج
  • {{invoice_id}} - رقم الفاتورة
  • {{invoice_amount}} - إجمالي مبلغ الفاتورة
  • {{due_date}} - تاريخ استحقاق الدفع
  • {{reset_link}} - رابط إعادة تعيين كلمة المرور
  • {{verification_link}} - رابط التحقق من البريد الإلكتروني
  • {{balance}} - الرصيد الحالي للحساب
  • {{expiry_date}} - تاريخ انتهاء الرصيد أو الخدمة

تكوين التوفير

provisioning:
failure_list: ['admin@yourcompany.com', 'ops@yourcompany.com']

الغرض:

  • failure_list - عناوين البريد الإلكتروني التي يتم إخطارها عند فشل توفير Ansible
  • تشمل الإشعارات اسم playbook، وتفاصيل الخطأ، ومعلومات العميل
  • يسمح لفريق العمليات بالاستجابة بسرعة لمشاكل التوفير

تكوين الفاتورة

invoice:
template_filename: 'yourcompany_invoice_template.html'

الغرض:

يحدد أي قالب HTML من Jinja2 يجب استخدامه لإنشاء فاتورة PDF.

موقع القالب: /OmniCRM-API/invoice_templates/

راجع قسم إنشاء PDF الفاتورة أدناه للحصول على تفاصيل حول إنشاء قوالب مخصصة.

عنوان URL الأساسي لـ CRM

crm:
base_url: 'http://localhost:5000'

الغرض:

  • يستخدمه playbooks الخاصة بـ Ansible لإجراء استدعاءات وا��هة برمجة التطبيقات
  • يستخدم في قوالب البريد الإلكتروني لإنشاء روابط إلى CRM
  • يجب أن يكون عنوان URL القابل للوصول للجمهور لواجهة برمجة التطبيقات الخاصة بك (ليس أسماء الحاويات الداخلية)

أمثلة:

  • التطوير: http://localhost:5000
  • الإنتاج: https://api.yourcompany.com
  • Docker: http://omnicrm-api:5000 (التواصل الداخلي بين الحاويات)

تكوين OCS و CGRates

ocs:
ocsApi: 'http://10.179.2.142:8080/api'
ocsTenant: 'mnc380.mcc313.3gppnetwork.org'
cgrates: 'localhost:2080'

التكوين:

  • ocsApi - نقطة نهاية واجهة برمجة تطبيقات OCS لإدارة المشتركين
  • ocsTenant - معرف المستأجر لتوزيعات OCS متعددة المستأجرين
  • cgrates - نقطة نهاية واجهة برمجة تطبيقات CGRates JSON-RPC (host:port)

تكوين SMSC (بوابة SMS)

smsc:
source_msisdn: 'YourCompany'
smsc_url: 'http://10.179.2.216/SMSc/'
api_key: 'your_smsc_api_key'

الغرض:

  • إرسال إشعارات SMS للعملاء (رصيد منخفض، تنبيهات الخدمة، رموز 2FA)
  • source_msisdn - معرف المرسل المعروض للمستلمين (ألفبائي أو رقم هاتف)
  • smsc_url - نقطة نهاية واجهة برمجة تطبيقات بوابة SMSC
  • api_key - مصادقة لواجهة برمجة تطبيقات SMSC

مفتاح سري JWT

jwt_secret: '2b93110f723db60172c8e9a1eaa80027a9a9c3f05b44e50dc3fcf38dba68d87e'

الأمان:

  • يستخدم لتوقيع والتحقق من رموز المصادقة
  • يجب تغييره من القيمة الافتراضية في الإنتاج
  • قم بإنشاء سلسلة عشوائية آمنة (الحد الأدنى 64 حرفًا)
  • لا تشارك أو تضف إلى التحكم في الإصدارات

إنشاء JWT Secret جديد:

# إنشاء مفتاح عشوائي آمن من الناحية التشفيرية
python3 -c "import secrets; print(secrets.token_hex(32))"

تكوين دفع Stripe

stripe:
secret_key: 'sk_live_xxxxxxxxxx'
publishable_key: 'pk_live_xxxxxxxxxx'
currency: 'aud'
statement_descriptor_suffix: 'YOURCOMPANY'

التكوين:

  • secret_key - مفتاح واجهة برمجة التطبيقات السري لـ Stripe (من جانب الخادم، احتفظ به سريًا)
  • publishable_key - مفتاح واجهة برمجة التطبيقات القابل للنشر لـ Stripe (من جانب العميل، آمن للكشف)
  • currency - رمز العملة ISO 4217 (aud، usd، gbp، eur، إلخ.)
  • statement_descriptor_suffix - يظهر على بيانات بطاقة الائتمان الخاصة بالعميل

استخدام وصف البيان:

  • يظهر على بيانات العملاء المصرفية كـ "YOURCOMPANY"
  • الحد الأقصى 22 حرفًا
  • يساعد العملاء في تحديد الرسوم
  • يستخدم أيضًا في أسماء ملفات PDF للفواتير (مثل، YOURCOMPANY_12345.pdf)

مفاتيح واجهة برمجة التطبيقات وقائمة بيضاء لعناوين IP

حدد مفاتيح واجهة برمجة التطبيقات مع وصول قائم على الأدوار وقيود IP:

api_keys:
"YOUR_API_KEY_1":
roles: ["admin"]
ips: ["127.0.0.1", "::1"]
"YOUR_API_KEY_2":
roles: ["customer_service_agent_1"]
ips: ["127.0.0.1", "::1", "10.0.1.0/24"]

# قائمة بيضاء لعناوين IP (مستقلة، بدون مفتاح واجهة برمجة التطبيقات)
ip_whitelist:
"10.179.2.142":
roles: ["admin"]

الغرض:

  • السماح للأ��ظمة الخارجية بالمصادقة عبر مفتاح واجهة برمجة التطبيقات
  • تقييد الوصول حسب عنوان IP
  • منح أدوار محددة لمستهلكي واجهة برمجة التطبيقات
  • مفيد للتكاملات (أنظمة الفوترة، المراقبة، الأتمتة)

أفضل ممارسات الأمان:

  • استخدم مفاتيح واجهة برمجة التطبيقات طويلة وعشوائية (الحد الأدنى 32 حرفًا)
  • قيد عناوين IP على المصادر المعروفة فقط
  • منح الحد الأدنى من الأدوار اللازمة
  • تدوير مفاتيح واجهة برمجة التطبيقات بانتظام
  • مراقبة استخدام مفاتيح واجهة برمجة التطبيقات في السجلات

إنشاء PDF الفاتورة

ينشئ OmniCRM فواتير PDF احترافية باستخدام قوالب HTML من Jinja2 و WeasyPrint لتوليد PDF.

كيف يعمل إنشاء PDF

  1. اختيار القالب:
    • يتم تحديد اسم ملف القالب في crm_config.yaml تحت invoice.template_filename
    • يتم تحميل القالب من دليل /OmniCRM-API/invoice_templates/
  2. إعداد البيانات:
    • يتم جلب ��يانات الفاتورة (ID، التواريخ، المبالغ، الحالة) من قاعدة البيانات
    • يتم استرداد معلومات العميل (الاسم، العنوان)
    • يتم تجميع قائمة المعاملات (جميع الرسوم/الائتمانات على الفاتورة)
  3. تقديم القالب:
    • يقوم Jinja2 بتقديم قالب HTML مع بيانات الفاتورة
    • يتم استبدال المتغيرات مثل {{ invoice_number }}، {{ total_amount }}، إلخ.
    • يتم حفظ HTML المقدم في invoice_templates/rendered/ لأغراض التصحيح
  4. إنشاء PDF:
    • يقوم WeasyPrint بتحويل HTML المقدم إلى PDF
    • يدعم PDF تنسيق CSS، والصور، وفواصل الصفحات، والرؤوس/التذييلات
    • يتم إنشاء بيانات PDF الثنائية في الذاكرة
  5. التخزين المؤقت:
    • يتم ترميز PDF بتنسيق Base64 وتخزينه في جدول Invoice_PDF_Cache
    • يتم حساب تجزئة SHA256 للتحقق من النزاهة
    • تعيد الطلبات اللاحقة PDF المخزن مؤقتًا (تسليم فوري)
  6. إبطال التخزين المؤقت:
    • يتم إبطال التخزي�� المؤقت عند تعديل الفاتورة أو إلغائها أو استردادها
    • لا تؤدي تغييرات القالب تلقائيًا إلى إبطال التخزين المؤقت الحالي

هيكل قالب الفاتورة

تكون قوالب الفواتير ملفات HTML من Jinja2 تحتوي على متغيرات ومنطق مضمن.

موقع القالب: /OmniCRM-API/invoice_templates/yourcompany_invoice_template.html

المتغيرات المتاحة:

{
'invoice_number': 12345,
'date': '2025-01-04',
'client': {
'name': 'John Smith',
'address': {
'address_line_1': '123 Main St',
'city': 'Sydney',
'state': 'NSW',
'zip_code': '2000',
'country': 'Australia'
}
},
'transaction_list': [
[
{
'transaction_id': 1,
'title': 'Mobile Service - Monthly Fee',
'retail_cost': 30.00,
'wholesale_cost': 10.00,
'created': '2025-01-01'
},
{
'transaction_id': 2,
'title': 'Data Addon - 5GB',
'retail_cost': 15.00,
'wholesale_cost': 5.00,
'created': '2025-01-15'
}
]
],
'total_amount': 45.00,
'due_date': '2025-01-31',
'start_date': '2025-01-01',
'end_date': '2025-01-31',
'paid': False,
'void': False
}

مثال على مقتطف القالب:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Invoice {{ invoice_number }}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.invoice-details {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #405189;
color: white;
}
.total {
text-align: right;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="header">
<img src="file:///path/to/logo.png" alt="Company Logo" height="60">
<h1>INVOICE</h1>
</div>

<div class="invoice-details">
<p><strong>Invoice Number:</strong> {{ invoice_number }}</p>
<p><strong>Date:</strong> {{ date }}</p>
<p><strong>Due Date:</strong> {{ due_date }}</p>
<p><strong>Billing Period:</strong> {{ start_date }} to {{ end_date }}</p>
</div>

<div class="customer-details">
<h3>Bill To:</h3>
<p>{{ client.name }}</p>
<p>{{ client.address.address_line_1 }}</p>
<p>{{ client.address.city }}, {{ client.address.state }} {{ client.address.zip_code }}</p>
<p>{{ client.address.country }}</p>
</div>

<table>
<thead>
<tr>
<th>Description</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
{% for transaction in transaction_list[0] %}
<tr>
<td>{{ transaction.title }}</td>
<td>{{ transaction.created }}</td>
<td>${{ "%.2f"|format(transaction.retail_cost) }}</td>
</tr>
{% endfor %}
</tbody>
</table>

<div class="total">
<p>Total Amount Due: ${{ "%.2f"|format(total_amount) }}</p>
</div>

{% if paid %}
<div style="text-align: center; color: green; font-weight: bold;">
PAID
</div>
{% endif %}

{% if void %}
<div style="text-align: center; color: red; font-weight: bold;">
VOID
</div>
{% endif %}
</body>
</html>

أفضل الممارسات للقالب:

  • استخدم مسارات مطلقة للصور - file:///absolute/path/to/image.png
  • CSS مضمن - لا يقوم WeasyPrint بتحميل أوراق الأنماط الخارجية بشكل موثوق
  • اختبر مع بيانات عينة - استخدم invoice_templates/rendered/ لفحص HTML
  • فواصل الصفحات - استخدم <div style="page-break-after: always;"></div> للفواتير متعددة الصفحات
  • الرؤوس والتذييلات - استخدم قواعد CSS @page للعناصر المتكررة
  • تنسيق العملة - استخدم مرشحات Jinja2: {{ "%.2f"|format(amount) }}

إنشاء قالب فاتورة مخصص

  1. انسخ قالب المثال:

    cd /OmniCRM/OmniCRM-API/invoice_templates
    cp norfone_invoice_template.html yourcompany_invoice_template.html
  2. عدل القالب:

    • استبدل اسم الشركة، والشعار، ومعلومات الاتصال
    • اضبط التنسيق (الألوان، الخطوط، التخطيط) ليتناسب مع العلامة التجارية
    • أضف أو أزل الأقسام حسب الحاجة (تفاصيل الضرائب، تعليمات الدفع، إلخ.)
  3. تحديث التكوين:

    عدل crm_config.yaml:

    invoice:
    template_filename: 'yourcompany_invoice_template.html'
  4. اختبر إنشاء الفاتورة:

    • أنشئ فاتورة اختبار في CRM
    • قم بتنزيل PDF والتحقق من التنسيق
    • تحقق من invoice_templates/rendered/{invoice_id}.html لأغراض التصحيح
  5. إبطال التخزين المؤقت القديم (إذا لزم الأمر):

    إذا قمت بتغيير القالب وترغب في إعادة إنشاء الفواتير الحالية:

    -- مسح جميع ملفات PDF المخزنة مؤقتًا (يجبر على إعادة الإنشاء)
    DELETE FROM Invoice_PDF_Cache;

نظام التخزين المؤقت لـ PDF

لتحسين الأداء، يقوم OmniCRM بتخزين PDFs المولدة مؤقتًا:

سلوك التخزين المؤقت:

  • الطلب الأول - يتم إنشاء PDF، وتخزينه مؤقتًا، وإرجاعه
  • الطلبات اللاحقة - يتم إرجاع PDF المخزن مؤقتًا على الفور (بدون إعادة إنشاء)
  • إبطال التخزين المؤقت - يحدث عند تعديل الفاتورة أو إلغائها أو استردادها
  • تنظيف التخزين المؤقت - يتم تلقائيًا تطهير التخزين المؤقت القديم بعد 30 يومًا من عدم النشاط

تخزين التخزين المؤقت:

  • PDF مشفر بتنسيق Base64 مخزن في جدول Invoice_PDF_Cache
  • تجزئة SHA256 لمحتوى التحقق من النزاهة
  • يتضمن اسم الملف، وطابع الزمن الإنشائي، وطابع الزمن الأخير الذي تم الوصول إليه

إدارة التخزين المؤقت اليدوية:

# في واجهة برمجة تطبيقات OmniCRM أو وحدة Python
from services.invoice_service import cleanup_old_pdf_cache, invalidate_invoice_cache
from utils.db_helpers import get_db_session

session = get_db_session()

# تنظيف التخزين المؤقت الأقدم من 30 يومًا
result = cleanup_old_pdf_cache(session, days_old=30)
print(result) # {'status': 'success', 'deleted_count': 15}

# إبطال التخزين المؤقت لفاتورة معينة
invalidate_invoice_cache(session, invoice_id='12345')

نقاط النهاية لواجهة برمجة التطبيقات:

إنشاء/تنزيل PDF الفاتورة:

GET /invoice/pdf/{invoice_id}

الاستجابة: تنزيل ملف PDF مع اسم الملف من وصف بيان Stripe

رؤوس التخزين المؤقت:

  • الطلب الأول: استجابة أبطأ (وقت الإنشاء)
  • الطلبات المخزنة مؤقتًا: استجابة فورية
  • نجاح/فشل التخزين المؤقت شفاف للمستخدم

استكشاف الأخطاء وإصلاحها

فشل إنشاء PDF:

  • تحقق من تثبيت WeasyPrint: pip install weasyprint
  • تحقق من تطابق اسم ملف القالب مع crm_config.yaml
  • تحقق من invoice_templates/rendered/ لأخطاء تقديم HTML
  • راجع سجلات واجهة برمجة التطبيقات لأخطاء قالب Jinja2

عدم ظهور الصور في PDF:

  • استخدم مسارات ملفات مطلقة: file:///full/path/to/image.png
  • تأكد من وجود ملفات الصور وقابليتها للقراءة
  • تحقق من تنسيق الصورة (تعمل PNG و JPEG بشكل أفضل)
  • تحقق من أن مسارات الصور لا تحتوي على أحرف خاصة

مشاكل التنسيق:

  • قم بتضمين جميع CSS (لا تدعم أوراق الأنماط الخارجية)
  • تجنب ميزات CSS المعقدة (قد لا يتم تقديم flexbox و grid بشكل صحيح)
  • اختبر مع تخطيطات بسيطة أولاً، ثم أضف التعقيد تدريجيًا
  • استخدم الجداول للتخطيط بدلاً من divs حيثما كان ذلك ممكنًا

عدم إبطال التخزين المؤقت:

  • تحقق من أنه يتم استدعاء invalidate_invoice_cache() عند تعديل الفاتورة
  • تحقق من أن تحديثات المعاملات تؤدي إلى إبطال التخزين المؤقت
  • احذف يدويًا من جدول Invoice_PDF_Cache إذا لزم الأمر

قائمة التحقق من التكوين

استخدم هذه القائمة عند نشر OmniCRM:

تكوين الخلفية

  • [ ] انسخ .env.example إلى .env
  • [ ] قم بتعيين كلمات مرور قوية لقاعدة البيانات
  • [ ] قم بتكوين بيانات اعتماد CGRates
  • [ ] تحديث crm_config.yaml بإعداداتك:
    • [ ] اتصال قاعدة البيانات
    • [ ] أنواع الخدمات
    • [ ] مفاتيح واجهة برمجة تطبيقات Mailjet ومعرفات القوالب
    • [ ] عناوين البريد الإلكتروني لإشعارات فشل التوفير
    • [ ] اسم ملف قالب الفاتورة
    • [ ] عنوان URL الأساسي لـ CRM (قابل للوصول للجمهور)
    • [ ] نقاط نهاية OCS/CGRates
    • [ ] تكوين SMSC
    • [ ] إنشاء مفتاح سري JWT جديد
    • [ ] مفاتيح Stripe (حقيقية، ليست تجريبية)
    • [ ] مفاتيح واجهة برمجة التطبيقات وقائمة بيضاء لعناوين IP

تكوين الواجهة الأمامية

  • [ ] انسخ OmniCRM-UI/.env.example إلى OmniCRM-UI/.env
  • [ ] قم بتعيين مفتاح واجهة برمجة تطبيقات خرائط Google
  • [ ] قم بتعيين مفتاح Stripe القابل للنشر
  • [ ] تحديث العلامة التجارية للشركة:
    • [ ] اسم الشركة
    • [ ] اسم البوابة
    • [ ] اسم الخدمة الذاتية
    • [ ] شعار الشركة
  • [ ] قم بتكوين التوطين:
    • [ ] اللغة الافتراضية
    • [ ] اللغة المحلية
    • [ ] الموقع الافتراضي والدولة
    • [ ] رمز العملة والرمز
  • [ ] قم بتعيين اللون الأساسي للعلامة التجارية
  • [ ] قم بتكوين تكاملات تطبيق الويب (اختياري)
  • [ ] أضف روابط الدعم والأسئلة الشائعة (اختياري)

أصول العلامة التجارية

  • [ ] إنشاء ملفات الشعار (logoSm.png، logoDark.png، logoLight.png)
  • [ ] تحميل الشعارات إلى OmniCRM-UI/src/assets/images/omnitouch/
  • [ ] إنشاء HTML لقالب الفاتورة المخصص
  • [ ] تحميل قالب الفاتورة إلى OmniCRM-API/invoice_templates/
  • [ ] تحديث crm_config.yaml باسم ملف قالب الفاتورة
  • [ ] اختبار إنشاء PDF للفواتير
  • [ ] إعادة بناء واجهة المستخدم: npm run build

الأمان

  • [ ] تغيير جميع كلمات المرور الافتراضية
  • [ ] إنشاء JWT سري فريد
  • [ ] استخدام مفاتيح Stripe الإنتاجية (ليست مفاتيح تجريبية)
  • [ ] تدوير مفاتيح واجهة برمجة تطبيقات Mailjet
  • [ ] تمكين قواعد جدار الحماية
  • [ ] تكوين قائمة بيضاء لعناوين IP للوصول إلى واجهة برمجة ا��تطبيقات
  • [ ] إعداد شهادات SSL/TLS
  • [ ] تمكين HTTPS لجميع نقاط النهاية
  • [ ] مراجعة إعدادات CORS
  • [ ] تنفيذ تحديد معدل
  • [ ] تكوين إجراءات النسخ الاحتياطي والاسترداد

الاختبار

  • [ ] اختبار تدفق تسجيل العملاء
  • [ ] اختبار توفير الخدمة من البداية إلى النهاية
  • [ ] التحقق من إرسال إشعارات البريد الإلكتروني بشكل صحيح
  • [ ] اختبار إنشاء الفاتورة وتنزيل PDF
  • [ ] التحقق من معالجة الدفع (Stripe)
  • [ ] التحقق من مصادقة المستخدم و 2FA
  • [ ] اختبار الانتحال وتسجيل التدقيق
  • [ ] التحقق من مزامنة بيانات الاستخدام من OCS
  • [ ] اختبار إنشاء خطة العمل وتجديدها
  • [ ] تأكيد أن تخصيص المخزون يعمل بشكل صحيح

النشر

  • [ ] بناء صور Docker أو نشرها على الخوادم
  • [ ] بدء حاويات قاعدة البيانات (MySQL، PostgreSQL)
  • [ ] بدء CGRates
  • [ ] بدء واجهة برمجة تطبيقات OmniCRM
  • [ ] بدء واجهة مستخدم OmniCRM
  • [ ] تكوين الوكيل العكسي (nginx، traefik)
  • [ ] إعداد المراقبة (Grafana، Prometheus)
  • [ ] تكوين تجميع السجلات
  • [ ] إعداد النسخ الاحتياطية التلقائية
  • [ ] توثيق بنية النشر
  • [ ] تدريب الموظفين على استخدام النظام

الوثائق ذات الصلة