role ?? null; if ($role !== 'admin' && $role !== 'super_admin') { http_response_code(403); echo json_encode([ 'status' => 'failure', 'message' => 'Forbidden. Admin access required.', ], JSON_UNESCAPED_UNICODE); exit; } // الحالات المسموح بها — قائمة مغلقة حتى لا تُكتب حالة عشوائية في الجدول const WITHDRAWAL_STATUSES = ['pending', 'approved', 'rejected', 'paid']; // التوجيه بحقل action لا بطريقة HTTP: عميل اللوحة (CRUD.getWallet في // siro_admin) يرسل كل الطلبات بـ POST form-encoded، فالتفريق بالطريقة كان // سيوجّه طلبات العرض إلى فرع التحديث. $body = $_POST; if (empty($body)) { $raw = json_decode(file_get_contents('php://input'), true); if (is_array($raw)) $body = $raw; } $action = $body['action'] ?? $_GET['action'] ?? 'list'; try { // ── تحديث حالة طلب ─────────────────────────────────────── if ($action === 'update_status') { // صرف المال فعلياً قرار لا رجعة فيه — نقصره على super_admin if ($role !== 'super_admin') { http_response_code(403); echo json_encode([ 'status' => 'failure', 'message' => 'Forbidden. Super Admin required to change withdrawal status.', ], JSON_UNESCAPED_UNICODE); exit; } $id = isset($body['id']) ? (int)$body['id'] : 0; $status = trim((string)($body['status'] ?? '')); if ($id <= 0 || !in_array($status, WITHDRAWAL_STATUSES, true)) { http_response_code(400); echo json_encode([ 'status' => 'failure', 'message' => 'Invalid id or status. Allowed: ' . implode(', ', WITHDRAWAL_STATUSES), ], JSON_UNESCAPED_UNICODE); exit; } // لا نسمح بتعديل طلب خرج من pending إلا إلى paid — يمنع عكس رفض // أو إعادة اعتماد طلب مدفوع بالخطأ. $cur = $con->prepare("SELECT status FROM driver_withdrawal_requests WHERE id = ?"); $cur->execute([$id]); $current = $cur->fetchColumn(); if ($current === false) { http_response_code(404); echo json_encode(['status' => 'failure', 'message' => 'Request not found.'], JSON_UNESCAPED_UNICODE); exit; } if ($current !== 'pending' && !($current === 'approved' && $status === 'paid')) { http_response_code(409); echo json_encode([ 'status' => 'failure', 'message' => "Cannot change status from '$current' to '$status'.", ], JSON_UNESCAPED_UNICODE); exit; } $upd = $con->prepare("UPDATE driver_withdrawal_requests SET status = ? WHERE id = ?"); $upd->execute([$status, $id]); error_log("[withdrawal_requests] id=$id '$current' -> '$status' by " . ($decodedToken->user_id ?? 'unknown')); echo json_encode([ 'status' => 'success', 'data' => ['id' => $id, 'from' => $current, 'to' => $status], ], JSON_UNESCAPED_UNICODE); exit; } // ── قائمة الطلبات ──────────────────────────────────────── $filter = $body['status'] ?? $_GET['status'] ?? 'pending'; $limit = (int)($body['limit'] ?? $_GET['limit'] ?? 100); $limit = max(1, min(200, $limit)); $where = ''; $params = []; if ($filter !== 'all') { if (!in_array($filter, WITHDRAWAL_STATUSES, true)) { http_response_code(400); echo json_encode(['status' => 'failure', 'message' => 'Invalid status filter.'], JSON_UNESCAPED_UNICODE); exit; } $where = 'WHERE status = :status'; $params = [':status' => $filter]; } $stmt = $con->prepare(" SELECT id, driver_id, driver_name, amount, wallet_type, wallet_number, status, created_at, updated_at FROM driver_withdrawal_requests $where ORDER BY created_at DESC LIMIT $limit "); $stmt->execute($params); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as &$r) { $r['amount'] = (float)$r['amount']; $r['id'] = (int)$r['id']; } unset($r); // مجاميع لكل حالة — تغذّي شارات العدّ في اللوحة دون طلب إضافي $totals = []; $agg = $con->query(" SELECT status, COUNT(*) AS cnt, COALESCE(SUM(amount), 0) AS total FROM driver_withdrawal_requests GROUP BY status "); foreach ($agg->fetchAll(PDO::FETCH_ASSOC) as $a) { $totals[$a['status']] = [ 'count' => (int)$a['cnt'], 'total' => (float)$a['total'], ]; } echo json_encode([ 'status' => 'success', 'data' => [ 'filter' => $filter, 'requests' => $rows, 'totals' => $totals, ], ], JSON_UNESCAPED_UNICODE); } catch (Throwable $e) { error_log('[withdrawal_requests] ' . $e->getMessage()); http_response_code(500); echo json_encode([ 'status' => 'failure', 'message' => 'An internal error occurred.', ], JSON_UNESCAPED_UNICODE); }