Initial commit: Uruk Prize Platform architecture, backend core, mobile app, gateway caller & deployment pipeline
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?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.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user