|
|
|
|
@@ -125,25 +125,23 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
late String driverCompletedRides = '0';
|
|
|
|
|
late String driverTier = 'Verified driver';
|
|
|
|
|
late String driverToken = '';
|
|
|
|
|
|
|
|
|
|
double kazan = 8;
|
|
|
|
|
double totalPassenger = 0;
|
|
|
|
|
String totalPassenger = '0';
|
|
|
|
|
double totalDriver = 0;
|
|
|
|
|
double costDistance = 0;
|
|
|
|
|
double costDuration = 0;
|
|
|
|
|
double averageDuration = 0;
|
|
|
|
|
double totalCostPassenger = 0;
|
|
|
|
|
String totalCostPassenger = '0';
|
|
|
|
|
|
|
|
|
|
double totalPassengerSpeed = 0;
|
|
|
|
|
double totalPassengerBalash = 0;
|
|
|
|
|
double totalPassengerComfort = 0;
|
|
|
|
|
double totalPassengerElectric = 0;
|
|
|
|
|
double totalPassengerLady = 0;
|
|
|
|
|
double totalPassengerScooter = 0;
|
|
|
|
|
double totalPassengerVan = 0;
|
|
|
|
|
double totalPassengerRayehGai = 0;
|
|
|
|
|
double totalPassengerRayehGaiComfort = 0;
|
|
|
|
|
double totalPassengerRayehGaiBalash = 0;
|
|
|
|
|
String totalPassengerSpeed = '0';
|
|
|
|
|
String totalPassengerBalash = '0';
|
|
|
|
|
String totalPassengerComfort = '0';
|
|
|
|
|
String totalPassengerElectric = '0';
|
|
|
|
|
String totalPassengerLady = '0';
|
|
|
|
|
String totalPassengerScooter = '0';
|
|
|
|
|
String totalPassengerVan = '0';
|
|
|
|
|
String totalPassengerRayehGai = '0';
|
|
|
|
|
String totalPassengerRayehGaiComfort = '0';
|
|
|
|
|
String totalPassengerRayehGaiBalash = '0';
|
|
|
|
|
|
|
|
|
|
double latePrice = 0;
|
|
|
|
|
double fuelPrice = 0;
|
|
|
|
|
@@ -744,7 +742,7 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
style: TextStyle(color: AppColor.greenColor)),
|
|
|
|
|
onPressed: () {
|
|
|
|
|
Get.back();
|
|
|
|
|
double newPrice = totalPassenger * 1.10;
|
|
|
|
|
double newPrice = double.parse(totalPassenger) * 1.10;
|
|
|
|
|
increasePriceAndRestartSearch(newPrice);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
@@ -755,7 +753,7 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> increasePriceAndRestartSearch(double newPrice) async {
|
|
|
|
|
totalPassenger = newPrice;
|
|
|
|
|
totalPassenger = newPrice.toStringAsFixed(2);
|
|
|
|
|
update();
|
|
|
|
|
|
|
|
|
|
await CRUD()
|
|
|
|
|
@@ -822,6 +820,7 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
_isRideStartedProcessed = true;
|
|
|
|
|
currentRideState.value = RideState.inProgress;
|
|
|
|
|
statusRide = 'Begin';
|
|
|
|
|
box.write(BoxName.passengerWalletTotal, '0');
|
|
|
|
|
|
|
|
|
|
remainingTimeDriverWaitPassenger5Minute = 0;
|
|
|
|
|
_stopWaitPassengerTimer();
|
|
|
|
|
@@ -1413,7 +1412,7 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
"date": DateTime.now().toString(),
|
|
|
|
|
"time": DateTime.now().toString(),
|
|
|
|
|
"endtime": "00:00:00",
|
|
|
|
|
"price": totalPassenger.toStringAsFixed(2),
|
|
|
|
|
"price": double.parse(totalPassenger.toString()).toStringAsFixed(2),
|
|
|
|
|
"passenger_id": box.read(BoxName.passengerID).toString(),
|
|
|
|
|
"driver_id": "0",
|
|
|
|
|
"status": "waiting",
|
|
|
|
|
@@ -1694,7 +1693,6 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
box.write(BoxName.serverChosen, AppLink.server);
|
|
|
|
|
|
|
|
|
|
if (newCountry != previousCountry) {
|
|
|
|
|
unawaited(getKazanPercent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newCountry;
|
|
|
|
|
@@ -1775,135 +1773,56 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
|
|
|
|
|
void applyPromoCodeToPassenger(BuildContext context) async {
|
|
|
|
|
if (promoTaken == true) {
|
|
|
|
|
MyDialog().getDialog(
|
|
|
|
|
'Promo Already Used'.tr,
|
|
|
|
|
'You have already used this promo code.'.tr,
|
|
|
|
|
() => Get.back(),
|
|
|
|
|
);
|
|
|
|
|
MyDialog().getDialog('Promo Already Used'.tr, 'You have already used this promo code.'.tr, () => Get.back());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!promoFormKey.currentState!.validate()) return;
|
|
|
|
|
|
|
|
|
|
const double minPromoLowSYP = 172;
|
|
|
|
|
const double minPromoHighSYP = 200;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
final value = await CRUD().get(
|
|
|
|
|
link: AppLink.getPassengersPromo,
|
|
|
|
|
payload: {'promo_code': promo.text},
|
|
|
|
|
);
|
|
|
|
|
final res = await CRUD().post(link: AppLink.getPrices, payload: {
|
|
|
|
|
'distance': distance.toString(),
|
|
|
|
|
'durationToRide': durationToRide.toString(),
|
|
|
|
|
'startNameAddress': startNameAddress,
|
|
|
|
|
'endNameAddress': endNameAddress,
|
|
|
|
|
'destLat': myDestination.latitude.toString(),
|
|
|
|
|
'destLng': myDestination.longitude.toString(),
|
|
|
|
|
'passengerLat': newMyLocation.latitude.toString(),
|
|
|
|
|
'passengerLng': newMyLocation.longitude.toString(),
|
|
|
|
|
'walletVal': box.read(BoxName.passengerWalletTotal)?.toString() ?? '0',
|
|
|
|
|
'activeMenuWaypointCount': activeMenuWaypointCount.toString(),
|
|
|
|
|
'promo_code': promo.text,
|
|
|
|
|
'passenger_id' :box.read(BoxName.passengerID),
|
|
|
|
|
'country': box.read(BoxName.countryCode) ?? '',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (value == 'failure') {
|
|
|
|
|
MyDialog().getDialog(
|
|
|
|
|
'Promo Ended'.tr,
|
|
|
|
|
'The promotion period has ended.'.tr,
|
|
|
|
|
() => Get.back(),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final bool eligibleNow = (totalPassengerSpeed >= minPromoLowSYP) ||
|
|
|
|
|
(totalPassengerBalash >= minPromoLowSYP) ||
|
|
|
|
|
(totalPassengerComfort >= minPromoHighSYP) ||
|
|
|
|
|
(totalPassengerElectric >= minPromoHighSYP) ||
|
|
|
|
|
(totalPassengerLady >= minPromoHighSYP);
|
|
|
|
|
|
|
|
|
|
if (!eligibleNow) {
|
|
|
|
|
Get.snackbar(
|
|
|
|
|
'Lowest Price Achieved'.tr,
|
|
|
|
|
'Cannot apply further discounts.'.tr,
|
|
|
|
|
backgroundColor: AppColor.yellowColor,
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final decode = jsonDecode(value);
|
|
|
|
|
if (decode["status"] != "success") {
|
|
|
|
|
MyDialog().getDialog(
|
|
|
|
|
'Promo Ended'.tr,
|
|
|
|
|
'The promotion period has ended.'.tr,
|
|
|
|
|
() => Get.back(),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Get.snackbar('Promo Code Accepted'.tr, '',
|
|
|
|
|
backgroundColor: AppColor.greenColor);
|
|
|
|
|
|
|
|
|
|
final firstElement = decode["message"][0];
|
|
|
|
|
final int discountPercentage =
|
|
|
|
|
int.tryParse(firstElement['amount'].toString()) ?? 0;
|
|
|
|
|
|
|
|
|
|
final double walletVal = double.tryParse(
|
|
|
|
|
box.read(BoxName.passengerWalletTotal)?.toString() ?? '0') ??
|
|
|
|
|
0.0;
|
|
|
|
|
|
|
|
|
|
final bool isWalletNegative = walletVal < 0;
|
|
|
|
|
|
|
|
|
|
double _applyDiscountPerTier({
|
|
|
|
|
required double fare,
|
|
|
|
|
required double minThreshold,
|
|
|
|
|
required bool isWalletNegative,
|
|
|
|
|
}) {
|
|
|
|
|
if (fare < minThreshold) return fare;
|
|
|
|
|
|
|
|
|
|
final double discount = fare * (discountPercentage / 100.0);
|
|
|
|
|
double result;
|
|
|
|
|
|
|
|
|
|
if (isWalletNegative) {
|
|
|
|
|
double neg = (-1) * walletVal;
|
|
|
|
|
result = fare + neg - discount;
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var response = jsonDecode(res);
|
|
|
|
|
if (response['status'] == 'success') {
|
|
|
|
|
var data = response['data'];
|
|
|
|
|
totalPassengerSpeed = data['totalPassengerSpeed']?.toString() ?? '0';
|
|
|
|
|
totalPassengerBalash = data['totalPassengerBalash']?.toString() ?? '0';
|
|
|
|
|
totalPassengerComfort = data['totalPassengerComfort']?.toString() ?? '0';
|
|
|
|
|
totalPassengerElectric = data['totalPassengerElectric']?.toString() ?? '0';
|
|
|
|
|
totalPassengerLady = data['totalPassengerLady']?.toString() ?? '0';
|
|
|
|
|
totalPassengerScooter = data['totalPassengerScooter']?.toString() ?? '0';
|
|
|
|
|
totalPassengerVan = data['totalPassengerVan']?.toString() ?? '0';
|
|
|
|
|
totalPassengerRayehGai = data['totalPassengerRayehGai']?.toString() ?? '0';
|
|
|
|
|
totalPassengerRayehGaiComfort = data['totalPassengerRayehGaiComfort']?.toString() ?? '0';
|
|
|
|
|
totalPassengerRayehGaiBalash = data['totalPassengerRayehGaiBalash']?.toString() ?? '0';
|
|
|
|
|
|
|
|
|
|
promoTaken = true;
|
|
|
|
|
update();
|
|
|
|
|
|
|
|
|
|
Confetti.launch(
|
|
|
|
|
context,
|
|
|
|
|
options: const ConfettiOptions(particleCount: 100, spread: 70, y: 0.6),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
result = fare - discount;
|
|
|
|
|
MyDialog().getDialog('Promo Error'.tr, response['message']?.toString() ?? 'Invalid Promo'.tr, () => Get.back());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result < minThreshold) {
|
|
|
|
|
result = minThreshold;
|
|
|
|
|
}
|
|
|
|
|
return result.clamp(0.0, double.infinity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
totalPassengerComfort = _applyDiscountPerTier(
|
|
|
|
|
fare: totalPassengerComfort,
|
|
|
|
|
minThreshold: minPromoHighSYP,
|
|
|
|
|
isWalletNegative: isWalletNegative,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
totalPassengerElectric = _applyDiscountPerTier(
|
|
|
|
|
fare: totalPassengerElectric,
|
|
|
|
|
minThreshold: minPromoHighSYP,
|
|
|
|
|
isWalletNegative: isWalletNegative,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
totalPassengerLady = _applyDiscountPerTier(
|
|
|
|
|
fare: totalPassengerLady,
|
|
|
|
|
minThreshold: minPromoHighSYP,
|
|
|
|
|
isWalletNegative: isWalletNegative,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
totalPassengerSpeed = _applyDiscountPerTier(
|
|
|
|
|
fare: totalPassengerSpeed,
|
|
|
|
|
minThreshold: minPromoLowSYP,
|
|
|
|
|
isWalletNegative: isWalletNegative,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
totalPassengerBalash = _applyDiscountPerTier(
|
|
|
|
|
fare: totalPassengerBalash,
|
|
|
|
|
minThreshold: minPromoLowSYP,
|
|
|
|
|
isWalletNegative: isWalletNegative,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
totalDriver = totalDriver - (totalDriver * discountPercentage / 100.0);
|
|
|
|
|
promoTaken = true;
|
|
|
|
|
update();
|
|
|
|
|
|
|
|
|
|
Confetti.launch(
|
|
|
|
|
context,
|
|
|
|
|
options: const ConfettiOptions(particleCount: 100, spread: 70, y: 0.6),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Get.back();
|
|
|
|
|
Get.back();
|
|
|
|
|
await Future.delayed(const Duration(milliseconds: 120));
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Get.snackbar('Error'.tr, e.toString(),
|
|
|
|
|
@@ -1920,236 +1839,49 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
double costForDriver = 0;
|
|
|
|
|
|
|
|
|
|
Future bottomSheet() async {
|
|
|
|
|
const double minFareSYP = 160;
|
|
|
|
|
const double minBillableKm = 0.3;
|
|
|
|
|
const double ladyFlatAddon = 20;
|
|
|
|
|
const double airportAddonSYP = 200;
|
|
|
|
|
const double damascusAirportBoundAddon = 1400;
|
|
|
|
|
|
|
|
|
|
const double electricPerKmUplift = 4;
|
|
|
|
|
const double electricFlatAddon = 10;
|
|
|
|
|
|
|
|
|
|
const double longSpeedThresholdKm = 40.0;
|
|
|
|
|
const double longSpeedPerKm = 26.0;
|
|
|
|
|
|
|
|
|
|
const double mediumDistThresholdKm = 25.0;
|
|
|
|
|
const double longDistThresholdKm = 35.0;
|
|
|
|
|
const double longTripPerMin = 6.0;
|
|
|
|
|
const int minuteCapMedium = 60;
|
|
|
|
|
const int minuteCapLong = 80;
|
|
|
|
|
const int freeMinutesLong = 10;
|
|
|
|
|
|
|
|
|
|
const double extraReduction100 = 0.07;
|
|
|
|
|
const double maxReductionCap = 0.35;
|
|
|
|
|
|
|
|
|
|
durationToAdd = Duration(seconds: durationToRide);
|
|
|
|
|
hours = durationToAdd.inHours;
|
|
|
|
|
minutes = (durationToAdd.inMinutes % 60).round();
|
|
|
|
|
final DateTime currentTime = DateTime.now();
|
|
|
|
|
newTime = currentTime.add(durationToAdd);
|
|
|
|
|
averageDuration = (durationToRide / 60) / distance;
|
|
|
|
|
final int waypointSurchargeMinutes = activeMenuWaypointCount * 5;
|
|
|
|
|
final int totalMinutes =
|
|
|
|
|
(durationToRide / 60).floor() + waypointSurchargeMinutes;
|
|
|
|
|
|
|
|
|
|
bool _isAirport(String s) {
|
|
|
|
|
final t = s.toLowerCase();
|
|
|
|
|
return t.contains('airport') ||
|
|
|
|
|
s.contains('مطار') ||
|
|
|
|
|
s.contains('المطار');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool _isClub(String s) {
|
|
|
|
|
final t = s.toLowerCase();
|
|
|
|
|
return t.contains('club') ||
|
|
|
|
|
t.contains('nightclub') ||
|
|
|
|
|
t.contains('night club') ||
|
|
|
|
|
s.contains('ديسكو') ||
|
|
|
|
|
s.contains('ملهى ليلي');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool _isInsideDamascusAirportBounds(double lat, double lng) {
|
|
|
|
|
final double northLat = 33.415313;
|
|
|
|
|
final double southLat = 33.400265;
|
|
|
|
|
final double eastLng = 36.531505;
|
|
|
|
|
final double westLng = 36.499687;
|
|
|
|
|
|
|
|
|
|
bool isLatInside = (lat <= northLat) && (lat >= southLat);
|
|
|
|
|
bool isLngInside = (lng <= eastLng) && (lng >= westLng);
|
|
|
|
|
return isLatInside && isLngInside;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final double naturePerMin = naturePrice;
|
|
|
|
|
final double latePerMin = latePrice;
|
|
|
|
|
final double heavyPerMin = heavyPrice;
|
|
|
|
|
|
|
|
|
|
double _perMinuteByTime(DateTime now, bool clubCtx) {
|
|
|
|
|
final h = now.hour;
|
|
|
|
|
if (h >= 21 || h < 1) return latePerMin;
|
|
|
|
|
if (h >= 1 && h < 5) return clubCtx ? (latePerMin * 2) : latePerMin;
|
|
|
|
|
if (h >= 14 && h <= 17) return heavyPerMin;
|
|
|
|
|
return naturePerMin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double _applyMinFare(double fare) =>
|
|
|
|
|
(fare < minFareSYP) ? minFareSYP : fare;
|
|
|
|
|
|
|
|
|
|
double _withCommission(double base) =>
|
|
|
|
|
(base * (1 + kazan / 100)).ceilToDouble();
|
|
|
|
|
|
|
|
|
|
final bool airportCtx =
|
|
|
|
|
_isAirport(startNameAddress) || _isAirport(endNameAddress);
|
|
|
|
|
final bool clubCtx = _isClub(startNameAddress) || _isClub(endNameAddress);
|
|
|
|
|
|
|
|
|
|
double destLat = 0.0;
|
|
|
|
|
double destLng = 0.0;
|
|
|
|
|
try {
|
|
|
|
|
destLat = myDestination.latitude;
|
|
|
|
|
destLng = myDestination.longitude;
|
|
|
|
|
} catch (_) {
|
|
|
|
|
if (locSearch.coordinatesWithoutEmpty.isNotEmpty) {
|
|
|
|
|
destLat = double.tryParse(
|
|
|
|
|
locSearch.coordinatesWithoutEmpty.last.split(',')[0]) ??
|
|
|
|
|
0.0;
|
|
|
|
|
destLng = double.tryParse(
|
|
|
|
|
locSearch.coordinatesWithoutEmpty.last.split(',')[1]) ??
|
|
|
|
|
0.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final bool damascusAirportBoundCtx =
|
|
|
|
|
_isInsideDamascusAirportBounds(destLat, destLng);
|
|
|
|
|
final bool isInDamascusAirportBoundCtx = _isInsideDamascusAirportBounds(
|
|
|
|
|
newMyLocation.latitude.toDouble(),
|
|
|
|
|
newMyLocation.longitude.toDouble(),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final double billableDistance =
|
|
|
|
|
(distance < minBillableKm) ? minBillableKm : distance;
|
|
|
|
|
|
|
|
|
|
final bool isLongSpeed = billableDistance > longSpeedThresholdKm;
|
|
|
|
|
final double perKmSpeedBaseFromServer = speedPrice;
|
|
|
|
|
final double perKmSpeed =
|
|
|
|
|
isLongSpeed ? longSpeedPerKm : perKmSpeedBaseFromServer;
|
|
|
|
|
|
|
|
|
|
double reductionPct40 = 0.0;
|
|
|
|
|
if (perKmSpeedBaseFromServer > 0) {
|
|
|
|
|
reductionPct40 = (1.0 - (longSpeedPerKm / perKmSpeedBaseFromServer))
|
|
|
|
|
.clamp(0.0, maxReductionCap);
|
|
|
|
|
}
|
|
|
|
|
final double reductionPct100 =
|
|
|
|
|
(reductionPct40 + extraReduction100).clamp(0.0, maxReductionCap);
|
|
|
|
|
double distanceReduction = 0.0;
|
|
|
|
|
if (billableDistance > 100.0) {
|
|
|
|
|
distanceReduction = reductionPct100;
|
|
|
|
|
} else if (billableDistance > 40.0) {
|
|
|
|
|
distanceReduction = reductionPct40;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double effectivePerMin = _perMinuteByTime(currentTime, clubCtx);
|
|
|
|
|
int billableMinutes = totalMinutes;
|
|
|
|
|
if (billableDistance > longDistThresholdKm) {
|
|
|
|
|
effectivePerMin = longTripPerMin;
|
|
|
|
|
final int capped =
|
|
|
|
|
(billableMinutes > minuteCapLong) ? minuteCapLong : billableMinutes;
|
|
|
|
|
billableMinutes = capped - freeMinutesLong;
|
|
|
|
|
if (billableMinutes < 0) billableMinutes = 0;
|
|
|
|
|
} else if (billableDistance > mediumDistThresholdKm) {
|
|
|
|
|
effectivePerMin = longTripPerMin;
|
|
|
|
|
billableMinutes = (billableMinutes > minuteCapMedium)
|
|
|
|
|
? minuteCapMedium
|
|
|
|
|
: billableMinutes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final double perKmComfortRaw = comfortPrice;
|
|
|
|
|
final double perKmDelivery = deliveryPrice;
|
|
|
|
|
final double perKmVanRaw =
|
|
|
|
|
(familyPrice > 0 ? familyPrice : (speedPrice + 13));
|
|
|
|
|
final double perKmElectricRaw = perKmComfortRaw + electricPerKmUplift;
|
|
|
|
|
|
|
|
|
|
double perKmComfort = perKmComfortRaw * (1.0 - distanceReduction);
|
|
|
|
|
double perKmElectric = perKmElectricRaw * (1.0 - distanceReduction);
|
|
|
|
|
double perKmVan = perKmVanRaw * (1.0 - distanceReduction);
|
|
|
|
|
perKmComfort = perKmComfort.clamp(0, double.infinity);
|
|
|
|
|
perKmElectric = perKmElectric.clamp(0, double.infinity);
|
|
|
|
|
perKmVan = perKmVan.clamp(0, double.infinity);
|
|
|
|
|
final double perKmBalash = (perKmSpeed - 5).clamp(0, double.infinity);
|
|
|
|
|
|
|
|
|
|
double _oneWayFare({
|
|
|
|
|
required double perKm,
|
|
|
|
|
required bool isLady,
|
|
|
|
|
double flatAddon = 0,
|
|
|
|
|
}) {
|
|
|
|
|
double fare = billableDistance * perKm;
|
|
|
|
|
fare += billableMinutes * effectivePerMin;
|
|
|
|
|
fare += flatAddon;
|
|
|
|
|
if (isLady) fare += ladyFlatAddon;
|
|
|
|
|
if (airportCtx) fare += airportAddonSYP;
|
|
|
|
|
|
|
|
|
|
if (damascusAirportBoundCtx || isInDamascusAirportBoundCtx) {
|
|
|
|
|
fare += damascusAirportBoundAddon;
|
|
|
|
|
}
|
|
|
|
|
return _applyMinFare(fare);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double _roundTripFare({required double perKm}) {
|
|
|
|
|
double distPart =
|
|
|
|
|
(billableDistance * 2 * perKm) - ((billableDistance * perKm) * 0.4);
|
|
|
|
|
double timePart = (billableMinutes * 2) * effectivePerMin;
|
|
|
|
|
double fare = distPart + timePart;
|
|
|
|
|
if (airportCtx) fare += airportAddonSYP;
|
|
|
|
|
|
|
|
|
|
if (damascusAirportBoundCtx || isInDamascusAirportBoundCtx) {
|
|
|
|
|
fare += damascusAirportBoundAddon;
|
|
|
|
|
}
|
|
|
|
|
return _applyMinFare(fare);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final double costSpeed = _oneWayFare(perKm: perKmSpeed, isLady: false);
|
|
|
|
|
final double costBalash = _oneWayFare(perKm: perKmBalash, isLady: false);
|
|
|
|
|
final double costComfort = _oneWayFare(perKm: perKmComfort, isLady: false);
|
|
|
|
|
final double costElectric = _oneWayFare(
|
|
|
|
|
perKm: perKmElectric, isLady: false, flatAddon: electricFlatAddon);
|
|
|
|
|
final double costDelivery =
|
|
|
|
|
_oneWayFare(perKm: perKmDelivery, isLady: false);
|
|
|
|
|
final double costLady = _oneWayFare(perKm: perKmComfort, isLady: true);
|
|
|
|
|
final double costVan = _oneWayFare(perKm: perKmVan, isLady: false);
|
|
|
|
|
final double costRayehGai = _roundTripFare(perKm: perKmSpeed);
|
|
|
|
|
final double costRayehGaiComfort = _roundTripFare(perKm: perKmComfort);
|
|
|
|
|
final double costRayehGaiBalash = _roundTripFare(perKm: perKmBalash);
|
|
|
|
|
|
|
|
|
|
totalPassengerSpeed = _withCommission(costSpeed);
|
|
|
|
|
totalPassengerBalash = _withCommission(costBalash);
|
|
|
|
|
totalPassengerComfort = _withCommission(costComfort);
|
|
|
|
|
totalPassengerElectric = _withCommission(costElectric);
|
|
|
|
|
totalPassengerLady = _withCommission(costLady);
|
|
|
|
|
totalPassengerScooter = _withCommission(costDelivery);
|
|
|
|
|
totalPassengerVan = _withCommission(costVan);
|
|
|
|
|
totalPassengerRayehGai = _withCommission(costRayehGai);
|
|
|
|
|
totalPassengerRayehGaiComfort = _withCommission(costRayehGaiComfort);
|
|
|
|
|
totalPassengerRayehGaiBalash = _withCommission(costRayehGaiBalash);
|
|
|
|
|
|
|
|
|
|
totalPassenger = totalPassengerSpeed;
|
|
|
|
|
totalCostPassenger = totalPassenger;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
final walletStr = box.read(BoxName.passengerWalletTotal).toString();
|
|
|
|
|
final walletVal = double.tryParse(walletStr) ?? 0.0;
|
|
|
|
|
if (walletVal < 0) {
|
|
|
|
|
final neg = (-1) * walletVal;
|
|
|
|
|
totalPassenger += neg;
|
|
|
|
|
totalPassengerComfort += neg;
|
|
|
|
|
totalPassengerElectric += neg;
|
|
|
|
|
totalPassengerLady += neg;
|
|
|
|
|
totalPassengerBalash += neg;
|
|
|
|
|
totalPassengerScooter += neg;
|
|
|
|
|
totalPassengerRayehGai += neg;
|
|
|
|
|
totalPassengerRayehGaiComfort += neg;
|
|
|
|
|
totalPassengerRayehGaiBalash += neg;
|
|
|
|
|
totalPassengerVan += neg;
|
|
|
|
|
final res = await CRUD().post(link: AppLink.getPrices, payload: {
|
|
|
|
|
'distance': distance.toString(),
|
|
|
|
|
'durationToRide': durationToRide.toString(),
|
|
|
|
|
'startNameAddress': startNameAddress,
|
|
|
|
|
'endNameAddress': endNameAddress,
|
|
|
|
|
'destLat': myDestination.latitude.toString(),
|
|
|
|
|
'destLng': myDestination.longitude.toString(),
|
|
|
|
|
'passengerLat': newMyLocation.latitude.toString(),
|
|
|
|
|
'passengerLng': newMyLocation.longitude.toString(),
|
|
|
|
|
'walletVal': box.read(BoxName.passengerWalletTotal)?.toString() ?? '0',
|
|
|
|
|
'activeMenuWaypointCount': activeMenuWaypointCount.toString(),
|
|
|
|
|
'passenger_id': box.read(BoxName.passengerID) ?? '',
|
|
|
|
|
'country': box.read(BoxName.countryCode) ?? '',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var response = jsonDecode(res);
|
|
|
|
|
if (response['status'] == 'success') {
|
|
|
|
|
var data = response['data'];
|
|
|
|
|
totalPassengerSpeed = data['totalPassengerSpeed']?.toString() ?? '0';
|
|
|
|
|
totalPassengerBalash = data['totalPassengerBalash']?.toString() ?? '0';
|
|
|
|
|
totalPassengerComfort = data['totalPassengerComfort']?.toString() ?? '0';
|
|
|
|
|
totalPassengerElectric = data['totalPassengerElectric']?.toString() ?? '0';
|
|
|
|
|
totalPassengerLady = data['totalPassengerLady']?.toString() ?? '0';
|
|
|
|
|
totalPassengerScooter = data['totalPassengerScooter']?.toString() ?? '0';
|
|
|
|
|
totalPassengerVan = data['totalPassengerVan']?.toString() ?? '0';
|
|
|
|
|
totalPassengerRayehGai = data['totalPassengerRayehGai']?.toString() ?? '0';
|
|
|
|
|
totalPassengerRayehGaiComfort = data['totalPassengerRayehGaiComfort']?.toString() ?? '0';
|
|
|
|
|
totalPassengerRayehGaiBalash = data['totalPassengerRayehGaiBalash']?.toString() ?? '0';
|
|
|
|
|
|
|
|
|
|
totalPassenger = totalPassengerSpeed;
|
|
|
|
|
totalCostPassenger = totalPassenger;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print("Error: $e");
|
|
|
|
|
Log.print("Error fetching prices: $e");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update();
|
|
|
|
|
@@ -2694,7 +2426,7 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
"end_location": '${endLoc.latitude},${endLoc.longitude}',
|
|
|
|
|
"date": DateTime.now().toString(),
|
|
|
|
|
"time": DateTime.now().toString(),
|
|
|
|
|
"price": totalPassenger.toStringAsFixed(2),
|
|
|
|
|
"price": double.parse(totalPassenger.toString()).toStringAsFixed(2),
|
|
|
|
|
'passenger_id': box.read(BoxName.passengerID).toString(),
|
|
|
|
|
'status': 'waiting',
|
|
|
|
|
'carType': box.read(BoxName.carType),
|
|
|
|
|
@@ -2720,144 +2452,9 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
double familyPrice = 55;
|
|
|
|
|
double deliveryPrice = 1.2;
|
|
|
|
|
|
|
|
|
|
Future<void> getKazanPercent() async {
|
|
|
|
|
var res = await CRUD().get(
|
|
|
|
|
link: AppLink.getKazanPercent,
|
|
|
|
|
payload: {'country': box.read(BoxName.countryCode).toString()},
|
|
|
|
|
);
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var json = jsonDecode(res);
|
|
|
|
|
var dataList = json['data'] ?? json['message'];
|
|
|
|
|
|
|
|
|
|
if (dataList != null && dataList is List && dataList.isNotEmpty) {
|
|
|
|
|
var firstRow = dataList[0];
|
|
|
|
|
kazan = double.parse(firstRow['kazan'].toString());
|
|
|
|
|
naturePrice = double.parse(firstRow['naturePrice'].toString());
|
|
|
|
|
heavyPrice = double.parse(firstRow['heavyPrice'].toString());
|
|
|
|
|
latePrice = double.parse(firstRow['latePrice'].toString());
|
|
|
|
|
comfortPrice = double.parse(firstRow['comfortPrice'].toString());
|
|
|
|
|
speedPrice = double.parse(firstRow['speedPrice'].toString());
|
|
|
|
|
deliveryPrice = double.parse(firstRow['deliveryPrice'].toString());
|
|
|
|
|
mashwariPrice = double.parse(firstRow['freePrice'].toString());
|
|
|
|
|
familyPrice = double.parse(firstRow['familyPrice'].toString());
|
|
|
|
|
fuelPrice = double.parse(firstRow['fuelPrice'].toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> getPassengerRate() async {
|
|
|
|
|
var res = await CRUD().get(
|
|
|
|
|
link: AppLink.getPassengerRate,
|
|
|
|
|
payload: {'passenger_id': box.read(BoxName.passengerID)});
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var json = jsonDecode(res);
|
|
|
|
|
var message = json['data'] ?? json['message'];
|
|
|
|
|
if (message['rating'] == null) {
|
|
|
|
|
passengerRate = 5.0;
|
|
|
|
|
} else {
|
|
|
|
|
var rating = message['rating'];
|
|
|
|
|
if (rating is String) {
|
|
|
|
|
passengerRate = double.tryParse(rating) ?? 5.0;
|
|
|
|
|
} else if (rating is num) {
|
|
|
|
|
passengerRate = rating.toDouble();
|
|
|
|
|
} else {
|
|
|
|
|
passengerRate = 5.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
passengerRate = 5.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> addFingerPrint() async {
|
|
|
|
|
String fingerPrint = await DeviceHelper.getDeviceFingerprint();
|
|
|
|
|
await CRUD().postWallet(link: AppLink.addFingerPrint, payload: {
|
|
|
|
|
'token': (box.read(BoxName.tokenFCM.toString())),
|
|
|
|
|
'passengerID': box.read(BoxName.passengerID).toString(),
|
|
|
|
|
"fingerPrint": fingerPrint
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> firstTimeRunToGetCoupon() async {
|
|
|
|
|
if (box.read(BoxName.isFirstTime).toString() == '0' &&
|
|
|
|
|
box.read(BoxName.isInstall).toString() == '1' &&
|
|
|
|
|
box.read(BoxName.isGiftToken).toString() == '0') {
|
|
|
|
|
var promoCode, discount, validity;
|
|
|
|
|
var resPromo = await CRUD().get(link: AppLink.getPromoFirst, payload: {
|
|
|
|
|
"passengerID": box.read(BoxName.passengerID).toString(),
|
|
|
|
|
});
|
|
|
|
|
if (resPromo != 'failure') {
|
|
|
|
|
var d1 = jsonDecode(resPromo);
|
|
|
|
|
promoCode = d1['message']['promo_code'];
|
|
|
|
|
discount = d1['message']['amount'];
|
|
|
|
|
validity = d1['message']['validity_end_date'];
|
|
|
|
|
}
|
|
|
|
|
box.write(BoxName.isFirstTime, '1');
|
|
|
|
|
|
|
|
|
|
Get.dialog(
|
|
|
|
|
AlertDialog(
|
|
|
|
|
contentPadding: EdgeInsets.zero,
|
|
|
|
|
content: SizedBox(
|
|
|
|
|
width: 300,
|
|
|
|
|
child: PromoBanner(
|
|
|
|
|
promoCode: promoCode,
|
|
|
|
|
discountPercentage: discount,
|
|
|
|
|
validity: validity,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> detectAndCacheDeviceTier() async {
|
|
|
|
|
bool isHighEnd = await DevicePerformanceManager.isHighEndDevice();
|
|
|
|
|
Log.print("Device Analysis - Is Flagship/HighEnd? $isHighEnd");
|
|
|
|
|
box.write(BoxName.lowEndMode, !isHighEnd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> initilizeGetStorage() async {
|
|
|
|
|
if (box.read(BoxName.addWork) == null) {
|
|
|
|
|
box.write(BoxName.addWork, 'addWork');
|
|
|
|
|
}
|
|
|
|
|
if (box.read(BoxName.addHome) == null) {
|
|
|
|
|
box.write(BoxName.addHome, 'addHome');
|
|
|
|
|
}
|
|
|
|
|
if (box.read(BoxName.lowEndMode) == null) {
|
|
|
|
|
detectAndCacheDeviceTier();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> selectDriverAndCarForMishwariTrip() async {
|
|
|
|
|
double latitudeOffset = 0.1;
|
|
|
|
|
double longitudeOffset = 0.12;
|
|
|
|
|
|
|
|
|
|
double southwestLat = passengerLocation.latitude - latitudeOffset;
|
|
|
|
|
double northeastLat = passengerLocation.latitude + latitudeOffset;
|
|
|
|
|
double southwestLon = passengerLocation.longitude - longitudeOffset;
|
|
|
|
|
double northeastLon = passengerLocation.longitude + longitudeOffset;
|
|
|
|
|
|
|
|
|
|
var payload = {
|
|
|
|
|
'southwestLat': southwestLat.toString(),
|
|
|
|
|
'northeastLat': northeastLat.toString(),
|
|
|
|
|
'southwestLon': southwestLon.toString(),
|
|
|
|
|
'northeastLon': northeastLon.toString(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Future selectDriverAndCarForMishwariTrip() async {
|
|
|
|
|
try {
|
|
|
|
|
var res = await CRUD().get(
|
|
|
|
|
link: AppLink.selectDriverAndCarForMishwariTrip, payload: payload);
|
|
|
|
|
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
try {
|
|
|
|
|
var d = jsonDecode(res);
|
|
|
|
|
driversForMishwari = d['message'];
|
|
|
|
|
Log.print('driversForMishwari: $driversForMishwari');
|
|
|
|
|
update();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print("Error decoding JSON: $e");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Logic for mishwari trip driver selection
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print("Error Mishwari select: $e");
|
|
|
|
|
}
|
|
|
|
|
@@ -4311,7 +3908,6 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
|
|
|
|
|
Future<void> _stagePricingAndState() async {
|
|
|
|
|
try {
|
|
|
|
|
await getKazanPercent();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Log.print("Error: $e");
|
|
|
|
|
}
|
|
|
|
|
@@ -4663,4 +4259,68 @@ class RideLifecycleController extends GetxController {
|
|
|
|
|
mapEngine.update();
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
initilizeGetStorage() async {
|
|
|
|
|
if (box.read(BoxName.addWork) == null) {
|
|
|
|
|
box.write(BoxName.addWork, 'addWork');
|
|
|
|
|
}
|
|
|
|
|
if (box.read(BoxName.addHome) == null) {
|
|
|
|
|
box.write(BoxName.addHome, 'addHome');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getPassengerRate() async {
|
|
|
|
|
var res = await CRUD().get(
|
|
|
|
|
link: AppLink.getPassengerRate,
|
|
|
|
|
payload: {'passenger_id': box.read(BoxName.passengerID)});
|
|
|
|
|
if (res != 'failure') {
|
|
|
|
|
var json = jsonDecode(res);
|
|
|
|
|
var message = json['data'] ?? json['message'];
|
|
|
|
|
if (message['rating'] == null) {
|
|
|
|
|
passengerRate = 5.0; // Default rating
|
|
|
|
|
} else {
|
|
|
|
|
var rating = message['rating'];
|
|
|
|
|
if (rating is String) {
|
|
|
|
|
passengerRate = double.tryParse(rating) ?? 5.0;
|
|
|
|
|
} else if (rating is num) {
|
|
|
|
|
passengerRate = rating.toDouble();
|
|
|
|
|
} else {
|
|
|
|
|
passengerRate = 5.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
passengerRate = 5.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
firstTimeRunToGetCoupon() async {
|
|
|
|
|
if (box.read(BoxName.isFirstTime).toString() == '0' &&
|
|
|
|
|
box.read(BoxName.isInstall).toString() == '1' &&
|
|
|
|
|
box.read(BoxName.isGiftToken).toString() == '0') {
|
|
|
|
|
var promo, discount, validity;
|
|
|
|
|
var resPromo = await CRUD().get(link: AppLink.getPromoFirst, payload: {
|
|
|
|
|
"passengerID": box.read(BoxName.passengerID).toString(),
|
|
|
|
|
});
|
|
|
|
|
if (resPromo != 'failure') {
|
|
|
|
|
var d1 = jsonDecode(resPromo);
|
|
|
|
|
promo = d1['message']['promo_code'];
|
|
|
|
|
discount = d1['message']['amount'];
|
|
|
|
|
validity = d1['message']['validity_end_date'];
|
|
|
|
|
}
|
|
|
|
|
box.write(BoxName.isFirstTime, '1');
|
|
|
|
|
Get.dialog(
|
|
|
|
|
AlertDialog(
|
|
|
|
|
contentPadding: EdgeInsets.zero,
|
|
|
|
|
content: SizedBox(
|
|
|
|
|
width: 300,
|
|
|
|
|
child: PromoBanner(
|
|
|
|
|
promoCode: promo ?? '',
|
|
|
|
|
discountPercentage: discount ?? '',
|
|
|
|
|
validity: validity ?? '',
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|