160 lines
6.1 KiB
PHP
160 lines
6.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controllers;
|
|
|
|
use Core\Request;
|
|
use Core\Response;
|
|
use Core\Database;
|
|
use PDO;
|
|
|
|
class AdminController
|
|
{
|
|
/**
|
|
* POST /api/v1/admin/partners/add
|
|
* Directly add a new hospital or hotel contract on the fly.
|
|
*/
|
|
public function addPartner(Request $request): void
|
|
{
|
|
$userId = (int)$request->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.');
|
|
}
|
|
}
|