diff --git a/lib/analytics/flows/advance_payments.dart b/lib/analytics/flows/advance_payments.dart index db52eb59..6bd43a08 100644 --- a/lib/analytics/flows/advance_payments.dart +++ b/lib/analytics/flows/advance_payments.dart @@ -79,4 +79,20 @@ class AdvancePayments{ 'transaction_currency' : txn_currency }); } + + // New + payment_fail({@required String appointment_type, clinic, hospital, payment_method, payment_type, txn_amount, txn_currency, error_code, error_message}){ + logger('payment_fail', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type, + 'hospital_name' : hospital, + 'transaction_number' : "", + 'transaction_amount' : txn_amount, + 'transaction_currency' : txn_currency, + "error_code" : error_code, + "error_message" : error_message, + }); + } } \ No newline at end of file diff --git a/lib/analytics/flows/appointments.dart b/lib/analytics/flows/appointments.dart index 50a02c76..0e911d75 100644 --- a/lib/analytics/flows/appointments.dart +++ b/lib/analytics/flows/appointments.dart @@ -232,14 +232,17 @@ class Appointment{ // R036 payment_success({@required String appointment_type, clinic, hospital, payment_method, payment_type, txn_number, txn_amount, txn_currency}){ - // appointment_type - // clinic_type_online - // payment_method - // payment_type: 'appointment' - // hospital_name - // transaction_number - // transaction_amount - // transaction_currency + + logger('payment_success', parameters: { + 'appointment_type' : appointment_type, + 'clinic_type_online' : clinic, + 'payment_method' : payment_method, + 'payment_type' : payment_type, + 'hospital_name' : hospital, + 'transaction_number' : txn_number, + 'transaction_amount' : txn_amount, + 'transaction_currency' : txn_currency, + }); } diff --git a/lib/analytics/google-analytics.dart b/lib/analytics/google-analytics.dart index 2a70d4e4..a8252051 100644 --- a/lib/analytics/google-analytics.dart +++ b/lib/analytics/google-analytics.dart @@ -9,7 +9,7 @@ import 'package:diplomaticquarterapp/analytics/flows/offers_promotions.dart'; import 'package:diplomaticquarterapp/analytics/flows/todo_list.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/routes.dart'; -import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; @@ -22,86 +22,79 @@ import 'package:geolocator/geolocator.dart'; import 'flows/app_nav.dart'; import 'flows/hmg_services.dart'; - -typedef GALogger = Function(String name, {Map parameters}); +typedef GALogger = Function(String name, {Map parameters}); var _analytics = FirebaseAnalytics(); -_logger(String name, {Map parameters}) async { + +_logger(String name, {Map parameters}) async { + // return; if (name != null && name.isNotEmpty) { - if(name.contains(' ')) - name = name.replaceAll(' ','_'); - + if (name.contains(' ')) name = name.replaceAll(' ', '_'); + // To LowerCase - if(parameters != null && parameters.isNotEmpty) + if (parameters != null && parameters.isNotEmpty) parameters = parameters.map((key, value) { final key_ = key.toLowerCase(); var value_ = value; - if(value is String) - value_ = value.toLowerCase(); + if (value is String) value_ = value.toLowerCase(); return MapEntry(key_, value_); }); - try{ - _analytics - .logEvent(name: name.trim().toLowerCase(), parameters: parameters) - .then((value) { + try { + _analytics.logEvent(name: name.trim().toLowerCase(), parameters: parameters).then((value) { debugPrint('SUCCESS: Google analytics event "$name" sent with parameters $parameters'); }).catchError((error) { debugPrint('ERROR: Google analytics event "$name" sent failed'); }); - }catch(e){ + } catch (e) { print(e); } } } - class GAnalytics { static String TREATMENT_TYPE; static String APPOINTMENT_DETAIL_FLOW_TYPE; static String PAYMENT_TYPE; - setUser(AuthenticatedUser user) async{ - try{ + setUser(AuthenticatedUser user) async { + try { _analytics.setUserProperty(name: 'user_language', value: user.preferredLanguage == '1' ? 'arabic' : 'english'); _analytics.setUserProperty(name: 'userid', value: Utils.generateMd5Hash(user.emailAddress)); _analytics.setUserProperty(name: 'login_status', value: user == null ? 'guest' : 'loggedin'); - final location = await Geolocator.getCurrentPosition(); - if(location != null && !location.isMocked){ - final places = await placemarkFromCoordinates(location.latitude, location.longitude, localeIdentifier: 'en_US'); - final countryCode = places.first.isoCountryCode; - _analytics.setUserProperty(name: 'user_country', value: countryCode); + if (await PermissionService.isLocationEnabled()) { + final location = await Geolocator.getCurrentPosition(); + if (location != null && !location.isMocked) { + final places = await placemarkFromCoordinates(location.latitude, location.longitude, localeIdentifier: 'en_US'); + final countryCode = places.first.isoCountryCode; + _analytics.setUserProperty(name: 'user_country', value: countryCode); + } + } else { + _analytics.setUserProperty(name: 'user_country', value: "N/A"); } - }catch(e){ - - } + } catch (e) {} } - + NavObserver navObserver() => NavObserver(); - final hamburgerMenu = HamburgerMenu(_logger); - final bottomTabNavigation = AppNav(_logger); - final hmgServices = HMGServices(_logger); - final loginRegistration = LoginRegistration(_logger); - final appointment = Appointment(_logger); - final liveCare = LiveCare(_logger); - final todoList = TodoList(_logger); - final advancePayments = AdvancePayments(_logger); - final offerPackages = OfferAndPromotion(_logger); - final errorTracking = ErrorTracking(_logger); + final hamburgerMenu = HamburgerMenu(_logger); + final bottomTabNavigation = AppNav(_logger); + final hmgServices = HMGServices(_logger); + final loginRegistration = LoginRegistration(_logger); + final appointment = Appointment(_logger); + final liveCare = LiveCare(_logger); + final todoList = TodoList(_logger); + final advancePayments = AdvancePayments(_logger); + final offerPackages = OfferAndPromotion(_logger); + final errorTracking = ErrorTracking(_logger); } - - // adb shell setprop debug.firebase.analytics.app com.ejada.hmg -> Android class NavObserver extends RouteObserver> { _sendScreenView(PageRoute route) async { log(String className) { var event = AnalyticEvents.get(className); if (event.active != null) { - _analytics - .setCurrentScreen( - screenName: event.flutterName(), screenClassOverride: className) - .catchError( + _analytics.setCurrentScreen(screenName: event.flutterName(), screenClassOverride: className).catchError( (Object error) { print('$FirebaseAnalyticsObserver: $error'); }, @@ -112,9 +105,7 @@ class NavObserver extends RouteObserver> { } } - if (route.settings.name != null && - route.settings.name.isNotEmpty && - route.settings.name != "null") { + if (route.settings.name != null && route.settings.name.isNotEmpty && route.settings.name != "null") { var class_ = routes[route.settings.name](0); if (class_ != null) log(class_.toStringShort()); } else if (route is FadePage) { diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart new file mode 100644 index 00000000..0fd54e74 --- /dev/null +++ b/lib/app_state/app_state.dart @@ -0,0 +1,13 @@ +class AppState { + static final AppState _instance = AppState._internal(); + + AppState._internal(); + + factory AppState() => _instance; + + bool isLogged = false; + + set setLogged(v) => isLogged = v; + + bool get getIsLogged => isLogged; +} diff --git a/lib/config/config.dart b/lib/config/config.dart index 34ea5128..ac610ee9 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -351,6 +351,9 @@ var INSERT_LIVECARE_SCHEDULE_APPOINTMENT = var GET_PATIENT_SHARE_LIVECARE = "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForLiveCare"; +var SET_ONLINE_CHECKIN_FOR_APPOINTMENT = + "Services/Patients.svc/REST/SetOnlineCheckInForAppointment"; + var GET_LIVECARE_CLINIC_TIMING = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule'; @@ -396,7 +399,7 @@ var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnar var CHANNEL = 3; var GENERAL_ID = 'Cs2020@2016\$2958'; var IP_ADDRESS = '10.20.10.20'; -var VERSION_ID = 9.0; +var VERSION_ID = 8.3; var SETUP_ID = '91877'; var LANGUAGE = 2; var PATIENT_OUT_SA = 0; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 7f2242a3..b0c7213f 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -268,12 +268,12 @@ const Map localizedValues = { "myMedicalFileSubTitle": {"en": "All your medical records", 'ar': 'جميع سجلاتك الطبية'}, "viewMore": {"en": "View More", 'ar': 'عرض المزيد'}, "homeHealthCareService": {"en": "Home Health Care Service", 'ar': 'الرعاية الصحية المنزلية'}, - "OnlinePharmacy": {"en": "Online Pharmacy", 'ar': 'الصيدلية االلكترونية'}, + "OnlinePharmacy": {"en": "Online Pharmacy", 'ar': 'الصيدلية الإلكترونية'}, "EmergencyService": {"en": "Emergency Service", 'ar': 'الفحص الطبي الشامل'}, "OnlinePaymentService": {"en": "Online Payment Service", 'ar': 'خدمة الدفع الإلكتروني'}, "OffersAndPackages": {"en": "Online transfer request", 'ar': 'طلب التحويل الالكتروني'}, "ComprehensiveMedicalCheckup": {"en": "Comprehensive Medical Check-up", 'ar': 'فحص طبي شامل'}, - "HMGService": {"en": "HMG Service", 'ar': 'الخدمات االلكترونية'}, + "HMGService": {"en": "HMG Service", 'ar': 'الخدمات الإلكترونية'}, "ViewAllHabibMedicalService": {"en": "View All Habib Medical Service", 'ar': 'عرض خدمات الحبيب الطبية'}, "viewAll": {"en": "View All", 'ar': 'عرض الكل'}, "view": {"en": "View", 'ar': 'عرض'}, @@ -541,11 +541,11 @@ const Map localizedValues = { "refferal": {"en": "E-Refferal", "ar": "الإحالة الإلكترونية"}, "refferalTitle": {"en": "E-Refferal", "ar": "خدمات"}, "refferalSubTitle": {"en": "Service", "ar": "الإحالة الإلكترونية"}, - "healthCare": {"en": "Health Care", "ar": "الصحية المزلية"}, + "healthCare": {"en": "Health Care", "ar": "الصحية المنزلية"}, "emergency": {"en": "Emergency", "ar": "الطوارئ"}, "erservices": {"en": "Emergency", "ar": "الطوارئ"}, "services2": {"en": "Services", "ar": "خدمات"}, - "cantSeeProfile": {"en": "To view your medical profile, please log in or register now", "ar": "للتصفح ملفك الطبي الرجاء تسجيل الدخول أو التسجيل االن"}, + "cantSeeProfile": {"en": "To view your medical profile, please log in or register now", "ar": "للتصفح ملفك الطبي الرجاء تسجيل الدخول أو التسجيل الآن"}, "loginRegisterNow": {"en": "Login or Register Now", "ar": "تسجيل الدخول أو التسجيل الآن"}, "HMGPharmacy": {"en": "HMG Pharmacy", "ar": "صيدلية HMG"}, "ecommerceSolution": {"en": "Ecommerce Solution", "ar": "حل التجارة الإلكترونية"}, @@ -1811,5 +1811,9 @@ const Map localizedValues = { "recordAudioPermission": { "en": "Dr. Al Habib app needs audio permission to enable voice command features.", "ar": "يحتاج تطبيق دكتور الحبيب إلى صلاحية الوصول الى الصوت لتفعيل خدمة الأوامر الصوتية." }, "wifiPermission": { "en": "Dr. Al Habib app needs to access WiFi state permission to connect to the HMG WiFi network from within the app when you visit the hospital.", "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى الواي فاي للاتصال بشبكة الواي فاي في المجموعة عند زيارة المستشفى." }, "physicalActivityPermission": { "en": "Dr. Al Habib app collects physical activity data to read heart rate, steps & distance from your smartwatch & send it to your doctor.", "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى بيانات النشاط البدني لقراءة معدل ضربات القلب والخطوات والمسافة من ساعتك الذكية وتحميلها على ملفك الطبي حتى يتمكن الطبيب من الاطلاع عليها." }, - "bluetoothPermission": { "en": "Dr. Al Habib app needs to access Bluetooth permission to connect blood pressure & blood sugar devices with the app to analyze the data", "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى البلوتوث لربط أجهزة ضغط الدم وسكر الدم بالتطبيق لتحليل البيانات وتحميلها على ملفك الطبي حتى يتمكن الطبيب من الاطلاع عليها." } + "bluetoothPermission": { "en": "Dr. Al Habib app needs to access Bluetooth permission to connect blood pressure & blood sugar devices with the app to analyze the data", "ar": "يحتاج تطبيق دكتور الحبيب إلى الوصول إلى البلوتوث لربط أجهزة ضغط الدم وسكر الدم بالتطبيق لتحليل البيانات وتحميلها على ملفك الطبي حتى يتمكن الطبيب من الاطلاع عليها." }, + "privacyPolicy": {"en": "Privacy Policy", "ar": "سياسة الخصوصية"}, + "termsConditions": {"en": "Terms & Conditions", "ar": "الأحكام والشروط"}, + "prescriptionDeliveryError": {"en": "This clinic does not support refill & delivery.", "ar": "هذه العيادة لا تدعم إعادة التعبئة والتسليم."}, + "liveCarePermissions": {"en": "LiveCare required Camera & Microphone permissions, Please allow these to proceed.", "ar": "هذه العيادة لا تدعم خدمة إعادة التعبئة والتسليم."}, }; diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index 7ce1c055..d5fb7e3b 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -2,6 +2,7 @@ const TOKEN = 'token'; const APP_LANGUAGE = 'language'; const USER_PROFILE = 'user-profile'; const PUSH_TOKEN = 'push-token'; +const APNS_TOKEN = 'apns-token'; const REGISTER_DATA_FOR_REGISTER = 'register-data-for-register'; const LOGIN_TOKEN_ID = 'register-data-for-register'; const REGISTER_DATA_FOR_LOGIIN = 'register-data-for-login'; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 8e864293..50370b52 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffers import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; @@ -62,6 +63,9 @@ class BaseAppClient { if (!isExternal) { String token = await sharedPref.getString(TOKEN); var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + if (endPoint == SEND_ACTIVATION_CODE) { + languageID = 'en'; + } if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null @@ -85,7 +89,7 @@ class BaseAppClient { : IS_DENTAL_ALLOWED_BACKEND; } - body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; + body['DeviceTypeID'] = Platform.isIOS ? 1 : 2; if (!body.containsKey('IsPublicRequest')) { body['PatientType'] = body.containsKey('PatientType') @@ -128,7 +132,7 @@ class BaseAppClient { // body['IdentificationNo'] = 2076117163; // body['MobileNo'] = "966503109207"; - // body['PatientID'] = 3628809; //3844083 + // body['PatientID'] = 50121262; //3844083 // body['TokenID'] = "@dm!n"; // Patient ID: 3027574 @@ -146,7 +150,6 @@ class BaseAppClient { if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) { final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers); final int statusCode = response.statusCode; - // print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); @@ -261,72 +264,65 @@ class BaseAppClient { if (!isExternal) { String token = await sharedPref.getString(TOKEN); var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - if (body.containsKey('SetupID')) { - body['SetupID'] = body.containsKey('SetupID') - ? body['SetupID'] != null - ? body['SetupID'] - : SETUP_ID - : SETUP_ID; - } - - body['VersionID'] = VERSION_ID; - body['Channel'] = CHANNEL; - body['LanguageID'] = languageID == 'ar' ? 1 : 2; - - body['IPAdress'] = IP_ADDRESS; - body['generalid'] = GENERAL_ID; - body['PatientOutSA'] = body.containsKey('PatientOutSA') - ? body['PatientOutSA'] != null - ? body['PatientOutSA'] - : PATIENT_OUT_SA - : PATIENT_OUT_SA; - - if (body.containsKey('isDentalAllowedBackend')) { - body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') - ? body['isDentalAllowedBackend'] != null - ? body['isDentalAllowedBackend'] - : IS_DENTAL_ALLOWED_BACKEND - : IS_DENTAL_ALLOWED_BACKEND; - } - - body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; - - if (!body.containsKey('IsPublicRequest')) { - body['PatientType'] = body.containsKey('PatientType') - ? body['PatientType'] != null - ? body['PatientType'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE - : PATIENT_TYPE; - body['PatientTypeID'] = body.containsKey('PatientTypeID') - ? body['PatientTypeID'] != null - ? body['PatientTypeID'] - : user['PatientType'] != null - ? user['PatientType'] - : PATIENT_TYPE_ID - : PATIENT_TYPE_ID; - if (user != null) { - body['TokenID'] = token; - body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; - body['PatientOutSA'] = user['OutSA']; - body['SessionID'] = SESSION_ID; //getSe - // headers = { - // 'Content-Type': 'application/json', - // 'Accept': 'application/json', - // 'Authorization': pharmacyToken, - // 'Mobilenumber': user['MobileNumber'].toString(), - // 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', - // 'Username': user['PatientID'].toString(), - // }; - } - } + // if (body.containsKey('SetupID')) { + // body['SetupID'] = body.containsKey('SetupID') + // ? body['SetupID'] != null + // ? body['SetupID'] + // : SETUP_ID + // : SETUP_ID; + // } + // + // body['VersionID'] = VERSION_ID; + // body['Channel'] = CHANNEL; + // body['LanguageID'] = languageID == 'ar' ? 1 : 2; + // + // body['IPAdress'] = IP_ADDRESS; + // body['generalid'] = GENERAL_ID; + // body['PatientOutSA'] = body.containsKey('PatientOutSA') + // ? body['PatientOutSA'] != null + // ? body['PatientOutSA'] + // : PATIENT_OUT_SA + // : PATIENT_OUT_SA; + // + // if (body.containsKey('isDentalAllowedBackend')) { + // body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') + // ? body['isDentalAllowedBackend'] != null + // ? body['isDentalAllowedBackend'] + // : IS_DENTAL_ALLOWED_BACKEND + // : IS_DENTAL_ALLOWED_BACKEND; + // } + // + // body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; + // + // if (!body.containsKey('IsPublicRequest')) { + // body['PatientType'] = body.containsKey('PatientType') + // ? body['PatientType'] != null + // ? body['PatientType'] + // : user['PatientType'] != null + // ? user['PatientType'] + // : PATIENT_TYPE + // : PATIENT_TYPE; + // + // body['PatientTypeID'] = body.containsKey('PatientTypeID') + // ? body['PatientTypeID'] != null + // ? body['PatientTypeID'] + // : user['PatientType'] != null + // ? user['PatientType'] + // : PATIENT_TYPE_ID + // : PATIENT_TYPE_ID; + // if (user != null) { + // body['TokenID'] = token; + // body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID']; + // body['PatientOutSA'] = user['OutSA']; + // body['SessionID'] = SESSION_ID; //getSe + // } + // } } - // print("URL : $url"); - // print("Body : ${json.encode(body)}"); - // print("Headers : ${json.encode(headers)}"); + print("URL : $url"); + print("Body : ${json.encode(body)}"); + print("Headers : ${json.encode(headers)}"); if (await Utils.checkConnection()) { final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers); @@ -492,7 +488,7 @@ class BaseAppClient { 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "", 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Username': user != null ? user['PatientID'].toString() : "", - 'Host': "mdlaboratories.com", + // 'Host': "mdlaboratories.com", }); final int statusCode = response.statusCode; // print("statusCode :$statusCode"); diff --git a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart index 41683165..d48e214e 100644 --- a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart @@ -124,9 +124,9 @@ class HomeHealthCareViewModel extends BaseViewModel { Future addAddressInfo({AddNewAddressRequestModel addNewAddressRequestModel}) async { setState(ViewState.Busy); - await _pharmacyModuleService.generatePharmacyToken().then((value) async { + // await _pharmacyModuleService.generatePharmacyToken().then((value) async { await _customerAddressesService.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); - }); + // }); if (_customerAddressesService.hasError) { error = _customerAddressesService.error; diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index 78ed83b4..dd3d3a62 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -6,6 +6,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/privilege/PrivilegeModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/laser_body_parts.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/cupertino.dart'; @@ -47,6 +48,9 @@ class ProjectViewModel extends BaseViewModel { List get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser; + List selectedBodyPartList = []; + int laserSelectionDuration = 0; + StreamSubscription subscription; ProjectViewModel() { diff --git a/lib/main.dart b/lib/main.dart index 254e0456..0be89cc5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -74,7 +74,7 @@ class _MyApp extends State { // var font = projectProvider.isArabic ? 'Cairo' : 'WorkSans'; // Re-enable once going live - // if (Platform.isAndroid) checkForUpdate(); + if (Platform.isAndroid) checkForUpdate(); ThemeNotifier(defaultTheme()); super.initState(); diff --git a/lib/models/ambulanceRequest/locationDetails.dart b/lib/models/ambulanceRequest/locationDetails.dart new file mode 100644 index 00000000..2ad61f2d --- /dev/null +++ b/lib/models/ambulanceRequest/locationDetails.dart @@ -0,0 +1,23 @@ +class LocationDetails { + double _lat; + double _long; + String _formattedAddress; + + double get lat => _lat; + + set lat(double lat) { + _lat = lat; + } + + double get long => _long; + + set long(double long) { + _long = long; + } + + String get formattedAddress => _formattedAddress; + + set formattedAddress(String formattedAddress) { + _formattedAddress = formattedAddress; + } +} diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart index a7478371..0dbc255d 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart @@ -1,18 +1,28 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import 'package:provider/provider.dart'; @@ -23,7 +33,6 @@ class CMCLocationPage extends StatefulWidget { final double longitude; final dynamic model; - const CMCLocationPage({Key key, this.onPick, this.latitude, this.longitude, this.model}) : super(key: key); @override @@ -35,10 +44,40 @@ class _CMCLocationPageState extends State { double longitude = 0; bool showCurrentLocation = false; Function onPick; + bool isHuawei = false; + Placemark selectedPlace; + AppMap appMap; + static CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + LatLng currentPostion; + AppSharedPreferences sharedPref = AppSharedPreferences(); @override void initState() { - onPick=widget.onPick; + checkIsHuawei(); + + appMap = AppMap( + _kGooglePlex.toMap(), + onCameraMove: (camera) { + _updatePosition(camera); + }, + onMapCreated: () { + currentPostion = LatLng(widget.latitude, widget.longitude); + latitude = widget.latitude; + longitude = widget.longitude; + _getUserLocation(); + setState(() {}); + }, + onCameraIdle: () async { + List placemarks = await placemarkFromCoordinates(latitude, longitude); + selectedPlace = placemarks[0]; + print(selectedPlace); + }, + ); + + onPick = widget.onPick; latitude = widget.latitude; longitude = widget.longitude; if (latitude == 0.0 && longitude == 0.0) { @@ -47,6 +86,12 @@ class _CMCLocationPageState extends State { super.initState(); } + checkIsHuawei() async { + isHuawei = await FlutterHmsGmsAvailability.isHmsAvailable; + print(isHuawei); + setState(() {}); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -65,89 +110,194 @@ class _CMCLocationPageState extends State { ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png'), ], appBarTitle: TranslationBase.of(context).addNewAddress, - body: PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - searchForInitialValue: false, - onPlacePicked: (PickResult result) { - print(result.adrAddress); - }, - selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: Column( - children: [ - SecondaryButton( - color: CustomColors.accentColor, - textColor: Colors.white, - onTap: () async { - print(selectedPlace); - AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( - customer: Customer( - addresses: [ - Addresses( - address1: selectedPlace.formattedAddress, - address2: selectedPlace.formattedAddress, - customerAttributes: "", - city: "", - createdOnUtc: "", - id: "0", - latLong: selectedPlace.geometry.location.lat.toString() + "," + selectedPlace.geometry.location.lng.toString(), - email: "", - ) - ], + body: isHuawei + ? Column( + children: [ + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ), + ], + ), + ), + Container( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton(TranslationBase.of(context).addNewAddress, () async { + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace.street, + address2: selectedPlace.street, + customerAttributes: "", + city: selectedPlace.administrativeArea, + createdOnUtc: "", + id: "0", + faxNumber: "", + phoneNumber: projectViewModel.user.mobileNumber, + province: selectedPlace.administrativeArea, + countryId: 69, + latLong: latitude.toStringAsFixed(6) + "," + longitude.toStringAsFixed(6), + country: selectedPlace.country, + zipPostalCode: selectedPlace.postalCode, + email: projectViewModel.user.emailAddress) + ]), + ); + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }), + ), + ], + ) + : PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + onPlacePicked: (PickResult result) { + print(result.adrAddress); + }, + selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(12.0), + child: state == SearchingState.Searching + ? Center(child: CircularProgressIndicator()) + : Container( + margin: EdgeInsets.all(12), + child: Column( + children: [ + SecondaryButton( + color: CustomColors.accentColor, + textColor: Colors.white, + onTap: () async { + print(selectedPlace); + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer( + addresses: [ + Addresses( + address1: selectedPlace.formattedAddress, + address2: selectedPlace.formattedAddress, + customerAttributes: "", + city: "", + createdOnUtc: "", + id: "0", + latLong: selectedPlace.geometry.location.lat.toString() + "," + selectedPlace.geometry.location.lng.toString(), + email: "", + ) + ], + ), + ); + + selectedPlace.addressComponents.forEach((e) { + if (e.types.contains("country")) { + addNewAddressRequestModel.customer.addresses[0].country = e.longName; + } + if (e.types.contains("postal_code")) { + addNewAddressRequestModel.customer.addresses[0].zipPostalCode = e.longName; + } + if (e.types.contains("locality")) { + addNewAddressRequestModel.customer.addresses[0].city = e.longName; + } + }); + + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + onPick(); + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(); + }, + label: TranslationBase.of(context).addNewAddress, ), - ); - - selectedPlace.addressComponents.forEach((e) { - if (e.types.contains("country")) { - addNewAddressRequestModel.customer.addresses[0].country = e.longName; - } - if (e.types.contains("postal_code")) { - addNewAddressRequestModel.customer.addresses[0].zipPostalCode = e.longName; - } - if (e.types.contains("locality")) { - addNewAddressRequestModel.customer.addresses[0].city = e.longName; - } - }); - - await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } else { - onPick(); - AppToast.showSuccessToast(message: "Address Added Successfully"); - } - Navigator.of(context).pop(); - }, - label: TranslationBase.of(context).addNewAddress, + ], + ), ), - ], - ), - ), - ); - }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: showCurrentLocation, - ), + ); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: showCurrentLocation, + ), ), ); } + + void _getUserLocation() async { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = LatLng(lat, long); + setMap(); + } else { + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + longitude = value.longitude; + currentPostion = LatLng(latitude, longitude); + setMap(); + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + longitude = value.longitude; + currentPostion = LatLng(latitude, longitude); + setMap(); + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + longitude = value.longitude; + setMap(); + }); + } + } + } + } + + setMap() { + setState(() { + _kGooglePlex = CameraPosition( + target: currentPostion, + zoom: 14.4746, + ); + appMap.moveTo(cameraPostion: _kGooglePlex); + }); + } + + void _updatePosition(CameraPosition _position) { + print(_position); + latitude = _position.target.latitude; + longitude = _position.target.longitude; + } } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart index a3fce7b4..81f2d03f 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart @@ -1,11 +1,14 @@ -import 'dart:async'; +import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -15,7 +18,9 @@ import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import 'package:provider/provider.dart'; @@ -37,6 +42,10 @@ class _LocationPageState extends State { double longitude = 0; bool showCurrentLocation = false; + GoogleMapController mapController; + + bool isHuawei = false; + AppMap appMap; AppSharedPreferences sharedPref = AppSharedPreferences(); static CameraPosition _kGooglePlex = CameraPosition( @@ -44,13 +53,15 @@ class _LocationPageState extends State { zoom: 14.4746, ); LatLng currentPostion; - Completer mapController = Completer(); + + // Completer mapController = Completer(); Placemark selectedPlace; @override void initState() { latitude = widget.latitude; longitude = widget.longitude; + checkIsHuawei(); if (latitude == 0.0 && longitude == 0.0) { showCurrentLocation = true; } @@ -63,12 +74,13 @@ class _LocationPageState extends State { currentPostion = LatLng(widget.latitude, widget.longitude); latitude = widget.latitude; longitude = widget.longitude; - setMap(); + _getUserLocation(); setState(() {}); }, onCameraIdle: () async { List placemarks = await placemarkFromCoordinates(latitude, longitude); selectedPlace = placemarks[0]; + print(selectedPlace); }, ); super.initState(); @@ -86,136 +98,173 @@ class _LocationPageState extends State { baseViewModel: model, showNewAppBarTitle: true, showNewAppBar: true, - body: - // Column( - // children: [ - // Expanded( - // child: Stack( - // alignment: Alignment.center, - // children: [ - // if (appMap != null) appMap, - // Container( - // margin: EdgeInsets.only(bottom: 50.0), - // child: Icon( - // Icons.place, - // color: CustomColors.accentColor, - // size: 50, - // ), - // ), - // ], - // ), - // ), - // Container( - // padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), - // child: DefaultButton(TranslationBase.of(context).addNewAddress, () async { - // AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( - // customer: Customer(addresses: [ - // Addresses( - // address1: selectedPlace.name, - // address2: selectedPlace.street, - // customerAttributes: "", - // city: selectedPlace.locality, - // createdOnUtc: "", - // id: "0", - // faxNumber: "", - // phoneNumber: projectViewModel.user.mobileNumber, - // province: selectedPlace.locality, - // countryId: 69, - // latLong: "$latitude,$longitude", - // country: selectedPlace.country, - // zipPostalCode: selectedPlace.postalCode, - // email: projectViewModel.user.emailAddress) - // ]), - // ); - // await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); - // if (model.state == ViewState.ErrorLocal) { - // Utils.showErrorToast(model.error); - // } else { - // AppToast.showSuccessToast(message: "Address Added Successfully"); - // } - // Navigator.of(context).pop(addNewAddressRequestModel); - // }), - // ), - // ], - // ), - - PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - searchForInitialValue: false, - onPlacePicked: (PickResult result) { - print(result.adrAddress); - }, - selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(0.0), - child: state == SearchingState.Searching - ? SizedBox(height: 43, child: Center(child: CircularProgressIndicator())).insideContainer - : DefaultButton(TranslationBase.of(context).addNewAddress, () async { - AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( - customer: Customer(addresses: [ - Addresses( - address1: selectedPlace.formattedAddress, - address2: selectedPlace.formattedAddress, - customerAttributes: "", - createdOnUtc: "", - id: "0", - faxNumber: "", - phoneNumber: projectViewModel.user.mobileNumber, - countryId: 69, - latLong: "$latitude,$longitude", - email: projectViewModel.user.emailAddress) - // Addresses( - // address1: selectedPlace.formattedAddress, - // address2: selectedPlace.formattedAddress, - // customerAttributes: "", - // city: "", - // createdOnUtc: "", - // id: "0", - // latLong: "${selectedPlace.geometry.location}", - // email: "") - ]), - ); - - selectedPlace.addressComponents.forEach((e) { - if (e.types.contains("country")) { - addNewAddressRequestModel.customer.addresses[0].country = e.longName; - } - if (e.types.contains("postal_code")) { - addNewAddressRequestModel.customer.addresses[0].zipPostalCode = e.longName; - } - if (e.types.contains("locality")) { - addNewAddressRequestModel.customer.addresses[0].city = e.longName; - } - }); - - await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); - if (model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); - } else { - AppToast.showSuccessToast(message: "Address Added Successfully"); - } - Navigator.of(context).pop(addNewAddressRequestModel); - }).insideContainer); - }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: showCurrentLocation, - ), + body: isHuawei + ? Column( + children: [ + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, + ), + ), + ], + ), + ), + Container( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton(TranslationBase.of(context).addNewAddress, () async { + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace.street, + address2: selectedPlace.street, + customerAttributes: "", + city: selectedPlace.administrativeArea, + createdOnUtc: "", + id: "0", + faxNumber: "", + phoneNumber: projectViewModel.user.mobileNumber, + province: selectedPlace.administrativeArea, + countryId: 69, + latLong: latitude.toStringAsFixed(6) + "," + longitude.toStringAsFixed(6), + country: selectedPlace.country, + zipPostalCode: selectedPlace.postalCode, + email: projectViewModel.user.emailAddress) + ]), + ); + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }), + ), + ], + ) + : PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + onMapCreated: (GoogleMapController controller) { + mapController = controller; + }, + onPlacePicked: (PickResult result) { + print(result.adrAddress); + }, + selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(0.0), + child: state == SearchingState.Searching + ? SizedBox(height: 43, child: Center(child: CircularProgressIndicator())).insideContainer + : DefaultButton(TranslationBase.of(context).addNewAddress, () async { + AddNewAddressRequestModel addNewAddressRequestModel = new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace.formattedAddress, + address2: selectedPlace.formattedAddress, + customerAttributes: "", + createdOnUtc: "", + id: "0", + faxNumber: "", + phoneNumber: projectViewModel.user.mobileNumber, + countryId: 69, + latLong: selectedPlace.geometry.location.lat.toString() + "," + selectedPlace.geometry.location.lng.toString(), + email: projectViewModel.user.emailAddress) + ]), + ); + + selectedPlace.addressComponents.forEach((e) { + if (e.types.contains("country")) { + addNewAddressRequestModel.customer.addresses[0].country = e.longName; + } + if (e.types.contains("postal_code")) { + addNewAddressRequestModel.customer.addresses[0].zipPostalCode = e.longName; + } + if (e.types.contains("locality")) { + addNewAddressRequestModel.customer.addresses[0].city = e.longName; + } + }); + + await model.addAddressInfo(addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast(message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }).insideContainer); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: showCurrentLocation, + ), ), ); } + checkIsHuawei() async { + isHuawei = await FlutterHmsGmsAvailability.isHmsAvailable; + print(isHuawei); + setState(() {}); + } + + void _getUserLocation() async { + if (await this.sharedPref.getDouble(USER_LAT) != null && await this.sharedPref.getDouble(USER_LONG) != null) { + var lat = await this.sharedPref.getDouble(USER_LAT); + var long = await this.sharedPref.getDouble(USER_LONG); + latitude = lat; + longitude = long; + currentPostion = LatLng(lat, long); + setMap(); + } else { + if (await PermissionService.isLocationEnabled()) { + Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + longitude = value.longitude; + currentPostion = LatLng(latitude, longitude); + setMap(); + }); + } else { + if (Platform.isAndroid) { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () { + Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + longitude = value.longitude; + currentPostion = LatLng(latitude, longitude); + setMap(); + }); + }); + } else { + Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + longitude = value.longitude; + setMap(); + }); + } + } + } + } + setMap() { setState(() { _kGooglePlex = CameraPosition( @@ -227,6 +276,7 @@ class _LocationPageState extends State { } void _updatePosition(CameraPosition _position) { + print(_position); latitude = _position.target.latitude; longitude = _position.target.longitude; } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart index 8614f521..d771f2b5 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart @@ -66,6 +66,9 @@ class _NewHomeHealthCareStepTowPageState extends State _updatePosition(_position)), - // onMapCreated: (GoogleMapController controller) { - // googleMapController = controller; - // _controller.complete(controller); - // }, - // ), - // Icon( - // Icons.place, - // color: CustomColors.accentColor, - // size: 50, - // ), - // ], - // ), - // ), Expanded( child: Stack( alignment: Alignment.center, diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart index 4798b533..5354ff35 100644 --- a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart @@ -382,7 +382,7 @@ class _AnicllaryOrdersState extends State with SingleTic makePayment() { showDraggableDialog(context, PaymentMethod( - onSelectedMethod: (String method) { + onSelectedMethod: (String method, [String selectedInstallmentPlan]) { selectedPaymentMethod = method; print(selectedPaymentMethod); openPayment(selectedPaymentMethod, projectViewModel.authenticatedUserObject.user, double.parse(getTotalValue()), null); diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart index 86c72ae3..a11915da 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart @@ -1,7 +1,6 @@ import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; @@ -52,12 +51,18 @@ class _IdealBodyState extends State { List _heightPopupList = List(); List _weightPopupList = List(); - - void calculateIdealWeight() { - heightInches = int.parse(_heightController.text) * .39370078740157477; - heightFeet = heightInches / 12; - idealWeight = (50 + 2.3 * (heightInches - 60)); + var height = int.parse(_heightController.text); + var weight = double.parse(_weightController.text); + var inchesVal = ((height) * .39370078740157477); + var meters = height / 100; + var feetVal = (inchesVal / 12).floor().round(); + inchesVal = (inchesVal % 12).roundToDouble(); + var kgValue = (weight * 2.2).floor(); + var heightFeet = feetVal; + var heightInches = inchesVal; + weight = kgValue.floorToDouble(); + var idealWeight = (((((heightFeet * 12) + heightInches) - 60) * 6) + 106); if (dropdownValue == TranslationBase.of(context).smallFinger) { idealWeight = idealWeight - 10; } else if (dropdownValue == TranslationBase.of(context).mediumFinger) { @@ -65,18 +70,22 @@ class _IdealBodyState extends State { } else if (dropdownValue == TranslationBase.of(context).largeFinger) { idealWeight = idealWeight + 10; } - - maxIdealWeight = (((idealWeight) * 1.1).round() * 100) / 100; - overWeightBy = weight - maxIdealWeight.roundToDouble(); - minRange = ((idealWeight / 1.1) * 10).round() / 10; - maxRange = maxIdealWeight; - idealWeight = idealWeight; + var maxIdealWeight = (((idealWeight).floorToDouble() * 1.1) * 100).round() / 100; + var overWeightBy = ((weight - double.parse(maxIdealWeight.toString())) * 100).round() / 100; + var difference = (((overWeightBy / 2.2) * 100) / 100).round(); //+ Loc.healthCalPage.IBWKg; Loc.healthCalPage.IBWRange + var minRange = ((idealWeight / 2.2) * 10).round() / 10; + var maxRange = ((maxIdealWeight / 2.2) * 100).round() / 100; //+ //Loc.healthCalPage.IBWKg; + idealWeight = weight / idealWeight; + idealWeight = (idealWeight * 100).round() / 100; + this.overWeightBy = overWeightBy; + this.minRange = minRange; + this.maxRange = maxIdealWeight; + this.idealWeight = idealWeight; } @override Widget build(BuildContext context) { - if(dropdownValue==null) - dropdownValue=TranslationBase.of(context).mediumFinger; + if (dropdownValue == null) dropdownValue = TranslationBase.of(context).mediumFinger; _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; @@ -200,7 +209,8 @@ class _IdealBodyState extends State { child: DropdownButtonHideUnderline( child: DropdownButton( value: dropdownValue, - icon: Icon(Icons.arrow_downward), key: clinicDropdownKey, + icon: Icon(Icons.arrow_downward), + key: clinicDropdownKey, iconSize: 0, elevation: 16, isExpanded: true, @@ -500,5 +510,3 @@ class CommonDropDownView extends StatelessWidget { ); } } - - diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart index a29d4bf0..0477fda4 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body_result_page.dart @@ -5,7 +5,6 @@ import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -33,7 +32,6 @@ class IdealBodyResult extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( padding: const EdgeInsets.all(20.0), child: Column( @@ -60,7 +58,7 @@ class IdealBodyResult extends StatelessWidget { Padding( padding: EdgeInsets.only(top: 8.0, left: 4.0), child: Text( - " "+TranslationBase.of(context).kg+" ", + " " + TranslationBase.of(context).kg + " ", style: TextStyle(color: Colors.red), ), ), @@ -74,13 +72,13 @@ class IdealBodyResult extends StatelessWidget { Row( children: [ Texts( - mixRange.toStringAsFixed(1), + (mixRange / 2.2).toStringAsFixed(1), fontSize: 30.0, ), Padding( padding: EdgeInsets.only(top: 8.0, left: 4.0), child: Text( - " "+TranslationBase.of(context).kg+" ", + " " + TranslationBase.of(context).kg + " ", style: TextStyle(color: Colors.red), ), ), @@ -93,7 +91,7 @@ class IdealBodyResult extends StatelessWidget { ? Column( children: [ Texts( - TranslationBase.of(context).currentWeightPerfect, + TranslationBase.of(context).currentWeightPerfect, fontSize: 20.0, ), ], @@ -108,7 +106,6 @@ class IdealBodyResult extends StatelessWidget { ) : overWeightBy >= 18 ? Container( - child: Column( children: [ Texts( @@ -117,13 +114,21 @@ class IdealBodyResult extends StatelessWidget { SizedBox( height: 12.0, ), - Text( - overWeightBy.toStringAsFixed(1), - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, - letterSpacing: -1.34, - ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Texts( + (overWeightBy / 2.2).toStringAsFixed(1), + fontSize: 30.0, + ), + Padding( + padding: EdgeInsets.only(top: 8.0, left: 4.0), + child: Text( + " " + TranslationBase.of(context).kg + " ", + style: TextStyle(color: Colors.red), + ), + ), + ], ), SizedBox( height: 12.0, @@ -139,7 +144,7 @@ class IdealBodyResult extends StatelessWidget { Padding( padding: const EdgeInsets.all(8.0), child: Texts( - TranslationBase.of(context).underWeight, + TranslationBase.of(context).underWeight, fontSize: 18.0, ), ), @@ -157,7 +162,6 @@ class IdealBodyResult extends StatelessWidget { ], ) : Container( - child: Column( children: [ Text( diff --git a/lib/pages/Blood/advance_payment_page.dart b/lib/pages/Blood/advance_payment_page.dart deleted file mode 100644 index dd3ea666..00000000 --- a/lib/pages/Blood/advance_payment_page.dart +++ /dev/null @@ -1,397 +0,0 @@ -// import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -// import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -// import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; -// import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; -// import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; -// import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; -// import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; -// import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; -// import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; -// import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -// import 'package:diplomaticquarterapp/pages/medical/balance/dialogs/SelectHospitalDialog.dart'; -// import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -// import 'package:diplomaticquarterapp/uitl/app_toast.dart'; -// import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -// import 'package:diplomaticquarterapp/uitl/utils.dart'; -// import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -// import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -// import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -// import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -// import 'package:flutter/cupertino.dart'; -// import 'package:flutter/material.dart'; -// import 'package:smart_progress_bar/smart_progress_bar.dart'; -// -// //import '../../../core/model/my_balance/AdvanceModel.dart'; -// import 'confirm_payment_page.dart'; -// import 'dialogs/SelectBeneficiaryDialog.dart'; -// import 'dialogs/SelectPatientFamilyDialog.dart'; -// import 'dialogs/SelectPatientInfoDialog.dart'; -// import 'new_text_Field.dart'; -// -// enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } -// -// class AdvancePaymentPage extends StatefulWidget { -// @override -// _AdvancePaymentPageState createState() => _AdvancePaymentPageState(); -// } -// -// class _AdvancePaymentPageState extends State { -// TextEditingController _fileTextController = TextEditingController(); -// TextEditingController _notesTextController = TextEditingController(); -// BeneficiaryType beneficiaryType = BeneficiaryType.NON; -// HospitalsModel _selectedHospital; -// String amount = ""; -// String email; -// PatientInfo _selectedPatientInfo; -// AuthenticatedUser authenticatedUser; -// GetAllSharedRecordsByStatusList selectedPatientFamily; -// AdvanceModel advanceModel = AdvanceModel(); -// -// AppSharedPreferences sharedPref = AppSharedPreferences(); -// AuthenticatedUser authUser; -// -// @override -// void initState() { -// super.initState(); -// getAuthUser(); -// } -// -// @override -// Widget build(BuildContext context) { -// return BaseView( -// onModelReady: (model) => model.getHospitals(), -// builder: (_, model, w) => AppScaffold( -// isShowAppBar: true, -// appBarTitle: TranslationBase.of(context).advancePayment, -// body: SingleChildScrollView( -// physics: ScrollPhysics(), -// child: Container( -// margin: EdgeInsets.all(12), -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Texts( -// TranslationBase.of(context).advancePaymentLabel, -// textAlign: TextAlign.center, -// ), -// SizedBox( -// height: 12, -// ), -// InkWell( -// onTap: () => confirmSelectBeneficiaryDialog(model), -// child: Container( -// padding: EdgeInsets.all(12), -// width: double.infinity, -// height: 65, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(12), -// color: Colors.white), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Texts(getBeneficiaryType()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// if (beneficiaryType == BeneficiaryType.MyFamilyFiles) -// SizedBox( -// height: 12, -// ), -// if (beneficiaryType == BeneficiaryType.MyFamilyFiles) -// InkWell( -// onTap: () { -// model.getFamilyFiles().then((value) { -// confirmSelectFamilyDialog(model -// .getAllSharedRecordsByStatusResponse -// .getAllSharedRecordsByStatusList); -// }).showProgressBar( -// text: "Loading", -// backgroundColor: Colors.blue.withOpacity(0.6)); -// }, -// child: Container( -// padding: EdgeInsets.all(12), -// width: double.infinity, -// height: 65, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(12), -// color: Colors.white), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Texts(getFamilyMembersName()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).fileNumber, -// controller: _fileTextController, -// ), -// if (beneficiaryType == BeneficiaryType.OtherAccount) -// SizedBox( -// height: 12, -// ), -// if (beneficiaryType == BeneficiaryType.OtherAccount) -// InkWell( -// onTap: () { -// if (_fileTextController.text.isNotEmpty) -// model -// .getPatientInfoByPatientID( -// id: _fileTextController.text) -// .then((value) { -// confirmSelectPatientDialog(model.patientInfoList); -// }).showProgressBar( -// text: "Loading", -// backgroundColor: -// Colors.blue.withOpacity(0.6)); -// else -// AppToast.showErrorToast( -// message: 'Please Enter The File Number'); -// }, -// child: Container( -// padding: EdgeInsets.all(12), -// width: double.infinity, -// height: 65, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(12), -// color: Colors.white), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Texts(getPatientName()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// InkWell( -// onTap: () => confirmSelectHospitalDialog(model.hospitals), -// child: Container( -// padding: EdgeInsets.all(12), -// width: double.infinity, -// height: 65, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(12), -// color: Colors.white), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// Texts(getHospitalName()), -// Icon(Icons.arrow_drop_down) -// ], -// ), -// ), -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).amount, -// keyboardType: TextInputType.number, -// onChanged: (value) { -// setState(() { -// amount = value; -// }); -// }, -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).depositorEmail, -// initialValue: model.user.emailAddress, -// onChanged: (value) { -// email = value; -// }, -// ), -// SizedBox( -// height: 12, -// ), -// NewTextFields( -// hintText: TranslationBase.of(context).notes, -// controller: _notesTextController, -// ), -// SizedBox( -// height: MediaQuery.of(context).size.height * 0.15, -// ) -// ], -// ), -// ), -// ), -// bottomSheet: Container( -// height: MediaQuery.of(context).size.height * 0.1, -// width: double.infinity, -// padding: EdgeInsets.all(12), -// child: SecondaryButton( -// textColor: Colors.white, -// label: TranslationBase.of(context).submit, -// disabled: amount.isEmpty || -// _fileTextController.text.isEmpty || -// _selectedHospital == null, -// onTap: () { -// advanceModel.fileNumber = _fileTextController.text; -// advanceModel.hospitalsModel = _selectedHospital; -// advanceModel.note = _notesTextController.text; -// advanceModel.email = email ?? model.user.emailAddress; -// advanceModel.amount = amount; -// -// model.getPatientInfoByPatientIDAndMobileNumber().then((value) { -// if (model.state != ViewState.Error && -// model.state != ViewState.ErrorLocal) { -// Utils.hideKeyboard(context); -// Navigator.push( -// context, -// MaterialPageRoute( -// builder: (context) => PaymentMethod())).then( -// (value) { -// Navigator.push( -// context, -// FadePage( -// page: ConfirmPaymentPage( -// advanceModel: advanceModel, -// selectedPaymentMethod: value, -// patientInfoAndMobileNumber: -// model.patientInfoAndMobileNumber, -// authenticatedUser: authUser, -// ), -// ), -// ); -// }, -// ); -// } -// }).showProgressBar( -// text: "Loading", -// backgroundColor: Colors.blue.withOpacity(0.6)); -// }, -// ), -// )), -// ); -// } -// -// void confirmSelectBeneficiaryDialog(MyBalanceViewModel model) { -// showDialog( -// context: context, -// child: SelectBeneficiaryDialog( -// beneficiaryType: beneficiaryType, -// onValueSelected: (value) { -// setState(() { -// if (value == BeneficiaryType.MyAccount) { -// _fileTextController.text = model.user.patientID.toString(); -// advanceModel.depositorName = -// model.user.firstName + " " + model.user.lastName; -// } else -// _fileTextController.text = ""; -// -// beneficiaryType = value; -// }); -// }, -// ), -// ); -// } -// -// void confirmSelectHospitalDialog(List hospitals) { -// showDialog( -// context: context, -// child: SelectHospitalDialog( -// hospitals: hospitals, -// selectedHospital: _selectedHospital, -// onValueSelected: (value) { -// setState(() { -// _selectedHospital = value; -// }); -// }, -// ), -// ); -// } -// -// void confirmSelectPatientDialog(List patientInfoList) { -// showDialog( -// context: context, -// child: SelectPatientInfoDialog( -// patientInfoList: patientInfoList, -// selectedPatientInfo: _selectedPatientInfo, -// onValueSelected: (value) { -// setState(() { -// advanceModel.depositorName = value.fullName; -// _selectedPatientInfo = value; -// }); -// }, -// ), -// ); -// } -// -// void confirmSelectFamilyDialog( -// List getAllSharedRecordsByStatusList) { -// showDialog( -// context: context, -// child: SelectPatientFamilyDialog( -// getAllSharedRecordsByStatusList: getAllSharedRecordsByStatusList, -// selectedPatientFamily: selectedPatientFamily, -// onValueSelected: (value) { -// setState(() { -// selectedPatientFamily = value; -// _fileTextController.text = -// selectedPatientFamily.patientID.toString(); -// advanceModel.depositorName = value.patientName; -// }); -// }, -// ), -// ); -// } -// -// String getBeneficiaryType() { -// switch (beneficiaryType) { -// case BeneficiaryType.MyAccount: -// return TranslationBase.of(context).myAccount; -// case BeneficiaryType.MyFamilyFiles: -// return TranslationBase.of(context).myFamilyFiles; -// break; -// case BeneficiaryType.OtherAccount: -// return TranslationBase.of(context).otherAccount; -// break; -// case BeneficiaryType.NON: -// return TranslationBase.of(context).selectBeneficiary; -// } -// return TranslationBase.of(context).selectBeneficiary; -// } -// -// String getHospitalName() { -// if (_selectedHospital != null) -// return _selectedHospital.name; -// else -// return TranslationBase.of(context).selectHospital; -// } -// -// String getPatientName() { -// if (_selectedPatientInfo != null) -// return _selectedPatientInfo.fullName; -// else -// return TranslationBase.of(context).selectPatientName; -// } -// -// getAuthUser() async { -// if (await this.sharedPref.getObject(USER_PROFILE) != null) { -// var data = AuthenticatedUser.fromJson( -// await this.sharedPref.getObject(USER_PROFILE)); -// setState(() { -// authUser = data; -// }); -// } -// } -// -// String getFamilyMembersName() { -// if (selectedPatientFamily != null) -// return selectedPatientFamily.patientName; -// else -// return TranslationBase.of(context).selectFamilyPatientName; -// } -// } diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 04f50198..706a51d9 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -10,7 +10,6 @@ import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; -import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; @@ -23,7 +22,6 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'book_reminder_page.dart'; @@ -37,8 +35,9 @@ class BookConfirm extends StatefulWidget { String appoDateFormatted = ""; String appoTimeFormatted = ""; bool isLiveCareAppointment; + int initialSlotDuration; - BookConfirm({@required this.doctor, @required this.selectedDate, @required this.isLiveCareAppointment, @required this.selectedTime}); + BookConfirm({@required this.doctor, @required this.selectedDate, @required this.isLiveCareAppointment, @required this.selectedTime, @required this.initialSlotDuration}); DoctorsListService service; PatientShareResponse patientShareResponse; @@ -208,7 +207,7 @@ class _BookConfirmState extends State { if (isLiveCareSchedule != null && isLiveCareSchedule) { insertLiveCareScheduledAppointment(context, widget.doctor); } else { - insertAppointment(context, widget.doctor); + insertAppointment(context, widget.doctor, widget.initialSlotDuration); } }, child: Text(TranslationBase.of(context).bookAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48)), @@ -246,18 +245,19 @@ class _BookConfirmState extends State { ); } - cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) { + cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) async { ConfirmDialog.closeAlertDialog(context); GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); + bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT); service.cancelAppointment(appo, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { Future.delayed(new Duration(milliseconds: 1500), () async { - if (await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) != null && !await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT)) { - insertAppointment(context, widget.doctor); - } else { + if (isLiveCareSchedule != null && isLiveCareSchedule) { insertLiveCareScheduledAppointment(context, widget.doctor); + } else { + insertAppointment(context, widget.doctor, widget.initialSlotDuration); } }); } else { @@ -269,13 +269,13 @@ class _BookConfirmState extends State { }); } - insertAppointment(context, DoctorList docObject) { + insertAppointment(context, DoctorList docObject, int initialSlotDuration) { final timeSlot = DocAvailableAppointments.selectedAppoDateTime; projectViewModel.analytics.appointment.book_appointment_click_confirm(appointment_type: 'regular', dateTime: timeSlot, doctor: widget.doctor); GifLoaderDialogUtils.showMyDialog(context); AppoitmentAllHistoryResultList appo; - widget.service.insertAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, widget.selectedTime, widget.selectedDate, context).then((res) { + widget.service.insertAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, widget.selectedTime, widget.selectedDate, initialSlotDuration, context, null, null, null, projectViewModel).then((res) { if (res['MessageStatus'] == 1) { projectViewModel.analytics.appointment.book_appointment_confirmation_success(appointment_type: 'regular', dateTime: timeSlot, doctor: widget.doctor); AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index e7db06e4..e16c618f 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -47,6 +47,17 @@ class _BookSuccessState extends State { ProjectViewModel projectViewModel; + @override + initState() { + WidgetsBinding.instance.addPostFrameCallback((_) async { + if (widget.patientShareResponse.isLiveCareAppointment && + (widget.patientShareResponse.patientShareWithTax.toString() == "0" || widget.patientShareResponse.patientShareWithTax.toString() == "0.0")) { + setOnlineCheckInForAppointment(); + } + }); + super.initState(); + } + @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); @@ -403,6 +414,24 @@ class _BookSuccessState extends State { return Container(); } + setOnlineCheckInForAppointment() { + DoctorsListService service = new DoctorsListService(); + service.setOnlineCheckInForAppointment(widget.patientShareResponse.appointmentNo.toString(), widget.patientShareResponse.projectID, context).then((res) { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.clinicID = widget.docObject.clinicID; + appo.projectID = widget.docObject.projectID; + appo.appointmentNo = widget.patientShareResponse.appointmentNo; + appo.serviceID = widget.patientShareResponse.serviceID; + appo.isLiveCareAppointment = widget.patientShareResponse.isLiveCareAppointment; + appo.doctorID = widget.patientShareResponse.doctorID; + insertLiveCareVIDARequest(appo, isMoveHome: false); + }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + confirmAppointment(AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); @@ -425,14 +454,13 @@ class _BookSuccessState extends State { }); } - insertLiveCareVIDARequest(AppoitmentAllHistoryResultList appo) { + insertLiveCareVIDARequest(AppoitmentAllHistoryResultList appo, {bool isMoveHome = true}) { DoctorsListService service = new DoctorsListService(); GifLoaderDialogUtils.showMyDialog(context); service.insertVIDARequest(appo.appointmentNo, appo.clinicID, appo.projectID, appo.serviceID, appo.doctorID, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); - navigateToHome(context); + if (isMoveHome) navigateToHome(context); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } @@ -516,6 +544,9 @@ class _BookSuccessState extends State { }); } + String _paymentMethod; + String _amount; + openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, double amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async { widget.browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); @@ -539,6 +570,7 @@ class _BookSuccessState extends State { widget.patientShareResponse.clinicID, widget.patientShareResponse.doctorID, paymentMethod[1]); + _paymentMethod = paymentMethod.first; // } } @@ -572,24 +604,33 @@ class _BookSuccessState extends State { service.checkPaymentStatus(Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), context).then((res) { String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { + createAdvancePayment(res, appo); String txn_ref = res['Merchant_Reference']; - String amount = res['Amount']; + String amount = res['Amount'].toString(); String payment_method = res['PaymentMethod']; final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; projectViewModel.analytics.appointment.payment_success( appointment_type: 'regular', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); - createAdvancePayment(res, appo); } else { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['Response_Message']); + paymentFail("400", res['Response_Message']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); + paymentFail("400", err.toString()); print(err); }); } + paymentFail(String errorCode, errorMessage){ + final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; + projectViewModel.analytics.advancePayments.payment_fail( + appointment_type: 'livecare', payment_method: _paymentMethod, payment_type: 'appointment', clinic: widget.patientShareResponse.clinicName, hospital: "", txn_amount: widget.patientShareResponse.patientShareWithTax.toString(), txn_currency: currency, error_code: errorCode, error_message: errorMessage + ); + } + getApplePayAPQ(AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index 033d360b..eea41c4d 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -154,7 +154,7 @@ class _DoctorProfileState extends State with TickerProviderStateM onTap: (index) { setState(() { if (index == 1) { - if (widget.doctor.clinicID == 17 || widget.doctor.clinicID == 23 || widget.doctor.clinicID == 47 || widget.isLiveCareAppointment) { + if (widget.doctor.clinicID == 23 || widget.doctor.clinicID == 47 || widget.isLiveCareAppointment) { _tabController.index = _tabController.previousIndex; showFooterButton = false; } else { @@ -529,6 +529,7 @@ class _DoctorProfileState extends State with TickerProviderStateM isLiveCareAppointment: widget.isLiveCareAppointment, selectedDate: DocAvailableAppointments.selectedDate, selectedTime: DocAvailableAppointments.selectedTime, + initialSlotDuration: DocAvailableAppointments.initialSlotDuration, ), ), ); diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index 0e7a3dc6..d7d78d89 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; +import 'package:jiffy/jiffy.dart'; import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; @@ -27,6 +28,7 @@ class DocAvailableAppointments extends StatefulWidget { static String selectedTime; bool isLiveCareAppointment; final dynamic doctorSchedule; + static int initialSlotDuration; DocAvailableAppointments({@required this.doctor, this.doctorSchedule, @required this.isLiveCareAppointment}); @@ -231,13 +233,18 @@ class _DocAvailableAppointmentsState extends State wit final DateFormat formatter = DateFormat('HH:mm'); final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); for (var i = 0; i < freeSlotsResponse.length; i++) { - date = DateUtil.convertStringToDate(freeSlotsResponse[i]); + if ((widget.doctor.projectID == 2 && DateTime.now().timeZoneName == "+04") || widget.doctor.projectID == 3 && DateTime.now().timeZoneName == "+04") { + date = Jiffy(DateUtil.convertStringToDate(freeSlotsResponse[i])).subtract(hours: 1).dateTime; + } else { + date = DateUtil.convertStringToDate(freeSlotsResponse[i]); + } slotsList.add(FreeSlot(date, ['slot'])); docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date)); } _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event); setState(() { DocAvailableAppointments.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(freeSlotsResponse[0])); + DocAvailableAppointments.selectedAppoDateTime = DateUtil.convertStringToDate(freeSlotsResponse[0]); selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(DateUtil.convertStringToDate(freeSlotsResponse[0]), language); selectedDateJSON = freeSlotsResponse[0]; }); @@ -291,9 +298,9 @@ class _DocAvailableAppointmentsState extends State wit GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['FreeTimeSlots'].length != 0) { + DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration']; DocAvailableAppointments.areAppointmentsAvailable = true; freeSlotsResponse = res['FreeTimeSlots']; - _getJSONSlots().then((value) { setState(() => { _events.clear(), diff --git a/lib/pages/BookAppointment/components/LaserClinic.dart b/lib/pages/BookAppointment/components/LaserClinic.dart index 37ec070a..8522a915 100644 --- a/lib/pages/BookAppointment/components/LaserClinic.dart +++ b/lib/pages/BookAppointment/components/LaserClinic.dart @@ -184,9 +184,11 @@ class _LaserClinicState extends State with SingleTickerProviderStat Expanded( child: DefaultButton( TranslationBase.of(context).continues, - getDuration() != 0 ? () { - callDoctorsSearchAPI(); - } : null, + getDuration() != 0 + ? () { + callDoctorsSearchAPI(); + } + : null, color: CustomColors.green, disabledColor: CustomColors.grey2, ), @@ -208,6 +210,7 @@ class _LaserClinicState extends State with SingleTickerProviderStat List _patientDoctorAppointmentListHospital = List(); DoctorsListService service = new DoctorsListService(); + projectViewModel.selectedBodyPartList = _selectedBodyPartList; service.getDoctorsList(253, 0, false, context).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { @@ -270,33 +273,14 @@ class _LaserClinicState extends State with SingleTickerProviderStat if (_selectedBodyPartList.length > 0) { duration = _selectedBodyPartList.fold(0, (previousValue, element) => previousValue + int.parse(element.timeDuration)); } - print("duration:$duration"); if (lowerUpperLegsList.length == 2) { duration -= 30; } - print("duration1:$duration"); if (upperLowerArmsList.length == 2) { duration -= 15; } - print("duration2:$duration"); - // for (int i = 0; i < _selectedBodyPartList.length; i++) { - // if ( - // - // (lowerUpperLegsList.length == 2 && (_selectedBodyPartList[i].mappingCode == "47" || _selectedBodyPartList[i].mappingCode == "48")) || - // (upperLowerArmsList.length == 2 && (_selectedBodyPartList[i].mappingCode == "40" || _selectedBodyPartList[i].mappingCode == "41")) - // - // - // ) { - // print("duration:$duration"); - // - // duration += 15; - // print("duration1:$duration"); - // } else { - // duration += int.parse(_selectedBodyPartList[i].timeDuration); - // } - // } - print(duration); _duration = duration; + projectViewModel.laserSelectionDuration = duration; return duration; } @@ -378,6 +362,9 @@ class _LaserClinicState extends State with SingleTickerProviderStat setState(() { if (value) { _selectedBodyPartList.clear(); + _selectedBodyPartList.add(fullBody); + } else { + _selectedBodyPartList.clear(); } _isFullBody = !_isFullBody; }); diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 6aad6b69..1b8641a0 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -534,7 +534,7 @@ class _SearchByClinicState extends State { Navigator.push( context, FadePage( - page: LiveCareBookAppointment(clinicName: "Family Medicine", liveCareClinicID: dropdownValue.split("-")[2], liveCareServiceID: dropdownValue.split("-")[3]), + page: LiveCareBookAppointment(clinicName: dropdownTitle, liveCareClinicID: dropdownValue.split("-")[2], liveCareServiceID: dropdownValue.split("-")[3]), ), ).then((value) { setState(() { diff --git a/lib/pages/BookAppointment/widgets/reminder_dialog.dart b/lib/pages/BookAppointment/widgets/reminder_dialog.dart index 3e6c0450..89ce6699 100644 --- a/lib/pages/BookAppointment/widgets/reminder_dialog.dart +++ b/lib/pages/BookAppointment/widgets/reminder_dialog.dart @@ -22,7 +22,7 @@ Future> requestPermissions() async { showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, {Function onSuccess, String title, String description, Function(int) onMultiDateSuccess}) async { if (Platform.isAndroid) { - if (await PermissionService.isCameraEnabled()) { + if (await PermissionService.isCalendarPermissionEnabled()) { _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess); } else { diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart index b4db054d..f4f73d49 100644 --- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -435,7 +435,7 @@ class _CovidTimeSlotsState extends State with TickerProviderStat DoctorsListService service = new DoctorsListService(); AppoitmentAllHistoryResultList appo; service - .insertAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, CovidTimeSlots.selectedTime, CovidTimeSlots.selectedDate, context, widget.selectedProcedure.procedureID, + .insertAppointment(docObject.doctorID, docObject.clinicID, docObject.projectID, CovidTimeSlots.selectedTime, CovidTimeSlots.selectedDate, 0, context, widget.selectedProcedure.procedureID, widget.selectedProject.testTypeEnum, widget.selectedProject.testProcedureEnum) .then((res) { if (res['MessageStatus'] == 1) { diff --git a/lib/pages/Covid-DriveThru/covid-payment-details.dart b/lib/pages/Covid-DriveThru/covid-payment-details.dart index 7f2ba582..1e48f3c9 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-details.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-details.dart @@ -12,6 +12,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class CovidPaymentDetails extends StatefulWidget { CovidPaymentInfoResponse covidPaymentInfoResponse; @@ -193,14 +194,19 @@ class _CovidPaymentDetailsState extends State { ), ), mWidth(3), - Text( - TranslationBase.of(context).termsConditoins, - style: TextStyle( - fontSize: 12, - letterSpacing: -0.48, - color: CustomColors.accentColor, - fontWeight: FontWeight.w600, - decoration: TextDecoration.underline, + InkWell( + onTap: () { + launch("https://hmg.com/en/Pages/Privacy.aspx"); + }, + child: Text( + TranslationBase.of(context).termsConditoins, + style: TextStyle( + fontSize: 12, + letterSpacing: -0.48, + color: CustomColors.accentColor, + fontWeight: FontWeight.w600, + decoration: TextDecoration.underline, + ), ), ), ], diff --git a/lib/pages/DrawerPages/notifications/notification_details_page.dart b/lib/pages/DrawerPages/notifications/notification_details_page.dart index ed31b3fc..4c5144ef 100644 --- a/lib/pages/DrawerPages/notifications/notification_details_page.dart +++ b/lib/pages/DrawerPages/notifications/notification_details_page.dart @@ -33,6 +33,7 @@ class NotificationsDetailsPage extends StatelessWidget { isShowAppBar: true, showNewAppBar: true, showNewAppBarTitle: true, + isShowDecPage: false, appBarTitle: TranslationBase.of(context).notificationDetails, body: ListView( physics: BouncingScrollPhysics(), @@ -49,7 +50,6 @@ class NotificationsDetailsPage extends StatelessWidget { letterSpacing: -0.64, ), ), - if (notification.messageTypeData.length != 0) Padding( padding: const EdgeInsets.only(top: 18), @@ -64,7 +64,6 @@ class NotificationsDetailsPage extends StatelessWidget { ); }, fit: BoxFit.fill), ), - SizedBox(height: 18), Text( notification.message.trim(), @@ -75,7 +74,6 @@ class NotificationsDetailsPage extends StatelessWidget { letterSpacing: -0.48, ), ), - ], ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart index 67d2f979..34340e0c 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/er/PatientER_RC.dart'; import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/ambulanceRequest/locationDetails.dart'; import 'package:diplomaticquarterapp/pages/ErService/widgets/AppointmentCard.dart'; import 'package:diplomaticquarterapp/uitl/ProgressDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; @@ -11,7 +12,6 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; @@ -19,7 +19,6 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import '../AvailableAppointmentsPage.dart'; @@ -44,7 +43,7 @@ class _PickupLocationState extends State { double _longitude; AppoitmentAllHistoryResultList myAppointment; HospitalsModel _selectedHospital; - PickResult _result; + LocationDetails _result; @override void initState() { @@ -496,15 +495,15 @@ class _PickupLocationState extends State { setState(() { widget.patientER_RC.transportationDetails.pickupSpot = _isInsideHome ? 1 : 0; if (widget.patientER_RC.transportationDetails.direction == 0) { - widget.patientER_RC.transportationDetails.dropoffLatitude = _result.geometry.location.lat.toString(); - widget.patientER_RC.transportationDetails.dropoffLongitude = _result.geometry.location.lng.toString(); + widget.patientER_RC.transportationDetails.dropoffLatitude = _result.lat.toStringAsFixed(6); + widget.patientER_RC.transportationDetails.dropoffLongitude = _result.long.toStringAsFixed(6); widget.patientER_RC.transportationDetails.pickupLatitude = _selectedHospital.latitude; widget.patientER_RC.transportationDetails.pickupLongitude = _selectedHospital.longitude; } else { widget.patientER_RC.transportationDetails.pickupLatitude = _selectedHospital.latitude; widget.patientER_RC.transportationDetails.pickupLongitude = _selectedHospital.longitude; - widget.patientER_RC.transportationDetails.dropoffLatitude = _result.geometry.location.lat.toString(); - widget.patientER_RC.transportationDetails.dropoffLongitude = _result.geometry.location.lng.toString(); + widget.patientER_RC.transportationDetails.dropoffLatitude = _result.lat.toStringAsFixed(6); + widget.patientER_RC.transportationDetails.dropoffLongitude = _result.long.toStringAsFixed(6); } // widget.patientER.latitude = diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index 901e6c6c..d4a1d367 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -1,3 +1,6 @@ +import 'dart:collection'; + +import 'package:device_calendar/device_calendar.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; @@ -11,6 +14,7 @@ import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; @@ -94,23 +98,30 @@ class _AppointmentDetailsState extends State with SingleTick children: [ DoctorHeader( headerModel: HeaderModel( - widget.appo.doctorTitle + " " + widget.appo.doctorNameObj, - widget.appo.doctorID, - widget.appo.doctorImageURL, - widget.appo.doctorSpeciality, - "", - widget.appo.projectName, - DateUtil.convertStringToDate(widget.appo.appointmentDate), - widget.appo.startTime.substring(0, 5), - null, - widget.appo.doctorRate, - widget.appo.actualDoctorRate, - widget.appo.noOfPatientsRate, - "", - decimalDoctorRate: widget.appo.decimalDoctorRate.toString() - //model.user.emailAddress, - ), - isNeedToShowButton: (widget.appo.clinicID == 17 || widget.appo.clinicID == 47 || widget.appo.clinicID == 23 || widget.appo.clinicID == 265 || widget.appo.isExecludeDoctor || widget.appo.isLiveCareAppointment) ? false : true, + widget.appo.doctorTitle + " " + widget.appo.doctorNameObj, + widget.appo.doctorID, + widget.appo.doctorImageURL, + widget.appo.doctorSpeciality, + "", + widget.appo.projectName, + DateUtil.convertStringToDate(widget.appo.appointmentDate), + widget.appo.startTime.substring(0, 5), + null, + widget.appo.doctorRate, + widget.appo.actualDoctorRate, + widget.appo.noOfPatientsRate, + "", + decimalDoctorRate: widget.appo.decimalDoctorRate.toString() + //model.user.emailAddress, + ), + isNeedToShowButton: (widget.appo.clinicID == 17 || + widget.appo.clinicID == 47 || + widget.appo.clinicID == 23 || + widget.appo.clinicID == 265 || + widget.appo.isExecludeDoctor || + widget.appo.isLiveCareAppointment) + ? false + : true, buttonTitle: TranslationBase.of(context).schedule, buttonIcon: 'assets/images/new/Boo_ Appointment.svg', showConfirmMessageDialog: false, @@ -139,7 +150,12 @@ class _AppointmentDetailsState extends State with SingleTick onTap: (index) { setState(() { if (index == 1) { - if (widget.appo.clinicID == 17 || widget.appo.clinicID == 47 || widget.appo.clinicID == 23 || widget.appo.clinicID == 265 || widget.appo.isExecludeDoctor || widget.appo.isLiveCareAppointment) { + if (widget.appo.clinicID == 17 || + widget.appo.clinicID == 47 || + widget.appo.clinicID == 23 || + widget.appo.clinicID == 265 || + widget.appo.isExecludeDoctor || + widget.appo.isLiveCareAppointment) { _tabController.index = _tabController.previousIndex; AppointmentDetails.showFooterButton = false; } else { @@ -150,7 +166,12 @@ class _AppointmentDetailsState extends State with SingleTick }, tabs: [ Tab(child: Text(TranslationBase.of(context).appoActions, style: TextStyle(color: Colors.black))), - widget.appo.clinicID == 17 || widget.appo.clinicID == 23 || widget.appo.clinicID == 47 || widget.appo.clinicID == 265 || widget.appo.isExecludeDoctor || widget.appo.isLiveCareAppointment + widget.appo.clinicID == 17 || + widget.appo.clinicID == 23 || + widget.appo.clinicID == 47 || + widget.appo.clinicID == 265 || + widget.appo.isExecludeDoctor || + widget.appo.isLiveCareAppointment ? Tab( child: Text(TranslationBase.of(context).availableAppo, style: TextStyle(color: Colors.grey)), ) @@ -563,15 +584,31 @@ class _AppointmentDetailsState extends State with SingleTick }); } + checkIfHasReminder() async { + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + + DateTime startEventsDate = DateUtil.convertStringToDate(widget.appo.appointmentDate); + DateTime endEventsDate = DateUtil.convertStringToDate(widget.appo.appointmentDate); + + RetrieveEventsParams params = new RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate); + + await calendarUtils.retrieveEvents(calendarUtils.calendars[0].id, params).then((value) { + Result> events = value; + events.data.forEach((element) { + if (element.title.contains(widget.appo.doctorNameObj)) calendarUtils.deleteEvent(calendarUtils.calendars[0], element); + }); + }); + } + cancelAppointment() { ConfirmDialog.closeAlertDialog(context); GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service.cancelAppointment(widget.appo, context).then((res) { - projectViewModel.analytics.appointment.appointment_details_cancel(appointment: widget.appo); GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { + checkIfHasReminder(); getToDoCount(); AppToast.showSuccessToast(message: res['ErrorEndUserMessage']); Navigator.of(context).pop(); diff --git a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart index 477d0736..f1b97146 100644 --- a/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart +++ b/lib/pages/ToDoList/ObGyne/ObGyne-TimeSlots.dart @@ -359,7 +359,7 @@ class _CovidTimeSlotsState extends State with TickerProviderSta AppoitmentAllHistoryResultList appo; service .insertAppointment( - docObject.doctorID, docObject.clinicID, docObject.projectID, ObGyneTimeSlots.selectedTime, ObGyneTimeSlots.selectedDate, context, widget.obGyneProcedureListResponse.procedureId) + docObject.doctorID, docObject.clinicID, docObject.projectID, ObGyneTimeSlots.selectedTime, ObGyneTimeSlots.selectedDate, 0, context, widget.obGyneProcedureListResponse.procedureId) .then((res) { if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 1dfe7110..5dacf8db 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -214,7 +214,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { borderRadius: BorderRadius.circular(6), ), child: Text( - getNextActionText(widget.appoList[index].nextAction), + getNextActionText(widget.appoList[index].nextAction), textAlign: TextAlign.center, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4), ), ), @@ -247,7 +247,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { children: [ MyRichText(TranslationBase.of(context).clinic + ": ", widget.appoList[index].clinicName, projectViewModel.isArabic), MyRichText(TranslationBase.of(context).appointmentDate + ": ", - DateUtil.getDayMonthYearHourMinuteDateFormatted(DateUtil.convertStringToDate(widget.appoList[index].appointmentDate)), projectViewModel.isArabic), + DateUtil.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(widget.appoList[index].appointmentDate)) + " " + widget.appoList[index].startTime.substring(0, 5), projectViewModel.isArabic), MyRichText(TranslationBase.of(context).branch, widget.appoList[index].projectName, projectViewModel.isArabic), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/pages/ToDoList/payment_method_select.dart b/lib/pages/ToDoList/payment_method_select.dart index b76ac855..46cad3aa 100644 --- a/lib/pages/ToDoList/payment_method_select.dart +++ b/lib/pages/ToDoList/payment_method_select.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:diplomaticquarterapp/core/model/my_balance/tamara_installment_details.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; @@ -9,6 +10,7 @@ import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; class PaymentMethod extends StatefulWidget { Function onSelectedMethod; @@ -27,6 +29,7 @@ class _PaymentMethodState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).paymentMethod, isShowAppBar: true, @@ -45,153 +48,157 @@ class _PaymentMethodState extends State { margin: EdgeInsets.fromLTRB(4, 15.0, 4, 0.0), child: Text(TranslationBase.of(context).selectPaymentOption, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)), ), - Container( - width: double.infinity, - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("MADA"); - }, - child: Card( - elevation: 0.0, - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: selectedPaymentMethod == "MADA" ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), - ), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Row( - children: [ - Container( - width: 24, - height: 24, - decoration: containerColorRadiusBorderWidth(selectedPaymentMethod == "MADA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), - ), - mWidth(12), - Container( - height: 70.0, - width: 70.0, - padding: EdgeInsets.all(7.0), - child: Image.asset("assets/images/new/payment/Mada.png"), - ), - mFlex(1), - if (selectedPaymentMethod == "MADA") + if (projectViewModel.havePrivilege(86)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("MADA"); + }, + child: Card( + elevation: 0.0, + margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: selectedPaymentMethod == "MADA" ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + children: [ Container( - decoration: containerRadius(CustomColors.green, 200), - padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), - child: Text( - TranslationBase.of(context).paymentSelected, - style: TextStyle( - color: Colors.white, - fontSize: 11, + width: 24, + height: 24, + decoration: containerColorRadiusBorderWidth(selectedPaymentMethod == "MADA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(12), + Container( + height: 70.0, + width: 70.0, + padding: EdgeInsets.all(7.0), + child: Image.asset("assets/images/new/payment/Mada.png"), + ), + mFlex(1), + if (selectedPaymentMethod == "MADA") + Container( + decoration: containerRadius(CustomColors.green, 200), + padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), + child: Text( + TranslationBase.of(context).paymentSelected, + style: TextStyle( + color: Colors.white, + fontSize: 11, + ), ), ), - ), - ], + ], + ), ), ), ), ), - ), - Container( - width: double.infinity, - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("VISA"); - }, - child: Card( - elevation: 0.0, - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: selectedPaymentMethod == "VISA" ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), - ), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Row( - children: [ - Container( - width: 24, - height: 24, - decoration: containerColorRadiusBorderWidth(selectedPaymentMethod == "VISA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), - ), - mWidth(12), - Container( - height: 60.0, - padding: EdgeInsets.all(7.0), - width: 60, - child: Image.asset("assets/images/new/payment/visa.png"), - ), - mFlex(1), - if (selectedPaymentMethod == "VISA") + if (projectViewModel.havePrivilege(87)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("VISA"); + }, + child: Card( + elevation: 0.0, + margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: selectedPaymentMethod == "VISA" ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + children: [ Container( - decoration: containerRadius(CustomColors.green, 200), - padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), - child: Text( - TranslationBase.of(context).paymentSelected, - style: TextStyle( - color: Colors.white, - fontSize: 11, + width: 24, + height: 24, + decoration: containerColorRadiusBorderWidth(selectedPaymentMethod == "VISA" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(12), + Container( + height: 60.0, + padding: EdgeInsets.all(7.0), + width: 60, + child: Image.asset("assets/images/new/payment/visa.png"), + ), + mFlex(1), + if (selectedPaymentMethod == "VISA") + Container( + decoration: containerRadius(CustomColors.green, 200), + padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), + child: Text( + TranslationBase.of(context).paymentSelected, + style: TextStyle( + color: Colors.white, + fontSize: 11, + ), ), ), - ), - ], + ], + ), ), ), ), ), - ), - Container( - width: double.infinity, - child: InkWell( - onTap: () { - updateSelectedPaymentMethod("MASTERCARD"); - }, - child: Card( - elevation: 0.0, - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - side: selectedPaymentMethod == "MASTERCARD" ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), - ), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Row( - children: [ - Container( - width: 24, - height: 24, - decoration: containerColorRadiusBorderWidth(selectedPaymentMethod == "MASTERCARD" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), - ), - mWidth(12), - Container( - height: 60.0, - padding: EdgeInsets.all(7.0), - width: 60, - child: Image.asset("assets/images/new/payment/Mastercard.png"), - ), - mFlex(1), - if (selectedPaymentMethod == "MASTERCARD") + if (projectViewModel.havePrivilege(88)) + Container( + width: double.infinity, + child: InkWell( + onTap: () { + updateSelectedPaymentMethod("MASTERCARD"); + }, + child: Card( + elevation: 0.0, + margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: selectedPaymentMethod == "MASTERCARD" ? BorderSide(color: Colors.green, width: 2.0) : BorderSide(color: Colors.transparent, width: 0.0), + ), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + children: [ Container( - decoration: containerRadius(CustomColors.green, 200), - padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), - child: Text( - TranslationBase.of(context).paymentSelected, - style: TextStyle( - color: Colors.white, - fontSize: 11, + width: 24, + height: 24, + decoration: containerColorRadiusBorderWidth(selectedPaymentMethod == "MASTERCARD" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5), + ), + mWidth(12), + Container( + height: 60.0, + padding: EdgeInsets.all(7.0), + width: 60, + child: Image.asset("assets/images/new/payment/Mastercard.png"), + ), + mFlex(1), + if (selectedPaymentMethod == "MASTERCARD") + Container( + decoration: containerRadius(CustomColors.green, 200), + padding: EdgeInsets.only(top: 6, bottom: 6, left: 12, right: 12), + child: Text( + TranslationBase.of(context).paymentSelected, + style: TextStyle( + color: Colors.white, + fontSize: 11, + ), ), ), - ), - ], + ], + ), ), ), ), ), - ), + if (projectViewModel.havePrivilege(90)) // Container( // width: double.infinity, // child: InkWell( @@ -241,7 +248,7 @@ class _PaymentMethodState extends State { // ), // ), // ), - if (widget.isShowInstallments) + if (widget.isShowInstallments && projectViewModel.havePrivilege(91)) Container( width: double.infinity, child: InkWell( @@ -292,7 +299,7 @@ class _PaymentMethodState extends State { ), ), ), - Platform.isIOS + (Platform.isIOS && projectViewModel.havePrivilege(89)) ? Container( width: double.infinity, child: InkWell( @@ -321,7 +328,9 @@ class _PaymentMethodState extends State { height: 60.0, padding: EdgeInsets.all(7.0), width: 60, - child: Image.asset("assets/images/new/payment/Apple_Pay.png"), + child: SvgPicture.asset( + "assets/images/new/payment/Apple_Pay.svg", + ), ), mFlex(1), if (selectedPaymentMethod == "ApplePay") diff --git a/lib/pages/feedback/send_feedback_page.dart b/lib/pages/feedback/send_feedback_page.dart index 6e879612..be91c099 100644 --- a/lib/pages/feedback/send_feedback_page.dart +++ b/lib/pages/feedback/send_feedback_page.dart @@ -6,19 +6,18 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; -import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/bottom_options/BottomSheet.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/floating_button_search.dart'; import 'package:flutter/cupertino.dart'; @@ -32,6 +31,7 @@ import 'package:speech_to_text/speech_to_text.dart' as stt; class SendFeedbackPage extends StatefulWidget { final AppoitmentAllHistoryResultList appointment; final MessageType messageType; + const SendFeedbackPage({Key key, this.appointment, this.messageType = MessageType.NON}) : super(key: key); @override @@ -93,11 +93,11 @@ class _SendFeedbackPageState extends State { this.messageType = widget.messageType; this.appointHistory = widget.appointment; }); - requestPermissions(); + // requestPermissions(); event.controller.stream.listen((p) { if (p['isIOSFeedback'] == 'true') { if (this.mounted) { - this.titleController.value = p['data']; + this.titleController.value = p['data']; } } }); @@ -217,8 +217,18 @@ class _SendFeedbackPageState extends State { ), inputWidget(TranslationBase.of(context).subject, "", titleController), SizedBox(height: 12), - inputWidget(TranslationBase.of(context).message, "", messageController, lines: 11, suffixTap: () { - openSpeechReco(); + inputWidget(TranslationBase.of(context).message, "", messageController, lines: 11, suffixTap: () async { + if (Platform.isAndroid) { + if (await PermissionService.isMicrophonePermissionEnabled()) { + openSpeechReco(); + } else { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).recordAudioPermission, () { + openSpeechReco(); + }); + } + } else { + openSpeechReco(); + } }), SizedBox(height: 12), InkWell( @@ -536,7 +546,6 @@ class _SendFeedbackPageState extends State { Map statuses = await [ Permission.microphone, ].request(); - print(statuses); } void resultListener(result) { @@ -548,7 +557,6 @@ class _SendFeedbackPageState extends State { messageController.text += reconizedWord + '\n'; RoboSearch.closeAlertDialog(context); speech.stop(); - }); } } @@ -558,4 +566,4 @@ class _SendFeedbackPageState extends State { print(hasSpeech); if (!mounted) return; } -} \ No newline at end of file +} diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index 4d95694d..6828b56f 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -284,7 +284,7 @@ class _HomePageFragment2State extends State { } Widget offersButton() { - final bypassPrivilageCheck = true; + final bypassPrivilageCheck = false; return Expanded( flex: 1, child: InkWell( diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index a939eea2..2278bdf0 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; @@ -21,9 +23,9 @@ import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart' as family; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; -import 'package:diplomaticquarterapp/uitl/HMGNetworkConnectivity.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; @@ -37,6 +39,9 @@ import 'package:diplomaticquarterapp/widgets/others/not_auh_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart'; +import 'package:flutter_ios_voip_kit/call_state_type.dart'; +import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -91,6 +96,35 @@ class _LandingPageState extends State with WidgetsBindingObserver { var event = RobotProvider(); var familyFileProvider = family.FamilyFilesProvider(); + // VoIPKit + final voIPKit = FlutterIOSVoIPKit.instance; + var dummyCallId = '123456'; + var dummyCallerName = 'Dummy Tester'; + Timer timeOutTimer; + bool isTalking = false; + + var sharedPref = new AppSharedPreferences(); + + var data = { + "AppointmentNo": "2016059247", + "ProjectID": "15", + "NotificationType": "10", + "background": "0", + "doctorname": "Call from postman", + "clinicname": "LIVECARE FAMILY MEDICINE AND GP", + "speciality": "General Practioner", + "appointmentdate": "2022-01-19", + "appointmenttime": "12:10", + "PatientName": "Testing", + "session_id": "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg", + "token": + "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", + "callerID": "9920", + "PatientID": "1231755", + "is_call": "true" + }; + void _requestIOSPermissions() { flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions( alert: true, @@ -99,6 +133,24 @@ class _LandingPageState extends State with WidgetsBindingObserver { ); } + void _showRequestAuthLocalNotification() async { + await voIPKit.requestAuthLocalNotification(); + } + + void _timeOut({ + int seconds = 15, + }) async { + timeOutTimer = Timer(Duration(seconds: seconds), () async { + print('🎈 example: timeOut'); + final incomingCallerName = await voIPKit.getIncomingCallerName(); + voIPKit.unansweredIncomingCall( + skipLocalNotification: false, + missedCallTitle: '📞 Missed call', + missedCallBody: 'There was a call from $incomingCallerName', + ); + }); + } + bool isPageNavigated = false; LocationUtils locationUtils; @@ -232,12 +284,81 @@ class _LandingPageState extends State with WidgetsBindingObserver { void initState() { super.initState(); PushNotificationHandler.getInstance().onResume(); + + // // VoIP Callbacks + // voIPKit.getVoIPToken().then((value) { + // print('🎈 example: getVoIPToken: $value'); + // sharedPref.setString("VOIPToken", value); + // }); + // + // voIPKit.onDidReceiveIncomingPush = ( + // Map payload, + // ) async { + // print('🎈 example: onDidReceiveIncomingPush $payload'); + // _timeOut(); + // }; + // + // voIPKit.onDidRejectIncomingCall = ( + // String uuid, + // String callerId, + // ) { + // if (isTalking) { + // return; + // } + // + // print('🎈 example: onDidRejectIncomingCall $uuid, $callerId'); + // voIPKit.endCall(); + // timeOutTimer?.cancel(); + // + // setState(() { + // isTalking = false; + // }); + // }; + // + // voIPKit.onDidAcceptIncomingCall = ( + // String uuid, + // String callerId, + // ) { + // // print('🎈 example: isTalking $isTalking'); + // // if (isTalking) { + // // return; + // // } + // + // print('🎈 example: onDidAcceptIncomingCall $uuid, $callerId'); + // + // var sessionID; + // var token; + // + // // String sessionID = callerId.split("*")[0]; + // // String identity = callerId.split("*")[1]; + // // String name = callerId.split("*")[2]; + // // + // // print("🎈 SessionID: $sessionID"); + // // print("🎈 Identity: $identity"); + // // print("🎈 Name: $name"); + // + // voIPKit.acceptIncomingCall(callerState: CallStateType.calling); + // voIPKit.callConnected(); + // timeOutTimer?.cancel(); + // + // print("🎈 CALL ACCEPTED!!!"); + // // print("🎈 Identity: $identity"); + // // print("🎈 Name: $name"); + // + // setState(() { + // isTalking = true; + // }); + // }; + // + // _showRequestAuthLocalNotification(); + WidgetsBinding.instance.addObserver(this); AppGlobal.context = context; _requestIOSPermissions(); pageController = PageController(keepPage: true); + _firebaseMessaging.setAutoInitEnabled(true); // locationUtils = new LocationUtils(isShowConfirmDialog: false, context: context); @@ -249,7 +370,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { // HMG (Guest/Internet) Wifi Access [Zohaib Kambrani] // for now commented to reduce this call will enable it when needed - HMGNetworkConnectivity(context).start(); + // HMGNetworkConnectivity(context).start(); + _firebaseMessaging.getToken().then((String token) { print("Firebase Token: " + token); sharedPref.setString(PUSH_TOKEN, token); @@ -572,6 +694,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); model.setState(model.count, true, notificationCount); sharedPref.setString(NOTIFICATION_COUNT, notificationCount); + FlutterAppIconBadge.updateBadge(num.parse(notificationCount)); } }), }); diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart index da40b985..9903835f 100644 --- a/lib/pages/landing/widgets/services_view.dart +++ b/lib/pages/landing/widgets/services_view.dart @@ -281,7 +281,6 @@ class ServicesView extends StatelessWidget { showCovidDialog(BuildContext context) { if (Platform.isAndroid) { - // Utils.showPermissionConsentDialog(context, "", () {}); showDialog( context: context, builder: (cxt) => CovidConsentDialog( diff --git a/lib/pages/livecare/incoming_call.dart b/lib/pages/livecare/incoming_call.dart index 66593df4..af6d7a5d 100644 --- a/lib/pages/livecare/incoming_call.dart +++ b/lib/pages/livecare/incoming_call.dart @@ -39,11 +39,6 @@ class _IncomingCallState extends State with SingleTickerProviderSt isCameraReady = false; WidgetsBinding.instance.addPostFrameCallback((_) => _runAnimation()); - // - // print(widget.incomingCallData.doctorname); - // print(widget.incomingCallData.clinicname); - // print(widget.incomingCallData.speciality); - super.initState(); } diff --git a/lib/pages/livecare/live_care_payment_page.dart b/lib/pages/livecare/live_care_payment_page.dart index 54aeffbf..4ae09885 100644 --- a/lib/pages/livecare/live_care_payment_page.dart +++ b/lib/pages/livecare/live_care_payment_page.dart @@ -1,14 +1,20 @@ +import 'dart:io'; + import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/ERAppointmentFeesResponse.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class LiveCarePatmentPage extends StatefulWidget { GetERAppointmentFeesList getERAppointmentFeesList; @@ -40,7 +46,6 @@ class _LiveCarePatmentPageState extends State { description: TranslationBase.of(context).erConsultation, body: Container( width: double.infinity, - height: double.infinity, child: Column( children: [ @@ -226,13 +231,18 @@ class _LiveCarePatmentPageState extends State { ), ), mWidth(4), - Text( - TranslationBase.of(context).termsConditoins, - style: new TextStyle( - fontSize: 12.0, - fontWeight: FontWeight.w600, - letterSpacing: -0.48, - color: CustomColors.accentColor, + InkWell( + onTap: () { + launch("https://hmg.com/en/Pages/Privacy.aspx"); + }, + child: Text( + TranslationBase.of(context).termsConditoins, + style: new TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + color: CustomColors.accentColor, + ), ), ), ], @@ -251,8 +261,6 @@ class _LiveCarePatmentPageState extends State { margin: EdgeInsets.fromLTRB(10.0, 5.0, 10.0, 5.0), child: getPaymentMethods(), ), - - ], ), ), @@ -266,7 +274,7 @@ class _LiveCarePatmentPageState extends State { Expanded( child: DefaultButton( TranslationBase.of(context).cancel, - () { + () { Navigator.pop(context, false); }, ), @@ -275,12 +283,24 @@ class _LiveCarePatmentPageState extends State { Expanded( child: DefaultButton( TranslationBase.of(context).next, - () { + () { if (_selected == 0) { AppToast.showErrorToast(message: TranslationBase.of(context).pleaseAcceptTerms); } else { - projectViewModel.analytics.liveCare.livecare_immediate_consultation_TnC(clinic: widget.clinicName); - Navigator.pop(context, true); + askVideoCallPermission().then((value) async { + if (value) { + if (Platform.isAndroid && !(await PlatformBridge.shared().isDrawOverAppsPermissionAllowed())) { + await drawOverAppsMessageDialog(context).then((value) { + return false; + }); + } else { + projectViewModel.analytics.liveCare.livecare_immediate_consultation_TnC(clinic: widget.clinicName); + Navigator.pop(context, true); + } + } else { + openPermissionsDialog(); + } + }); } }, color: CustomColors.green, @@ -295,6 +315,41 @@ class _LiveCarePatmentPageState extends State { ); } + Future askVideoCallPermission() async { + if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { + return false; + } + return true; + } + + openPermissionsDialog() { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).liveCarePermissions, + okText: TranslationBase.of(context).settings, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + openAppSettings(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + + Future drawOverAppsMessageDialog(BuildContext context) async { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: TranslationBase.of(context).drawOverAppsPermission, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, + okFunction: () async { + await PlatformBridge.shared().askDrawOverAppsPermission(); + Navigator.pop(context); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + } + void onRadioChanged(int value) { setState(() { _selected = value; diff --git a/lib/pages/livecare/livecare_home.dart b/lib/pages/livecare/livecare_home.dart index 396b629d..653a5fc8 100644 --- a/lib/pages/livecare/livecare_home.dart +++ b/lib/pages/livecare/livecare_home.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryResponse.dart'; @@ -5,6 +6,7 @@ import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePendingReque import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_list.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/livecare_logs.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -31,12 +33,13 @@ class _LiveCareHomeState extends State with SingleTickerProviderSt ErRequestHistoryList pendingERRequestHistoryList; ProjectViewModel projectViewModel; + AppSharedPreferences sharedPref = AppSharedPreferences(); @override void initState() { _tabController = new TabController(length: 2, vsync: this); erRequestHistoryList = List(); - + LiveCareHome.isLiveCareTypeSelected = false; pendingERRequestHistoryList = new ErRequestHistoryList(); imagesInfo.add(ImagesInfo( imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/er-consultation_en/en/0.png', imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/er-consultation_ar/ar/0.png')); @@ -47,6 +50,13 @@ class _LiveCareHomeState extends State with SingleTickerProviderSt super.initState(); } + @override + void dispose() { + LiveCareHome.isLiveCareTypeSelected = false; + sharedPref.remove(LIVECARE_CLINIC_DATA); + super.dispose(); + } + @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index fb5f1e0f..4c350123 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -122,7 +122,7 @@ class _LiveCareTypeSelectState extends State { } }, child: Container( - padding: EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), + padding: EdgeInsets.only(left: 20, right: 20, bottom: 3, top: 28), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: Colors.white, diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index b7978ea2..74d25f5a 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -59,7 +59,7 @@ class _clinic_listState extends State { var languageID; var currentSelectedLiveCareType; - int selectedClinicID = 1; + int selectedClinicID; String selectedClinicName = "-"; AppSharedPreferences sharedPref = AppSharedPreferences(); @@ -190,15 +190,21 @@ class _clinic_listState extends State { navigateTo(context, LiveCarePatmentPage(getERAppointmentFeesList: getERAppointmentFeesList, waitingTime: waitingTime, clinicName: selectedClinicName)).then( (value) { if (value) { - askVideoCallPermission().then((value) { - if (value) { - if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { - showLiveCareInfoDialog(getERAppointmentFeesList); - } else { - navigateToPaymentMethod(getERAppointmentFeesList, context); - } - } - }); + if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { + addNewCallForPatientER(projectViewModel.user.patientID.toString() + "" + DateTime.now().millisecondsSinceEpoch.toString()); + } else { + navigateToPaymentMethod(getERAppointmentFeesList, context); + } + + // askVideoCallPermission().then((value) { + // if (value) { + // if (getERAppointmentFeesList.total == "0" || getERAppointmentFeesList.total == "0.0") { + // addNewCallForPatientER(projectViewModel.user.patientID.toString() + "" + DateTime.now().millisecondsSinceEpoch.toString()); + // } else { + // navigateToPaymentMethod(getERAppointmentFeesList, context); + // } + // } + // }); } }, ); @@ -290,11 +296,15 @@ class _clinic_listState extends State { }); } + String _paymentMethod; + String _amount; openPayment(List paymentMethod, AuthenticatedUser authenticatedUser, double amount, AppoitmentAllHistoryResultList appo) { + _paymentMethod = paymentMethod.first; + _amount = amount.toString(); browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context); browser.openPaymentBrowser(amount, "LiveCare Payment", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), "12", authenticatedUser.emailAddress, paymentMethod[0], - authenticatedUser.patientType, authenticatedUser.firstName, authenticatedUser.patientID, authenticatedUser, browser, false, "4", selectedClinicID.toString(), "", "", "", "", paymentMethod[1]); + authenticatedUser.patientType, authenticatedUser.firstName, authenticatedUser.patientID, authenticatedUser, browser, false, "4", selectedClinicID, "", "", "", "", paymentMethod[1]); } onBrowserLoadStart(String url) { @@ -328,21 +338,33 @@ class _clinic_listState extends State { GifLoaderDialogUtils.showMyDialog(context); service.checkPaymentStatus(Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), context).then((res) { GifLoaderDialogUtils.hideDialog(context); - print("Printing Payment Status Reponse!!!!"); - print(res); String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { addNewCallForPatientER(Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo)); + String txn_ref = res['Merchant_Reference']; + String amount = res['Amount'].toString(); + String payment_method = res['PaymentMethod']; + final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; + projectViewModel.analytics.appointment.payment_success( + appointment_type: 'livecare', payment_method: payment_method, clinic: selectedClinicName, hospital: "", payment_type: 'appointment', txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref); } else { AppToast.showErrorToast(message: res['Response_Message']); + paymentFail("400", res['Response_Message'], _amount); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); - print(err); + paymentFail("400", err.toString(),_amount); }); } + paymentFail(String errorCode, errorMessage, String amount,){ + final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; + projectViewModel.analytics.advancePayments.payment_fail( + appointment_type: 'livecare', payment_method: _paymentMethod, payment_type: 'appointment', clinic: selectedClinicName, hospital: "", txn_amount: "$amount", txn_currency: currency, error_code: errorCode, error_message: errorMessage + ); + } + addNewCallForPatientER(String clientRequestID) { LiveCareService service = new LiveCareService(); GifLoaderDialogUtils.showMyDialog(context); @@ -380,9 +402,13 @@ class _clinic_listState extends State { liveCareOfflineClinicsListResponse.add(clinic); } }); - - selectedClinicID = liveCareClinicsListResponse.patientERGetClinicsList[0].serviceID; - selectedClinicName = liveCareClinicsListResponse.patientERGetClinicsList[0].serviceName; + if(liveCareClinicIDs != null) { + selectedClinicID = int.parse(liveCareClinicIDs.split("-")[2]); + selectedClinicName = liveCareClinicIDs.split("-")[0]; + } else { + selectedClinicID = liveCareClinicsListResponse.patientERGetClinicsList[0].serviceID; + selectedClinicName = liveCareClinicsListResponse.patientERGetClinicsList[0].serviceName; + } isDataLoaded = true; }); } else { diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 8332d19b..84a16f15 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -376,5 +376,11 @@ class _Login extends State { this.mobileNo = registerData['PatientMobileNumber'].toString(); }); } + + // var voipToken = await sharedPref.getString("VOIPToken"); + // setState(() { + // nationalIDorFile.text = voipToken; + // }); + } } diff --git a/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart b/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart index 978636e0..489e9281 100644 --- a/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart +++ b/lib/pages/medical/ask_doctor/ViewDoctorResponsesPage.dart @@ -44,7 +44,7 @@ class ViewDoctorResponsesPage extends StatelessWidget { itemBuilder: (context, _index) { return Container( padding: const EdgeInsets.only(left: 20, right: 12, top: 12, bottom: 12), - height: 110, + height: 130, decoration: BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(10.0), @@ -86,7 +86,7 @@ class ViewDoctorResponsesPage extends StatelessWidget { Container( margin: EdgeInsets.only(top: 10.0), child: Text( - doctorResponse.transactions[_index]['DoctorResponse'], + doctorResponse.transactions[_index]['InfoStatusDescription'], style: TextStyle( fontSize: 16, color: Color(0xff2E303A), diff --git a/lib/pages/medical/ask_doctor/ask_doctor_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_page.dart index 877c52fc..19636d62 100644 --- a/lib/pages/medical/ask_doctor/ask_doctor_page.dart +++ b/lib/pages/medical/ask_doctor/ask_doctor_page.dart @@ -33,11 +33,7 @@ class AskDoctorPage extends StatelessWidget { return Container( margin: EdgeInsets.only(left: 50.0, right: 50.0), child: Center( - child: Text(TranslationBase.of(context).askDocEmpty, textAlign: TextAlign.center, style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w400, - color: CustomColors.accentColor - )), + child: Text(TranslationBase.of(context).askDocEmpty, textAlign: TextAlign.center, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: CustomColors.accentColor)), ), ); } @@ -81,23 +77,20 @@ class AskDoctorPage extends StatelessWidget { return DoctorView( doctor: doctorList, isLiveCareAppointment: false, + isShowFlag: false, onTap: () { GifLoaderDialogUtils.showMyDialog(context); service.getCallInfoHoursResult(doctorId: _doctor.doctorID, projectId: _doctor.projectID).then((res) { GifLoaderDialogUtils.hideDialog(context); - if (res['ErrorEndUserMessage'] == null) { - Navigator.push( - context, - FadePage( - page: RequestTypePage(doctorList: _doctor), - ), - ); - } else { - AppToast.showErrorToast(message: res['ErrorEndUserMessage']); - } + Navigator.push( + context, + FadePage( + page: RequestTypePage(doctorList: _doctor), + ), + ); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - if (err != null) AppToast.showErrorToast(message: err); + if (err != null) AppToast.showErrorToast(message: err.toString()); print(err); }); }, diff --git a/lib/pages/medical/ask_doctor/doctor_response.dart b/lib/pages/medical/ask_doctor/doctor_response.dart index b827529b..37e5f1c9 100644 --- a/lib/pages/medical/ask_doctor/doctor_response.dart +++ b/lib/pages/medical/ask_doctor/doctor_response.dart @@ -71,7 +71,7 @@ class DoctorResponse extends StatelessWidget { ); }, child: Container( - height: 75, + height: 100, margin: EdgeInsets.only(top: 8, bottom: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), @@ -101,8 +101,8 @@ class DoctorResponse extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), child: Icon(projectViewModel.isArabic - ? Icons.arrow_back_ios - : Icons.arrow_forward_ios), + ? Icons.arrow_forward_ios + : Icons.arrow_back_ios), ) ], ), @@ -144,7 +144,7 @@ class DoctorResponse extends StatelessWidget { return InkWell( onTap: () {}, child: Container( - height: 70, + height: 85, margin: EdgeInsets.only(top: 8, bottom: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), @@ -171,9 +171,12 @@ class DoctorResponse extends StatelessWidget { ), ), ), - Icon(projectViewModel.isArabic - ? Icons.arrow_forward - : Icons.arrow_back_ios) + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon(projectViewModel.isArabic + ? Icons.arrow_forward_ios + : Icons.arrow_back_ios), + ) ], ), ), diff --git a/lib/pages/medical/balance/confirm_payment_page.dart b/lib/pages/medical/balance/confirm_payment_page.dart index 3a7ef839..12bcc439 100644 --- a/lib/pages/medical/balance/confirm_payment_page.dart +++ b/lib/pages/medical/balance/confirm_payment_page.dart @@ -24,6 +24,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:pay/pay.dart'; import 'package:provider/provider.dart'; @@ -128,7 +129,11 @@ class _ConfirmPaymentPageState extends State { height: 100.0, padding: EdgeInsets.all(7.0), width: MediaQuery.of(context).size.width * 0.30, - child: Image.asset(getImagePath(widget.selectedPaymentMethod)), + child: widget.selectedPaymentMethod == "ApplePay" + ? SvgPicture.asset( + getImagePath(widget.selectedPaymentMethod), + ) + : Image.asset(getImagePath(widget.selectedPaymentMethod)), ), Text( '${widget.advanceModel.amount} ' + TranslationBase.of(context).sar, @@ -206,16 +211,16 @@ class _ConfirmPaymentPageState extends State { () { projectViewModel.analytics.advancePayments.payment_confirm(method: widget.selectedPaymentMethod.toLowerCase(), type: 'wallet'); - GifLoaderDialogUtils.showMyDialog(context); - model - .sendActivationCodeForAdvancePayment( - patientID: int.parse(widget.advanceModel.fileNumber), - projectID: widget.advanceModel.hospitalsModel.iD) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state != ViewState.ErrorLocal && - model.state != ViewState.Error) showSMSDialog(model); - }); + if (widget.advanceModel.fileNumber == projectViewModel.user.patientID.toString()) { + openPayment(widget.selectedPaymentMethod, widget.authenticatedUser, double.parse(widget.advanceModel.amount), null); + } else { + GifLoaderDialogUtils.showMyDialog(context); + model.sendActivationCodeForAdvancePayment(patientID: int.parse(widget.advanceModel.fileNumber), projectID: widget.advanceModel.hospitalsModel.iD).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state != ViewState.ErrorLocal && model.state != ViewState.Error) showSMSDialog(model); + }); + } + // startApplePay(); // if() // GifLoaderDialogUtils.showMyDialog(context); @@ -232,7 +237,6 @@ class _ConfirmPaymentPageState extends State { } startApplePay() { - // GifLoaderDialogUtils.showMyDialog(context); ApplePayResponse applePayResponse; var _paymentItems = [ PaymentItem( @@ -332,7 +336,8 @@ class _ConfirmPaymentPageState extends State { return 'assets/images/new/payment/installments.png'; break; case "ApplePay": - return 'assets/images/new/payment/Apple_Pay.png'; + return 'assets/images/new/payment/Apple_Pay.svg'; + // return 'assets/images/new/payment/Apple_Pay.png'; break; case "TAMARA": return 'assets/images/new/payment/tamara.png'; @@ -347,8 +352,26 @@ class _ConfirmPaymentPageState extends State { transID = Utils.getAdvancePaymentTransID(widget.advanceModel.hospitalsModel.iD, int.parse(widget.advanceModel.fileNumber)); - browser.openPaymentBrowser(amount, "Advance Payment", transID, widget.advanceModel.hospitalsModel.iD.toString(), widget.advanceModel.email, paymentMethod, - widget.patientInfoAndMobileNumber.patientType, widget.advanceModel.patientName, widget.advanceModel.fileNumber, authenticatedUser, browser, false, "3", "", "", "", "", "", widget.installmentPlan); + browser.openPaymentBrowser( + amount, + "Advance Payment", + transID, + widget.advanceModel.hospitalsModel.iD.toString(), + widget.advanceModel.email, + paymentMethod, + widget.patientInfoAndMobileNumber.patientType, + widget.advanceModel.patientName, + widget.advanceModel.fileNumber, + authenticatedUser, + browser, + false, + "3", + "0", + "", + "", + "", + "", + widget.installmentPlan); } onBrowserLoadStart(String url) { @@ -384,17 +407,39 @@ class _ConfirmPaymentPageState extends State { String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { createAdvancePayment(res, appo); + String txn_ref = res['Merchant_Reference']; + String amount = res['Amount'].toString(); + String payment_method = res['PaymentMethod']; + final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; + + final hospital = widget.advanceModel.hospitalsModel.name; + + projectViewModel.analytics.advancePayments.payment_success( + appointment_type: '', payment_method: payment_method, payment_type: 'wallet', clinic: '', hospital: hospital, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref + ); } else { GifLoaderDialogUtils.hideDialog(AppGlobal.context); AppToast.showErrorToast(message: res['Response_Message']); + paymentFail("400", paymentInfo); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); AppToast.showErrorToast(message: err); - print(err); + paymentFail("400", err.toString()); }); } + paymentFail(String errorCode, errorMessage){ + + final hospital = widget.advanceModel.hospitalsModel.name; + final amount = widget.advanceModel.amount; + final currency = projectViewModel.user.outSA == 0 ? "sar" : 'aed'; + projectViewModel.analytics.advancePayments.payment_fail( + appointment_type: '', payment_method: widget.selectedPaymentMethod, payment_type: 'wallet', clinic: '', hospital: hospital, txn_amount: "$amount", txn_currency: currency, error_code: errorCode, error_message: errorMessage + ); + + } + createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); diff --git a/lib/pages/medical/prescriptions/prescription_items_page.dart b/lib/pages/medical/prescriptions/prescription_items_page.dart index 4b5f951d..6e817f8c 100644 --- a/lib/pages/medical/prescriptions/prescription_items_page.dart +++ b/lib/pages/medical/prescriptions/prescription_items_page.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_inp.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_page.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -384,22 +385,23 @@ class PrescriptionItemsPage extends StatelessWidget { padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: DefaultButton( TranslationBase.of(context).resendOrder, - // ((!projectViewModel.havePrivilege(62)) || projectViewModel.user.outSA == 1 || model.isMedDeliveryAllowed == false) - // ? null - // : - () => { - Navigator.push( - context, - FadePage( - page: PrescriptionDeliveryAddressPage( - prescriptions: prescriptions, - prescriptionReportList: model.prescriptionReportList, - prescriptionReportEnhList: model.prescriptionReportEnhList, - ), - ), - ) - }, - color: Color(0xff359846), + () { + if (model.isMedDeliveryAllowed == false) { + AppToast.showErrorToast(message: TranslationBase.of(context).prescriptionDeliveryError); + } else { + Navigator.push( + context, + FadePage( + page: PrescriptionDeliveryAddressPage( + prescriptions: prescriptions, + prescriptionReportList: model.prescriptionReportList, + prescriptionReportEnhList: model.prescriptionReportEnhList, + ), + ), + ); + } + }, + color: model.isMedDeliveryAllowed == false ? Color(0xff575757) : Color(0xff359846), disabledColor: Color(0xff575757), ), ), diff --git a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart index 156fb55a..38da7db3 100644 --- a/lib/pages/medical/smart_watch_health_data/syncHealthData.dart +++ b/lib/pages/medical/smart_watch_health_data/syncHealthData.dart @@ -51,14 +51,14 @@ class _syncHealthDataButtonState extends State { if (Platform.isAndroid) { if (await PermissionService.isHealthDataPermissionEnabled()) { await health.requestAuthorization(types).then((value) { - if(value) { + if (value) { readAll(); } }); } else { Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async { await health.requestAuthorization(types).then((value) { - if(value) { + if (value) { readAll(); } }); @@ -66,7 +66,7 @@ class _syncHealthDataButtonState extends State { } } else { await health.requestAuthorization(types).then((value) { - if(value) { + if (value) { readAll(); } }); @@ -82,8 +82,6 @@ class _syncHealthDataButtonState extends State { Med_InsertTransactionsInputsList.clear(); DateTime startDate = DateTime.now().subtract(new Duration(days: 30)); - await checkPermissions(); - try { List healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types); _healthDataList.addAll(healthData); diff --git a/lib/pages/webRTC/OpenTok/OpenTok.dart b/lib/pages/webRTC/OpenTok/OpenTok.dart index 4246049d..6c70170f 100644 --- a/lib/pages/webRTC/OpenTok/OpenTok.dart +++ b/lib/pages/webRTC/OpenTok/OpenTok.dart @@ -10,6 +10,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart'; import 'OpenTokPlatformBridge.dart'; @@ -36,6 +37,7 @@ class OpenTokState extends State{ var audioMute = false; var videoMute = false; + final voIPKit = FlutterIOSVoIPKit.instance; initOpenTok(){ openTokPlatform = OpenTokPlatformBridge.init( @@ -196,6 +198,7 @@ class OpenTokState extends State{ Future _onHangup() async { print('onHangup'); await openTokPlatform.hangupCall(); + voIPKit.endCall(); endCallAPI(); Navigator.of(context).pop(); } diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 606d9486..7003f376 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -3,10 +3,12 @@ import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; +import 'package:diplomaticquarterapp/models/Appointments/laser_body_parts.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/models/apple_pay_request.dart'; @@ -28,6 +30,7 @@ class DoctorsListService extends BaseService { double long; String deviceToken; String tokenID; + List selectedBodyPartList = []; Future getDoctorsList(int clinicID, int projectID, bool isNearest, BuildContext context, {doctorId, doctorName, isContinueDentalPlan = false}) async { Map request; @@ -317,8 +320,8 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, BuildContext context, - [String procedureID, num testTypeEnum, num testProcedureEnum]) async { + Future insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, BuildContext context, + [String procedureID, num testTypeEnum, num testProcedureEnum, ProjectViewModel projectViewModel]) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { @@ -339,13 +342,14 @@ class DoctorsListService extends BaseService { "ProcedureID": procedureID, "TestTypeEnum": testTypeEnum, "TestProcedureEnum": testProcedureEnum, - "InitialSlotDuration": 0, + "InitialSlotDuration": initialSlotDuration, "StrAppointmentDate": selectedDate, "IsVirtual": false, "DeviceType": Platform.isIOS ? 'iOS' : 'Android', "BookedBy": 102, "VisitType": 1, "VisitFor": 1, + "GenderID": authUser.gender, "VersionID": req.VersionID, "Channel": req.Channel, "LanguageID": languageID == 'ar' ? 1 : 2, @@ -360,10 +364,18 @@ class DoctorsListService extends BaseService { "PatientType": authUser.patientType }; + if(clinicID == 253) { + List procedureID = projectViewModel.selectedBodyPartList.map((element) => element.id.toString()).toList(); + request["GeneralProcedureList"] = procedureID; + request["InitialSlotDuration"] = projectViewModel.laserSelectionDuration; + } + dynamic localRes; await baseAppClient.post(INSERT_SPECIFIC_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; + projectViewModel.selectedBodyPartList.clear(); + projectViewModel.laserSelectionDuration = 0; }, onFailure: (String error, int statusCode) { throw error; }, body: request); @@ -461,6 +473,28 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future setOnlineCheckInForAppointment(String appoID, int projectID, BuildContext context) async { + Map request; + + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + request = { + "ProjectID": projectID, + "AppointmentNo": appoID + }; + + dynamic localRes; + + await baseAppClient.post(SET_ONLINE_CHECKIN_FOR_APPOINTMENT, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future getLiveCareAppointmentPatientShare(String appoID, int clinicID, int projectID, BuildContext context) async { Map request; diff --git a/lib/services/livecare_services/livecare_provider.dart b/lib/services/livecare_services/livecare_provider.dart index 7d4950a9..b30960b4 100644 --- a/lib/services/livecare_services/livecare_provider.dart +++ b/lib/services/livecare_services/livecare_provider.dart @@ -201,6 +201,7 @@ class LiveCareService extends BaseService { Map request; String deviceToken; + String voipToken = await sharedPref.getString(APNS_TOKEN); getDeviceToken().then((value) { print(value); deviceToken = value; @@ -215,8 +216,8 @@ class LiveCareService extends BaseService { "ErServiceID": serviceID, "ClientRequestID": clientRequestID, "DeviceToken": deviceToken, - "VoipToken": "", - // "IsFlutter": true, + "VoipToken": voipToken, + "IsFlutter": true, "Latitude": await this.sharedPref.getDouble(USER_LAT), "Longitude": await this.sharedPref.getDouble(USER_LONG), "DeviceType": Platform.isIOS ? 'iOS' : 'Android', diff --git a/lib/uitl/CalendarUtils.dart b/lib/uitl/CalendarUtils.dart index ee602391..ae943617 100644 --- a/lib/uitl/CalendarUtils.dart +++ b/lib/uitl/CalendarUtils.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:ui'; import 'package:device_calendar/device_calendar.dart'; +import 'package:timezone/timezone.dart'; final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin(); @@ -52,8 +53,17 @@ class CalendarUtils { // daysOfWeek: daysOfWeek, endDate: scheduleDateTime, ); + + Location _currentLocation; + if (DateTime.now().timeZoneName == "+04") + _currentLocation = getLocation('Asia/Dubai'); + else + _currentLocation = getLocation('Asia/Riyadh'); + + TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime, _currentLocation); + print("eventId " + eventId); - Event event = Event(writableCalendars.id, recurrenceRule: recurrenceRule, start: scheduleDateTime, end: scheduleDateTime.add(Duration(minutes: 30)), title: title, description: description); + Event event = Event(writableCalendars.id, recurrenceRule: recurrenceRule, start: scheduleDateTimeUTZ, end: scheduleDateTimeUTZ.add(Duration(minutes: 30)), title: title, description: description); deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) { print("catchError " + e.toString()); }).whenComplete(() { diff --git a/lib/uitl/date_uitl.dart b/lib/uitl/date_uitl.dart index 370914f0..1c9db2f5 100644 --- a/lib/uitl/date_uitl.dart +++ b/lib/uitl/date_uitl.dart @@ -5,7 +5,6 @@ class DateUtil { /// convert String To Date function /// [date] String we want to convert static DateTime convertStringToDate(String date) { - // /Date(1585774800000+0300)/ if (date != null) { const start = "/Date("; const end = "+0300)"; @@ -14,7 +13,7 @@ class DateUtil { return DateTime.fromMillisecondsSinceEpoch( int.parse( date.substring(startIndex + start.length, endIndex), - ), + ) ); } else return DateTime.now(); diff --git a/lib/uitl/push-notification-handler.dart b/lib/uitl/push-notification-handler.dart index 76399a1a..b448bff4 100644 --- a/lib/uitl/push-notification-handler.dart +++ b/lib/uitl/push-notification-handler.dart @@ -1,35 +1,53 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_response_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; +import 'package:diplomaticquarterapp/pages/DrawerPages/notifications/notification_details_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart'; +import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:huawei_push/huawei_push.dart' as h_push; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart' as fir; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter_ios_voip_kit/call_state_type.dart'; +import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart'; +import 'package:huawei_push/huawei_push.dart' as h_push; import 'app_shared_preferences.dart'; import 'navigation_service.dart'; // |--> Push Notification Background Future backgroundMessageHandler(dynamic message) async { + print("Firebase backgroundMessageHandler!!!"); fir.RemoteMessage message_; if (message is h_push.RemoteMessage) { // if huawei remote message convert it to Firebase Remote Message message_ = toFirebaseRemoteMessage(message); + h_push.Push.localNotification({h_push.HMSLocalNotificationAttr.TITLE: 'Background Message', h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"}); } - if (message.data != null && message.data['is_call'] == 'true') { + if (message.data != null && (message.data['is_call'] == 'true' || message.data['is_call'] == true)) { _incomingCall(message.data); return; + } else { + GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.convertDateToString(DateTime.now()); + notification.messageTypeData = message.data['picture']; + notification.message = message.data['message']; + + await NavigationService.navigateToPage(NotificationsDetailsPage( + notification: notification, + )); } - h_push.Push.localNotification({h_push.HMSLocalNotificationAttr.TITLE: 'Background Message', h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"}); } // Push Notification Background <--| @@ -67,6 +85,10 @@ RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) { return fire_message; } +callPage(String sessionID, String token) async { + await NavigationService.navigateToPage(OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: sessionID, token: token)); +} + _incomingCall(Map data) async { LandingPage.incomingCallData = IncomingCallData.fromJson(data); if (LandingPage.isOpenCallPage == false) { @@ -82,6 +104,30 @@ _incomingCall(Map data) async { class PushNotificationHandler { final BuildContext context; static PushNotificationHandler _instance; + final voIPKit = FlutterIOSVoIPKit.instance; + + Timer timeOutTimer; + bool isTalking = false; + + var data = { + "AppointmentNo": "2016059247", + "ProjectID": "15", + "NotificationType": "10", + "background": "0", + "doctorname": "Call from postman", + "clinicname": "LIVECARE FAMILY MEDICINE AND GP", + "speciality": "General Practioner", + "appointmentdate": "2022-01-19", + "appointmenttime": "12:10", + "PatientName": "Testing", + "session_id": "1_MX40NjIwOTk2Mn5-MTY1NDE2NDQxMjc2Mn5xc3NCZkNIejJOdzgzTkg2TmlXblhQdnl-fg", + "token": + "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9MTliNTA3NDAxYmU0MjI5OGY5NTcxZTdhNzQyMTcyZjRjMjBhNjljZTpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTFOREUyTkRReE1qYzJNbjV4YzNOQ1prTkllakpPZHpnelRrZzJUbWxYYmxoUWRubC1mZyZjcmVhdGVfdGltZT0xNjU0MTY0NDEzJm5vbmNlPTAuNjM3ODkzNDk4NDQ2NTIxOSZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjU0MjUwODEzJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", + "callerID": "9920", + "PatientID": "1231755", + "is_call": "true" + }; PushNotificationHandler(this.context) { PushNotificationHandler._instance = this; @@ -89,7 +135,90 @@ class PushNotificationHandler { static PushNotificationHandler getInstance() => _instance; + void _timeOut({ + int seconds = 15, + }) async { + timeOutTimer = Timer(Duration(seconds: seconds), () async { + print('🎈 example: timeOut'); + final incomingCallerName = await voIPKit.getIncomingCallerName(); + voIPKit.unansweredIncomingCall( + skipLocalNotification: false, + missedCallTitle: '📞 Missed call', + missedCallBody: 'There was a call from $incomingCallerName', + ); + }); + } + init() async { + // VoIP Callbacks + voIPKit.getVoIPToken().then((value) { + print('🎈 example: getVoIPToken: $value'); + AppSharedPreferences().setString(APNS_TOKEN, value); + }); + + voIPKit.onDidUpdatePushToken = ( + String token, + ) { + print('🎈 example: onDidUpdatePushToken: $token'); + AppSharedPreferences().setString(APNS_TOKEN, token); + }; + + voIPKit.onDidReceiveIncomingPush = ( + Map payload, + ) async { + print('🎈 example: onDidReceiveIncomingPush $payload'); + _timeOut(); + }; + + voIPKit.onDidRejectIncomingCall = ( + String uuid, + String callerId, + ) { + if (isTalking) { + return; + } + + print('🎈 example: onDidRejectIncomingCall $uuid, $callerId'); + voIPKit.endCall(); + timeOutTimer?.cancel(); + }; + + voIPKit.onDidAcceptIncomingCall = ( + String uuid, + String callerId, + ) { + print('🎈 example: onDidAcceptIncomingCall $uuid, $callerId'); + + String sessionID = callerId.split("*")[0]; + String token = callerId.split("*")[1]; + + print("🎈 SessionID: $sessionID"); + print("🎈 Token: $token"); + + voIPKit.acceptIncomingCall(callerState: CallStateType.calling); + voIPKit.callConnected(); + timeOutTimer?.cancel(); + + print("🎈 CALL ACCEPTED!!!"); + + Future.delayed(new Duration(milliseconds: 2000)).then((value) async { + print("🎈 Incoming Call!!!"); + callPage(sessionID, token); + }); + + // print("🎈 Identity: $identity"); + // print("🎈 Name: $name"); + + // setState(() { + // isTalking = true; + // }); + }; + + if (Platform.isAndroid && (!await FlutterHmsGmsAvailability.isHmsAvailable)) { + final fcmToken = await FirebaseMessaging.instance.getToken(); + if (fcmToken != null) onToken(fcmToken); + } + if (Platform.isIOS) { final permission = await FirebaseMessaging.instance.requestPermission(); if (permission.authorizationStatus == AuthorizationStatus.denied) return; @@ -116,14 +245,40 @@ class PushNotificationHandler { h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler); } else { - // 'Android GMS or iOS' (Handle Firebase Messaging Streams) + // 'Android GMS or iOS' (Handle Firebase Messaging Streams + + FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage message) async { + print("Firebase getInitialMessage!!!"); + subscribeFCMTopic(); + if (Platform.isIOS) + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + if (message != null) newMessage(message); + }); + else if (message != null) newMessage(message); + }); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { - newMessage(message); + print("Firebase onMessage!!!"); + // Utils.showPermissionConsentDialog(context, "onMessage", (){}); + // newMessage(message); + if (Platform.isIOS) + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + newMessage(message); + }); + else + newMessage(message); }); - FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { - newMessage(message); + FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { + print("Firebase onMessageOpenedApp!!!"); + // Utils.showPermissionConsentDialog(context, "onMessageOpenedApp", (){}); + // newMessage(message); + if (Platform.isIOS) + await Future.delayed(Duration(milliseconds: 3000)).then((value) { + newMessage(message); + }); + else + newMessage(message); }); FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { @@ -131,14 +286,31 @@ class PushNotificationHandler { }); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); - - final fcmToken = await FirebaseMessaging.instance.getToken(); - if (fcmToken != null) onToken(fcmToken); } } - newMessage(RemoteMessage remoteMessage) { - if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) _incomingCall(remoteMessage.data); + subscribeFCMTopic() async { + print("subscribeFCMTopic!!!"); + await FirebaseMessaging.instance.unsubscribeFromTopic('all_hmg_patients').then((value) async { + await FirebaseMessaging.instance.subscribeToTopic('all_hmg_patients'); + }); + } + + newMessage(RemoteMessage remoteMessage) async { + print("Remote Message: " + remoteMessage.data.toString()); + if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) { + _incomingCall(remoteMessage.data); + } else { + GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); + + notification.createdOn = DateUtil.convertDateToString(DateTime.now()); + notification.messageTypeData = remoteMessage.data['picture']; + notification.message = remoteMessage.data['message']; + + await NavigationService.navigateToPage(NotificationsDetailsPage( + notification: notification, + )); + } } onToken(String token) async { diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 917c3d01..7b44b24a 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2849,6 +2849,11 @@ class TranslationBase { String get wifiPermission => localizedValues["wifiPermission"][locale.languageCode]; String get physicalActivityPermission => localizedValues["physicalActivityPermission"][locale.languageCode]; String get bluetoothPermission => localizedValues["bluetoothPermission"][locale.languageCode]; + String get privacyPolicy => localizedValues["privacyPolicy"][locale.languageCode]; + String get termsConditions => localizedValues["termsConditions"][locale.languageCode]; + String get liveCarePermissions => localizedValues["liveCarePermissions"][locale.languageCode]; + String get prescriptionDeliveryError => localizedValues["prescriptionDeliveryError"][locale.languageCode]; + } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index da65edbd..4fa4057a 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -165,7 +165,7 @@ class Utils { } String loginIDPattern(loginType) { - var length = loginType == 1 ? 10 : 4; + var length = loginType == 1 ? 10 : 1; return "([0-9]{" + length.toString() + "})"; } diff --git a/lib/widgets/app_map/google_huawei_map.dart b/lib/widgets/app_map/google_huawei_map.dart index 0e9b4936..2ff86acd 100644 --- a/lib/widgets/app_map/google_huawei_map.dart +++ b/lib/widgets/app_map/google_huawei_map.dart @@ -88,6 +88,10 @@ class AppMapState extends State { _huaweiMapControllerComp.complete(controller); widget.onMapCreated(); }, + onCameraIdle: () { + print("onCameraIdle"); + widget.onCameraIdle(); + }, ); } } diff --git a/lib/widgets/bottom_navigation/bottom_navigation_item.dart b/lib/widgets/bottom_navigation/bottom_navigation_item.dart index b729aa91..ff085dd9 100644 --- a/lib/widgets/bottom_navigation/bottom_navigation_item.dart +++ b/lib/widgets/bottom_navigation/bottom_navigation_item.dart @@ -72,7 +72,7 @@ class BottomNavigationItem extends StatelessWidget { ), ], ) - : (authenticatedUserObject.isLogin && model.isShowBadge && !projectViewModel.isLoginChild) + : (authenticatedUserObject.isLogin && model.isShowBadge) ? Stack( alignment: AlignmentDirectional.center, children: [ diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 06751d02..72a8dbed 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; +import 'package:diplomaticquarterapp/pages/Blood/user_agreement_page.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/notifications/notifications_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; @@ -39,6 +40,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:in_app_review/in_app_review.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../../config/size_config.dart'; import '../../locator.dart'; @@ -427,16 +429,21 @@ class _AppDrawerState extends State { login(); }, ), - // InkWell( - // child: DrawerItem( - // TranslationBase.of(context).appsetting, - // Icons.settings_input_composite), - // onTap: () { - // Navigator.of(context).pushNamed( - // SETTINGS, - // ); - // }, - // ) + InkWell( + child: DrawerItem(TranslationBase.of(context).privacyPolicy, Icons.web, letterSpacing: -0.84, fontSize: 14, bottomLine: false), + onTap: () { + if (projectProvider.isArabic) + launch("https://hmg.com/ar/Pages/Privacy.aspx"); + else + launch("https://hmg.com/en/Pages/Privacy.aspx"); + }, + ), + InkWell( + child: DrawerItem(TranslationBase.of(context).termsConditions, Icons.web, letterSpacing: -0.84, fontSize: 14, bottomLine: false), + onTap: () { + Navigator.of(context).push(FadePage(page: UserAgreementPage())); + }, + ) ], )) ], diff --git a/lib/widgets/in_app_browser/InAppBrowser.dart b/lib/widgets/in_app_browser/InAppBrowser.dart index 2a8721ae..a21028f8 100644 --- a/lib/widgets/in_app_browser/InAppBrowser.dart +++ b/lib/widgets/in_app_browser/InAppBrowser.dart @@ -24,13 +24,14 @@ var _InAppBrowserOptions = InAppBrowserClassOptions( crossPlatform: InAppBrowserOptions(hideUrlBar: true), ios: IOSInAppBrowserOptions( hideToolbarBottom: false, + toolbarBottomBackgroundColor: Colors.white, )); class MyInAppBrowser extends InAppBrowser { _PAYMENT_TYPE paymentType; - static String APPLE_PAY_PAYFORT_URL = 'https://hmgwebservices.com/PayFortWebLive/PayFortApi/MakeApplePayRequest'; // Payfort Payment Gateway URL LIVE - // static String APPLE_PAY_PAYFORT_URL = 'https://hmgwebservices.com/PayFortWeb/PayFortApi/MakeApplePayRequest'; // Payfort Payment Gateway URL UAT + // static String APPLE_PAY_PAYFORT_URL = 'https://hmgwebservices.com/PayFortWebLive/PayFortApi/MakeApplePayRequest'; // Payfort Payment Gateway URL LIVE + static String APPLE_PAY_PAYFORT_URL = 'https://hmgwebservices.com/PayFortWeb/PayFortApi/MakeApplePayRequest'; // Payfort Payment Gateway URL UAT static String SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; // Payfort Payment Gateway URL UAT @@ -147,6 +148,7 @@ class MyInAppBrowser extends InAppBrowser { this.browser = browser; await getPatientData(); if (paymentMethod == "ApplePay") { + getDeviceToken(); MyChromeSafariBrowser safariBrowser = new MyChromeSafariBrowser(new MyInAppBrowser(), onExitCallback: browser.onExit, onLoadStartCallback: this.browser.onLoadStart, appo: this.appo); if (context != null) GifLoaderDialogUtils.showMyDialog(context); @@ -155,28 +157,28 @@ class MyInAppBrowser extends InAppBrowser { ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest(); applePayInsertRequest.clientRequestID = transactionID; - applePayInsertRequest.clinicID = clinicID != null ? clinicID : 0; + applePayInsertRequest.clinicID = (clinicID != null && clinicID != "") ? clinicID : 0; applePayInsertRequest.currency = authenticatedUser.outSA == 1 ? "AED" : "SAR"; applePayInsertRequest.customerEmail = emailId; applePayInsertRequest.customerID = authenticatedUser.patientID; applePayInsertRequest.customerName = authenticatedUser.firstName; - applePayInsertRequest.deviceToken = deviceToken; - applePayInsertRequest.doctorID = doctorID != null ? doctorID : 0; + applePayInsertRequest.deviceToken = await sharedPref.getString(PUSH_TOKEN); + applePayInsertRequest.doctorID = (doctorID != null && doctorID != "") ? doctorID : 0; applePayInsertRequest.projectID = projId; applePayInsertRequest.serviceID = servID; applePayInsertRequest.channelID = 3; applePayInsertRequest.patientID = authenticatedUser.patientID; applePayInsertRequest.patientTypeID = authenticatedUser.patientType; applePayInsertRequest.patientOutSA = authenticatedUser.outSA; - applePayInsertRequest.appointmentDate = appoDate != null ? appoDate : null; - applePayInsertRequest.appointmentNo = appoNo != null ? appoNo : 0; + applePayInsertRequest.appointmentDate = (appoDate != null && appoDate != "") ? appoDate : null; + applePayInsertRequest.appointmentNo = (appoNo != null && appoNo != "") ? appoNo : 0; applePayInsertRequest.orderDescription = orderDesc; - applePayInsertRequest.liveServiceID = LiveServID; + applePayInsertRequest.liveServiceID = LiveServID.toString() == "" ? "0" : LiveServID.toString(); applePayInsertRequest.latitude = this.lat.toString(); applePayInsertRequest.longitude = this.long.toString(); applePayInsertRequest.amount = amount.toString(); - applePayInsertRequest.isSchedule = "0"; - applePayInsertRequest.language = await getLanguageID() == 'ar' ? 'AR' : 'EN'; + applePayInsertRequest.isSchedule = ((appoNo != null && appoNo != "") && (appoDate != null && appoDate != "")) ? "1" : "0"; + applePayInsertRequest.language = await getLanguageID() == 'ar' ? 'ar' : 'en'; applePayInsertRequest.userName = authenticatedUser.patientID; applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html"; applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html"; @@ -247,6 +249,7 @@ class MyInAppBrowser extends InAppBrowser { form = form.replaceFirst('PATIENT_OUT_SA', authUser.outSA == 0 ? false.toString() : true.toString()); form = form.replaceFirst('PATIENT_TYPE_ID', patientData == null ? patientType.toString() : "1"); + // form = form.replaceFirst('DEVICE_TOKEN', await sharedPref.getString(PUSH_TOKEN) + "," + await sharedPref.getString(APNS_TOKEN)); form = form.replaceFirst('DEVICE_TOKEN', await sharedPref.getString(PUSH_TOKEN)); form = form.replaceFirst('LATITUDE_VALUE', this.lat.toString()); form = form.replaceFirst('LONGITUDE_VALUE', this.long.toString()); @@ -258,7 +261,7 @@ class MyInAppBrowser extends InAppBrowser { if (servID != null) { form = form.replaceFirst('SERV_ID', servID); - form = form.replaceFirst('LIVE_SERVICE_ID', LiveServID); + form = form.replaceFirst('LIVE_SERVICE_ID', LiveServID.toString()); } else { form = form.replaceFirst('SERV_ID', "2"); form = form.replaceFirst('LIVE_SERVICE_ID', "2"); diff --git a/lib/widgets/otp/sms-popup.dart b/lib/widgets/otp/sms-popup.dart index afb27530..64c981b2 100644 --- a/lib/widgets/otp/sms-popup.dart +++ b/lib/widgets/otp/sms-popup.dart @@ -7,15 +7,19 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; -import 'package:sms_retriever/sms_retriever.dart'; +import 'package:sms_otp_auto_verify/sms_otp_auto_verify.dart'; import '../otp_widget.dart'; class SMSOTP { final type; + final mobileNo; + final Function onSuccess; + final Function onFailure; + final context; int remainingTime = 120; @@ -39,8 +43,11 @@ class SMSOTP { final TextEditingController _pinPutController = TextEditingController(); TextEditingController digit1 = TextEditingController(text: ""); + TextEditingController digit2 = TextEditingController(text: ""); + TextEditingController digit3 = TextEditingController(text: ""); + TextEditingController digit4 = TextEditingController(text: ""); Map verifyAccountFormValue = { @@ -49,23 +56,44 @@ class SMSOTP { 'digit3': '', 'digit4': '', }; + final focusD1 = FocusNode(); + final focusD2 = FocusNode(); + final focusD3 = FocusNode(); + final focusD4 = FocusNode(); + String errorMsg; + ProjectViewModel projectProvider; + String displayTime = ''; + String _code; + dynamic setState; + static String signature; displayDialog(BuildContext context) async { + // var signature = await checkSignature(); + + // print(signature); + + // if (signature) { + + // onSuccess(signature); + + // } + return showDialog( context: context, barrierColor: Colors.black.withOpacity(0.63), builder: (context) { projectProvider = Provider.of(context); + return Dialog( backgroundColor: Colors.white, shape: RoundedRectangleBorder(), @@ -73,6 +101,9 @@ class SMSOTP { child: StatefulBuilder(builder: (context, setState) { if (displayTime == '') { startTimer(setState); + + // startLister(); + if (Platform.isAndroid) checkSignature(); } return Container( @@ -96,6 +127,7 @@ class SMSOTP { constraints: BoxConstraints(), onPressed: () { Navigator.pop(context); + this.onFailure(); }, ) @@ -162,20 +194,26 @@ class SMSOTP { InputDecoration buildInputDecoration(BuildContext context) { return InputDecoration( counterText: " ", + // ts/images/password_icon.png + // contentPadding: EdgeInsets.only(top: 20, bottom: 20), + enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10)), borderSide: BorderSide(color: Colors.black), ), + focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Theme.of(context).primaryColor), ), + errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Theme.of(context).errorColor), ), + focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Theme.of(context).errorColor), @@ -195,6 +233,7 @@ class SMSOTP { checkValue() { //print(verifyAccountFormValue); + if (verifyAccountForm.currentState.validate()) { onSuccess(digit1.text.toString() + digit2.text.toString() + digit3.text.toString() + digit4.text.toString()); } @@ -202,18 +241,27 @@ class SMSOTP { getSecondsAsDigitalClock(int inputSeconds) { var sec_num = int.parse(inputSeconds.toString()); // don't forget the second param + var hours = (sec_num / 3600).floor(); + var minutes = ((sec_num - hours * 3600) / 60).floor(); + var seconds = sec_num - hours * 3600 - minutes * 60; + var minutesString = ""; + var secondsString = ""; + minutesString = minutes < 10 ? "0" + minutes.toString() : minutes.toString(); + secondsString = seconds < 10 ? "0" + seconds.toString() : seconds.toString(); + return minutesString + ":" + secondsString; } startTimer(setState) { this.remainingTime--; + setState(() { displayTime = this.getSecondsAsDigitalClock(this.remainingTime); }); @@ -237,9 +285,26 @@ class SMSOTP { } } + checkSignature() async { + SmsVerification.startListeningSms().then((message) { + // setState(() { + final intRegex = RegExp(r'\d+', multiLine: true); + var otp = SmsVerification.getCode(message, intRegex); + _pinPutController.text = otp; + onSuccess(otp); + // }); + }); + } + + // startLister() { + // var signature = checkSignature(); + // + // print(signature); + // } + static getSignature() async { if (Platform.isAndroid) { - return await SmsRetriever.getAppSignature(); + return await SmsVerification.getAppSignature(); } else { return null; } diff --git a/lib/widgets/pickupLocation/PickupLocationFromMap.dart b/lib/widgets/pickupLocation/PickupLocationFromMap.dart index 9a3ff303..f9bd92d2 100644 --- a/lib/widgets/pickupLocation/PickupLocationFromMap.dart +++ b/lib/widgets/pickupLocation/PickupLocationFromMap.dart @@ -1,18 +1,22 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/ambulanceRequest/locationDetails.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; +import 'package:diplomaticquarterapp/widgets/app_map/google_huawei_map.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/close_back.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:geocoding/geocoding.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import 'package:provider/provider.dart'; -class PickupLocationFromMap extends StatelessWidget { - final Function(PickResult) onPick; +class PickupLocationFromMap extends StatefulWidget { + final Function(LocationDetails) onPick; final double latitude; final double longitude; final bool isWithAppBar; @@ -21,6 +25,54 @@ class PickupLocationFromMap extends StatelessWidget { const PickupLocationFromMap({Key key, this.onPick, this.latitude, this.longitude, this.isWithAppBar = true, this.buttonLabel, this.buttonColor}) : super(key: key); + @override + State createState() => _PickupLocationFromMapState(); +} + +class _PickupLocationFromMapState extends State { + bool isHuawei = false; + Placemark selectedPlace; + AppMap appMap; + LatLng currentPostion; + AppSharedPreferences sharedPref = AppSharedPreferences(); + double latitude = 0; + double longitude = 0; + + static CameraPosition kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + + @override + void initState() { + checkIsHuawei(); + + appMap = AppMap( + kGooglePlex.toMap(), + onCameraMove: (camera) { + _updatePosition(camera); + }, + onMapCreated: () { + currentPostion = LatLng(widget.latitude, widget.longitude); + latitude = widget.latitude; + longitude = widget.longitude; + setState(() {}); + }, + onCameraIdle: () async { + List placemarks = await placemarkFromCoordinates(latitude, longitude); + selectedPlace = placemarks[0]; + print(selectedPlace); + }, + ); + super.initState(); + } + + checkIsHuawei() async { + isHuawei = await FlutterHmsGmsAvailability.isHmsAvailable; + print(isHuawei); + setState(() {}); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -29,58 +81,92 @@ class PickupLocationFromMap extends StatelessWidget { showNewAppBarTitle: true, showNewAppBar: true, appBarTitle: TranslationBase.of(context).selectLocation, - // appBar: isWithAppBar - // ? AppBar( - // elevation: 0, - // textTheme: TextTheme( - // headline6: - // TextStyle(color: Colors.white, fontWeight: FontWeight.bold), - // ), - // title: Text('Location'), - // leading: CloseBack(), - // centerTitle: true, - // ) - // : null, - body: PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - selectInitialPosition: true, - region: "SA", - onPlacePicked: (PickResult result) { - print(result.adrAddress); - onPick(result); - Navigator.of(context).pop(); - }, - selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: DefaultButton( - TranslationBase.of(context).next, - () { - onPick(selectedPlace); - Navigator.of(context).pop(); - }, - ), + body: isHuawei + ? Column( + children: [ + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + if (appMap != null) appMap, + Container( + margin: EdgeInsets.only(bottom: 50.0), + child: Icon( + Icons.place, + color: CustomColors.accentColor, + size: 50, ), - ); - }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: true, - ), + ), + ], + ), + ), + Container( + padding: const EdgeInsets.only(left: 20, right: 20, top: 14, bottom: 14), + child: DefaultButton(TranslationBase.of(context).next, () async { + LocationDetails locationDetails = new LocationDetails(); + locationDetails.lat = latitude; + locationDetails.long = longitude; + locationDetails.formattedAddress = selectedPlace.street; + widget.onPick(locationDetails); + Navigator.of(context).pop(); + }), + ), + ], + ) + : PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + selectInitialPosition: true, + region: "SA", + onPlacePicked: (PickResult result) { + LocationDetails locationDetails = new LocationDetails(); + locationDetails.lat = latitude; + locationDetails.long = longitude; + locationDetails.formattedAddress = result.formattedAddress; + print(result.adrAddress); + widget.onPick(locationDetails); + Navigator.of(context).pop(); + }, + selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(12.0), + child: state == SearchingState.Searching + ? Center(child: CircularProgressIndicator()) + : Container( + margin: EdgeInsets.all(12), + child: DefaultButton( + TranslationBase.of(context).next, + () { + LocationDetails locationDetails = new LocationDetails(); + locationDetails.lat = latitude; + locationDetails.long = longitude; + locationDetails.formattedAddress = selectedPlace.formattedAddress; + widget.onPick(locationDetails); + Navigator.of(context).pop(); + }, + ), + ), + ); + }, + initialPosition: LatLng(widget.latitude, widget.longitude), + useCurrentLocation: true, + ), ); } + + void _updatePosition(CameraPosition _position) { + print(_position); + latitude = _position.target.latitude; + longitude = _position.target.longitude; + } } diff --git a/pubspec.yaml b/pubspec.yaml index ceccf36e..0165c607 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,7 @@ name: diplomaticquarterapp description: A new Flutter application. - -version: 4.4.3+1 +version: 4.4.94+404094 environment: sdk: ">=2.7.0 <3.0.0" @@ -180,6 +179,7 @@ dependencies: in_app_review: ^2.0.3 badges: ^2.0.1 + flutter_app_icon_badge: ^2.0.0 syncfusion_flutter_sliders: ^19.3.55 searchable_dropdown: ^1.1.3 dropdown_search: 0.4.9 @@ -199,6 +199,10 @@ dependencies: signalr_core: ^1.1.1 wave: ^0.2.0 sms_retriever: ^1.0.0 + sms_otp_auto_verify: ^2.1.0 + flutter_ios_voip_kit: ^0.0.5 + + payfort_plugin: ^0.3.1 dependency_overrides: provider : ^5.0.0