سجل التحديثات الشامل لإضافة Branch Games Manager (BGM)
الإصدار 1.3.5.3 — 2026-06-08
🐛 إصلاحات حرجة
📨 إصلاح توجيه الإشعارات — وصول الرسائل لولي الأمر فقط بدل اللاعب وولي الأمر
المشكلة:
بعض الإشعارات (الغياب، التأخير، الحضور، انتهاء الاشتراك…) كانت تُرسل لولي الأمر فقط رغم اختيار “اللاعب وولي الأمر”.
السبب الجذري:
القيم الافتراضية في النظام كانت 'parent' بدل 'both' في عدة أماكن:
get_option()كان يرجع'parent'عند عدم وجود قيمة محفوظة- مصفوفة القوالب
$templates_infoكانت تستخدم'default_rec' => 'parent' - القوائم في صفحة الإعدادات كانت تعرض “ولي الأمر فقط” كخيار افتراضي
- دالة التثبيت
set_default_options()كانت تحفظ'parent'كبداية
الحل:
توحيد القيم الافتراضية إلى 'both' في جميع أجزاء النظام:
class-bgm-notifications.php— تعديل 12 fallbackhtml-bm-message-templates.php— تعديل 18 قالبclass-bgm-settings.php— تعديل 11 قائمة إعداداتclass-bgm-trial-service.php— تعديل 3 حالاتclass-bgm-install.php— تعديل القيم الافتراضية
ملاحظة مهمة:
بعد التحديث، يجب الدخول إلى إعدادات القوالب واختيار “اللاعب وولي الأمر” ثم الحفظ لتحديث القيم الحالية.
🔀 إصلاح تمديد العضوية الخطأ عند شراء خطة مختلفة (Cross-Plan Stacking)
المشكلة:
لاعب لديه عضوية شهرية نشطة، وعند شراء عضوية سنوية يتم تمديد الشهرية بدل إنشاء عضوية جديدة.
السبب:
منطق التمديد كان يعتمد على مطابقة عامة بين المنتجات والخطط بدون التحقق من الـ variation الفعلي.
الحل:
إضافة تحقق يضمن أن المنتج الجديد هو نفس الـ variation الأصلي:
- قراءة
_product_idمن العضوية - مقارنته بالمنتج في الطلب الجديد
- نفس المنتج → تمديد
- منتج مختلف → إنشاء عضوية جديدة
الملف:class-bgm-branch-product-binding.php
✨ تحسينات
📱 منع تكرار الرسائل لنفس الرقم بصيغ مختلفة (Phone Deduplication)
المشكلة:
إرسال نفس الرسالة مرتين لنفس الرقم بسبب اختلاف الصيغة (مثال: 056xxxxxxx و 9665xxxxxxx).
السبب:
المقارنة كانت نصية مباشرة.
الحل:
إضافة نظام توحيد الأرقام:
normalize_phone()لتحويل الرقم للصيغة الدوليةis_duplicate_phone()للمقارنة بعد التوحيد- التطبيق داخل
get_recipient_phones()لجميع الإشعارات
الملف:class-bgm-notifications.php
🔒 منع تسجيل حضور لاعب من فرع آخر (Cross-Branch Attendance Guard)
المشكلة:
إمكانية تسجيل حضور لاعب من فرع مختلف باستخدام كود اللاعب.
السبب:
عدم التحقق من تطابق فرع اللاعب مع فرع المستخدم في ajax_quick_code_attendance().
الحل:
إضافة تحقق بين فرع اللاعب وفرع المدير:
- في حالة الاختلاف تظهر رسالة:
⚠️ اللاعب [اسم] تابع لفرع آخر ([اسم الفرع]) — لا يمكن تسجيل حضوره من هذا الفرع
استثناء:
الأدمن يمكنه تسجيل حضور أي لاعب.
يشمل:
الإدخال اليدوي + QR
الملف:trait-bma-attendance.php
الإصدار 1.3.5.2 — 2026-05-29
🐛 إصلاحات حرجة
🔄 إصلاح عدم تجديد العضوية عند إعادة شراء نفس الـ Variation
المشكلة:
العضوية لا تتجدد عند شراء نفس الاشتراك بعد انتهائها.
السبب الجذري:
7 مشاكل داخل reactivate_expired_memberships:
- المطابقة غير شاملة
- غياب مطابقة
_product_id - عدم تحديث تاريخ الانتهاء
- فشل حفظ التغييرات
- عدم تحديث تاريخ البدء
- اختلاف أنواع البيانات
- بقاء بيانات قديمة تؤثر على الحالة
الحل:
- إعادة كتابة الميثود بالكامل
- إضافة 6 طبقات مطابقة
- تحديث الحالة مباشرة عبر
wp_update_post - تحديث البيانات عبر
update_post_meta - تنظيف الكاش
- حذف بيانات الإلغاء والإيقاف
- إضافة VERIFY step
- fallback لمدة الاشتراك (30 يوم)
- Debug logging كامل
الملف:class-bgm-branch-product-binding.php
💾 إصلاح حفظ قوالب رسائل الإجازة
المشكلة:
إعدادات المستلم لا تُحفظ بشكل صحيح.
الحل:
إضافة القوالب الناقصة في save handler.
الملف:class-bgm-branches-manager-account.php
✨ ميزات جديدة
📱 رسالة تجديد الاشتراك (membership_renewed)
- رسالة تلقائية عند التجديد
- متغيرات متعددة +
{plan_name} - Toggle مفعل افتراضياً
- حماية من التكرار باستخدام
order_id
🔒 إخفاء الاشتراكات التجريبية عند التعطيل
- تظهر فقط عند التفعيل
- تختفي من القائمة عند التعطيل
- منع الوصول المباشر مع رسالة توضيحية
📅 تمديد الاشتراك النشط (Stacking)
- إضافة المدة الجديدة على الحالية
- مثال: 15 يونيو → 15 يوليو
- رسالة
membership_extended - حماية من التكرار
🛡️ منع مضاعفة مدة الاشتراك لأول مرة
الحل:
مقارنة _order_id لتجنب التمديد الخاطئ لنفس الطلب.
الملف:class-bgm-branch-product-binding.php
الإصدار 1.3.5 — 2026-05-27
✨ ميزات جديدة
🏖️ نظام الإيقاف الجماعي للعضويات (Bulk Holiday Pause)
الوصف:
إيقاف مؤقت جماعي لعضويات اللاعبين أثناء الإجازات الرسمية مع تمديد تلقائي عند الاستئناف.
- فلاتر مرنة: اختيار فرع / لعبة / جنس (بنين أو بنات) أو تطبيق على الجميع
- تضمين العضويات التجريبية: خيار لتحديد شمولها من عدمه
- جدولة مستقبلية: تحديد تاريخ بداية مستقبلي، والكرون يفعّل الإجازة تلقائيًا
- استئناف تلقائي: عند انتهاء الإجازة يتم إعادة تفعيل العضويات وإضافة أيام الإيقاف
- حماية الإيقاف الفردي: أي إيقاف/استئناف يدوي أثناء الإجازة لا يتم التعديل عليه
- عضويات جديدة أثناء الإجازة: يتم إيقافها تلقائيًا إذا تم الاشتراك خلال فترة الإجازة
- واجهة إدارة متكاملة:
- Card مستقل داخل صفحة الفروع
- فورم جدولة
- بانر حالة الإجازة
- سجل كامل للإيقافات
- Modal تأكيد: يعرض عدد العضويات المتأثرة وملخص الفلاتر قبل التنفيذ
- سجل الإيقافات: عرض جميع العمليات (جماعي / فردي) مع فلاتر وتقسيم صفحات
- إلغاء مرن:
- الإجازة المجدولة: حذف فقط وكأنها لم تُنشأ
- الإجازة النشطة: إنهاء فوري مع احتساب الأيام وإضافتها
- قوالب واتساب:
holiday_pause_startedholiday_pause_ended
مع متغيرات مخصصة
- كرون يومي:
bgm_check_holiday_status
يعمل الساعة 7 صباحًا ومتاح من إدارة الكرون - تنبيه الحضور: عند تسجيل حضور لعضوية موقوفة، يظهر سبب الإيقاف وتاريخ الانتهاء
🛡️ حماية من التكرار (Deduplication Guards)
🔒 رسائل الإجازة — حماية بثلاث طبقات
- الطبقة 1:
GET_LOCK(MySQL)
يمنع تنفيذ الإيقاف أو الاستئناف أكثر من مرة في نفس اللحظة - الطبقة 2:
post_meta
(_bgm_holiday_pause_notified/_bgm_holiday_resume_notified)
يمنع إرسال نفس الرسالة لنفس العضوية خلال نفس الإجازة - الطبقة 3:
notification_log
طبقة أمان إضافية لمنع التكرار في نفس اليوم
📁 الملفات المتأثرة
class-bgm-membership-service.php
إضافة 7 methods جديدة + hook + تحسين منطق الإيقاف والاستئنافclass-bgm-branches-manager-account.php
إضافة واجهة Card + عدد 4 AJAX handlersclass-bgm-notifications.php
إضافة 2 methods للإشعارات + تسجيل hooksclass-bgm-attendance.php
إضافة تنبيه عند محاولة تسجيل حضور أثناء الإجازةhtml-bm-message-templates.php
إضافة 2 قالب + 4 متغيرات جديدةclass-bgm-install.php
إنشاء جدولbgm_holiday_pause_log+ إعدادات افتراضية + تسجيل الكرونclass-bgm-cron-manager.php
تسجيل hook الخاص بالإجازات
الإصدار 1.3.4 — 2026-05-22
✨ ميزات جديدة
⏰ نظام تنبيه اقتراب انتهاء الاشتراك (Expiry Reminder)
الوصف:
إرسال رسالة واتساب تلقائية لأولياء الأمور أو اللاعبين قبل انتهاء الاشتراك بعدد أيام محدد.
⚙️ إعدادات مدير الفروع
/bm-branches/
- تفعيل / إيقاف الميزة (الافتراضي: معطل)
- تحديد عدد الأيام قبل الانتهاء (من 1 إلى 30 — الافتراضي: 7)
- عرض/إخفاء الإعدادات بشكل ديناميكي حسب حالة التفعيل
💬 قالب الرسالة (expiry_reminder)
- يظهر فقط عند تفعيل الميزة
- يدعم اختيار المستلم:
- ولي الأمر
- اللاعب
- الاثنين
- متغير جديد:
{days_remaining}→ عدد الأيام المتبقية
- يحتوي على رسالة افتراضية بالعربي مع إيموجي
⏳ الكرون اليومي
bgm_check_expiry_reminders
- يعمل يوميًا الساعة 8 صباحًا
- متاح في إدارة الكرون:
- تشغيل / إيقاف
- تعديل الإعدادات
- يدعم التشغيل عبر System Cron ping
📁 الملفات المرتبطة
html-bm-message-templates.phpclass-bgm-branches-manager-account.phpclass-bgm-notifications.phpclass-bgm-install.phpclass-bgm-cron-manager.php
🛡️ حماية من التكرار (Deduplication Guards)
🔒 تنبيه اقتراب الانتهاء — حماية بثلاث طبقات
الطبقة 1:GET_LOCK (MySQL)
→ يمنع تشغيل الكرون أكثر من مرة في نفس اللحظة
الطبقة 2:post_meta: _bgm_expiry_reminder_sent
→ تخزين تاريخ الانتهاء المرتبط بالإرسال
- نفس التاريخ → ❌ لا يتم الإرسال
- تاريخ جديد (بعد التجديد) → ✅ يتم الإرسال
الطبقة 3:notification_log
→ طبقة أمان إضافية لنفس اليوم
📌 ملاحظة:
العضويات التجريبية (Trial) مستثناة تلقائيًا
🔒 رسالة انتهاء العضوية (membership_expired)
المشكلة:
WooCommerce Memberships قد يطلق status_changed أكثر من مرة
الحل:
استخدام post_meta: _bgm_expired_notification_sent
- يتم تخزين تاريخ الانتهاء
- لن يتم الإرسال مرة أخرى لنفس التاريخ
📁 الملف:class-bgm-notifications.php
🔒 رسالة استئناف العضوية (membership_resumed)
المشكلة:
قد يتم تفعيل الـ hook أكثر من مرة في نفس اليوم
الحل:
فحص notification_log
- إذا تم الإرسال اليوم → ❌ لا يتم التكرار
📁 الملف:class-bgm-notifications.php
🧠 ملخص سريع
- إضافة نظام تنبيه ذكي قبل انتهاء الاشتراك
- تحكم كامل من لوحة الإدارة
- حماية قوية من التكرار (3 طبقات)
- تكامل كامل مع نظام الكرون
الإصدار 1.3.3 — 2026-05-10
🔧 تحسينات تقنية
⚠️ كشف اللاعبين بدون عضوية (No-Membership Detection)
- المشكلة: صفحة التحضير تعرض 93 لاعب بينما صفحة إدارة العضويات تعرض 88 فقط — الفرق هو لاعبين مسجلين في الفرع (
bgm_player_games) بدون أي عضوية WooCommerce. - الحل (3 تحسينات):
- صفحة التحضير: إضافة تنبيه
⚠️ X لاعب بدون عضوية نشطةفي معلومات الفرع + بادج تحذيرية بجنب اسم كل لاعب بدون عضوية. - صفحة العضويات: إضافة كارت إحصائي جديد
⚠️ بدون عضويةيعرض عدد اللاعبين المسجلين بدون عضوية. - مودال التفاصيل: عند الضغط على كارت “بدون عضوية” يظهر مودال بقائمة كاملة (الاسم، البريد، الهاتف، اللعبة) مع نصيحة للمدير بإنشاء عضوية أو إلغاء التسجيل.
- صفحة التحضير: إضافة تنبيه
- الأداء: استعلام واحد فقط (
SELECT DISTINCT post_author FROM wp_posts WHERE post_type='wc_user_membership') — بدون تأثير على سرعة التحميل. - الملفات:
trait-bma-attendance.php،trait-bma-memberships.php
🧾 عرض الكوبون والخصم في الفاتورة (Invoice Coupon Display)
- المشكلة: الفاتورة كانت تعرض فقط “المجموع الفرعي” و”الإجمالي” — بدون توضيح إذا تم استخدام كوبون أو تطبيق خصم.
- الحل: إضافة عرض تفصيلي للكوبونات في قسم الإجمالي:
- 🎟️ اسم الكوبون المستخدم (بخط عريض وأخضر)
- مبلغ الخصم لكل كوبون
- يدعم كوبونات متعددة على نفس الطلب
- Fallback: لو فيه خصم بدون كوبون (خصم يدوي)، يعرض “الخصم” بالطريقة القديمة
- يشمل: الفاتورة الكاملة (Full Page) + فاتورة المودال (AJAX Modal)
- الملف:
class-bgm-invoice.php
⏱️ تمديد تلقائي للعضوية عند الاستئناف (Auto-Extend on Resume)
- الخيار: toggle جديد في صفحة
/bm-branches/— “تمديد تلقائي عند استئناف الإيقاف المؤقت” - السلوك عند التفعيل:
- عند إيقاف العضوية مؤقتاً → يتم حفظ تاريخ الإيقاف (
_bgm_paused_at) - عند الاستئناف → يتم حساب عدد أيام الإيقاف وإضافتها على
end_dateتلقائياً - يتم إضافة ملاحظة (note) على العضوية بتفاصيل التمديد
- عند إيقاف العضوية مؤقتاً → يتم حفظ تاريخ الإيقاف (
- مثال: إيقاف يوم 25 أبريل → استئناف 1 مايو = 6 أيام → العضوية تتمدد من 10 مايو إلى 16 مايو
- الملفات:
class-bgm-membership-service.php،class-bgm-branches-manager-account.php
▶️ رسالة واتساب عند استئناف العضوية (Membership Resume Notification)
- قالب جديد:
membership_resumed— يظهر في صفحة قوالب الرسائل - المتغيرات:
{paused_days}،{old_end_date}،{new_end_date}+ المتغيرات الأساسية - يتم الإرسال تلقائياً عند الاستئناف مع تمديد (لو خيار التمديد مفعل)
- الملفات:
class-bgm-notifications.php،html-bm-message-templates.php
📨 خيار إشعارات الغياب/التأخير للعضويات الموقوفة (Paused Notifications Toggle)
- الخيار: toggle جديد في صفحة
/bm-branches/— “إرسال رسائل الغياب والتأخير للعضويات الموقوفة” - عند التفعيل: اللاعبين الموقوفين مؤقتاً يوصلهم رسائل غياب وتأخير كأنهم نشطين
- ملاحظة: الـ Backend logic كان موجود أصلاً — التعديل أضاف الخيار في واجهة مدير الفروع (Frontend)
- الملف:
class-bgm-branches-manager-account.php
الإصدار 1.3.2 — 2026-04-30
✨ ميزات جديدة
👔 إضافة موظفين من حساب مدیر الفروع (bm-staff)
- زر إضافة جديد في حساب مدير الفروع صفحة الموظفين.
- إضافة مرنة: يمكن إضافة إداريين، مديري فروع، ومدربين مباشرة من الواجهة الأمامية دون دخول لوحة تحكم ووردبريس.
- تخصيص الفئة: عند إضافة إداري، يظهر حقل لاختيار تخصيصه للبنين، البنات، أو الكل لتفعيل نظام فلترة العرض التلقائي حسب الجنس في باقي لوحات التحكم.
- التعيين والصلاحيات: يتم إنشاء الحساب، تعيين الفرع والصلاحيات، وتوليد كود الـ QR بالإضافة إلى تسجيل العملية في Activity Log بشكل آلي.
🆓 دمج الاشتراكات التجريبية في صفحة إدارة العضويات
- رؤية موحدة: ظهور الاشتراكات التجريبية جنباً إلى جنب مع العضويات المدفوعة في صفحة إدارة العضويات.
- شريط إحصائيات: إضافة بطاقة إحصائية مخصصة للاشتراكات التجريبية.
- إجراءات سريعة:
- أزرار تحويل و إلغاء مخصصة تظهر فقط للاشتراكات التجريبية، مع استخدام نوافذ التحويل التلقائية المدمجة بـ AJAX.
- الفلترة الذكية: الاشتراكات التجريبية تتفلتر تلقائياً حسب صلاحيات المدير (بالفرع والجنس).
🔧 تحسينات تقنية
🧾 توحيد كود الفواتير (Invoice Consolidation)
- ملف مركزي جديد:
class-bgm-invoice.phpكمرجع موحد لجميع عمليات الفواتير بدلاً من التكرار السابق. - تقليل التكرار: تم حذف حوالي 900 سطر برمجي مكرر من
trait-bma-payments.phpوclass-bgm-membership-orders.php. - توحيد المظهر والبيانات: الفواتير سواء في صيغة Modal، صفحة منفصلة، أو PDF أصبحت تشارك نفس التنسيق ونفس البيانات المستخرجة (بما فيها الـ Variations).
🔧 تحسينات UX
📥 تصدير المصروفات CSV
- ميزة جديدة: إضافة زر “تصدير CSV” في قسم المصروفات بلوحة الإيرادات.
- فلترة ذكية: التصدير يتبع نفس فلاتر العرض الحالية (الفرع، التاريخ، التصنيف، القسم).
- أمان: التصدير محمي بـ nonce + التحقق من الصلاحيات + عزل الفرع.
- دعم العربية: استخدام UTF-8 BOM لضمان عرض النصوص العربية في Excel.
📋 عداد حالة القوالب
- ميزة جديدة: إضافة شريط حالة في أعلى تبويب قوالب الرسائل يعرض:
- عدد القوالب المعبأة من الإجمالي.
- تنبيه بعدد القوالب الفارغة مع توضيح أنها ستستخدم الرسالة الافتراضية.
- تلوين ديناميكي: الشريط يظهر أخضر لو كل القوالب معبأة، وأصفر لو فيه قوالب فارغة.
📨 إضافة “إرسال إلى” لقوالب التجربة
- الحالة السابقة: قوالب الاشتراك التجريبي الثلاثة (بدء التجربة، حضور بعد الانتهاء، انتهاء التجربة) كانت ترسل لولي الأمر فقط.
- التحسين: إضافة dropdown “إرسال إلى” (ولي الأمر / اللاعب / كلاهما) لكل قالب تجريبي.
- تحديث Backend: تم تعديل
class-bgm-trial-service.phpلاستخدامBGM_Notifications::get_recipient_phones()بدلاً من إرسال مباشر لـparent_phone.
🐛 إصلاحات
🔧 إصلاح القوالب الافتراضية الفارغة
- المشكلة: 8 قوالب رسائل كانت تظهر فارغة في صفحة الإعدادات بعد الحفظ بدون تعبئة. السبب:
get_option('...', $default)يرجع القيمة المخزنة (نص فاضي) ومش بيفعّل الـ default. - الحل: تغيير المنطق لاستخدام
!empty($val) ? $val : $defaultفي كل القوالب:- التقرير الشهري، تعيين الجدول، الانصراف (Checkout)، حصة السماح، انتهاء الاشتراك، كوبون الولاء
- بدء التجربة، حضور بعد انتهاء التجربة، انتهاء التجربة
- إضافة رسائل افتراضية: القوالب التي لم يكن لها default أصلاً (Checkout، التجربة الثلاثة) تم إضافة رسائل افتراضية لها مطابقة للقيم في كود الإرسال.
📊 إصلاح تصدير الصفحة الحالية في الإيرادات
- المشكلة: تصدير “الصفحة الحالية” في الإيرادات كان يستخدم
per_page = 15بينما واجهة العرض تعرض20صف في الصفحة. - النتيجة: فقدان 5 صفوف عند تصدير الصفحة الحالية.
- الحل: توحيد
per_page = 20في كلا المكانين.
✋ تأكيد حصص السماح قبل التحضير (Grace Session Confirmation)
- السلوك القديم: عند تحضير لاعب اشتراكه منتهي (عادي أو تجريبي) وعنده حصص سماح متبقية، كان النظام يحضّره تلقائياً بدون سؤال الإداري — فيستهلك حصة سماح بدون علم المسؤول.
- السلوك الجديد (3 مسارات):
- زر التحضير اليدوي: يظهر رسالة تأكيد
confirm()توضح أن الاشتراك منتهي وعدد حصص السماح المتبقية من الإجمالي — الإداري يختار “نعم” أو “إلغاء”. - ماسح QR: يظهر الرسالة في شريط الحالة الأصفر +
confirm()— لو الإداري وافق يُحضر ويعرض “تم (سماح)”، لو رفض يعرض “تم الإلغاء”. - كود اللاعب: يظهر
confirm()— لو الإداري وافق يرسل request ثاني بـforce_grace=1.
- زر التحضير اليدوي: يظهر رسالة تأكيد
- اشتراك منتهي بدون حصص سماح: رسالة واضحة
🚫 اشتراكه منتهي — يرجى تجديد الاشتراك أولاًبدون خيار تحضير. - الملفات:
trait-bma-attendance.php(backend + frontend JS)،class-bgm-attendance.php
🔁 إصلاح إنشاء عضوية تجريبية مزدوجة
- المشكلة: عند اشتراك لاعب في التجربة المجانية، كان يتم إنشاء عضويتين: واحدة من WooCommerce Memberships تلقائياً (مرتبطة بالـ variation)، وأخرى يدوياً من الإضافة عبر
wp_insert_post. - السبب: الإضافة كانت تمنع WooCommerce Memberships من إنشاء العضوية التلقائية عبر فلاتر، ثم تُنشئ عضوية يدوية بخطة مختلفة.
- الحل:
- حذف فلاتر المنع (
wc_memberships_grant_access_from_new_purchaseوwc_memberships_access_granting_purchased_product_id) — السماح لـ WooCommerce Memberships بالعمل طبيعياً. - إعادة هيكلة
swap_trial_membershipلتعمل كـ “أداة تصحيح مسار” (Safety Net) بـ priority 999:- تتحقق من العضوية اللي أنشأها النظام تلقائياً.
- لو الخطة صحيحة (المحددة في
bgm_trial_membership_plan)، يتم ضبط تاريخ الانتهاء فقط. - لو الخطة خاطئة، يتم تعديلها للخطة الصحيحة.
- في حال عدم وجود عضوية، يتم استخدام
wc_memberships_create_user_membership(الـ API الرسمي) كخيار احتياطي.
- حذف أي استخدام لـ
wp_insert_postلإنشاء العضويات — ضمان التوافق مع تحديثات WooCommerce Memberships المستقبلية.
- حذف فلاتر المنع (
- الملف:
class-bgm-branch-product-binding.php
⏰ إصلاح التوقيت الخاطئ في عرض حضور الموظفين واللاعبين
- المشكلة: وقت تسجيل الحضور كان يظهر بفارق ساعات عن التوقيت الفعلي (مثلاً: تسجيل الحضور الساعة 4 مساءً يظهر 7 مساءً).
- السبب: الوقت يتخزن صحيحاً بـ
current_time('H:i:s')(توقيت محلي). لكن عند العرض،wp_date('H:i', strtotime($time))كان يعمل تحويل مزدوج:strtotimeيعتبر الوقت المحلي كـ UTC، ثمwp_dateيضيف فارق التوقيت مرة أخرى. - الحل: عرض الوقت المخزن مباشرة بدون تحويل (بـ
substr($time, 0, 5)) وإضافةgmt=trueلدوالdate_i18nفي الإشعارات. - الملفات المتأثرة (5 أماكن):
trait-bma-staff.php— عرض وقت حضور الموظف في صفحة التحضيرtrait-bma-players.php— عرض وقت الحضور في كالندر حضور الموظفينclass-bgm-branches-manager-account.php— عرض وقت حضور اللاعبين في سجل الحضور (سطر 1212)class-bgm-branches-manager-account.php— عرض وقت حضور الموظفين في سجل الحضور (سطر 2143)class-bgm-notifications.php— وقت الحضور والانصراف في إشعارات الواتساب (سطر 1018 و 1028)
🚫 منع الحضور للاعبين بدون عضوية نشطة
- المشكلة: النظام كان يسمح بتسجيل حضور لاعبين ليس لديهم أي عضوية WooCommerce بالأساس.
- الحل: تمت إضافة فحص جذري (
!has_membership) في جميع مسارات الحضور (زر التحضير اليدوي، الكود السريع، وماسح الـ QR). - النتيجة: النظام يمنع فوراً أي تفاعل ويُظهر رسالة صريحة بتجديد الاشتراك للاعبين الذين ليس لديهم سجل اشتراك.
✉️ إصلاح رسائل انتهاء الفترة التجريبية والمشتركين تجريبياً
- المشكلة: عند انتهاء الفترة التجريبية للاعب، كان النظام يرسل الرسالة العامة لانتهاء الاشتراك بدلاً من قالب رسالة التجربة، وأحياناً لا يرسل رسائل في حال عدم حفظ الإعدادات.
- الحل 1: منع إرسال إشعار انتهاء الـ WooCommerce Membership للاشتراكات المرتبطة بعضوية التجربة المجانية (
bgm_trial_membership_plan)، لتتولى الدالة المخصصة للتجربة الإرسال فقط. - الحل 2: إضافة نصوص احتياطية (Fallbacks) لجميع رسائل فترة التجربة (بداية، انتهاء، وحضور بعد الانتهاء) لضمان إرسالها للعميل حتى في حالة عدم تخصيصها من لوحة التحكم.
🔁 إصلاح إرسال رسائل التأخير والغياب مكررة
- المشكلة: رسائل “تنبيه غياب” و”تنبيه تأخير” كانت تتبعت مرتين لنفس اللاعب في نفس الوقت بالظبط.
- السبب: Race Condition — دالة
check_late_and_absence_notificationsكانت ممكن تتشغل في نفس اللحظة من مسارين: WP-Cron المجدول + System Cron ping (handle_cron_ping). الاتنين بيفحصواbgm_notification_logويلاقوا$already = 0ويبعتوا الرسالة. - الحل (3 طبقات حماية):
- MySQL Concurrency Lock: إضافة
GET_LOCK('bgm_absence_check', 0)في بداية الدالة — لو عملية تانية شغالة، العملية الجديدة بتتجاهل فوراً. - Atomic Duplicate Check في
send_absence_notification: فحصbgm_notification_logمرة تانية قبل الإرسال الفعلي كخط دفاع أخير. - Atomic Duplicate Check في
send_late_notification: نفس الحماية لرسائل التأخير.
- MySQL Concurrency Lock: إضافة
- الملف:
class-bgm-notifications.php
🔄 مزامنة بيانات الاشتراك التجريبي عند تعديل العضوية
- المشكلة: عند تعديل تواريخ أو حالة العضوية من صفحة إدارة العضويات، كانت صفحة “جدولي وألعابي” عند اللاعب تعرض بيانات قديمة (مثلاً “7 يوم متبقي” رغم تغيير التاريخ) — لأن جدول
bgm_trial_subscriptionsلم يكن يُحدَّث. - الحل: إضافة منطق مزامنة في
ajax_edit_membershipيحدّث تلقائياً:- تواريخ البدء والانتهاء في
bgm_trial_subscriptions - حالة الاشتراك التجريبي (
active/expired) - سجلات
bgm_player_games(تفعيل/إلغاء تفعيل حسب الحالة الجديدة)
- تواريخ البدء والانتهاء في
- الملف:
trait-bma-memberships.php
⏰ انتهاء العضوية تلقائياً عند تغيير تاريخ الانتهاء للماضي
- المشكلة: عند تعديل
end_dateليصبح في الماضي بدون تغيير الحالة صراحةً، كانت العضوية تبقىactiveفي WooCommerce Memberships — مما يسمح بتسجيل الحضور رغم انتهاء العضوية فعلياً. - الحل: إضافة فحص تلقائي بعد تحديث التواريخ: إذا كان
end_dateفي الماضي ولم يُحدَّد status جديد، يتم تغيير حالة العضوية تلقائياً إلىexpired. - الملف:
trait-bma-memberships.php
🔄 إصلاح عرض كارد الاشتراك التجريبي رغم انتهاء العضوية
- المشكلة: عند تعديل حالة العضوية إلى “منتهية” من صفحة إدارة العضويات، كانت صفحة “جدولي وألعابي” للاعب لا تزال تعرض كارد الاشتراك التجريبي بأيام متبقية — رغم أن العضوية انتهت فعلياً.
- السبب (3 مشاكل):
- مقارنة صارمة: في
ajax_edit_membershipكانت المقارنة$plan->get_id() === $trial_plan_idبـ===ممكن تفشل بسبب اختلاف النوع (int vs string). - عدم مزامنة في العضويات غير التجريبية: لو العضوية المُعدَّلة ليست على الخطة التجريبية، لا يتم تحديث
bgm_trial_subscriptionsإطلاقاً. - استعلام العرض بدون فحص التاريخ: صفحة “جدولي وألعابي” كانت تجلب الاشتراكات بشرط
status = 'active'فقط بدون التحقق منend_dateأو حالة العضوية.
- مقارنة صارمة: في
- الحل (3 طبقات حماية):
- إصلاح المقارنة: تغيير
===إلى==فيajax_edit_membership. - Safety Net: لو العضوية أصبحت expired/cancelled/paused → يتم تحديث جميع الاشتراكات التجريبية النشطة لهذا المستخدم إلى
expired. - طبقات فحص في صفحة العرض: إضافة شرط
end_date >= TODAY+ Self-healing للاشتراكات المنتهية + فحص حالة عضويات WooCommerce الفعلية.
- إصلاح المقارنة: تغيير
- الملفات:
trait-bma-memberships.php،class-bgm-my-account.php
🛒 استقرار جلسة دفع متجر ووكومرس (Checkout Session Stability)
- المشكلة: ظهور تنبيه خطأ وهمي “عذراً لقد انتهت صلاحية جلستك” لبضع ثوانٍ بعد ضغط زر الدفع وقبل تحويل المشتري لصفحة الشكر.
- السبب: يقوم WooCommerce أحياناً بطلب استعلامات متأخرة عن السلة (التي فُرّغت للتو بنجاح في الخلفية) ما يؤدي لظهور التنبيه.
- الحل:
- حقن كود JS في خلفية الدفع يعمل كمراقب (DOM Observer) لالتقاط وحجب هذه الإشعارات الوهمية أثناء فترة معالجة الطلب لعدم تشتيت العميل.
- تعميم حفظ حالة الجلسة (
session->save_data) وتفريغ السلة على جميع بوابات دفع الإضافة (الكاش، الشبكة، والتجريبي المجاني) لتعزيز موثوقية التوجيه لصفحة الشكر. - تم إصلاح خطأ برمجي (Syntax Error) إضافي في ملف
class-bgm-branch-product-binding.phpمتعلق بتصاريح الجلسة.
🔒 تحسينات أمنية واستقرار النظام
🛡️ تأمين واجهات لوحة تحكم اللاعب (Frontend Security Guard)
- إضافة حماية قوية تمنع الإداريين (Admins/Managers) من التصفح الخطأ داخل ملفات العميل (My Account) في الواجهة الأساسية.
- التوجيه التلقائي المباشر لأي مدير لو حاول الوصول لهذه الصفحات إلى لوحة الإدارة المختصة به.
- يقتصر السماح وتفعيل الصفحات الأمامية حصراً على دور
playerوcustomer.
🧹 تنظيف السلات عند التبديل الآمن (Cart clearing on Logout)
- إضافة آلية أوتوماتيكية تقوم بتفريغ السلة
WC()->cart->empty_cart()بمجرد عمل تسجيل الانصراف / الخروج للمدير أو الحساب المسجل. - يضمن ذلك عدم تداخل المنتجات الموجودة بالسلة عند تجربة حجز جديدة أو الدخول بحساب ولي أمر من نفس المتصفح.
الإصدار 1.3.1 — 2026-04-20
✨ ميزات جديدة
🆓 نظام الاشتراك التجريبي (Trial Subscription)
- اشتراك تجريبي مجاني لمدة أسبوع: يمكن للاعبين تجربة خدمة الأكاديمية لمدة 7 أيام قبل الالتزام بالشراء
- تفعيل من إعدادات مدير الفروع: خيار تشغيل/إيقاف الاشتراك التجريبي مع تحديد عدد حصص السماح التجريبية
- زر التجريبي على صفحة المنتج:
- يظهر فقط للمستخدمين المسجلين غير المشتركين
- يختفي تلقائياً عند استخدام التجربة مسبقاً أو إيقاف النظام
- ربط كامل بـ AJAX لتسجيل التجربة فورياً بدون إعادة تحميل
- تسجيل تلقائي كامل عند بدء التجربة:
- إنشاء سجل في
bgm_trial_subscriptionsوbgm_player_games - تعيين الفرع واللعبة والجنس تلقائياً
- إنشاء كود QR للاعب (إذا لم يكن موجوداً)
- إضافة تلقائية للمجموعة المطابقة (لعبة + فرع + جنس)
- إنشاء سجل في
📋 صفحة إدارة التجارب (manage-trials)
- صفحة جديدة في حساب مدير الفرع/الإداري لعرض وإدارة الاشتراكات التجريبية
- بطاقات إحصائية: الكل / نشط / منتهي / محوّل — كلها قابلة للنقر للفلترة
- جدول متكامل: اسم اللاعب، اللعبة، الحالة، البداية/النهاية، الحضور، حصص السماح
- فلترة بالجنس (
admin_category): يرى كل مدير الفرع فقط اللاعبين حسب قسمه
💳 تحويل سريع من تجريبي إلى مشترك
- زر “تحويل لمشترك” في جدول التجارب (للمنتهية فقط)
- نافذة تحويل (Modal): اختيار طريقة الدفع (كاش/شبكة) وإنشاء طلب WooCommerce كامل
- تحويل تلقائي: عند إتمام أي طلب عادي من لاعب تجريبي، يتحوّل سجله تلقائياً
💰 بوابات دفع جديدة (كاش / شبكة)
- بوابتا دفع مخصصتان للإداريين فقط — لا تظهر للعملاء العاديين
- دعم في إنشاء الطلبات: dropdown اختيار طريقة الدفع في modal إضافة طلب جديد
✉️ قوالب رسائل تجريبية
- 3 قوالب جديدة في إعدادات قوالب الرسائل (admin + مدير الفروع):
- 🆓 بدء الاشتراك التجريبي — عند تسجيل اللاعب
- ⏰ حضور بعد انتهاء التجربة — عند استخدام حصة سماح تجريبية
- 📢 انتهاء الفترة التجريبية — من الكرون اليومي
- متغيرات مخصصة:
{trial_start_date},{trial_end_date},{player_code}وغيرها
🔄 كرون يومي لإدارة التجارب
- مهمة جديدة
bgm_check_trial_expirationsمسجلة في Cron Manager - تفحص يومياً الاشتراكات المنتهية وتحدّث حالتها وتُلغي تنشيط اللعبة
- ترسل إشعارات انتهاء تلقائية لأولياء الأمور
⏰ دعم التجربة في نظام الحضور
- فحص حالة التجربة قبل التحقق من العضوية في
ajax_mark_attendanceوajax_quick_code_attendance - حصص سماح تجريبية: عند حضور لاعب تجريبي منتهي، يُستهلك من حصص السماح التجريبية
- إشعارات تلقائية عند استخدام حصة سماح تجريبية
- نافذة تفاعلية (Modal) لحصص السماح التجريبية في صفحة التحضير
🗃️ بنية البيانات
- جدول جديد
bgm_trial_subscriptions:user_id,product_id,variation_id,game_id,branch_id,gender,start_date,end_date,status,grace_used,converted_order_id - عمود جديد
is_trialفيbgm_player_games - عمود جديد
is_trial_graceفيbgm_attendance
🔧 تحسينات تقنية
- تقسيم ملف
class-bgm-branch-manager-account.php(12,496 سطر → 492 سطر + 7 ملفات Traits):trait-bma-attendance.php— تحضير اللاعبين وAJAX الحضورtrait-bma-reports.php— التقارير وأكواد QRtrait-bma-players.php— إدارة اللاعبين والإشعارات والجداولtrait-bma-staff.php— إدارة الموظفين والمدربينtrait-bma-memberships.php— العضويات والمجموعاتtrait-bma-payments.php— المدفوعات والإيرادات والمصروفات والفواتيرtrait-bma-facilities.php— الملاعب ونقاط الولاء والتجارب
الإصدار 1.3.0 — 2026-04-10
✨ ميزات جديدة
🗑️ إدارة المستخدمين (حذف اللاعبين) لمدير الفروع
- صفحة جديدة (
bm-users): تبويب جديد في حساب مدير الفروع لعرض وإدارة حسابات اللاعبين - جدول لاعبين متكامل: يعرض الاسم، الفرع، الجنس، ولي الأمر، ورقم الهاتف
- ترقيم صفحات (Pagination): 20 لاعب في الصفحة مع أزرار ترقيم أنيقة
- فلاتر بحث متقدمة: بحث بالاسم، فلتر بالفرع، فلتر بالجنس
- حذف آمن مع تأكيد برقم الجوال:
- نافذة تأكيد (Modal) تطلب من المدير كتابة رقم جوال اللاعب للتأكيد قبل الحذف
- زر الحذف يبقى معطلاً حتى كتابة الرقم الصحيح بالكامل
- حالة خاصة: إذا لم يكن للاعب رقم جوال مسجل، يظهر تنبيه ويُسمح بالحذف مباشرة
- حذف نهائي شامل: يستخدم
wp_delete_user()الذي يُفعّل hook الـdelete_userلتنظيف جميع بيانات BGM تلقائياً (الحضور، المجموعات، العضويات، الألعاب) - حمايات أمنية متعددة:
- حماية CSRF عبر
check_ajax_referer - التحقق من صلاحيات مدير الفروع (
is_bm) - منع حذف الحساب الذاتي
- السماح بحذف أدوار
player,customer,subscriberفقط - حماية مطلقة ضد حذف
administrator,branches_manager,branch_manager,branch_admin,coach,shop_manager
- حماية CSRF عبر
- تسجيل في Activity Log: كل عملية حذف تُسجَّل مع اسم المحذوف والحاذف والتوقيت
🔒 تحسينات أمنية
إخفاء جميع صفحات الإضافة عند عدم تفعيل الرخصة
- قبل: جميع صفحات الإضافة كانت ظاهرة في القائمة حتى بدون رخصة مفعلة
- بعد: عند عدم تفعيل الرخصة، يظهر فقط تبويب 🔑 الرخصة — لتمكين المدير من تفعيلها
- عند تفعيل الرخصة، تظهر جميع الصفحات بالكامل بما فيها صفحة الرخصة
حاجز حماية WooCommerce في تبويب الكوبونات
- المشكلة: فتح تبويب الكوبونات بدون تفعيل WooCommerce كان يسبب خطأ قاتل (Fatal Error) بسبب عدم وجود
WC_Coupon - الحل: إضافة فحص
class_exists('WC_Coupon')مع عرض رسالة تنبيه واضحة بدلاً من الخطأ
📥 تصدير البيانات
تصدير العضويات (CSV) من لوحة التحكم الأمامية
- إعداد جديد: خيار
تصدير العضوياتفي الإعدادات العامة لتفعيل/تعطيل زر التصدير - زر تصدير ذكي: يظهر في صفحة إدارة العضويات لمدير الفرع ومدير الفروع عند التفعيل
- خيارين عند التصدير:
- 📋 تصدير كامل — يشمل الاسم، البريد، الهاتف، هاتف ولي الأمر، الجنس، اللعبة، الخطة، الحالة، التواريخ، الفرع
- 🔒 تصدير بدون بيانات التواصل — بدون البريد والهاتف (للحماية والخصوصية)
- يحترم جميع الفلاتر: الفرع، اللعبة، الجنس، الخطة، الحالة، البحث
- حماية أمنية: Nonce verification + فحص الصلاحيات + عزل الفرع لمدير الفرع
تحسين تصدير الإيرادات (CSV) — دعم التصدير الذكي للصفحات
- سلوك ذكي: لو البيانات في صفحة واحدة → يصدر مباشرة بدون أسئلة
- لو فيه أكثر من صفحة: يظهر قائمة منسدلة بخيارين:
- 📋 تصدير كل الصفحات — جميع الطلبات المطابقة للفلتر
- 📄 تصدير الصفحة الحالية — فقط الطلبات الظاهرة في الصفحة الحالية
- تحديث تلقائي: الزر يتغير شكله تلقائياً (يظهر ▾) لما فيه صفحات متعددة
الإصدار 1.2.9 — 2026-04-02
🔄 ترقية WAWP WhatsApp API إلى v2
ترقية كاملة لتكامل WhatsApp API
- ترقية Base URL: من
wawp.net/wp-json/awp/v1/إلى[https://api.wawp.net](https://api.wawp.net) - تحديث Endpoints:
- إرسال رسالة نصية:
/v2/send/text(بدل/send) - إرسال صورة:
/v2/send/image(بدل/sendImage) - اختبار الاتصال:
/v2/session/info(بدل/session/info)
- إرسال رسالة نصية:
- إرسال الصور بـ JSON Body: تحويل إرسال الصور من query parameters إلى JSON body كامل مع كشف تلقائي لـ mimetype من امتداد الملف
- حذف دعم v1 القديم: إزالة كامل لكود الـ API القديم (
wawp.net/api/) — الإضافة أصبحت تدعم v2 فقط - توحيد Response Parsing: دمج
parse_response_v1وparse_response_v2في method واحدparse_response()يدعم responses الـ v2 الجديدة (_data,result, rate limiting) - استخراج Auth Helper: method جديد
auth_query()لبناء query string الـ authentication
Migration تلقائي للإعدادات
- تحديث تلقائي لـ API URL: عند تحديث الإضافة، لو الـ URL القديم محفوظ في قاعدة البيانات (
wawp.net/api/أوwawp.net/wp-json/awp/v1/)، يتم تحديثه تلقائياً إلى[https://api.wawp.net](https://api.wawp.net) - تحديث الـ Default URL في صفحة الإعدادات وملف التثبيت
الإصدار 1.2.8 — 2026-03-28
✨ ميزات جديدة
🏆 نظام نقاط الولاء والمكافآت التلقائي (Loyalty System)
- نظام مكافآت مرن مبني على مسارين (التجديدات أو الحضور)
- مسار التجديدات الشهرية:
- كل تجديد لاشتراك يمنح اللاعب نقاط تلقائياً
- عند الوصول لعدد معين من التجديدات، يحصل اللاعب على كوبون خصم تلقائي
- مسار الحضور الفعلي:
- كل جلسة حضور تُسجَّل تمنح اللاعب نقاط
- عند الوصول لعدد معين من الحضور، يُصدر له كوبون خصم تلقائي
- لوحة تحكم متكاملة لمدير الفرع (
bm-loyalty):- الإعدادات: تحكم كامل في المسارين المستقلين، تحديد النقاط، نسبة الخصم، ومدة صلاحية الكوبون
- الإنجازات والمكافآت (Milestones): عرض قائمة اللاعبين المؤهلين للمكافأة لإنشاء الكوبونات يدوياً أو تركها للنظام التلقائي
- سجل اللاعبين: استعراض أرصدة النقاط لجميع لاعبي الفرع، مع إمكانية إضافة أو خصم نقاط يدوياً مع إدراج سبب الحركة
- سجل الحركات (Logs): أرشيف كامل وتفصيلي لكل العمليات (اكتساب، خصم، استبدال)
- معالجة في الخلفية وأمان البيانات:
- العمليات الثقيلة (إنشاء الكوبون وإرسال إشعارات الواتساب) تُعالج في الخلفية (Asynchronous) باستخدام
Action Schedulerلضمان سرعة الواجهة - تحديث الأرصدة يتم بشكل آمن 100% (Atomic SQL) لتفادي تداخل البيانات (Race Conditions)
- العمليات الثقيلة (إنشاء الكوبون وإرسال إشعارات الواتساب) تُعالج في الخلفية (Asynchronous) باستخدام
- إشعار الواتساب التلقائي: إرسال رسالة تبريكات وكود الكوبون للاعب أو ولي أمره أو كليهما بناءً على الإعدادات
✉️ قوالب الرسائل لمدير الفرع (Message Templates)
- إدارة كاملة من حساب فرونت إند: مدير الفرع لم يعد بحاجة لدخول لوحة التحكم (Dashboard)
- صفحة جديدة (
bm-message-templates): يمكن لمدير الفرع تعديل القوالب الـ 12 الأساسية للنظام - مرونة في الاستهداف: تحديد الجهة المستلمة لكل قالب (اللاعب فقط، ولي الأمر فقط، أو كلاهما)
- رسائل متخصصة تشمل: الحضور، الانصراف، التأخير، الغياب، الانتهاء، كود QR، استخراج QR، التقارير الشهرية، حصص السماح، هدايا الولاء، وغيرها
🧾 إدارة الضرائب (Tax Management)
- تبويب جديد للضرائب (
bm-taxes): تم إضافة تاب جديد في حساب مدير الفرع لإدارة الضرائب بسهولة. - التحكم بالتفعيل والإيقاف: تمكين مدير الفرع من تفعيل أو إيقاف ربط واعتماد الضرائب على مستوى نظام WooCommerce بضغطة زر.
- تعديل النسبة القياسية: في حال التفعيل، تظهر قائمة الضرائب القياسية المتاحة لتمكين المدير من تحديث النسبة المئوية (%) بسهولة وبدون صلاحيات زائدة، مما يسهل التحكم بأسعار الاشتراكات.
🎟️ كوبونات الخصم لطلبات الفرع الأمامية (Frontend Coupons)
- إضافة حقل الكوبون: يمكن لمديري الفروع الآن إدخال كود خصم عند إنشاء طلب جديد من نافذة “إضافة طلب” في الواجهة الأمامية.
- التطبيق التلقائي: يتم التحقق من صحة الكوبون وتطبيقه على إجمالي الطلب قبل حفظه في النظام.
🌐 الإعدادات الأساسية الشاملة لنظام الولاء
- خيار “استخدام الإعدادات العامة”: إضافة خيار جديد في إعدادات الولاء لربط إعدادات الفرع بالإعدادات العامة (الأساسية) ليسهل توحيد النظام.
- إدارة مركزية لمدير الفروع: تمت إضافة خيار “🌐 الإعدادات الأساسية لجميع الفروع” في قائمة الفروع لتسهيل تعديل القيم الافتراضية دفعة واحدة.
- تأمين الحقول الذكي: عند تفعيل خيار الإعدادات العامة للفرع، يتم تعطيل الحقول وتظليلها لمنع إحداث تعارض وضمان وراثة القيم.
🛠️ تحسينات وإصلاحات
- الصفحات الفارغة (Taxes & Message Templates): إصلاح جذري لمشكلة ظهور صفحات فارغة (Taxes, Message Templates) بسبب خلل في إعادة بناء الروابط (Rewrite Rules). تم تحديث
maybe_flush()لتتعقب جميع نقاط النهاية الجديدة (bm-revenues,bm-taxes,bm-message-templates,bm-loyalty). - فلترة سجل اللاعبين في نقاط الولاء: استبعاد الإداريين ومديري الفروع والمدربين من الظهور في قائمة اللاعبين في صفحة الولاء.
- إصلاح تحذير
_load_textdomain_just_in_timeالخاص بترجمة إضافات (WooCommerce Memberships) عبر تأجيل تسجيل Endpoints إلى خطافinit.
الإصدار 1.2.7 — 2026-03-22
✨ ميزات جديدة
⚙️ إعدادات حصص السماح (Grace Sessions)
- إعداد جديد في صفحة الفروع (
bm-branches) لمدير الفروع - تفعيل/إيقاف حصص السماح مع تحديد عددها
- عند الإيقاف، يتم تجاهل حصص السماح في جميع حسابات الحضور
✉️ توقيع المرسل على الرسائل (Message Signature)
- إعداد جديد في صفحة الرسائل (
bm-messages) لمدير الفروع - عند التفعيل، يُلحق بكل رسالة يدوية:
اسم المرسل | دوره في الموقع - يعمل مع الرسائل اليدوية فقط:
- رسائل مدير الفروع من
bm-messages - إشعارات مدير الفرع والإداري من صفحة الإشعارات
- رسائل المدرب (فردية وجماعية)
- رسائل مدير الفروع من
- الأدوار المدعومة: مدير الفروع، مدير الفرع، إداري، مدرب، مدير النظام
👨🏫 صلاحية تحضير اللاعبين للمدربين (Coach Attendance)
- إعداد جديد في صفحة الموظفين (
bm-staff) لمدير الفروع - عند التفعيل، يحصل المدربون على صلاحية
scan_player_attendance - عند الإيقاف، تُسحب الصلاحية تلقائياً
🔧 تفاصيل تقنية
- AJAX handler مشترك:
bgm_save_bm_settingsلحفظ جميع الإعدادات الثلاثة - Helper جديد:
get_sender_signature()فيBGM_Branches_Manager_Account - Dynamic capability: صلاحية المدرب تُمنح عبر فلتر
user_has_capبدون تعديل دائم على الدور
🐛 إصلاحات وتحديثات (تحديثات الواجهة الدقيقة)
⚙️ تحسين واجهة إعدادات الإضافة لحصص السماح
- المشكلة: عند قيام مدير الفروع بإيقاف حصص السماح، كانت صفحة الإعدادات العامة للإضافة تعرض “عدد حصص السماح: 1” فقط دون توضيح أن الخاصية موقوفة، مما كان يسبب التباساً.
- الحل: تمت إضافة زر تفعيل/إيقاف صريح في صفحة الإعدادات العامة (
bgm-settings) يتزامن مع اختيار مدير الفروع ليعكس حالة الخاصية الفعلية بشكل مرئي.
👨🏫 تقييد وتحسين واجهة التحضير للمدربين
- المشكلة: بعد تفعيل صلاحية التحضير للمدرب، كانت شاشة التحضير لا تظهر له في قائمة حسابي، وحال ظهورها كانت تسمح بظهور جميع لاعبي الفرع.
- الحل:
- تمت تهيئة واجهة “حسابي” للمدرب لتعرض أيقونة “📋 تحضير اللاعبين” بشكل سليم إلى جانب قوائمه الأساسية من غير تعارض.
- تم ربط دالة الفلترة بمجموعات المدرب، بحيث لا يعرض النظام للمدرب في شاشة التحضير سوى لاعبي المجموعاته المسندة إليه فقط، لضمان الخصوصية وسهولة الاستخدام.
الإصدار 1.2.6 — 2026-03-20
🐛 إصلاحات
🔔 إرسال الإشعارات حسب اللعبة لمدير الفرع
- المشكلة: عند إرسال مدير الفرع إشعاراً باختيار (لعبة معينة)، كانت الرسالة تصل لجميع لاعبي تلك اللعبة في كل الفروع.
- الحل: تقييد الاستعلام بـ
branch_idالخاص بمدير الفرع لضمان وصول الرسالة للاعبي فرعه فقط.
🔍 محرك البحث وعرض الجدول في صفحة إدارة العضويات
- المشاكل:
- البحث بالاسم أو رقم الهاتف لم يكن يعرض اللاعبين الذين انتهت اشتراكاتهم أو ليس لديهم ألعاب نشطة.
- الجدول كان دائماً فارغاً بسبب عدم تطابق بنية الـ response: الـ AJAX يُعيد
{memberships, stats}لكن الـ JS كان يتعامل معres.dataمباشرةً كمصفوفة. - فلتر الحالة لم يكن يعمل: الـ HTML يُرسل
activeبينما WordPress يخزّنwcm-active. - أسماء الحقول غير متطابقة: الـ JS يطلب
start_date/end_dateوالسيرفر يُعيدstart/end. - عمود الفرع كان يعرض
-دائماً لأنbranch_nameلم يكن مُضمَّناً في الـ response. global $wpdbلم يكن مُعلَناً في بداية الـ function بل داخل شرط مشروط.
- الحل:
- تعديل الـ JS ليقرأ
res.data.membershipsبدلاً منres.data. - تصحيح قيم الحالة في الـ HTML إلى
wcm-active/wcm-paused/wcm-expired/wcm-cancelled. - تصحيح أسماء الحقول في الـ JS إلى
item.startوitem.end. - إضافة
branch_nameإلى بيانات كل عضوية في الـ response. - نقل
global $wpdbلأول الـ function. - تعديل استعلام جلب اللاعبين للاعتماد على
user_branchmeta بدلاً من جدول الألعاب المقتصر على الاشتراكات النشطة فقط.
- تعديل الـ JS ليقرأ
📊 بطاقات الإحصائيات في الداشبورد (Admin Dashboard)
- المشكلة: عناصر الإحصائيات لا تحمل IDs فلا يستطيع الـ JS تحديثها، وعداد “اللاعبين” كان مفقوداً من الـ AJAX response
- الحل:
- أُضيفت IDs لجميع بطاقات الإحصائيات (
bgm-card-players,bgm-card-paused,bgm-card-today,bgm-card-week) - أُضيفت بطاقة جديدة لعداد العضويات الموقوفة مؤقتاً (
bgm-paused-count) - مُدِّد الـ AJAX handler
bgm_get_dashboard_stats_ajaxليُعيدplayer_countوpaused_count - حُدِّث JS ليملأ البطاقات الأربع عند استلام الـ response
- أُضيفت IDs لجميع بطاقات الإحصائيات (
🎮 الألعاب في إنشاء المجموعة
- المشكلة: قائمة الألعاب عند إنشاء مجموعة كانت تعتمد فقط على
bgm_player_games— فلو لم يكن هناك لاعبون مسجَّلون بعد، القائمة تكون فارغة - الحل: دمج الألعاب من ثلاثة مصادر:
bgm_player_games(لاعبون مسجَّلون)_bgm_product_gameعلى المنتجات البسيطة المرتبطة بالفرع_bgm_variation_gameعلى التنويعات (Variations) المرتبطة بالفرع
- الملفات:
class-bgm-branch-manager-account.phpوclass-bgm-branches-manager-account.php
🏟️ تحميل المرافق (Venue) لمشرف الفرع (branch_admin)
- المشكلة:
ajax_get_facilities()كانت ترفضbranch_adminلأنBGM_User_Roles::is_branch_manager()لا تشمله - الحل: إضافة فحص
branch_adminصريح في شرط الصلاحية داخلclass-bgm-groups.php
👨🏫 فلتر المدربين حسب الفرع في صفحة المجموعات
- المشكلة:
bm-groups.phpكانت تجلب جميع المدربين في الموقع بغض النظر عن الفرع - الحل: تقييد
get_users()بـmeta_key = user_branchمع قيمة فرع المستخدم الحالي ($view_user_branch) أو الفرع المُختار في الفلتر ($filter_branch)
✨ تحسينات
🔀 حقل الـ Variation في بوب-اب “طلب جديد”
- الميزة: عند إنشاء طلب جديد من صفحة إدارة الطلبات، يظهر الآن حقل إضافي “الخيار (Variation)” عند اختيار منتج متغير
- التفاصيل:
- الـ Variations المعروضة مقيَّدة بالفرع الحالي فقط (من
$branch_product_ids) - الحقل مخفي تلقائياً للمنتجات البسيطة، ويظهر فقط للمنتجات المتغيرة التي لها variations مرتبطة بالفرع
- يُشترط اختيار Variation قبل الإرسال لو الحقل ظاهر
- يُرسَل الـ
variation_idمباشرةً كـproduct_idللـ AJAX handler
- الـ Variations المعروضة مقيَّدة بالفرع الحالي فقط (من
🐛 إصلاحات (تحديث ما بعد الإصدار)
👤 قسم رسائل الموظفين لا يظهر في صفحة إدارة الإشعارات (frontend)
- المشكلة: قسم “إرسال رسائل للموظفين” كان مضافاً فقط في صفحة الأدمن (
bgm-send-messages)، ولم يظهر في صفحةplayer-notificationsالخاصة بمدير الفرع في حساب WooCommerce - الحل: إضافة قسم رسائل الموظفين مباشرةً داخل
player_notifications_content()فيclass-bgm-branch-manager-account.php - الشرط: يظهر فقط للمستخدمين الذين لديهم صلاحية
send_admin_notification
🛒 المنتجات غير المرتبطة لا تظهر في موداَل “طلب جديد”
- المشكلة: استعلام
compare => NOT EXISTSلا يجد المنتجات التي تحمل_bgm_product_branchكمفتاح موجود لكن بقيمة فارغة''(يحدث عند حفظ المنتج من لوحة التحكم بدون اختيار فرع) - الحل: تغيير
meta_queryإلىrelation => ORمع شرطين:NOT EXISTS+= '' - الملف:
includes/class-bgm-membership-orders.php
📎 إضافة مرفق للمصروفات
- الميزة: يمكن الآن رفع مرفق (صورة أو PDF) عند إضافة مصروف أو تعديله
- الصلاحيات: متاح لمدير الفرع، مشرف الفرع، ومدير الفروع
- عرض المرفق: يظهر أيقونة 📎 قابلة للنقر في عمود “مرفق” بجدول المصروفات
- التعديل: في موداَل التعديل يظهر رابط “عرض المرفق الحالي” مع خيار حذفه أو استبداله بملف جديد
- حماية المصروفات:
- لو مفعّلة: المرفق مقفول مع باقي بيانات المصروف — لا يمكن تعديله أو حذفه لغير مدير الفروع
- مدير الفروع يستطيع التعديل والحذف بغض النظر عن حالة الحماية
- التنظيف: عند حذف المصروف أو استبدال المرفق يُحذف الملف تلقائياً من السيرفر
- التحقق: صور (jpg, png, gif, webp) وملفات PDF — حجم أقصاه 5MB
- الملفات:
includes/class-bgm-install.php،includes/class-bgm-branch-manager-account.php
🛒 المنتجات غير المرتبطة بفرع في موداَل “طلب جديد”
- الميزة: المنتجات التي لا تحمل ربطاً بفرع (كالطقم الرياضي) تظهر الآن في قائمة المنتجات داخل موداَل إنشاء طلب جديد من صفحة إدارة الطلبات
- التفاصيل:
- يُجلَب المنتجات غير المرتبطة (
_bgm_product_branch NOT EXISTS) ويُضاف إلى$modal_products - للمنتجات المتغيرة غير المرتبطة: تُعرض جميع variations عبر
get_children()بدلاً من تقييدها بـ$branch_product_ids
- يُجلَب المنتجات غير المرتبطة (
- الملف:
includes/class-bgm-membership-orders.php
🐛 إصلاحات
📦 ظهور طلبات المنتجات غير المرتبطة بفرع في إدارة الطلبات
- المشكلة: عندما يشتري لاعب منتجاً غير مربوط بفرع (مثل الطقم الرياضي)، لم يكن الطلب يظهر في صفحة إدارة الطلبات لمدير الفرع
- الحل:
- عند الحفظ: في
_save_order_branch_meta()أُضيف منطق fallback: إذا لم يُحدَّد فرع من المنتجات، يُستخدم فرع اللاعب المسجَّل (user_branch)، ثم الفرع المختار من الجلسة (bgm_selected_branch) كاحتياط ثانٍ - عند العرض: في
get_filtered_branch_orders()أُضيف استعلام ثانٍ بـwc_get_orders()يبحث عن الطلبات المُوسومة بـ_bgm_order_branchبدلاً من الاعتماد على منتجات الطلب فقط
- عند الحفظ: في
- الملف:
includes/class-bgm-branch-product-binding.phpوincludes/class-bgm-membership-orders.php
🔔 إيقاف إرسال QR ورسائل الاشتراك لطلبات المنتجات غير المرتبطة
- المشكلة: عند شراء منتج غير مربوط بفرع أو لعبة (كالطقم الرياضي)، كانت تُرسَل رسالة اشتراك و QR code بشكل خاطئ
- الحل: في
auto_generate_qr_on_order()أُضيف فحص: إذا لم يحتوِ أي عنصر من عناصر الطلب على_bgm_product_branchأو_bgm_product_game/_bgm_variation_game، يتوقف التنفيذ فوراً دون إرسال أي إشعار أو توليد QR - الملف:
includes/class-bgm-qr-code.php
✨ تحسينات
📨 إرسال رسائل للموظفين من صفحة إدارة الإشعارات
- الميزة: إضافة قسم جديد “رسائل الموظفين” في صفحة إدارة الإشعارات
- الصلاحيات:
- مدير الفرع (
branch_manager): يرى موظفي فرعه فقط (branch_adminوcoach) - مدير الفروع / المشرف (
branches_manager/admin): يرى جميع الموظفين مع فلتر اختيار الفرع
- مدير الفرع (
- المتغيرات المدعومة:
{name}(اسم الموظف) و{branch_name}(اسم الفرع) - الإرسال: عبر AJAX action جديد
bgm_send_staff_messageباستخدامBGM_WAWP_API، يبحث عن رقم الهاتف فيbilling_phoneمع fallback علىparent_phone - الملفات:
admin/views/send-messages.phpوincludes/class-bgm-bulk-messages.php
الإصدار 1.2.5 — 2026-03-14
🐛 إصلاحات
⏰ استناد وقت رسالة الانصراف إلى توقيت الجدول
- المشكلة: الانصراف التلقائي كان يُحتسب بناءً على وقت التحضير الفعلي (
scan_time) إذا سجل اللاعب حضوراً في يوم غير متواجد في إعدادات المجموعة. - الحل: تم تعديل نظام الجدولة ليعتمد دائماً على توقيت المجموعة المُحدد للاعب كـ
Base Timeلبدء حساب المهلة، لضمان إرسال إشعار الانصراف بعد المدة المحددة بدقة.
👥 حقوق “إداري الفرع” في تعديل العضويات
- المشكلة: خطأ “غير مصرح” كان يظهر لـ “إداري الفرع” (
branch_admin) عند محاولته تعديل تواريخ الانتهاء، إيقاف، أو استئناف العضويات في صفحةmanage-memberships. - الحل: تم توسيع الصلاحيات وتضمين فحص
is_branch_admin()في دوال الـ AJAX المسؤولة عن هذه العمليات.
✨ تحسينات
🏷️ فلتر خطط العضوية حسب الفرع في صفحة إدارة العضويات
- الميزة: قائمة “الخطة” في فلاتر صفحة العضويات أصبحت تعرض فقط الخطط المرتبطة بفرع المدير
- مدير الفروع / المشرف: يرى جميع الخطط المتاحة
- مدير الفرع / مشرف الفرع: يرى فقط الخطط المرتبطة بمنتجات فرعه — عبر ربط
_bgm_product_branch(المنتج) ← variations ←_membership_plan_id - حماية في الـ AJAX: لو مدير الفرع أرسل
plan_idلا ينتمي لفرعه يُتجاهل تلقائياً
🧾 فواتير BGM في صفحة “طلباتي” للعميل
- الميزة: أزرار “تحميل فاتورة” و”طباعة فاتورة” في صفحة طلبات العميل أصبحت تستخدم فواتير BGM المخصصة بدلاً من إضافات الطرف الثالث
- تحميل الفاتورة: عبر
bgm_download_invoice_pdf— ينزّل الفاتورة كملف HTML - طباعة الفاتورة: عبر
bgm_get_order_invoice?print=1— يفتح الفاتورة ويطبعها تلقائياً (auto-print) - الصلاحيات: كلا الـ handlers يقبلان الآن صاحب الأوردر نفسه (وليس المديرين فقط)
👥 تطوير صفحة إدارة اللاعبين في الداشبورد (bgm-manage-players)
أعمدة جديدة في جدول اللاعبين:
- الفروع: عدد الفروع النشطة — اضغط الرقم لتظهر قائمة بأسماء الفروع
- الألعاب: عدد الألعاب النشطة — اضغط الرقم لتظهر قائمة بالألعاب والفروع مع زر حذف لكل لعبة
- المجموعات: عدد المجموعات المرتبطة باللاعب
- إجراءات: زر “➕ لعبة” لإضافة لعبة/فرع جديد مباشرةً
Modal إضافة لعبة:
- اختيار اللعبة والفرع وإضافتهم في
bgm_player_gamesفوراً - يمنع التكرار (نفس اللعبة + نفس الفرع)
- يُحدّث العداد في الجدول مباشرةً بدون reload
- اختيار المجموعة (اختياري): عند اختيار اللعبة والفرع يظهر dropdown بالمجموعات المرتبطة بهما — لو اختار المشرف مجموعة يُضاف اللاعب لها تلقائياً
حذف لعبة:
- من popup الألعاب، زر حذف بجانب كل لعبة
- يعمل deactivate (
is_active = 0) فيbgm_player_games - يحذف اللاعب تلقائياً من المجموعات المرتبطة بهذه اللعبة والفرع
⏰ تنبيه انتهاء الاشتراك (Expired Subscription Overlay)
- الميزة: overlay يظهر على جميع صفحات حساب اللاعب عند انتهاء اشتراكه
- الشرط: اللاعب سبق أن اشترك وجميع عضوياته في WooCommerce Memberships منتهية (
expired/cancelled) - التحكم: اللاعب يقدر يقفله — يُحفظ في
localStorageويختفي لبقية اليوم (يعود في اليوم التالي) - ميزة: لو اللاعب عنده أكثر من عضوية منتهية يظهر له قائمة بكل عضوية مع اسم الخطة وتاريخ الانتهاء
- الإعداد في لوحة التحكم (
إعدادات عامة): مفتاح تشغيل/إيقاف + حقل نص لتخصيص رسالة التنبيه
🚫 منتجات متعارضة (Incompatible Products)
- الميزة: في كل منتج WooCommerce يوجد حقل جديد “منتجات متعارضة” — يختار منه المشرف المنتجات التي لا يمكن شراؤها في نفس الطلب
- التحقق: تلقائي عند إضافة المنتج للسلة — لو المنتج المُضاف أو أي منتج في السلة حدد الآخر كـ متعارض، تظهر رسالة خطأ
- التحقق ثنائي الاتجاه: يكفي تحديد التعارض في منتج واحد فقط ليُطبَّق في الاتجاهين
- الإعداد في لوحة التحكم (
إعدادات عامة): حقل نص لتخصيص رسالة الخطأ
الإصدار 1.2.4 — 2026-03-07
🐛 إصلاحات
🔒 user_branch يُكتب فوقه عند كل شراء جديد
- المشكلة:
assign_on_orderوassign_on_membershipكانا يستدعيانupdate_user_meta('user_branch')في كل مرة — فكل شراء جديد يمسح الفرع الأول - الحل: يُعيَّن
user_branchعند أول شراء فقط — لا يُكتب فوقه لاحقاً
⚡ AJAX handlers مكررة لـ pause/resume تتعارض
- المشكلة:
bgm_pause_membershipوbgm_resume_membershipمسجّلَين في ملفين — النسخة الخاطئة (تتحقق منuser_branch) تنفَّذ أولاً وترفض اللاعبين متعددي الفروع - الحل: حذف التسجيل من
class-bgm-membership-orders.php— تبقى النسخة الصحيحة فيclass-bgm-branch-manager-account.phpفقط
🔍 قائمة العضويات تُظهر لاعبين من كل الفروع
- المشكلة:
$branch_user_idsتُجلَب صحيحاً لكن لا تُمرَّر إلىget_users()— فكل المديرين يشوفون عضويات جميع اللاعبين - الحل: تمرير
$branch_user_idsإلى$player_args['include']مع intersect عند البحث
🏢 إصلاح جذري لمشكلة اللاعب المشترك في فرعين — لا يُسجَّل في الفرع الثاني
- المشكلة: لاعب اشترى نفس اللعبة في فرعين (أو لعبتين في فرعين مختلفين) — كان يظهر فقط في الفرع الأول
- السبب:
assign_on_orderكان يتحقق منuser_id + game_idفقط — فلو اللاعب لديه اللعبة نشطة في أي فرع، يُتجاهل تسجيله في الفرع الجديد - الحل: إضافة
branch_idللـ duplicate check:user_id + game_id + branch_id— الآن نفس اللعبة في فرع مختلف تُضاف كـ row مستقل فيbgm_player_games
🏢 إصلاح شامل: اللاعب المشترك في فرعين يظهر في كلا الفرعين في جميع الصفحات
- المشكلة:
assign_on_orderيكتبuser_branchmeta في كل شراء — فتُكتب فوق القيمة السابقة، ويبقى للاعب فرع واحد فقط في meta ويختفي من الفرع الأول في كل الصفحات - الحل: استبدال جميع فلاتر
user_branchللاعبين بـbgm_player_games WHERE branch_id = X AND is_active = 1في:get_allowed_players— manage-players وسجل الحضورget_filtered_playersفيBGM_Branch_Manager_Account— تحضير اللاعبينget_filtered_playersفيBGM_Membership_Orders— قائمة اللاعبين في الطلباتbpc()فيBGM_Branches_Manager_Account— عداد اللاعبين في بطاقة الفرع- صفحة تفاصيل الفرع (
bm-branch-detail) — قائمة اللاعبين - إرسال رسالة جماعية (
branch_players) — يرسل لكل لاعب نشط في الفرع
🎮 إصلاح صفحة “جدولي وألعابي” — ألعاب مكررة ومجموعات مفقودة
- المشكلة 1: اللاعب المشترك في فرعين كان يرى ألعاباً أكثر مما اشترى (صفوف مكررة في
bgm_player_games) - الحل 1: إضافة
GROUP BY game_id, branch_idعلى query ألعاب اللاعب - المشكلة 2: المجموعات كانت تُجلب من
bgm_user_schedule— لو اللعبة بدون جدول لا تظهر مجموعتها - الحل 2: جلب اسم المجموعة مباشرة من
bgm_group_membersJOINbgm_groups
⏰ إصلاح جذري لـ Expired Subscription Overlay — لم يكن يظهر عند انتهاء العضوية
- المشكلة: الكود كان يفحص
bgm_player_games.is_active— هذا الحقل لا يتحدث تلقائياً عند انتهاء WC Membership - الحل: الفحص الآن يعتمد على
wc_memberships_get_user_memberships()مباشرةً مع Fallback علىbgm_player_gamesفي حال WC Memberships غير مثبتة
الإصدار 1.2.3 — 2026-02-21
🐛 إصلاحات
🧾 إصلاح أزرار تنزيل الفاتورة (تظهر “0” أو تفتح بدل التنزيل)
- المشكلة 1: زر تنزيل PDF داخل modal الفاتورة، وزر التنزيل (📥) في صفحة إدارة الطلبات كانوا يفتحوا صفحة فيها “0” فقط
- السبب:
ajax_download_invoice_pdfوajax_get_order_invoiceكانوا يعملوا redirect لإضافات WebToffee / WPO WCPDF بدون تمرير الـ nonce المطلوب — فالإضافة دي ترفض الطلب وترجع “0” - الحل: حذف بلوكات الـ redirect لـ WebToffee و WPO واستخدام الفاتورة المدمجة مباشرة (
generate_simple_invoice_pdf/render_html_invoice) - المشكلة 2: زرار التحميل كان يفتح الفاتورة في المتصفح بدل ما يحملها
- الحل: إضافة header
Content-Disposition: attachmentفيgenerate_simple_invoice_pdfعشان المتصفح يعاملها كملف للتحميل - يشمل: صفحة إدارة الطلبات (
manage-orders-branch) وصفحة الإيرادات (payments/bm-revenues)
🗂️ إصلاح بيانات المجموعة واللعبة في الفاتورة
- المشكلة: الفاتورة كانت بتعرض كل المجموعات اللي اللاعب مشترك فيها (من كل الفروع)
- السبب: كان بيستخدم
BGM_Groups::get_player_groups($uid)اللي بترجع كل مجموعات اللاعب - الحل: استبدال ذلك بـ loop على items الطلب نفسه لجلب:
- اللعبة من
_bgm_variation_gameعلى الـ variation المشتراة (أو_bgm_product_gameكـ fallback) - المجموعة من
_bgm_variation_groupعلى الـ variation المشتراة (أو من المنتج كـ fallback)
- اللعبة من
- النتيجة: كل فاتورة بتعرض اللعبة والمجموعة الخاصة بهذا الطلب تحديداً (بالأيام)
- يشمل:
generate_simple_invoice_pdfوrender_html_invoice
🏢 إصلاح الفرع في الفاتورة
- المشكلة: الفاتورة كانت بتجيب الفرع من
user_branch(الفرع الحالي للاعب) — لو اتغير الفرع بعدين يتعرض فرع غلط - الحل: استخدام
_bgm_order_branch(الفرع المسجل على الطلب وقت الشراء) مع fallback لـuser_branch
🔒 تحسينات الترخيص
إخفاء صفحات المجموعات والملاعب والإيرادات عند انتهاء الترخيص
- المشكلة: صفحات المجموعات والملاعب والإيرادات كانت تظهر في القائمة حتى لو الإضافة مش متفعلة أو انتهى ترخيصها
- الحل: إضافة فحص
MCLM_Client::is_licensed()قبل إضافة هذه العناصر للقائمة:- مدير الفرع / الإداري (
branch_manager,branch_admin): إخفاءpayments(الإيرادات)،manage-groups(المجموعات)،bm-facilities(الملاعب) - مدير الفروع (
branches_manager): إخفاءbm-revenues،bm-groups،bm-facilities
- مدير الفرع / الإداري (
- طبقة حماية ثانية: إضافة
bm-revenues،bm-facilities،bm-groups،manage-groupsلقائمةfrontend_endpointsفي MCLM (تعرض رسالة “معلق” عند الوصول المباشر للرابط بدون ترخيص)
📦 إصلاح اسم المنتج في الفاتورة وصفحة إدارة الطلبات
- المشكلة: اسم المنتج كان يظهر بشكل
اسم المنتج<span> - </span>اسم المتغير— يعني HTML خام ظاهر - السبب: WooCommerce بيرجع
$item->get_name()بـ HTML tag كـ separator بين اسم المنتج والـ variation - الحل: استبدال
<span> - </span>بـ|وإزالة أي HTML متبقي قبل عرض الاسم في:- صفحة إدارة الطلبات (قائمة الطلبات + جدول التفاصيل)
- عرض الفاتورة (
ajax_get_order_details) - تحميل الفاتورة (
generate_simple_invoice_pdf) - فاتورة الإيرادات (
render_html_invoice)
📱 إصلاح رسالة QR عند الاشتراك — تظهر كل الألعاب بدل لعبة الطلب
- المشكلة: لما لاعب عنده أكثر من اشتراك، رسالة QR اللي بتتبعت عند إتمام الطلب كانت بتعرض كل الألعاب والفروع اللي هو مشترك فيها
- السبب:
send_qr_notificationكانت بتجيب كل الألعاب النشطة منbgm_player_gamesبدون ما تعرف هو اشترك في أي لعبة دلوقتي - الحل: تمرير الـ
$orderلـsend_qr_notification— لما الطلب متاح، تجيب اللعبة والفرع من items الطلب الحالي فقط (عن طريق_bgm_variation_gameو_bgm_order_branch) - كمان تم تصحيح استدعاء
get_group_extra_vars_publicعشان يمررgame_idوbranch_idللمجموعة الصح
🔄 إضافة قالب رسالة منفصل لإعادة إنشاء QR
- السبب: عند إعادة إنشاء QR يدوياً (بدون طلب)، لازم رسالة مختلفة تعرض كل اشتراكات اللاعب بتفاصيلها
- الحل: إضافة قالب جديد
bgm_template_qr_regenerateفي الإعدادات مع:- متغير
{subscriptions_summary}يبني تلقائياً ملخص لكل الاشتراكات (اللعبة، الفرع، المجموعة، الأيام، الوقت) - إعداد منفصل “إرسال إلى” للقالب الجديد
- عند إعادة الإنشاء اليدوية → يستخدم القالب الجديد، عند الاشتراك → يستخدم القالب القديم
- متغير
⏰ إصلاح رسائل التأخير والغياب لا تُرسل يوم الجمعة
- المشكلة: رسائل التأخير والغياب ما بتتبعتش رغم أن اللوغ يظهر
SENDING - السبب: الإعداد الافتراضي لـ Cron Manager كان يستثني يوم الجمعة (Day 5) من أيام العمل — الـ
dry_runفي debug بيتخطى هذا الفلتر لكن الـ cron الحقيقي لأ - الحل: تغيير الإعداد الافتراضي لـ
bgm_check_absencesليشمل كل أيام الأسبوع (0-6) - ملاحظة: لو الإعداد محفوظ مسبقاً في قاعدة البيانات، يلزم تفعيل يوم الجمعة يدوياً من Cron Manager
📅 إصلاح الأيام المقررة في “حضوري” للاعب المشترك في أكثر من لعبة
- المشكلة: لو اللاعب مشترك في لعبتين، الأيام المقررة في صفحة
my-attendanceكانت تظهر على أساس لعبة واحدة فقط (12 أو 13 حصة دايماً بغض النظر) - السبب:
count_scheduled_daysكانت تعتمد علىget_user_allowed_days()اللي بترجع مجموعة أيام واحدة منbgm_allowed_daysmeta — قيمة واحدة بتتكتب فوق نفسها - الحل: استبدال المصدر بـ query مباشر على
bgm_group_membersJOINbgm_groupsلجلب أيام كل مجموعات اللاعب، ثم دمجها في set واحد بدون تكرار — فلو اللاعب في لعبتين يظهر مجموع الأيام الفعلي من المجموعتين
🏢 إصلاح ظهور اللاعب في فرع واحد فقط عند التسجيل في فرعين
- المشكلة: لاعب مشترك في فرعين (لعبة في الدمام + لعبة في الخبر مثلاً) يظهر فقط في آخر فرع اشترى فيه
- السبب 1 — الفلتر: فلتر الفرع في
bm-attendance-logكان يعتمد علىuser_branchmeta — وهي قيمة واحدة بتتكتب فوق نفسها في كل عملية شراء - الحل 1: استبدال الفلتر باستعلام على
bgm_player_games WHERE branch_id = X AND is_active = 1— فاللاعب المشترك في فرعين يظهر في الفرعين - السبب 2 — التسجيل:
assign_on_orderكان يتحقق من وجود اللعبة بـuser_id + game_idفقط — فلو اللاعب اشترى نفس اللعبة في فرع ثانٍ، بيشوف “اللعبة موجودة” ويتجاهل التسجيل في الفرع الجديد - الحل 2: إضافة
branch_idللـ duplicate check:user_id + game_id + branch_id— فنفس اللعبة في فرع مختلف تُضاف كـ row جديد فيbgm_player_games
📊 إصلاح عمود “المتوقع الكلي” في سجل حضور اللاعبين
- المشكلة: عمود “المتوقع الكلي” كان يظهر عدداً أقل بكثير من الصحيح (مثلاً 5 بدل 16)
- السبب: الحساب كان مقيداً بأيام الشهر حتى اليوم فقط (مثلاً 6 أيام في بداية الشهر) بدل الشهر كامل
- الحل: تغيير الحساب ليمر على كل أيام الشهر كاملاً — بنفس منطق عمود “المتوقع” العادي
🪟 إصلاح موضع بوب أب الألعاب والفروع في الأعمدة الإضافية
- المشكلة: البوب أب كان يظهر في أسفل الصفحة بعيداً عن الزر، ومحتواه مقطوع
- السبب: الـ popup هو
position: fixedلكن الكود كان يضيفwindow.scrollY— وهذا خطأ لأنgetBoundingClientRect()ترجع إحداثيات نسبية للـ viewport مباشرة - الحل: حذف
scrollYوscrollXمن الحساب، وإضافة فحص لو البوب أب سيخرج من أسفل الشاشة يظهر فوق الزر بدل تحته
✨ تحسينات
📊 أعمدة إضافية في سجل حضور اللاعبين لمدير الفروع (bm-attendance-log)
- الميزة: إضافة 4 أعمدة اختيارية يتم تفعيلها من إعدادات الإضافة (
bgm_att_log_extra_cols):- المتوقع الكلي: مجموع الحصص المقررة من كل مجموعات اللاعب في الشهر كامل
- الألعاب: عدد الألعاب النشطة — اضغط الرقم لتظهر أسماء الألعاب في بوب أب
- الفروع: عدد الفروع النشطة — اضغط الرقم لتظهر أسماء الفروع في بوب أب
- نسبة الكل: نسبة الحضور الفعلي ÷ المتوقع الكلي (تأخذ بالاعتبار كل الاشتراكات)
- البيانات تُجلب بـ batch query واحد لجميع اللاعبين (لا تأثير على الأداء)
🧾 تحسين الفواتير (Invoice Enhancement)
- فاتورة صفحة الإيرادات (
render_html_invoice) أصبحت تعرض 12 حقل تفصيلي:- بيانات اللاعب: اسم اللاعب، رقم اللاعب، رقم ولي الأمر، كود اللاعب، الجنس
- بيانات الطلب: رقم الطلب، التاريخ، طريقة الدفع، الفرع
- بيانات الاشتراك: المنتج، اللعبة، المجموعة (اسم المجموعة + أيام التدريب)
- فاتورة صفحة إدارة الطلبات (
ajax_get_order_details) محدّثة بنفس التصميم والبيانات - فاتورة PDF الاحتياطية (
generate_simple_invoice_pdf) محدّثة بنفس التصميم - اسم ملف PDF: عند الطباعة/التنزيل، اسم الملف أصبح
كود_اللاعب - الشهر - السنة(مثال:BGM-00058 - 03 - 2026) - تصميم جديد: تخطيط info-cards عصري مع أيقونات ملونة وألوان premium
الإصدار 1.2.2 — 2026-02-17
🐛 إصلاحات
إصلاح حماية المصروفات — مدير الفرع والإداري مش قادرين يعدلوا خالص
- المشكلة: لما خاصية قفل المصروفات تشتغل، مدير الفرع والإداري مش قادرين يعدلوا أو يمسحوا أي مصروف حتى لو من نفس اليوم
- السبب: المقارنة كانت بتستخدم
created_at(توقيت UTC للسيرفر) معcurrent_time()(توقيت ووردبريس المحلي) — الفرق في التوقيت كان بيخلي التواريخ مابتتطابقش - الحل: تغيير المقارنة لاستخدام
expense_date(تاريخ المصروف المحلي) بدلcreated_atفي 3 أماكن: عرض المصروفات، الحذف، والتعديل
إصلاح نسبة الحضور في صفحة “حضوري” للاعب (my-attendance)
- المشكلة: نسبة الحضور كانت تظهر 0% ونسبة الغياب تظهر 50% رغم حضور اللاعب
- السبب: الحساب كان يعتمد فقط على
scheduled_attended(الجلسات المجدولة) وتتجاهل الجلسات غير المجدولة وحصص السماح - الحل: تغيير الحساب ليستخدم
real_total_attended(كل الجلسات: مجدولة + غير مجدولة + سماح) مع حد أقصى 100%
إصلاح إحصائيات بطاقات حضور اللاعبين لمدير الفروع (bm-attendance-log)
- المشكلة: عدد حضور اليوم ونسبة الحضور كانوا يظهرون صفر
- السبب: كان يستخدم SQL query منفصل لحساب حضور اليوم بينما البيانات موجودة مسبقاً في
$att_data - الحل: تغيير الحساب ليعد من
$att_dataarray مباشرة (نفس إصلاح حضور الموظفين)
✨ تحسينات
فلترة المصروفات حسب القسم (بنين / بنات)
- عمود
genderجديد في جدولbgm_expenses+ migration تلقائي للجداول القديمة - الإداري (
branch_admin):- لو مسؤول عن البنين → يضيف ويشوف مصروفات البنين فقط
- لو مسؤول عن البنات → يضيف ويشوف مصروفات البنات فقط
- القسم بيتحدد تلقائياً من
admin_category(hidden input)
- مدير الفرع (
branch_manager):- dropdown لاختيار القسم (بنين / بنات / عام) عند إضافة مصروف
- فلتر قسم في عرض المصروفات لعرض مصروفات بنين أو بنات أو الكل
- صافي الربح يتحدث حسب القسم المختار — كل قسم يشوف أرقامه الصحيحة
عرض الملاعب مجمعة بالفرع لمدير الفروع في صفحة المجموعات
- قبل: عند إنشاء/تعديل مجموعة، الملاعب كانت تظهر لفرع واحد فقط
- بعد: الملاعب تظهر مجمعة تحت كل فرع باستخدام
optgroup(🏢 اسم الفرع → ملاعب الفرع) - تحميل مسبق لكل الملاعب من كل الفروع بدون AJAX إضافي
🔒 قفل المصروفات (Expense Lock)
- خاصية جديدة: منع تعديل وحذف المصروفات بعد انتهاء اليوم — المصروفات المضافة اليوم قابلة للتعديل والحذف حتى نهاية اليوم، وبعد بداية يوم جديد تُقفل تلقائياً
- تشغيل/إيقاف: من إعدادات الإضافة أو من صفحة الإيرادات/المصروفات عند مدير الفروع
- يشمل الكل ما عدا مدير الفروع: القفل يطبق على جميع الأدوار (مدير الفرع، الإداري، المدير) — مدير الفروع (
branches_manager) يقدر يعدل ويمسح دايماً - مؤشر بصري: أيقونة 🔒 تظهر بدل أزرار التعديل/الحذف للمصروفات المقفلة
- رسائل واضحة: عند محاولة تعديل أو حذف مصروف مقفل تظهر رسالة “🔒 تم قفله لأنه من يوم سابق”
✏️ تعديل المصروفات (Expense Edit)
- زر تعديل جديد (✏️) بجانب كل مصروف قابل للتعديل
- نافذة تعديل (Modal): تحتوي حقول النوع، المبلغ، الملاحظة، التاريخ، والقسم
- AJAX handler جديد:
bgm_update_expenseلحفظ التعديلات مع فحص القفل والفرع - عمود الإجراءات: تغيير عنوان العمود من “حذف” إلى “إجراءات” ليشمل التعديل والحذف
الإصدار 1.2.1 — 2026-02-12
🐛 إصلاحات
🔒 إصلاح: user_branch يُكتب فوقه عند كل شراء جديد
- المشكلة:
assign_on_orderوassign_on_membershipفيclass-bgm-branch-product-binding.phpكانا يستدعيانupdate_user_meta('user_branch', ...)في كل مرة — فكل شراء جديد يمسح الفرع الأول ويكتب الفرع الجديد - الأثر: أي كود يعتمد على
user_branch(مثل صلاحيات المدير أو pause/resume) يتعامل مع اللاعب كأنه في الفرع الأخير فقط - الحل: إضافة شرط
!get_user_meta(..., 'user_branch', true)— يُعيَّن الفرع عند أول شراء فقط، ولا يُكتب فوقه لاحقاً
⚡ إصلاح: AJAX handlers مكررة لـ pause/resume تتعارض
- المشكلة:
bgm_pause_membershipوbgm_resume_membershipكانا مسجّلَين في ملفين:class-bgm-membership-orders.php(النسخة الخاطئة — تتحقق منuser_branchوترفض اللاعبين متعددي الفروع) وclass-bgm-branch-manager-account.php(النسخة الصحيحة) - الأثر: النسخة الخاطئة تنفَّذ أولاً وتُرجع خطأ “هذا اللاعب ليس في فرعك” للمديرين الذين يديرون لاعباً سبق أن اشترى في فرع آخر
- الحل: حذف تسجيل الـ handlers من
class-bgm-membership-orders.php— تبقى النسخة الصحيحة فيclass-bgm-branch-manager-account.phpفقط
🧾 فواتير BGM في صفحة “طلباتي” للعميل
- المشكلة: أزرار “تحميل فاتورة” و”طباعة فاتورة” كانت تُنتج فواتير من إضافة WebToffee (أو مشابهة)، وليس فواتير BGM المخصصة
- الحل: filter على
woocommerce_my_account_my_orders_actions(priority 100) يحذف أزرار الطرف الثالث ويضيف:- تحميل الفاتورة →
bgm_download_invoice_pdf(تنزيل HTML) - طباعة الفاتورة →
bgm_get_order_invoice?print=1(يفتح ويطبع تلقائياً)
- تحميل الفاتورة →
- الصلاحيات:
ajax_download_invoice_pdfوajax_get_order_invoiceيقبلان الآن صاحب الأوردر نفسه (وليس المديرين فقط) - Auto-print: عند
?print=1—window.onloadيستدعيwindow.print()تلقائياً
🔍 إصلاح: قائمة العضويات تُظهر لاعبين من كل الفروع لجميع المديرين
- المشكلة: في
ajax_get_membershipsبـclass-bgm-branch-manager-account.php— الكود يجلب$branch_user_idsمنbgm_player_gamesصحيحاً، لكنه لا يُضيفها إلى$player_args['include']قبل استدعاءget_users()— فتُرجَع كل المستخدمين بغض النظر عن الفرع - الأثر: كل مديري الفروع يشوفون عضويات جميع اللاعبين (مشكلة خصوصية)
- الحل: تمرير
$branch_user_idsإلى$player_args['include']— مع intersect مع$search_idsعند البحث
✨ ميزات جديدة وتحسينات (إجازات الموظفين)
- خيار احتساب الإجازة كحضور: إضافة خيار جديد
تحتسب كحضورعند إضافة إجازة للموظف. - إعادة هيكلة نسبة الحضور:
- يتم الآن احتساب أيام الحضور بناءً على إجمالي أيام الشهر ونقصان أيام العطلات للموظف.
- إذا تم تفعيل الإجازة (✓)، يتم إضافتها لأيام الحضور كأيام اعتيادية وتضاف للنسبة المتوقعة.
- إذا تم الاستبعاد (✗)، يتم احتسابها غياب ولا يتم زيادتها للإجمالي.
- تبويب خاص للإجازات: إضافة تبويب جديد
سجل الإجازاتفي صفحة حضور الموظفين لمتابعة الإجازات للموظفين بالفرع، والتأكد من إمكانية الفلترة بالموظف أو الشهر. - منع التحضير المزدوج: إضافة حظر لمنع مدير الفرع من تسجيل حضور لموظف في حالة كان لديه إجازة اليوم.
🐛 إصلاح — المصروفات لا تتفلتر بالتاريخ وتؤثر على صافي الربح
- المشكلة: تغيير الفترة (مثلاً “الشهر السابق”) كان يحدث الإيرادات بس، والمصروفات وصافي الربح يفضلوا بقيم الشهر الحالي
- السبب: في الصفحة فيه inputs أربعة للتاريخ —
#rev-date-from/toللإيرادات و#exp-date-from/toللمصروفات. الأزرار السريعة وزر “تحديث” كانوا بيحدثوا inputs الإيرادات بس، فـloadExpensesStats()كانت بتقرأ التواريخ القديمة من inputs المصروفات - الحل: أي تغيير في الفترة (أزرار سريعة، زر تحديث، initial load) دلوقتي بيحدث الـ inputs الأربعة مع بعض — ضمان إن الإيرادات والمصروفات وصافي الربح كلهم محسوبين على نفس الفترة
🐛 إصلاحات وتعديلات أخرى
- إصلاح تقارير و سجلات حضور مدير الفروع: تعديل تصميم وطريقة عرض سجلات حضور الموظفين وحضور اللاعبين لتصبح 4 أعمدة (حضور، المتوقع، غياب، النسبة) بدلاً من عمود واحد المجموع لضمان الدقة وتطابقها مع التصميم.
- تقرير الفروع لمدير الفرع: تحديث خوارزمية إحصائيات تقارير الفروع للاعتماد على الحسابات الجديدة للغياب والحضور.
- إصلاح نظام التحديثات للإضافة: إصلاح مشكلة عدم استقبال التحديثات من لوحة تحكم ووردبريس بتعديل الـ API Client ليرسل الطلبات بصيغة
JSONالمتوافقة مع السيرفر بدلاً منform-data.
الإصدار 1.2.0 — 2026-01-28
🐛 إصلاح حرج — جدول الأوردرات في صفحة الإيرادات (/payments) يعرض أوردرات من كل الفروع
- المشكلة: تغيير الفترة (مثلاً “الشهر السابق”) كان يحدث الإيرادات بس، والمصروفات وصافي الربح يفضلوا بقيم الشهر الحالي
- السبب: في الصفحة فيه inputs أربعة للتاريخ —
#rev-date-from/toللإيرادات و#exp-date-from/toللمصروفات. الأزرار السريعة وزر “تحديث” كانوا بيحدثوا inputs الإيرادات بس، فـloadExpensesStats()كانت بتقرأ التواريخ القديمة من inputs المصروفات - الحل: أي تغيير في الفترة (أزرار سريعة، زر تحديث، initial load) دلوقتي بيحدث الـ inputs الأربعة مع بعض — ضمان إن الإيرادات والمصروفات وصافي الربح كلهم محسوبين على نفس الفترة
الإصدار 1.2.0 — 2026-02-05
🐛 إصلاح حرج — جدول الأوردرات في صفحة الإيرادات (/payments) يعرض أوردرات من كل الفروع
- المشكلة: الجدول كان يعرض أوردرات من جميع الفروع لمدير الفرع، رغم أن العدد في البطاقات كان صحيحاً
- السبب: الـ branch filter في
ajax_get_revenuesكان يستخدمORبين_bgm_order_branchعلى الأوردر وuser_branchعلى العميل — يعني أي أوردر لأي لاعب في الفرع كان يظهر، حتى لو الأوردر نفسه مرتبط بفرع آخر أو غير مرتبط بفرع أصلاً - الحل: إزالة شرط
user_branchمن الـ OR، والاعتماد فقط على_bgm_order_branch/branch_idفي الـ order meta — نفس المنطق المستخدم في تقارير الفرع التي كانت تعمل صح
الإصدار 1.1.9 — 2026-01-24
🐛 إصلاح — فلترة التاريخ في صفحة الإيرادات (/payments)
- المشكلة: فلترة الفترة (من تاريخ / إلى تاريخ) كانت غير فعالة — الصفحة كانت تعرض كل الأوردرات بغض النظر عن التواريخ المحددة
- الإصلاح: التاريخ الافتراضي عند التحميل أصبح أول الشهر الحالي ← اليوم بدل آخر 30 يوم، مما يضمن تطبيق الفلتر من أول لحظة
✨ ميزة جديدة — أزرار فلتر سريع للتاريخ
أضفنا شريط أزرار فوق حقلي التاريخ لتحديد الفترة بضغطة واحدة:
- الشهر الحالي — يُحدد تلقائياً عند فتح الصفحة
- الشهر السابق
- آخر 7 أيام
- آخر 30 يوم
- هذه السنة
- الكل — يمسح التواريخ ويعرض كل الأوردرات
الزر النشط يتميز بلون مختلف، ويُلغى التحديد تلقائياً لو المستخدم غيّر التواريخ يدوياً.
الإصدار 1.1.8 — 2026-01-08
🐛 إصلاحات حرجة — صفحة الإيرادات (/payments) لمدير الفرع
إصلاح ظهور أوردرات كل الفروع بدل فرع المدير فقط
- المشكلة:
ajax_get_paymentsكان يعرض أوردرات اللاعبين من كل الفروع لمدير الفرع - السبب: الـ
elseفي meta_query كان يجيب كل المستخدمين اللي عندهمuser_branch != ''(يعني كل الفروع) لماeffective_branchيكون فارغاً - الحل: لو مدير الفرع مش عنده
user_branchمحدد → يرجع نتائج فارغة بدل ما يجيب الكل
إصلاح تحقق HPOS خاطئ في ajax_get_payments
- المشكلة: كان يتحقق من وجود جدول
wc_ordersبـSHOW TABLES LIKE— الجدول ممكن يكون موجود وHPOS مش مفعل - الحل: استخدام
OrderUtil::custom_orders_table_usage_is_enabled()(نفس الطريقة الرسمية المستخدمة فيajax_get_revenues)
إصلاح حساب إجمالي المبلغ مع HPOS
- المشكلة: الحساب كان يستخدم
get_post_meta($id, '_order_total')حتى لو HPOS مفعل → يرجع صفر - الحل: SQL مباشر على
wc_orders.total_amount(HPOS) أوpostmeta._order_total(legacy) حسب الوضع الفعلي
إصلاح نفس المشاكل في CSV Export
- تطبيق نفس الإصلاحات على
ajax_export_revenues_csvلضمان التوافق
الإصدار 1.1.7 — 2025-12-22
🔧 إصلاحات
إصلاح إيرادات صفحة الإيرادات والمصروفات (حرج)
- المشكلة: صفحة الإيرادات (
ajax_get_revenues) كانت تعرض طلبات كل الفروع لمدير الفرع بدل فرعه فقط - السبب:
wc_get_ordersمعcustomerarray ما بيفلترش صح — نفس المشكلة اللي كانت في التقارير - الحل: تغيير لـ per-player iteration باستخدام
customer_id(singular) مع date range filtering - البطاقات (إجمالي الإيرادات، عدد الاشتراكات، المعلق، المسترد) الآن تعرض أرقام الفرع الصحيحة
✨ تحسينات
🔄 دعم Changelog والأيقون في التحديثات
- نافذة “عرض التفاصيل” عند التحديث تعرض الآن:
- سجل التغييرات (Changelog) من السيرفر
- أيقون الإضافة (Icon + Banner)
- نسبة التوافق مع نسخة ووردبريس الحالية
📋 بطاقات حالة الاشتراكات
- 3 بطاقات جديدة في صفحة تقارير مدير الفرع ومدير الفروع:
- ✅ اشتراكات نشطة — عدد الاشتراكات الفعالة
- ⚠️ على وشك الانتهاء — اشتراكات ستنتهي خلال 7 أيام
- ❌ اشتراكات منتهية — عدد الاشتراكات المنتهية
💰📄 تقرير PDF محسّن
- إيرادات ومصروفات وصافي الربح + حالة الاشتراكات في تقرير PDF
- زر تحميل PDF مضاف لصفحة تقارير مدير الفروع
إصلاح حساب الإيرادات في التقارير (حرج)
- تم إصلاح حساب الإيرادات في 3 أماكن بالتقارير (مدير الفرع + مدير الفروع + جدول الملخص)
الإصدار 1.1.6 — 2025-12-05
✨ ميزات جديدة
📤 نظام المصروفات (Expenses)
- قسم جديد في صفحة الإيرادات لإدارة المصروفات
- فلتر عرض: إيرادات فقط / مصروفات فقط / الكل (3 أزرار في أعلى الصفحة)
- إضافة مصروف بـ 3 أنواع:
- 💼 رواتب → ملاحظة “رواتب لـ:” (مثال: راتب المدرب أحمد)
- 🏠 إيجارات → ملاحظة “إيجارات لـ:” (مثال: إيجار الملعب الرئيسي)
- 📋 أخرى → ملاحظة “تفاصيل المصروف:” (مثال: صيانة المكيفات)
- جدول مصروفات مع فلتر بالنوع + فلتر بالفرع (لمدير الفروع) + فلتر بالتاريخ + ترقيم صفحات + حذف
- جدول
bgm_expensesجديد في قاعدة البيانات
🏛️ مصروفات الأكاديمية (لمدير الفروع)
- مدير الفروع يقدر يضيف مصروفات لفرع معين أو مصروفات عامة للأكاديمية (branch_id=0)
- خيار “🏛️ الأكاديمية (عام)” في قائمة الفروع عند إضافة مصروف
- فلتر المصروفات بالفرع يشمل خيار “الأكاديمية” لعرض المصروفات العامة
📈 بطاقة صافي الربح
- بطاقة جديدة تظهر لمدير الفرع ومدير الفروع
- صافي الربح = إجمالي الإيرادات − إجمالي المصروفات
- لون أخضر (teal) لو ربح، لون أحمر لو خسارة
- تتحدث تلقائياً مع تغيير الفلاتر أو إضافة/حذف مصروف
📋 أعمدة جديدة في جدول الإيرادات
- كود اللاعب (Player ID) — مثال: BGM-00058
- القسم (Division) — ♂ ذكر / ♀ أنثى
- الملعب (Location/Facility) — الملعب المربوط بمجموعة اللاعب
- طريقة الدفع (Payment Method) — من WooCommerce (كاش، تحويل، إلخ)
- تصدير CSV محدّث يشمل كل الأعمدة الجديدة
📊 تقارير مدير الفروع (أُعيدت بناؤها بالكامل)
- فلتر الفرع + فلتر الشهر — اختر فرع معين أو “كل الفروع” مع اختيار الشهر
- بطاقات ملخص شاملة: إجمالي اللاعبين / حضور اليوم / سجلات الحضور / غير مجدول / الغياب / الموظفين / الفروع
- بطاقات الإيرادات والمصروفات: إيرادات الشهر + مصروفات الشهر + صافي الربح
- جدول ملخص الفروع محدّث يشمل: إيرادات الشهر + مصروفات الشهر لكل فرع
- إحصائيات حسب اللعبة: المسجلين + حضروا + إجمالي الحضور
- الحضور اليومي: جدول يومي بعدد الحاضرين
- أعلى 10 لاعبين حضوراً مع الفرع
💰 بطاقات مالية في تقرير الفرع
- بطاقات الإيرادات والمصروفات وصافي الربح مضافة لصفحة تقارير مدير الفرع
- تتحدث حسب الشهر المختار
📋 بطاقات حالة الاشتراكات
- 3 بطاقات جديدة في صفحة تقارير مدير الفرع ومدير الفروع:
- ✅ اشتراكات نشطة — عدد الاشتراكات الفعالة
- ⚠️ على وشك الانتهاء — اشتراكات ستنتهي خلال 7 أيام
- ❌ اشتراكات منتهية — عدد الاشتراكات المنتهية
- مدير الفرع يشوف بيانات فرعه فقط، مدير الفروع يشوف الكل مع إمكانية الفلترة بالفرع
💰📄 إيرادات ومصروفات واشتراكات في تقرير PDF
- قسم جديد في التقرير الشهري PDF يعرض:
- بطاقات الإيرادات والمصروفات وصافي الربح
- بطاقات حالة الاشتراكات (نشطة / على وشك الانتهاء / منتهية)
📄 زر تحميل PDF لمدير الفروع
- زر ” تحميل تقرير PDF” مضاف لصفحة تقارير مدير الفروع
- يدعم الفلترة بالفرع والشهر
🔄 دعم Changelog والأيقون في التحديثات
- نافذة “عرض التفاصيل” عند التحديث تعرض الآن:
- سجل التغييرات (Changelog) من السيرفر
- أيقون الإضافة (Icon + Banner)
- نسبة التوافق مع نسخة ووردبريس الحالية
🔧 إصلاحات
إصلاح حساب الإيرادات (حرج)
- المشكلة:
wc_get_ordersمعcustomerarray كان يرجع طلبات كل الفروع بدل الفرع المحدد - الحل: تغيير لـ per-player iteration باستخدام
customer_id(singular) مع date range filtering - تم الإصلاح في 3 أماكن:
- تقارير مدير الفرع (
branch_reports_content) - تقارير مدير الفروع (
reports_content) — الإجمالي - جدول ملخص الفروع — إيرادات كل فرع
- تقارير مدير الفرع (
إصلاح فلاتر الإيرادات
- إصلاح
get_usersكان يرجع 10 لاعبين فقط — الآن يجلب كل اللاعبين (number => -1) - إصلاح فلتر التاريخ: دعم
>=و<=بدل formatfrom...toغير الموثوق - إصلاح قراءة حالة الطلب: استخدام
$order->get_status()بدلget_post_metaللتوافق مع HPOS - إصلاح عرض المصروفات في تبويب “المصروفات”: كان
.bgm-rev-table-wrapيخفي جدول المصروفات — تم استخدام IDs فريدة
🔒 الصلاحيات
- مدير الفرع: يضيف ويحذف مصروفات فرعه فقط + يشوف إيرادات ومصروفات فرعه
- مدير الفروع: يضيف مصروفات لأي فرع أو للأكاديمية + يشوف كل الفروع + يفلتر بفرع معين
- جميع الفلاتر (الفرع، التاريخ، اللعبة، المجموعة، الجنس، البحث) تعمل على الإيرادات والمصروفات
الإصدار 1.1.5 — 2025-11-18
🔥 إصلاحات حرجة
إصلاح رسائل التأخير والغياب (كانت متوقفة بالكامل)
- السبب الجذري: نظام الـ Group Scheduler (v1.1.3) كان يحط transient locks لمدة 20 ساعة قبل محاولة الإرسال عبر
wp_schedule_single_event— ولأن WordPress Cron يعتمد على زيارات الموقع، الأحداث كانت مش بتتنفذ، بس الـ locks كانت بتمنع نظام الـ Polling من الإرسال - الحل:
- إزالة نظام الـ Event-Driven بالكامل من إرسال الإشعارات
- توحيد الإرسال في نظام Polling واحد (
bgm_check_absences) يفحص كل اللاعبين (مجموعات + جداول فردية) كل 5 دقائق - إزالة جميع الـ transient locks واستبدالها بفحص
notification_logtable - تنظيف تلقائي لكل الـ locks القديمة من قاعدة البيانات عند التحديث
- النتيجة: رسائل التأخير والغياب تشتغل بنفس الطريقة الموثوقة اللي كانت قبل إضافة المجموعات
إصلاح متغيرات القوالب في جميع أنواع الإشعارات
{group_name},{coach_name},{scheduled_days},{scheduled_time}كانت لا تظهر في رسائل الحضور والتسجيل (QR) — تم إصلاحها- تحسين
get_group_extra_vars()لتشمل كل المتغيرات وتدعم fallback لوgame_idأوbranch_idمش محددين - المتغيرات متاحة الآن في كل أنواع الرسائل: حضور، انصراف، تأخير، غياب، تعيين جدول، QR Code
✨ ميزات جديدة
مدير الفرع يمكنه إنشاء مجموعات
branch_managerأصبح يقدر يضيف ويحذف مجموعات لفرعه فقط (كان مقصوراً علىadministratorوbranches_manager)- حماية: لا يمكنه إنشاء مجموعات لفروع أخرى
تسجيل اللاعب تلقائياً في player_games عند الإضافة للمجموعة
- عند إضافة لاعب لمجموعة (يدوياً أو تلقائياً عبر الشراء) يتم:
- تسجيله في جدول
player_gamesتلقائياً (كان يحتاج تسجيل منفصل) - تعيين فرعه (
user_branch) إذا لم يكن محدداً
- تسجيله في جدول
صفحة تشخيص الإشعارات
- شورتكود
[bgm_debug_notifications]يعرض تفاصيل كاملة لكل لاعب:- مصدر الجدول (مجموعة / جدول فردي / meta)
- حالة الاشتراك (Membership)
- التوقيتات بالتفصيل (وقت الحصة / وقت التأخير / وقت الغياب)
- سبب التخطي لو اتعمل skip
🔧 تحسينات تقنية
BGM_Group_Schedulerأصبح مبسطاً — ينظف الأحداث القديمة فقط ولا يتدخل في الإرسالhandle_cron_pingيعملdo_action('bgm_check_absences')مباشرة بدون الاعتماد علىspawn_cron()
الإصدار 1.1.4 — 2025-11-01
✨ ميزات جديدة
🏟️ إدارة الملاعب (Facilities)
- جدول جديد
bgm_facilitiesلتخزين الملاعب لكل فرع - عمود
facility_idعلى جدولbgm_groupsلربط المجموعة بالملعب - صفحة إدارة جديدة 🏟️ الملاعب في قائمة الأدمن + حساب مدير الفرع + مدير الفروع
- حقل الملعب في نموذج إنشاء/تعديل المجموعة
- تحقق من تعارض الوقت: مجموعتين في نفس الملعب، نفس اليوم، فرق أقل من ساعة → رفض
- Shortcodes:
{facility_name}و{facility_id}متاحان في قوالب الرسائل
☑️ Checkbox إرسال إشعار الجدول
- checkbox “📢 إرسال إشعار تحديث الجدول للاعبين” في نموذج المجموعة (إنشاء وتعديل)
🔑 Cron Ping URL
- صفحة إدارة الكرون تعرض أمر crontab جاهز + URL أمني لتشغيل الكرون من السيرفر
- إمكانية تجديد السر الأمني
الإصدار 1.1.3 — 2025-10-15
✨ ميزات جديدة
📅 نظام جدولة Event-Driven للإشعارات (class-bgm-group-scheduler.php)
- بدل polling كل 5 دقائق: لما تُحفظ المجموعة يُجدَّل job دقيق لكل جلسة (وقت التدريب + threshold)
- Job التأخير: وقت التدريب + إعداد “دقائق التأخير”
- Job الغياب: وقت التدريب + إعداد “دقائق الغياب”
- تحديث تلقائي عند تغيير الجدول أو الإعدادات أو حذف المجموعة
- إعادة جدولة أسبوعية تلقائية + زرار “إعادة جدولة الكل” في صفحة الكرون
- النظام القديم (polling) بيتوقف تلقائياً للاعبين في مجموعات لما الـ scheduler شغّال
🔧 إصلاحات
⏰ إصلاح مشكلة تكرار وغياب الإشعارات
- Transient Lock لكل لاعب + نوع إشعار + تاريخ — يمنع race condition
- حذف شرط
status = 'sent'— أي سجل موجود في اليوم يمنع الإعادة - إصلاح nonce check في AJAX handlers الملاعب — يقبل
bgm_manage_groupsوbgm_groups_nonce
ملاحظة: هذا النظام تم استبداله بالكامل في الإصدار 1.1.5 بسبب مشاكل في transient locks مع WordPress Cron
الإصدار 1.1.2 — 2025-09-28
✨ ميزات جديدة
💰 صفحة الإيرادات (جديدة)
- صفحة جديدة “💰 الإيرادات” تظهر لمدير الفرع ومدير الفروع في قائمة حسابي
- بطاقات ملخص تتحدث حسب الفلتر: إجمالي الإيرادات / عدد الاشتراكات / المعلق والمعالجة / المسترد
- فلاتر مدير الفرع: اللعبة، المجموعة، الجنس، من تاريخ / إلى تاريخ، بحث
- فلاتر مدير الفروع: + فلتر الفرع بالإضافة لكل الفلاتر أعلاه
- افتراضي يعرض آخر 30 يوم مع إمكانية تغيير النطاق الزمني بحرية
- الجدول يعرض: رقم الطلب، اللاعب، الفرع (لمدير الفروع)، اللعبة، المجموعة، المبلغ، التاريخ، الحالة مع badge ملوّن، رابط الفاتورة
- تصدير CSV بكل البيانات المفلترة مع BOM للغة العربية
- ترقيم صفحات (20 طلب لكل صفحة)
- فلترة المجموعات تتحدث تلقائياً عند اختيار لعبة معينة
🐛 إصلاحات
- إصلاح حرج: رسالة الغياب لا تُرسَل بعد رسالة التأخير: كانت queries التحقق من “هل اتبعتلوا رسالة؟” تعد أي record في الـ log بما فيها الفاشلة (
status = 'failed')، فلما رسالة الغياب تفشل مرة تُعدّ كأنها أُرسلت وتُوقَف المحاولات الجاية — الآن التحقق يفلتر علىstatus = 'sent'فقط لكلٍّ من رسالة التأخير والغياب.
الإصدار 1.1.1 — 2025-09-10
🐛 إصلاحات
- إصلاح خطأ 404 بعد التحديث: كان flush_rewrite_rules يتنفذ قبل تسجيل الـ Custom Post Types والـ endpoints — الآن يتنفذ في نهاية init بعد تسجيل كل شيء
- إصلاح حفظ المدرب عند تعديل المجموعة: كان تغيير المدرب لا يُحفظ لأن الصلاحية كانت مقتصرة على admin و branches_manager فقط
- إصلاح تعديل اسم وجنس المجموعة: كان الاسم محصور بـ admin فقط والجنس لم يكن يُحفظ أصلاً — الآن أي مدير يقدر يعدل الاسم والجنس والمدرب
- منع نقل لاعب لمجموعة جنس مختلف: لا يمكن نقل ولد لمجموعة بنات أو العكس — التحقق يتم في السيرفر والواجهة
- فلترة المجموعات حسب الجنس عند النقل: الولد يشوف مجموعات الأولاد + المختلطة فقط، والبنت تشوف مجموعات البنات + المختلطة فقط — مجموعات الجنس الآخر لا تظهر أساساً في dropdown النقل
- إصلاح حذف المجموعات عند حفظ الجدول: كان حفظ جدول لاعب في لعبة يمسح مجموعاته في كل الألعاب الأخرى — الآن يمسح فقط من نفس اللعبة والفرع
✨ تحسينات
- إنشاء حسابات مدربين: مدير الفرع يقدر ينشئ حساب مدرب جديد مباشرة من صفحة تحضير الموظفين (زرار ➕ إضافة مدرب)
- الجنس في الـ Variations: إضافة حقل الجنس (ذكر/أنثى) بجانب المجموعة في WooCommerce Variations — لما اللاعب يشتري الاشتراك ويختار الجنس + المجموعة، يتسجل جنسه ويتحط في المجموعة تلقائياً
- الجنس على مستوى المنتج: إضافة حقل الجنس في إعدادات BGM للمنتج — لو المنتج مخصص لجنس معين (بنات فقط مثلاً) الجنس يتسجل تلقائياً عند الشراء بدون الحاجة لـ variation (الـ variation له أولوية لو محدد فيه جنس)
- بوب اب ولي الأمر عند إتمام الطلب: البوب اب بقى يظهر لما العميل يضغط “إتمام الطلب” في صفحة الـ Checkout — لو بيانات ولي الأمر ناقصة يمنع الطلب ويطلب البيانات أولاً، وبعد الحفظ يكمل الطلب تلقائياً
- إزالة الجنس من بوب اب ولي الأمر: الجنس بقى بييجي تلقائي من المنتج أو الـ variation — البوب اب بقى يسأل عن بيانات ولي الأمر فقط (الاسم، الهاتف، العلاقة)
- فلترة الرسائل بالمجموعة: إضافة خيار “👥 كل لاعبي مجموعة” في صفحة إرسال الرسائل الجماعية
- تطبيق قيود الجنس على الرسائل: الإداري المسؤول عن الأولاد يبعت للأولاد فقط والعكس (عبر admin_category)
- إضافة نقل اللاعبين من صفحة الأدمن: إمكانية نقل لاعب لمجموعة أخرى مباشرة من صفحة إدارة المجموعات (Admin)
الإصدار 1.1.0 — 2025-08-25
✨ نظام المجموعات التدريبية (Training Groups)
👥 إدارة المجموعات
- كل لعبة تتقسم لمجموعات (A, B, AG…) مرتبطة بفرع وجنس محددين
- كل مجموعة: اسم، جنس، أيام ثابتة، وقت ثابت، مدرب أو أكثر
- إنشاء/حذف: Admin و branches_manager فقط
- تعديل الجدول: branch_manager يعدل مجموعات فرعه — مع خيار “اختيار من مجموعة أخرى” لتعبئة الأيام والوقت تلقائياً
🗄️ قاعدة البيانات
- جدول
bgm_groups: id, name, game_id, branch_id, gender, days (JSON), scheduled_time, coach_ids, created_by - جدول
bgm_group_members: group_id, user_id, joined_at — مع migration تلقائي
🛒 WooCommerce Integration
- حقل “المجموعة BGM” على كل Variation
- عند إتمام الطلب: اللاعب يتضاف للمجموعة تلقائياً وجدوله يتحدث فوراً
📅 مزامنة الجدول
- اللاعب ينضم لمجموعة →
bgm_user_scheduleوbgm_allowed_daysيتحدثوا تلقائياً - مدير الفرع يعدل جدول المجموعة → كل اللاعبين يتحدث جدولهم + رسالة واتساب
- نقل لاعب من مجموعة لأخرى يحدّث جدوله فوراً
📨 شورت كودات جديدة في قالب الرسالة
{group_name}— اسم المجموعة{coach_name}— اسم المدرب / المدربين
🔔 الإشعارات
- رسالة تحديث الجدول من قالب
schedule_assigned، المستلم حسب الإعداد
📱 الواجهات
- Dashboard WordPress: صفحة “👥 المجموعات” — إنشاء/تعديل/حذف/عرض الأعضاء
- حساب branches_manager: تبويب “👥 المجموعات” — إنشاء/تعديل/نقل لاعبين
- حساب branch_manager: تبويب “👥 المجموعات” — تعديل جدول + خيار نسخ جدول من مجموعة أخرى
- حساب branch_admin: يدير مجموعات فرعه حسب فئته (ذكور/إناث/كليهما)
- حساب اللاعب: يظهر اسم المجموعة واسم المدرب في صفحة “جدولي وألعابي”
🏋️ دور المدرب (Coach) — جديد
الصلاحيات
- عرض فقط — لا يقدر يسجل حضور أو يعدل بيانات
- مرتبط بمجموعة أو أكثر في لعبة محددة
قائمة المدرب
- قائمة نظيفة: Dashboard / مجموعاتي / سجل حضوري / إرسال رسائل / تسجيل الخروج
- إخفاء كامل للعضويات وتفاصيل الحساب والطلبات
- إعادة توجيه تلقائي لو حاول يفتح صفحة ممنوعة
صفحة “👥 مجموعاتي”
- فلتر بالمجموعة لو عنده أكتر من واحدة
- قائمة اللاعبين مع جنسهم وآخر حضور
- فتح سجل حضور كل لاعب (30 سجل أخير)
- بحث في أعضاء المجموعة
صفحة “📅 سجل حضوري”
- جدول شهري: حاضر / غائب / إجازة مع وقت الحضور
- Summary cards (أيام الحضور / الغياب / الإجازات)
صفحة “✉️ إرسال رسائل”
- إرسال لـ: لاعب محدد / مجموعة معينة / كل لاعبيه
- سجل آخر 30 رسالة مرسلة
- دعم متغيرات:
{parent_name}{child_name}{group_name}{coach_name}
المدرب في قائمة الموظفين
- يظهر في صفحة الموظفين لمدير الفروع مع badge “🏋️ مدرب”
- له سجل حضور وإجازات مثل باقي الموظفين
- فلتر الدور في صفحة الموظفين: الكل / مدير فرع / إداري / 🏋️ مدرب
🔔 إدارة الإشعارات — تحسينات
فلتر بالمجموعة
- خيار جديد “👥 كل لاعبي مجموعة” في صفحة الإشعارات لـ branch_manager و branch_admin
- التحقق من صلاحية الـ branch_manager على المجموعة قبل الإرسال
{group_name} و{coach_name} في الرسائل المخصصة
- كانت موجودة فقط في
schedule_assigned— اتضافوا لـsend_custom_message
🐛 إصلاحات
- فلتر الجنس في إدارة المجموعات: لم يكن يقرأ
$_GET['gender']للـ branch_manager والأدمن - فلتر المجموعة في الحضور:
$branch_groupsكان يُعرَّف بعد استخدامه $count++بدون تهيئة فيajax_bulk_save_schedule(PHP Notice)- Multi-game player: إضافة
game_idفي الـ save request لحفظ الجدول للعبة الصحيحة - مجموعة اللاعب: تتحفظ فعلاً في
bgm_group_membersعند حفظ الجدول (Single + Bulk) - فلتر الجنس في schedule modal: يفلتر المجموعات حسب جنس اللاعب تلقائياً
bgm_groupsوbgm_group_members: كانوا بيتحذفوا عند أي تحديث — الآن فقط عند تفعيل “حذف البيانات”- الـ modal يحتفظ بالمجموعة المختارة عند إعادة الفتح
- إضافة
coachلـcan_send_to_player: المدرب يقدر يبعت للاعبيه
⚡ أداء
- تحضير اللاعبين: 2 batch queries (attendance + games) بدل N×2 queries
- صفحة المجموعات: preload لعدد الأعضاء وأسماء المدربين في query واحدة
- player_stats loop: preload للألعاب بدل query لكل لاعب
- Staff attendance: batch query بدل N queries
- Checkout cron loop: preload لأوقات الجداول
- players_raw loop: preload للجداول بدل query لكل لاعب
- Bulk save: إزالة
$alreadycheck الزائدة بعد DELETE
الإصدار 1.0.9 — 2025-08-01
✨ ميزات جديدة
💰 صفحة الإيرادات (Revenue Page)
- صفحة جديدة 💰 الإيرادات لمدير الفرع ومدير الفروع
- بطاقات ملخص: إجمالي الإيرادات + عدد الاشتراكات + معلق/قيد المعالجة + مسترد
- فلاتر: الفرع + اللعبة + المجموعة + الجنس + التاريخ من/إلى + بحث بالاسم أو رقم الطلب
- جدول مفصّل بكل الأوردرات مع حالة الطلب وزر الفاتورة
- ترقيم صفحات + تصدير CSV
- مدير الفروع يشوف كل الفروع، مدير الفرع يشوف فرعه فقط
📋 سجل حضور الموظفين لمدير الفروع
- صفحة شاملة 📋 سجل حضور الموظفين لمدير الفروع
- فلاتر: الفرع + الشهر + الموظف + الجنس + التصنيف + عرض الوقت
- جدول شهري بكل أيام الشهر مع ✓ للحضور و ✗ للغياب
- بطاقات: إجمالي الموظفين + حضور اليوم + نسبة الحضور
- زر تصدير الجدول
🔑 صفحة الرخصة لمدير الفروع
- صفحة 🔑 الرخصة في حساب مدير الفروع لعرض حالة التفعيل
الإصدار 1.0.8 — 2025-07-12
🚀 تحديثات النظام (Remote Updates)
✅ التحديث التلقائي للإضافة
- تحديث بضغطة زر: الآن يمكنك الحصول على أحدث التحديثات والميزات الجديدة مباشرة من لوحة تحكم ووردبريس.
- إشعارات التحديث: سيظهر إشعار تلقائي عند توفر إصدار جديد للإضافة.
- تثبيت آمن: يتم تنزيل وتثبيت التحديثات بشكل آمن من السيرفر الرسمي.
⚙️ إصلاحات المهام المجدولة (Cron)
🔧 إزالة التكرار في فترات التكرار
- حذف
bgm_every_1_minutesالمكرر معevery_minute— مفتاح واحد موحد لكل دقيقة. - حذف
every_five_minutesالمكرر معbgm_every_5_minutes— مفتاح واحد موحد لكل 5 دقائق. - تصحيح كل الاستدعاءات في الكود لتستخدم المفاتيح الموحدة.
⚡ إضافة وضع لحظي
- خيار جديد
bgm_instantفي فترات التكرار (30 ثانية — أسرع ما يمكن في WordPress Cron). - عند اختياره تظهر رسالة تحذيرية صفراء تُنبّه المدير من تأثيره على أداء الموقع.
🛠️ إصلاح جدولة bgm_auto_checkout_cron
- إصلاح حرج: مهمة الانصراف التلقائي لم تكن تُجدَّل تلقائياً عند تفعيل الإضافة أو تحديثها.
- الآن تُجدَّل تلقائياً مع احترام الإعدادات المحفوظة في لوحة إدارة الكرون.
🔄 تحسين منطق إعادة الجدولة
- إصلاح تكرار
update_optionالمزدوج فيajax_save_cron_settings. - جدولة
bgm_check_absencesالآن تقرأ الـ interval من إعدادات لوحة الكرون مباشرة. - إضافة تأخير 5 ثوانٍ عند إعادة الجدولة لضمان عدم التعارض مع الحدث المحذوف.
🐛 إصلاح حرج: سجل الغياب في اليوم الحالي
المشكلة
كان سجل الحضور يُسجّل اللاعب غائباً من بداية اليوم المجدول مباشرة، حتى قبل أن يحين موعده أو يمر وقت كافٍ للحكم عليه بالغياب.
الحل
- اليوم الحالي لا يُعدّ غياباً إلا بعد مرور مدة رسالة الغياب (
bgm_absence_minutes_threshold) من الموعد المحدد للاعب. - في فترة الانتظار يظهر العمود بأيقونة ⏳ (قيد الانتظار) بدلاً من ✗ (غائب).
- الإصلاح يشمل: جدول إحصائيات اللاعبين الشهري، جدول إحصائيات الموظفين، وصفحة سجل الحضور.
🐛 إصلاح: اسم اللعبة لا يظهر في رسالة التأخر
- المشكلة: كانت رسالة التأخر تُرسَل وفيها
{game_name}بدون استبدال رغم أن اللعبة محددة للاعب. - السبب: الكود كان يمرر اسم اللعبة باسم المتغير
course_nameبينما القالب يستخدم{game_name}. - الحل: إضافة كلا المتغيرين (
game_nameوcourse_name) لضمان التوافق مع جميع القوالب.
🐛 إصلاح: منطق الانصراف التلقائي
المشكلة
- الانصراف التلقائي كان يعمل حتى لو نظام الانصراف اليدوي (QR) مُفعَّل.
- وقت الانصراف كان يُحسَب أحياناً من وقت الحضور الفعلي (scan_time) بدل الموعد المجدول للاعب.
- اللاعبون الذين موعدهم محفوظ في جدول
bgm_user_scheduleلم يكن يُقرأ موعدهم بشكل صحيح.
الحل
- لو نظام الانصراف اليدوي (QR) مُفعَّل → الانصراف التلقائي لا يعمل تلقائياً.
- وقت الانصراف يُحسَب دائماً من موعد اللاعب المجدول + المدة المحددة:
- مثال: لاعب موعده 5:30 ومدة الحصة 90 دقيقة → انصراف تلقائي الساعة 7:00 بغض النظر عن وقت وصوله.
- الأولوية في قراءة الموعد:
- جدول
bgm_user_schedule(الأدق) bgm_scheduled_timeفي user metascan_timeكـ fallback أخير فقط
- جدول
🐛 إصلاحات وتحسينات أخرى
- تحسين عملية التحقق من الرخصة لجعلها أكثر استقراراً وأماناً.
- إصلاح مشكلة عدم ظهور التحديثات في بعض الحالات.
الإصدار 1.0.7 — 2025-06-22
🔐 نظام الرخصة الجديد (Server-Based License)
✅ تفعيل الرخصة عن بُعد
- استبدال نظام الرخصة القديم (المحلي) بنظام جديد يتواصل مع سيرفر إدارة الرخص.
- دعم كامل لدورة حياة الرخصة: تفعيل (
/activate)، إلغاء تفعيل (/deactivate)، والتحقق (/validate). - فحص تلقائي للرخصة مرتين يومياً (Cron Job).
- تشفير مفتاح الرخصة المحفوظ محلياً باستخدام
wp_salt. - حجب صفحات الإضافة (Admin + Frontend) عند عدم تفعيل الرخصة.
- صفحة إدارة رخصة مخصصة مع عرض الحالة (نشطة/منتهية/موقوفة) وتاريخ الانتهاء.
- زر إعادة فحص يدوي لتحديث حالة الرخصة فوراً.
🛡 تكامل البيانات (Data Integrity)
✅ إصلاح قاعدة البيانات
- إضافة عمود
is_grace_sessionالمفقود لجدول الحضور (bgm_attendance) تلقائياً عند التحديث. - حل مشكلة “Unknown column” التي كانت تمنع التحضير.
🐛 إصلاحات حرجة
📊 مزامنة الإحصائيات (Dashboard Sync)
- إصلاح عدم تحديث الأرقام والنسب في “حسابي” بعد التحضير مباشرة.
- إضافة
delete_transientلمسح الكاش فور تسجيل الحضور.
📍 خطأ الحالة (Status Error)
- تسجيل الحضور يتم الآن بناءً على فرع المدير الحالي وليس فرع اللاعب المسجل.
- هذا يضمن ظهور “علامة الصح الخضراء” ✅ (حضور) بدلاً من “X حمراء” عند تحضير لاعب في فرع غير فرعه الأصلي.
⚠️ تحسينات السجل
- إضافة علامة تعجب (!) في سجل الحضور لتمييز اللاعبين الذين حضروا في غير أيامهم المجدولة.
🔍 البحث المتقدم في العضويات
✅ بحث لحظي (AJAX Search)
- تحسين صفحة “إدارة العضويات” لتدعم البحث الفوري بدون إعادة تحميل الصفحة.
- البحث يشمل: الاسم، رقم الجوال، و البريد الإلكتروني.
- تحديث الجدول والعدادات ديناميكياً بناءً على نتائج البحث.
⚙️ إعدادات الإشعارات
🔔 التحكم في إشعارات العضويات المنتهية
- إضافة إعداد جديد في لوحة التحكم:
bgm_notify_membership_expired_late_absence. - يتيح للمدير تفعيل أو تعطيل إرسال رسائل “التأخير” و”الغياب” للاعبين أصحاب العضويات المنتهية.
- الافتراضي: معطل (لا يتم إزعاج اللاعبين المنتهية عضويتهم برسائل الغياب).
🤖 الانصراف التلقائي (Auto-Checkout)
✅ نظام ذكي لتسجيل الخروج
- مؤقت تلقائي: يقوم النظام بتسجيل انصراف اللاعبين تلقائياً بعد انتهاء وقت الحصة المحدد + مدة السماح.
- إعدادات مرنة: إمكانية تحديد “مدة الانصراف التلقائي” بالدقائق من إعدادات الحضور.
- حماية ذكية: يعمل فقط في أيام النشاط وساعات العمل المحددة، ويتوقف في أيام العطلات.
⏱️ التحكم في المهام المجدولة (Cron Control)
🛡️ جدولة ذكية للموارد
- تحديد أيام العمل: المهام المجدولة (مثل التحقق من الغياب) تعمل فقط في الأيام المحددة (Active Days).
- ساعات العمل: تحديد “وقت البدء” و “وقت الانتهاء” للمهام، لتتوقف تماماً أثناء الليل (Sleep Mode).
- تطبيق فوري: أي تغيير في الإعدادات يتم تطبيقه وإعادة جدولة المهام فوراً.
- حماية شاملة: تشمل: التحقق من التأخير والغياب، الانصراف التلقائي، والتقارير الشهرية.
📱 تحسينات واجهة اللاعب (My Account)
🎨 أيقونات وقوائم جديدة
- أيقونات معبرة: إضافة أيقونات (Emojis) لكل عنصر في قائمة حسابي (🪪, 📱, 📅, etc.) لتحسين التجربة البصرية.
- إعادة ترتيب القائمة: تنظيم العناصر لتبدأ بالأهم: معلوماتي الشخصية، كود QR، حضوري، ثم باقي العناصر.
- تكامل سلس: تظهر الأيقونات بشكل متناسق في الموبايل والديسكتوب.
🐛 إصلاحات أخرى
- تعارض الـ Hooks: إزالة التداخل بين
bgm_check_absencesوprocess_auto_checkout. - تحسينات الأداء: تقليل استهلاك الموارد بإيقاف المهام في أوقات الخمول.
الإصدار 1.0.6 — 2025-06-02
🚀 ميزات جديدة
🎮 تغيير اللعبة للاعب
- AJAX handler مخصوص
bgm_change_player_gameلتغيير لعبة اللاعب - يحدّث جدولي
bgm_player_gamesوbgm_user_scheduleمعاً - دعم تغيير اللعبة لعدة لاعبين دفعة واحدة (Bulk)
- عرض كل الألعاب المنشورة في القائمة (ليس فقط الألعاب المسجّل فيها لاعبين)
⚧ تعديل جنس اللاعب
- مودال مخصوص لتعديل الجنس بزر (♂/♀/⚧)
- يدعم صلاحيات
branches_manager
✅ التحضير اليدوي (إصلاح شامل)
- التحضير اليدوي الآن يعمل بنفس فلو الـ QR بالظبط:
- عضوية موقوفة → مودال تحذيري مع خيار “تحضير + إلغاء الإيقاف”
- عضوية منتهية → فحص حصص السماح (Grace Sessions): لو فاضل حصص يتحضر مع رسالة تحذير، لو مفيش يُمنع
- يوم غير مجدول → رسالة تأكيد مع خيار “تحضير رغم ذلك” أو “إلغاء”
- كل حاجة تمام → يتحضر مباشرة
- إضافة
ajax_attend_and_resumehandler لتحضير اللاعب + إلغاء إيقاف العضوية - حماية ضد الأخطاء:
try-catchحول فحص العضوية والإشعارات
🔔 رسائل التأخير والغياب (إصلاح وتحسين)
- إصلاح فحص الحضور: الآن يبحث بالـ
user_id+scan_dateفقط - إضافة فحص
notify_lateللمستخدم (كان ناقص) - استخدام
BGM_WAWP_API::for_user()لإرسال رسائل التأخير والغياب عبر API الفرع المخصصة
🧾 فاتورة PDF (إصلاح)
- إضافة صلاحية
manage_woocommerceديناميكياً لأدوار BGM عند طلب الفاتورة - Fallback لعرض فاتورة HTML قابلة للطباعة لو WebToFee مش متوفر
🔍 بحث العضويات
- البحث يشمل الآن: الاسم + الإيميل + رقم الجوال (
billing_phone+parent_phone)
🔓 نظام الرخصة
- تجاوز كامل لنظام التفعيل (License Bypass) — الإضافة تعمل بدون Serial
- 5 أكواد تفعيل جديدة احتياطية
👤 بوب أب بيانات ولي الأمر بعد الأوردر
- عند اكتمال الأوردر، لو بيانات ولي الأمر ناقصة يظهر popup تلقائياً
- يشمل: الجنس + اسم ولي الأمر + رقم الجوال + العلاقة
- البيانات بتتحفظ مرة واحدة فقط — اللاعب لا يستطيع تعديلها بعد الحفظ
👔 إرسال رسالة لموظف محدد
- خيار “موظف محدد” في الرسائل عند مدير الفروع
- AJAX handler جديد
bgm_bm_search_staff
🐛 إصلاحات حرجة
✅ إصلاح سجل حضور اللاعبين (X حمراء بدل ✓ خضراء)
- إضافة
BGM_Attendance::get_user_allowed_days()helper عام لجلب الأيام المجدولة - بحث في
bgm_allowed_daysuser meta أولاً، ثم fallback لجدولbgm_user_schedule - تطبيق الإصلاح في: مدير الفروع + مدير الفرع + الإداري + التقارير
📊 إصلاح بطاقات “حضوري” للاعب
- أيام الحضور = مجدول + غير مجدول + سماح (كانت بتستبعد حصص السماح)
🔧 إصلاح التحضير اليدوي
- إضافة حقل
is_grace_sessionالمفقود في INSERT عند التحضير اليدوي
📱 إصلاح إشعارات الحضور (WhatsApp)
- استخدام
BGM_WAWP_API::for_user()بدل API العام لإشعارات الحضور
AJAX Handlers
- إضافة
returnبعد كلwp_send_json_error— كان الكود يكمّل تنفيذ بعد إرسال الخطأ - إصلاح nonce الـ Quick Code
🛡 إصلاحات الصلاحيات
- استبدال
current_user_can('administrator')بـcan_bypass_branch_check()يدعمbranches_manager - إضافة صلاحيات:
manage_all_games,manage_branch_users,view_branch_reports - إجبار إعادة إنشاء الأدوار عند تحديث الإضافة
الإصدار 1.0.5 — 2025-05-15
🚀 ميزات جديدة
👥 نظام حضور وانصراف الموظفين (محسّن)
- تحديد أيام العطلة: يمكن لمدير الفرع تحديد “أيام العطلة” لكل موظف بشكل فردي (الجمعة هو الافتراضي).
- تقارير دقيقة: نسبة الحضور تُحسب الآن بناءً على أيام العمل الفعلية فقط (استبعاد أيام العطلة من الحساب).
⏰ نظام الجدولة والإشعارات الذكية
- تحديد مواعيد الحضور: إضافة حقل “وقت الحضور” لكل لاعب.
- إشعارات التأخير والغياب: نظام آلي يرسل رسائل واتساب عند تأخر اللاعب أو غيابه عن موعده.
- جدولة جماعية: إمكانية تحديد موعد موحد لمجموعة من اللاعبين دفعة واحدة.
- منطق صارم: الإشعارات تُرسل فقط في الأيام المجدولة للاعب.
🚪 نظام تسجيل الانصراف (Check-out)
- خيار جديد “تفعيل تسجيل الانصراف” في الإعدادات.
- المسح الأول = دخول ✅، المسح الثاني = خروج 🏃.
- تقارير الحضور تشمل الآن “وقت الدخول” و “وقت الخروج”.
🤖 الانصراف التلقائي (Auto-Checkout)
- إعداد جديد “مدة الحصة”: يقوم النظام بتسجيل انصراف تلقائي للاعبين الذين نسوا تسجيل الخروج بعد انتهاء المدة المحددة.
⚠️ التعامل مع الحضور غير المجدول
- الماسح الضوئي يُظهر “تحذير” عند محاولة تحضير لاعب في يوم غير مجدول له.
- خياران: “تسجيل حضور استثنائي” أو “إلغاء”.
📊 تحسينات تقارير الحضور (Attendance Reports)
- بطاقات إحصائية ذكية: إضافة ملخصات علوية (إجمالي، حضور، غياب، نسبة التزام) لصفحتي اللاعبين والموظفين.
- تتبع الحضور غير المجدول: تمييز الحضور في غير الأيام المخصصة (لون أصفر) واحتسابه بشكل منفصل.
- تحليلات دقيقة للغياب: احتساب الغياب فقط في الأيام المجدولة (لون أحمر).
- فلترة الفروع: إمكانية للمدراء (Admins) لاستعراض تقارير الحضور لأي فرع من القائمة المنسدلة.
- تحسينات بصرية: تحسين جداول الحضور برموز واضحة (✓ للحضور، ✗ للغياب المجدول).
🛠 تحسينات تقنية
- Service Layer Pattern: إعادة هيكلة الكود لاستخدام طبقة الخدمات (Services) لتحسين الأداء وسهولة الصيانة.
الإصدار 1.0.4 — 2025-04-25
🆕 دور مدير الفروع (branches_manager) — جديد بالكامل
الدور والصلاحيات
- دور جديد:
branches_manager(مدير الفروع) — يشوف كل الفروع واللاعبين والموظفين من الفرونت إند (حسابي) - يقدر يوقف/يفعّل حسابات اللاعبين والموظفين (لا يقدر يوقف administrator أو branches_manager)
- يقدر يحط إعدادات WAWP API خاصة لكل فرع
- يقدر يبعت رسائل للاعبين والموظفين بمرونة كاملة
صفحات حسابي (My Account) الجديدة
| الصفحة | المحتوى |
| 🏢 الفروع | كروت لكل فرع → صفحة تفاصيل شاملة (لاعبين + موظفين + إحصائيات + إعدادات WAWP API) |
| 👥 اللاعبين | كل لاعبي كل الفروع + فلتر فرع/لعبة/جنس + بحث + إيقاف/تفعيل حساب |
| 👔 الموظفين | كل الموظفين (مدير فرع + إداري) + فلتر فرع + إيقاف/تفعيل حساب |
| 📊 التقارير | إحصائيات شاملة: لاعبين / موظفين / فروع + فلتر فرع + جدول ملخص الفروع |
| 📋 حضور اللاعبين | سجل حضور + فلتر فرع/لعبة/جنس/تاريخ |
| ⏰ حضور الموظفين | سجل حضور + فلتر فرع/تاريخ |
| 🔔 الرسائل | إرسال لـ: كل لاعبي فرع / كل لاعبي لعبة / كل اللاعبين / موظفي فرع / كل الموظفين + سجل الرسائل |
| 🎫 العضويات | كل الفروع بفلتر |
| 🛒 الطلبات | كل الفروع بفلتر |
نظام إيقاف/تفعيل الحسابات
- زر ⏸ إيقاف و ▶ تفعيل بجانب كل لاعب/إداري/مدير فرع
- المستخدم الموقوف يشوف رسالة “تم إيقاف حسابك مؤقتاً من قِبل مدير الفروع” عند محاولة الدخول
- يتم منع الدخول من صفحة تسجيل الدخول + من template_redirect
- تخزين: bgm_account_suspended + bgm_suspended_by + bgm_suspended_at
WAWP API لكل فرع
- مدير الفروع يقدر يحط Access Token + Instance ID خاصين لكل فرع
- لو الفرع عنده API خاصة → تُستخدم تلقائياً في كل رسائل الفرع
- لو الفرع مفيهوش → يتم استخدام الإعدادات العامة (fallback)
BGM_WAWP_APIيقبلbranch_idويختار الـ credentials المناسبةBGM_WAWP_API::for_user($user_id)— يكتشف فرع المستخدم تلقائياً
✨ ميزات جديدة
🎫 صفحة إدارة العضويات (جديدة)
- صفحة فرونت إند جديدة في “حسابي” لعرض وإدارة عضويات WooCommerce Memberships
- تظهر فقط لمدير الفرع والإداري (مع مراعاة صلاحيات الجنس)
- عرض: اسم اللاعب، الخطة، اللعبة، تاريخ الاشتراك، تاريخ الانتهاء، الحالة
- ألوان مميزة لكل حالة: نشط (أخضر)، متوقف مؤقتاً (أصفر)، منتهي (أحمر)، ملغي (رمادي)
- زر إيقاف العضوية مؤقتاً مع نافذة لكتابة سبب الإيقاف
- زر استئناف العضوية للعضويات المتوقفة
- تسجيل ملاحظات تلقائية على العضوية (اسم المسؤول + السبب)
- فلاتر: بحث بالاسم/الإيميل + حالة العضوية + الخطة + اللعبة
🛒 صفحة إدارة الطلبات (جديدة)
- صفحة فرونت إند جديدة في “حسابي” لعرض أوردرات الفرع
- تعرض فقط الطلبات التي تحتوي على منتجات مربوطة بالفرع
- عرض: رقم الطلب، العميل، المنتجات، اللعبة، المبلغ، التاريخ، الحالة
- تغيير حالة الطلب مباشرة (select + زر حفظ) مع تسجيل ملاحظة على الأوردر
- فلاتر: بحث برقم الطلب/الاسم + حالة الطلب + اللعبة + من تاريخ/إلى تاريخ
- ترقيم صفحات (20 طلب لكل صفحة)
⚠️ فحص العضوية عند تسجيل الحضور (QR / كود اللاعب / يدوي)
- عند محاولة تحضير لاعب عنده إيقاف مؤقت، تظهر نافذة تحذيرية
- زر ✅ “تحضير اللاعب + إلغاء الإيقاف المؤقت” — يستأنف العضوية ويسجل الحضور
- زر ❌ “إلغاء – عدم التحضير” — يُلغي العملية بالكامل
- يعمل مع: مسح QR، إدخال كود اللاعب، الزر اليدوي
🔒 صلاحيات الجنس (admin_category)
- إداري الفرع في صفحة العضويات: يشوف فقط اللاعبين حسب فئته (ولاد/بنات/الكل)
- إداري الفرع في صفحة الطلبات: يشوف فقط طلبات اللاعبين حسب فئته
- مدير الفرع: يشوف كل اللاعبين والطلبات في فرعه
🎮 فلترة حسب اللعبة
- العضويات: فلتر حسب اللعبة المسجل فيها اللاعب (من جدول bgm_player_games)
- الطلبات: فلتر حسب اللعبة المربوطة بالمنتج (دعم المنتج البسيط + Variation)
- عمود “اللعبة” في جدول العضويات يعرض كل ألعاب اللاعب في الفرع
- عمود “اللعبة” في جدول الطلبات يعرض اللعبة المربوطة بكل منتج
📱 تحسينات واجهة المستخدم
- الجداول الكبيرة scrollable أفقياً وعمودياً (max-height: 70vh)
- تثبيت رأس الجدول (sticky header) عند التمرير العمودي
- حدود مستديرة للجداول
- تصميم متجاوب للموبايل (الفلاتر تتحول لعمودية)
🚫 إخفاء صفحات WooCommerce الافتراضية
- إخفاء صفحة “الطلبات” الافتراضية من حسابي للإداري ومدير الفرع
- إخفاء صفحة “العناوين” من حسابي للإداري ومدير الفرع
- إخفاء صفحة “العضويات” الافتراضية لـ WooCommerce Memberships
- إخفاء صفحات: التنزيلات، طرق الدفع، الاشتراكات
- فلتر متأخر (priority 999) لضمان إخفاء أي عناصر تضيفها إضافات أخرى
- لا يتأثر مدير الموقع (administrator) — يرى كل شيء
🐛 إصلاحات
- إصلاح سجل الإشعارات: كان يستخدم اسم عمود خاطئ
nl.messageبدلnl.message_content - إصلاح استعلام الطلبات: تحسين التوافق مع PHP القديم (إزالة spread operator)
- إصلاح فلتر المنتجات: شمول كل حالات المنتج (publish + private + draft)
- إصلاح سجل الإشعارات في الداشبورد: اسم الجدول كان خطأ
bgm_notifications→bgm_notification_log - إضافة طريقة بديلة (fallback) لجلب الطلبات عبر لاعبي الفرع إذا لم توجد منتجات مربوطة
🔧 تحسينات لوحة التحكم (WordPress Dashboard)
تقارير الحضور (محسّنة)
- فلتر اللعبة: عرض سجلات حضور لعبة محددة
- فلتر اللاعب: عرض سجلات لاعب معين
- فلتر الجنس: ولاد / بنات / الكل
- فلتر يوم مجدول: مجدول / غير مجدول / الكل
- بحث بالاسم
- عمود “اللعبة” في الجدول
- رمز الجنس (♂/♀) بجانب اسم اللاعب
- تصدير CSV شامل مع BOM للعربية
- إحصائية حضور الأيام المجدولة
سجل الإشعارات (أُعيد بناؤه بالكامل)
- يقرأ من الجدول الصحيح
bgm_notification_logمع الأعمدة الصحيحة - فلتر البحث: اسم / هاتف / نص الرسالة
- فلتر النوع: حضور / غياب / تقرير شهري / مخصص / QR كود
- فلتر الحالة: مُرسل / فشل / في الانتظار / مُستلم
- فلتر الفرع (للأدمن)
- فلتر التاريخ (من – إلى)
- عمود الهاتف وعمود الخطأ
- ترقيم صفحات (50 لكل صفحة)
- تصدير CSV
- تقييد البيانات حسب الفرع للمدير والإداري
لوحة التحكم الرئيسية (محسّنة)
- فلتر الفرع للأدمن — يغيّر كل الإحصائيات حسب الفرع المختار
- كارت عدد اللاعبين + كارت عدد الفروع (للأدمن)
- الإحصائيات عبر AJAX تحترم فلتر الفرع
إرسال الرسائل (محسّنة)
- فلتر الفرع للأدمن — تحديث قائمة اللاعبين تلقائياً
- اختيار نوع الإرسال: لاعبين محددين / كل لاعبي لعبة / كل لاعبي الفرع
- فلتر لعبة للإرسال لكل لاعبي لعبة معينة
- عرض رمز الجنس (♂/♀) وعلامة ⚠️ للاعبين بدون رقم هاتف
قائمة انتظار الرسائل (محسّنة)
- فلتر الفرع للأدمن
- فلتر الحالة + فلتر النوع + بحث
- عمود “بواسطة” يعرض اسم مُرسل الرسالة
- زر “إعادة الفاشلة” لإرجاع الرسائل الفاشلة لقائمة الانتظار
الإصدار 1.0.3 — 2025-04-08
✨ ميزات جديدة
📄 تقرير شهري PDF
- زر “📄 تحميل تقرير الشهر PDF” في صفحة تقارير الفرع
- يفتح صفحة مطبوعة جاهزة للحفظ كـ PDF (Ctrl+P → حفظ كـ PDF)
- يشمل: ملخص عام، إحصائيات الألعاب، إحصائيات الجنس، رسم بياني يومي
- أعلى 10 لاعبين حضوراً، تنبيه اللاعبين الأقل من 50%
- حضور الموظفين، ملخص الإشعارات
- يحترم فئة الإداري (أولاد/بنات/الكل)
📆 صفحة سجل حضور اللاعبين
- صفحة جديدة “📆 سجل حضور اللاعبين” في حسابي
- جدول شهري يعرض حضور كل لاعب لكل يوم
- فلتر بالشهر + فلتر لاعب + فلتر جنس
- تصدير إكسل + أسكرول أفقي مع تثبيت عمود الاسم
الإصدار 1.0.2 — 2025-03-20
✨ ميزات جديدة
تقرير شهري PDF
- زر “📄 تحميل تقرير الشهر PDF” في صفحة تقارير الفرع
- يفتح صفحة مطبوعة جاهزة للحفظ كـ PDF (Ctrl+P → حفظ كـ PDF)
- يشمل: ملخص عام، إحصائيات الألعاب، إحصائيات الجنس، رسم بياني يومي
- أعلى 10 لاعبين حضوراً، تنبيه اللاعبين الأقل من 50%
- حضور الموظفين، ملخص الإشعارات
- يحترم فئة الإداري (أولاد/بنات/الكل)
صفحة سجل حضور اللاعبين (جديدة)
- صفحة جديدة “📆 سجل حضور اللاعبين” في حسابي
- جدول شهري يعرض حضور كل لاعب لكل يوم
- فلتر بالشهر + فلتر لاعب + فلتر جنس
- تصدير إكسل + أسكرول أفقي مع تثبيت عمود الاسم
نظام فئة الإداري (admin_category)
- حقل جديد “الفئة المسؤول عنها” عند إنشاء حساب إداري
- خيارات: أولاد فقط / بنات فقط / أولاد وبنات
- يتحكم في كل الصفحات والتقارير
تعديل بيانات اللاعبين
- عمود “تعديل” منفصل مع زر تعديل ولي الأمر وزر تعديل الجنس
🐛 إصلاحات
- إصلاح أيام الحضور: كان يقرأ من meta key غلط (bgm_schedule_days بدل bgm_allowed_days)
- إصلاح حفظ الأيام: PHP كان يتوقع JSON لكن jQuery يبعث array
- إصلاح AJAX URL لتعديل بيانات ولي الأمر
- عزل بيانات الفرع — كل فرع يشوف بياناته فقط
الإصدار 1.0.1 — 2025-03-05
- عرض اللعبة في حسابي + QR تلقائي + إرسال QR واتساب
- إعداد المستلم لكل قالب + دعم منتج بسيط ومتعدد
- WAWP API v2 + تصدير إكسل + نظام رسائل جماعية
الإصدار 1.0.0 — 2025-02-18
- الإصدار الأول: نظام الفروع، الألعاب، الحضور، QR، إشعارات واتساب
