91 lines
3.5 KiB
PHP
91 lines
3.5 KiB
PHP
<?php
|
|
// Admin/fuel/list.php — قائمة محطات الوقود الشريكة
|
|
// POST (اختياري): search, city, only_active
|
|
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
if ($role !== 'admin' && $role !== 'super_admin') {
|
|
jsonError('Unauthorized: Admin access required', 403);
|
|
}
|
|
|
|
$search = filterRequest('search');
|
|
$city = filterRequest('city');
|
|
$onlyActive = filterRequest('only_active') === '1';
|
|
|
|
$where = [];
|
|
$params = [];
|
|
|
|
if (!empty($search)) {
|
|
$where[] = '(s.name_ar LIKE ? OR s.chain_name LIKE ? OR s.address LIKE ?)';
|
|
$like = '%' . $search . '%';
|
|
array_push($params, $like, $like, $like);
|
|
}
|
|
if (!empty($city)) {
|
|
$where[] = 's.city = ?';
|
|
$params[] = $city;
|
|
}
|
|
if ($onlyActive) {
|
|
$where[] = 's.is_active = 1';
|
|
}
|
|
|
|
$clause = $where ? 'WHERE ' . implode(' AND ', $where) : '';
|
|
|
|
try {
|
|
// إحصاء الصرف مع كل محطة: لوحة بلا أرقام لا تخبر أحداً أي محطة
|
|
// تعمل فعلاً وأيها اسمٌ في جدول. `redeemed` وحدها — القسائم الملغاة
|
|
// والمنتهية لا تقول شيئاً عن أداء المحطة.
|
|
$st = $con->prepare("
|
|
SELECT s.*,
|
|
COUNT(v.id) AS redeem_count,
|
|
COALESCE(SUM(v.amount_redeemed), 0) AS redeem_total,
|
|
MAX(v.redeemed_at) AS last_redeem_at
|
|
FROM fuel_stations s
|
|
LEFT JOIN fuel_vouchers v
|
|
ON v.station_id = s.id AND v.status = 'redeemed'
|
|
$clause
|
|
GROUP BY s.id
|
|
ORDER BY s.is_active DESC, s.city ASC, s.name_ar ASC
|
|
LIMIT 200
|
|
");
|
|
$st->execute($params);
|
|
$rows = $st->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
error_log('[admin/fuel/list] ' . $e->getMessage());
|
|
jsonError('Server error', 500);
|
|
}
|
|
|
|
$stations = array_map(static fn(array $r): array => [
|
|
'id' => (int) $r['id'],
|
|
'name_ar' => $r['name_ar'],
|
|
'chain_name' => $r['chain_name'],
|
|
'city' => $r['city'],
|
|
'address' => $r['address'],
|
|
'lat' => $r['lat'] !== null ? (float) $r['lat'] : null,
|
|
'lng' => $r['lng'] !== null ? (float) $r['lng'] : null,
|
|
'phone' => $r['phone'],
|
|
'discount_percent' => (float) $r['discount_percent'],
|
|
'is_active' => (int) $r['is_active'] === 1,
|
|
'created_at' => $r['created_at'],
|
|
'redeem_count' => (int) $r['redeem_count'],
|
|
'redeem_total' => (float) $r['redeem_total'],
|
|
'last_redeem_at' => $r['last_redeem_at'],
|
|
// المفتاح لا يخرج أبداً — لا هنا ولا في أي نقطة أخرى. مخزَّن مُهشَّراً
|
|
// أصلاً، ويُعرض مرة واحدة فقط لحظة إنشائه أو تدويره.
|
|
], $rows);
|
|
|
|
// حالة المنتج تُرسل مع القائمة لا في نقطة منفصلة: الشاشة تحتاج أن تعرض
|
|
// «مُجهَّز وغير مُشغَّل» بوضوح، وطلبان لبناء لافتة واحدة إسراف.
|
|
$productActive = false;
|
|
try {
|
|
$st = $con->prepare("SELECT is_active FROM obligation_products WHERE code = 'fuel_wallet' LIMIT 1");
|
|
$st->execute();
|
|
$productActive = (int) $st->fetchColumn() === 1;
|
|
} catch (PDOException $e) {
|
|
error_log('[admin/fuel/list] تعذّرت قراءة حالة المنتج: ' . $e->getMessage());
|
|
}
|
|
|
|
jsonSuccess([
|
|
'stations' => $stations,
|
|
'product_active' => $productActive,
|
|
], 'success');
|