Update: 2026-07-03 01:48:00
This commit is contained in:
@@ -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
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user