diff --git a/backend/ride/pricing/get.php b/backend/ride/pricing/get.php index 25aaf97b..15b2edc8 100644 --- a/backend/ride/pricing/get.php +++ b/backend/ride/pricing/get.php @@ -183,13 +183,31 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR $damascusAirportBoundAddon = 1400.0; break; } + + $longSpeedThresholdKm = 40.0; + // Country specific overrides for long distance pricing + // Damascus bounds to roughly estimate if we are in Syria vs Jordan/Egypt + $isSyria = ($passengerLat > 32.0 && $passengerLat < 37.0 && $passengerLng > 35.0 && $passengerLng < 42.0 && $kazanRow['country'] === 'Syria'); + $isJordan = ($kazanRow['country'] === 'Jordan' || $kazanRow['country'] === 'JO'); + + if ($isJordan) { + $longSpeedPerKm = 0.30; // Reasonable long distance speed price for Jordan + $longTripPerMin = 0.06; // Reasonable long distance minute price for Jordan + } else { + $longSpeedPerKm = 26.0; // Syrian Pound + $longTripPerMin = 6.0; // Syrian Pound + } + $mediumDistThresholdKm = 25.0; $longDistThresholdKm = 35.0; $minuteCapMedium = 60; $minuteCapLong = 80; $freeMinutesLong = 10; + $extraReduction100 = 0.07; + $maxReductionCap = 0.35; + $totalMinutes = floor($duration / 60); $airportCtx = (stripos($startNameAddress, 'airport') !== false || stripos($startNameAddress, 'مطار') !== false || stripos($endNameAddress, 'airport') !== false || stripos($endNameAddress, 'مطار') !== false); @@ -203,15 +221,23 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR $isInDamascusAirportBoundCtx = ($passengerLat <= $northLat && $passengerLat >= $southLat && $passengerLng <= $eastLng && $passengerLng >= $westLng); $billableDistance = ($distance < $minBillableKm) ? $minBillableKm : $distance; + $isLongSpeed = $billableDistance > $longSpeedThresholdKm; $perKmSpeedBaseFromServer = getPerKmRate($carType, $kazanRow); - - // Apply dynamic percentage discount instead of hardcoded currencies for long trips - $perKmSpeed = $perKmSpeedBaseFromServer; - if ($billableDistance > $longDistThresholdKm) { - $perKmSpeed = $perKmSpeedBaseFromServer * 0.85; // 15% discount per km - } else if ($billableDistance > $mediumDistThresholdKm) { - $perKmSpeed = $perKmSpeedBaseFromServer * 0.90; // 10% discount per km + $perKmSpeed = $isLongSpeed ? $longSpeedPerKm : $perKmSpeedBaseFromServer; + + $reductionPct40 = 0.0; + if ($perKmSpeedBaseFromServer > 0) { + $r = 1.0 - ($longSpeedPerKm / $perKmSpeedBaseFromServer); + $reductionPct40 = max(0.0, min($maxReductionCap, $r)); + } + $reductionPct100 = max(0.0, min($maxReductionCap, $reductionPct40 + $extraReduction100)); + + $distanceReduction = 0.0; + if ($billableDistance > 100.0) { + $distanceReduction = $reductionPct100; + } else if ($billableDistance > 40.0) { + $distanceReduction = $reductionPct40; } date_default_timezone_set('Asia/Damascus'); @@ -227,10 +253,11 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR $billableMinutes = $totalMinutes; if ($billableDistance > $longDistThresholdKm) { - // Prevent absurd time billing for very long trips + $effectivePerMin = $longTripPerMin; $capped = ($billableMinutes > $minuteCapLong) ? $minuteCapLong : $billableMinutes; $billableMinutes = max(0, $capped - $freeMinutesLong); } else if ($billableDistance > $mediumDistThresholdKm) { + $effectivePerMin = $longTripPerMin; $billableMinutes = ($billableMinutes > $minuteCapMedium) ? $minuteCapMedium : $billableMinutes; } diff --git a/siro_rider/lib/controller/home/map/ride_lifecycle_controller.dart b/siro_rider/lib/controller/home/map/ride_lifecycle_controller.dart index 52e9a612..16245bdd 100644 --- a/siro_rider/lib/controller/home/map/ride_lifecycle_controller.dart +++ b/siro_rider/lib/controller/home/map/ride_lifecycle_controller.dart @@ -2198,32 +2198,24 @@ class RideLifecycleController extends GetxController { Future calculateDriverToPassengerRoute( LatLng driverPos, LatLng passengerPos, {bool isBeginPhase = false}) async { - final Map queryParams = { - 'fromLat': driverPos.latitude.toString(), - 'fromLng': driverPos.longitude.toString(), - 'toLat': passengerPos.latitude.toString(), - 'toLng': passengerPos.longitude.toString(), - }; - final uri = - Uri.parse(AppLink.mapSaasRoute).replace(queryParameters: queryParams); + + if (mapController == null) { + Log.print('⚠️ mapController is null, cannot calculate route via intaleq_maps'); + return; + } - Log.print('📍 Calculating Driver Route: $uri'); + Log.print('📍 Calculating Driver Route via IntaleqMapController...'); try { - final response = await http.get(uri, headers: { - 'x-api-key': Env.mapSaasKey, - }).timeout(const Duration(seconds: 20)); + final responseData = await mapController!.getDirections(driverPos, passengerPos); - if (response.statusCode == 200) { - final responseData = json.decode(response.body); + var routeData = responseData['routes'] != null + ? responseData['routes'][0] + : responseData; - var routeData = responseData['routes'] != null - ? responseData['routes'][0] - : responseData; - - double durationSecondsRaw = (routeData['duration'] as num).toDouble(); - int finalDurationSeconds = - (durationSecondsRaw * kDurationScalar).toInt(); + double durationSecondsRaw = (routeData['trafficAwareDuration'] ?? routeData['duration'] as num).toDouble(); + int finalDurationSeconds = + (durationSecondsRaw * kDurationScalar).toInt(); double distanceMeters = (routeData['distance'] as num).toDouble(); updateDriverRouteMetrics( @@ -2299,7 +2291,6 @@ class RideLifecycleController extends GetxController { mapEngine.fitCameraToPoints(driverPos, passengerPos); _updatePassengerWalkLine(); update(); - } } catch (e) { Log.print('❌ Error calculating driver route: $e'); }