diff --git a/ios/Podfile b/ios/Podfile index 264db98d..5495f0ca 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -48,7 +48,7 @@ post_install do |installer| 'PERMISSION_CAMERA=1', 'PERMISSION_MICROPHONE=1', ## dart: PermissionGroup.calendar - 'PERMISSION_EVENTS=1', + 'PERMISSION_EVENTS_FULL_ACCESS=1', ## dart: PermissionGroup.reminders 'PERMISSION_REMINDERS=1', ] diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 65a0bf75..43474d39 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -59,6 +59,10 @@ This App requires access to Bluetooth to connect blood pressure & blood sugar devices with the app to analyze the data. NSCalendarsUsageDescription This app requires calendar access to set reminders for Virtual & Normal Appointments. + NSCalendarsWriteOnlyAccessUsageDescription + This app requires calendar access to set reminders for Virtual & Normal Appointments. + NSCalendarsFullAccessUsageDescription + This app requires calendar access to set reminders for Virtual & Normal Appointments. NSCameraUsageDescription This app requires camera access to enable virtual consultation between patient & doctor NSContactsUsageDescription diff --git a/lib/config/config.dart b/lib/config/config.dart index 24d6c620..3b774575 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -21,14 +21,16 @@ var PACKAGES_ORDER_HISTORY = '/api/orders/items'; var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; // var BASE_URL = 'http://10.50.100.198:2018/'; var BASE_URL = 'https://uat.hmgwebservices.com/'; - //var BASE_URL = 'https://hmgwebservices.com/'; +// var BASE_URL = 'https://hmgwebservices.com/'; // var BASE_URL = 'https://orash.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidamergeuat.cloudsolutions.com.sa/'; // var BASE_URL = 'https://webservices.hmg.com/'; -// Pharmacy UAT URLsProductDetailService +// var BASE_URL = 'http://10.50.100.198:4422/'; + +// Pharmacy UAT URLs // var BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; // var PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; @@ -36,6 +38,8 @@ var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; var BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapi/api/'; var PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapi/api/'; +var PHARMACY_REDIRECT_URL = 'https://bit.ly/AlhabibPharmacy'; + // Pharmacy VidaPlus URLs // var BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapitest/api/'; // var PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapitest/api/'; @@ -335,7 +339,7 @@ var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnari var CHANNEL = 3; var GENERAL_ID = 'Cs2020@2016\$2958'; var IP_ADDRESS = '10.20.10.20'; -var VERSION_ID = 11.1; +var VERSION_ID = 11.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 63619f59..3f3074d3 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1901,4 +1901,6 @@ const Map localizedValues = { "habibCallCenter": {"en": "Please contact AlHabib call center to update your insurance manually.", "ar": "يرجى الاتصال بمركز اتصال الحبيب لتحديث التأمين الخاص بك يدوياً."}, "cashAmountUpdateInsurance": {"en": "Please note that this is the cash amount, If you want to update your insurance, Please tap below:", "ar": "يرجى ملاحظة أن هذا هو المبلغ النقدي، إذا كنت ترغب في تحديث التأمين الخاص بك، يرجى النقر أدناه:"}, "validInsurance": {"en": "Do you have a valid insurance?", "ar": "هل لديك تأمين صالح؟"}, + "checkInViaLocation": {"en": "Check-In Via Location", "ar": "تسجيل الوصول عبر الموقع"}, + "locationCheckInError": {"en": "Please make sure that you're within the hospital location to perform online check-in.", "ar": "يرجى التأكد من تواجدك داخل موقع المستشفى لإجراء تسجيل الوصول عبر الإنترنت."}, }; \ No newline at end of file diff --git a/lib/core/model/privilege/ProjectDetailListModel.dart b/lib/core/model/privilege/ProjectDetailListModel.dart new file mode 100644 index 00000000..782c376b --- /dev/null +++ b/lib/core/model/privilege/ProjectDetailListModel.dart @@ -0,0 +1,32 @@ +class ProjectDetailListModel { + int? projectID; + String? latitude; + String? longitude; + int? geofenceRadius; + String? checkInQrCode; + + ProjectDetailListModel( + {this.projectID, + this.latitude, + this.longitude, + this.geofenceRadius, + this.checkInQrCode}); + + ProjectDetailListModel.fromJson(Map json) { + projectID = json['ProjectID']; + latitude = json['Latitude']; + longitude = json['Longitude']; + geofenceRadius = json['GeofenceRadius']; + checkInQrCode = json['CheckInQrCode']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + data['GeofenceRadius'] = this.geofenceRadius; + data['CheckInQrCode'] = this.checkInQrCode; + return data; + } +} diff --git a/lib/core/service/ancillary_orders_service.dart b/lib/core/service/ancillary_orders_service.dart index a9608682..99babdfd 100644 --- a/lib/core/service/ancillary_orders_service.dart +++ b/lib/core/service/ancillary_orders_service.dart @@ -54,15 +54,18 @@ class AncillaryOrdersService extends BaseService { return Future.value(localRes); } - Future getOrdersDetails(appointmentNo, orderNo, projectID) async { + Future getOrdersDetails(appointmentNo, orderNo, projectID) async { Map body = Map(); body['AppointmentNo_Vida'] = appointmentNo; body['OrderNo'] = orderNo; body['ProjectID'] = projectID; hasError = false; + + dynamic localRes; + await baseAppClient.post(GET_ANCILLARY_ORDERS_DETAILS, onSuccess: (dynamic response, int statusCode) { + localRes = response; _ancillaryProcLists = []; - response['AncillaryOrderProcList'].forEach((item) { ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); }); @@ -70,5 +73,6 @@ class AncillaryOrdersService extends BaseService { hasError = true; super.error = error; }, body: body); + return Future.value(localRes); } } diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 55a39d0a..c795394f 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -90,7 +90,7 @@ class BaseAppClient { : IS_DENTAL_ALLOWED_BACKEND; } - body['DeviceTypeID'] = Platform.isIOS ? 1 : 2; + body['DeviceTypeID'] = Platform.isIOS ? 1 : await Utils.isGoogleServicesAvailable() ? 2 : 3; if (!body.containsKey('IsPublicRequest')) { // if (!body.containsKey('PatientType')) { diff --git a/lib/core/service/privilege_service.dart b/lib/core/service/privilege_service.dart index 560c0628..b3f2269a 100644 --- a/lib/core/service/privilege_service.dart +++ b/lib/core/service/privilege_service.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/privilege/HMCProjectListModel.dart'; import 'package:diplomaticquarterapp/core/model/privilege/PrivilegeModel.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; import 'package:diplomaticquarterapp/core/model/privilege/VidaPlusProjectListModel.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/main.dart'; @@ -9,6 +10,7 @@ class PrivilegeService extends BaseService { List privilegeModelList = []; List vidaPlusProjectListModel = []; List hMCProjectListModel = []; + List projectDetailListModel = []; Future getPrivilege() async { Map body = Map(); @@ -29,6 +31,12 @@ class PrivilegeService extends BaseService { hMCProjectListModel.add(HMCProjectListModel.fromJson(item)); }); } + + if (response['ProjectDetailList'].length != 0) { + response['ProjectDetailList'].forEach((item) { + projectDetailListModel.add(ProjectDetailListModel.fromJson(item)); + }); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModels/ancillary_orders_view_model.dart b/lib/core/viewModels/ancillary_orders_view_model.dart index 8d601f20..51b12087 100644 --- a/lib/core/viewModels/ancillary_orders_view_model.dart +++ b/lib/core/viewModels/ancillary_orders_view_model.dart @@ -10,11 +10,10 @@ class AnciallryOrdersViewModel extends BaseViewModel { bool hasError = false; AncillaryOrdersService _ancillaryService = locator(); - List get ancillaryLists => - _ancillaryService.ancillaryLists; - List get ancillaryListsDetails => - _ancillaryService.ancillaryProcLists; + List get ancillaryLists => _ancillaryService.ancillaryLists; + + List get ancillaryListsDetails => _ancillaryService.ancillaryProcLists; Future getOrders() async { hasError = false; @@ -30,7 +29,7 @@ class AnciallryOrdersViewModel extends BaseViewModel { Future getOrdersDetails(appointmentNo, orderNo, projectID) async { hasError = false; setState(ViewState.Busy); - await _ancillaryService.getOrdersDetails(appointmentNo, orderNo, projectID ); + await _ancillaryService.getOrdersDetails(appointmentNo, orderNo, projectID); if (_ancillaryService.hasError) { error = _ancillaryService.error!; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index 80e90713..45c4e95c 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/privilege/HMCProjectListModel.dart'; import 'package:diplomaticquarterapp/core/model/privilege/PrivilegeModel.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; import 'package:diplomaticquarterapp/core/model/privilege/VidaPlusProjectListModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; @@ -53,11 +54,14 @@ class ProjectViewModel extends BaseViewModel { List privilegeChildUser = []; List _vidaPlusProjectListModel = []; List _hMCProjectListModel = []; + List _projectDetailListModel = []; List get privileges => isLoginChild ? privilegeChildUser : privilegeChildUser; List get vidaPlusProjectList => _vidaPlusProjectListModel; List get hMCProjectListModel => _hMCProjectListModel; + List get projectDetailListModel => _projectDetailListModel; + List selectedBodyPartList = []; late StreamSubscription subscription; @@ -127,6 +131,11 @@ class ProjectViewModel extends BaseViewModel { notifyListeners(); } + setProjectsDetailList(List projectDetailListModel) { + _projectDetailListModel = projectDetailListModel; + notifyListeners(); + } + setHMCProjectList(List hMCProjectListModel) { _hMCProjectListModel = hMCProjectListModel; notifyListeners(); diff --git a/lib/main.dart b/lib/main.dart index 44be8712..1842c15e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -161,7 +161,7 @@ class _MyApp extends State { builder: (_, mchild) { return MediaQuery( data: MediaQuery.of(context).copyWith( - textScaleFactor: 1.0, + textScaler: TextScaler.linear(1.0), ), //set desired text scale factor here child: mchild! ); diff --git a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart index 2ea76b65..daf11a8f 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_step_two_page.dart @@ -35,7 +35,7 @@ class _NewEReferralStepTowPageState extends State { TextEditingController _patientNameTextController = TextEditingController(); TextEditingController _patientIdentificationTextController = TextEditingController(); String mobileNo = ""; - late GetAllCitiesResponseModel _selectedCity; + GetAllCitiesResponseModel _selectedCity =GetAllCitiesResponseModel(); late GetAllSharedRecordsByStatusList selectedPatientFamily; @@ -297,7 +297,7 @@ class _NewEReferralStepTowPageState extends State { } String getRelationName() { - if (_selectedCity != null) + if (_selectedCity?.description != null) return _selectedCity.description!; else return TranslationBase.of(context).selectCity /*TranslationBase.of(context).selectHospital*/; diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart index 8858889d..915703aa 100644 --- a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; @@ -23,6 +24,7 @@ import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:flutter_svg/flutter_svg.dart'; class AnicllaryOrdersDetails extends StatefulWidget { final dynamic appoNo; @@ -45,11 +47,15 @@ class _AnicllaryOrdersState extends State with SingleTic String? selectedInstallmentPlan; List selectedProcList = []; + List _ancillaryProcLists = []; String? tamaraPaymentStatus; String? tamaraOrderID; void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getAncillaryOrderDetails(); + }); super.initState(); } @@ -57,12 +63,21 @@ class _AnicllaryOrdersState extends State with SingleTic super.dispose(); } - void getAncillaryOrderDetails(AnciallryOrdersViewModel model) { + void getAncillaryOrderDetails() { GifLoaderDialogUtils.showMyDialog(context); - model.getOrdersDetails(widget.appoNo, widget.orderNo, widget.projectID).then((value) { - addToSelectedProcedures(model); + AncillaryOrdersService ancillaryOrdersService = new AncillaryOrdersService(); + ancillaryOrdersService.getOrdersDetails(widget.appoNo, widget.orderNo, widget.projectID).then((response) { + _ancillaryProcLists = []; + selectedProcList = []; + if (response['AncillaryOrderProcList'] != null && response['AncillaryOrderProcList'].length != 0) { + response['AncillaryOrderProcList'].forEach((item) { + _ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); + }); + addToSelectedProcedures(); + } GifLoaderDialogUtils.hideDialog(context); }).catchError((err) { + AppToast.showErrorToast(message: err.toString()); GifLoaderDialogUtils.hideDialog(context); }); } @@ -72,83 +87,74 @@ class _AnicllaryOrdersState extends State with SingleTic projectViewModel = Provider.of(context); localContext = context; AppGlobal.context = context; - return BaseView( - onModelReady: (model) { - // getAncillaryOrderDetails(model); - model.getOrdersDetails(widget.appoNo, widget.orderNo, widget.projectID).then((value) { - addToSelectedProcedures(model); - }); - }, - builder: (_, model, widget) => AppScaffold( - isShowAppBar: true, - showNewAppBar: true, - showNewAppBarTitle: true, - baseViewModel: model, - appBarTitle: TranslationBase.of(context).anicllaryOrders, - body: SingleChildScrollView( - padding: EdgeInsets.all(12), - child: model.ancillaryListsDetails.length > 0 - ? Column(children: [ - getPatientInfo(model), - getAncillaryDetails(model), - ]) - : getNoDataWidget(context), - ), - bottomSheet: model.ancillaryListsDetails.length > 0 - ? Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 5, - blurRadius: 7, - offset: Offset(0, 3), // changes position of shadow - ), - ], - ), - padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), - width: double.infinity, - // color: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: 12), - Text( - TranslationBase.of(context).YouCanPayByTheFollowingOptions, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.64, - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.75, - child: getPaymentMethods(), - ), - _amountView(TranslationBase.of(context).patientShareTotalToDo, getTotalValue() + " " + TranslationBase.of(context).sar, isBold: true, isTotal: true), - SizedBox(height: 12), - DefaultButton( - TranslationBase.of(context).payNow.toUpperCase(), - selectedProcList!.length > 0 - ? () { - if (getTotalValue() != "0.00") { - makePayment(model); - } else { - autoGenerateInvoice(); - } - } - : null, - color: CustomColors.green, - disabledColor: CustomColors.grey2, - ), - ], - ), + return AppScaffold( + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + appBarTitle: TranslationBase.of(context).anicllaryOrders, + body: SingleChildScrollView( + padding: EdgeInsets.all(12), + child: _ancillaryProcLists.isNotEmpty + ? Column( + children: [ + getPatientInfo(), + getAncillaryDetails(), + ], ) - : Container(), + : getNoDataWidget(context), + ), + bottomSheet: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), + width: double.infinity, + // color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + Text( + TranslationBase.of(context).YouCanPayByTheFollowingOptions, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + child: getPaymentMethods(), + ), + _amountView(TranslationBase.of(context).patientShareTotalToDo, getTotalValue() + " " + TranslationBase.of(context).sar, isBold: true, isTotal: true), + SizedBox(height: 12), + DefaultButton( + TranslationBase.of(context).payNow.toUpperCase(), + selectedProcList.length > 0 + ? () { + if (getTotalValue() != "0.00") { + makePayment(); + } else { + autoGenerateInvoice(); + } + } + : null, + color: selectedProcList.length > 0 ? CustomColors.green : CustomColors.grey2, + disabledColor: CustomColors.grey2, + ), + ], + ), ), ); } @@ -183,7 +189,7 @@ class _AnicllaryOrdersState extends State with SingleTic ); } - Widget getPatientInfo(AnciallryOrdersViewModel model) { + Widget getPatientInfo() { return Padding( child: Column( children: [ @@ -276,7 +282,7 @@ class _AnicllaryOrdersState extends State with SingleTic ), mWidth(3), Text( - model.ancillaryListsDetails[0].appointmentNo.toString(), + _ancillaryProcLists[0].appointmentNo.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, @@ -299,7 +305,7 @@ class _AnicllaryOrdersState extends State with SingleTic ), mWidth(3), Text( - model.ancillaryListsDetails[0].ancillaryOrderProcDetailsList![0].orderNo.toString(), + _ancillaryProcLists[0].ancillaryOrderProcDetailsList![0].orderNo.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, @@ -324,7 +330,7 @@ class _AnicllaryOrdersState extends State with SingleTic mWidth(3), Expanded( child: Text( - model.ancillaryListsDetails[0].companyName.toString(), + _ancillaryProcLists[0].companyName.toString(), overflow: TextOverflow.clip, style: TextStyle( fontWeight: FontWeight.w600, @@ -349,7 +355,7 @@ class _AnicllaryOrdersState extends State with SingleTic ), mWidth(3), Text( - model.ancillaryListsDetails[0].insurancePolicyNo.toString(), + _ancillaryProcLists[0].insurancePolicyNo.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, @@ -369,16 +375,11 @@ class _AnicllaryOrdersState extends State with SingleTic ); } - // Widget getAncillaryDetails(AnciallryOrdersViewModel model) { - // Map newMap = groupBy(model.ancillaryListsDetails[0].ancillaryOrderProcDetailsList!, (obj) => obj.procedureCategoryName); - // return Padding(padding: EdgeInsets.only(top: 0, bottom: 200), child: getHeaderDetails(newMap)); - // } -// Changed By Aamir - Widget getAncillaryDetails(AnciallryOrdersViewModel model) { - Map> newMap = {}; + - // Grouping the list manually by the 'procedureCategoryName' key - model.ancillaryListsDetails[0].ancillaryOrderProcDetailsList!.forEach((obj) { + Widget getAncillaryDetails() { + Map> newMap = {}; + _ancillaryProcLists[0].ancillaryOrderProcDetailsList!.forEach((obj) { String key = obj.procedureCategoryName!; if (newMap.containsKey(key)) { newMap[key]!.add(obj); @@ -511,35 +512,35 @@ class _AnicllaryOrdersState extends State with SingleTic return tableRow; } - makePayment(AnciallryOrdersViewModel model) { + makePayment() { showDraggableDialog( context, PaymentMethod( onSelectedMethod: (String method, [String? selectedInstallmentPlan]) { selectedPaymentMethod = method; - this.selectedInstallmentPlan = selectedInstallmentPlan!; - openPayment(selectedPaymentMethod, projectViewModel.user!, double.parse(getTotalValue()), AppoitmentAllHistoryResultList(), model, selectedInstallmentPlan); + this.selectedInstallmentPlan = selectedInstallmentPlan; + openPayment(selectedPaymentMethod, projectViewModel.user, double.parse(getTotalValue()), AppoitmentAllHistoryResultList(), selectedInstallmentPlan); }, patientShare: double.parse(getTotalValue()), - isFromAdvancePayment: !projectViewModel!.havePrivilege(94), + isFromAdvancePayment: !projectViewModel.havePrivilege(94), )); } - openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo, AnciallryOrdersViewModel model, [String? selectedInstallmentPlan]) { + openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo, [String? selectedInstallmentPlan]) { browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); - transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user!.patientID!); + transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!); browser.openPaymentBrowser( amount, "Ancillary Orders Payment", transID, widget.projectID.toString(), - projectViewModel.user!.emailAddress!, + projectViewModel.user.emailAddress!, paymentMethod, - projectViewModel.user!.patientType, - projectViewModel.user!.firstName! + " " + projectViewModel.user!.lastName!, - projectViewModel.user!.patientID, + projectViewModel.user.patientType, + projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, + projectViewModel.user.patientID, authenticatedUser, browser, false, @@ -547,10 +548,10 @@ class _AnicllaryOrdersState extends State with SingleTic // Need to get new Service ID from Ayman for Ancillary Tamara "", context, - model.ancillaryListsDetails[0].appointmentDate, - model.ancillaryListsDetails[0].appointmentNo, - model.ancillaryListsDetails[0].clinicID, - model.ancillaryListsDetails[0].doctorID, + _ancillaryProcLists[0].appointmentDate, + _ancillaryProcLists[0].appointmentNo, + _ancillaryProcLists[0].clinicID, + _ancillaryProcLists[0].doctorID, selectedInstallmentPlan); } @@ -736,16 +737,18 @@ class _AnicllaryOrdersState extends State with SingleTic } } - addToSelectedProcedures(AnciallryOrdersViewModel model) { - if (model.ancillaryListsDetails.isNotEmpty) { + addToSelectedProcedures() { + if (_ancillaryProcLists.isNotEmpty) { selectedProcList.clear(); - model.ancillaryListsDetails[0].ancillaryOrderProcDetailsList!.forEach((element) { - if (!isProcedureDisabled(element)) { - selectedProcList.add(element); - } - }); - setState(() {}); + if (_ancillaryProcLists[0].ancillaryOrderProcDetailsList != null) { + _ancillaryProcLists[0].ancillaryOrderProcDetailsList!.forEach((element) { + if (!isProcedureDisabled(element)) { + selectedProcList.add(element); + } + }); + } else {} } + setState(() {}); } String getInsuranceText(value) { diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index 021d4bf2..5c815605 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -94,7 +94,7 @@ class _BookSuccessState extends State { widget.docObject.projectName!, null, null, - widget.docObject.nationalityFlagURL!, + widget.docObject.nationalityFlagURL ?? "", widget.docObject.doctorRate, null, widget.docObject.noOfPatientsRate, @@ -174,6 +174,7 @@ class _BookSuccessState extends State { elevation: 0, onPressed: () { // navigateToQR(context); + GifLoaderDialogUtils.showMyDialog(context); getAppoQR(context); }, child: Text(TranslationBase.of(context).viewQR.toUpperCase(), style: TextStyle(fontSize: 18.0, color: Colors.white)), @@ -190,7 +191,7 @@ class _BookSuccessState extends State { child: Container( color: CustomColors.appBackgroudGreyColor, margin: EdgeInsets.all(14), - height: 150.0, + height: widget.isCash ? 150.0 : 50, child: Column( children: [ Row( diff --git a/lib/pages/BookAppointment/QRCode.dart b/lib/pages/BookAppointment/QRCode.dart index 1844a3d6..0f253b63 100644 --- a/lib/pages/BookAppointment/QRCode.dart +++ b/lib/pages/BookAppointment/QRCode.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; @@ -17,7 +18,9 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.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/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; @@ -49,6 +52,8 @@ class _QRCodeState extends State { late BuildContext _context; late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); @override void initState() { @@ -90,6 +95,20 @@ class _QRCodeState extends State { } else {} } + startLocationCheckIn() async { + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, widget.appointment!.projectID); + double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; + print(dist); + if (dist <= projectDetailListModel.geofenceRadius!) { + sendNfcCheckInRequest(projectDetailListModel.checkInQrCode!); + } else { + AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError); + } + }); + } + @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); @@ -107,7 +126,7 @@ class _QRCodeState extends State { DoctorHeader( headerModel: HeaderModel( widget.appointment!.doctorTitle! + " " + widget.appointment!.doctorNameObj!, - widget.appointment!.doctorID!, + widget.appointment!.doctorID ?? 0, widget.appointment!.doctorImageURL!, widget.appointment!.doctorSpeciality!, "", @@ -256,6 +275,24 @@ class _QRCodeState extends State { ), ); + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(102)) { + startLocationCheckIn(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).checkInViaLocation, + imagePath: 'location.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(102), + width: 70.0, + height: 70.0, + ), + ), + ); + return optionsList; } diff --git a/lib/pages/BookAppointment/book_reminder_page.dart b/lib/pages/BookAppointment/book_reminder_page.dart index 6a124fd2..56c48589 100644 --- a/lib/pages/BookAppointment/book_reminder_page.dart +++ b/lib/pages/BookAppointment/book_reminder_page.dart @@ -1,5 +1,6 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/main.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/header_model.dart'; @@ -82,10 +83,10 @@ class _BookReminderPageState extends State { widget.docObject.projectName!, null, null, - widget.docObject.nationalityFlagURL!, - widget.docObject.doctorRate!, + widget.docObject.nationalityFlagURL ?? "", + widget.docObject.doctorRate?? 0, null, - widget.docObject.noOfPatientsRate!, + widget.docObject.noOfPatientsRate ?? 0, "", ), isNeedToShowButton: false, @@ -188,8 +189,6 @@ class _BookReminderPageState extends State { backgroundColor: CustomColors.green, elevation: 0, onPressed: () async { - print(widget.patientShareResponse); - print(widget.patientShareResponse.appointmentNo); showReminderDialog( context, widget.dateTime!, @@ -201,7 +200,8 @@ class _BookReminderPageState extends State { AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); navigateToBookSuccess(context); }, - title: "" + title: null, + description: null ); projectViewModel.analytics.appointment.appointment_reminder(true); }, diff --git a/lib/pages/BookAppointment/widgets/reminder_dialog.dart b/lib/pages/BookAppointment/widgets/reminder_dialog.dart index a68fbfa4..37f343ad 100644 --- a/lib/pages/BookAppointment/widgets/reminder_dialog.dart +++ b/lib/pages/BookAppointment/widgets/reminder_dialog.dart @@ -24,28 +24,25 @@ showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, S if (Platform.isAndroid) { if (await PermissionService.isCalendarPermissionEnabled()) { _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - onSuccess: onSuccess, title: title ?? "", description: description ?? "", onMultiDateSuccess: onMultiDateSuccess ?? (int) {}); + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess ?? (int) {}); } else { Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async { if (await Permission.calendarFullAccess.request().isGranted) { _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - onSuccess: onSuccess, title: title ?? "", description: description ?? "", onMultiDateSuccess: onMultiDateSuccess ?? (int) {}); + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess ?? (int) {}); } }); } } else { if (await Permission.calendarFullAccess.request().isGranted) { - print(await Permission.calendarFullAccess.request().isGranted); _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - onSuccess: onSuccess, title: title ?? "", description: description ?? "", onMultiDateSuccess: onMultiDateSuccess ?? (int) {}); + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess ?? (int) {}); } } } -final CalendarPlugin _myPlugin = CalendarPlugin(); - Future _showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, - {required Function onSuccess, required String title, required String description, required Function(int) onMultiDateSuccess}) async { + {required Function onSuccess, String? title, String? description, required Function(int) onMultiDateSuccess}) async { return showDialog( context: context, barrierDismissible: true, // user must tap button! @@ -78,17 +75,21 @@ Future _showReminderDialog(BuildContext context, DateTime dateTime, String text = "2 hours"; } - if (onMultiDateSuccess == null) { + if (onMultiDateSuccess.call(i) == null) { CalendarUtils calendarUtils = await CalendarUtils.getInstance(); - calendarUtils - .createOrUpdateEvent( - title: title ?? TranslationBase.of(context).reminderTitle + " " + doctorName, - description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, - scheduleDateTime: dateTime, - eventId: eventId) - .then((value) {}); + try { + await calendarUtils.createOrUpdateEvent( + title: title ?? TranslationBase + .of(context) + .reminderTitle + " " + doctorName, + description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, + scheduleDateTime: dateTime, + eventId: eventId); - onSuccess(); + onSuccess(); + }catch(e){ + print(e); + } } else { onMultiDateSuccess(i); } diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index b03a6db2..19ccae1e 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -47,7 +47,7 @@ class AddNewChildPage extends StatefulWidget { class _AddNewChildPageState extends State { late int tappedIndex; - late int checkedValue; + int checkedValue =0; @override void initState() { diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index 29ed7736..7889c531 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -1,8 +1,10 @@ import 'dart:collection'; +import 'dart:convert'; 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/main.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; @@ -30,7 +32,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:provider/provider.dart'; - import 'widgets/AppointmentActions.dart'; class AppointmentDetails extends StatefulWidget { @@ -50,7 +51,7 @@ class _AppointmentDetailsState extends State with SingleTick static TabController? _tabController; AppSharedPreferences sharedPref = AppSharedPreferences(); - List doctorDetailsList =[]; + List doctorDetailsList = []; ToDoCountProviderModel? toDoProvider; ProjectViewModel? projectViewModel; @@ -306,10 +307,12 @@ class _AppointmentDetailsState extends State with SingleTick context, FadePage( page: BookConfirm( - doctor: getDoctorObject(), - isLiveCareAppointment: widget.appo.isLiveCareAppointment!, - selectedDate: DocAvailableAppointments.selectedDate!, - selectedTime: DocAvailableAppointments.selectedTime!, initialSlotDuration: 0,))); + doctor: getDoctorObject(), + isLiveCareAppointment: widget.appo.isLiveCareAppointment!, + selectedDate: DocAvailableAppointments.selectedDate!, + selectedTime: DocAvailableAppointments.selectedTime!, + initialSlotDuration: 0, + ))); } void getDoctorRatingsDetails() { @@ -357,41 +360,50 @@ class _AppointmentDetailsState extends State with SingleTick margin: EdgeInsets.only(bottom: 5.0), padding: EdgeInsets.all(10.0), child: Text(TranslationBase.of(context).doctorRating, style: TextStyle(fontSize: 22.0, color: Colors.black))), - Container(margin: EdgeInsets.only(top: 0.0), child: Text(this.widget.appo.actualDoctorRate!.ceilToDouble().toString(), style: TextStyle(fontSize: 32.0, color: Colors.black))), Container( - margin: EdgeInsets.only(top: 5.0), - alignment: Alignment.center, - child: - // RatingBar.readOnly( - // initialRating: this.widget.appo.actualDoctorRate.toDouble(), - // size: 35.0, - // filledColor: Colors.yellow[700], - // emptyColor: Colors.grey[500], - // isHalfAllowed: true, - // halfFilledIcon: Icons.star_half, - // filledIcon: Icons.star, - // emptyIcon: Icons.star, - // ), - RatingBar( - initialRating: this.widget.appo.actualDoctorRate!.toDouble(), - direction: Axis.horizontal, - allowHalfRating: true, - itemCount: 5, - itemSize: 20, - ignoreGestures: true, - ratingWidget: RatingWidget( - full: Icon(Icons.star, color: CustomColors.accentColor,), - half: Icon(Icons.star_half, color: CustomColors.accentColor,), - empty: Icon(Icons.star, color: CustomColors.accentColor,), - ), - tapOnlyMode: true, - unratedColor: Colors.grey[500], - itemPadding: EdgeInsets.symmetric(horizontal: 4.0), - onRatingUpdate: (rating) { - print(rating); - }, - ) - ), + margin: EdgeInsets.only(top: 0.0), child: Text(this.widget.appo.actualDoctorRate!.ceilToDouble().toString(), style: TextStyle(fontSize: 32.0, color: Colors.black))), + Container( + margin: EdgeInsets.only(top: 5.0), + alignment: Alignment.center, + child: + // RatingBar.readOnly( + // initialRating: this.widget.appo.actualDoctorRate.toDouble(), + // size: 35.0, + // filledColor: Colors.yellow[700], + // emptyColor: Colors.grey[500], + // isHalfAllowed: true, + // halfFilledIcon: Icons.star_half, + // filledIcon: Icons.star, + // emptyIcon: Icons.star, + // ), + RatingBar( + initialRating: this.widget.appo.actualDoctorRate!.toDouble(), + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 20, + ignoreGestures: true, + ratingWidget: RatingWidget( + full: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + half: Icon( + Icons.star_half, + color: CustomColors.accentColor, + ), + empty: Icon( + Icons.star, + color: CustomColors.accentColor, + ), + ), + tapOnlyMode: true, + unratedColor: Colors.grey[500], + itemPadding: EdgeInsets.symmetric(horizontal: 4.0), + onRatingUpdate: (rating) { + print(rating); + }, + )), Container( margin: EdgeInsets.only(top: 10.0), child: Text(this.widget.appo.noOfPatientsRate.toString() + " " + TranslationBase.of(context).reviews, style: TextStyle(fontSize: 14.0, color: Colors.black))), @@ -510,10 +522,10 @@ class _AppointmentDetailsState extends State with SingleTick minWidth: MediaQuery.of(context).size.width, height: 40.0, child: CustomTextButton( - elevation: 0.0, - backgroundColor: Colors.white, - disabledForegroundColor: new Color(0xFFbcc2c4).withOpacity(0.38), - disabledBackgroundColor: new Color(0xFFbcc2c4).withOpacity(0.12), + elevation: 0.0, + backgroundColor: Colors.white, + disabledForegroundColor: new Color(0xFFbcc2c4).withOpacity(0.38), + disabledBackgroundColor: new Color(0xFFbcc2c4).withOpacity(0.12), onPressed: () { Navigator.of(context).pop(); }, @@ -612,15 +624,24 @@ class _AppointmentDetailsState extends State with SingleTick 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); + if (calendarUtils.calendars.length > 1) { + calendarUtils.calendars.forEach((calender) { + calendarUtils.retrieveEvents(calender.id!, params).then((value) { + Result> events = value; + events.data!.forEach((element) { + if (element.title!.contains(widget.appo.doctorNameObj!)) calendarUtils.deleteEvent(calender, element); + }); + }); }); - }); + } else { + 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() { diff --git a/lib/pages/MyAppointments/models/BookedButtons.dart b/lib/pages/MyAppointments/models/BookedButtons.dart index bec7f39c..66e4366f 100644 --- a/lib/pages/MyAppointments/models/BookedButtons.dart +++ b/lib/pages/MyAppointments/models/BookedButtons.dart @@ -38,6 +38,7 @@ class BookedButtons { "subtitle": TranslationBase.of(AppGlobal.context).location, "icon": "hosp_location.svg", "caller": "navigateToProject", - } + }, + {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"} ]; } diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index 769b6761..560163ae 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -34,11 +34,15 @@ import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profil import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:intl/intl.dart'; import 'package:map_launcher/map_launcher.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'dart:io'; +import 'package:huawei_map/huawei_map.dart' as hmsMap; + class AppointmentActions extends StatefulWidget { AppoitmentAllHistoryResultList appo; @@ -55,10 +59,13 @@ class AppointmentActions extends StatefulWidget { class _AppointmentActionsState extends State { List appoButtonsList = []; + static bool isHuawei =false; + late HmsApiAvailability hmsApiAvailability; @override void initState() { _getAppointmentActionButtons(); + checkIsHuawei(); super.initState(); } @@ -73,6 +80,7 @@ class _AppointmentActionsState extends State { padding: EdgeInsets.all(21), shrinkWrap: true, itemBuilder: (context, index) { + // bool shouldEnable = ((widget.appo.clinicID == 17 || widget.appo.clinicID == 47) || (widget.appo.isLiveCareAppointment && appoButtonsList[index].caller == "askDoc") || appoButtonsList[index].caller == "openReschedule"); bool shouldEnable = (((widget.appo.clinicID == 17 || widget.appo.clinicID == 47) && appoButtonsList[index].caller == "openReschedule") || (widget.appo.isLiveCareAppointment! && appoButtonsList[index].caller == "askDoc") || (Utils.isVidaPlusProject(projectViewModel, widget.appo.projectID!) && @@ -181,7 +189,7 @@ class _AppointmentActionsState extends State { _getConfirmedAppoActionsList(); } } else { - print("isConfirmed dynamic"); + print("isConfirmed Null"); } if (isBooked()) { if (widget.appo.isOnlineCheckedIN!) { @@ -190,7 +198,7 @@ class _AppointmentActionsState extends State { _getBookedAppoActionsList(); } } else { - print("isBooked dynamic"); + print("isBooked Null"); } if (isArrived()) { if (widget.appo.clinicID == 17) { @@ -199,10 +207,10 @@ class _AppointmentActionsState extends State { _getArrivedAppoActionsList(); } } else { - print("isArrived dynamic"); + print("isArrived Null"); } } else { - print("Appo dynamic"); + print("Appo Null"); } } @@ -455,13 +463,22 @@ class _AppointmentActionsState extends State { static Future openMap(double latitude, double longitude) async { await MapLauncher.showMarker( - mapType: MapType.google, + mapType: Platform.isAndroid ? isHuawei == true ? MapType.petal: MapType.google : MapType.apple, coords: Coords(latitude, longitude), title: "Sulaiman Al Habib", description: "Appointment Location", ); } + checkIsHuawei() async { + if( Platform.isAndroid) { + await hmsApiAvailability.isHMSAvailable().then((value) { + isHuawei = value == 0 ? true : false; + hmsMap.HuaweiMapInitializer.initializeMap(); + }); + print(isHuawei); + } + } askYourDoc() { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); @@ -586,30 +603,51 @@ class _AppointmentActionsState extends State { navigateToToDoPage(BuildContext context, ToDoCountProviderModel model) { if (widget.projectViewModel!.isLogin) { - if (model.count != 0) { - Navigator.push( - context, - FadePage( - page: ToDo( - isShowAppBar: true, - isFromMyAppointments: true, - appointment: widget.appo, - ))); - } else { - AppToast.showErrorToast(message: TranslationBase.of(context).upcomingEmpty); - } - } else { + // if (model.count != 0) { + getPatientAppointmentHistoryWithAppo(); + } + // else { + // AppToast.showErrorToast(message: TranslationBase.of(context).upcomingEmpty); + // } + else { Navigator.push( context, FadePage( page: ToDo( - isShowAppBar: true, - isFromMyAppointments: true, - appointment: widget.appo, - ))); + isShowAppBar: true, + isFromMyAppointments: true, + appointment: widget.appo, + ))); } } + +getPatientAppointmentHistoryWithAppo() { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service.getPatientAppointmentHistoryWithAppoNo(widget.appo.appointmentNo).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList.fromJson(res['AppoimentAllHistoryResultList'][0]); + Navigator.push( + context, + FadePage( + page: ToDo( + isShowAppBar: true, + isFromMyAppointments: true, + appointment: appo, + ), + ), + ); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + err != null ?? AppToast.showErrorToast(message: err); + }); +} rateAppointment() { widget.browser = new MyInAppBrowser(); var url = 'http://hmg.com/SitePages/pso.aspx?p=' + widget.appo.projectID.toString() + '.' + widget.appo.appointmentNo.toString() + '&c=1'; diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 1cd68226..cefaaa4f 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -568,9 +568,15 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { performNextAction(AppoitmentAllHistoryResultList appo) { switch (appo.nextAction) { + case 0: + // getAppoQR(context, appo); + break; case 10: confirmAppointment(appo); break; + case 15: + AppToast.showErrorToast(message: TranslationBase.of(context).upcomingPaymentPending); + break; case 20: getPatientShare(context, appo); // checkPatientNphiesEligibility(context, appo); @@ -859,7 +865,8 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { } dataLoaded = true; if (widget.isFromMyAppointments) { - getPatientShare(context, widget.appointment!); + performNextAction(widget.appointment!); + widget.isFromMyAppointments = false; } }); } else { diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index 0745daa8..da2c8e98 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -422,7 +422,8 @@ class _HomePageFragment2State extends State { flex: 1, child: InkWell( onTap: () { - if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!(); + if (projectViewModel.havePrivilege(100)) + widget.onPharmacyClick!(); }, child: Stack(children: [ Container( diff --git a/lib/pages/landing/home_page_2.dart b/lib/pages/landing/home_page_2.dart index fcff1f30..b6294922 100644 --- a/lib/pages/landing/home_page_2.dart +++ b/lib/pages/landing/home_page_2.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -11,6 +12,8 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher/url_launcher_string.dart'; import 'fragments/home_page_fragment2.dart'; import 'landing_page_pharmcy.dart'; @@ -48,7 +51,9 @@ class _HomePageState2 extends State { widget.onLoginClick!(); }, onPharmacyClick: () { - getPharmacyToken(model); + // getPharmacyToken(model); + Uri uri = Uri.parse(PHARMACY_REDIRECT_URL); + launchUrl(uri, mode: LaunchMode.externalApplication); }, onMedicalFileClick: () { widget.onMedicalFileClick!(); diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 02850e7c..13fa4e23 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -641,7 +641,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { projectViewModel.analytics.setUser(AuthenticatedUser()); } if (Platform.isIOS) { - String voipToken = await sharedPref.getString(APNS_TOKEN); + String? voipToken = await sharedPref.getString(APNS_TOKEN?? ""); // getOneSignalVOIPToken(voipToken); } } diff --git a/lib/pages/landing/widgets/services_view.dart b/lib/pages/landing/widgets/services_view.dart index e713989f..bafec12e 100644 --- a/lib/pages/landing/widgets/services_view.dart +++ b/lib/pages/landing/widgets/services_view.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -209,7 +210,9 @@ class ServicesView extends StatelessWidget { Navigator.push(context, FadePage(page: CMCPage())); locator().hmgServices.logServiceName('comprehensive medical checkup'); } else if (hmgServices.action == 5) { - getPharmacyToken(context); + // getPharmacyToken(context); + Uri uri = Uri.parse(PHARMACY_REDIRECT_URL); + launchUrl(uri, mode: LaunchMode.externalApplication); locator().hmgServices.logServiceName('al habib pharmacy'); } else if (hmgServices.action == 6) { Navigator.push(context, FadePage(page: MedicalProfilePageNew())); diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 15e9e0a0..d93a4e0d 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -47,16 +47,16 @@ class DoctorsListService extends BaseService { } var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); + // Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', + // "LanguageID": languageID == 'ar' ? 1 : 2, + // "IPAdress": "10.20.10.20", + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "generalid": 'Cs2020@2016\$2958', "PatientOutSA": authProvider.isLogin ? authUser.outSA : 0, "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, + // "DeviceTypeID": req.DeviceTypeID, "SessionID": "YckwoXhUmWBsnHKEKig", "ClinicID": clinicID, "ProjectID": projectID, @@ -393,10 +393,8 @@ class DoctorsListService extends BaseService { await baseAppClient.post(INSERT_SPECIFIC_APPOINTMENT, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { - logger.d(error); throw error; }, body: request); - logger.d(localRes); return Future.value(localRes); } catch (e) { logger.d(e); @@ -619,6 +617,19 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future getPatientAppointmentHistoryWithAppoNo(int appoNo) async { + Map request; + request = {"IsActiveAppointment": true, "AppointmentNo": appoNo, "IsComingFromCOC": false}; + dynamic localRes; + await baseAppClient.post(GET_PATIENT_APPOINTMENT_HISTORY, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + Future getPatientAppointmentHistory(bool isActiveAppointment, BuildContext context, {bool isForCOC = false}) async { Map request; diff --git a/lib/services/clinic_services/get_clinic_service.dart b/lib/services/clinic_services/get_clinic_service.dart index 296d2b00..3b3c3395 100644 --- a/lib/services/clinic_services/get_clinic_service.dart +++ b/lib/services/clinic_services/get_clinic_service.dart @@ -18,19 +18,7 @@ class ClinicListService extends BaseService { late double long; Future getClinicsList(context) async { - Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); - request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": null - }; + Map request = {}; dynamic localRes; @@ -44,21 +32,10 @@ class ClinicListService extends BaseService { } Future getActiveAppointmentNo(context) async { - Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); + Map request = {}; + request = { - // "LanguageID": languageID == 'ar' ? 1 : 2, - // "IPAdress": "10.20.10.20", - // "VersionID": req.VersionID, - // "Channel": req.Channel, - // "generalid": 'Cs2020@2016\$2958', - // "PatientOutSA": user.outSA, "IsActiveAppointment": true, - // "DeviceTypeID": req.DeviceTypeID, - // "PatientType": user.patientType, - // "PatientTypeID": user.patientType, - // "SessionID": null }; dynamic localRes; @@ -72,19 +49,7 @@ class ClinicListService extends BaseService { } Future getProjectsList(context) async { - Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - Request req = appGlobal.getPublicRequest(); - request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "TokenID": "", - "DeviceTypeID": req.DeviceTypeID, - "SessionID": null - }; + Map request = {}; dynamic localRes; @@ -113,9 +78,9 @@ class ClinicListService extends BaseService { "SelectedDate": "", "SelectedTime": "", "License": true, - "VersionID": 5.6, - "Channel": 3, - "LanguageID": languageID == 'ar' ? 1 : 2, + // "VersionID": 5.6, + // "Channel": 3, + // "LanguageID": languageID == 'ar' ? 1 : 2, "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016\$2958", "SessionID": null, @@ -155,11 +120,11 @@ class ClinicListService extends BaseService { request = { "ChiefComplaintID": chiefComplaintID, "ProjectID": projectID, - "VersionID": 5.6, - "Channel": 3, - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": req.IPAdress, - "generalid": req.generalid, + // "VersionID": 5.6, + // "Channel": 3, + // "LanguageID": languageID == 'ar' ? 1 : 2, + // "IPAdress": req.IPAdress, + // "generalid": req.generalid, "SessionID": null, "isDentalAllowedBackend": true, "Latitude": lat != null ? lat.toString() : "0.0", diff --git a/lib/splashPage.dart b/lib/splashPage.dart index cf0db4c0..c52a00ad 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; @@ -33,9 +34,8 @@ class _SplashScreenState extends State { super.initState(); Timer( Duration(seconds: 1, milliseconds: 500), - () { - loadPrivilege().then((value) { - print(value); + () async { + await loadPrivilege().then((value) { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (BuildContext context) => LandingPage(), @@ -46,8 +46,8 @@ class _SplashScreenState extends State { ); AppSharedPreferences().getAll().then((value) { - // debugPrint("ALL SHARED PREFERENCES!!!!!"); - // debugPrint(jsonEncode(value)); + debugPrint("ALL SHARED PREFERENCES!!!!!"); + debugPrint(jsonEncode(value)); }); } @@ -58,11 +58,11 @@ class _SplashScreenState extends State { projectProvider.setPrivilegeModelList(privilege: _privilegeService.privilegeModelList); projectProvider.setVidaPlusProjectList(_privilegeService.vidaPlusProjectListModel); projectProvider.setHMCProjectList(_privilegeService.hMCProjectListModel); + projectProvider.setProjectsDetailList(_privilegeService.projectDetailListModel); AppSharedPreferences().clear(); // Clearing Shared Preferences On App Launch AppSharedPreferences().setString(APP_LANGUAGE, projectProvider.isArabic ? "ar" : "en"); var themeNotifier = Provider.of(context, listen: false); themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins')); - // if (Platform.isIOS) PushNotificationHandler.getInstance().init(context); // Asyncronously } diff --git a/lib/uitl/CalendarUtils.dart b/lib/uitl/CalendarUtils.dart index add65f64..1b34d18b 100644 --- a/lib/uitl/CalendarUtils.dart +++ b/lib/uitl/CalendarUtils.dart @@ -59,7 +59,7 @@ class CalendarUtils { }); } - Future createOrUpdateEvent({String? title, String? description, DateTime? scheduleDateTime, String? eventId}) async { + Future createOrUpdateEvent({required String title, required String description, DateTime? scheduleDateTime, String? eventId}) async { RecurrenceRule recurrenceRule = RecurrenceRule( RecurrenceFrequency.Daily, // daysOfWeek: daysOfWeek, @@ -74,7 +74,7 @@ class CalendarUtils { TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime!, _currentLocation); - // print("eventId: " + eventId); + //print("eventId: " + eventId); // print("writableCalendars-name: " + writableCalendars.name); // print("writableCalendars-Id: " + writableCalendars.id); // print("writableCalendarsToString: " + writableCalendars.toString()); diff --git a/lib/uitl/location_util.dart b/lib/uitl/location_util.dart index 402d9f57..a40277c7 100644 --- a/lib/uitl/location_util.dart +++ b/lib/uitl/location_util.dart @@ -128,8 +128,8 @@ class LocationUtils { heading: 0.0, speed: 0.0, speedAccuracy: 1, - altitudeAccuracy: 0, - headingAccuracy: 0, + altitudeAccuracy: 0, + headingAccuracy: 0, // Added by Aamir ), ); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 16889d12..a4d61818 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2910,6 +2910,8 @@ class TranslationBase { String get habibCallCenter => localizedValues["habibCallCenter"][locale.languageCode]; String get cashAmountUpdateInsurance => localizedValues["cashAmountUpdateInsurance"][locale.languageCode]; String get validInsurance => localizedValues["validInsurance"][locale.languageCode]; + String get checkInViaLocation => localizedValues["checkInViaLocation"][locale.languageCode]; + String get locationCheckInError => localizedValues["locationCheckInError"][locale.languageCode]; } diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 17f072e7..21bef1ce 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -10,6 +10,7 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:crypto/crypto.dart' as crypto; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; @@ -45,6 +46,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_api_availability/google_api_availability.dart'; +import 'dart:math' show asin, cos, pi, pow, sin, sqrt; // import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; import 'package:provider/provider.dart'; @@ -803,6 +805,24 @@ class Utils { return false; } + static double distance(double lat1, double lon1, double lat2, double lon2) { + const r = 6372.8; // Earth radius in kilometers + + final dLat = _toRadians(lat2 - lat1); + final dLon = _toRadians(lon2 - lon1); + final lat1Radians = _toRadians(lat1); + final lat2Radians = _toRadians(lat2); + + final a = _haversin(dLat) + cos(lat1Radians) * cos(lat2Radians) * _haversin(dLon); + final c = 2 * asin(sqrt(a)); + + return r * c; + } + + static double _toRadians(double degrees) => degrees * pi / 180; + + static num _haversin(double radians) => pow(sin(radians / 2), 2); + static Widget tableColumnValueWithUnderLine(String text, {bool isLast = false, bool isCapitable = true}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -851,9 +871,17 @@ class Utils { return isHMCProject; } -// static String generateSignature() { -// -// } + static ProjectDetailListModel getProjectDetailObj(ProjectViewModel projectViewModel, int projectID) { + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); + projectViewModel.projectDetailListModel.forEach((element) { + if (element.projectID == projectID) { + projectDetailListModel = element; + } + }); + return projectDetailListModel; + } + + //static String generateSignature() {} } Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) { diff --git a/lib/widgets/others/floating_button_search.dart b/lib/widgets/others/floating_button_search.dart index d2da2564..c3e9e884 100644 --- a/lib/widgets/others/floating_button_search.dart +++ b/lib/widgets/others/floating_button_search.dart @@ -68,7 +68,6 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; -import 'package:speech_to_text/speech_to_text.dart'; import 'package:url_launcher/url_launcher.dart'; class FloatingSearchButton extends StatefulWidget { @@ -144,7 +143,7 @@ class _FloatingSearchButton extends State with TickerProvi if (p['startPopUp'] == 'true') { if (this.mounted) { new RoboSearch(context: context).showAlertDialog(context); - // initSpeechState().then((value) => {startVoiceSearch()}); + initSpeechState().then((value) => {startVoiceSearch()}); } } }); @@ -259,16 +258,19 @@ class _FloatingSearchButton extends State with TickerProvi // } // some time later... if(available) { - speech.stop(); + + // speech.listen( onResult: resultListener ); + // speech.stop(); speech.listen( onResult: resultListener, listenFor: Duration(seconds: 10), localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA', onSoundLevelChange: soundLevelListener, - cancelOnError: true, - partialResults: true, - onDevice: true, - listenMode: ListenMode.deviceDefault); + // cancelOnError: true, + // partialResults: true, + // onDevice: true, + // listenMode: stt.ListenMode.deviceDefault + ); } } diff --git a/pubspec.yaml b/pubspec.yaml index 5f16ef12..1382380b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: diplomaticquarterapp description: A new Flutter application. -version: 4.5.029+4050029 +version: 4.5.73+1 environment: sdk: ">=3.0.0 <3.13.0" @@ -121,7 +121,7 @@ dependencies: flutter_datetime_picker_plus: ^2.1.0 carousel_pro_nullsafety: ^2.0.0 flutter_local_notifications: any - device_calendar: ^4.2.0 + device_calendar: ^4.3.2 geolocator: ^9.0.2 geocoding: ^2.0.1 jiffy: ^6.2.1