diff --git a/assets/images/svg/all_payment_method.svg b/assets/images/svg/all_payment_method.svg
new file mode 100644
index 0000000..ef72e6a
--- /dev/null
+++ b/assets/images/svg/all_payment_method.svg
@@ -0,0 +1,34 @@
+
diff --git a/assets/images/svg/ic_rrt_vehicle.svg b/assets/images/svg/ic_rrt_vehicle.svg
new file mode 100644
index 0000000..d858fb4
--- /dev/null
+++ b/assets/images/svg/ic_rrt_vehicle.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/svg/mada.svg b/assets/images/svg/mada.svg
new file mode 100644
index 0000000..99fd132
--- /dev/null
+++ b/assets/images/svg/mada.svg
@@ -0,0 +1,9 @@
+
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index b276dd7..6a5d34f 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -1,7 +1,7 @@
import Flutter
import UIKit
-import FirebaseCore
-import FirebaseMessaging
+//import FirebaseCore
+//import FirebaseMessaging
import GoogleMaps
@main
@objc class AppDelegate: FlutterAppDelegate {
@@ -10,13 +10,13 @@ import GoogleMaps
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng")
- FirebaseApp.configure()
+// FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
- Messaging.messaging().apnsToken = deviceToken
+// Messaging.messaging().apnsToken = deviceToken
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}
}
diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart
index 28475ea..aa534f6 100644
--- a/lib/core/api/api_client.dart
+++ b/lib/core/api/api_client.dart
@@ -161,10 +161,11 @@ class ApiClientImp implements ApiClient {
// body['VersionID'] = ApiConsts.appVersionID.toString();
if (!isExternal) {
- body['VersionID'] = ApiConsts.appVersionID;
- body['Channel'] = ApiConsts.appChannelId;
+ body['VersionID'] = ApiConsts.appVersionID.toString();
+ body['Channel'] = ApiConsts.appChannelId.toString();
body['IPAdress'] = ApiConsts.appIpAddress;
body['generalid'] = ApiConsts.appGeneralId;
+
body['LanguageID'] = _appState.getLanguageID().toString();
body['Latitude'] = _appState.userLat.toString();
body['Longitude'] = _appState.userLong.toString();
@@ -183,6 +184,9 @@ class ApiClientImp implements ApiClient {
}
body.removeWhere((key, value) => value == null);
+ log("uri: ${Uri.parse(url.trim())}");
+
+ log("body: ${json.encode(body)}");
final bool networkStatus = await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck);
@@ -201,6 +205,7 @@ class ApiClientImp implements ApiClient {
log("uri: ${Uri.parse(url.trim())}");
log("body: ${json.encode(body)}");
log("response.body: ${response.body}");
+ // log("response.body: ${response.body}");
if (statusCode < 200 || statusCode >= 400) {
onFailure('Error While Fetching data', statusCode, failureType: StatusCodeFailure("Error While Fetching data"));
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
@@ -364,7 +369,7 @@ class ApiClientImp implements ApiClient {
debugPrint("URL : $url");
// print("Body : ${json.encode(body)}");
- if (await Utils.checkConnection()) {
+ if (await Utils.checkConnection(bypassConnectionCheck: true)) {
final response = await http.get(
Uri.parse(url.trim()),
headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart
index 4cedda1..2be40d0 100644
--- a/lib/core/api_consts.dart
+++ b/lib/core/api_consts.dart
@@ -753,7 +753,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
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=';
- rcBaseUrl = 'https://rc.hmg.com/';
+ rcBaseUrl = 'https://rc.hmg.com/uat/';
break;
case AppEnvironmentTypeEnum.uat:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -763,7 +763,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
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=';
- rcBaseUrl = 'https://rc.hmg.com/';
+ rcBaseUrl = 'https://rc.hmg.com/uat/';
break;
case AppEnvironmentTypeEnum.preProd:
baseUrl = "https://webservices.hmg.com/";
@@ -783,7 +783,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
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=';
- rcBaseUrl = 'https://rc.hmg.com/';
+ rcBaseUrl = 'https://rc.hmg.com/uat/';
break;
case AppEnvironmentTypeEnum.staging:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -793,7 +793,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
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=';
- rcBaseUrl = 'https://rc.hmg.com/';
+ rcBaseUrl = 'https://rc.hmg.com/uat/';
break;
}
}
@@ -837,16 +837,18 @@ class ApiConsts {
static final String createAdvancePayments = 'Services/Patients.svc/REST/HIS_CreateAdvancePayment';
static final String addAdvanceNumberRequest = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest';
- // RC CMC ServIces
+ // RC COMPREHENSIVE MEDICAL CHECKUP ServIces
static final String allCMCOrdersRc = 'api/cmc/list';
static final String allCMCServicesRc = 'api/cmc/getallcmc';
static final String updateCMCOrder = 'api/cmc/update';
+ static final String addCMCOrder = 'api/cmc/add';
+ static final String getHospitalsList = 'Services/Lists.svc/REST/GetProject';
- // CMC RC SERVICES
- var GET_ALL_CMC_SERVICES_RC = 'api/cmc/getallcmc';
- var ADD_CMC_ORDER_RC = 'api/cmc/add';
- var GET_ALL_CMC_ORDERS_RC = 'api/cmc/list';
- var UPDATE_CMC_ORDER_RC = 'api/cmc/update';
+ // RC HOME HEALTHCARE ServIces
+ static final String allHHCOrdersRc = 'api/hhc/list';
+ static final String allHHCServicesRc = 'api/HHC/getallhhc';
+ static final String updateHHCOrder = 'api/hhc/update';
+ static final String addHHCOrder = 'api/HHC/add';
//E-REFERRAL SERVICES
@@ -860,7 +862,7 @@ class ApiConsts {
// ************ static values for Api ****************
- static final double appVersionID = 20.0;
+ static final double appVersionID = 19.3;
static final int appChannelId = 3;
static final String appIpAddress = "10.20.10.20";
static final String appGeneralId = "Cs2020@2016\$2958";
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index 3f524be..5fccc6e 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -173,6 +173,9 @@ class AppAssets {
static const String forward_arrow_medium = '$svgBasePath/forward_arrow_medium.svg';
static const String eReferral = '$svgBasePath/e-referral.svg';
static const String comprehensiveCheckup = '$svgBasePath/comprehensive_checkup.svg';
+ static const String all_payment_method = '$svgBasePath/all_payment_method.svg';
+ static const String ic_rrt_vehicle = '$svgBasePath/ic_rrt_vehicle.svg';
+
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';
diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart
index 835e9bf..73a93c6 100644
--- a/lib/core/dependencies.dart
+++ b/lib/core/dependencies.dart
@@ -122,7 +122,13 @@ class AppDependencies {
getIt.registerLazySingleton(() => LabViewModel(labRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()));
- getIt.registerLazySingleton(() => RadiologyViewModel(radiologyRepo: getIt(), errorHandlerService: getIt()));
+ getIt.registerLazySingleton(
+ () => RadiologyViewModel(
+ radiologyRepo: getIt(),
+ errorHandlerService: getIt(),
+ navigationService: getIt()
+ ),
+ );
getIt.registerLazySingleton(() => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt()));
@@ -215,7 +221,7 @@ class AppDependencies {
);
getIt.registerLazySingleton(
- () => HmgServicesViewModel(hmgServicesRepo: getIt(), errorHandlerService: getIt()),
+ () => HmgServicesViewModel(bookAppointmentsRepo: getIt(), hmgServicesRepo: getIt(), errorHandlerService: getIt()),
);
// Screen-specific VMs → Factory
diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart
index 82b9909..a918706 100644
--- a/lib/core/utils/date_util.dart
+++ b/lib/core/utils/date_util.dart
@@ -6,6 +6,8 @@ class DateUtil {
/// convert String To Date function
/// [date] String we want to convert
static DateTime convertStringToDate(String? date) {
+
+
if (date == null) return DateTime.now();
if (date.isEmpty) return DateTime.now();
diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart
index 6f1dcc6..e3b108f 100644
--- a/lib/core/utils/utils.dart
+++ b/lib/core/utils/utils.dart
@@ -102,8 +102,9 @@ class Utils {
? getMonthArabic(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString()
: getMonth(dateTime.month) + " " + dateTime.day.toString() + ", " + dateTime.year.toString();
}
+
static String getDayMonthYearDateFormatted(DateTime? dateTime) {
- if(dateTime == null ) return "";
+ if (dateTime == null) return "";
return appState.isArabic()
? "${dateTime.day.toString()} ${getMonthArabic(dateTime.month)}, ${dateTime.year.toString()}"
: "${dateTime.day.toString()} ${getMonth(dateTime.month)}, ${dateTime.year.toString()}";
@@ -376,16 +377,21 @@ class Utils {
).center;
}
- static Widget getWarningWidget(
- {String? loadingText, bool isShowActionButtons = false, Widget? bodyWidget, Function? onConfirmTap, Function? onCancelTap}) {
+ static Widget getWarningWidget({
+ String? loadingText,
+ bool isShowActionButtons = false,
+ Widget? bodyWidget,
+ Function? onConfirmTap,
+ Function? onCancelTap,
+ }) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Lottie.asset(AppAnimations.warningAnimation,
- repeat: false, reverse: false, frameRate: FrameRate(60), width: 128.h, height: 128.h, fit: BoxFit.fill),
+ repeat: false, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
SizedBox(height: 8.h),
- (loadingText ?? LocaleKeys.loadingText.tr()).toText14(color: AppColors.blackColor, letterSpacing: 0),
+ (loadingText ?? LocaleKeys.loadingText.tr()).toText15(color: AppColors.blackColor, letterSpacing: 0),
SizedBox(height: 16.h),
bodyWidget ?? SizedBox.shrink(),
SizedBox(height: 16.h),
@@ -753,14 +759,15 @@ class Utils {
);
}
- static Widget getPaymentAmountWithSymbol2(num habibWalletAmount,
- {double iconSize = 14,
+ static Widget getPaymentAmountWithSymbol2(
+ num habibWalletAmount, {
+ double iconSize = 14,
double? fontSize,
double? letterSpacing,
FontWeight? fontWeight,
Color iconColor = AppColors.textColor,
- Color textColor = AppColors.blackColor,
- bool isSaudiCurrency = true,
+ Color textColor = AppColors.blackColor,
+ bool isSaudiCurrency = true,
bool isExpanded = true,
}) {
return RichText(
@@ -777,7 +784,7 @@ class Utils {
style: TextStyle(
color: textColor,
fontSize: fontSize ?? 32.f,
- letterSpacing: letterSpacing??-4,
+ letterSpacing: letterSpacing ?? -4,
fontWeight: fontWeight ?? FontWeight.w600,
height: 1),
),
@@ -839,7 +846,12 @@ class Utils {
static PatientDoctorAppointmentList? convertToPatientDoctorAppointmentList(HospitalsModel? hospital) {
if (hospital == null) return null;
return PatientDoctorAppointmentList(
- filterName: hospital.name, distanceInKMs: hospital.distanceInKilometers?.toString(), projectTopName: hospital.name, projectBottomName: hospital.name, model: hospital, isHMC: hospital.isHMC);
+ filterName: hospital.name,
+ distanceInKMs: hospital.distanceInKilometers?.toString(),
+ projectTopName: hospital.name,
+ projectBottomName: hospital.name,
+ model: hospital,
+ isHMC: hospital.isHMC);
}
static bool havePrivilege(int id) {
@@ -853,7 +865,4 @@ class Utils {
}
return isHavePrivilege;
}
-
-
-
}
diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart
index 1a6d1cc..250453d 100644
--- a/lib/extensions/string_extensions.dart
+++ b/lib/extensions/string_extensions.dart
@@ -41,12 +41,14 @@ extension EmailValidator on String {
FontWeight? weight,
bool isBold = false,
bool isUnderLine = false,
+ bool isCenter = false,
int? maxlines,
FontStyle? fontStyle,
TextOverflow? textOverflow,
double letterSpacing = 0}) =>
Text(
this,
+ textAlign: isCenter ? TextAlign.center : null,
maxLines: maxlines,
overflow: textOverflow,
style: TextStyle(
@@ -223,6 +225,7 @@ extension EmailValidator on String {
FontWeight? weight,
TextOverflow? textOverflow,
double? letterSpacing = -0.4,
+ Color decorationColor =AppColors.errorColor
}) =>
Text(
this,
@@ -236,6 +239,7 @@ extension EmailValidator on String {
overflow: textOverflow,
fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal),
decoration: isUnderLine ? TextDecoration.underline : null,
+ decorationColor: decorationColor
),
);
diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart
index 424aa88..70f10bb 100644
--- a/lib/extensions/widget_extensions.dart
+++ b/lib/extensions/widget_extensions.dart
@@ -1,9 +1,8 @@
-import 'package:hmg_patient_app_new/core/enums.dart';
-import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
+import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/extensions/int_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:shimmer/shimmer.dart';
import 'package:sizer/sizer.dart';
import 'package:smooth_corner/smooth_corner.dart';
@@ -19,7 +18,8 @@ extension WidgetExtensions on Widget {
Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this);
- Widget paddingSymmetrical(double horizontal, double vertical) => Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);
+ Widget paddingSymmetrical(double horizontal, double vertical) =>
+ Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);
Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) =>
Padding(padding: EdgeInsetsDirectional.only(start: left, end: right, top: top, bottom: bottom), child: this);
@@ -99,7 +99,7 @@ extension WidgetExtensions on Widget {
bool disablePadding = false,
double radius = 20,
Color? color,
- Color borderColor = AppColors.buttonColor,
+ Color? borderColor,
bool disableWidth = false,
bool isAlignment = false}) {
return Container(
@@ -110,7 +110,7 @@ extension WidgetExtensions on Widget {
),
color: color,
border: Border.all(
- color: borderColor,
+ color: borderColor ?? Colors.transparent,
width: disableWidth ? 2 : 1,
),
),
diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart
index f24766b..a50b683 100644
--- a/lib/features/book_appointments/book_appointments_view_model.dart
+++ b/lib/features/book_appointments/book_appointments_view_model.dart
@@ -3,7 +3,6 @@ import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
-import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/location_util.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
@@ -105,8 +104,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
List searchedRegionList = [];
List facilityList = ["hmgHospitals", "hmcMedicalClinic"];
List searchedHospitalList = [];
- List
- searchedPatientDoctorAppointmentHospitalsList = [];
+ List searchedPatientDoctorAppointmentHospitalsList = [];
List searchedClinicList = [];
PatientDoctorAppointmentList? selectedHospitalForFilters;
@@ -114,15 +112,14 @@ class BookAppointmentsViewModel extends ChangeNotifier {
String? selectedClinicForFilters;
bool applyFilters = false;
-
///variables for laser clinic
- List femaleLaserCategory = [
+ List femaleLaserCategory = [
LaserCategoryType(1, 'bodyString'),
LaserCategoryType(2, 'face'),
- LaserCategoryType(10,'bikini'),
+ LaserCategoryType(10, 'bikini'),
LaserCategoryType(11, 'retouch'),
];
- List maleLaserCategory =[
+ List maleLaserCategory = [
LaserCategoryType(1, 'body'),
LaserCategoryType(2, 'face'),
LaserCategoryType(11, 'retouch'),
@@ -136,9 +133,13 @@ class BookAppointmentsViewModel extends ChangeNotifier {
bool isBodyPartsLoading = false;
int duration = 0;
-
BookAppointmentsViewModel(
- {required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils, required this.dialogService }) {
+ {required this.bookAppointmentsRepo,
+ required this.errorHandlerService,
+ required this.navigationService,
+ required this.myAppointmentsViewModel,
+ required this.locationUtils,
+ required this.dialogService}) {
initBookAppointmentViewModel();
}
@@ -287,7 +288,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
Future getLiveCareScheduleClinics({Function(dynamic)? onSuccess, Function(String)? onError}) async {
liveCareClinicsList.clear();
- final result = await bookAppointmentsRepo.getLiveCareScheduleClinics(_appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!);
+ final result =
+ await bookAppointmentsRepo.getLiveCareScheduleClinics(_appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@@ -309,8 +311,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
Future getLiveCareDoctorsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear();
- final result =
- await bookAppointmentsRepo.getLiveCareDoctorsList(selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!, onError: onError);
+ final result = await bookAppointmentsRepo.getLiveCareDoctorsList(
+ selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!,
+ onError: onError);
result.fold(
(failure) async {
@@ -333,10 +336,17 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
//TODO: Make the API dynamic with parameters for ProjectID, isNearest, languageID, doctorId, doctorName
- Future getDoctorsList({int projectID = 0, bool isNearest = false, int doctorId = 0, String doctorName = "", Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ Future getDoctorsList(
+ {int projectID = 0,
+ bool isNearest = false,
+ int doctorId = 0,
+ String doctorName = "",
+ Function(dynamic)? onSuccess,
+ Function(String)? onError}) async {
doctorsList.clear();
projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
- final result = await bookAppointmentsRepo.getDoctorsList(selectedClinic.clinicID ?? 0, projectID, isNearest, doctorId, doctorName, isContinueDentalPlan: isContinueDentalPlan);
+ final result = await bookAppointmentsRepo.getDoctorsList(selectedClinic.clinicID ?? 0, projectID, isNearest, doctorId, doctorName,
+ isContinueDentalPlan: isContinueDentalPlan);
result.fold(
(failure) async {
@@ -365,7 +375,13 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
Future getMappedDoctors(
- {int projectID = 0, bool isNearest = false, int doctorId = 0, String doctorName = "", isContinueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ {int projectID = 0,
+ bool isNearest = false,
+ int doctorId = 0,
+ String doctorName = "",
+ isContinueDentalPlan = false,
+ Function(dynamic)? onSuccess,
+ Function(String)? onError}) async {
filteredHospitalList = null;
hospitalList = null;
isRegionListLoading = true;
@@ -374,10 +390,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
final result = await bookAppointmentsRepo.getDoctorsList(selectedClinic.clinicID ?? 0, projectID, isNearest, doctorId, doctorName);
result.fold(
- (failure) async {
+ (failure) async {
onError?.call("No doctors found for the search criteria".needTranslation);
},
- (apiResponse) async {
+ (apiResponse) async {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
@@ -401,7 +417,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
Future getDoctorProfile({Function(dynamic)? onSuccess, Function(String)? onError}) async {
- final result = await bookAppointmentsRepo.getDoctorProfile(selectedDoctor.clinicID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, onError: onError);
+ final result = await bookAppointmentsRepo
+ .getDoctorProfile(selectedDoctor.clinicID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, onError: onError);
result.fold(
(failure) async {},
@@ -457,7 +474,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
// :
date = DateUtil.convertStringToDateSaudiTimezone(element, int.parse(selectedDoctor.projectID.toString()));
slotsList.add(FreeSlot(date, ['slot']));
- docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element));
+ docFreeSlots.add(TimeSlot(
+ isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element));
});
notifyListeners();
@@ -476,8 +494,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
final DateFormat dateFormatter = DateFormat('yyyy-MM-dd');
Map _eventsParsed;
- final result = await bookAppointmentsRepo.getLiveCareDoctorFreeSlots(
- selectedDoctor.clinicID ?? 0, selectedLiveCareClinic.serviceID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, isBookingForLiveCare,
+ final result = await bookAppointmentsRepo.getLiveCareDoctorFreeSlots(selectedDoctor.clinicID ?? 0, selectedLiveCareClinic.serviceID ?? 0,
+ selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, isBookingForLiveCare,
onError: onError);
result.fold(
@@ -501,7 +519,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
// :
date = DateUtil.convertStringToDateSaudiTimezone(element, int.parse(selectedDoctor.projectID.toString()));
slotsList.add(FreeSlot(date, ['slot']));
- docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element));
+ docFreeSlots.add(TimeSlot(
+ isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element));
});
notifyListeners();
@@ -513,7 +532,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
);
}
- Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ Future cancelAppointment(
+ {required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel,
+ Function(dynamic)? onSuccess,
+ Function(String)? onError}) async {
final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
result.fold(
@@ -597,13 +619,15 @@ class BookAppointmentsViewModel extends ChangeNotifier {
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
navigationService.pop();
Future.delayed(Duration(milliseconds: 50)).then((value) async {});
- LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation);
+ LoadingUtils.showFullScreenLoader(
+ barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation);
await insertSpecificAppointment(
onError: (err) {},
onSuccess: (apiResp) async {
LoadingUtils.hideFullScreenLoader();
await Future.delayed(Duration(milliseconds: 50)).then((value) async {
- LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr());
+ LoadingUtils.showFullScreenLoader(
+ barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr());
await Future.delayed(Duration(milliseconds: 4000)).then((value) {
LoadingUtils.hideFullScreenLoader();
Navigator.pushAndRemoveUntil(
@@ -693,13 +717,15 @@ class BookAppointmentsViewModel extends ChangeNotifier {
await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async {
navigationService.pop();
Future.delayed(Duration(milliseconds: 50)).then((value) async {});
- LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation);
+ LoadingUtils.showFullScreenLoader(
+ barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation);
await insertSpecificAppointment(
onError: (err) {},
onSuccess: (apiResp) async {
LoadingUtils.hideFullScreenLoader();
await Future.delayed(Duration(milliseconds: 50)).then((value) async {
- LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr());
+ LoadingUtils.showFullScreenLoader(
+ barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr());
await Future.delayed(Duration(milliseconds: 4000)).then((value) {
LoadingUtils.hideFullScreenLoader();
Navigator.pushAndRemoveUntil(
@@ -773,7 +799,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
} else {
filteredHospitalList = RegionList();
- var list = isHMG ? hospitalList?.registeredDoctorMap![selectedRegionId]!.hmgDoctorList : hospitalList?.registeredDoctorMap![selectedRegionId]!.hmcDoctorList;
+ var list = isHMG
+ ? hospitalList?.registeredDoctorMap![selectedRegionId]!.hmgDoctorList
+ : hospitalList?.registeredDoctorMap![selectedRegionId]!.hmcDoctorList;
if (list != null && list.isEmpty) {
notifyListeners();
@@ -856,12 +884,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
- void setSelections(
- List? selectedFacilityForFilters,
- List? selectedRegionForFilters,
- String? selectedClinicForFilters,
- PatientDoctorAppointmentList? selectedHospitalForFilters,
- bool applyFilters) {
+ void setSelections(List? selectedFacilityForFilters, List? selectedRegionForFilters, String? selectedClinicForFilters,
+ PatientDoctorAppointmentList? selectedHospitalForFilters, bool applyFilters) {
this.selectedFacilityForFilters = selectedFacilityForFilters;
this.selectedClinicForFilters = selectedClinicForFilters;
this.selectedHospitalForFilters = selectedHospitalForFilters;
@@ -872,17 +896,14 @@ class BookAppointmentsViewModel extends ChangeNotifier {
void getFiltersFromDoctorList() {
doctorsList.forEach((element) {
- if (!searchedRegionList
- .contains(element.getRegionName(_appState.isArabic()))) {
- searchedRegionList
- .add(element.getRegionName(_appState.isArabic()) ?? "");
+ if (!searchedRegionList.contains(element.getRegionName(_appState.isArabic()))) {
+ searchedRegionList.add(element.getRegionName(_appState.isArabic()) ?? "");
}
if (!searchedHospitalList.contains(element.projectName)) {
- searchedPatientDoctorAppointmentHospitalsList
- .add(PatientDoctorAppointmentList()
- ..filterName = element.projectName
- ..isHMC = element.isHMC
- ..distanceInKMs = "0");
+ searchedPatientDoctorAppointmentHospitalsList.add(PatientDoctorAppointmentList()
+ ..filterName = element.projectName
+ ..isHMC = element.isHMC
+ ..distanceInKMs = "0");
searchedHospitalList.add(element.projectName ?? "");
}
if (!searchedClinicList.contains(element.clinicName)) {
@@ -939,27 +960,15 @@ class BookAppointmentsViewModel extends ChangeNotifier {
return doctorsList;
}
var list = doctorsList.where((element) {
- var isInSelectedRegion = (selectedRegionForFilters?.isEmpty == true)
- ? true
- : selectedRegionForFilters
- ?.any((region) => region == element.getRegionName(isArabic()));
- var shouldApplyFacilityFilter =
- (selectedFacilityForFilters?.isEmpty == true) ? false : true;
- var isHMC = (selectedFacilityForFilters?.isEmpty == true)
- ? true
- : selectedFacilityForFilters?.any((item) => item.contains("hmc"));
- var isInSelectedClinic = (selectedClinicForFilters == null)
- ? true
- : selectedClinicForFilters == element.clinicName;
- var isInSelectedHospital = (selectedHospitalForFilters == null)
- ? true
- : element.projectName == selectedHospitalForFilters?.filterName;
+ var isInSelectedRegion =
+ (selectedRegionForFilters?.isEmpty == true) ? true : selectedRegionForFilters?.any((region) => region == element.getRegionName(isArabic()));
+ var shouldApplyFacilityFilter = (selectedFacilityForFilters?.isEmpty == true) ? false : true;
+ var isHMC = (selectedFacilityForFilters?.isEmpty == true) ? true : selectedFacilityForFilters?.any((item) => item.contains("hmc"));
+ var isInSelectedClinic = (selectedClinicForFilters == null) ? true : selectedClinicForFilters == element.clinicName;
+ var isInSelectedHospital = (selectedHospitalForFilters == null) ? true : element.projectName == selectedHospitalForFilters?.filterName;
var facilityFilter = ((shouldApplyFacilityFilter == true) ? isHMC : true);
- return (isInSelectedRegion ?? true) &&
- (facilityFilter ?? true) &&
- isInSelectedClinic &&
- isInSelectedHospital;
+ return (isInSelectedRegion ?? true) && (facilityFilter ?? true) && isInSelectedClinic && isInSelectedHospital;
}).toList();
return list;
}
@@ -1003,7 +1012,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
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);
+ final result = await bookAppointmentsRepo.getDentalChiefComplaintsList(
+ patientID: patientID, projectID: int.parse(currentlySelectedHospitalFromRegionFlow ?? "0"), clinicID: 17);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@@ -1051,7 +1061,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
);
}
- setBodyType(int bodyType){
+ setBodyType(int bodyType) {
selectedBodyTypeIndex = bodyType;
selectedCategory = 0;
selectedBodyPartList = [];
@@ -1059,33 +1069,33 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
- FutureOr getLaserClinic() async{
+ FutureOr getLaserClinic() async {
isBodyPartsLoading = true;
int id = bodyTypes[selectedBodyTypeIndex][selectedCategory].laserCategoryID;
int projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : 0;
int languageID = _appState.isArabic() ? 1 : 0;
final result = await bookAppointmentsRepo.getLaserClinics(id, projectID, languageID);
result.fold(
- (failure) {
+ (failure) {
isBodyPartsLoading = false;
notifyListeners();
},
- (apiResponse) {isBodyPartsLoading = false;
+ (apiResponse) {
+ isBodyPartsLoading = false;
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
- List response =apiResponse.data!;
- if(response.first.category == 2 || response.first.category == 10 ) response.remove(response.first);
+ List response = apiResponse.data!;
+ if (response.first.category == 2 || response.first.category == 10) response.remove(response.first);
laserBodyPartsList = response;
}
- notifyListeners();
-
+ notifyListeners();
},
);
}
int getDuration() {
- var duration = 0;
+ var duration = 0;
var lowerUpperLegsList = selectedBodyPartList.where((element) => element.mappingCode == "47" || element.mappingCode == "48")?.toList() ?? [];
var upperLowerArmsList = selectedBodyPartList.where((element) => element.mappingCode == "40" || element.mappingCode == "41")?.toList() ?? [];
@@ -1110,21 +1120,25 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
void setSelectedBodyPart(LaserBodyPart part) {
- if(selectedBodyPartList.contains(part)){
+ if (selectedBodyPartList.contains(part)) {
selectedBodyPartList.remove(part);
this.duration = getDuration();
notifyListeners();
} else {
- if(this.duration == 90){
- dialogService.showErrorBottomSheet(message: "Duration can not exceed 90 min".needTranslation,);
+ if (this.duration == 90) {
+ dialogService.showErrorBottomSheet(
+ message: "Duration can not exceed 90 min".needTranslation,
+ );
return;
}
selectedBodyPartList.add(part);
var duration = getDuration();
- if(duration > 90){
+ if (duration > 90) {
selectedBodyPartList.remove(part);
- dialogService.showErrorBottomSheet(message: "Duration Exceeds 90 min".needTranslation,);
+ dialogService.showErrorBottomSheet(
+ message: "Duration Exceeds 90 min".needTranslation,
+ );
return;
}
this.duration = duration;
@@ -1137,10 +1151,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}
String getLaserProcedureNameWRTLanguage(LaserBodyPart part) {
- if(_appState.isArabic()){
- return part.bodyPartN??"";
- }else {
- return part.bodyPart??"";
+ if (_appState.isArabic()) {
+ return part.bodyPartN ?? "";
+ } else {
+ return part.bodyPart ?? "";
}
}
diff --git a/lib/features/contact_us/contact_us_repo.dart b/lib/features/contact_us/contact_us_repo.dart
index f2b1169..3e96f91 100644
--- a/lib/features/contact_us/contact_us_repo.dart
+++ b/lib/features/contact_us/contact_us_repo.dart
@@ -3,14 +3,18 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart';
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/exceptions/api_failure.dart';
+import 'package:hmg_patient_app_new/features/contact_us/models/req_models/request_insert_coc_item.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_hmg_locations.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_patient_ic_projects.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class ContactUsRepo {
Future>>> getHMGLocations();
Future>>> getLiveChatProjectsList();
+
+ Future>> insertCOCItem({required RequestInsertCOCItem requestInsertCOCItem, PatientAppointmentHistoryResponseModel? patientSelectedAppointment});
}
class ContactUsRepoImp implements ContactUsRepo {
@@ -72,13 +76,57 @@ class ContactUsRepoImp implements ContactUsRepo {
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_PatientICProjects'];
- final hmgLocations = list.map((item) => GetPatientICProjectsModel.fromJson(item as Map)).toList().cast();
+ final liveChatProjectsList = list.map((item) => GetPatientICProjectsModel.fromJson(item as Map)).toList().cast();
apiResponse = GenericApiModel>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
- data: hmgLocations,
+ data: liveChatProjectsList,
+ );
+ } 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>> insertCOCItem({required RequestInsertCOCItem requestInsertCOCItem, PatientAppointmentHistoryResponseModel? patientSelectedAppointment}) async {
+ final Map body = requestInsertCOCItem.toJson();
+
+ if (patientSelectedAppointment != null) {
+ body['AppoinmentNo'] = patientSelectedAppointment.appointmentNo;
+ body['AppointmentDate'] = patientSelectedAppointment.appointmentDate;
+ body['ClinicID'] = patientSelectedAppointment.clinicID;
+ body['ClinicName'] = patientSelectedAppointment.clinicName;
+ body['DoctorID'] = patientSelectedAppointment.doctorID;
+ body['DoctorName'] = patientSelectedAppointment.doctorNameObj;
+ body['ProjectName'] = patientSelectedAppointment.projectName;
+ }
+
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ SEND_FEEDBACK,
+ body: body,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
diff --git a/lib/features/contact_us/contact_us_view_model.dart b/lib/features/contact_us/contact_us_view_model.dart
index 7826bd1..1185700 100644
--- a/lib/features/contact_us/contact_us_view_model.dart
+++ b/lib/features/contact_us/contact_us_view_model.dart
@@ -1,7 +1,15 @@
+import 'dart:io';
+
import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
+import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/contact_us/contact_us_repo.dart';
+import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dart';
+import 'package:hmg_patient_app_new/features/contact_us/models/req_models/request_insert_coc_item.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_hmg_locations.dart';
+import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_patient_ic_projects.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
class ContactUsViewModel extends ChangeNotifier {
@@ -11,17 +19,43 @@ class ContactUsViewModel extends ChangeNotifier {
bool isHMGLocationsListLoading = false;
bool isHMGHospitalsListSelected = true;
+ bool isLiveChatProjectsListLoading = false;
+ bool isSendFeedbackTabSelected = true;
List hmgHospitalsLocationsList = [];
List hmgPharmacyLocationsList = [];
+ List liveChatProjectsList = [];
+
+ int selectedLiveChatProjectIndex = -1;
+
+ List feedbackAttachmentList = [];
+
+ PatientAppointmentHistoryResponseModel? patientFeedbackSelectedAppointment;
+
+ List feedbackTypeList = [
+ FeedbackType(id: 1, nameEN: "Complaint for appointment", nameAR: 'شكوى على موعد'),
+ FeedbackType(id: 2, nameEN: "Complaint without appointment", nameAR: 'شكوى بدون موعد'),
+ FeedbackType(id: 3, nameEN: "Question", nameAR: 'سؤال'),
+ FeedbackType(id: 4, nameEN: "Appreciation", nameAR: 'تقدير'),
+ FeedbackType(id: 6, nameEN: "Suggestion", nameAR: 'إقتراØ'),
+ FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير Ù…ØØ¯Ø¯'),
+ ];
+
+ FeedbackType selectedFeedbackType = FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير Ù…ØØ¯Ø¯');
+
ContactUsViewModel({required this.contactUsRepo, required this.errorHandlerService, required this.appState});
initContactUsViewModel() {
isHMGLocationsListLoading = true;
isHMGHospitalsListSelected = true;
+ isLiveChatProjectsListLoading = true;
hmgHospitalsLocationsList.clear();
hmgPharmacyLocationsList.clear();
+ liveChatProjectsList.clear();
+ feedbackAttachmentList.clear();
+ selectedFeedbackType = FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير Ù…ØØ¯Ø¯');
+ setPatientFeedbackSelectedAppointment(null);
getHMGLocations();
notifyListeners();
}
@@ -31,6 +65,36 @@ class ContactUsViewModel extends ChangeNotifier {
notifyListeners();
}
+ setSelectedLiveChatProjectIndex(int index) {
+ selectedLiveChatProjectIndex = index;
+ notifyListeners();
+ }
+
+ setIsSendFeedbackTabSelected(bool isSelected) {
+ isSendFeedbackTabSelected = isSelected;
+ notifyListeners();
+ }
+
+ setSelectedFeedbackType(FeedbackType feedbackType) {
+ selectedFeedbackType = feedbackType;
+ notifyListeners();
+ }
+
+ addFeedbackAttachment(String attachmentPath) {
+ feedbackAttachmentList.add(attachmentPath);
+ notifyListeners();
+ }
+
+ removeFeedbackAttachment(String attachmentPath) {
+ feedbackAttachmentList.remove(attachmentPath);
+ notifyListeners();
+ }
+
+ setPatientFeedbackSelectedAppointment(PatientAppointmentHistoryResponseModel? appointment) {
+ patientFeedbackSelectedAppointment = appointment;
+ notifyListeners();
+ }
+
Future getHMGLocations({Function(dynamic)? onSuccess, Function(String)? onError}) async {
isHMGLocationsListLoading = true;
hmgHospitalsLocationsList.clear();
@@ -62,4 +126,73 @@ class ContactUsViewModel extends ChangeNotifier {
},
);
}
+
+ Future getLiveChatProjectsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ isLiveChatProjectsListLoading = true;
+ liveChatProjectsList.clear();
+
+ notifyListeners();
+
+ final result = await contactUsRepo.getLiveChatProjectsList();
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ liveChatProjectsList = apiResponse.data!;
+ liveChatProjectsList.sort((a, b) => b.distanceInKilometers.compareTo(a.distanceInKilometers));
+ isLiveChatProjectsListLoading = false;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
+
+ Future insertCOCItem({required String subject, required String message, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ RequestInsertCOCItem requestInsertCOCItem = RequestInsertCOCItem();
+ requestInsertCOCItem.attachment = feedbackAttachmentList.isNotEmpty ? feedbackAttachmentList.first : "";
+ requestInsertCOCItem.title = subject;
+ requestInsertCOCItem.details = message;
+ requestInsertCOCItem.cOCTypeName = selectedFeedbackType.id.toString();
+ requestInsertCOCItem.formTypeID = selectedFeedbackType.id.toString();
+ requestInsertCOCItem.mobileNo = "966${Utils.getPhoneNumberWithoutZero(appState.getAuthenticatedUser()!.mobileNumber!)}";
+ requestInsertCOCItem.isUserLoggedIn = true;
+ requestInsertCOCItem.projectID = 0;
+ requestInsertCOCItem.patientName = "${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}";
+ requestInsertCOCItem.fileName = "";
+ requestInsertCOCItem.appVersion = ApiConsts.appVersionID;
+ requestInsertCOCItem.uILanguage = appState.isArabic() ? "ar" : "en"; //TODO Change it to be dynamic
+ requestInsertCOCItem.browserInfo = Platform.localHostname;
+ requestInsertCOCItem.deviceInfo = Platform.localHostname;
+ requestInsertCOCItem.resolution = "400x847";
+ requestInsertCOCItem.projectID = 0;
+ requestInsertCOCItem.tokenID = "C0c@@dm!n?T&A&A@Barcha202029582948";
+ requestInsertCOCItem.identificationNo = int.parse(appState.getAuthenticatedUser()!.patientIdentificationNo!);
+ if (BASE_URL.contains('uat')) {
+ requestInsertCOCItem.forDemo = true;
+ } else {
+ requestInsertCOCItem.forDemo = false;
+ }
+
+ final result = await contactUsRepo.insertCOCItem(requestInsertCOCItem: requestInsertCOCItem, patientSelectedAppointment: patientFeedbackSelectedAppointment);
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
}
diff --git a/lib/features/contact_us/models/feedback_type.dart b/lib/features/contact_us/models/feedback_type.dart
new file mode 100644
index 0000000..ff1025a
--- /dev/null
+++ b/lib/features/contact_us/models/feedback_type.dart
@@ -0,0 +1,11 @@
+class FeedbackType {
+ final int id;
+ final String nameEN;
+ final String nameAR;
+
+ FeedbackType({
+ required this.id,
+ required this.nameEN,
+ required this.nameAR,
+ });
+}
diff --git a/lib/features/contact_us/models/req_models/request_insert_coc_item.dart b/lib/features/contact_us/models/req_models/request_insert_coc_item.dart
new file mode 100644
index 0000000..e285999
--- /dev/null
+++ b/lib/features/contact_us/models/req_models/request_insert_coc_item.dart
@@ -0,0 +1,137 @@
+class RequestInsertCOCItem {
+ bool? isUserLoggedIn;
+ String? mobileNo;
+ int? identificationNo;
+ int? patientID;
+ int? patientOutSA;
+ int? patientTypeID;
+ String? tokenID;
+ String? patientName;
+ int? projectID;
+ String? fileName;
+ String? attachment;
+ String? uILanguage;
+ String? browserInfo;
+ String? cOCTypeName;
+ String? formTypeID;
+ String? details;
+ String? deviceInfo;
+ String? deviceType;
+ String? title;
+ String? resolution;
+ double? versionID;
+ int? channel;
+ int? languageID;
+ String? iPAdress;
+ String? generalid;
+ String? sessionID;
+ bool? isDentalAllowedBackend;
+ int? deviceTypeID;
+ int? patientType;
+ double? appVersion;
+ bool? forDemo;
+
+ RequestInsertCOCItem(
+ {this.isUserLoggedIn,
+ this.mobileNo,
+ this.identificationNo,
+ this.patientID,
+ this.patientOutSA,
+ this.patientTypeID,
+ this.tokenID,
+ this.patientName,
+ this.projectID,
+ this.fileName,
+ this.attachment,
+ this.uILanguage,
+ this.browserInfo,
+ this.cOCTypeName,
+ this.formTypeID,
+ this.details,
+ this.deviceInfo,
+ this.deviceType,
+ this.title,
+ this.resolution,
+ this.versionID,
+ this.channel,
+ this.languageID,
+ this.iPAdress,
+ this.generalid,
+ this.sessionID,
+ this.isDentalAllowedBackend,
+ this.deviceTypeID,
+ this.patientType,
+ this.appVersion,
+ this.forDemo});
+
+ RequestInsertCOCItem.fromJson(Map json) {
+ isUserLoggedIn = json['IsUserLoggedIn'];
+ mobileNo = json['MobileNo'];
+ identificationNo = json['IdentificationNo'];
+ patientID = json['PatientID'];
+ patientOutSA = json['PatientOutSA'];
+ patientTypeID = json['PatientTypeID'];
+ tokenID = json['TokenID'];
+ patientName = json['PatientName'];
+ projectID = json['ProjectID'];
+ fileName = json['FileName'];
+ attachment = json['Attachment'];
+ uILanguage = json['UILanguage'];
+ browserInfo = json['BrowserInfo'];
+ cOCTypeName = json['COCTypeName'];
+ formTypeID = json['FormTypeID'];
+ details = json['Details'];
+ deviceInfo = json['DeviceInfo'];
+ deviceType = json['DeviceType'];
+ title = json['Title'];
+ resolution = json['Resolution'];
+ versionID = json['VersionID'];
+ channel = json['Channel'];
+ languageID = json['LanguageID'];
+ iPAdress = json['IPAdress'];
+ generalid = json['generalid'];
+ sessionID = json['SessionID'];
+ isDentalAllowedBackend = json['isDentalAllowedBackend'];
+ deviceTypeID = json['DeviceTypeID'];
+ patientType = json['PatientType'];
+ appVersion = json['AppVersion'];
+ forDemo = json['ForDemo'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['IsUserLoggedIn'] = this.isUserLoggedIn;
+ data['MobileNo'] = this.mobileNo;
+ data['IdentificationNo'] = this.identificationNo;
+ data['PatientID'] = this.patientID;
+ data['PatientOutSA'] = this.patientOutSA;
+ data['PatientTypeID'] = this.patientTypeID;
+ data['TokenID'] = this.tokenID;
+ data['PatientName'] = this.patientName;
+ data['ProjectID'] = this.projectID;
+ data['FileName'] = this.fileName;
+ data['Attachment'] = this.attachment;
+ data['UILanguage'] = this.uILanguage;
+ data['BrowserInfo'] = this.browserInfo;
+ data['COCTypeName'] = this.cOCTypeName;
+ data['FormTypeID'] = this.formTypeID;
+ data['Details'] = this.details;
+ data['DeviceInfo'] = this.deviceInfo;
+ data['DeviceType'] = this.deviceType;
+ data['Title'] = this.title;
+ data['Resolution'] = this.resolution;
+ data['VersionID'] = this.versionID;
+ data['Channel'] = this.channel;
+ data['LanguageID'] = this.languageID;
+ data['IPAdress'] = this.iPAdress;
+ data['generalid'] = this.generalid;
+ data['SessionID'] = this.sessionID;
+ data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
+ data['DeviceTypeID'] = this.deviceTypeID;
+ data['PatientType'] = this.patientType;
+ data['AppVersion'] = this.appVersion;
+ data['ForDemo'] = this.forDemo;
+
+ return data;
+ }
+}
diff --git a/lib/features/emergency_services/emergency_services_repo.dart b/lib/features/emergency_services/emergency_services_repo.dart
index ccfc210..c63f0ee 100644
--- a/lib/features/emergency_services/emergency_services_repo.dart
+++ b/lib/features/emergency_services/emergency_services_repo.dart
@@ -8,9 +8,11 @@ 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/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/PatientER_RC.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/RRTRequestModel.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/EROnlineCheckInPaymentDetailsResponse.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/ProjectAvgERWaitingTime.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/rrt_procedures_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
@@ -18,7 +20,7 @@ import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'models/resp_model/PatientERTransportationMethod.dart';
abstract class EmergencyServicesRepo {
- Future>>> getRRTProcedures();
+ Future>>> getRRTProcedures(int languageId);
Future>>> getNearestEr({int? id, int? projectID});
@@ -48,7 +50,14 @@ abstract class EmergencyServicesRepo {
Future>>> getTransportationOrders({int? id});
- Future>> cancelOrder(int? iD, int patientId);
+ Future>> cancelOrder(int? iD, int patientId);
+
+ Future>> submitRRTRequest(RRTRequestModel request);
+
+ Future>> getRRTOrders({int? id});
+
+ Future>> cancelRRTOrder(int? iD);
+ Future>> getTermsAndCondition();
}
class EmergencyServicesRepoImp implements EmergencyServicesRepo {
@@ -95,8 +104,8 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
}
@override
- Future>>> getRRTProcedures() async {
- Map mapDevice = {"ProjectID": 15};
+ Future>>> getRRTProcedures(int languageId) async {
+ Map mapDevice = {"ProjectID": 15, "languageID":1};
try {
GenericApiModel>? apiResponse;
@@ -558,4 +567,155 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>> submitRRTRequest(RRTRequestModel request) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ body: request.toJson(),
+ ADD_RRT_ORDER_RC,
+ isRCService: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: true,
+ );
+ } 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>> cancelRRTOrder(int? iD) async{
+ try {
+ GenericApiModel? apiResponse;
+
+ Map request = {"Id": iD, "ClickButton": 14};
+
+ Failure? failure;
+ await apiClient.post(
+ body: request,
+ UPDATE_RRT_ORDER_RC,
+ isRCService: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: true,
+ );
+ } 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>> getRRTOrders({int? id}) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ body: {},
+ GET_ALL_RRT_ORDERS_RC,
+ isRCService: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['response'];
+
+ RRTServiceData serviceData = RRTServiceData();
+ list.forEach((item) {
+ if (item["StatusId"] == 1 || item["StatusId"] == 2) {
+ // Pending
+ serviceData.pendingOrders.add(GetCMCAllOrdersResponseModel.fromJson(item));
+ }
+ serviceData.completedOrders.add(GetCMCAllOrdersResponseModel.fromJson(item));
+ });
+
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: serviceData,
+ );
+ } 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>> getTermsAndCondition() async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ body: {},
+ GET_USER_TERMS,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final agreement = response['UserAgreementContent'];
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: agreement,
+ );
+
+ } 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()));
+ }
+
+ }
+
+
}
diff --git a/lib/features/emergency_services/emergency_services_view_model.dart b/lib/features/emergency_services/emergency_services_view_model.dart
index 9526f16..5dbb89d 100644
--- a/lib/features/emergency_services/emergency_services_view_model.dart
+++ b/lib/features/emergency_services/emergency_services_view_model.dart
@@ -2,22 +2,30 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart' as GMSMapServices;
+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/location_util.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.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/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_repo.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/OrderDisplay.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/RRTRequestModel.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/EROnlineCheckInPaymentDetailsResponse.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/AmbulanceCallingPlace.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/PatientER_RC.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/EROnlineCheckInPaymentDetailsResponse.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/PatientERTransportationMethod.dart'
show PatientERTransportationMethod;
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/ProjectAvgERWaitingTime.dart';
@@ -25,21 +33,25 @@ import 'package:hmg_patient_app_new/features/emergency_services/models/resp_mode
import 'package:hmg_patient_app_new/features/location/PlaceDetails.dart' show PlaceDetails;
import 'package:hmg_patient_app_new/features/location/PlacePrediction.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart';
-import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/RRT/rrt_map_screen.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/RRT/rrt_request_type_select.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/RRT/terms_and_condition.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/call_ambulance_page.dart';
-import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart';
-import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/requesting_services_page.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/tracking_screen.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/nearest_er_page.dart';
import 'package:hmg_patient_app_new/routes/app_routes.dart' show AppRoutes;
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/expandable_bottom_sheet/model/BottomSheetType.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/order_tracking/order_tracking_state.dart';
@@ -71,7 +83,6 @@ class EmergencyServicesViewModel extends ChangeNotifier {
List nearestERList = [];
List nearestERFilteredList = [];
- List RRTProceduresList = [];
List? hospitalList;
List? hmgHospitalList;
@@ -83,7 +94,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
int hmcCount = 0;
bool pickupFromInsideTheLocation = true;
List? appointments;
- List? orders = [];
+ List? ambulanceOrders = [];
//ambulance selection data section
List transportationOptions = [];
@@ -91,7 +102,6 @@ class EmergencyServicesViewModel extends ChangeNotifier {
AmbulanceCallingPlace callingPlace = AmbulanceCallingPlace.FROM_HOSPITAL;
AmbulanceDirection ambulanceDirection = AmbulanceDirection.ONE_WAY;
- late RRTProceduresResponseModel selectedRRTProcedure;
bool patientHasAdvanceERBalance = false;
bool isERBookAppointment = false;
@@ -99,13 +109,27 @@ class EmergencyServicesViewModel extends ChangeNotifier {
BottomSheetType bottomSheetType = BottomSheetType.FIXED;
+ ///RRT request data
+ List RRTProceduresList = [];
+ RRTProceduresResponseModel? selectedRRTProcedure;
+ bool agreedToTermsAndCondition = false;
+ RRTServiceData? ordersRRT;
+ TextEditingController rrtNotes = TextEditingController();
+
+
+ List allOrders = [];
+ List orderDisplayList = [];
+ bool historyLoading= false;
+ OrderDislpay currentlyDisplayedOrder = OrderDislpay.ALL;
+
+
+
setSelectedRRTProcedure(RRTProceduresResponseModel procedure) {
selectedRRTProcedure = procedure;
notifyListeners();
}
- get isGMSAvailable
- {
+ get isGMSAvailable {
return appState.isGMSAvailable;
}
@@ -132,11 +156,25 @@ class EmergencyServicesViewModel extends ChangeNotifier {
bool isMyAppointmentsLoading = false;
+ String? termsAndConditions;
+
Future getRRTProcedures({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+
+ print("the app state is ${appState.isAuthenticated}");
+ if (!appState.isAuthenticated) {
+ dialogService.showErrorBottomSheet(
+ message: "You Need To Login First To Continue".needTranslation,
+ onOkPressed: () {
+ navServices.pop();
+ getIt().onLoginPressed();
+ });
+ return;
+ }
+
RRTProceduresList.clear();
notifyListeners();
- final result = await emergencyServicesRepo.getRRTProcedures();
+ final result = await emergencyServicesRepo.getRRTProcedures(appState.getLanguageID());
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@@ -173,7 +211,8 @@ class EmergencyServicesViewModel extends ChangeNotifier {
if (query.isEmpty) {
nearestERFilteredList = nearestERList;
} else {
- nearestERFilteredList = nearestERList.where((er) => er.projectName != null && er.projectName!.toLowerCase().contains(query.toLowerCase())).toList();
+ nearestERFilteredList =
+ nearestERList.where((er) => er.projectName != null && er.projectName!.toLowerCase().contains(query.toLowerCase())).toList();
}
notifyListeners();
}
@@ -256,8 +295,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
onSuccess: (position) {
updateBottomSheetState(BottomSheetType.FIXED);
navServices.push(
- CustomPageRoute(
- page: CallAmbulancePage(), direction: AxisDirection.down),
+ CustomPageRoute(page: CallAmbulancePage(), direction: AxisDirection.down),
);
});
} else {
@@ -265,9 +303,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
message: "You Need To Login First To Continue".needTranslation,
onOkPressed: () {
navServices.pop();
- navServices.pushAndReplace(
- AppRoutes.loginScreen
- );
+ navServices.pushAndReplace(AppRoutes.loginScreen);
});
}
}
@@ -299,19 +335,20 @@ class EmergencyServicesViewModel extends ChangeNotifier {
void setIsGMSAvailable(bool value) {
notifyListeners();
}
+
Future checkPatientERAdvanceBalance({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await emergencyServicesRepo.checkPatientERAdvanceBalance();
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
- (failure) {
+ (failure) {
patientHasAdvanceERBalance = false;
isERBookAppointment = true;
if (onSuccess != null) {
onSuccess(failure.message);
}
},
- (apiResponse) {
+ (apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
patientHasAdvanceERBalance = false;
@@ -332,12 +369,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
final result = await emergencyServicesRepo.checkPatientERPaymentInformation(projectID: selectedHospital!.iD);
result.fold(
- (failure) {
+ (failure) {
if (onError != null) {
onError(failure.message);
}
},
- (apiResponse) {
+ (apiResponse) {
if (apiResponse.messageStatus == 2) {
} else if (apiResponse.messageStatus == 1) {
erOnlineCheckInPaymentDetailsResponse = apiResponse.data!;
@@ -350,7 +387,8 @@ class EmergencyServicesViewModel extends ChangeNotifier {
);
}
- Future ER_CreateAdvancePayment({required String paymentMethodName, required String paymentReference, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ Future ER_CreateAdvancePayment(
+ {required String paymentMethodName, required String paymentReference, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await emergencyServicesRepo.createAdvancePaymentForER(
projectID: selectedHospital!.iD,
authUser: appState.getAuthenticatedUser()!,
@@ -359,12 +397,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
paymentReference: paymentReference);
result.fold(
- (failure) {
+ (failure) {
if (onError != null) {
onError(failure.message);
}
},
- (apiResponse) {
+ (apiResponse) {
if (apiResponse.messageStatus == 2) {
} else if (apiResponse.messageStatus == 1) {
// erOnlineCheckInPaymentDetailsResponse = apiResponse.data!;
@@ -378,12 +416,17 @@ class EmergencyServicesViewModel extends ChangeNotifier {
}
Future addAdvanceNumberRequest(
- {required String advanceNumber, required String paymentReference, required String appointmentNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
- final result = await emergencyServicesRepo.addAdvanceNumberRequest(advanceNumber: advanceNumber, paymentReference: paymentReference, appointmentNo: appointmentNo);
+ {required String advanceNumber,
+ required String paymentReference,
+ required String appointmentNo,
+ Function(dynamic)? onSuccess,
+ Function(String)? onError}) async {
+ final result = await emergencyServicesRepo.addAdvanceNumberRequest(
+ advanceNumber: advanceNumber, paymentReference: paymentReference, appointmentNo: appointmentNo);
result.fold(
- (failure) async => await errorHandlerService.handleError(failure: failure),
- (apiResponse) {
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
@@ -401,12 +444,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
- (failure) {
+ (failure) {
if (onError != null) {
onError(failure.message);
}
},
- (apiResponse) {
+ (apiResponse) {
if (apiResponse.messageStatus == 2) {
if (onError != null) {
onError(apiResponse.errorMessage!);
@@ -426,12 +469,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
- (failure) {
+ (failure) {
if (onError != null) {
onError(failure.message);
}
},
- (apiResponse) {
+ (apiResponse) {
if (apiResponse.messageStatus == 2) {
if (onError != null) {
onError(apiResponse.data["InvoiceResponse"]["Message"]);
@@ -457,16 +500,13 @@ class EmergencyServicesViewModel extends ChangeNotifier {
onOkPressed: () {
navServices.pop();
print("inside the ok button");
- getIt().onLoginPressed();
+ getIt().onLoginPressed();
});
return;
}
- if (transportationOptions.isNotEmpty) return;
-
int? id = appState.getAuthenticatedUser()?.patientId;
- LoaderBottomSheet.showLoader(
- loadingText: "Getting Ambulance Transport Option".needTranslation);
+ LoaderBottomSheet.showLoader(loadingText: "Getting Ambulance Transport Option".needTranslation);
notifyListeners();
var response = await emergencyServicesRepo.getTransportationMethods(id: id);
@@ -485,8 +525,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
Future getTransportationMethods() async {
int? id = appState.getAuthenticatedUser()?.patientId;
- LoaderBottomSheet.showLoader(
- loadingText: "Getting Ambulance Transport Option".needTranslation);
+ LoaderBottomSheet.showLoader(loadingText: "Getting Ambulance Transport Option".needTranslation);
notifyListeners();
var response = await emergencyServicesRepo.getTransportationMethods(id: id);
@@ -597,11 +636,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
sourceList = hmcHospitalList;
break;
}
- displayList = sourceList
- ?.where((hospital) =>
- hospital.name != null &&
- hospital.name!.toLowerCase().contains(query.toLowerCase()))
- .toList();
+ displayList = sourceList?.where((hospital) => hospital.name != null && hospital.name!.toLowerCase().contains(query.toLowerCase())).toList();
notifyListeners();
}
@@ -620,7 +655,6 @@ class EmergencyServicesViewModel extends ChangeNotifier {
notifyListeners();
}
-
void setSelectedHospital(HospitalsModel? hospital) {
selectedHospital = hospital;
notifyListeners();
@@ -668,13 +702,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
}
Future updateAppointment(bool value) async {
-
if (value) {
await getAppointments();
} else {
clearAppointmentData();
}
- if(appointments?.isNotEmpty == true) {
+ if (appointments?.isNotEmpty == true) {
haveAnAppointment = value;
}
notifyListeners();
@@ -729,18 +762,24 @@ class EmergencyServicesViewModel extends ChangeNotifier {
}
Future getTransportationOrders({bool shouldNavigateToTrackingScreen = false, bool showLoader = false}) async {
- if(shouldNavigateToTrackingScreen == false && showLoader ) {
+ if (shouldNavigateToTrackingScreen == false && showLoader) {
LoaderBottomSheet.showLoader(loadingText: "Fetching Orders");
}
int? id = appState.getAuthenticatedUser()?.patientId;
+ historyLoading = true;
+ notifyListeners();
var response = await emergencyServicesRepo.getTransportationOrders(id: id);
- if(shouldNavigateToTrackingScreen == false && showLoader ) {
- LoaderBottomSheet.hideLoader();}
+ if (shouldNavigateToTrackingScreen == false && showLoader) {
+ LoaderBottomSheet.hideLoader();
+ }
response.fold(
(failure) async {
+ historyLoading = false;
+ notifyListeners();
if (shouldNavigateToTrackingScreen) {
- navServices.pushAndRemoveUntil(CustomPageRoute(page: TrackingScreen(state: OrderTrackingState.waitingForCall)), ModalRoute.withName("/EmergencyServicesPage"));
+ navServices.pushAndRemoveUntil(
+ CustomPageRoute(page: TrackingScreen(state: OrderTrackingState.waitingForCall)), ModalRoute.withName("/EmergencyServicesPage"));
}
},
(apiResponse) {
@@ -753,8 +792,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
)),
ModalRoute.withName("/EmergencyServicesPage"));
}
-
- orders = apiResponse.data;
+ historyLoading = false;
+ ambulanceOrders = apiResponse.data;
+ allOrders.clear();
+ allOrders.addAll(ambulanceOrders??[]);
+ allOrders.addAll(ordersRRT?.completedOrders??[]);
+ changeOrderDisplayItems(OrderDislpay.ALL);
notifyListeners();
},
);
@@ -828,10 +871,10 @@ class EmergencyServicesViewModel extends ChangeNotifier {
Future cancelOrder(AmbulanceRequestOrdersModel? order, {bool shouldPop = false}) async {
dialogService.showCommonBottomSheetWithoutH(
- message: "Do you want to cancel the order".needTranslation,
+ message: "Do you want to cancel the request".needTranslation,
onOkPressed: () async {
navServices.pop();
- LoaderBottomSheet.showLoader(loadingText: "Cancelling Order".needTranslation);
+ LoaderBottomSheet.showLoader(loadingText: "Cancelling request".needTranslation);
var response = await emergencyServicesRepo.cancelOrder(order?.iD, appState.getAuthenticatedUser()?.patientId ?? 0);
LoaderBottomSheet.hideLoader();
response.fold((failure) => errorHandlerService.handleError(failure: failure), (success) {
@@ -843,4 +886,201 @@ class EmergencyServicesViewModel extends ChangeNotifier {
navServices.pop();
});
}
+
+
+ RRTRequestModel createRRTRequest(GeocodeResult? result, PlaceDetails? place, PlacePrediction? placePrediction){
+ AuthenticatedUser? user = appState.getAuthenticatedUser();
+ if (user == null) throw Exception("Authentication Required to Continue");
+
+ RRTRequestModel rrtRequestModel = new RRTRequestModel();
+ Procedures procedures = new Procedures();
+ rrtRequestModel.procedures = [];
+
+
+ procedures.serviceID = selectedRRTProcedure?.procedureID;
+
+ rrtRequestModel.latitude = ((result?.geometry.location.lat) ?? place?.lat);
+ rrtRequestModel.longitude = ((result?.geometry.location.lat) ?? place?.lat);
+ rrtRequestModel.additionalDetails = "";
+ rrtRequestModel.nationality = user.nationalityId;
+ rrtRequestModel.paymentAmount = selectedRRTProcedure?.patientShareWithTax;
+ rrtRequestModel.nearestProjectId = 0;
+ rrtRequestModel.patientId = user.patientId;
+ rrtRequestModel.patientOutSa = user.outSa;
+ rrtRequestModel.procedures!.add(procedures);
+
+ return rrtRequestModel;
+ }
+
+ ///method to toggle the value for the aggremnent to the terms and conditon for the rrt
+ void setTermsAndConditions(bool value) {
+ agreedToTermsAndCondition = value;
+ notifyListeners();
+ }
+
+ FutureOr submitRRTRequest(GeocodeResult? result, PlaceDetails? place, PlacePrediction? placePrediction) async {
+ RRTRequestModel request = createRRTRequest(result, place, placePrediction);
+ navServices.push(CustomPageRoute(page: RequestingServicesPage()));
+
+ var response = await emergencyServicesRepo.submitRRTRequest(request);
+ response.fold((failure) {
+ navServices.pushAndRemoveUntil(
+ CustomPageRoute(
+ page: TrackingScreen(
+ isRRTOrder: true,
+ state: OrderTrackingState.failed,
+ )),
+ ModalRoute.withName("/EmergencyServicesPage"));
+ }, (success) {
+ getRRTOrders(shouldNavigateToTrackingScreen: true);
+ });
+ }
+
+ Future getRRTOrders({bool shouldNavigateToTrackingScreen = false, bool showLoader = false}) async {
+ if(shouldNavigateToTrackingScreen == false && showLoader ) {
+ LoaderBottomSheet.showLoader(loadingText: "Fetching Orders");
+ }
+ historyLoading = true;
+ notifyListeners();
+ int? id = appState.getAuthenticatedUser()?.patientId;
+
+ var response = await emergencyServicesRepo.getRRTOrders(id: id);
+ if(shouldNavigateToTrackingScreen == false && showLoader ) {
+ LoaderBottomSheet.hideLoader();}
+ response.fold(
+ (failure) async {
+ historyLoading = false;
+ notifyListeners();
+ if (shouldNavigateToTrackingScreen) {
+ navServices.pushAndRemoveUntil(CustomPageRoute(page: TrackingScreen(isRRTOrder: true,state: OrderTrackingState.waitingForCall)), ModalRoute.withName("/EmergencyServicesPage"));
+ }
+ },
+ (apiResponse) {
+ if (shouldNavigateToTrackingScreen) {
+ navServices.pushAndRemoveUntil(
+ CustomPageRoute(
+ page: TrackingScreen(
+ state: OrderTrackingState.waitingForCall,
+ isRRTOrder: true,
+ rrtOrder: apiResponse.data?.pendingOrders.first,
+ )),
+ ModalRoute.withName("/EmergencyServicesPage"));
+ }
+ historyLoading = false;
+ ordersRRT = apiResponse.data;
+ allOrders.clear();
+ allOrders.addAll(ambulanceOrders??[]);
+ allOrders.addAll(ordersRRT?.completedOrders??[]);
+ changeOrderDisplayItems(OrderDislpay.ALL);
+ notifyListeners();
+ },
+ );
+ }
+
+
+ FutureOr cancelRRTOrder(int? orderID, {bool shouldPop = false}) async {
+ dialogService.showCommonBottomSheetWithoutH(
+ message: "Do you want to cancel the request".needTranslation,
+ onOkPressed: () async {
+ navServices.pop();
+ LoaderBottomSheet.showLoader(loadingText: "Cancelling request".needTranslation);
+ var response = await emergencyServicesRepo.cancelRRTOrder(orderID);
+ LoaderBottomSheet.hideLoader();
+ response.fold((failure) => errorHandlerService.handleError(failure: failure), (success) {
+ getRRTOrders();
+ if (shouldPop) navServices.pop();
+ });
+ },
+ onCancelPressed: () {
+ navServices.pop();
+ });
+ }
+
+ void changeOrderDisplayItems(OrderDislpay currentlyDisplayedOrder){
+ this.currentlyDisplayedOrder = currentlyDisplayedOrder;
+ switch(currentlyDisplayedOrder){
+ case OrderDislpay.ALL:
+ orderDisplayList = allOrders;
+ break;
+ case OrderDislpay.RRT:
+ orderDisplayList = ordersRRT?.completedOrders ?? [];
+ break;
+ case OrderDislpay.AMBULANCE:
+ orderDisplayList = ambulanceOrders??[];
+ break;
+ }
+ notifyListeners();
+ }
+
+ void openRRT(){
+ print("the app state is ${appState.isAuthenticated}");
+ if (appState.isAuthenticated) {
+ if(agreedToTermsAndCondition == false){
+ dialogService.showErrorBottomSheet(message: "You Need To Agree To Terms And Conditions".needTranslation, onOkPressed: (){
+ if(navServices.context == null ) return;
+ showCommonBottomSheetWithoutHeight(
+ navServices.context!,
+ padding: EdgeInsets.only(top: 24.h),
+ titleWidget: Transform.flip(
+ flipX: isArabic,
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.arrow_back,
+ iconColor: Color(0xff2B353E),
+ fit: BoxFit.contain,
+ ),
+ ).onPress(() {
+ navServices.pop();
+ }),
+ // title: "Rapid Response Team (RRT)".needTranslation,
+ child: RrtRequestTypeSelect(),
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ hasBottomPadding: false,
+ backgroundColor: AppColors.bottomSheetBgColor,
+ callBackFunc: () {
+ navServices.pop();
+ },
+ );
+ });
+ return;
+ }
+ placeValueInController();
+ locationUtils!.getLocation(
+ isShowConfirmDialog: true,
+ onSuccess: (position) {
+ updateBottomSheetState(BottomSheetType.FIXED);
+ navServices.push(
+ CustomPageRoute(
+ page: RrtMapScreen(), direction: AxisDirection.down),
+ );
+ });
+ } else{
+ dialogService.showErrorBottomSheet(
+ message: "You Need To Login First To Continue".needTranslation,
+ onOkPressed: () {
+ navServices.pop();
+ getIt().onLoginPressed();
+ });
+ }
+ }
+ clearRRTData(){
+ selectedRRTProcedure = null;
+ }
+
+
+ FutureOr getTermsAndConditions() async {
+ LoaderBottomSheet.showLoader(loadingText: "Fetching Terms And Conditions".needTranslation);
+ var response = await emergencyServicesRepo.getTermsAndCondition();
+ LoaderBottomSheet.hideLoader();
+ response.fold((failure)=>errorHandlerService.handleError(failure: failure),(success){
+ termsAndConditions = success.data;
+ print("the response terms are $termsAndConditions");
+ notifyListeners();
+ navServices.push(
+ CustomPageRoute(
+ page: TermsAndCondition(termsAndCondition:success.data??""), direction: AxisDirection.down),
+ );
+ });
+ }
+
}
diff --git a/lib/features/emergency_services/models/OrderDisplay.dart b/lib/features/emergency_services/models/OrderDisplay.dart
new file mode 100644
index 0000000..9f1e929
--- /dev/null
+++ b/lib/features/emergency_services/models/OrderDisplay.dart
@@ -0,0 +1,3 @@
+enum OrderDislpay{
+ ALL,RRT,AMBULANCE
+}
\ No newline at end of file
diff --git a/lib/features/emergency_services/models/request_model/RRTRequestModel.dart b/lib/features/emergency_services/models/request_model/RRTRequestModel.dart
new file mode 100644
index 0000000..dfb5b1b
--- /dev/null
+++ b/lib/features/emergency_services/models/request_model/RRTRequestModel.dart
@@ -0,0 +1,75 @@
+class RRTRequestModel {
+ num? patientId;
+ int? patientOutSa;
+ bool? isOutPatient;
+ int? nearestProjectId;
+ num? longitude;
+ num? latitude;
+ String? additionalDetails;
+ String? nationality;
+ num? paymentAmount;
+ List? procedures;
+
+ RRTRequestModel(
+ {this.patientId,
+ this.patientOutSa,
+ this.isOutPatient,
+ this.nearestProjectId,
+ this.longitude,
+ this.latitude,
+ this.additionalDetails,
+ this.nationality,
+ this.paymentAmount,
+ this.procedures});
+
+ RRTRequestModel.fromJson(Map json) {
+ patientId = json['patientId'];
+ patientOutSa = json['patientOutSa'];
+ isOutPatient = json['isOutPatient'];
+ nearestProjectId = json['nearestProjectId'];
+ longitude = json['longitude'];
+ latitude = json['latitude'];
+ additionalDetails = json['additionalDetails'];
+ nationality = json['nationality'];
+ paymentAmount = json['paymentAmount'];
+ if (json['procedures'] != null) {
+ procedures = [];
+ json['procedures'].forEach((v) {
+ procedures!.add(new Procedures.fromJson(v));
+ });
+ }
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['patientId'] = this.patientId;
+ data['patientOutSa'] = this.patientOutSa;
+ data['isOutPatient'] = this.isOutPatient;
+ data['nearestProjectId'] = this.nearestProjectId;
+ data['longitude'] = this.longitude;
+ data['latitude'] = this.latitude;
+ data['additionalDetails'] = this.additionalDetails;
+ data['nationality'] = this.nationality;
+ data['paymentAmount'] = this.paymentAmount;
+ if (this.procedures != null) {
+ data['procedures'] = this.procedures!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class Procedures {
+ String? serviceID;
+
+ Procedures({this.serviceID});
+
+ Procedures.fromJson(Map json) {
+ serviceID = json['ServiceID'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ServiceID'] = this.serviceID;
+ return data;
+ }
+}
diff --git a/lib/features/emergency_services/models/request_model/service_price.dart b/lib/features/emergency_services/models/request_model/service_price.dart
new file mode 100644
index 0000000..abb57be
--- /dev/null
+++ b/lib/features/emergency_services/models/request_model/service_price.dart
@@ -0,0 +1,53 @@
+class ServicePrice {
+ String? currency;
+ dynamic maxPrice;
+ dynamic maxTotalPrice;
+ dynamic maxVAT;
+ dynamic minPrice;
+ dynamic minTotalPrice;
+ dynamic minVAT;
+ dynamic price;
+ dynamic totalPrice;
+ dynamic vat;
+
+ ServicePrice({
+ this.currency,
+ this.maxPrice,
+ this.maxTotalPrice,
+ this.maxVAT,
+ this.minPrice,
+ this.minTotalPrice,
+ this.minVAT,
+ this.price,
+ this.totalPrice,
+ this.vat});
+
+ ServicePrice.fromJson(dynamic json) {
+ currency = json["Currency"];
+ maxPrice = json["MaxPrice"];
+ maxTotalPrice = json["MaxTotalPrice"];
+ maxVAT = json["MaxVAT"];
+ minPrice = json["MinPrice"];
+ minTotalPrice = json["MinTotalPrice"];
+ minVAT = json["MinVAT"];
+ price = json["Price"];
+ totalPrice = json["TotalPrice"];
+ vat = json["VAT"];
+ }
+
+ Map toJson() {
+ var map = {};
+ map["Currency"] = currency;
+ map["MaxPrice"] = maxPrice;
+ map["MaxTotalPrice"] = maxTotalPrice;
+ map["MaxVAT"] = maxVAT;
+ map["MinPrice"] = minPrice;
+ map["MinTotalPrice"] = minTotalPrice;
+ map["MinVAT"] = minVAT;
+ map["Price"] = price;
+ map["TotalPrice"] = totalPrice;
+ map["VAT"] = vat;
+ return map;
+ }
+
+}
\ No newline at end of file
diff --git a/lib/features/emergency_services/models/resp_model/RRTServiceData.dart b/lib/features/emergency_services/models/resp_model/RRTServiceData.dart
new file mode 100644
index 0000000..e4e7ce7
--- /dev/null
+++ b/lib/features/emergency_services/models/resp_model/RRTServiceData.dart
@@ -0,0 +1,406 @@
+class RRTServiceData {
+ List pendingOrders = [];
+ List completedOrders = [];
+ ServicePrice servicePrice = ServicePrice();
+}
+
+class GetCMCAllOrdersResponseModel {
+ int? iD;
+ int? patientId;
+ int? patientOutSa;
+ bool? isOutPatient;
+ int? projectId;
+ int? nearestProjectId;
+ dynamic longitude;
+ dynamic latitude;
+ dynamic appointmentNo;
+ dynamic dischargeId;
+ int? statusId;
+ int? serviceId;
+ int? channel;
+ Orderpayment? orderpayment;
+ dynamic orderselectedservice;
+ dynamic wforder;
+ dynamic orderapprovalobj;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+ String? statusText;
+ int? paymentStatus;
+ dynamic clientRequestid;
+ dynamic paymentStatusText;
+ String? projectName;
+ String? nearestProjectName;
+ dynamic paymentAmount;
+ WFOrder? wFOrder;
+ String? serviceText;
+ bool? isSentForApproval;
+ int? exaCartOrderId;
+ bool? isTimer;
+ int? timeSeconds;
+ int? totalPendingSeconds;
+ int? timeMinute;
+ int? timeHour;
+ int? timeTotalSeconds;
+ int? timeTotalMinute;
+ int? timeTotalHour;
+ dynamic approvalStatus;
+ bool? isActive;
+ int? clickButton;
+ List? procedures;
+ dynamic pickupLocation;
+ dynamic dropOffLocation;
+ dynamic clinicName;
+ dynamic doctorName;
+ dynamic branch;
+ dynamic time;
+ dynamic notes;
+
+ GetCMCAllOrdersResponseModel(
+ {this.iD,
+ this.patientId,
+ this.patientOutSa,
+ this.isOutPatient,
+ this.projectId,
+ this.nearestProjectId,
+ this.longitude,
+ this.latitude,
+ this.appointmentNo,
+ this.dischargeId,
+ this.statusId,
+ this.serviceId,
+ this.channel,
+ this.orderpayment,
+ this.orderselectedservice,
+ this.wforder,
+ this.orderapprovalobj,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted,
+ this.statusText,
+ this.paymentStatus,
+ this.clientRequestid,
+ this.paymentStatusText,
+ this.projectName,
+ this.nearestProjectName,
+ this.paymentAmount,
+ this.wFOrder,
+ this.serviceText,
+ this.isSentForApproval,
+ this.exaCartOrderId,
+ this.isTimer,
+ this.timeSeconds,
+ this.totalPendingSeconds,
+ this.timeMinute,
+ this.timeHour,
+ this.timeTotalSeconds,
+ this.timeTotalMinute,
+ this.timeTotalHour,
+ this.approvalStatus,
+ this.isActive,
+ this.clickButton,
+ this.procedures,
+ this.pickupLocation,
+ this.dropOffLocation,
+ this.clinicName,
+ this.doctorName,
+ this.branch,
+ this.time,
+ this.notes});
+
+ GetCMCAllOrdersResponseModel.fromJson(Map json) {
+ iD = json['ID'];
+ patientId = json['PatientId'];
+ patientOutSa = json['PatientOutSa'];
+ isOutPatient = json['IsOutPatient'];
+ projectId = json['ProjectId'];
+ nearestProjectId = json['NearestProjectId'];
+ longitude = json['Longitude'];
+ latitude = json['Latitude'];
+ appointmentNo = json['AppointmentNo'];
+ dischargeId = json['DischargeId'];
+ statusId = json['StatusId'];
+ serviceId = json['ServiceId'];
+ channel = json['Channel'];
+ orderpayment = json['orderpayment'] != null
+ ? new Orderpayment.fromJson(json['orderpayment'])
+ : null;
+ orderselectedservice = json['orderselectedservice'];
+ wforder = json['wforder'];
+ orderapprovalobj = json['orderapprovalobj'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ statusText = json['StatusText'];
+ paymentStatus = json['PaymentStatus'];
+ clientRequestid = json['ClientRequestid'];
+ paymentStatusText = json['PaymentStatusText'];
+ projectName = json['ProjectName'];
+ nearestProjectName = json['NearestProjectName'];
+ paymentAmount = json['PaymentAmount'];
+ wFOrder = json['WF_order'] != null
+ ? new WFOrder.fromJson(json['WF_order'])
+ : null;
+ serviceText = json['ServiceText'];
+ isSentForApproval = json['isSentForApproval'];
+ exaCartOrderId = json['ExaCart_OrderId'];
+ isTimer = json['isTimer'];
+ timeSeconds = json['TimeSeconds'];
+ totalPendingSeconds = json['TotalPendingSeconds'];
+ timeMinute = json['TimeMinute'];
+ timeHour = json['TimeHour'];
+ timeTotalSeconds = json['TimeTotalSeconds'];
+ timeTotalMinute = json['TimeTotalMinute'];
+ timeTotalHour = json['TimeTotalHour'];
+ approvalStatus = json['ApprovalStatus'];
+ isActive = json['isActive'];
+ clickButton = json['ClickButton'];
+ pickupLocation = json['PickupLocation'];
+ dropOffLocation = json['DropOffLocation'];
+ clinicName = json['clinicName'];
+ doctorName = json['DoctorName'];
+ branch = json['Branch'];
+ time = json['Time'];
+ notes = json['Notes'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ID'] = this.iD;
+ data['PatientId'] = this.patientId;
+ data['PatientOutSa'] = this.patientOutSa;
+ data['IsOutPatient'] = this.isOutPatient;
+ data['ProjectId'] = this.projectId;
+ data['NearestProjectId'] = this.nearestProjectId;
+ data['Longitude'] = this.longitude;
+ data['Latitude'] = this.latitude;
+ data['AppointmentNo'] = this.appointmentNo;
+ data['DischargeId'] = this.dischargeId;
+ data['StatusId'] = this.statusId;
+ data['ServiceId'] = this.serviceId;
+ data['Channel'] = this.channel;
+ if (this.orderpayment != null) {
+ data['orderpayment'] = this.orderpayment!.toJson();
+ }
+ data['orderselectedservice'] = this.orderselectedservice;
+
+ data['wforder'] = this.wforder;
+ data['orderapprovalobj'] = this.orderapprovalobj;
+ data['Created'] = this.created;
+ data['CreatedBy'] = this.createdBy;
+ data['Modified'] = this.modified;
+ data['ModifiedBy'] = this.modifiedBy;
+ data['IsDeleted'] = this.isDeleted;
+ data['StatusText'] = this.statusText;
+ data['PaymentStatus'] = this.paymentStatus;
+ data['ClientRequestid'] = this.clientRequestid;
+ data['PaymentStatusText'] = this.paymentStatusText;
+ data['ProjectName'] = this.projectName;
+ data['NearestProjectName'] = this.nearestProjectName;
+ data['PaymentAmount'] = this.paymentAmount;
+ if (this.wFOrder != null) {
+ data['WF_order'] = this.wFOrder!.toJson();
+ }
+ data['ServiceText'] = this.serviceText;
+ data['isSentForApproval'] = this.isSentForApproval;
+ data['ExaCart_OrderId'] = this.exaCartOrderId;
+ data['isTimer'] = this.isTimer;
+ data['TimeSeconds'] = this.timeSeconds;
+ data['TotalPendingSeconds'] = this.totalPendingSeconds;
+ data['TimeMinute'] = this.timeMinute;
+ data['TimeHour'] = this.timeHour;
+ data['TimeTotalSeconds'] = this.timeTotalSeconds;
+ data['TimeTotalMinute'] = this.timeTotalMinute;
+ data['TimeTotalHour'] = this.timeTotalHour;
+ data['ApprovalStatus'] = this.approvalStatus;
+ data['isActive'] = this.isActive;
+ data['ClickButton'] = this.clickButton;
+ data['PickupLocation'] = this.pickupLocation;
+ data['DropOffLocation'] = this.dropOffLocation;
+ data['clinicName'] = this.clinicName;
+ data['DoctorName'] = this.doctorName;
+ data['Branch'] = this.branch;
+ data['Time'] = this.time;
+ data['Notes'] = this.notes;
+ return data;
+ }
+}
+
+class Orderpayment {
+ int? iD;
+ int? orderId;
+ dynamic clientRequestId;
+ dynamic totalAmount;
+ int? paymentStatus;
+ dynamic order;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+
+ Orderpayment(
+ {this.iD,
+ this.orderId,
+ this.clientRequestId,
+ this.totalAmount,
+ this.paymentStatus,
+ this.order,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted});
+
+ Orderpayment.fromJson(Map json) {
+ iD = json['ID'];
+ orderId = json['OrderId'];
+ clientRequestId = json['ClientRequestId'];
+ totalAmount = json['TotalAmount'];
+ paymentStatus = json['PaymentStatus'];
+ order = json['Order'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ID'] = this.iD;
+ data['OrderId'] = this.orderId;
+ data['ClientRequestId'] = this.clientRequestId;
+ data['TotalAmount'] = this.totalAmount;
+ data['PaymentStatus'] = this.paymentStatus;
+ data['Order'] = this.order;
+ data['Created'] = this.created;
+ data['CreatedBy'] = this.createdBy;
+ data['Modified'] = this.modified;
+ data['ModifiedBy'] = this.modifiedBy;
+ data['IsDeleted'] = this.isDeleted;
+ return data;
+ }
+}
+
+class WFOrder {
+ dynamic wfButtonsDTO;
+ int? iD;
+ int? orderId;
+ int? previousStep;
+ int? nextStep;
+ int? serviceId;
+ dynamic order;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+
+ WFOrder(
+ {this.wfButtonsDTO,
+ this.iD,
+ this.orderId,
+ this.previousStep,
+ this.nextStep,
+ this.serviceId,
+ this.order,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted});
+
+ WFOrder.fromJson(Map json) {
+ wfButtonsDTO = json['wf_ButtonsDTO'];
+ iD = json['ID'];
+ orderId = json['OrderId'];
+ previousStep = json['PreviousStep'];
+ nextStep = json['NextStep'];
+ serviceId = json['ServiceId'];
+ order = json['Order'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['wf_ButtonsDTO'] = this.wfButtonsDTO;
+ data['ID'] = this.iD;
+ data['OrderId'] = this.orderId;
+ data['PreviousStep'] = this.previousStep;
+ data['NextStep'] = this.nextStep;
+ data['ServiceId'] = this.serviceId;
+ data['Order'] = this.order;
+ data['Created'] = this.created;
+ data['CreatedBy'] = this.createdBy;
+ data['Modified'] = this.modified;
+ data['ModifiedBy'] = this.modifiedBy;
+ data['IsDeleted'] = this.isDeleted;
+ return data;
+ }
+}
+
+
+class ServicePrice {
+ String? currency;
+ dynamic maxPrice;
+ dynamic maxTotalPrice;
+ dynamic maxVAT;
+ dynamic minPrice;
+ dynamic minTotalPrice;
+ dynamic minVAT;
+ dynamic price;
+ dynamic totalPrice;
+ dynamic vat;
+
+ ServicePrice({
+ this.currency,
+ this.maxPrice,
+ this.maxTotalPrice,
+ this.maxVAT,
+ this.minPrice,
+ this.minTotalPrice,
+ this.minVAT,
+ this.price,
+ this.totalPrice,
+ this.vat});
+
+ ServicePrice.fromJson(dynamic json) {
+ currency = json["Currency"];
+ maxPrice = json["MaxPrice"];
+ maxTotalPrice = json["MaxTotalPrice"];
+ maxVAT = json["MaxVAT"];
+ minPrice = json["MinPrice"];
+ minTotalPrice = json["MinTotalPrice"];
+ minVAT = json["MinVAT"];
+ price = json["Price"];
+ totalPrice = json["TotalPrice"];
+ vat = json["VAT"];
+ }
+
+ Map toJson() {
+ var map = {};
+ map["Currency"] = currency;
+ map["MaxPrice"] = maxPrice;
+ map["MaxTotalPrice"] = maxTotalPrice;
+ map["MaxVAT"] = maxVAT;
+ map["MinPrice"] = minPrice;
+ map["MinTotalPrice"] = minTotalPrice;
+ map["MinVAT"] = minVAT;
+ map["Price"] = price;
+ map["TotalPrice"] = totalPrice;
+ map["VAT"] = vat;
+ return map;
+ }
+
+}
\ No newline at end of file
diff --git a/lib/features/hmg_services/hmg_services_repo.dart b/lib/features/hmg_services/hmg_services_repo.dart
index 1115f18..6e1d533 100644
--- a/lib/features/hmg_services/hmg_services_repo.dart
+++ b/lib/features/hmg_services/hmg_services_repo.dart
@@ -6,10 +6,12 @@ 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/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/check_activation_e_referral_req_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_all_cities_resp_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:provider/provider.dart';
@@ -18,12 +20,32 @@ import 'models/req_models/send_activation_code_ereferral_req_model.dart';
import 'models/resq_models/relationship_type_resp_mode.dart';
abstract class HmgServicesRepo {
- Future>>> getAllCmcOrders();
+ Future>>> getAllComprehensiveCheckupOrders();
+
+ Future>>> getAllHomeHealthCareCheckupOrders();
Future>> updateCmcPresOrder(OrderUpdateRequestModel requestModel);
+ Future>> updateHhcPresOrder(OrderUpdateRequestModel requestModel);
+
Future>>> getAllCmcServices({required int patientID});
+ Future>>> getAllHhcServices({required int patientID});
+
+ Future>>> getHospitalsList();
+
+ Future>> addCmcOrder({
+ required int projectID,
+ required int orderServiceID,
+ required List services,
+ });
+
+ Future>> addHhcOrder({
+ required int projectID,
+ required int orderServiceID,
+ required List services,
+ });
+
Future>>> getRelationshipTypes();
Future>>> getAllCities();
@@ -43,7 +65,7 @@ class HmgServicesRepoImp implements HmgServicesRepo {
HmgServicesRepoImp({required this.apiClient, required this.loggerService});
@override
- Future>>> getAllCmcOrders() async {
+ Future>>> getAllComprehensiveCheckupOrders() async {
Map requestBody = {};
try {
@@ -101,6 +123,65 @@ class HmgServicesRepoImp implements HmgServicesRepo {
}
}
+ @override
+ Future>>> getAllHomeHealthCareCheckupOrders() async {
+ Map requestBody = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ ApiConsts.allHHCOrdersRc,
+ isRCService: true,
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("HHC Orders API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ List cmcOrdersList = [];
+ // Log the full response for debugging
+ // Extract MessageStatus and ErrorEndUserMessage from root level
+ final apiErrorMessage = response['ErrorEndUserMessage'] as String?;
+ // Parse the response array
+ if (response['response'] != null && response['response'] is List) {
+ final ordersList = response['response'] as List;
+
+ for (var orderJson in ordersList) {
+ if (orderJson is Map) {
+ try {
+ cmcOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(orderJson));
+ } catch (e) {
+ loggerService.logError("Error parsing individual order: ${e.toString()}");
+ }
+ }
+ }
+ }
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: apiErrorMessage ?? errorMessage,
+ data: cmcOrdersList,
+ );
+ } catch (e) {
+ loggerService.logError("Error parsing HHC orders: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in getAllHHCOrders: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
@override
Future>>> getAllCmcServices({required int patientID}) async {
Map requestBody = {};
@@ -154,6 +235,59 @@ class HmgServicesRepoImp implements HmgServicesRepo {
}
}
+ @override
+ Future>>> getAllHhcServices({required int patientID}) async {
+ Map requestBody = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ '${ApiConsts.allHHCServicesRc}?patientID=$patientID',
+ isRCService: true,
+ isAllowAny: true,
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("HHC Services API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ List hhcServicesList = [];
+
+ if (response['response'] != null && response['response'] is List) {
+ final servicesList = response['response'] as List;
+
+ for (var serviceJson in servicesList) {
+ if (serviceJson is Map) {
+ hhcServicesList.add(GetCMCServicesResponseModel.fromJson(serviceJson));
+ }
+ }
+ }
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: hhcServicesList,
+ );
+ } catch (e) {
+ loggerService.logError("Error parsing HHC services: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ log("Unknown error in getAllHhcServices: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
@override
Future>> updateCmcPresOrder(OrderUpdateRequestModel requestModel) async {
try {
@@ -194,6 +328,216 @@ class HmgServicesRepoImp implements HmgServicesRepo {
}
}
+ @override
+ Future>> updateHhcPresOrder(OrderUpdateRequestModel requestModel) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ ApiConsts.updateHHCOrder,
+ isRCService: true,
+ body: requestModel.toJson(),
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("Update HHC Order API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: true,
+ );
+
+ loggerService.logInfo("HHC Order updated successfully: PresOrderID=${requestModel.presOrderID}");
+ } catch (e) {
+ loggerService.logError("Error processing update HHC order response: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in updateHhcPresOrder: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> getHospitalsList() async {
+ Map requestBody = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ ApiConsts.getHospitalsList,
+ isRCService: false, // This uses the base HIS API URL, not RC
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("Get Hospitals List API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ List hospitalsList = [];
+
+ loggerService.logInfo("Hospitals List Raw Response: $response");
+
+ if (response['ListProject'] != null && response['ListProject'] is List) {
+ final projectsList = response['ListProject'] as List;
+
+ for (var projectJson in projectsList) {
+ try {
+ if (projectJson is Map) {
+ hospitalsList.add(HospitalsModel.fromJson(projectJson));
+ }
+ } catch (e) {
+ loggerService.logError('Error parsing hospital item: ${e.toString()}');
+ }
+ }
+ } else {
+ loggerService.logInfo('Hospitals list response array is empty or missing');
+ }
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: hospitalsList,
+ );
+
+ loggerService.logInfo("Hospitals fetched successfully: ${hospitalsList.length} hospitals");
+ } catch (e) {
+ loggerService.logError("Error parsing hospitals list: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in getHospitalsList: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>> addCmcOrder({
+ required int projectID,
+ required int orderServiceID,
+ required List services,
+ }) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+
+ final requestBody = {
+ 'ProjectID': projectID,
+ 'OrderServiceID': orderServiceID,
+ 'procedures': services.map((service) => service.toJson()).toList(),
+ };
+
+ await apiClient.post(
+ ApiConsts.addCMCOrder,
+ isRCService: true,
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("Add CMC Order API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ int requestId = 0;
+ if (response is Map) {
+ requestId = response['response'];
+ }
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: requestId,
+ );
+
+ loggerService.logInfo("CMC Order added successfully: ProjectID=$projectID, OrderServiceID=$orderServiceID");
+ } catch (e) {
+ loggerService.logError("Error processing add CMC order response: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in addCmcOrder: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>> addHhcOrder({
+ required int projectID,
+ required int orderServiceID,
+ required List services,
+ }) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+
+ final requestBody = {
+ 'ProjectID': projectID,
+ 'OrderServiceID': orderServiceID,
+ 'procedures': services.map((service) => service.toJson()).toList(),
+ };
+
+ await apiClient.post(
+ ApiConsts.addHHCOrder,
+ isRCService: true,
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("Add HHC Order API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ int requestId = 0;
+ if (response is Map) {
+ requestId = response['response'];
+ }
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: requestId,
+ );
+
+ loggerService.logInfo("HHC Order added successfully: ProjectID=$projectID, OrderServiceID=$orderServiceID");
+ } catch (e) {
+ loggerService.logError("Error processing add HHC order response: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in addHhcOrder: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
/*e-referral functions*/
diff --git a/lib/features/hmg_services/hmg_services_view_model.dart b/lib/features/hmg_services/hmg_services_view_model.dart
index 5dd5482..1e97a63 100644
--- a/lib/features/hmg_services/hmg_services_view_model.dart
+++ b/lib/features/hmg_services/hmg_services_view_model.dart
@@ -1,12 +1,15 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_repo.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/create_e_referral_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/send_activation_code_ereferral_req_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_all_cities_resp_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'models/req_models/check_activation_e_referral_req_model.dart';
@@ -14,28 +17,68 @@ import 'models/resq_models/relationship_type_resp_mode.dart';
class HmgServicesViewModel extends ChangeNotifier {
final HmgServicesRepo hmgServicesRepo;
+ final BookAppointmentsRepo bookAppointmentsRepo;
final ErrorHandlerService errorHandlerService;
- HmgServicesViewModel({required this.hmgServicesRepo, required this.errorHandlerService});
+ HmgServicesViewModel({required this.bookAppointmentsRepo, required this.hmgServicesRepo, required this.errorHandlerService});
bool isCmcOrdersLoading = false;
bool isCmcServicesLoading = false;
bool isUpdatingOrder = false;
+ bool isHospitalListLoading = false;
+
+ // HHC specific loading states
+ bool isHhcOrdersLoading = false;
+ bool isHhcServicesLoading = false;
List cmcOrdersList = [];
List cmcServicesList = [];
+ List hospitalsList = [];
+ List filteredHospitalsList = [];
+ HospitalsModel? selectedHospital;
+
+ // HHC specific lists
+ List hhcOrdersList = [];
+ List hhcServicesList = [];
+
+ // CMC order creation state
+ HospitalsModel? selectedHospitalForOrder;
+ GetCMCServicesResponseModel? selectedServiceForOrder;
+
+ // HHC order creation state (no hospital selection needed for home healthcare)
+ GetCMCServicesResponseModel? selectedServiceForHhcOrder;
List relationTypes =[];
List getAllCitiesList =[];
Future getOrdersList() async {
+ // HHC multiple services selection
+ List selectedHhcServices = [];
+
+ Future getCmcOrdersList() async {
cmcOrdersList.clear();
isCmcOrdersLoading = true;
notifyListeners();
await getAllCmcOrders();
}
+ // Helper to sort hospitals by distance (ascending). Safely converts distanceinkMS to double.
+ void _sortHospitalsByDistance(List list) {
+ double toDouble(dynamic v) {
+ if (v == null) return double.infinity;
+ if (v is num) return v.toDouble();
+ if (v is String) return double.tryParse(v) ?? double.infinity;
+ return double.infinity;
+ }
+
+ list.sort((a, b) {
+ final da = toDouble(a.distanceInKilometers);
+ final db = toDouble(b.distanceInKilometers);
+ return da.compareTo(db);
+ });
+ }
+
Future getAllCmcOrders({
Function(dynamic)? onSuccess,
Function(String)? onError,
@@ -43,7 +86,7 @@ class HmgServicesViewModel extends ChangeNotifier {
isCmcOrdersLoading = true;
notifyListeners();
- final result = await hmgServicesRepo.getAllCmcOrders();
+ final result = await hmgServicesRepo.getAllComprehensiveCheckupOrders();
result.fold(
(failure) async {
@@ -146,6 +189,342 @@ class HmgServicesViewModel extends ChangeNotifier {
return success;
}
+ Future getHospitalsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ isHospitalListLoading = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.getHospitalsList();
+
+ result.fold(
+ (failure) async {
+ isHospitalListLoading = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isHospitalListLoading = false;
+ if (apiResponse.messageStatus == 1) {
+ hospitalsList = apiResponse.data ?? [];
+ filteredHospitalsList = List.from(hospitalsList);
+ // ensure hospitals are sorted by distance before showing
+ _sortHospitalsByDistance(filteredHospitalsList);
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+ }
+
+ void filterHospitalsByString(String searchText, bool isArabic) {
+ if (searchText.isEmpty) {
+ filteredHospitalsList = List.from(hospitalsList);
+ _sortHospitalsByDistance(filteredHospitalsList);
+ } else {
+ filteredHospitalsList = hospitalsList.where((HospitalsModel hospital) {
+ final name = isArabic ? (hospital.nameN ?? '') : (hospital.name ?? '');
+ return name.toLowerCase().contains(searchText.toLowerCase());
+ }).toList();
+ _sortHospitalsByDistance(filteredHospitalsList);
+ }
+ notifyListeners();
+ }
+
+ void setSelectedHospital(HospitalsModel? hospital) {
+ selectedHospital = hospital;
+ notifyListeners();
+ }
+
+ void clearHospitalSelection() {
+ selectedHospital = null;
+ filteredHospitalsList = List.from(hospitalsList);
+ _sortHospitalsByDistance(filteredHospitalsList);
+ notifyListeners();
+ }
+
+ // CMC Order management methods
+ void setSelectedHospitalForOrder(HospitalsModel? hospital) {
+ selectedHospitalForOrder = hospital;
+ notifyListeners();
+ }
+
+ void setSelectedServiceForOrder(GetCMCServicesResponseModel? service) {
+ selectedServiceForOrder = service;
+ notifyListeners();
+ }
+
+ void clearOrderSelection() {
+ selectedHospitalForOrder = null;
+ selectedServiceForOrder = null;
+ notifyListeners();
+ }
+
+ bool get isOrderReadyToConfirm => selectedHospitalForOrder != null && selectedServiceForOrder != null;
+
+ Future addCmcOrder({
+ required int projectID,
+ required int orderServiceID,
+ required List services,
+ Function(int)? onSuccess,
+ Function(String)? onError,
+ }) async {
+ isUpdatingOrder = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.addCmcOrder(
+ projectID: projectID,
+ orderServiceID: orderServiceID,
+ services: services,
+ );
+
+ int requestId = 0;
+
+ result.fold(
+ (failure) async {
+ isUpdatingOrder = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isUpdatingOrder = false;
+ if (apiResponse.messageStatus == 1) {
+ requestId = apiResponse.data ?? 0;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(requestId);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+
+ return requestId;
+ }
+
+// ******************* HOME HEALTHCARE APIs ********************
+
+ Future getHhcOrdersList() async {
+ hhcOrdersList.clear();
+ isHhcOrdersLoading = true;
+ notifyListeners();
+ await getAllHhcOrders();
+ }
+
+ Future getAllHhcOrders({
+ Function(dynamic)? onSuccess,
+ Function(String)? onError,
+ }) async {
+ isHhcOrdersLoading = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.getAllHomeHealthCareCheckupOrders();
+
+ result.fold(
+ (failure) async {
+ isHhcOrdersLoading = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isHhcOrdersLoading = false;
+ if (apiResponse.messageStatus == 1) {
+ hhcOrdersList = apiResponse.data ?? [];
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+ }
+
+ Future getAllHhcServices({required int patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ isHhcServicesLoading = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.getAllHhcServices(patientID: patientID);
+
+ result.fold(
+ (failure) async {
+ isHhcServicesLoading = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isHhcServicesLoading = false;
+ if (apiResponse.messageStatus == 1) {
+ hhcServicesList = apiResponse.data ?? [];
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+ }
+
+ Future updateHhcPresOrder({
+ required OrderUpdateRequestModel requestModel,
+ Function(dynamic)? onSuccess,
+ Function(String)? onError,
+ }) async {
+ isUpdatingOrder = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.updateHhcPresOrder(requestModel);
+
+ bool success = false;
+
+ result.fold(
+ (failure) async {
+ isUpdatingOrder = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isUpdatingOrder = false;
+ if (apiResponse.messageStatus == 1) {
+ success = true;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+
+ return success;
+ }
+
+ Future addHhcOrder({
+ required int projectID,
+ required int orderServiceID,
+ required List services,
+ Function(int)? onSuccess,
+ Function(String)? onError,
+ }) async {
+ isUpdatingOrder = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.addHhcOrder(
+ projectID: projectID,
+ orderServiceID: orderServiceID,
+ services: services,
+ );
+
+ int requestId = 0;
+
+ result.fold(
+ (failure) async {
+ isUpdatingOrder = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isUpdatingOrder = false;
+ if (apiResponse.messageStatus == 1) {
+ requestId = apiResponse.data ?? 0;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(requestId);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+
+ return requestId;
+ }
+
+ // HHC Order management methods (no hospital selection for home healthcare)
+ void setSelectedServiceForHhcOrder(GetCMCServicesResponseModel? service) {
+ selectedServiceForHhcOrder = service;
+ notifyListeners();
+ }
+
+ void clearHhcOrderSelection() {
+ selectedServiceForHhcOrder = null;
+ selectedHhcServices.clear();
+ notifyListeners();
+ }
+
+ bool get isHhcOrderReadyToConfirm => selectedServiceForHhcOrder != null;
+
+ // Multiple HHC services selection methods
+ void toggleHhcServiceSelection(GetCMCServicesResponseModel service) {
+ final index = selectedHhcServices.indexWhere((s) => s.iD == service.iD);
+ if (index != -1) {
+ selectedHhcServices.removeAt(index);
+ } else {
+ selectedHhcServices.add(service);
+ }
+ notifyListeners();
+ }
+
+ bool isHhcServiceSelected(GetCMCServicesResponseModel service) {
+ return selectedHhcServices.any((s) => s.iD == service.iD);
+ }
+
+ double getHhcSelectedServicesTotal() {
+ double total = 0.0;
+ for (var service in selectedHhcServices) {
+ total += (service.priceTotal ?? 0);
+ }
+ return total;
+ }
+
+ void clearHhcServicesSelection() {
+ selectedHhcServices.clear();
+ notifyListeners();
+ }
+
/*e-referral functions*/
Future getRelationshipType({
diff --git a/lib/features/hmg_services/models/req_models/cmc_create_service_order_req_model.dart b/lib/features/hmg_services/models/req_models/cmc_create_service_order_req_model.dart
new file mode 100644
index 0000000..af2808d
--- /dev/null
+++ b/lib/features/hmg_services/models/req_models/cmc_create_service_order_req_model.dart
@@ -0,0 +1,41 @@
+class CmcCreateServiceOrderReqModel {
+ int? recordID;
+ String? serviceID;
+ String? selectedServiceName;
+ String? selectedServiceNameAR;
+ dynamic price;
+ dynamic vAT;
+ dynamic totalPrice;
+
+ CmcCreateServiceOrderReqModel({
+ this.recordID,
+ this.serviceID,
+ this.selectedServiceName,
+ this.selectedServiceNameAR,
+ this.price,
+ this.vAT,
+ this.totalPrice,
+ });
+
+ CmcCreateServiceOrderReqModel.fromJson(Map json) {
+ recordID = json['RecordID'];
+ serviceID = json['ServiceID'];
+ selectedServiceName = json['selectedServiceName'];
+ selectedServiceNameAR = json['selectedServiceNameAR'];
+ price = json['Price'];
+ vAT = json['VAT'];
+ totalPrice = json['TotalPrice'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['RecordID'] = recordID;
+ data['ServiceID'] = serviceID;
+ data['selectedServiceName'] = selectedServiceName;
+ data['selectedServiceNameAR'] = selectedServiceNameAR;
+ data['Price'] = price;
+ data['VAT'] = vAT;
+ data['TotalPrice'] = totalPrice;
+ return data;
+ }
+}
diff --git a/lib/features/lab/lab_repo.dart b/lib/features/lab/lab_repo.dart
index 3bb793b..e661157 100644
--- a/lib/features/lab/lab_repo.dart
+++ b/lib/features/lab/lab_repo.dart
@@ -21,6 +21,7 @@ abstract class LabRepo {
Future>> getLabResultReportPDF({required PatientLabOrdersResponseModel labOrder});
+ Future>> getLabResultsByAppointmentNo({required num appointmentNo, required num projectID, required num clinicID});
}
class LabRepoImp implements LabRepo {
@@ -135,6 +136,7 @@ class LabRepoImp implements LabRepo {
request['SetupID'] = laborder!.setupID;
request['ProjectID'] = laborder.projectID;
request['ClinicID'] = laborder.clinicID;
+ request['InvoiceType'] = laborder.invoiceType ?? "";
try {
GenericApiModel>? apiResponse;
Failure? failure;
@@ -184,6 +186,7 @@ class LabRepoImp implements LabRepo {
request['SetupID'] = laborder!.setupID;
request['ProjectID'] = laborder.projectID;
request['ClinicID'] = laborder.clinicID;
+ request['InvoiceType'] = laborder.invoiceType ?? "";
try {
GenericApiModel>? apiResponse;
Failure? failure;
@@ -278,4 +281,41 @@ class LabRepoImp implements LabRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future> getLabResultsByAppointmentNo({required num appointmentNo, required num projectID, required num clinicID}) async {
+ Map request = {};
+ request['AppointmentNo'] = appointmentNo;
+ request['ProjectID'] = projectID;
+ request['ClinicID'] = clinicID;
+
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response['ListLabResultsByAppNo'],
+ );
+ } 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()));
+ }
+ }
}
diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart
index 12f0f27..bad4f89 100644
--- a/lib/features/lab/lab_view_model.dart
+++ b/lib/features/lab/lab_view_model.dart
@@ -9,11 +9,13 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils;
import 'package:hmg_patient_app_new/features/lab/lab_repo.dart';
import 'package:hmg_patient_app_new/features/lab/models/resp_models/lab_result.dart';
import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart';
+import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_results/lab_result_details.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.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:intl/intl.dart' show DateFormat;
import 'package:logger/logger.dart';
@@ -75,14 +77,14 @@ class LabViewModel extends ChangeNotifier {
required this.navigationService});
initLabProvider() {
- if (isLabNeedToLoad) {
+ // if (isLabNeedToLoad) {
patientLabOrders.clear();
filteredLabOrders.clear();
labOrderTests.clear();
isLabOrdersLoading = true;
isLabResultsLoading = true;
getPatientLabOrders();
- }
+ // }
notifyListeners();
}
@@ -92,7 +94,7 @@ class LabViewModel extends ChangeNotifier {
}
Future getPatientLabOrders({Function(dynamic)? onSuccess, Function(String)? onError}) async {
- if (!isLabNeedToLoad) return;
+ // if (!isLabNeedToLoad) return;
isLabOrdersLoading = true;
patientLabOrders.clear();
@@ -158,7 +160,7 @@ class LabViewModel extends ChangeNotifier {
filterSuggestions() {
final List labels = patientLabOrders
- .expand((order) => order.testDetails!)
+ .expand((order) => order.testDetails ?? [])
.map((detail) => detail.description)
.whereType()
.toList();
@@ -198,6 +200,69 @@ class LabViewModel extends ChangeNotifier {
}
}
+ Future getLabResultsByAppointmentNo(
+ {required num appointmentNo,
+ required num projectID,
+ required num clinicID,
+ required int doctorID,
+ required String clinicName,
+ required String doctorName,
+ required String projectName,
+ required String appointmentDate,
+ Function(dynamic)? onSuccess,
+ Function(String)? onError}) async {
+ bool isVidaPlus = Utils.isVidaPlusProject(projectID.toInt());
+ final result = await labRepo.getLabResultsByAppointmentNo(appointmentNo: appointmentNo, projectID: projectID, clinicID: clinicID);
+
+ result.fold(
+ (failure) async {
+ // await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.message);
+ }
+ },
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ if (onError != null) {
+ onError(apiResponse.errorMessage!);
+ }
+ } else if (apiResponse.messageStatus == 1) {
+ if (apiResponse.data != null && apiResponse.data!.isNotEmpty) {
+ PatientLabOrdersResponseModel labOrder = PatientLabOrdersResponseModel();
+
+ labOrder.invoiceNoVP = isVidaPlus ? apiResponse.data[0]['InvoiceNo'].toString() : "0";
+ labOrder.invoiceNo = isVidaPlus ? "0" : apiResponse.data[0]['InvoiceNo'].toString();
+ labOrder.orderNo = apiResponse.data[0]['OrderNo'].toString();
+ labOrder.invoiceType = apiResponse.data[0]['InvoiceType'].toString();
+ labOrder.setupID = apiResponse.data[0]['SetupID'].toString();
+ labOrder.projectID = projectID.toString();
+ labOrder.clinicID = clinicID.toInt();
+ labOrder.doctorID = doctorID;
+ labOrder.clinicDescription = clinicName;
+ labOrder.doctorName = doctorName;
+ labOrder.projectName = projectName;
+ labOrder.orderDate = appointmentDate;
+
+ currentlySelectedPatientOrder = labOrder;
+
+ getPatientLabResultByHospital(labOrder);
+ getPatientSpecialResult(labOrder);
+
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ navigationService.push(
+ CustomPageRoute(
+ page: LabResultByClinic(labOrder: labOrder),
+ ),
+ );
+ } else {}
+ notifyListeners();
+ }
+ },
+ );
+ }
+
Future getPatientLabResultByHospital(
PatientLabOrdersResponseModel laborder) async {
isLabResultByHospitalLoading = true;
diff --git a/lib/features/my_appointments/models/resp_models/hospital_model.dart b/lib/features/my_appointments/models/resp_models/hospital_model.dart
index 9a211d0..a807b99 100644
--- a/lib/features/my_appointments/models/resp_models/hospital_model.dart
+++ b/lib/features/my_appointments/models/resp_models/hospital_model.dart
@@ -62,9 +62,9 @@ class HospitalsModel {
mainProjectID = json['MainProjectID'];
projectOutSA = json['ProjectOutSA'];
usingInDoctorApp = json['UsingInDoctorApp'];
- this.isHMC = json["IsHMC"];
- this.regionArabic = json['RegionNameN'];
- this.regionEnglish = json['RegionName'];
+ isHMC = json["IsHMC"];
+ regionArabic = json['RegionNameN'];
+ regionEnglish = json['RegionName'];
}
String? getRegionName(bool isArabic) {
@@ -83,24 +83,22 @@ class HospitalsModel {
Map toJson() {
final Map data = new Map();
- data['Desciption'] = this.desciption;
- data['DesciptionN'] = this.desciptionN;
- data['ID'] = this.iD;
- data['LegalName'] = this.legalName;
- data['LegalNameN'] = this.legalNameN;
- data['Name'] = this.name;
- data['NameN'] = this.nameN;
- data['PhoneNumber'] = this.phoneNumber;
- data['SetupID'] = this.setupID;
- data['DistanceInKilometers'] = this.distanceInKilometers;
- data['IsActive'] = this.isActive;
- data['Latitude'] = this.latitude;
- data['Longitude'] = this.longitude;
- data['MainProjectID'] = this.mainProjectID;
- data['ProjectOutSA'] = this.projectOutSA;
- data['UsingInDoctorApp'] = this.usingInDoctorApp;
+ data['Desciption'] = desciption;
+ data['DesciptionN'] = desciptionN;
+ data['ID'] = iD;
+ data['LegalName'] = legalName;
+ data['LegalNameN'] = legalNameN;
+ data['Name'] = name;
+ data['NameN'] = nameN;
+ data['PhoneNumber'] = phoneNumber;
+ data['SetupID'] = setupID;
+ data['DistanceInKilometers'] = distanceInKilometers;
+ data['IsActive'] = isActive;
+ data['Latitude'] = latitude;
+ data['Longitude'] = longitude;
+ data['MainProjectID'] = mainProjectID;
+ data['ProjectOutSA'] = projectOutSA;
+ data['UsingInDoctorApp'] = usingInDoctorApp;
return data;
}
-
-
}
diff --git a/lib/features/radiology/radiology_repo.dart b/lib/features/radiology/radiology_repo.dart
index b81fd50..2af3e0f 100644
--- a/lib/features/radiology/radiology_repo.dart
+++ b/lib/features/radiology/radiology_repo.dart
@@ -15,6 +15,8 @@ abstract class RadiologyRepo {
Future>> getRadiologyReportPDF(
{required PatientRadiologyResponseModel patientRadiologyResponseModel, required AuthenticatedUser authenticatedUser});
+
+ Future>>> getPatientRadiologyOrderByAppointment({required num appointmentNo, required num projectID});
}
class RadiologyRepoImp implements RadiologyRepo {
@@ -168,4 +170,50 @@ class RadiologyRepoImp implements RadiologyRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>>> getPatientRadiologyOrderByAppointment({required num appointmentNo, required num projectID}) async {
+ Map mapDevice = {
+ "AppointmentNo": appointmentNo,
+ "ProjectID": projectID,
+ };
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_PATIENT_ORDERS,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ final radOrders;
+ try {
+ if (response['FinalRadiologyList'] != null && response['FinalRadiologyList'].length != 0) {
+ final list = response['FinalRadiologyList'];
+ radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast();
+ } else {
+ final list = response['FinalRadiologyListAPI'];
+ radOrders = list.map((item) => PatientRadiologyResponseModel.fromJson(item as Map)).toList().cast();
+ }
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: radOrders,
+ );
+ } 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()));
+ }
+ }
}
diff --git a/lib/features/radiology/radiology_view_model.dart b/lib/features/radiology/radiology_view_model.dart
index d39d84f..4a87906 100644
--- a/lib/features/radiology/radiology_view_model.dart
+++ b/lib/features/radiology/radiology_view_model.dart
@@ -1,7 +1,11 @@
import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_repo.dart';
+import 'package:hmg_patient_app_new/presentation/radiology/radiology_result_page.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
+import 'package:hmg_patient_app_new/services/navigation_service.dart';
+import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'models/resp_models/patient_radiology_response_model.dart';
@@ -11,6 +15,7 @@ class RadiologyViewModel extends ChangeNotifier {
RadiologyRepo radiologyRepo;
ErrorHandlerService errorHandlerService;
+ NavigationService navigationService;
List patientRadiologyOrders = [];
List filteredRadiologyOrders = [];
@@ -22,7 +27,9 @@ class RadiologyViewModel extends ChangeNotifier {
List get radiologySuggestions => _radiologySuggestionsList;
- RadiologyViewModel({required this.radiologyRepo, required this.errorHandlerService});
+ late PatientRadiologyResponseModel patientRadiologyOrderByAppointment;
+
+ RadiologyViewModel({required this.radiologyRepo, required this.errorHandlerService, required this.navigationService});
initRadiologyViewModel() {
patientRadiologyOrders.clear();
@@ -57,6 +64,35 @@ class RadiologyViewModel extends ChangeNotifier {
);
}
+ Future getPatientRadiologyOrdersByAppointment({required num appointmentNo, required num projectID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await radiologyRepo.getPatientRadiologyOrderByAppointment(appointmentNo: appointmentNo, projectID: projectID);
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ notifyListeners();
+ if (apiResponse.data!.isNotEmpty) {
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ navigationService.push(
+ CustomPageRoute(
+ page: RadiologyResultPage(patientRadiologyResponseModel: apiResponse.data!.first),
+ ),
+ );
+ } else {
+ if (onError != null) {
+ onError("No Radiology Orders Found".needTranslation);
+ }
+ }
+ }
+ },
+ );
+ }
+
Future getRadiologyImage(
{required PatientRadiologyResponseModel patientRadiologyResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await radiologyRepo.getRadiologyImage(patientRadiologyResponseModel: patientRadiologyResponseModel);
@@ -107,23 +143,20 @@ class RadiologyViewModel extends ChangeNotifier {
},
);
}
+
filterSuggestions() {
- final List labels = patientRadiologyOrders
- .map((detail) => detail.description)
- .whereType()
- .toList();
+ final List labels = patientRadiologyOrders.map((detail) => detail.description).whereType().toList();
_radiologySuggestionsList = labels.toSet().toList();
notifyListeners();
}
+
filterRadiologyReports(String query) {
if (query.isEmpty) {
- patientRadiologyOrders =tempRadiologyOrders;// reset
+ patientRadiologyOrders = tempRadiologyOrders; // reset
} else {
- filteredRadiologyOrders =
- filteredRadiologyOrders.where((desc) => desc.description!.toLowerCase().contains(query.toLowerCase())).toList();
+ filteredRadiologyOrders = filteredRadiologyOrders.where((desc) => desc.description!.toLowerCase().contains(query.toLowerCase())).toList();
patientRadiologyOrders = filteredRadiologyOrders;
}
notifyListeners();
}
-
}
diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart
index 12f3589..e620783 100644
--- a/lib/presentation/appointments/appointment_details_page.dart
+++ b/lib/presentation/appointments/appointment_details_page.dart
@@ -11,26 +11,32 @@ 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/doctors_list_response_model.dart';
+import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart';
+import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart';
import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
+import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/appointment_payment_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart';
+import 'package:hmg_patient_app_new/presentation/contact_us/feedback_page.dart';
+import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart';
+import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart';
+import 'package:hmg_patient_app_new/presentation/radiology/radiology_orders_page.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.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/shimmer/common_shimmer_widget.dart';
import 'package:maps_launcher/maps_launcher.dart';
import 'package:provider/provider.dart';
@@ -50,14 +56,17 @@ class _AppointmentDetailsPageState extends State {
late MyAppointmentsViewModel myAppointmentsViewModel;
late PrescriptionsViewModel prescriptionsViewModel;
late BookAppointmentsViewModel bookAppointmentsViewModel;
+ late ContactUsViewModel contactUsViewModel;
+ late LabViewModel labViewModel;
+ late RadiologyViewModel radiologyViewModel;
@override
void initState() {
scheduleMicrotask(() {
- if (AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) {
- prescriptionsViewModel.setPrescriptionsDetailsLoading();
- prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel());
- }
+ // if (AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) {
+ // prescriptionsViewModel.setPrescriptionsDetailsLoading();
+ // prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel());
+ // }
});
super.initState();
}
@@ -68,6 +77,9 @@ class _AppointmentDetailsPageState extends State {
myAppointmentsViewModel = Provider.of(context, listen: false);
prescriptionsViewModel = Provider.of