قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
101 lines
3.9 KiB
PHP
101 lines
3.9 KiB
PHP
<?php
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
$lat = filterRequest('passenger_lat') ?: filterRequest('lat');
|
|
$lng = filterRequest('passenger_lng') ?: filterRequest('lng');
|
|
$country = filterRequest('country') ?: filterRequest('country_code');
|
|
$distance = (float)(filterRequest('distance') ?: 0);
|
|
$siroPrice = (float)(filterRequest('siro_price') ?: 0);
|
|
|
|
if (!$lat || !$lng || !$country) {
|
|
echo json_encode(["status" => "error", "message" => "Missing parameters"]);
|
|
exit;
|
|
}
|
|
|
|
$lat = (float)$lat;
|
|
$lng = (float)$lng;
|
|
$countryCode = strtoupper($country);
|
|
if ($countryCode == 'JORDAN') $countryCode = 'JO';
|
|
if ($countryCode == 'SYRIA') $countryCode = 'SY';
|
|
if ($countryCode == 'EGYPT') $countryCode = 'EG';
|
|
|
|
$avgPricePerKm = 0;
|
|
$topComp = 'TaxiF'; // Default
|
|
|
|
try {
|
|
$redis = getRedisConnection();
|
|
$cacheJson = $redis->get('siro:cache:pricing:grids');
|
|
if ($cacheJson) {
|
|
$cacheData = json_decode($cacheJson, true);
|
|
if ($cacheData && isset($cacheData['grids'])) {
|
|
$gridSize = 0.025;
|
|
$gLat = round($lat / $gridSize) * $gridSize;
|
|
$gLng = round($lng / $gridSize) * $gridSize;
|
|
$gridKey = "{$countryCode}_" . number_format($gLat, 3) . "_" . number_format($gLng, 3);
|
|
|
|
$grids = $cacheData['grids'];
|
|
if (isset($grids[$gridKey])) {
|
|
$avgPricePerKm = (float)$grids[$gridKey]['avg_price'];
|
|
$topComp = $grids[$gridKey]['top_competitor'] ?? 'TaxiF';
|
|
} else {
|
|
$fallbackKey = "{$countryCode}_FALLBACK";
|
|
if (isset($grids[$fallbackKey])) {
|
|
$avgPricePerKm = (float)$grids[$fallbackKey]['avg_price'];
|
|
$topComp = $grids[$fallbackKey]['top_competitor'] ?? 'TaxiF';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
// Continue with defaults if Redis fails
|
|
}
|
|
|
|
// If we couldn't get a price from Redis, use a smart default based on country
|
|
if ($avgPricePerKm <= 0) {
|
|
if ($countryCode === 'JO') {
|
|
$avgPricePerKm = 0.35;
|
|
$topComp = 'TaxiF';
|
|
} else if ($countryCode === 'SY') {
|
|
$avgPricePerKm = 4000;
|
|
$topComp = 'Yango';
|
|
} else if ($countryCode === 'EG') {
|
|
$avgPricePerKm = 15;
|
|
$topComp = 'inDrive';
|
|
}
|
|
}
|
|
|
|
// Calculate the competitor's total price based on distance and average market per-km rate
|
|
// 🔥 لا يوجد أي تعديل صناعي على سعر المنافس هنا — الرقم المعروض للراكب
|
|
// يجب أن يعكس بيانات السوق الحقيقية فقط، حتى لو لم نكن أرخص فعلياً في هذه الرحلة.
|
|
$competitorTotalPrice = round($distance * $avgPricePerKm, 2);
|
|
|
|
// Format the labels
|
|
$compNameAr = 'التطبيقات الأخرى';
|
|
|
|
// نعرض شارة "أوفر" فقط إذا كنا أرخص فعلياً حسب البيانات الحقيقية — لا تلاعب بالأرقام
|
|
$savingsPct = 0;
|
|
$savingsLabel = null;
|
|
if ($competitorTotalPrice > 0 && $siroPrice > 0 && $siroPrice < $competitorTotalPrice) {
|
|
$savingsPct = (($competitorTotalPrice - $siroPrice) / $competitorTotalPrice) * 100;
|
|
$savingsLabel = "أوفر بـ " . number_format($savingsPct, 1) . "% من $compNameAr ⚡";
|
|
}
|
|
|
|
$siroCommissionRate = 0.14; // Default 14% commission
|
|
if ($countryCode === 'JO') $siroCommissionRate = 0.14;
|
|
$extraEarnings = $siroPrice * $siroCommissionRate;
|
|
$driverExtraLabel = "رحلة مربحة! تكسب أكثر مقارنة بـ $compNameAr 💰";
|
|
|
|
// Return exactly what Dart expects in the root JSON
|
|
echo json_encode([
|
|
"status" => "success",
|
|
"has_competitor_data" => true,
|
|
"competitor_avg_price" => $competitorTotalPrice,
|
|
"top_competitor" => $topComp,
|
|
"savings_percent" => $savingsPct,
|
|
"savings_label" => $savingsLabel,
|
|
"driver_extra_amount" => round($extraEarnings, 2),
|
|
"driver_extra_label" => $driverExtraLabel
|
|
]);
|
|
?>
|