Merge branch 'development_v2.5' of https://gitlab.com/Cloud_Solution/diplomatic-quarter into development_v2.5

# Conflicts:
#	lib/pages/BookAppointment/BookSuccess.dart
merge-requests/597/merge
haroon amjad 3 years ago
commit d344169399

@ -59,6 +59,16 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-FIRAnalyticsDebugEnabled"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-v"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"

@ -1,11 +1,16 @@
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Appointments/DentalChiefComplaintsModel.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../google-analytics.dart';
class Appointment{
final GALogger logger;
@ -55,12 +60,13 @@ class Appointment{
}
// R020
book_appointment_chief_complaints({@required String appointment_type, clinic, hospital, treatment}){
book_appointment_chief_complaints({@required String appointment_type, ListClinicCentralized clinic, HospitalsModel hospital, ListDentalChiefComplain treatment}){
GAnalytics.TREATMENT_TYPE = treatment.name;
logger('book_appointment_chief_complaints', parameters: {
'appointment_type' : appointment_type,
'clinic_type' : clinic,
'hospital_name' : hospital,
'treatment_type' : treatment,
'clinic_type' : clinic.clinicDescription,
'hospital_name' : hospital.name,
'treatment_type' : treatment.name,
});
}
@ -71,7 +77,7 @@ class Appointment{
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
@ -85,7 +91,7 @@ class Appointment{
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
@ -98,7 +104,7 @@ class Appointment{
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
@ -109,68 +115,81 @@ class Appointment{
// R024.1
book_appointment_time_selection({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){
final day = DateUtil.getWeekDay(dateTime.weekday);
final time = DateUtil.formatDateToTime(dateTime);
final hour = DateFormat('HH').format(dateTime);
logger('book_appointment_time_selection', parameters: {
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
'appointment_day' : day,
'appointment_hour' : time
'appointment_hour' : hour
});
}
// R024.2
book_appointment_review({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){
final day = DateUtil.getWeekDay(dateTime.weekday);
final time = DateUtil.formatDateToTime(dateTime);
final hour = DateFormat('HH').format(dateTime);
logger('book_appointment_review', parameters: {
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
'appointment_day' : day,
'appointment_hour' : time
'appointment_hour' : hour
});
}
// R025
book_appointment_click_confirm({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){
final day = DateUtil.getWeekDay(dateTime.weekday);
final time = DateUtil.formatDateToTime(dateTime);
final hour = DateFormat('HH').format(dateTime);
logger('book_appointment_click_confirm', parameters: {
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
'appointment_day' : day,
'appointment_hour' : time // '5-6'
'appointment_hour' : hour // '5-6'
});
}
// R026
book_appointment_confirmation_success({@required String appointment_type, @required DateTime dateTime, @required DoctorList doctor}){
final day = DateUtil.getWeekDay(dateTime.weekday);
final time = DateUtil.formatDateToTime(dateTime);
final hour = DateFormat('HH').format(dateTime);
logger('book_appointment_confirmation_success', parameters: {
'appointment_type' : appointment_type,
'clinic_type' : doctor.clinicName,
'hospital_name' : doctor.projectName,
'treatment_type' : doctor.clinicName,
'treatment_type' : GAnalytics.TREATMENT_TYPE ?? '',
'doctor_name' : doctor.name,
'doctor_nationality' : doctor.nationalityName,
'doctor_gender' : doctor.genderDescription,
'appointment_day' : day,
'appointment_hour' : time
'appointment_hour' : hour
});
}
// R049.1 // should be for appointment flow
appointment_actions(AppoitmentAllHistoryResultList appointment, String action){
logger('to_do_list_pay_now', parameters: {
'action_type' : action,
'flow_type' : GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE,
'appointment_type' : appointment.appointmentType,
'clinic_type_online' : appointment.clinicName,
'hospital_name' : appointment.projectName,
'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName,
'payment_type' : 'appointment',
});
}
@ -227,6 +246,8 @@ class Appointment{
// Note : - Payment flow beyond this step are same as listed under Advance Payment section of this document
appointment_detail_action({@required AppoitmentAllHistoryResultList appointment, @required String action}){
logger('appointment_detail_action', parameters: {
'action_type' : action,
'flow_type' : GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE,
});
}

@ -5,8 +5,11 @@ class ErrorTracking{
final GALogger logger;
ErrorTracking(this.logger);
log({String error}){
logger(error);
log(String type, {String error}){
logger('errors', parameters: {
'error_type' : type ?? 'unknown',
'error' : error ?? 'unknown',
});
}
}

@ -50,7 +50,7 @@ class LoginRegistration{
logger('registration_verification_option');
}
// R010
// R010:registration_confirmation
registration_confirmation({@required String by}){
// verification_method: by
logger('registration_confirmation', parameters: {
@ -65,17 +65,22 @@ class LoginRegistration{
});
}
// R011.x
login_verify_otp({@required int method}){
// R011:login_verify_otp | R009:registration_verification_option
verify_otp_method({@required int method, bool forRegistration = false}){
var verification_method = '';
if(method == 1) verification_method = 'sms';
if(method == 2) verification_method = 'fingerprint';
if(method == 3) verification_method = 'face id';
if(method == 4) verification_method = 'whatsapp';
logger('login_verify_otp', parameters: {
'login_method' : verification_method
});
if(forRegistration == false)
logger("login_verify_otp", parameters: {
'login_method' : verification_method
});
else
logger("registration_verification_option", parameters: {
'verification_method' : verification_method
});
}
// R011.2

@ -51,16 +51,7 @@ class TodoList{
});
}
// R049.1 // should be for appointment flow
// to_do_list_appointment_actions(AppoitmentAllHistoryResultList appointment, action){
// logger('to_do_list_pay_now', parameters: {
// 'appointment_type' : appointment.appointmentType,
// 'clinic_type_online' : appointment.clinicName,
// 'hospital_name' : appointment.projectName,
// 'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName,
// 'payment_type' : 'appointment',
// });
// }
// R049.2
to_do_list_cancel_appointment(AppoitmentAllHistoryResultList appointment){
@ -75,8 +66,9 @@ class TodoList{
// R049.3
to_do_list_confirm_appointment(AppoitmentAllHistoryResultList appointment){
logger('to_do_list_confirm_appointment', parameters: {
logger('confirm_appointment', parameters: {
'appointment_type' : appointment.isLiveCareAppointment ? 'livecare' : 'regular',
'flow_type' : 'todo list',
'clinic_type_online' : appointment.clinicName,
'hospital_name' : appointment.projectName,
'doctor_name' : (appointment.doctorName == null || appointment.doctorName == '') ? appointment.doctorNameObj : appointment.doctorName,

@ -39,18 +39,26 @@ _logger(String name, {Map<String,dynamic> parameters}) async {
return MapEntry(key_, value_);
});
_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');
});
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){
print(e);
}
}
}
class GAnalytics {
static String TREATMENT_TYPE;
static String APPOINTMENT_DETAIL_FLOW_TYPE;
static String PAYMENT_TYPE;
setUser(AuthenticatedUser user){
if(user != null){
_analytics.setUserProperty(name: 'user_country', value: user.iSOCountryID);

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io' show Platform;
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart';
@ -15,6 +16,7 @@ import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
@ -34,6 +36,8 @@ AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObjec
VitalSignService _vitalSignService = locator<VitalSignService>();
class BaseAppClient {
final _analytics = locator<GAnalytics>();
post(String endPoint,
{Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
@ -143,6 +147,7 @@ class BaseAppClient {
// print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
var decoded = utf8.decode(response.bodyBytes);
var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -155,9 +160,11 @@ class BaseAppClient {
} else {
if (parsed['ErrorType'] == 4) {
navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
if (parsed['ErrorType'] == 2) {
await logout();
logApiEndpointError(endPoint, "session logged out", statusCode);
}
if (isAllowAny) {
onSuccess(parsed, statusCode);
@ -173,6 +180,7 @@ class BaseAppClient {
// onSuccess(parsed, statusCode);
// } else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
// logout();
// }
}
@ -185,11 +193,14 @@ class BaseAppClient {
if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", statusCode);
logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
}
} else {
onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
}
}
}
@ -202,8 +213,10 @@ class BaseAppClient {
} else {
if (parsed['message'] != null) {
onFailure(parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
}
@ -212,10 +225,12 @@ class BaseAppClient {
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
print(e);
onFailure(e.toString(), -1);
_analytics.errorTracking.log(endPoint, error: "api exception: $e");
}
}
@ -317,6 +332,7 @@ class BaseAppClient {
// print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
// var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -325,6 +341,7 @@ class BaseAppClient {
} else {
if (parsed['ErrorType'] == 4) {
navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
if (isAllowAny) {
onSuccess(parsed, statusCode);
@ -340,6 +357,8 @@ class BaseAppClient {
onSuccess(parsed, statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, 'session logged out', statusCode);
logout();
}
}
@ -352,11 +371,14 @@ class BaseAppClient {
if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", statusCode);
logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
} else {
onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
} else if (!parsed['IsAuthenticated']) {
@ -369,8 +391,10 @@ class BaseAppClient {
} else {
if (parsed['message'] != null) {
onFailure(parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
}
@ -378,10 +402,12 @@ class BaseAppClient {
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
print(e);
onFailure(e.toString(), -1);
_analytics.errorTracking.log(endPoint, error: "api exception: $e");
}
}
@ -421,6 +447,7 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
} else {
// var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -428,6 +455,7 @@ class BaseAppClient {
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
@ -470,11 +498,13 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
if (statusCode == 401) {
onFailure(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
Navigator.of(AppGlobal.context).pushNamed(HOME);
} else {
var bodyUtf = json.decode(utf8.decode(response.bodyBytes));
// print(bodyUtf);
onFailure(bodyUtf['error']['ErrorEndUserMsg'], statusCode);
logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
}
} else {
// var parsed = json.decode(response.body.toString());
@ -483,6 +513,7 @@ class BaseAppClient {
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
@ -512,11 +543,13 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess(response.body.toString(), statusCode);
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
@ -545,11 +578,13 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess(response.body.toString(), statusCode);
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
@ -571,11 +606,13 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess(response.body.toString(), statusCode);
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
@ -604,11 +641,13 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode);
logApiFullUrlError(fullUrl, 'Error While Fetching data', statusCode);
} else {
onSuccess(response.body.toString(), statusCode);
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
}
@ -750,6 +789,7 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) {
var parsed = json.decode(utf8.decode(response.bodyBytes));
onFailure(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
} else {
// var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -773,6 +813,7 @@ class BaseAppClient {
onSuccess(parsed, statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logout();
}
}
@ -782,11 +823,14 @@ class BaseAppClient {
if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", statusCode);
logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
} else {
onFailure(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
}
} else {
onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
} else if (!parsed['IsAuthenticated']) {
await logout();
@ -798,8 +842,10 @@ class BaseAppClient {
} else {
if (parsed['message'] != null) {
onFailure(parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
} else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
}
}
}
@ -807,10 +853,12 @@ class BaseAppClient {
}
} else {
onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking.log("internet_connectivity", error: "no internet available");
}
} catch (e) {
print(e);
onFailure(e.toString(), -1);
logApiEndpointError(endPoint, e.toString(), -1);
}
}
@ -829,8 +877,20 @@ class BaseAppClient {
}
}, onFailure: (String error, int statusCode) {
completer.complete();
logApiFullUrlError(url, error, statusCode);
});
await completer.future;
return token;
}
logApiFullUrlError(String fullUrl, error, code){
final endpoint = Uri.parse(fullUrl).pathSegments.last;
logApiEndpointError(endpoint, error, code);
}
logApiEndpointError(String endPoint, error, code){
_analytics.errorTracking.log(endPoint, error: error);
}
}

@ -1,3 +1,6 @@
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart';
class SearchInfo {
int ProjectID;
int ClinicID;
@ -7,4 +10,7 @@ class SearchInfo {
String currentLat;
String currentLong;
DateTime date;
HospitalsModel hospital;
ListClinicCentralized clinic;
}

@ -574,8 +574,8 @@ class _BookSuccessState extends State<BookSuccess> {
String txn_ref = res['Merchant_Reference'];
String amount = res['Amount'];
String payment_method = res['PaymentMethod'];
projectViewModel.analytics.appointment.payment_success(
appointment_type: 'regular', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: 'SAR', txn_number: txn_ref);
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);

@ -1,4 +1,6 @@
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/models/Appointments/DentalChiefComplaintsModel.dart';
import 'package:diplomaticquarterapp/models/Appointments/DentalProceduresModel.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
@ -64,7 +66,10 @@ class _DentalComplaintsState extends State<DentalComplaints> {
child: DentalComplaintCard(
listDentalChiefComplain: complaintsList[index],
languageID: languageID,
),
)..logAnalytics = (){
final info = widget.searchInfo;
locator<GAnalytics>().appointment.book_appointment_chief_complaints(appointment_type: 'regular', hospital: info.hospital, clinic: info.clinic, treatment: complaintsList[index]);
},
);
},
separatorBuilder: (BuildContext context, int index) {

@ -1,3 +1,5 @@
import 'package:diplomaticquarterapp/analytics/flows/appointments.dart';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart';
@ -33,6 +35,8 @@ class _SearchState extends State<Search> with TickerProviderStateMixin {
Widget build(BuildContext context) {
AppGlobal.context = context;
ProjectViewModel projectViewModel = Provider.of(context);
GAnalytics.TREATMENT_TYPE = null; // reset treatment type on start new booking
return AppScaffold(
isShowAppBar: false,
isShowDecPage: false,

@ -52,6 +52,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
bool isProjectLoaded = false;
ListClinicCentralized selectedClinic;
HospitalsModel selectedHospital;
AuthenticatedUser authUser = new AuthenticatedUser();
AuthProvider authProvider = new AuthProvider();
@ -228,6 +229,7 @@ class _SearchByClinicState extends State<SearchByClinic> {
: InkWell(
onTap: () {
showClickListDialog(context, clinicsList, onSelection: (ListClinicCentralized clincs) {
selectedClinic = clincs;
projectViewModel.analytics.appointment.book_appointment_select_clinic(appointment_type: 'regular', clinic: clincs.clinicDescription);
Navigator.pop(context);
setState(() {
@ -310,22 +312,23 @@ class _SearchByClinicState extends State<SearchByClinic> {
Container(
height: 18,
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
child: DropdownButton<HospitalsModel>(
key: projectDropdownKey,
hint: new Text(TranslationBase.of(context).selectHospital),
value: projectDropdownValue,
value: selectedHospital,
iconSize: 0,
isExpanded: true,
style: TextStyle(fontSize: 14, letterSpacing: -0.56, color: Colors.black),
items: projectsList.map((item) {
return new DropdownMenuItem<String>(
value: item.mainProjectID.toString(),
return new DropdownMenuItem<HospitalsModel>(
value: item,
child: new Text(item.name),
);
}).toList(),
onChanged: (newValue) {
onChanged: (newValue) async{
setState(() {
projectDropdownValue = newValue;
selectedHospital = newValue;
projectDropdownValue = newValue.mainProjectID.toString();
getDoctorsList(context);
});
},
@ -516,6 +519,8 @@ class _SearchByClinicState extends State<SearchByClinic> {
if (dropdownValue.split("-")[0] == "17") {
searchInfo.ProjectID = int.parse(projectDropdownValue);
searchInfo.ClinicID = int.parse(dropdownValue.split("-")[0]);
searchInfo.hospital = selectedHospital;
searchInfo.clinic = selectedClinic;
searchInfo.date = DateTime.now();
navigateToDentalComplaints(context, searchInfo);

@ -12,6 +12,7 @@ import 'package:flutter/material.dart';
// ignore: must_be_immutable
class DentalComplaintCard extends StatefulWidget {
final ListDentalChiefComplain listDentalChiefComplain;
VoidCallback logAnalytics;
var languageID;
DentalComplaintCard({@required this.listDentalChiefComplain, this.languageID});
@ -26,7 +27,8 @@ class _DentalComplaintCardState extends State<DentalComplaintCard> {
return Container(
child: InkWell(
onTap: () {
// locator<GAnalytics>().appointment.book_appointment_chief_complaints(appointment_type: 'regular', hospital: widget.listDentalChiefComplain.);
if(widget.logAnalytics != null)
widget.logAnalytics();
getChiefComplaintsList();
},
child: Container(

@ -1,8 +1,10 @@
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart';
import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart';
import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Appointments/appoDetailsButtons.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart';
@ -94,15 +96,18 @@ class _AppointmentActionsState extends State<AppointmentActions> {
_handleButtonClicks(AppoDetailsButton, ToDoCountProviderModel model) {
switch (AppoDetailsButton.caller) {
case "openReschedule":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'reschedule appointment');
widget.tabController.animateTo((widget.tabController.index + 1) % 2);
setState(() {
widget.enableFooterButton();
});
break;
case "navigateToProject":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'hospital location');
openMap(double.parse(widget.appo.latitude), double.parse(widget.appo.longitude));
break;
case "addReminder":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'add reminder');
showReminderDialog(
context,
DateUtil.convertStringToDate(widget.appo.appointmentDate),
@ -117,32 +122,41 @@ class _AppointmentActionsState extends State<AppointmentActions> {
break;
case "goToTodoList":
// Navigator.of(context).pop();
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'todo list');
navigateToToDoPage(context, model);
break;
case "askDoc":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'ask doctor');
askYourDoc();
break;
case "radiology":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'radiology');
openAppointmentRadiology();
break;
case "labResult":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'lab result');
openAppointmentLabResults();
break;
case "prescriptions":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'prescriptions');
openPrescriptionReport();
break;
case "Survey":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'survey');
rateAppointment();
break;
case "Insurance":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'insurance');
navigateToInsuranceApprovals(widget.appo.appointmentNo);
break;
case "VitalSigns":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'vital sign');
navigateToVitalSigns(widget.appo.appointmentNo, widget.appo.projectID);
break;
case "insertComplaint":
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint');
navigateToInsertComplaint();
break;
}

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/pages/MyAppointments/models/AppointmentType.dart';
@ -237,6 +238,7 @@ class _ApointmentCardState extends State<AppointmentCard> {
}
Future navigateToAppointmentDetails(context, appo) async {
GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'my appointment';
Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo)))
.then((value) {
widget.onReloadAppointmentHistory();

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
@ -628,6 +629,7 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
Future navigateToAppointmentDetails(context, AppoitmentAllHistoryResultList appo) async {
projectViewModel.analytics.todoList.to_do_list_more_details(appo);
GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'todo list';
Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo, parentIndex: appo.patientStatusType == 42 ? 1 : 0))).then((value) {
getPatientAppointmentHistory();
});

@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/cupertino.dart';

@ -40,8 +40,8 @@ import 'package:provider/provider.dart';
class ConfirmLogin extends StatefulWidget {
final Function changePageViewIndex;
const ConfirmLogin({Key key, this.changePageViewIndex}) : super(key: key);
final fromRegistration;
const ConfirmLogin({Key key, this.changePageViewIndex, this.fromRegistration = false}) : super(key: key);
@override
_ConfirmLogin createState() => _ConfirmLogin();
@ -579,6 +579,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
else
{
// Navigator.of(context).pop(),
projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result),
GifLoaderDialogUtils.hideDialog(context),
Future.delayed(Duration(seconds: 1), () {
AppToast.showErrorToast(message: result);
@ -628,7 +629,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
// Navigator.of(context).pop(),
GifLoaderDialogUtils.hideDialog(context),
Future.delayed(Duration(seconds: 1), () {
projectViewModel.analytics.errorTracking.log(error: "login_failed: $result");
projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result);
AppToast.showErrorToast(message: result);
startSMSService(tempType);
}),
@ -727,7 +728,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
isMoreOption = true;
});
} else {
projectViewModel.analytics.loginRegistration.login_verify_otp(method: _flag);
projectViewModel.analytics.loginRegistration.verify_otp_method(method: _flag, forRegistration: widget.fromRegistration);
authenticateUser(_flag, isActive: _loginIndex);
}
},

@ -282,7 +282,7 @@ class _RegisterInfo extends State<RegisterInfo> {
child: Padding(
padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () {
Navigator.of(context).pop();
locator<GAnalytics>().loginRegistration.registration_cancel(step: page == 1 ? 'personal info' : 'patient info');
locator<GAnalytics>().loginRegistration.registration_cancel(step: page == 1 ? 'personal info' : 'other details');
}, textColor: Colors.white, color: Color(0xffD02127))),
),
Expanded(

@ -54,20 +54,17 @@ class _Register extends State<Register> {
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: TranslationBase.of(context).register,
isShowAppBar: false,
isShowDecPage: false,
showNewAppBar: false,
showNewAppBarTitle: true,
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30),
height: SizeConfig.realScreenHeight * .9,
width: SizeConfig.realScreenWidth,
child: Column(children: <Widget>[
body: Column(
children: [
Expanded(
child: ListView(
padding: EdgeInsets.zero,
padding: EdgeInsets.all(21),
physics: BouncingScrollPhysics(),
children: [
SizedBox(height: 10),
@ -150,32 +147,32 @@ class _Register extends State<Register> {
],
),
),
]),
)),
bottomSheet: Container(
width: double.maxFinite,
// height: 80.0,
color: Colors.white,
margin: EdgeInsets.only(bottom: 50.0),
child: Row(
children: [
Expanded(
child: Padding(
padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () {
Navigator.of(context).pop();
locator<GAnalytics>().loginRegistration.registration_cancel(step: 'enter details');
}, textColor: Colors.white, color: Color(0xffD02127))),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(10),
child: DefaultButton(TranslationBase.of(context).next, (){
startRegistration();
locator<GAnalytics>().loginRegistration.registration_enter_details();
}, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))),
),
],
)));
Container(
width: double.maxFinite,
// height: 80.0,
color: Colors.white,
// margin: EdgeInsets.only(bottom: 50.0),
child: Row(
children: [
Expanded(
child: Padding(
padding: EdgeInsets.all(10), child: DefaultButton(TranslationBase.of(context).cancel, () {
Navigator.of(context).pop();
locator<GAnalytics>().loginRegistration.registration_cancel(step: 'enter details');
}, textColor: Colors.white, color: Color(0xffD02127))),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(10),
child: DefaultButton(TranslationBase.of(context).next, (){
locator<GAnalytics>().loginRegistration.registration_enter_details();
startRegistration();
}, textColor: Colors.white, color: isButtonDisabled == true ? Colors.grey : Color(0xff359846))),
),
],
),)
],
),);
}
Future<Null> _selectDate(BuildContext context) async {
@ -394,7 +391,7 @@ class _Register extends State<Register> {
{
result = CheckUserStatusResponse.fromJson(result),
sharedPref.setObject(NHIC_DATA, result),
Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex))),
Navigator.of(context).push(FadePage(page: ConfirmLogin(changePageViewIndex: widget.changePageViewIndex, fromRegistration: true))),
}
else
{

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/theme/theme_notifier.dart';
@ -40,6 +41,11 @@ class _SplashScreenState extends State<SplashScreen> {
});
},
);
AppSharedPreferences().getAll().then((value){
debugPrint(jsonEncode(value));
});
}
/// load the Privilege from service

@ -4,6 +4,17 @@ import 'package:shared_preferences/shared_preferences.dart';
class AppSharedPreferences {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Map<String, dynamic> _allData;
// To Test Saved Data
Future<Map<String, dynamic>> getAll() async{
final prefs = (await _prefs);
_allData = {};
prefs.getKeys().forEach((key) {
_allData[key] = prefs.get(key);
});
return _allData;
}
/// Save String [key] the key for save value [value] the value we need to save it
setString(String key, String value) async {

@ -1,4 +1,5 @@
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/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
@ -343,6 +344,7 @@ class TimelineNewWidget extends StatelessWidget {
mHeight(10),
LargeAvatar(
onTap: () {
GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'timeline';
Navigator.push(
context,
FadePage(

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dart';
@ -51,6 +52,7 @@ class TimeLineWidget extends StatelessWidget {
LargeAvatar(
onTap: () {
//AppointmentDetails
GAnalytics.APPOINTMENT_DETAIL_FLOW_TYPE = 'timeline';
Navigator.push(
context,
FadePage(

Loading…
Cancel
Save