سجل التحديثات الشامل لإضافة Branch Games Manager (BGM)

الإصدار 1.3.5.3 — 2026-06-08

🐛 إصلاحات حرجة

📨 إصلاح توجيه الإشعارات — وصول الرسائل لولي الأمر فقط بدل اللاعب وولي الأمر

المشكلة:
بعض الإشعارات (الغياب، التأخير، الحضور، انتهاء الاشتراك…) كانت تُرسل لولي الأمر فقط رغم اختيار “اللاعب وولي الأمر”.

السبب الجذري:
القيم الافتراضية في النظام كانت 'parent' بدل 'both' في عدة أماكن:

  1. get_option() كان يرجع 'parent' عند عدم وجود قيمة محفوظة
  2. مصفوفة القوالب $templates_info كانت تستخدم 'default_rec' => 'parent'
  3. القوائم في صفحة الإعدادات كانت تعرض “ولي الأمر فقط” كخيار افتراضي
  4. دالة التثبيت set_default_options() كانت تحفظ 'parent' كبداية

الحل:
توحيد القيم الافتراضية إلى 'both' في جميع أجزاء النظام:

  • class-bgm-notifications.php — تعديل 12 fallback
  • html-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:

  1. المطابقة غير شاملة
  2. غياب مطابقة _product_id
  3. عدم تحديث تاريخ الانتهاء
  4. فشل حفظ التغييرات
  5. عدم تحديث تاريخ البدء
  6. اختلاف أنواع البيانات
  7. بقاء بيانات قديمة تؤثر على الحالة

الحل:

  • إعادة كتابة الميثود بالكامل
  • إضافة 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_started
    • holiday_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 handlers
  • class-bgm-notifications.php
    إضافة 2 methods للإشعارات + تسجيل hooks
  • class-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.php
  • class-bgm-branches-manager-account.php
  • class-bgm-notifications.php
  • class-bgm-install.php
  • class-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 تحسينات):
    1. صفحة التحضير: إضافة تنبيه ⚠️ X لاعب بدون عضوية نشطة في معلومات الفرع + بادج تحذيرية بجنب اسم كل لاعب بدون عضوية.
    2. صفحة العضويات: إضافة كارت إحصائي جديد ⚠️ بدون عضوية يعرض عدد اللاعبين المسجلين بدون عضوية.
    3. مودال التفاصيل: عند الضغط على كارت “بدون عضوية” يظهر مودال بقائمة كاملة (الاسم، البريد، الهاتف، اللعبة) مع نصيحة للمدير بإنشاء عضوية أو إلغاء التسجيل.
  • الأداء: استعلام واحد فقط (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 طبقات حماية):
    1. MySQL Concurrency Lock: إضافة GET_LOCK('bgm_absence_check', 0) في بداية الدالة — لو عملية تانية شغالة، العملية الجديدة بتتجاهل فوراً.
    2. Atomic Duplicate Check في send_absence_notification: فحص bgm_notification_log مرة تانية قبل الإرسال الفعلي كخط دفاع أخير.
    3. Atomic Duplicate Check في send_late_notification: نفس الحماية لرسائل التأخير.
  • الملف: 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 مشاكل):
    1. مقارنة صارمة: في ajax_edit_membership كانت المقارنة $plan->get_id() === $trial_plan_id بـ === ممكن تفشل بسبب اختلاف النوع (int vs string).
    2. عدم مزامنة في العضويات غير التجريبية: لو العضوية المُعدَّلة ليست على الخطة التجريبية، لا يتم تحديث bgm_trial_subscriptions إطلاقاً.
    3. استعلام العرض بدون فحص التاريخ: صفحة “جدولي وألعابي” كانت تجلب الاشتراكات بشرط status = 'active' فقط بدون التحقق من end_date أو حالة العضوية.
  • الحل (3 طبقات حماية):
    1. إصلاح المقارنة: تغيير === إلى == في ajax_edit_membership.
    2. Safety Net: لو العضوية أصبحت expired/cancelled/paused → يتم تحديث جميع الاشتراكات التجريبية النشطة لهذا المستخدم إلى expired.
    3. طبقات فحص في صفحة العرض: إضافة شرط 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 — التقارير وأكواد QR
    • trait-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
  • تسجيل في 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)
  • إشعار الواتساب التلقائي: إرسال رسالة تبريكات وكود الكوبون للاعب أو ولي أمره أو كليهما بناءً على الإعدادات

✉️ قوالب الرسائل لمدير الفرع (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_branch meta بدلاً من جدول الألعاب المقتصر على الاشتراكات النشطة فقط.

📊 بطاقات الإحصائيات في الداشبورد (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

🎮 الألعاب في إنشاء المجموعة

  • المشكلة: قائمة الألعاب عند إنشاء مجموعة كانت تعتمد فقط على 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

🐛 إصلاحات (تحديث ما بعد الإصدار)

👤 قسم رسائل الموظفين لا يظهر في صفحة إدارة الإشعارات (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_branch meta في كل شراء — فتُكتب فوق القيمة السابقة، ويبقى للاعب فرع واحد فقط في 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_members JOIN bgm_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_days meta — قيمة واحدة بتتكتب فوق نفسها
  • الحل: استبدال المصدر بـ query مباشر على bgm_group_members JOIN bgm_groups لجلب أيام كل مجموعات اللاعب، ثم دمجها في set واحد بدون تكرار — فلو اللاعب في لعبتين يظهر مجموع الأيام الفعلي من المجموعتين

🏢 إصلاح ظهور اللاعب في فرع واحد فقط عند التسجيل في فرعين

  • المشكلة: لاعب مشترك في فرعين (لعبة في الدمام + لعبة في الخبر مثلاً) يظهر فقط في آخر فرع اشترى فيه
  • السبب 1 — الفلتر: فلتر الفرع في bm-attendance-log كان يعتمد على user_branch meta — وهي قيمة واحدة بتتكتب فوق نفسها في كل عملية شراء
  • الحل 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_data array مباشرة (نفس إصلاح حضور الموظفين)

✨ تحسينات

فلترة المصروفات حسب القسم (بنين / بنات)

  • عمود 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=1window.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 مع customer array ما بيفلترش صح — نفس المشكلة اللي كانت في التقارير
  • الحل: تغيير لـ 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 مع customer array كان يرجع طلبات كل الفروع بدل الفرع المحدد
  • الحل: تغيير لـ per-player iteration باستخدام customer_id (singular) مع date range filtering
  • تم الإصلاح في 3 أماكن:
    • تقارير مدير الفرع (branch_reports_content)
    • تقارير مدير الفروع (reports_content) — الإجمالي
    • جدول ملخص الفروع — إيرادات كل فرع

إصلاح فلاتر الإيرادات

  • إصلاح get_users كان يرجع 10 لاعبين فقط — الآن يجلب كل اللاعبين (number => -1)
  • إصلاح فلتر التاريخ: دعم >= و <= بدل format from...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_log table
    • تنظيف تلقائي لكل الـ 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: إزالة $already check الزائدة بعد 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 بغض النظر عن وقت وصوله.
  • الأولوية في قراءة الموعد:
    1. جدول bgm_user_schedule (الأدق)
    2. bgm_scheduled_time في user meta
    3. scan_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_resume handler لتحضير اللاعب + إلغاء إيقاف العضوية
  • حماية ضد الأخطاء: 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_days user 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_notificationsbgm_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، إشعارات واتساب