This commit is contained in:
Hamza-Ayed
2024-05-21 16:46:49 +03:00
parent 908b5979a8
commit 5fb6a706c8
17 changed files with 193 additions and 191 deletions

View File

@@ -189,8 +189,10 @@ class AppLink {
static String loginFromGoogleCaptin = "$authCaptin/loginFromGoogle.php";
static String signUpCaptin = "$authCaptin/register.php";
static String sendVerifyEmailCaptin = "$authCaptin/sendVerifyEmail.php";
static String sendVerifyOtpMessage = "$server/auth/otpmessage.php";
static String sendVerifyOtpMessage =
"$server/auth/captin/sendOtpMessageDriver.php";
static String verifyOtpMessage = "$server/auth/verifyOtpMessage.php";
static String verifyOtpDriver = "$server/auth/captin/verifyOtpDriver.php";
static String verifyEmailCaptin = "$authCaptin/verifyEmail.php";
static String removeUser = "$authCaptin/removeAccount.php";
static String deletecaptainAccounr = "$authCaptin/deletecaptainAccounr.php";

View File

@@ -123,7 +123,7 @@ class LoginCaptinController extends GetxController {
'id': driverID,
});
print(res);
if (res == 'failure') {
if (res == 'Failure') {
//Failure
Get.offAll(SmsSignupEgypt());
isloading = false;
@@ -135,7 +135,10 @@ class LoginCaptinController extends GetxController {
if (jsonDecoeded.isNotEmpty) {
if (jsonDecoeded['status'] == 'success' &&
jsonDecoeded['data'][0]['is_verified'] == 1) {
//
box.write(BoxName.emailDriver, jsonDecoeded['data'][0]['email']);
box.write(BoxName.phoneVerified,
jsonDecoeded['data'][0]['is_verified'].toString());
box.write(BoxName.phoneDriver, jsonDecoeded['data'][0]['phone']);
Get.off(HomeCaptain());
} else {
Get.offAll(SmsSignupEgypt());

View File

@@ -91,8 +91,8 @@ class RegisterCaptainController extends GetxController {
'token_code': randomNumber.toString(),
});
await smsEgyptController.sendSmsEgypt(
phoneController.text.toString(), randomNumber.toString());
// await smsEgyptController.sendSmsEgypt(
// phoneController.text.toString(), randomNumber.toString());
isSent = true;
isLoading = false;
update();
@@ -102,19 +102,20 @@ class RegisterCaptainController extends GetxController {
verifySMSCode() async {
if (formKey3.currentState!.validate()) {
var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
var res = await CRUD().post(link: AppLink.verifyOtpDriver, payload: {
'phone_number': '+2${phoneController.text}',
'token_code': verifyCode.text.toString(),
});
if (res != 'failure') {
// var dec = jsonDecode(res);
box.write(BoxName.phoneDriver, '+2${phoneController.text}');
var res1 = await CRUD().post(
link: AppLink.updateAccountBank,
payload: {'phone': '+2${phoneController.text}'});
if (jsonDecode(res1)['status'] == 'success') {
Get.to(EgyptCardAI());
}
box.write(BoxName.phoneVerified, '1');
// var res1 = await CRUD().post(
// link: AppLink.updateAccountBank,
// payload: {'phone': '+2${phoneController.text}'});
// if (jsonDecode(res1)['status'] == 'success') {
Get.to(EgyptCardAI());
// }
}
}
}

View File

@@ -5,6 +5,7 @@ import 'package:SEFER/views/auth/captin/cards/sms_signup.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import '../../onbording_page.dart';
import '../../views/auth/captin/ai_page.dart';
class GoogleSignInHelper {
@@ -66,6 +67,31 @@ class GoogleSignInHelper {
}
}
static Future<void> _handleSignOut() async {
// Clear stored driver information
box.remove(BoxName.driverID);
box.remove(BoxName.emailDriver);
box.remove(BoxName.lang);
box.remove(BoxName.nameDriver);
box.remove(BoxName.passengerID);
box.remove(BoxName.phoneDriver);
box.remove(BoxName.tokenFCM);
box.remove(BoxName.tokens);
box.remove(BoxName.carPlate);
box.remove(BoxName.lastNameDriver);
box.remove(BoxName.agreeTerms);
box.remove(BoxName.tokenDriver);
box.remove(BoxName.countryCode);
box.remove(BoxName.accountIdStripeConnect);
box.remove(BoxName.phoneVerified);
Get.offAll(OnBoardingPage());
// Perform any additional sign-out tasks or API calls here
// For example, you can notify your server about the user sign-out
print('User data cleared.');
}
// Method to get the current signed-in user
static GoogleSignInAccount? getCurrentUser() {
return _googleSignIn.currentUser;
@@ -87,18 +113,4 @@ class GoogleSignInHelper {
// print('nameDriver = ${box.read(BoxName.nameDriver)}');
// print('driverPhotoUrl = ${box.read(BoxName.driverPhotoUrl)}');
}
// Method to handle sign-out process
static Future<void> _handleSignOut() async {
// Clear stored driver information
box.remove(BoxName.driverID);
box.remove(BoxName.emailDriver);
box.remove(BoxName.nameDriver);
box.remove(BoxName.driverPhotoUrl);
// Perform any additional sign-out tasks or API calls here
// For example, you can notify your server about the user sign-out
print('User data cleared.');
}
}

View File

@@ -6,6 +6,7 @@ import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/controller/functions/device_info.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/home/Captin/home_captain/home_captin.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_cropper/image_cropper.dart';
@@ -194,12 +195,12 @@ class AI extends GetxController {
);
} else {
await addDriverEgypt();
await addRegistrationCarEgypt();
// await addRegistrationCarEgypt();
if (isCarSaved && isDriverSaved) {
DeviceController().getDeviceSerialNumber();
box.write(BoxName.phoneVerified, '1');
Get.offAll(() => const MyApp());
Get.offAll(() => HomeCaptain());
// Get.offAll(() => HomeCaptain());
}
}
@@ -208,6 +209,18 @@ class AI extends GetxController {
Future<void> addDriverEgypt() async {
try {
print(box.read(BoxName.driverID).toString());
print(box.read(BoxName.phoneDriver)?.toString() ?? '');
print(responseIdEgyptBack['gender']);
print(responseIdEgyptDriverLicense['license_type']);
print(responseIdEgyptBack['nationalID']);
print(responseIdEgyptDriverLicense['issue_date']);
print(responseIdEgyptDriverLicense['expiry_date']);
print(responseIdEgyptDriverLicense['license_categories']);
print(responseIdEgyptFront['card_id']);
print(responseIdEgyptDriverLicense['issue_date']);
print(responseIdEgyptFront['dob'] != null
? responseIdEgyptFront['dob'] + '-01-01'.toString()
: '');
// Extract values from box or set defaults
var firstName = responseIdEgyptDriverLicense['firstName'] ?? '';
@@ -229,12 +242,14 @@ class AI extends GetxController {
var cardId = responseIdEgyptFront['card_id'] ?? '';
var occupation = responseIdEgyptBack['occupation'] ?? '';
var education = responseIdEgyptBack['occupation'] ?? '';
var licenseIssueDate = responseIdEgyptDriverLicense['issue_date'] ?? '';
var licenseIssueDate =
responseIdEgyptDriverLicense['issue_date'].toString() ?? '';
var religion = responseIdEgyptBack['religion'] ?? '';
var status = responseIdEgyptBack['fullName'] ?? '';
var birthdate = responseIdEgyptFront['dob'] != null
? responseIdEgyptFront['dob'] + '-01-01'
? DateTime.parse(responseIdEgyptFront['dob'] + '-01-01').toString()
: '';
var maritalStatus = responseIdEgyptBack['maritalStatus'] ?? '';
var site = responseIdEgyptDriverLicense['address'] ?? '';
var employmentType = responseIdEgyptDriverLicense['employmentType'] ?? '';
@@ -245,7 +260,7 @@ class AI extends GetxController {
'last_name': lastName,
'email': email,
'phone': phone,
'driverId': driverId,
'id': driverId,
'password': password,
'gender': gender,
'license_type': licenseType,
@@ -267,6 +282,7 @@ class AI extends GetxController {
'site': site,
'employmentType': employmentType,
};
print(payload);
isLoading = true;
update();
// Make POST request

View File

@@ -1,72 +1,28 @@
import 'dart:async';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/auth/captin/login_captin_controller.dart';
import 'package:background_location/background_location.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../main.dart';
class LocationBackgroundController extends GetxController {
@override
Future<void> onInit() async {
void onInit() {
super.onInit();
await requestLocationPermission();
await configureBackgroundLocation();
requestLocationPermission();
configureBackgroundLocation();
}
Future<void> requestLocationPermission() async {
var status = await Permission.locationAlways.status;
print('Initial status: $status');
if (status == PermissionStatus.denied ||
status == PermissionStatus.restricted) {
// Show dialog to inform the driver about background GPS location usage
await Get.dialog(
AlertDialog(
title: Text('Location Permission'.tr),
content: Text(
'We use GPS location in the background to enable you to receive orders.'
.tr),
actions: [
TextButton(
onPressed: () async {
Get.back(); // Close the dialog
// Request permission
status = await Permission.locationAlways.request();
print('Requested status: $status');
_handlePermissionStatus(status);
},
child: Text('OK'),
),
],
),
);
} else {
_handlePermissionStatus(status);
}
}
void _handlePermissionStatus(PermissionStatus status) async {
status = await Permission.locationAlways.status;
if (!status.isGranted) {
// Open app settings if permission is permanently denied
openAppSettings();
box.write(BoxName.locationPermission, 'true');
Get.find<LoginCaptinController>().update();
} else if (status.isGranted) {
// Permission granted
box.write(BoxName.locationPermission, 'true');
Get.find<LoginCaptinController>().update();
await Permission.locationAlways.request();
}
}
Future<void> configureBackgroundLocation() async {
await BackgroundLocation.setAndroidNotification(
title: "Sefer Driver ",
title: "Background Location",
message: "Tracking location...",
icon: "app_icon",
icon: "@mipmap/ic_launcher",
);
BackgroundLocation.setAndroidConfiguration(1000);

View File

@@ -10,8 +10,6 @@ import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/controller/home/payment/captain_wallet_controller.dart';
import 'package:SEFER/main.dart';
import '../home/captin/map_driver_controller.dart';
// LocationController.dart
class LocationController extends GetxController {
LocationData? _currentLocation;
@@ -41,6 +39,7 @@ class LocationController extends GetxController {
// startLocationUpdates();
totalPoints = Get.put(CaptainWalletController()).totalPoints;
// isActive = Get.put(HomeCaptainController()).isActive;
}
Future<void> startLocationUpdates() async {
@@ -49,37 +48,39 @@ class LocationController extends GetxController {
Timer.periodic(const Duration(seconds: 5), (timer) async {
try {
totalPoints = Get.find<CaptainWalletController>().totalPoints;
isActive = Get.find<HomeCaptainController>().isActive;
print('isActive $isActive');
print(totalPoints);
if (isActive) {
if (double.parse(totalPoints) > -300) {
print('total point is $totalPoints');
// if (isActive) {
if (double.parse(totalPoints) > -300) {
print('total point is $totalPoints');
await getLocation();
await getLocation();
// if (box.read(BoxName.driverID) != null) {
await CRUD()
.post(link: AppLink.addCarsLocationByPassenger, payload: {
'driver_id': box.read(BoxName.driverID).toString(),
'latitude': myLocation.latitude.toString(),
'longitude': myLocation.longitude.toString(),
'heading': heading.toString(),
'speed': (speed * 3.6).toStringAsFixed(1),
'distance': totalDistance == 0
? '0'
: totalDistance < 1
? totalDistance.toStringAsFixed(3)
: totalDistance.toStringAsFixed(1),
'status': box.read(BoxName.statusDriverLocation).toString()
});
// Animate camera to user location (optional)
// if (Get.find<HomeCaptainController>().rideId == 'rideId') {
// Get.find<MapDriverController>()
// .mapController!
// .animateCamera(CameraUpdate.newLatLng(LatLng(
// Get.find<LocationController>().myLocation.latitude,
// Get.find<LocationController>().myLocation.longitude,
// )));
// }
// if (box.read(BoxName.driverID) != null) {
await CRUD()
.post(link: AppLink.addCarsLocationByPassenger, payload: {
'driver_id': box.read(BoxName.driverID).toString(),
'latitude': myLocation.latitude.toString(),
'longitude': myLocation.longitude.toString(),
'heading': heading.toString(),
'speed': (speed * 3.6).toStringAsFixed(1),
'distance': totalDistance == 0
? '0'
: totalDistance < 1
? totalDistance.toStringAsFixed(3)
: totalDistance.toStringAsFixed(1),
'status': box.read(BoxName.statusDriverLocation).toString()
});
// Animate camera to user location (optional)
// if (Get.find<HomeCaptainController>().rideId == 'rideId') {
// Get.find<MapDriverController>()
// .mapController!
// .animateCamera(CameraUpdate.newLatLng(LatLng(
// Get.find<LocationController>().myLocation.latitude,
// Get.find<LocationController>().myLocation.longitude,
// )));
}
Get.find<HomeCaptainController>()
.mapHomeCaptainController!
.animateCamera(CameraUpdate.newLatLng(LatLng(

View File

@@ -50,7 +50,7 @@ class HomeCaptainController extends GetxController {
double widthMapTypeAndTraffic = 50;
// Inject the LocationController class
final locationController = Get.put(LocationController());
// final locationBackController = Get.put(LocationBackgroundController());
final locationBackController = Get.put(LocationBackgroundController());
String formatDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
@@ -222,6 +222,8 @@ class HomeCaptainController extends GetxController {
@override
void onInit() async {
// await locationBackController.requestLocationPermission();
await addToken();
await getlocation();
onButtonSelected();

View File

@@ -1,6 +1,6 @@
import 'dart:async';
import 'package:SEFER/views/auth/captin/cards/sms_signup.dart';
import 'package:SEFER/controller/auth/captin/login_captin_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -8,7 +8,6 @@ import '../../constant/box_name.dart';
import '../../main.dart';
import '../../onbording_page.dart';
import '../../views/auth/captin/login_captin.dart';
import '../../views/home/Captin/home_captain/home_captin.dart';
class SplashScreenController extends GetxController
with SingleGetTickerProviderMixin {
@@ -50,10 +49,13 @@ class SplashScreenController extends GetxController
: box.read(BoxName.emailDriver) != null
// todo
&&
box.read(BoxName.deviceInfo) != null &&
box.read(BoxName.phoneDriver) != null &&
box.read(BoxName.phoneVerified) == '1'
// ? Get.off(() => SmsSignupEgypt())
? Get.off(() => HomeCaptain())
// ? Get.off(() => HomeCaptain())
? Get.put(LoginCaptinController()).loginFromSignInGoogle(
box.read(BoxName.driverID).toString(),
box.read(BoxName.emailDriver))
: Get.off(() => LoginCaptin());
});
}

View File

@@ -4,8 +4,9 @@ class MyTranslation extends Translations {
@override
Map<String, Map<String, String>> get keys => {
"ar": {
'You will recieve code in sms message': '',
'Please enter': '',
'Approve Driver Documents': '',
'You will recieve code in sms message': 'ستتلقى رمزًا في رسالة SMS',
'Please enter': 'يرجى إدخال',
'We need your phone number to contact you and to help you receive orders.':
"نحتاج إلى رقم هاتفك للتواصل معك ولمساعدتك في تلقي الطلبات.",
'The full name on your criminal record does not match the one on your drivers license. Please verify and provide the correct documents.':

View File

@@ -18,7 +18,7 @@ class CaptainProfileController extends GetxController {
Future updateFields() async {
var payload = {
'driverID': box.read(BoxName.driverID),
'driverID': box.read(BoxName.driverID).toString(),
};
if (vin.text.isNotEmpty) {

View File

@@ -18,6 +18,7 @@ import 'controller/firebase/firbase_messge.dart';
import 'controller/firebase/local_notification.dart';
import 'controller/functions/device_info.dart';
import 'controller/functions/location_background_controller.dart';
import 'controller/functions/location_controller.dart';
import 'controller/local/local_controller.dart';
import 'controller/local/translations.dart';
import 'controller/payment/paymob/paymob_wallet.dart';
@@ -60,7 +61,7 @@ Future<void> handleBackgroundNotificationClick(RemoteMessage message) async {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
WakelockPlus.enable();
// await LocationController().startLocationUpdates();
await LocationController().startLocationUpdates();
if (Platform.isAndroid) {
await NotificationController().initNotifications();
}
@@ -74,8 +75,7 @@ void main() async {
print(Get.deviceLocale!.countryCode);
Stripe.publishableKey = AK.publishableKey;
Get.put(LocationBackgroundController());
// await LocationBackgroundController().requestLocationPermission();
if (Platform.isAndroid || Platform.isIOS) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
@@ -87,8 +87,6 @@ void main() async {
List<Future> initializationTasks = [
FirebaseMessagesController().getNotificationSettings(),
FirebaseMessagesController().getToken(),
// Get.put(LocationController()).startLocationUpdates(),
// Get.put(LocationBackgroundController()).startBackLocation(),
];
// cameras = await availableCameras();
await Future.wait(initializationTasks);

View File

@@ -5,6 +5,7 @@ import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/info.dart';
import 'package:SEFER/constant/style.dart';
import 'controller/functions/location_background_controller.dart';
import 'controller/home/splash_screen_controlle.dart';
class SplashScreen extends StatelessWidget {
@@ -15,6 +16,7 @@ class SplashScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
Get.put(LocationBackgroundController());
return Scaffold(
backgroundColor:
AppColor.secondaryColor, // Set your desired background color
@@ -34,8 +36,7 @@ class SplashScreen extends StatelessWidget {
: splashScreenController.zoomOutAnimation.value,
child: Image.asset(
'assets/images/logo.gif',
width: Get.width * .3,
height: Get.width * .3,
width: Get.width * .5,
),
);
},

View File

@@ -101,7 +101,7 @@ class EgyptCardAI extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'Approve Driver Documents',
'Approve Driver Documents'.tr,
style: AppStyle.title,
),
const SizedBox(height: 8),

View File

@@ -17,8 +17,8 @@ class SmsSignupEgypt extends StatelessWidget {
body: [
GetBuilder<RegisterCaptainController>(
builder: (registerCaptainController) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
return ListView(
// mainAxisAlignment: MainAxisAlignment.center,
children: [
// Logo at the top
Padding(

View File

@@ -1,5 +1,3 @@
import 'package:SEFER/views/auth/captin/register_captin.dart';
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
@@ -11,6 +9,7 @@ import '../../../constant/info.dart';
import '../../../constant/style.dart';
import '../../../controller/auth/captin/login_captin_controller.dart';
import '../../../controller/auth/google_sign.dart';
import '../../../controller/functions/location_background_controller.dart';
import '../../../main.dart';
import '../../widgets/elevated_btn.dart';
import '../../widgets/my_scafold.dart';
@@ -207,31 +206,40 @@ class LoginCaptin extends StatelessWidget {
onPressed: () async {
await GoogleSignInHelper.signInFromLogin();
},
kolor: AppColor.blueColor,
kolor: AppColor.redColor,
),
// MyElevatedButton(
// title: 'Sign In by Google'.tr,
// onPressed: () async {
// print(box.read(BoxName.emailDriver));
// print(box.read(BoxName.phoneDriver));
// print(box.read(BoxName.phoneVerified));
// },
// kolor: AppColor.redColor,
// ),
],
),
))),
Text(
'if you don\'t have account'.tr,
style: AppStyle.subtitle,
),
AnimatedTextKit(
onTap: () => Get.to(() => const RegisterCaptin()),
animatedTexts: [
TypewriterAnimatedText(
'Register as Driver'.tr,
textStyle: AppStyle.headTitle2,
speed: const Duration(milliseconds: 200),
),
],
totalRepeatCount: 4,
pause: const Duration(milliseconds: 200),
displayFullTextOnTap: true,
stopPauseOnTap: true,
),
// IconButton(
// Text(
// 'if you don\'t have account'.tr,
// style: AppStyle.subtitle,
// ),
// AnimatedTextKit(
// onTap: () => Get.to(() => const RegisterCaptin()),
// animatedTexts: [
// TypewriterAnimatedText(
// 'Register as Driver'.tr,
// textStyle: AppStyle.headTitle2,
// speed: const Duration(milliseconds: 200),
// ),
// ],
// totalRepeatCount: 4,
// pause: const Duration(milliseconds: 200),
// displayFullTextOnTap: true,
// stopPauseOnTap: true,
// ),
// // IconButton(
// onPressed: () async {
// AC credentials = AC();
// String apiKey = AK.payMobApikey;
@@ -354,46 +362,45 @@ class LoginCaptin extends StatelessWidget {
locationPermissionDialog() {
return GetBuilder<LoginCaptinController>(builder: (controller) {
return box.read(BoxName.locationPermission) != 'true'
? Padding(
padding: const EdgeInsets.all(16),
child: Container(
height: Get.height * .4,
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'We use location to get accurate and nearest passengers for you'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
Text(
'You will choose allow all the time to be ready receive orders'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title
.copyWith(color: AppColor.greenColor),
),
MyElevatedButton(
title: 'Grant Location'.tr,
onPressed: () async {
await controller.getLocationPermission();
},
kolor: AppColor.greenColor,
)
],
),
return Padding(
padding: const EdgeInsets.all(16),
child: Container(
height: Get.height * .4,
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'We use location to get accurate and nearest passengers for you'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
),
Text(
'You will choose allow all the time to be ready receive orders'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title.copyWith(color: AppColor.greenColor),
),
MyElevatedButton(
title: 'Grant Location'.tr,
onPressed: () async {
// await Get.put(LocationBackgroundController()); //////
box.write(BoxName.locationPermission, 'true');
controller.update();
},
kolor: AppColor.greenColor,
)
],
),
)
: const SizedBox();
),
),
),
);
});
}
}

View File

@@ -17,13 +17,13 @@ import 'widget/connect.dart';
import 'widget/left_menu_map_captain.dart';
import '../../../../controller/home/payment/captain_wallet_controller.dart';
import '../../../../main.dart';
import '../../../widgets/circle_container.dart';
class HomeCaptain extends StatelessWidget {
HomeCaptain({super.key});
final LocationController locationController = Get.put(LocationController());
final HomeCaptainController homeCaptainController =
Get.put(HomeCaptainController());
@override
Widget build(BuildContext context) {
Get.put(OrderRequestController());