"SELECT COALESCE(SUM(CASE WHEN s.status IN ('pending','overdue') THEN (s.base_amount + s.development_fee + s.fine_amount - s.discount_amount) ELSE 0 END), 0) as total
// Update member status for suspension/ban/termination
if(in_array($penaltyType,['suspension','ban'])){
$db->update('members',['status'=>'suspended','updated_at'=>date('Y-m-d H:i:s')],'`id` = ? AND `status` = \'active\'',[(int)$violation['member_id']]);
}elseif($penaltyType==='termination'){
$db->update('members',['status'=>'terminated','updated_at'=>date('Y-m-d H:i:s')],'`id` = ? AND `status` IN (\'active\',\'suspended\')',[(int)$violation['member_id']]);
// Cancel any pending individual addition_fee requests — the collective payment subsumes them
$pendingAdditions=$db->select(
"SELECT id FROM payment_requests WHERE member_id = ? AND payment_type = 'addition_fee' AND status IN ('pending','processing') AND is_voided = 0",
[(int)$id]
);
foreach($pendingAdditionsas$pa){
PaymentRequestService::cancelRequest((int)$pa['id'],'ألغي تلقائياً — مشمول في الفاتورة المجمعة');
}
$bill=BillingService::getMemberBill((int)$id);
$breakdown=[];
foreach($bill['items']??[]as$item){
...
...
@@ -277,6 +287,13 @@ class MemberController extends Controller
$fee=$entity['addition_fee']??'0.00';
if(bccomp($fee,'0.01',2)<0)return$this->redirect('/members/'.$id)->withError('لا توجد رسوم مستحقة');
// Check if already paid via payments table
$alreadyPaid=$db->selectOne(
"SELECT id FROM payments WHERE member_id = ? AND payment_type = 'addition_fee' AND related_entity_type = ? AND related_entity_id = ? AND is_voided = 0 LIMIT 1",
[(int)$id,$entityType,$entityId]
);
if($alreadyPaid)return$this->redirect('/members/'.$id)->withError('تم سداد رسوم هذا التابع بالفعل');