haroon_dev #75

Merged
Haroon6138 merged 4 commits from haroon_dev into master 4 weeks ago

@ -173,8 +173,8 @@ class ApiClientImp implements ApiClient {
body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken; body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken;
} }
body['TokenID'] = "@dm!n"; // body['TokenID'] = "@dm!n";
body['PatientID'] = 4767884; // body['PatientID'] = 4767884;
// body['PatientTypeID'] = 1; // body['PatientTypeID'] = 1;
// //
// body['PatientOutSA'] = 0; // body['PatientOutSA'] = 0;

@ -745,6 +745,7 @@ class ApiConsts {
static String TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout"; static String TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
static String GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments"; static String GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
static String GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
// static String GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; // static String GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
@ -760,6 +761,7 @@ class ApiConsts {
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx"; SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout"; TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments"; GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
break; break;
case AppEnvironmentTypeEnum.dev: case AppEnvironmentTypeEnum.dev:
baseUrl = "https://uat.hmgwebservices.com/"; baseUrl = "https://uat.hmgwebservices.com/";
@ -768,6 +770,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout"; TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
break; break;
case AppEnvironmentTypeEnum.uat: case AppEnvironmentTypeEnum.uat:
baseUrl = "https://uat.hmgwebservices.com/"; baseUrl = "https://uat.hmgwebservices.com/";
@ -776,6 +779,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout"; TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
break; break;
case AppEnvironmentTypeEnum.preProd: case AppEnvironmentTypeEnum.preProd:
@ -785,6 +789,7 @@ class ApiConsts {
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx"; SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout"; TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
break; break;
case AppEnvironmentTypeEnum.qa: case AppEnvironmentTypeEnum.qa:
baseUrl = "https://uat.hmgwebservices.com/"; baseUrl = "https://uat.hmgwebservices.com/";
@ -793,6 +798,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout"; TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
break; break;
case AppEnvironmentTypeEnum.staging: case AppEnvironmentTypeEnum.staging:
baseUrl = "https://uat.hmgwebservices.com/"; baseUrl = "https://uat.hmgwebservices.com/";
@ -801,6 +807,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx'; SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout"; TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
break; break;
} }
} }

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; // These are the Viewport values of your Figma Design. import 'package:flutter/material.dart'; // These are the Viewport values of your Figma Design.
// These are used in the code as a reference to create your UI Responsively. // These are used in the code as a reference to create your UI Responsively.
const num FIGMA_DESIGN_WIDTH = 375; final num FIGMA_DESIGN_WIDTH = SizeUtils.width;
const num FIGMA_DESIGN_HEIGHT = 667; final num FIGMA_DESIGN_HEIGHT = SizeUtils.height;
const num FIGMA_DESIGN_STATUS_BAR = 0; const num FIGMA_DESIGN_STATUS_BAR = 0;
extension ResponsiveExtension on num { extension ResponsiveExtension on num {
@ -70,10 +70,10 @@ class SizeUtils {
static late DeviceType deviceType; static late DeviceType deviceType;
/// Device's Height /// Device's Height
static late double height; static double height = 667;
/// Device's Width /// Device's Width
static late double width; static double width = 375;
static void setScreenSize( static void setScreenSize(
BoxConstraints constraints, BoxConstraints constraints,

@ -757,4 +757,5 @@ class Utils {
} }
return isHavePrivilege; return isHavePrivilege;
} }
} }

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
@ -72,6 +73,12 @@ abstract class BookAppointmentsRepo {
Future<Either<Failure, GenericApiModel<List<PatientDentalPlanEstimationResponseModel>>>> getPatientDentalEstimation( Future<Either<Failure, GenericApiModel<List<PatientDentalPlanEstimationResponseModel>>>> getPatientDentalEstimation(
{required int projectID, Function(dynamic)? onSuccess, Function(String)? onError}); {required int projectID, Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<List<DentalChiefComplaintsListResponseModel>>>> getDentalChiefComplaintsList(
{required int projectID, required int clinicID, required int patientID, Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<List<DoctorsListResponseModel>>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID,
{Function(dynamic)? onSuccess, Function(String)? onError});
} }
class BookAppointmentsRepoImp implements BookAppointmentsRepo { class BookAppointmentsRepoImp implements BookAppointmentsRepo {
@ -701,4 +708,96 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
return Left(UnknownFailure(e.toString())); return Left(UnknownFailure(e.toString()));
} }
} }
@override
Future<Either<Failure, GenericApiModel<List<DentalChiefComplaintsListResponseModel>>>> getDentalChiefComplaintsList(
{required int projectID, required int clinicID, required int patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"PatientID": patientID,
"ClinicID": clinicID,
"ProjectID": projectID,
"isDentalAllowedBackend": true,
"ContinueDentalPlan": false,
"IsSearchAppointmnetByClinicID": false,
};
try {
GenericApiModel<List<DentalChiefComplaintsListResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_DOCTORS_LIST_URL,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
onError!(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_DentalChiefComplain'];
final chiefComplaintsList = list.map((item) => DentalChiefComplaintsListResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<DentalChiefComplaintsListResponseModel>();
apiResponse = GenericApiModel<List<DentalChiefComplaintsListResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: chiefComplaintsList,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<DoctorsListResponseModel>>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID,
{Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"ProjectID": projectID,
"ChiefComplaintID": chiefComplaintID,
"isDentalAllowedBackend": true,
"IsPublicRequest": true,
};
try {
GenericApiModel<List<DoctorsListResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_DENTAL_DOCTORS_LIST_URL,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
onError!(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_DentalDoctorChiefComplaintMapping'];
final doctorsList = list.map((item) => DoctorsListResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<DoctorsListResponseModel>();
apiResponse = GenericApiModel<List<DoctorsListResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: doctorsList,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
} }

@ -12,6 +12,7 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/free_slot.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/free_slot.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
@ -57,8 +58,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
List<DoctorsListResponseModel> liveCareDoctorsList = []; List<DoctorsListResponseModel> liveCareDoctorsList = [];
List<PatientDentalPlanEstimationResponseModel> patientDentalPlanEstimationList = []; List<PatientDentalPlanEstimationResponseModel> patientDentalPlanEstimationList = [];
List<DentalChiefComplaintsListResponseModel> dentalChiefComplaintsList = [];
int totalTimeNeededForDentalProcedure = 0; int totalTimeNeededForDentalProcedure = 0;
bool isContinueDentalPlan = false; bool isContinueDentalPlan = false;
bool isChiefComplaintsListLoading = false;
int selectedChiefComplaintID = 0;
GetClinicsListResponseModel selectedClinic = GetClinicsListResponseModel(); GetClinicsListResponseModel selectedClinic = GetClinicsListResponseModel();
DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel(); DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel();
@ -134,7 +138,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
doctorsList.clear(); doctorsList.clear();
liveCareClinicsList.clear(); liveCareClinicsList.clear();
patientDentalPlanEstimationList.clear(); patientDentalPlanEstimationList.clear();
dentalChiefComplaintsList.clear();
isContinueDentalPlan = false; isContinueDentalPlan = false;
isChiefComplaintsListLoading = true;
// getLocation(); // getLocation();
notifyListeners(); notifyListeners();
} }
@ -201,6 +207,16 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
setIsChiefComplaintsListLoading(bool value) {
isChiefComplaintsListLoading = value;
notifyListeners();
}
setSelectedChiefComplaintID(int id) {
selectedChiefComplaintID = id;
notifyListeners();
}
void onTabChanged(int index) { void onTabChanged(int index) {
selectedTabIndex = index; selectedTabIndex = index;
notifyListeners(); notifyListeners();
@ -949,4 +965,56 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}, },
); );
} }
Future<void> getDentalChiefComplaintsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
dentalChiefComplaintsList.clear();
notifyListeners();
int patientID = _appState.isAuthenticated ? _appState.getAuthenticatedUser()!.patientId ?? -1 : -1;
final result = await bookAppointmentsRepo.getDentalChiefComplaintsList(patientID: patientID, projectID: int.parse(currentlySelectedHospitalFromRegionFlow ?? "0"), clinicID: 17);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage!);
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
dentalChiefComplaintsList = apiResponse.data!;
isChiefComplaintsListLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
Future<void> getDentalChiefComplaintDoctorsList({int projectID = 0, Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear();
projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
final result = await bookAppointmentsRepo.getDentalChiefComplaintDoctorsList(projectID, selectedChiefComplaintID);
result.fold(
(failure) async {
onError!("No doctors found for the search criteria...".needTranslation);
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
doctorsList = apiResponse.data!;
filteredDoctorList = doctorsList;
isDoctorsListLoading = false;
// initializeFilteredList();
// clearSearchFilters();
// getFiltersFromDoctorList();
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
} }

@ -0,0 +1,24 @@
class DentalChiefComplaintsListResponseModel {
int? projectID;
int? iD;
String? name;
dynamic nameN;
DentalChiefComplaintsListResponseModel({this.projectID, this.iD, this.name, this.nameN});
DentalChiefComplaintsListResponseModel.fromJson(Map<String, dynamic> json) {
projectID = json['ProjectID'];
iD = json['ID'];
name = json['Name'];
nameN = json['NameN'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ProjectID'] = this.projectID;
data['ID'] = this.iD;
data['Name'] = this.name;
data['NameN'] = this.nameN;
return data;
}
}

@ -155,6 +155,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
patientAppointmentsHistoryList.addAll(patientUpcomingAppointmentsHistoryList); patientAppointmentsHistoryList.addAll(patientUpcomingAppointmentsHistoryList);
patientAppointmentsHistoryList.addAll(patientArrivedAppointmentsHistoryList); patientAppointmentsHistoryList.addAll(patientArrivedAppointmentsHistoryList);
filteredAppointmentList.addAll(patientAppointmentsHistoryList); filteredAppointmentList.addAll(patientAppointmentsHistoryList);
print('Upcoming Appointments: ${patientUpcomingAppointmentsHistoryList.length}'); print('Upcoming Appointments: ${patientUpcomingAppointmentsHistoryList.length}');
print('Arrived Appointments: ${patientArrivedAppointmentsHistoryList.length}'); print('Arrived Appointments: ${patientArrivedAppointmentsHistoryList.length}');
print('All Appointments: ${patientAppointmentsHistoryList.length}'); print('All Appointments: ${patientAppointmentsHistoryList.length}');

@ -18,6 +18,13 @@ abstract class PayfortRepo {
Future<Either<Failure, GenericApiModel<SdkTokenResponse>>> generateSdkSignatureFromAPI({required SdkTokenRequest tokenRequest}); Future<Either<Failure, GenericApiModel<SdkTokenResponse>>> generateSdkSignatureFromAPI({required SdkTokenRequest tokenRequest});
Future<Either<Failure, GenericApiModel<PayfortCheckPaymentStatusResponseModel>>> checkPaymentStatus({required String transactionID}); Future<Either<Failure, GenericApiModel<PayfortCheckPaymentStatusResponseModel>>> checkPaymentStatus({required String transactionID});
Future<Either<Failure, GenericApiModel<dynamic>>> checkTamaraPaymentStatus({required String transactionID});
Future<Either<Failure, GenericApiModel<dynamic>>> markAppointmentAsTamaraPaid({required int projectID, required int appointmentNo});
Future<Either<Failure, GenericApiModel<dynamic>>> updateTamaraRequestStatus(
{required String responseMessage, required String status, required String clientRequestID, required String tamaraOrderID});
} }
class PayfortRepoImp implements PayfortRepo { class PayfortRepoImp implements PayfortRepo {
@ -147,4 +154,100 @@ class PayfortRepoImp implements PayfortRepo {
return Left(UnknownFailure(e.toString())); return Left(UnknownFailure(e.toString()));
} }
} }
@override
Future<Either<Failure, GenericApiModel>> checkTamaraPaymentStatus({required String transactionID}) async {
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.get(
'${ApiConsts.GET_TAMARA_PAYMENT_STATUS}$transactionID',
isExternal: true,
isAllowAny: true,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel>> updateTamaraRequestStatus({required String responseMessage, required String status, required String clientRequestID, required String tamaraOrderID}) async {
Map<String, dynamic> body = {
"Response_Message": responseMessage,
"ClientRequestID": clientRequestID,
"Status": status,
"FortID": tamaraOrderID, // Tamara order ID
"LanguageID": 1,
"Installments_Number": 3,
};
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(UPDATE_TAMARA_STATUS, body: body, onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
}, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
}, isAllowAny: true, isPaymentServices: true);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel>> markAppointmentAsTamaraPaid({required int projectID, required int appointmentNo}) async {
Map<String, dynamic> body = {"ProjectID": projectID, "AppointmentNo": appointmentNo, "LanguageID": 1};
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(MARK_APPOINTMENT_TAMARA_STATUS, body: body, onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
}, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
}, isAllowAny: true, isPaymentServices: true);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
} }

@ -94,6 +94,40 @@ class PayfortViewModel extends ChangeNotifier {
); );
} }
Future<void> checkTamaraPaymentStatus({required String transactionID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await payfortRepo.checkTamaraPaymentStatus(transactionID: transactionID);
result.fold(
(failure) async {
onError!(failure.message);
},
(apiResponse) {
print(apiResponse.data);
if (onSuccess != null) {
onSuccess(apiResponse);
}
// }
},
);
}
Future<void> updateTamaraRequestStatus(
{required String responseMessage, required String status, required String clientRequestID, required String tamaraOrderID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await payfortRepo.updateTamaraRequestStatus(responseMessage: responseMessage, status: status, clientRequestID: clientRequestID, tamaraOrderID: tamaraOrderID);
result.fold(
(failure) async {
onError!(failure.message);
},
(apiResponse) {
print(apiResponse.data);
if (onSuccess != null) {
onSuccess(apiResponse);
}
},
);
}
Future<SdkTokenResponse?> _generateSdkResponse({ Future<SdkTokenResponse?> _generateSdkResponse({
String? applePayAccessCode, String? applePayAccessCode,
String? merchantIdentifier, String? merchantIdentifier,
@ -199,4 +233,20 @@ class PayfortViewModel extends ChangeNotifier {
onFailed!(e.toString() as PayFortFailureResult); onFailed!(e.toString() as PayFortFailureResult);
} }
} }
Future<void> markAppointmentAsTamaraPaid({required int projectID, required int appointmentNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await payfortRepo.markAppointmentAsTamaraPaid(projectID: projectID, appointmentNo: appointmentNo);
result.fold(
(failure) async {
onError!(failure.message);
},
(apiResponse) {
print(apiResponse.data);
if (onSuccess != null) {
onSuccess(apiResponse);
}
},
);
}
} }

@ -79,94 +79,53 @@ void main() async {
fallbackLocale: Locale('en', 'US'), fallbackLocale: Locale('en', 'US'),
child: MultiProvider(providers: <SingleChildWidget>[ child: MultiProvider(providers: <SingleChildWidget>[
ChangeNotifierProvider<LabViewModel>( ChangeNotifierProvider<LabViewModel>(
create: (_) => LabViewModel( create: (_) => getIt.get<LabViewModel>(),
labRepo: getIt(),
errorHandlerService: getIt(),
navigationService: getIt()),
), ),
ChangeNotifierProvider<RadiologyViewModel>( ChangeNotifierProvider<RadiologyViewModel>(
create: (_) => RadiologyViewModel( create: (_) => getIt.get<RadiologyViewModel>(),
radiologyRepo: getIt(),
errorHandlerService: getIt(),
),
), ),
ChangeNotifierProvider<PrescriptionsViewModel>( ChangeNotifierProvider<PrescriptionsViewModel>(
create: (_) => PrescriptionsViewModel( create: (_) => getIt.get<PrescriptionsViewModel>(),
prescriptionsRepo: getIt(),
errorHandlerService: getIt(),
),
), ),
ChangeNotifierProvider<InsuranceViewModel>( ChangeNotifierProvider<InsuranceViewModel>(
create: (_) => InsuranceViewModel( create: (_) => getIt.get<InsuranceViewModel>(),
insuranceRepo: getIt(),
errorHandlerService: getIt(),
),
), ),
ChangeNotifierProvider<MedicalFileViewModel>( ChangeNotifierProvider<MedicalFileViewModel>(
create: (_) => MedicalFileViewModel( create: (_) => getIt.get<MedicalFileViewModel>(),
medicalFileRepo: getIt(),
errorHandlerService: getIt(),
),
), ),
ChangeNotifierProvider<ProfileSettingsViewModel>( ChangeNotifierProvider<ProfileSettingsViewModel>(
create: (_) => ProfileSettingsViewModel(), create: (_) => getIt.get<ProfileSettingsViewModel>(),
), ),
ChangeNotifierProvider<MyAppointmentsViewModel>( ChangeNotifierProvider<MyAppointmentsViewModel>(
create: (_) => MyAppointmentsViewModel( create: (_) => getIt.get<MyAppointmentsViewModel>(),
myAppointmentsRepo: getIt(),
errorHandlerService: getIt(),
appState: getIt(),
),
), ),
ChangeNotifierProvider<PayfortViewModel>( ChangeNotifierProvider<PayfortViewModel>(
create: (_) => PayfortViewModel( create: (_) => getIt.get<PayfortViewModel>(),
payfortRepo: getIt(),
errorHandlerService: getIt(),
),
), ),
ChangeNotifierProvider<HabibWalletViewModel>( ChangeNotifierProvider<HabibWalletViewModel>(
create: (_) => HabibWalletViewModel( create: (_) => getIt.get<HabibWalletViewModel>(),
habibWalletRepo: getIt(),
errorHandlerService: getIt(),
),
), ),
ChangeNotifierProvider<BookAppointmentsViewModel>( ChangeNotifierProvider<BookAppointmentsViewModel>(
create: (_) => BookAppointmentsViewModel( create: (_) => getIt.get<BookAppointmentsViewModel>(),
bookAppointmentsRepo: getIt(),
errorHandlerService: getIt(),
navigationService: getIt(),
myAppointmentsViewModel: getIt(),
locationUtils: getIt(),
),
), ),
ChangeNotifierProvider<ImmediateLiveCareViewModel>( ChangeNotifierProvider<ImmediateLiveCareViewModel>(
create: (_) => ImmediateLiveCareViewModel( create: (_) => getIt.get<ImmediateLiveCareViewModel>(),
immediateLiveCareRepo: getIt(),
errorHandlerService: getIt(),
navigationService: getIt(),
myAppointmentsViewModel: getIt(),
),
), ),
ChangeNotifierProvider<AuthenticationViewModel>( ChangeNotifierProvider<AuthenticationViewModel>(
create: (_) => AuthenticationViewModel( create: (_) => getIt.get<AuthenticationViewModel>(),
authenticationRepo: getIt(),
appState: getIt(),
dialogService: getIt(),
errorHandlerService: getIt(),
navigationService: getIt(),
cacheService: getIt(),
localAuthService: getIt(),
),
), ),
ChangeNotifierProvider<AppointmentViaRegionViewmodel>( ChangeNotifierProvider<AppointmentViaRegionViewmodel>(
create: (_) => AppointmentViaRegionViewmodel( create: (_) => getIt.get<AppointmentViaRegionViewmodel>(),
navigationService: getIt(), appState: getIt())), ),
ChangeNotifierProvider<LabHistoryViewModel>( ChangeNotifierProvider<LabHistoryViewModel>(
create: (_) => LabHistoryViewModel()), create: (_) => getIt.get<LabHistoryViewModel>(),
),
ChangeNotifierProvider<DateRangeSelectorRangeViewModel>( ChangeNotifierProvider<DateRangeSelectorRangeViewModel>(
create: (_) => DateRangeSelectorRangeViewModel()) , create: (_) => getIt.get<DateRangeSelectorRangeViewModel>(),
),
ChangeNotifierProvider<DoctorFilterViewModel>( ChangeNotifierProvider<DoctorFilterViewModel>(
create: (_) => DoctorFilterViewModel()) create: (_) => getIt.get<DoctorFilterViewModel>(),
)
], child: MyApp()), ], child: MyApp()),
), ),
); );

@ -52,6 +52,8 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
String transID = ""; String transID = "";
bool isShowTamara = false; bool isShowTamara = false;
String tamaraPaymentStatus = "";
String tamaraOrderID = "";
@override @override
void initState() { void initState() {
@ -117,7 +119,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18.h, width: 18.h,
height: 13.h, height: 13.h,
@ -159,7 +161,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18.h, width: 18.h,
height: 13.h, height: 13.h,
@ -196,18 +198,18 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18.h, width: 18.h,
height: 13.h, height: 13.h,
fit: BoxFit.contain, fit: BoxFit.contain,
).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading), ).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
), ),
], ],
).paddingSymmetrical(16.h, 16.h), ).paddingSymmetrical(16.h, 16.h),
).paddingSymmetrical(24.h, 0.h).onPress(() { ).paddingSymmetrical(24.h, 0.h).onPress(() {
selectedPaymentMethod = "TAMARA"; selectedPaymentMethod = "TAMARA";
openPaymentURL("tamara"); openPaymentURL("tamara");
}) })
: SizedBox.shrink(), : SizedBox.shrink(),
], ],
@ -328,12 +330,12 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
if (selectedPaymentMethod == "tamara") { if (selectedPaymentMethod == "tamara") {
if (Platform.isAndroid) { if (Platform.isAndroid) {
Uri uri = new Uri.dataFromString(url); Uri uri = new Uri.dataFromString(url);
// tamaraPaymentStatus = uri.queryParameters['status']!; tamaraPaymentStatus = uri.queryParameters['status']!;
// tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!; tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!;
} else { } else {
Uri uri = new Uri.dataFromString(url); Uri uri = new Uri.dataFromString(url);
// tamaraPaymentStatus = uri.queryParameters['paymentStatus']!; tamaraPaymentStatus = uri.queryParameters['paymentStatus']!;
// tamaraOrderID = uri.queryParameters['orderId']!; tamaraOrderID = uri.queryParameters['orderId']!;
} }
} }
@ -359,95 +361,155 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
} }
onBrowserExit(bool isPaymentMade) async { onBrowserExit(bool isPaymentMade) async {
print("onBrowserExit Called!!!!"); checkPaymentStatus();
if (selectedPaymentMethod == "TAMARA") {
// checkTamaraPaymentStatus(transID!, appo);
// if (tamaraPaymentStatus != null && tamaraPaymentStatus.toLowerCase() == "approved") {
// updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallments), appo);
// } else {
// updateTamaraRequestStatus("Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallments), appo);
// }
} else {
checkPaymentStatus();
// checkPaymentStatus(appo);
}
} }
void checkPaymentStatus() async { void checkPaymentStatus() async {
LoaderBottomSheet.showLoader(); LoaderBottomSheet.showLoader(loadingText: "Checking payment status, Please wait...".needTranslation);
await payfortViewModel.checkPaymentStatus( if (selectedPaymentMethod == "TAMARA") {
transactionID: transID, await payfortViewModel.checkTamaraPaymentStatus(
onSuccess: (apiResponse) async { transactionID: transID,
print(apiResponse.data); onSuccess: (apiResponse) async {
if (payfortViewModel.payfortCheckPaymentStatusResponseModel!.responseMessage!.toLowerCase() == "success") { if (apiResponse.data["status"].toString().toLowerCase() == "success") {
await myAppointmentsViewModel.createAdvancePayment( tamaraOrderID = apiResponse.data["tamara_order_id"].toString();
paymentMethodName: selectedPaymentMethod, await payfortViewModel.updateTamaraRequestStatus(responseMessage: "success", status: "14", clientRequestID: transID, tamaraOrderID: tamaraOrderID);
projectID: widget.patientAppointmentHistoryResponseModel.projectID, await payfortViewModel.markAppointmentAsTamaraPaid(
clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, projectID: widget.patientAppointmentHistoryResponseModel.projectID, appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo);
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), await myAppointmentsViewModel.addAdvanceNumberRequest(
payedAmount: payfortViewModel.payfortCheckPaymentStatusResponseModel!.amount!, advanceNumber: "Tamara-Advance-0000",
paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, paymentReference: tamaraOrderID,
patientID: appState.getAuthenticatedUser()!.patientId.toString(), appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
patientType: appState.getAuthenticatedUser()!.patientType!, onSuccess: (value) async {
onSuccess: (value) async { if (widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!) {
print(value); //TODO: Implement LiveCare Check-In API Call
await myAppointmentsViewModel.addAdvanceNumberRequest( await myAppointmentsViewModel.insertLiveCareVIDARequest(
advanceNumber: Utils.isVidaPlusProject(widget.patientAppointmentHistoryResponseModel.projectID) clientRequestID: tamaraOrderID,
? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
: value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), onSuccess: (apiResponse) {
paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, Future.delayed(Duration(milliseconds: 500), () {
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), LoaderBottomSheet.hideLoader();
onSuccess: (value) async { Navigator.pushAndRemoveUntil(
if (widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!) { context,
//TODO: Implement LiveCare Check-In API Call CustomPageRoute(
await myAppointmentsViewModel.insertLiveCareVIDARequest( page: LandingNavigation(),
clientRequestID: transID, ),
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, (r) => false);
onSuccess: (apiResponse) { });
Future.delayed(Duration(milliseconds: 500), () { },
LoaderBottomSheet.hideLoader(); onError: (error) {});
Navigator.pushAndRemoveUntil( } else {
context, await myAppointmentsViewModel.generateAppointmentQR(
CustomPageRoute( clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
page: LandingNavigation(), projectID: widget.patientAppointmentHistoryResponseModel.projectID,
), appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
(r) => false); isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!,
}); onSuccess: (apiResponse) {
}, Future.delayed(Duration(milliseconds: 500), () {
onError: (error) {}); LoaderBottomSheet.hideLoader();
} else { Navigator.pushAndRemoveUntil(
await myAppointmentsViewModel.generateAppointmentQR( context,
clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, CustomPageRoute(
projectID: widget.patientAppointmentHistoryResponseModel.projectID, page: LandingNavigation(),
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), ),
isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!, (r) => false);
onSuccess: (apiResponse) { });
Future.delayed(Duration(milliseconds: 500), () { });
LoaderBottomSheet.hideLoader(); }
Navigator.pushAndRemoveUntil( });
context, } else {
CustomPageRoute( await payfortViewModel.updateTamaraRequestStatus(responseMessage: "Failed", status: "00", clientRequestID: transID, tamaraOrderID: tamaraOrderID);
page: LandingNavigation(), LoaderBottomSheet.hideLoader();
), showCommonBottomSheetWithoutHeight(
(r) => false); context,
// Navigator.of(context).push( child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation),
// CustomPageRoute(page: MyAppointmentsPage()), callBackFunc: () {},
// ); isFullScreen: false,
}); isCloseButtonVisible: true,
}); );
} }
}); },
}); onError: (err) {
} else { LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation), child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
); );
} });
}); } else {
await payfortViewModel.checkPaymentStatus(
transactionID: transID,
onSuccess: (apiResponse) async {
print(apiResponse.data);
if (payfortViewModel.payfortCheckPaymentStatusResponseModel!.responseMessage!.toLowerCase() == "success") {
await myAppointmentsViewModel.createAdvancePayment(
paymentMethodName: selectedPaymentMethod,
projectID: widget.patientAppointmentHistoryResponseModel.projectID,
clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
payedAmount: payfortViewModel.payfortCheckPaymentStatusResponseModel!.amount!,
paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!,
patientID: appState.getAuthenticatedUser()!.patientId.toString(),
patientType: appState.getAuthenticatedUser()!.patientType!,
onSuccess: (value) async {
print(value);
await myAppointmentsViewModel.addAdvanceNumberRequest(
advanceNumber: Utils.isVidaPlusProject(widget.patientAppointmentHistoryResponseModel.projectID)
? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString()
: value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(),
paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!,
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
onSuccess: (value) async {
if (widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!) {
//TODO: Implement LiveCare Check-In API Call
await myAppointmentsViewModel.insertLiveCareVIDARequest(
clientRequestID: transID,
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
onSuccess: (apiResponse) {
Future.delayed(Duration(milliseconds: 500), () {
LoaderBottomSheet.hideLoader();
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
});
},
onError: (error) {});
} else {
await myAppointmentsViewModel.generateAppointmentQR(
clinicID: widget.patientAppointmentHistoryResponseModel.clinicID,
projectID: widget.patientAppointmentHistoryResponseModel.projectID,
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(),
isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!,
onSuccess: (apiResponse) {
Future.delayed(Duration(milliseconds: 500), () {
LoaderBottomSheet.hideLoader();
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
});
});
}
});
});
} else {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
});
}
} }
openPaymentURL(String paymentMethod) { openPaymentURL(String paymentMethod) {

@ -177,6 +177,7 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
separatorBuilder: (BuildContext cxt, int index) => separatorBuilder: (BuildContext cxt, int index) =>
SizedBox(height: 16.h), SizedBox(height: 16.h),
), ),
SizedBox(height: 24.h),
], ],
); );
} }

@ -124,7 +124,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18.h, width: 18.h,
height: 13.h, height: 13.h,

@ -48,7 +48,7 @@ class FacilitySelectionItem extends StatelessWidget {
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18, width: 18,
height: 13, height: 13,

@ -45,7 +45,7 @@ class RegionListItem extends StatelessWidget {
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon, icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
width: 18, width: 18,
height: 13, height: 13,

@ -0,0 +1,95 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/chief_complaint_card.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
class DentalChiefComplaintsPage extends StatefulWidget {
const DentalChiefComplaintsPage({super.key});
@override
State<DentalChiefComplaintsPage> createState() => _DentalChiefComplaintsPageState();
}
class _DentalChiefComplaintsPageState extends State<DentalChiefComplaintsPage> {
late AppState appState;
late BookAppointmentsViewModel bookAppointmentsViewModel;
@override
void initState() {
scheduleMicrotask(() {
bookAppointmentsViewModel.getDentalChiefComplaintsList();
});
super.initState();
}
@override
Widget build(BuildContext context) {
bookAppointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
appState = getIt.get<AppState>();
return CollapsingListView(
title: "Dental Chief Complaints".needTranslation,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h),
child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
return ListView.separated(
padding: EdgeInsets.only(top: 24.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsVM.isChiefComplaintsListLoading ? 5 : bookAppointmentsVM.dentalChiefComplaintsList.length,
itemBuilder: (context, index) {
return bookAppointmentsVM.isChiefComplaintsListLoading
? ChiefComplaintCard(
bookAppointmentsVM: bookAppointmentsVM,
dentalChiefComplaintsListResponseModel: DentalChiefComplaintsListResponseModel(),
isLoading: bookAppointmentsVM.isChiefComplaintsListLoading,
)
: AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: ChiefComplaintCard(
bookAppointmentsVM: bookAppointmentsVM,
dentalChiefComplaintsListResponseModel: bookAppointmentsVM.dentalChiefComplaintsList[index],
isLoading: bookAppointmentsVM.isChiefComplaintsListLoading,
).onPress(() {
bookAppointmentsVM.setSelectedChiefComplaintID(bookAppointmentsVM.dentalChiefComplaintsList[index].iD!);
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
}),
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
);
}),
),
),
);
}
}

@ -57,6 +57,8 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
String transID = ""; String transID = "";
bool isShowTamara = false; bool isShowTamara = false;
String tamaraPaymentStatus = "";
String tamaraOrderID = "";
@override @override
void initState() { void initState() {
@ -319,15 +321,15 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
print("onBrowserLoadStart"); print("onBrowserLoadStart");
print(url); print(url);
if (selectedPaymentMethod == "tamara") { if (selectedPaymentMethod == "TAMARA") {
if (Platform.isAndroid) { if (Platform.isAndroid) {
Uri uri = new Uri.dataFromString(url); Uri uri = new Uri.dataFromString(url);
// tamaraPaymentStatus = uri.queryParameters['status']!; tamaraPaymentStatus = uri.queryParameters['status']!;
// tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!; tamaraOrderID = uri.queryParameters['AuthorizePaymentId']!;
} else { } else {
Uri uri = new Uri.dataFromString(url); Uri uri = new Uri.dataFromString(url);
// tamaraPaymentStatus = uri.queryParameters['paymentStatus']!; tamaraPaymentStatus = uri.queryParameters['paymentStatus']!;
// tamaraOrderID = uri.queryParameters['orderId']!; tamaraOrderID = uri.queryParameters['orderId']!;
} }
} }
@ -353,61 +355,107 @@ class _ImmediateLiveCarePaymentPageState extends State<ImmediateLiveCarePaymentP
} }
onBrowserExit(bool isPaymentMade) async { onBrowserExit(bool isPaymentMade) async {
print("onBrowserExit Called!!!!"); debugPrint("onBrowserExit Called!!!!");
if (selectedPaymentMethod == "TAMARA") { checkPaymentStatus();
// checkTamaraPaymentStatus(transID!, appo);
// if (tamaraPaymentStatus != null && tamaraPaymentStatus.toLowerCase() == "approved") {
// updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallments), appo);
// } else {
// updateTamaraRequestStatus("Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID, num.parse(selectedInstallments), appo);
// }
} else {
checkPaymentStatus();
// checkPaymentStatus(appo);
}
} }
void checkPaymentStatus() async { void checkPaymentStatus() async {
LoaderBottomSheet.showLoader(loadingText: "Checking payment status, Please wait...".needTranslation); LoaderBottomSheet.showLoader(loadingText: "Checking payment status, Please wait...".needTranslation);
await payfortViewModel.checkPaymentStatus(
transactionID: transID, if (selectedPaymentMethod == "TAMARA") {
onSuccess: (apiResponse) async { await payfortViewModel.checkTamaraPaymentStatus(
debugPrint(apiResponse.data.toString()); transactionID: transID,
if (payfortViewModel.payfortCheckPaymentStatusResponseModel!.responseMessage!.toLowerCase() == "success") { onSuccess: (apiResponse) async {
await immediateLiveCareViewModel.addNewCallRequestForImmediateLiveCare(transID); if (apiResponse.data["status"].toString().toLowerCase() == "success") {
await immediateLiveCareViewModel.getPatientLiveCareHistory(); tamaraOrderID = apiResponse.data["tamara_order_id"].toString();
LoaderBottomSheet.hideLoader(); await payfortViewModel.updateTamaraRequestStatus(responseMessage: "success", status: "14", clientRequestID: transID, tamaraOrderID: tamaraOrderID);
if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) { await immediateLiveCareViewModel.addNewCallRequestForImmediateLiveCare(transID);
Navigator.pushAndRemoveUntil( await immediateLiveCareViewModel.getPatientLiveCareHistory();
context, LoaderBottomSheet.hideLoader();
if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: LandingNavigation(), page: ImmediateLiveCarePendingRequestPage(),
), ),
(r) => false); );
Navigator.of(context).push( } else {
CustomPageRoute( showCommonBottomSheetWithoutHeight(
page: ImmediateLiveCarePendingRequestPage(), context,
), child: Utils.getErrorWidget(loadingText: "Unknown error occurred...".needTranslation),
); callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
} else { } else {
await payfortViewModel.updateTamaraRequestStatus(responseMessage: "Failed", status: "00", clientRequestID: transID, tamaraOrderID: tamaraOrderID);
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: "Unknown error occurred...".needTranslation), child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
); );
} }
} else { },
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation), child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
); );
} });
}); } else {
await payfortViewModel.checkPaymentStatus(
transactionID: transID,
onSuccess: (apiResponse) async {
debugPrint(apiResponse.data.toString());
if (payfortViewModel.payfortCheckPaymentStatusResponseModel!.responseMessage!.toLowerCase() == "success") {
await immediateLiveCareViewModel.addNewCallRequestForImmediateLiveCare(transID);
await immediateLiveCareViewModel.getPatientLiveCareHistory();
LoaderBottomSheet.hideLoader();
if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
Navigator.pushAndRemoveUntil(
context,
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
Navigator.of(context).push(
CustomPageRoute(
page: ImmediateLiveCarePendingRequestPage(),
),
);
} else {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Unknown error occurred...".needTranslation),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
} else {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Payment Failed! Please try again.".needTranslation),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
});
}
} }
openPaymentURL(String paymentMethod) { openPaymentURL(String paymentMethod) {

@ -18,6 +18,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/dental_chief_complaints_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_livecare_clinic_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/select_livecare_clinic_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic_card.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic_card.dart';
@ -222,124 +223,13 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
void handleDoctorScreen(GetClinicsListResponseModel clinic) async { void handleDoctorScreen(GetClinicsListResponseModel clinic) async {
if (widget.isFromRegionFlow) { if (widget.isFromRegionFlow) {
//Dental Clinic Flow //Dental Clinic Flow
if (clinic.clinicID == 17) { if (clinic.clinicID == 17 && appState.isAuthenticated) {
LoaderBottomSheet.showLoader(loadingText: "Checking for an existing dental plan, Please wait...".needTranslation); initDentalAppointmentBookingFlow(int.parse(bookAppointmentsViewModel.currentlySelectedHospitalFromRegionFlow ?? "0"));
await bookAppointmentsViewModel.getPatientDentalEstimation(projectID: int.parse(bookAppointmentsViewModel.currentlySelectedHospitalFromRegionFlow ?? "0")).then((value) {
LoaderBottomSheet.hideLoader();
if (bookAppointmentsViewModel.patientDentalPlanEstimationList.isNotEmpty) {
showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: context),
title: "Dental treatment plan".needTranslation,
context,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"You have an existing treatment plan: ".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 8.h),
Container(
width: double.infinity,
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsViewModel.patientDentalPlanEstimationList.length,
separatorBuilder: (_, __) {
return Column(
children: [
SizedBox(height: 8.h),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(height: 8.h),
],
);
},
itemBuilder: (context, index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
bookAppointmentsViewModel.patientDentalPlanEstimationList[index].procedureName!.toText12(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "${bookAppointmentsViewModel.totalTimeNeededForDentalProcedure} Mins".needTranslation),
],
);
},
),
SizedBox(
height: 16.h,
),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(
height: 8.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total time required".needTranslation.toText14(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "30 Mins".needTranslation),
],
)
],
),
),
SizedBox(height: 16.h),
"Would you like to continue it?".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.cancel.tr(),
onPressed: () {
bookAppointmentsViewModel.setIsContinueDentalPlan(false);
Navigator.of(context).pop();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
),
),
SizedBox(width: 8.h),
Expanded(
child: CustomButton(
text: LocaleKeys.confirm.tr(),
onPressed: () async {
bookAppointmentsViewModel.setIsContinueDentalPlan(true);
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
},
backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor,
textColor: Colors.white,
icon: AppAssets.confirm,
),
),
],
)
],
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
} else {
// Navigate to Chief Complaint Screen
}
});
} else { } else {
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: SelectDoctorPage(), page: DentalChiefComplaintsPage(),
), ),
); );
} }
@ -361,7 +251,18 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false, showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) { child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data); return getRegionalSelectionWidget(data);
}), callBackFunc: () {}); }), callBackFunc: () {
if (type == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER && appState.isAuthenticated) {
initDentalAppointmentBookingFlow(regionalViewModel.selectedHospital?.hospitalList.first.iD);
} else {
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
Navigator.of(context).push(
CustomPageRoute(
page: DentalChiefComplaintsPage(),
),
);
}
});
} }
Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data) { Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data) {
@ -378,12 +279,12 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
return HospitalBottomSheetBody(); return HospitalBottomSheetBody();
} }
if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) { if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) {
//if the region screen is opened for the dental clinic thenthe project id will be in the hospital list as the list is formed form the get project api //if the region screen is opened for the dental clinic then the project id will be in the hospital list as the list is formed form the get project api
var id = ""; var id = "";
if (data.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) { if (data.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
id = regionalViewModel.selectedHospital?.hospitalList?.first?.iD?.toString() ?? ""; id = regionalViewModel.selectedHospital?.hospitalList.first.iD?.toString() ?? "";
} else { } else {
id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first?.projectID?.toString() ?? ""; id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first.projectID?.toString() ?? "";
} }
bookAppointmentsViewModel.setProjectID(id); bookAppointmentsViewModel.setProjectID(id);
return SizedBox.shrink(); return SizedBox.shrink();
@ -410,4 +311,128 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
}); });
} }
} }
void initDentalAppointmentBookingFlow(int projectID) async {
bookAppointmentsViewModel.setProjectID(projectID.toString());
LoaderBottomSheet.showLoader(loadingText: "Checking for an existing dental plan, Please wait...".needTranslation);
await bookAppointmentsViewModel.getPatientDentalEstimation(projectID: projectID).then((value) {
LoaderBottomSheet.hideLoader();
if (bookAppointmentsViewModel.patientDentalPlanEstimationList.isNotEmpty) {
showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: context),
title: "Dental treatment plan".needTranslation,
context,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"You have an existing treatment plan: ".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 8.h),
Container(
width: double.infinity,
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsViewModel.patientDentalPlanEstimationList.length,
separatorBuilder: (_, __) {
return Column(
children: [
SizedBox(height: 8.h),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(height: 8.h),
],
);
},
itemBuilder: (context, index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
bookAppointmentsViewModel.patientDentalPlanEstimationList[index].procedureName!.toText12(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "${bookAppointmentsViewModel.totalTimeNeededForDentalProcedure} Mins".needTranslation),
],
);
},
),
SizedBox(
height: 16.h,
),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(
height: 8.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total time required".needTranslation.toText14(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "30 Mins".needTranslation),
],
)
],
),
),
SizedBox(height: 16.h),
"Would you like to continue it?".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.cancel.tr(),
onPressed: () {
bookAppointmentsViewModel.setIsContinueDentalPlan(false);
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
Navigator.of(context).pop();
Navigator.of(context).push(
CustomPageRoute(
page: DentalChiefComplaintsPage(),
),
);
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
),
),
SizedBox(width: 8.h),
Expanded(
child: CustomButton(
text: LocaleKeys.confirm.tr(),
onPressed: () async {
bookAppointmentsViewModel.setIsContinueDentalPlan(true);
Navigator.of(context).pop();
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
},
backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor,
textColor: Colors.white,
icon: AppAssets.confirm,
),
),
],
)
],
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
} else {
// Navigate to Chief Complaint Screen
}
});
}
} }

@ -21,7 +21,6 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class SelectDoctorPage extends StatefulWidget { class SelectDoctorPage extends StatefulWidget {
@ -45,7 +44,11 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
if (bookAppointmentsViewModel.isLiveCareSchedule) { if (bookAppointmentsViewModel.isLiveCareSchedule) {
bookAppointmentsViewModel.getLiveCareDoctorsList(); bookAppointmentsViewModel.getLiveCareDoctorsList();
} else { } else {
bookAppointmentsViewModel.getDoctorsList(); if (bookAppointmentsViewModel.selectedClinic.clinicID == 17) {
bookAppointmentsViewModel.getDentalChiefComplaintDoctorsList();
} else {
bookAppointmentsViewModel.getDoctorsList();
}
} }
}); });
super.initState(); super.initState();
@ -66,7 +69,6 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// TODO: Implement doctor filter functionality
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Row(
spacing: 8.h, spacing: 8.h,

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class ChiefComplaintCard extends StatelessWidget {
ChiefComplaintCard({super.key, required this.isLoading, required this.bookAppointmentsVM, required this.dentalChiefComplaintsListResponseModel});
bool isLoading;
BookAppointmentsViewModel bookAppointmentsVM;
DentalChiefComplaintsListResponseModel dentalChiefComplaintsListResponseModel;
@override
Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>();
return Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: false,
),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(child: (isLoading ? "Cardiology" : dentalChiefComplaintsListResponseModel.name)!.toText16(isBold: true).toShimmer2(isShow: isLoading)),
Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 40.h, height: 40.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)),
]),
);
}
}

@ -36,7 +36,8 @@ class ClinicCard extends StatelessWidget {
(clinicsListResponseModel.isLiveCareClinicAndOnline ?? true) (clinicsListResponseModel.isLiveCareClinicAndOnline ?? true)
? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading) ? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading)
: SizedBox.shrink(), : SizedBox.shrink(),
]), ],
),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded( Expanded(
@ -44,7 +45,7 @@ class ClinicCard extends StatelessWidget {
.toText16(isBold: true) .toText16(isBold: true)
.toShimmer2(isShow: isLoading)), .toShimmer2(isShow: isLoading)),
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 40.h, height: 40.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 40.h, height: 40.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)),
]), ]),
], ],

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save