return$db->selectOne("SELECT * FROM treasuries WHERE code = 'SUB_MEM' AND is_active = 1");
}
publicstaticfunctiongetByCode(string$code):?array
{
$db=App::getInstance()->db();
return$db->selectOne("SELECT * FROM treasuries WHERE code = ? AND is_active = 1",[$code]);
}
publicstaticfunctiongetMainTreasury():?array
publicstaticfunctiongetMainTreasury():?array
{
{
$db=App::getInstance()->db();
$db=App::getInstance()->db();
...
@@ -164,9 +176,10 @@ final class TreasuryService
...
@@ -164,9 +176,10 @@ final class TreasuryService
$where.=" AND pr.status IN ('pending','processing')";
$where.=" AND pr.status IN ('pending','processing')";
}
}
// Filter by sports-related payment types for sub-treasury
if($treasury['code']==='SUB_SA'){
if($treasury['type']==='sub'){
$where.=" AND pr.payment_type IN ('activity_subscription','hourly_booking','sports_registration')";
$where.=" AND pr.payment_type IN ('activity_subscription','hourly_booking','sports_registration')";
}elseif($treasury['code']==='SUB_MEM'){
$where.=" AND pr.payment_type IN ('form_fee','membership_fee','down_payment','addition_fee','annual_subscription','divorce_fee','death_fee','waiver_fee','separation_fee','fine','carnet_replacement','seasonal_fee')";
"SELECT COUNT(*) as count FROM payment_requests WHERE status IN ('pending','processing') AND is_voided = 0 AND payment_type IN ('activity_subscription','hourly_booking','sports_registration')"
"SELECT COUNT(*) as count FROM payment_requests WHERE status IN ('pending','processing') AND is_voided = 0 AND payment_type IN {$typeFilter}"
<divclass="tut-step"><divclass="tut-step-num">1</div><h3class="tut-step-title">فتح تسجيل اللاعبين</h3><divclass="tut-step-body">من صفحة المجموعة > <spanclass="field">تسجيل لاعب</span>.</div></div>
<divclass="tut-step"><divclass="tut-step-num">1</div><h3class="tut-step-title">فتح تسجيل اللاعبين</h3><divclass="tut-step-body">من صفحة المجموعة > <spanclass="field">تسجيل لاعب</span>.</div></div>
<divclass="tut-step"><divclass="tut-step-num">2</div><h3class="tut-step-title">البحث عن اللاعب</h3><divclass="tut-step-body">ابحث بالاسم أو الرقم التسلسلي أو الرقم القومي.</div></div>
<divclass="tut-step"><divclass="tut-step-num">2</div><h3class="tut-step-title">البحث عن اللاعب</h3><divclass="tut-step-body">ابحث بالاسم أو الرقم التسلسلي أو الرقم القومي.</div></div>
<divclass="tut-step"><divclass="tut-step-num">3</div><h3class="tut-step-title">التحقق التلقائي</h3><divclass="tut-step-body">النظام يتحقق من:<ul><li>الحالة الطبية: لازم تكون <spanclass="field">fit</span> أو <spanclass="field">conditional</span></li><li>السعة: المجموعة لسه فيها مكان</li><li>العمر: ضمن الفئة العمرية للبرنامج</li><li>عدم التكرار: مش مسجل بالفعل</li></ul><spanclass="warn">إذا اللاعب حالته الطبية "pending" أو "unfit" أو "expired"، التسجيل مرفوض تلقائياً.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">3</div><h3class="tut-step-title">التحقق التلقائي</h3><divclass="tut-step-body">النظام يتحقق من:<ul><li>الحالة الطبية: لازم تكون <spanclass="field">fit</span> أو <spanclass="field">conditional</span></li><li>السعة: المجموعة لسه فيها مكان</li><li>العمر: ضمن الفئة العمرية للبرنامج</li><li>عدم التكرار: مش مسجل بالفعل</li></ul><spanclass="warn">إذا اللاعب حالته الطبية "pending" أو "unfit" أو "expired"، التسجيل مرفوض تلقائياً.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">4</div><h3class="tut-step-title">نتيجة التسجيل</h3><divclass="tut-step-body">إذا كل الشروط تمام → يتم التسجيل. إذا المجموعة ممتلئة → يُعرض خيار "قائمة الانتظار".<spanclass="success">بعد التسجيل بنجاح، اللاعب يظهر في كشف الحضور اليومي ويتم توليد اشتراك شهري له.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">4</div><h3class="tut-step-title">نتيجة التسجيل</h3><divclass="tut-step-body">إذا كل الشروط تمام → يُسجل اللاعب بحالة <spanclass="field">pending_payment</span> (في انتظار الدفع). إذا المجموعة ممتلئة → يُعرض خيار "قائمة الانتظار".<spanclass="info">التسجيل لا يُفعّل مباشرة — يجب دفع أول اشتراك من خزنة الأنشطة أولاً. انظر: <ahref="/tutorials/sports-activity/enrollment-payment"style="color:#1E40AF;font-weight:600;">الدفع الإجباري عند التسجيل</a>.</span><spanclass="success">بعد التحصيل: اللاعب يظهر في كشف الحضور اليومي ويتم توليد اشتراك شهري له.</span></div></div>
<divclass="tut-nav">
<divclass="tut-nav">
<ahref="/tutorials/sports-activity/create-group"><idata-lucide="arrow-right"style="width:14px;height:14px;"></i> إنشاء مجموعة تدريبية</a>
<ahref="/tutorials/sports-activity/create-group"><idata-lucide="arrow-right"style="width:14px;height:14px;"></i> إنشاء مجموعة تدريبية</a>
<div><h1>الدفع الإجباري عند التسجيل</h1><p>لا يتم تفعيل التسجيل بدون دفع أول اشتراك من خزنة الأنشطة</p></div>
</div>
<divclass="tut-step"><divclass="tut-step-num">1</div><h3class="tut-step-title">كيف يعمل النظام؟</h3><divclass="tut-step-body">عند تسجيل لاعب في مجموعة، لا يُفعّل التسجيل مباشرة. بدلاً من ذلك:<ul><li>يُسجل اللاعب بحالة <spanclass="field">pending_payment</span> (في انتظار الدفع)</li><li>يُنشئ النظام <strong>طلب دفع</strong> تلقائياً في طابور خزنة الأنشطة</li><li>المبلغ = رسم الاشتراك الشهري للمجموعة (حسب نوع اللاعب: عضو أو غير عضو)</li></ul><spanclass="info">هذا يضمن عدم تفعيل أي تسجيل بدون سداد — لا استثناءات إلا عبر الإعفاء الرسمي.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">2</div><h3class="tut-step-title">حالة اللاعب بعد التسجيل</h3><divclass="tut-step-body">في صفحة المجموعة، اللاعب يظهر بخلفية صفراء وبادج <spanclass="field">في انتظار الدفع</span>.<ul><li>لا يُحسب ضمن العدد الفعلي للمجموعة (السعة)</li><li>لا يظهر في كشوف الحضور</li><li>لا يُولد له اشتراك شهري</li></ul><spanclass="warn">إذا أُلغي طلب الدفع بدون تحصيل — التسجيل يبقى معلقاً ولا يُحذف تلقائياً.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">3</div><h3class="tut-step-title">تحصيل الدفعة</h3><divclass="tut-step-body">أمين خزنة الأنشطة يفتح طابور الدفع ويرى الطلب بنوع <spanclass="field">sports_registration</span>. يقوم بالتحصيل بالطريقة المعتادة (نقدي/فيزا/شيك).<divclass="tut-diagram">تسجيل لاعب → طلب دفع (pending) → تحصيل من الخزنة → تفعيل التسجيل (active)</div></div></div>
<divclass="tut-step"><divclass="tut-step-num">4</div><h3class="tut-step-title">التفعيل التلقائي</h3><divclass="tut-step-body">بعد التحصيل الناجح، النظام يقوم تلقائياً بـ:<ul><li>تغيير حالة التسجيل من <spanclass="field">pending_payment</span> إلى <spanclass="field">active</span></li><li>زيادة عدد اللاعبين الفعليين في المجموعة</li><li>إنشاء أول اشتراك شهري بحالة <spanclass="field">paid</span></li><li>طباعة إيصال الدفع</li></ul><spanclass="success">من هذه اللحظة، اللاعب يظهر في كشوف الحضور ويُولد له اشتراك شهري كل شهر.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">5</div><h3class="tut-step-title">ماذا لو أُلغيت الدفعة؟</h3><divclass="tut-step-body">إذا تم إلغاء (void) دفعة تسجيل بعد التحصيل:<ul><li>يعود التسجيل لحالة <spanclass="field">pending_payment</span></li><li>يتم خفض عدد اللاعبين في المجموعة</li><li>يحتاج اللاعب لدفعة جديدة لإعادة التفعيل</li></ul><spanclass="warn">الإلغاء يُرجع حالة التسجيل فقط — لا يحذف سجل اللاعب من المجموعة.</span></div></div>
<divclass="tut-nav">
<ahref="/tutorials/sports-activity/enroll-player"><idata-lucide="arrow-right"style="width:14px;height:14px;"></i> تسجيل لاعب في مجموعة</a>
<ahref="/tutorials/sports-activity/sports-payment-queue">طابور دفع الأنشطة الرياضية <idata-lucide="arrow-left"style="width:14px;height:14px;"></i></a>
<div><h1>طابور دفع الأنشطة الرياضية</h1><p>عرض ومعالجة طلبات الدفع في خزنة الأنشطة الفرعية</p></div>
</div>
<divclass="tut-step"><divclass="tut-step-num">1</div><h3class="tut-step-title">فتح الطابور</h3><divclass="tut-step-body">من القائمة الجانبية: <spanclass="field">خزنة الأنشطة</span> > <spanclass="field">طابور الدفع</span>. يظهر جميع طلبات الدفع المعلقة والجارية المرتبطة بالأنشطة الرياضية.<spanclass="info">الطابور يتحدث تلقائياً كل 30 ثانية. أنواع الطلبات: تسجيل رياضي، اشتراك نشاط، حجز ساعة، إيجار لوكر.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">2</div><h3class="tut-step-title">التأكد من وجود وردية مفتوحة</h3><divclass="tut-step-body">قبل التحصيل — يجب أن تكون هناك وردية مفتوحة. إذا لم تكن موجودة:<ul><li>يظهر شريط أصفر: «لا توجد وردية مفتوحة»</li><li>اضغط <spanclass="field">فتح وردية</span> لبدء العمل</li></ul><spanclass="warn">لا يمكن تحصيل أي دفعة بدون وردية مفتوحة — الزر «تحصيل» لن يعمل.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">3</div><h3class="tut-step-title">اختيار طلب الدفع</h3><divclass="tut-step-body">اضغط <spanclass="field">تحصيل</span> بجانب الطلب المطلوب. تُفتح صفحة التحصيل بمعلومات:<ul><li>اسم اللاعب/العضو</li><li>نوع الدفعة (تسجيل رياضي، اشتراك شهري، حجز ساعة)</li><li>المبلغ المطلوب</li><li>تفاصيل إضافية (المجموعة، الوحدة، التاريخ)</li></ul></div></div>
<divclass="tut-step"><divclass="tut-step-num">4</div><h3class="tut-step-title">اختيار طريقة الدفع والتحصيل</h3><divclass="tut-step-body">حدد <spanclass="field">طريقة الدفع</span>: نقدي، فيزا، شيك، أو تحويل بنكي. لكل طريقة حقول إضافية (رقم الشيك، مرجع التحويل...). ثم اضغط <spanclass="field">تأكيد التحصيل</span>.<divclass="tut-diagram">طلب دفع (pending) → تحصيل → إيصال + قيد محاسبي + تفعيل الخدمة</div><spanclass="success">بعد التحصيل: يُطبع الإيصال تلقائياً، ويُربط المبلغ بالوردية الحالية وعهدة أمين الخزنة.</span></div></div>
<divclass="tut-step"><divclass="tut-step-num">5</div><h3class="tut-step-title">إغلاق الوردية والتسوية</h3><divclass="tut-step-body">بعد الانتهاء من التحصيلات:<ul><li>اضغط <spanclass="field">إغلاق الوردية</span> — يُحفظ إجمالي التحصيلات</li><li>أنشئ <spanclass="field">تسوية</span> لترحيل المبالغ للخزنة الرئيسية</li><li>أمين الخزنة الرئيسية يستلم ويؤكد</li></ul><spanclass="info">شريط الوردية يعرض دائماً: رقم الوردية، عدد الإيصالات، إجمالي التحصيلات، ورصيد العهدة الحالي.</span></div></div>
<divclass="tut-nav">
<ahref="/tutorials/sports-activity/enrollment-payment"><idata-lucide="arrow-right"style="width:14px;height:14px;"></i> الدفع الإجباري عند التسجيل</a>