Update: 2026-07-06 01:28:23
This commit is contained in:
@@ -184,12 +184,30 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
|
|||||||
break;
|
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;
|
$mediumDistThresholdKm = 25.0;
|
||||||
$longDistThresholdKm = 35.0;
|
$longDistThresholdKm = 35.0;
|
||||||
$minuteCapMedium = 60;
|
$minuteCapMedium = 60;
|
||||||
$minuteCapLong = 80;
|
$minuteCapLong = 80;
|
||||||
$freeMinutesLong = 10;
|
$freeMinutesLong = 10;
|
||||||
|
|
||||||
|
$extraReduction100 = 0.07;
|
||||||
|
$maxReductionCap = 0.35;
|
||||||
|
|
||||||
$totalMinutes = floor($duration / 60);
|
$totalMinutes = floor($duration / 60);
|
||||||
|
|
||||||
$airportCtx = (stripos($startNameAddress, 'airport') !== false || stripos($startNameAddress, 'مطار') !== false || stripos($endNameAddress, 'airport') !== false || stripos($endNameAddress, 'مطار') !== false);
|
$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);
|
$isInDamascusAirportBoundCtx = ($passengerLat <= $northLat && $passengerLat >= $southLat && $passengerLng <= $eastLng && $passengerLng >= $westLng);
|
||||||
|
|
||||||
$billableDistance = ($distance < $minBillableKm) ? $minBillableKm : $distance;
|
$billableDistance = ($distance < $minBillableKm) ? $minBillableKm : $distance;
|
||||||
|
$isLongSpeed = $billableDistance > $longSpeedThresholdKm;
|
||||||
|
|
||||||
$perKmSpeedBaseFromServer = getPerKmRate($carType, $kazanRow);
|
$perKmSpeedBaseFromServer = getPerKmRate($carType, $kazanRow);
|
||||||
|
$perKmSpeed = $isLongSpeed ? $longSpeedPerKm : $perKmSpeedBaseFromServer;
|
||||||
|
|
||||||
// Apply dynamic percentage discount instead of hardcoded currencies for long trips
|
$reductionPct40 = 0.0;
|
||||||
$perKmSpeed = $perKmSpeedBaseFromServer;
|
if ($perKmSpeedBaseFromServer > 0) {
|
||||||
if ($billableDistance > $longDistThresholdKm) {
|
$r = 1.0 - ($longSpeedPerKm / $perKmSpeedBaseFromServer);
|
||||||
$perKmSpeed = $perKmSpeedBaseFromServer * 0.85; // 15% discount per km
|
$reductionPct40 = max(0.0, min($maxReductionCap, $r));
|
||||||
} else if ($billableDistance > $mediumDistThresholdKm) {
|
}
|
||||||
$perKmSpeed = $perKmSpeedBaseFromServer * 0.90; // 10% discount per km
|
$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');
|
date_default_timezone_set('Asia/Damascus');
|
||||||
@@ -227,10 +253,11 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
|
|||||||
|
|
||||||
$billableMinutes = $totalMinutes;
|
$billableMinutes = $totalMinutes;
|
||||||
if ($billableDistance > $longDistThresholdKm) {
|
if ($billableDistance > $longDistThresholdKm) {
|
||||||
// Prevent absurd time billing for very long trips
|
$effectivePerMin = $longTripPerMin;
|
||||||
$capped = ($billableMinutes > $minuteCapLong) ? $minuteCapLong : $billableMinutes;
|
$capped = ($billableMinutes > $minuteCapLong) ? $minuteCapLong : $billableMinutes;
|
||||||
$billableMinutes = max(0, $capped - $freeMinutesLong);
|
$billableMinutes = max(0, $capped - $freeMinutesLong);
|
||||||
} else if ($billableDistance > $mediumDistThresholdKm) {
|
} else if ($billableDistance > $mediumDistThresholdKm) {
|
||||||
|
$effectivePerMin = $longTripPerMin;
|
||||||
$billableMinutes = ($billableMinutes > $minuteCapMedium) ? $minuteCapMedium : $billableMinutes;
|
$billableMinutes = ($billableMinutes > $minuteCapMedium) ? $minuteCapMedium : $billableMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2198,30 +2198,22 @@ class RideLifecycleController extends GetxController {
|
|||||||
Future<void> calculateDriverToPassengerRoute(
|
Future<void> calculateDriverToPassengerRoute(
|
||||||
LatLng driverPos, LatLng passengerPos,
|
LatLng driverPos, LatLng passengerPos,
|
||||||
{bool isBeginPhase = false}) async {
|
{bool isBeginPhase = false}) async {
|
||||||
final Map<String, String> 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);
|
|
||||||
|
|
||||||
Log.print('📍 Calculating Driver Route: $uri');
|
if (mapController == null) {
|
||||||
|
Log.print('⚠️ mapController is null, cannot calculate route via intaleq_maps');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.print('📍 Calculating Driver Route via IntaleqMapController...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await http.get(uri, headers: {
|
final responseData = await mapController!.getDirections(driverPos, passengerPos);
|
||||||
'x-api-key': Env.mapSaasKey,
|
|
||||||
}).timeout(const Duration(seconds: 20));
|
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
|
||||||
final responseData = json.decode(response.body);
|
|
||||||
|
|
||||||
var routeData = responseData['routes'] != null
|
var routeData = responseData['routes'] != null
|
||||||
? responseData['routes'][0]
|
? responseData['routes'][0]
|
||||||
: responseData;
|
: responseData;
|
||||||
|
|
||||||
double durationSecondsRaw = (routeData['duration'] as num).toDouble();
|
double durationSecondsRaw = (routeData['trafficAwareDuration'] ?? routeData['duration'] as num).toDouble();
|
||||||
int finalDurationSeconds =
|
int finalDurationSeconds =
|
||||||
(durationSecondsRaw * kDurationScalar).toInt();
|
(durationSecondsRaw * kDurationScalar).toInt();
|
||||||
double distanceMeters = (routeData['distance'] as num).toDouble();
|
double distanceMeters = (routeData['distance'] as num).toDouble();
|
||||||
@@ -2299,7 +2291,6 @@ class RideLifecycleController extends GetxController {
|
|||||||
mapEngine.fitCameraToPoints(driverPos, passengerPos);
|
mapEngine.fitCameraToPoints(driverPos, passengerPos);
|
||||||
_updatePassengerWalkLine();
|
_updatePassengerWalkLine();
|
||||||
update();
|
update();
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.print('❌ Error calculating driver route: $e');
|
Log.print('❌ Error calculating driver route: $e');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user