Update: 2026-07-03 01:48:00

This commit is contained in:
Hamza-Ayed
2026-07-03 01:48:00 +03:00
parent 8f59189832
commit 5ce6c00905
13 changed files with 1119 additions and 12 deletions
+76 -9
View File
@@ -112,7 +112,7 @@ function getPerKmRate($carType, $kazanRow) {
return $rate;
}
function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType = 'Speed') {
function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType = 'Speed', $isPrime = false) {
global $redis, $redisLocation, $con;
$surgeMultiplier = 1.0;
@@ -250,11 +250,17 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
$billableMinutes = ($billableMinutes > $minuteCapMedium) ? $minuteCapMedium : $billableMinutes;
}
$fare = $billableDistance * $perKmSpeed;
$fare += $billableMinutes * $effectivePerMin;
$baseFareForDistance = $billableDistance * $perKmSpeed;
// 1. حساب التسعيرة مع الذروة (للسائق)
$fareWithSurge = $baseFareForDistance + ($billableMinutes * $effectivePerMin);
$fareWithSurge *= $surgeMultiplier;
// 2. حساب التسعيرة الطبيعية بدون ذروة (لراكب Prime)
$fareNoSurge = $baseFareForDistance + ($billableMinutes * $naturePrice);
// Apply Redis Geohash Surge Multiplier
$fare *= $surgeMultiplier;
// نحدد التسعيرة الأساسية حسب حالة الراكب
$fare = $isPrime ? $fareNoSurge : $fareWithSurge;
if ($airportCtx) $fare += $airportAddon;
if ($damascusAirportBoundCtx || $isInDamascusAirportBoundCtx) {
$fare += $damascusAirportBoundAddon;
@@ -363,10 +369,21 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
}
}
// Apply kazan (e.g. 11%)
// Apply kazan (e.g. 11%) on the passenger's price
$withCommission = ceil($price * (1 + $kazanPercent / 100));
$kazan = $withCommission - $price;
$price_for_driver = $price;
// Driver price is based on the surged fare ($fareWithSurge)
$driverPriceTarget = max($fareWithSurge, $minFare);
if ($airportCtx) $driverPriceTarget += $airportAddon;
if ($damascusAirportBoundCtx || $isInDamascusAirportBoundCtx) {
$driverPriceTarget += $damascusAirportBoundAddon;
}
// The driver always gets the non-commissioned part of the SURGE price
$price_for_driver = $driverPriceTarget;
// Our commission is the difference between what passenger pays and what driver gets
$kazan = $withCommission - $price_for_driver;
return [
'price' => $price,
@@ -529,9 +546,58 @@ try {
error_log("[Destination Matching] Error: " . $e->getMessage());
}
// ----------------------------------------------------------------------
// Siro Prime: Check if passenger is a Prime subscriber
// ----------------------------------------------------------------------
$isPrime = false;
if (!empty($passenger_id)) {
$primeKey = "prime:passenger:{$passenger_id}";
$cachedPrime = null;
if (isset($redis) && $redis !== null) {
try {
$cachedPrime = $redis->get($primeKey);
} catch (Exception $e) {}
}
if ($cachedPrime !== false && $cachedPrime !== null) {
$primeData = json_decode($cachedPrime, true);
if (isset($primeData['is_prime']) && $primeData['is_prime'] == 1) {
$expireAt = strtotime($primeData['expire_at'] ?? '0');
if ($expireAt > time()) {
$isPrime = true;
}
}
} else {
// Fallback to MySQL if not in Redis
try {
$stmtPrime = $con->prepare("SELECT is_prime, expire_at FROM passenger_prime_subscriptions WHERE passenger_id = :pid LIMIT 1");
$stmtPrime->execute([':pid' => $passenger_id]);
$primeRow = $stmtPrime->fetch(PDO::FETCH_ASSOC);
if ($primeRow) {
$expireTime = strtotime($primeRow['expire_at'] ?? '0');
if ($primeRow['is_prime'] == 1 && $expireTime > time()) {
$isPrime = true;
}
// Cache in Redis for 1 hour
if (isset($redis) && $redis !== null) {
$redis->setex($primeKey, 3600, json_encode([
'is_prime' => $primeRow['is_prime'],
'expire_at' => $primeRow['expire_at']
]));
}
}
} catch (PDOException $e) {
error_log("[Prime] DB error: " . $e->getMessage());
}
}
}
// Calculate prices for all categories
foreach ($categories as $key => $carType) {
$result = calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType);
$result = calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType, $isPrime);
$withCommission = $result['withCommission'];
$price_for_driver = $result['price_for_driver'];
@@ -579,6 +645,7 @@ if (isset($encryptionHelper)) {
'duration' => $duration,
'is_destination_match' => $isDestinationMatch ? 1 : 0,
'matched_driver_id' => $matchedDriverId,
'is_prime' => $isPrime ? 1 : 0,
'expires' => time() + 420, // Valid for 7 minutes
'prices' => $pricesRaw
];