Update: 2026-06-21 18:58:05

This commit is contained in:
Hamza-Ayed
2026-06-21 18:58:13 +03:00
parent b492b5076b
commit e73be65a72
8755 changed files with 92977 additions and 99 deletions

View File

@@ -109,12 +109,13 @@ function getPerKmRate($carType, $kazanRow) {
}
function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanRow, $startNameAddress, $endNameAddress, $destLat, $destLng, $passengerLat, $passengerLng, $carType = 'Speed') {
global $redis, $redisLocation;
global $redis, $redisLocation, $con;
$surgeMultiplier = 1.0;
if (isset($redis) && $redis !== null) {
try {
$grid_size = 0.0135;
$refLat = 33.5;
$grid_size = 0.0135 * (cos(deg2rad($refLat)) / max(cos(deg2rad((float)$passengerLat)), 0.01));
$grid_lat = round((float)$passengerLat / $grid_size) * $grid_size;
$grid_lng = round((float)$passengerLng / $grid_size) * $grid_size;
$grid_id = $grid_lat . "_" . $grid_lng;
@@ -242,6 +243,105 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
$price = max($fare, $minFare);
// Apply competitor-linked regional pricing overrides (undercut by 8%)
$competitorTarget = null;
if (isset($con) && $con !== null) {
try {
$countryCodeMap = [
'Syria' => 'SY',
'Jordan' => 'JO',
'Egypt' => 'EG',
'Iraq' => 'IQ'
];
$cc = $countryCodeMap[$country] ?? 'SY';
$latDelta = 0.02;
$lngDelta = 0.02;
$minFlat = $passengerLat - $latDelta;
$maxFlat = $passengerLat + $latDelta;
$minFlng = $passengerLng - $lngDelta;
$maxFlng = $passengerLng + $lngDelta;
$minTlat = $destLat - $latDelta;
$maxTlat = $destLat + $latDelta;
$minTlng = $destLng - $lngDelta;
$maxTlng = $destLng + $lngDelta;
// Layer 1: Start and End match within bounding box
$sqlComp = "SELECT total_price, distance_km
FROM competitor_prices
WHERE country_code = :country_code
AND (from_latitude + 0.0) BETWEEN :min_flat AND :max_flat
AND (from_longitude + 0.0) BETWEEN :min_flng AND :max_flng
AND (to_latitude + 0.0) BETWEEN :min_tlat AND :max_tlat
AND (to_longitude + 0.0) BETWEEN :min_tlng AND :max_tlng
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY created_at DESC LIMIT 5";
$stmtComp = $con->prepare($sqlComp);
$stmtComp->execute([
':country_code' => $cc,
':min_flat' => $minFlat,
':max_flat' => $maxFlat,
':min_flng' => $minFlng,
':max_flng' => $maxFlng,
':min_tlat' => $minTlat,
':max_tlat' => $maxTlat,
':min_tlng' => $minTlng,
':max_tlng' => $maxTlng
]);
$matches = $stmtComp->fetchAll(PDO::FETCH_ASSOC);
if (empty($matches)) {
// Layer 2 Fallback: Start match only within bounding box
$sqlFallback = "SELECT total_price, distance_km
FROM competitor_prices
WHERE country_code = :country_code
AND (from_latitude + 0.0) BETWEEN :min_flat AND :max_flat
AND (from_longitude + 0.0) BETWEEN :min_flng AND :max_flng
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY created_at DESC LIMIT 10";
$stmtFallback = $con->prepare($sqlFallback);
$stmtFallback->execute([
':country_code' => $cc,
':min_flat' => $minFlat,
':max_flat' => $maxFlat,
':min_flng' => $minFlng,
':max_flng' => $maxFlng
]);
$matches = $stmtFallback->fetchAll(PDO::FETCH_ASSOC);
}
if (!empty($matches)) {
$normalizedPrices = [];
foreach ($matches as $row) {
$compDist = (float)$row['distance_km'];
$compPrice = (float)$row['total_price'];
if ($compDist > 0) {
$normalizedPrices[] = ($compPrice / $compDist) * $distance;
}
}
if (!empty($normalizedPrices)) {
$competitorTarget = array_sum($normalizedPrices) / count($normalizedPrices);
}
}
} catch (Exception $e) {
error_log("[calculateDynamicPrice] Competitor pricing query failed: " . $e->getMessage());
}
}
if ($competitorTarget !== null) {
$undercutPrice = $competitorTarget * 0.92;
$speedBaseRate = getPerKmRate('Speed', $kazanRow);
$currentBaseRate = getPerKmRate($carType, $kazanRow);
$categoryMultiplier = $speedBaseRate > 0 ? ($currentBaseRate / $speedBaseRate) : 1.0;
$targetAdjustedPrice = $undercutPrice * $categoryMultiplier;
if ($price > $targetAdjustedPrice) {
$price = $targetAdjustedPrice;
}
}
// Apply kazan (e.g. 11%)
$withCommission = ceil($price * (1 + $kazanPercent / 100));
$kazan = $withCommission - $price;
@@ -341,7 +441,7 @@ if (isset($encryptionHelper)) {
// ✅ FIX R6: تضمين distance و duration في الـ token لمنع التلاعب
'distance' => $distance,
'duration' => $duration,
'expires' => time() + 180, // Valid for 3 minutes
'expires' => time() + 420, // Valid for 7 minutes
'prices' => $pricesRaw
];
$priceToken = $encryptionHelper->encryptData(json_encode($tokenPayload));