getHeader('x-user-id'); $type = strtoupper(trim((string)$request->get('type', 'HOSPITAL'))); $nameAr = trim((string)$request->get('name_ar')); $nameEn = trim((string)$request->get('name_en', '')); $category = trim((string)$request->get('category', 'عام')); $country = trim((string)$request->get('country', 'العراق')); $city = trim((string)$request->get('city', 'بغداد')); $discount = (float)$request->get('discount_percentage', $type === 'HOSPITAL' ? 50.00 : 50.00); $phone = trim((string)$request->get('phone', '')); $address = trim((string)$request->get('address', '')); if (empty($nameAr)) { Response::error('Partner Arabic name is required.'); } $pdo = Database::getConnection(); $stmt = $pdo->prepare(' INSERT INTO partners (type, name_ar, name_en, category, country, city, discount_percentage, address, phone, is_active, added_by_admin, created_at) VALUES (:type, :name_ar, :name_en, :category, :country, :city, :discount, :address, :phone, 1, :admin_id, NOW()) '); $stmt->execute([ ':type' => $type, ':name_ar' => $nameAr, ':name_en' => $nameEn, ':category' => $category, ':country' => $country, ':city' => $city, ':discount' => $discount, ':address' => $address, ':phone' => $phone, ':admin_id' => $userId, ]); $newId = (int)$pdo->lastInsertId(); Response::success([ 'partner_id' => $newId, 'name_ar' => $nameAr, 'discount' => $discount, 'message' => 'تمت إضافة الشريك بنجاح ومتاح فورياً لجميع المشتركين.', ], 'Partner created successfully.'); } /** * GET /api/v1/admin/payments/pending */ public function listPendingPayments(Request $request): void { $pdo = Database::getConnection(); $stmt = $pdo->query(' SELECT t.id, t.subscription_id, t.reference_number, t.amount, t.currency, t.method, t.receipt_image_url, t.created_at, u.id AS user_id, u.full_name, u.phone, s.membership_number FROM transactions t JOIN subscriptions s ON s.id = t.subscription_id JOIN users u ON u.id = t.user_id WHERE t.status = "SUBMITTED" ORDER BY t.id DESC LIMIT 50 '); $pending = $stmt->fetchAll(PDO::FETCH_ASSOC); Response::success($pending, 'Pending payments list retrieved.'); } /** * POST /api/v1/admin/payments/approve */ public function approvePayment(Request $request): void { $adminId = (int)$request->getHeader('x-user-id'); $transactionId = (int)$request->get('transaction_id'); $pdo = Database::getConnection(); $pdo->beginTransaction(); try { $stmt = $pdo->prepare('SELECT id, subscription_id, user_id FROM transactions WHERE id = :id LIMIT 1'); $stmt->execute([':id' => $transactionId]); $trans = $stmt->fetch(PDO::FETCH_ASSOC); if (!$trans) { Response::notFound('Transaction not found.'); } // Update transaction $updTrans = $pdo->prepare('UPDATE transactions SET status = "VERIFIED_ADMIN", verified_at = NOW() WHERE id = :id'); $updTrans->execute([':id' => $transactionId]); // Activate subscription $updSub = $pdo->prepare(' UPDATE subscriptions SET status = "ACTIVE", starts_at = CURDATE(), expires_at = DATE_ADD(CURDATE(), INTERVAL 2 YEAR), activated_by = :admin_id WHERE id = :sub_id '); $updSub->execute([ ':admin_id' => $adminId, ':sub_id' => $trans['subscription_id'], ]); // Activate user $updUser = $pdo->prepare('UPDATE users SET status = "ACTIVE" WHERE id = :uid'); $updUser->execute([':uid' => $trans['user_id']]); $pdo->commit(); Response::success([ 'transaction_id' => $transactionId, 'subscription_id' => $trans['subscription_id'], 'status' => 'ACTIVE', ], 'Payment approved and membership activated successfully.'); } catch (\Throwable $e) { $pdo->rollBack(); Response::error('Approval failed: ' . $e->getMessage(), 500); } } /** * GET /api/v1/admin/stats */ public function getStats(Request $request): void { $pdo = Database::getConnection(); $membersCount = (int)$pdo->query('SELECT COUNT(*) FROM subscriptions WHERE status = "ACTIVE"')->fetchColumn(); $pendingCount = (int)$pdo->query('SELECT COUNT(*) FROM subscriptions WHERE status = "PENDING_PAYMENT"')->fetchColumn(); $totalRevenue = (float)$pdo->query('SELECT COALESCE(SUM(amount), 0) FROM transactions WHERE status IN ("VERIFIED_AUTO", "VERIFIED_ADMIN")')->fetchColumn(); $hospitalsCount = (int)$pdo->query('SELECT COUNT(*) FROM partners WHERE type = "HOSPITAL" AND is_active = 1')->fetchColumn(); $hotelsCount = (int)$pdo->query('SELECT COUNT(*) FROM partners WHERE type = "HOTEL" AND is_active = 1')->fetchColumn(); Response::success([ 'active_members' => $membersCount, 'pending_verifications' => $pendingCount, 'total_revenue_iqd' => $totalRevenue, 'total_revenue_usd' => round($totalRevenue / 1320, 2), 'active_hospitals' => $hospitalsCount, 'active_hotels' => $hotelsCount, ], 'System statistics retrieved.'); } }