From 75c55db90f174f9acd3925b744b5149cf80e3bae Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Wed, 15 Jul 2026 11:15:35 +0300 Subject: [PATCH 01/12] notification center-id --- lib/core/utils/request_utils.dart | 7 +++++++ .../request_models/send_activation_request_model.dart | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/core/utils/request_utils.dart b/lib/core/utils/request_utils.dart index 4d4ae4b5..4e5293a7 100644 --- a/lib/core/utils/request_utils.dart +++ b/lib/core/utils/request_utils.dart @@ -192,6 +192,13 @@ class RequestUtils { request.familyRegionID = zipCode == CountryEnum.saudiArabia.countryCode ? 1 : 2; } + request.notificationCenterAppGUID = ApiConsts.notificationCenterAppGUID; + request.notificationCenterAppServiceGUID = isFormFamilyFile + ? ApiConsts.notificationServiceGUID_FamilyFile + : isForRegister + ? ApiConsts.notificationServiceGUID_Registration + : ApiConsts.notificationServiceGUID_Login; + return request; } diff --git a/lib/features/authentication/models/request_models/send_activation_request_model.dart b/lib/features/authentication/models/request_models/send_activation_request_model.dart index 2908f7ec..76d6c939 100644 --- a/lib/features/authentication/models/request_models/send_activation_request_model.dart +++ b/lib/features/authentication/models/request_models/send_activation_request_model.dart @@ -30,6 +30,8 @@ class SendActivationRequest { int? status; int? familyRegionID; bool? isPatientExcluded; + String? notificationCenterAppGUID; + String? notificationCenterAppServiceGUID; SendActivationRequest( {this.patientMobileNumber, @@ -62,7 +64,9 @@ class SendActivationRequest { this.responseID, this.status, this.familyRegionID, - this.isPatientExcluded}); + this.isPatientExcluded, + this.notificationCenterAppGUID, + this.notificationCenterAppServiceGUID}); SendActivationRequest.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; @@ -96,6 +100,8 @@ class SendActivationRequest { status = json['Status']; familyRegionID = json['FamilyRegionID']; isPatientExcluded = json['IsPatientExcluded']; + notificationCenterAppGUID = json['NotificationCenterAppGUID']; + notificationCenterAppServiceGUID = json['NotificationCenterAppSeviceGUID']; } Map toJson() { @@ -135,6 +141,8 @@ class SendActivationRequest { data['Status'] = status; data['FamilyRegionID'] = familyRegionID; data['IsPatientExcluded'] = isPatientExcluded; + data['NotificationCenterAppGUID'] = notificationCenterAppGUID; + data['NotificationCenterAppSeviceGUID'] = notificationCenterAppServiceGUID; return data; } } From f860fa9b14243f2021e5e695ab10a40aba33b761 Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Tue, 29 Sep 2026 11:12:51 +0300 Subject: [PATCH 02/12] remove the notification id send on checkactivation code --- lib/features/authentication/authentication_repo.dart | 2 ++ lib/features/authentication/authentication_view_model.dart | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 291e4a9b..1c95d99a 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -222,6 +222,8 @@ class AuthenticationRepoImp implements AuthenticationRepo { if (isRegister) { newRequest["activationCode"] = activationCode ?? "0000"; newRequest["isSilentLogin"] = activationCode == null; + newRequest.remove("NotificationCenterAppGUID"); + newRequest.remove("NotificationCenterAppSeviceGUID"); } else { newRequest.activationCode = activationCode ?? "0000"; newRequest.isSilentLogin = activationCode == null; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 271c628d..57f76b66 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -1517,7 +1517,9 @@ class AuthenticationViewModel extends ChangeNotifier { LoaderBottomSheet.hideLoader(); if (apiResponse.data["MessageStatus"] == 1) { LoaderBottomSheet.showLoader(loadingText: "Your medical file has been created successfully. \nPlease proceed to login."); - //TODO: Here We Need to Show a Dialog Of Something in the case of Success. + // Reset registration payload and clear healthId so subsequent logins hit the login endpoint + _appState.getUserRegistrationPayload.healthId = null; + _appState.setUserRegistrationPayload = RegistrationDataModelPayload(); await clearDefaultInputValues(); // This will Clear All Default Values Of User. Future.delayed(Duration(seconds: 1), () { LoaderBottomSheet.hideLoader(); From 585514576199619c56c25fe7f4de274b20f82ab7 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 30 Sep 2026 16:49:02 +0300 Subject: [PATCH 03/12] Notification page changes --- assets/langs/ar-SA.json | 4 +- assets/langs/en-US.json | 4 +- .../notifications_view_model.dart | 60 +++++++++++++++---- .../occasion_theme/occasion_config_model.dart | 5 ++ lib/generated/locale_keys.g.dart | 2 + .../hmg_services/services_page.dart | 2 +- lib/presentation/home/landing_page.dart | 1 + .../widgets/medical_report_card.dart | 6 +- .../widgets/patient_sick_leave_card.dart | 2 +- .../medical_report/medical_reports_page.dart | 37 +----------- .../notifications_list_page.dart | 49 +++++++++++++++ 11 files changed, 119 insertions(+), 53 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index a09efff5..8f047535 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -2054,5 +2054,7 @@ "importantNotice": "تنبيه هام", "appDecommissionedText": "تم إيقاف هذا الإصدار من تطبيق الحبيب الطبي.\nللاستمرار في الاستفادة من الخدمات الصحية والسجلات الطبية، يرجى تحميل التطبيق الجديد.", "appDecommissionedSubText": "نعتذر بشدة عن الإزعاج الناتج عن هذا الانتقال.", - "downloadApp": "حمل التطبيق" + "downloadApp": "حمل التطبيق", + "unread": "غير مقروء", + "read": "مقروءة" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index d7cd2411..184fb93e 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -2044,7 +2044,9 @@ "importantNotice": "Important Notice", "appDecommissionedText": "This version of our healthcare application has been officially discontinued. To ensure uninterrupted access to your clinical records, we are transitioning all patients back to our main platform.", "appDecommissionedSubText": "We sincerely apologize for the inconvenience of this transition.", - "downloadApp": "Download App" + "downloadApp": "Download App", + "unread": "Unread", + "read": "Read" } diff --git a/lib/features/notifications/notifications_view_model.dart b/lib/features/notifications/notifications_view_model.dart index 85049ec9..0f3cc160 100644 --- a/lib/features/notifications/notifications_view_model.dart +++ b/lib/features/notifications/notifications_view_model.dart @@ -13,11 +13,16 @@ class NotificationsViewModel extends ChangeNotifier { ErrorHandlerService errorHandlerService; List notificationsList = []; + List readdNotificationsList = []; + List unreadNotificationsList = []; + List allNotificationsList = []; int currentPage = 0; int pagingSize = 50; int notificationStatusID = 2; // Default to status 2 (e.g., unread) + int selectedNotificationsTabIndex = 0; + NotificationsViewModel({ required this.notificationsRepo, required this.errorHandlerService, @@ -35,6 +40,18 @@ class NotificationsViewModel extends ChangeNotifier { notifyListeners(); } + void onNotificationTabChange(int index) { + selectedNotificationsTabIndex = index; + if (index == 0) { + notificationsList = allNotificationsList; + } else if (index == 1) { + notificationsList = unreadNotificationsList; + } else if (index == 2) { + notificationsList = readdNotificationsList; + } + notifyListeners(); + } + setNotificationStatusID(int statusID) { notificationStatusID = statusID; notificationsList.clear(); @@ -49,6 +66,9 @@ class NotificationsViewModel extends ChangeNotifier { }) async { isNotificationsLoading = true; unreadNotificationsCount = 0; + + notificationsList.clear(); + notifyListeners(); final result = await notificationsRepo.getAllNotifications( @@ -80,17 +100,37 @@ class NotificationsViewModel extends ChangeNotifier { hasMoreNotifications = false; } - notificationsList.addAll(newNotifications); - for (var notification in notificationsList) { - if (notification.isRead == false) { - unreadNotificationsCount++; + try { + notificationsList.addAll(newNotifications); + + // allNotificationsList.clear(); + // readdNotificationsList.clear(); + // unreadNotificationsList.clear(); + + // for (var notification in notificationsList) { + // if (notification.isRead == false) { + // unreadNotificationsCount++; + // unreadNotificationsList.add(notification); + // } else { + // readdNotificationsList.add(notification); + // } + // } + + // Filter out the items directly without a loop + unreadNotificationsList = notificationsList.where((n) => n.isRead == false).toList(); + readdNotificationsList = notificationsList.where((n) => n.isRead == true).toList(); + + // Calculate count based on the new list length + unreadNotificationsCount = unreadNotificationsList.length; + + currentPage++; + allNotificationsList = notificationsList; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); } - } - currentPage++; - - notifyListeners(); - if (onSuccess != null) { - onSuccess(apiResponse); + } catch (ex) { + print(ex.toString()); } } }, diff --git a/lib/features/occasion_theme/occasion_config_model.dart b/lib/features/occasion_theme/occasion_config_model.dart index 03bf9392..de8d14ef 100644 --- a/lib/features/occasion_theme/occasion_config_model.dart +++ b/lib/features/occasion_theme/occasion_config_model.dart @@ -68,6 +68,11 @@ class OccasionConfigModel { enabled: (json['enabled'] as bool?) ?? false, startDate: _parseDate(json['start_date']), endDate: _parseDate(json['end_date']), + + // enabled: true, + // startDate: _parseDate("2026-09-30T00:00:00Z"), + // endDate: _parseDate("2026-10-05T00:00:00Z"), + primaryColorHex: json['primary_color'] as String?, backgroundOpacityImage: json['background_opacity_image'] as String?, backgroundImageOpacity: (json['background_image_opacity'] as num?)?.toDouble() ?? 1.0, diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 67aacc0e..9de9ce9f 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -2036,5 +2036,7 @@ abstract class LocaleKeys { static const appDecommissionedText = 'appDecommissionedText'; static const appDecommissionedSubText = 'appDecommissionedSubText'; static const downloadApp = 'downloadApp'; + static const unread = 'unread'; + static const read = 'read'; } diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 582fd6fc..34fc268f 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -72,7 +72,7 @@ class _ServicesPageState extends State { LocaleKeys.emergencyServices.tr(), "", AppAssets.emergency_services_icon, - bgColor: AppColors.primaryRedColor, + bgColor: AppColors.primaryRedColorBase, true, route: null, onTap: () async { // if (getIt.get().isAuthenticated) { diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 8644655d..9d401fac 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -437,6 +437,7 @@ class _LandingPageState extends State { : SizedBox.shrink(), ]).onPress(() async { if (appState.isAuthenticated) { + notificationsViewModel.onNotificationTabChange(0); notificationsViewModel.setNotificationStatusID(2); notificationsViewModel.getAllNotifications(); Navigator.of(context).push( diff --git a/lib/presentation/medical_file/widgets/medical_report_card.dart b/lib/presentation/medical_file/widgets/medical_report_card.dart index 1a43b83b..905823b4 100644 --- a/lib/presentation/medical_file/widgets/medical_report_card.dart +++ b/lib/presentation/medical_file/widgets/medical_report_card.dart @@ -84,15 +84,15 @@ class MedicalReportCard extends StatelessWidget { ), ); }, - backgroundColor: AppColors.lightRedButtonColor, - borderColor: AppColors.lightRedButtonColor, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor, fontSize: 14.f, - // fontWeight: FontWeight.w600, isBold: true, borderRadius: 12.r, height: 40.h, + iconSize: 18.f, ).toShimmer2(isShow: isLoading), ], ), diff --git a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart index f06e6a0e..2bb879b5 100644 --- a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart +++ b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart @@ -122,7 +122,7 @@ class PatientSickLeaveCard extends StatelessWidget { }); }, backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.transparent, textColor: AppColors.primaryRedColor, fontSize: 14.f, isBold: true, diff --git a/lib/presentation/medical_report/medical_reports_page.dart b/lib/presentation/medical_report/medical_reports_page.dart index e1ac3969..64939629 100644 --- a/lib/presentation/medical_report/medical_reports_page.dart +++ b/lib/presentation/medical_report/medical_reports_page.dart @@ -50,42 +50,7 @@ class _MedicalReportsPageState extends State { child: Consumer(builder: (context, medicalFileVM, child) { return Column( children: [ - SizedBox(height: 16.h), - // Status filter tabs - // Row( - // children: [ - // CustomButton( - // text: LocaleKeys.byClinic.tr(context: context), - // onPressed: () { - // medicalFileVM.setIsMedicalReportsSortByClinic(true); - // }, - // backgroundColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, - // borderColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), - // textColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, - // fontSize: 12, - // isBold: true, - // borderRadius: 10, - // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - // height: 40.h, - // ), - // SizedBox(width: 8.h), - // CustomButton( - // text: LocaleKeys.byHospital.tr(context: context), - // onPressed: () { - // medicalFileVM.setIsMedicalReportsSortByClinic(false); - // }, - // backgroundColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, - // borderColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, - // textColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, - // fontSize: 12, - // isBold: true, - // borderRadius: 10, - // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - // height: 40.h, - // ), - // ], - // ).paddingSymmetrical(24.h, 0.h), - SizedBox(height: 8.h), + SizedBox(height: 24.h), Row( children: [ CustomButton( diff --git a/lib/presentation/notifications/notifications_list_page.dart b/lib/presentation/notifications/notifications_list_page.dart index 77f9a20a..eb1af696 100644 --- a/lib/presentation/notifications/notifications_list_page.dart +++ b/lib/presentation/notifications/notifications_list_page.dart @@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/notifications/notification_details_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:provider/provider.dart'; import 'package:intl/intl.dart'; import 'dart:ui' as ui; @@ -51,6 +52,54 @@ class _NotificationsListPageState extends State { child: Consumer(builder: (context, notificationsVM, child) { return Column( children: [ + Row( + children: [ + CustomButton( + text: LocaleKeys.all.tr(context: context), + onPressed: () { + notificationsVM.onNotificationTabChange(0); + }, + backgroundColor: notificationsVM.selectedNotificationsTabIndex == 0 ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: notificationsVM.selectedNotificationsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: notificationsVM.selectedNotificationsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + isBold: true, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.unread.tr(context: context), + onPressed: () { + notificationsVM.onNotificationTabChange(1); + }, + backgroundColor: notificationsVM.selectedNotificationsTabIndex == 1 ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: notificationsVM.selectedNotificationsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: notificationsVM.selectedNotificationsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + isBold: true, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.read.tr(context: context), + onPressed: () { + notificationsVM.onNotificationTabChange(2); + }, + backgroundColor: notificationsVM.selectedNotificationsTabIndex == 2 ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: notificationsVM.selectedNotificationsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: notificationsVM.selectedNotificationsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + isBold: true, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ).paddingSymmetrical(24.h, 0.h), Container( margin: EdgeInsets.symmetric(vertical: 24.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( From 71af4fe15a45e6619cdfb01d5f2015d3cea97329 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 5 Oct 2026 09:53:19 +0300 Subject: [PATCH 04/12] updates --- lib/core/api_consts.dart | 4 ++-- lib/features/occasion_theme/occasion_config_model.dart | 2 +- .../livecare/immediate_livecare_payment_page.dart | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index daa51bba..4b2cd1c1 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -6,7 +6,7 @@ import 'package:myfatoorah_flutter/myfatoorah_flutter.dart'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.preProd; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT @@ -316,7 +316,7 @@ class ApiConsts { static String googleCloudStorageENTranslationFileBaseURL = "https://storage.googleapis.com/hmg-patientapp-translations"; // ************ static values for Api **************** - static final double appVersionID = 22.3; + static final double appVersionID = 22.4; // static final double appVersionID = 50.7; static final int appChannelId = 3; diff --git a/lib/features/occasion_theme/occasion_config_model.dart b/lib/features/occasion_theme/occasion_config_model.dart index de8d14ef..bf9d713f 100644 --- a/lib/features/occasion_theme/occasion_config_model.dart +++ b/lib/features/occasion_theme/occasion_config_model.dart @@ -71,7 +71,7 @@ class OccasionConfigModel { // enabled: true, // startDate: _parseDate("2026-09-30T00:00:00Z"), - // endDate: _parseDate("2026-10-05T00:00:00Z"), + // endDate: _parseDate("2026-10-07T00:00:00Z"), primaryColorHex: json['primary_color'] as String?, backgroundOpacityImage: json['background_opacity_image'] as String?, diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart index 2147cbd6..9d30f976 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart @@ -759,8 +759,8 @@ class _ImmediateLiveCarePaymentPageState extends State Date: Mon, 5 Oct 2026 10:00:35 +0300 Subject: [PATCH 05/12] updates --- android/app/proguard-rules.pro | 2 +- android/gradle.properties | 1 + ios/Podfile | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index e4e65227..68b506a1 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -3,7 +3,7 @@ -keep class com.twilio.common.** { *; } -keepattributes InnerClasses --keep class com.ejada.** { *; } +#-keep class com.ejada.** { *; } -keep class org.webrtc.** { *; } -keep class com.builttoroam.devicecalendar.** { *; } diff --git a/android/gradle.properties b/android/gradle.properties index f47e3b3a..210295ee 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,6 @@ #org.gradle.jvmargs=-xmx4608m android.enableR8=true +android.enableR8.fullMode=true android.enableJetifier=true android.useDeprecatedNdk=true org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 diff --git a/ios/Podfile b/ios/Podfile index a74c7fb2..e0283052 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -59,7 +59,7 @@ post_install do |installer| 'PERMISSION_NOTIFICATIONS=1', ] build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386' - build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0' build_configuration.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' xcconfig_path = build_configuration.base_configuration_reference.real_path xcconfig = File.read(xcconfig_path) From 11370ae860db2fa5008c8e1c6f37ec14d50071cd Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 5 Oct 2026 10:49:56 +0300 Subject: [PATCH 06/12] In App Browser fixes --- lib/core/api_consts.dart | 2 +- lib/widgets/in_app_browser/InAppBrowser.dart | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 4b2cd1c1..89ab00e3 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -6,7 +6,7 @@ import 'package:myfatoorah_flutter/myfatoorah_flutter.dart'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.preProd; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/widgets/in_app_browser/InAppBrowser.dart b/lib/widgets/in_app_browser/InAppBrowser.dart index fe08fbbe..5eaa313c 100644 --- a/lib/widgets/in_app_browser/InAppBrowser.dart +++ b/lib/widgets/in_app_browser/InAppBrowser.dart @@ -307,12 +307,13 @@ class MyInAppBrowser extends InAppBrowser { form = form.replaceFirst('CUSTNAME_VALUE', patientName); form = form.replaceFirst('CUSTID_VALUE', patientID.toString()); + form = form.replaceFirst('APPOINTMENT_DATE_VALUE', appoDate); + form = form.replaceFirst('APPOINTMENT_NO_VALUE', appoNo.toString()); + form = form.replaceFirst('DOCTOR_ID_VALUE', doctorID.toString()); + form = form.replaceFirst('CLINIC_ID_VALUE', clinicID.toString()); + if (isLiveCareAppo) { form = form.replaceFirst('IS_SCHEDULE_VALUE', "true"); - form = form.replaceFirst('APPOINTMENT_DATE_VALUE', appoDate); - form = form.replaceFirst('APPOINTMENT_NO_VALUE', appoNo.toString()); - form = form.replaceFirst('DOCTOR_ID_VALUE', doctorID.toString()); - form = form.replaceFirst('CLINIC_ID_VALUE', clinicID.toString()); } var bytes = utf8.encode(form); @@ -363,6 +364,10 @@ class MyInAppBrowser extends InAppBrowser { '' + '' + '' + + '' + + '' + + '' + + '' + '' + '' + '' + From d9ad16f9d78829654e13362d488112e0b54a5295 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 5 Oct 2026 11:35:28 +0300 Subject: [PATCH 07/12] CR 22303 Medical Report implemented --- assets/langs/ar-SA.json | 3 ++- assets/langs/en-US.json | 3 ++- .../medical_file/medical_file_view_model.dart | 13 +++++++++++++ lib/generated/locale_keys.g.dart | 1 + .../appointments/appointment_payment_page.dart | 3 ++- .../appointments/widgets/appointment_card.dart | 12 +++++++++++- .../medical_report/medical_report_request_page.dart | 9 ++++++--- .../medical_report/medical_reports_page.dart | 1 + 8 files changed, 38 insertions(+), 7 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 8f047535..51cc0ec3 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -2056,5 +2056,6 @@ "appDecommissionedSubText": "نعتذر بشدة عن الإزعاج الناتج عن هذا الانتقال.", "downloadApp": "حمل التطبيق", "unread": "غير مقروء", - "read": "مقروءة" + "read": "مقروءة", + "pendingMedicalReportRequest": "لديك بالفعل طلب معلّق للحصول على تقرير طبي خاص بهذا الموعد. يرجى الانتظار حتى اكتمال الطلب قبل تقديم طلب جديد." } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 184fb93e..ceaf6579 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -2046,7 +2046,8 @@ "appDecommissionedSubText": "We sincerely apologize for the inconvenience of this transition.", "downloadApp": "Download App", "unread": "Unread", - "read": "Read" + "read": "Read", + "pendingMedicalReportRequest": "You already have a pending medical report request for this appointment. Please wait for the request to be completed before submitting a new one.", } diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index 29f653ec..f3a4e2e8 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -864,4 +864,17 @@ class MedicalFileViewModel extends ChangeNotifier { print("❌ Error updating family member profile image in cache: $e"); } } + + bool checkExistingMedicalReportStatus(PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel) { + bool hasExistingRequest = false; + + for (var report in patientMedicalReportRequestedList) { + if (report.clinicID == patientAppointmentHistoryResponseModel.clinicID && report.doctorID == patientAppointmentHistoryResponseModel.doctorID) { + hasExistingRequest = true; + break; + } + } + + return hasExistingRequest; + } } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 9de9ce9f..30e3bc0a 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -2038,5 +2038,6 @@ abstract class LocaleKeys { static const downloadApp = 'downloadApp'; static const unread = 'unread'; static const read = 'read'; + static const pendingMedicalReportRequest = 'pendingMedicalReportRequest'; } diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index ffa9b723..5b7e4c80 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -748,7 +748,8 @@ class _AppointmentPaymentPageState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (myAppointmentsVM.patientAppointmentShareResponseModel!.isCash ?? true) + // (myAppointmentsVM.patientAppointmentShareResponseModel!.isCash ?? true) + (true) ? Container( height: 50.h, decoration: ShapeDecoration( diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 1eeb842c..b9a2f26f 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -448,7 +448,17 @@ class _AppointmentCardState extends State { if (widget.isForFeedback) { widget.contactUsViewModel!.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel); } else { - widget.medicalFileViewModel!.setSelectedMedicalReportAppointment(widget.patientAppointmentHistoryResponseModel); + if(!widget.medicalFileViewModel!.checkExistingMedicalReportStatus(widget.patientAppointmentHistoryResponseModel)) { + widget.medicalFileViewModel!.setSelectedMedicalReportAppointment(widget.patientAppointmentHistoryResponseModel); + } else { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: LocaleKeys.pendingMedicalReportRequest.tr(context: context)), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } } Navigator.pop(context, false); } else { diff --git a/lib/presentation/medical_report/medical_report_request_page.dart b/lib/presentation/medical_report/medical_report_request_page.dart index 47a2df32..859a6b2f 100644 --- a/lib/presentation/medical_report/medical_report_request_page.dart +++ b/lib/presentation/medical_report/medical_report_request_page.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; @@ -26,8 +27,9 @@ class MedicalReportRequestPage extends StatelessWidget { isClose: true, child: Column( children: [ - ListView.separated( - padding: EdgeInsets.only(top: 24.h), + medicalFileViewModel.patientMedicalReportAppointmentHistoryList.isNotEmpty + ? ListView.separated( + padding: EdgeInsets.only(top: 24.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: medicalFileViewModel.patientMedicalReportAppointmentHistoryList.length, @@ -57,7 +59,8 @@ class MedicalReportRequestPage extends StatelessWidget { ); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ), + ) + : Utils.getNoDataWidget(context), SizedBox(height: 24.h), ], ), diff --git a/lib/presentation/medical_report/medical_reports_page.dart b/lib/presentation/medical_report/medical_reports_page.dart index 64939629..33f9e6e3 100644 --- a/lib/presentation/medical_report/medical_reports_page.dart +++ b/lib/presentation/medical_report/medical_reports_page.dart @@ -369,6 +369,7 @@ class _MedicalReportsPageState extends State { showCommonBottomSheetWithoutHeight(context, child: Utils.getSuccessWidget(loadingText: LocaleKeys.yourMedicalReportRequestSubmittedSuccessfully.tr(context: context)), callBackFunc: () async{ + medicalFileViewModel.setIsMedicalReportsDataNeedsReloading(true); medicalFileViewModel.setIsPatientMedicalReportsLoading(true); medicalFileViewModel.onMedicalReportTabChange(0); medicalFileViewModel.getPatientMedicalReportList(); From 133d27155b38837765c8244a68ec67c423169339 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 6 Oct 2026 10:26:45 +0300 Subject: [PATCH 08/12] updates --- assets/langs/en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index ceaf6579..4cf2827c 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -2047,7 +2047,7 @@ "downloadApp": "Download App", "unread": "Unread", "read": "Read", - "pendingMedicalReportRequest": "You already have a pending medical report request for this appointment. Please wait for the request to be completed before submitting a new one.", + "pendingMedicalReportRequest": "You already have a pending medical report request for this appointment. Please wait for the request to be completed before submitting a new one." } From 5b889b0b109c0cfcf701cead8ba55964b0ff662f Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Tue, 6 Oct 2026 10:32:34 +0300 Subject: [PATCH 09/12] family file card fix --- lib/presentation/my_family/widget/family_cards.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/presentation/my_family/widget/family_cards.dart b/lib/presentation/my_family/widget/family_cards.dart index f6300be3..468dd28f 100644 --- a/lib/presentation/my_family/widget/family_cards.dart +++ b/lib/presentation/my_family/widget/family_cards.dart @@ -475,7 +475,7 @@ class _FamilyCardsState extends State { ? Wrap(direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( icon: AppAssets.file_icon, - richText: "${LocaleKeys.fileno.tr(context: context)}: ${profile.responseId}".toText10(isBold: true), + richText: "${profile.responseId}".toText10(isBold: true), labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), ), AppCustomChipWidget( @@ -489,7 +489,7 @@ class _FamilyCardsState extends State { : SizedBox( height: 4.h, ), - Spacer(), + SizedBox(height: 8.h), widget.isForWalletRecharge ? CustomButton( height: 40.h, From e4aba3a50470957d5335c91b1e2254f5592f69ac Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Tue, 6 Oct 2026 10:33:04 +0300 Subject: [PATCH 10/12] family file notification key changed --- lib/core/api_consts.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index d5053e3b..784704c3 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -6,7 +6,7 @@ import 'package:myfatoorah_flutter/myfatoorah_flutter.dart'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT @@ -316,7 +316,7 @@ class ApiConsts { static String googleCloudStorageENTranslationFileBaseURL = "https://storage.googleapis.com/hmg-patientapp-translations"; // ************ static values for Api **************** - static final double appVersionID = 22.1; + static final double appVersionID = 22.5; // static final double appVersionID = 50.7; static final int appChannelId = 3; @@ -328,7 +328,7 @@ class ApiConsts { static final String notificationCenterAppGUID = "SzFwWjI0TjhmSjZreDVsNmc3SDRSdWlxUG1h"; static final String notificationServiceGUID_Login = "D8BD5C76-4B50-4122-81D0-C3AA25DB08A2"; static final String notificationServiceGUID_Registration = "690D3595-A1E1-489A-B9AB-6270E83AD6ED"; - static final String notificationServiceGUID_FamilyFile = "420D7C25-9CEF-4BCB-9963-27D9ECF8484C"; + static final String notificationServiceGUID_FamilyFile = "318285E4-6221-4A66-8FAF-2265D2B4B24C"; } // PACKAGES and OFFERS From 5d4031e02dd8921230b90ebc3c3f4b0521c7da36 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 6 Oct 2026 11:33:39 +0300 Subject: [PATCH 11/12] Reschedule logic updated --- .../book_appointments/book_appointments_repo.dart | 6 +++--- .../book_appointments_view_model.dart | 10 +++++----- lib/features/my_appointments/my_appointments_repo.dart | 6 +++--- .../my_appointments/my_appointments_view_model.dart | 4 ++-- .../appointments/appointment_details_page.dart | 1 + 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/features/book_appointments/book_appointments_repo.dart b/lib/features/book_appointments/book_appointments_repo.dart index a705d84a..caf97cb8 100644 --- a/lib/features/book_appointments/book_appointments_repo.dart +++ b/lib/features/book_appointments/book_appointments_repo.dart @@ -37,7 +37,7 @@ abstract class BookAppointmentsRepo { Future>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare, {bool continueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}); - Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); + Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false}); Future>> insertSpecificAppointment( {required int docID, @@ -483,12 +483,12 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo { } @override - Future> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}) async { + Future> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false}) async { Map requestBody = { "AppointmentID": patientAppointmentHistoryResponseModel.appointmentNo, "ClinicID": patientAppointmentHistoryResponseModel.clinicID, "ProjectID": patientAppointmentHistoryResponseModel.projectID, - "CancelToReschadual": false, + "CancelToReschadual": isReschedule, "EndTime": patientAppointmentHistoryResponseModel.endTime, "StartTime": patientAppointmentHistoryResponseModel.startTime, "DoctorID": patientAppointmentHistoryResponseModel.doctorID, diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index a4530eee..5865a829 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -948,8 +948,8 @@ class BookAppointmentsViewModel extends ChangeNotifier { ); } - Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); + Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: isReschedule); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -1011,7 +1011,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { appointmentDate: apiResponse.data["SameClinicApptList"][0]['AppointmentDate'], ); - await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async { + await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: true).then((val) async { // LoaderBottomSheet.hideLoader(); Future.delayed(Duration(milliseconds: 50)).then((value) async {}); // LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingYourAppointment.tr()); @@ -1069,7 +1069,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { // loadingText: LocaleKeys.reschedulingAppo.tr(context: navigationService.navigatorKey.currentContext!), loadingText: LocaleKeys.loadingText.tr(context: navigationService.navigatorKey.currentContext!), ); - await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async { + await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: true).then((val) async { LoaderBottomSheet.hideLoader(); Future.delayed(Duration(milliseconds: 50)).then((value) async {}); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingYourAppointment.tr()); @@ -1174,7 +1174,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { isCloseButtonVisible: false, isDismissible: false, isFullScreen: false); - await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async { + await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: true).then((val) async { navigationService.pop(); Future.delayed(Duration(milliseconds: 50)).then((value) async {}); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.bookingYourAppointment.tr()); diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart index 87fb2ec2..ef3cd283 100644 --- a/lib/features/my_appointments/my_appointments_repo.dart +++ b/lib/features/my_appointments/my_appointments_repo.dart @@ -44,7 +44,7 @@ abstract class MyAppointmentsRepo { Future>> generateAppointmentQR({required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp}); - Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); + Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false}); Future>> confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); @@ -341,12 +341,12 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { } @override - Future> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}) async { + Future> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false}) async { Map requestBody = { "AppointmentID": patientAppointmentHistoryResponseModel.appointmentNo, "ClinicID": patientAppointmentHistoryResponseModel.clinicID, "ProjectID": patientAppointmentHistoryResponseModel.projectID, - "CancelToReschadual": false, + "CancelToReschadual": isReschedule, "EndTime": patientAppointmentHistoryResponseModel.endTime, "StartTime": patientAppointmentHistoryResponseModel.startTime, "DoctorID": patientAppointmentHistoryResponseModel.doctorID, diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index b2b990db..f040fd82 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -639,8 +639,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { ); } - Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); + Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, bool isReschedule = false, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, isReschedule: isReschedule); result.fold( // (failure) async => await errorHandlerService.handleError(failure: failure), diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 7d1d3f91..874c97c6 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -338,6 +338,7 @@ class _AppointmentDetailsPageState extends State { myAppointmentsViewModel.updateListWRTTab(0); await myAppointmentsViewModel.cancelAppointment( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, + isReschedule: false, onSuccess: (apiResponse) async { LoaderBottomSheet.hideLoader(); myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); From b68bf1d3219c5b090f8df658a24dd928dbce0ba9 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 6 Oct 2026 15:40:18 +0300 Subject: [PATCH 12/12] Apple Pay payfort response API Added --- lib/core/api/api_client.dart | 4 +- lib/features/payfort/payfort_view_model.dart | 23 +++++ .../appointment_payment_page.dart | 85 +++++++++++++++++++ .../immediate_livecare_payment_page.dart | 2 + .../waiting_appointment_payment_page.dart | 2 + .../wallet_payment_confirm_page.dart | 2 + .../medical_file/medical_file_page.dart | 2 +- .../ancillary_order_payment_page.dart | 2 + lib/splashPage.dart | 2 +- 9 files changed, 120 insertions(+), 4 deletions(-) diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 00eebb34..0bc0211a 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -209,8 +209,8 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - body['TokenID'] = "@dm!n"; - // body['PatientID'] = 7000792; + // body['TokenID'] = "@dm!n"; + // body['PatientID'] = 1009156; // body['PatientID'] = 53320; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; diff --git a/lib/features/payfort/payfort_view_model.dart b/lib/features/payfort/payfort_view_model.dart index c4f96857..7b6b8b7d 100644 --- a/lib/features/payfort/payfort_view_model.dart +++ b/lib/features/payfort/payfort_view_model.dart @@ -578,4 +578,27 @@ class PayfortViewModel extends ChangeNotifier { ); } + Future addApplePayPayfortResponse(dynamic paymentMap) async { + PayfortResponseInsertModel payfortResponseInsertModel = PayfortResponseInsertModel(); + + payfortResponseInsertModel.fortId = paymentMap['fort_id'] ?? ""; + payfortResponseInsertModel.commandType = paymentMap['command'] ?? ""; + payfortResponseInsertModel.amount = num.tryParse(paymentMap['amount'] ?? "0") ?? 0; + payfortResponseInsertModel.sadadOLP = ""; + payfortResponseInsertModel.paymentOption = paymentMap['payment_option'] ?? ""; + payfortResponseInsertModel.customerIP = paymentMap['customer_ip'] ?? ""; + payfortResponseInsertModel.eCI = paymentMap['eci'] ?? ""; + payfortResponseInsertModel.responseMessage = paymentMap['response_message'] ?? ""; + payfortResponseInsertModel.cardNumber = paymentMap['card_number'] ?? ""; + payfortResponseInsertModel.cardBin = paymentMap['card_bin'] ?? ""; + payfortResponseInsertModel.installmentsNumber = int.tryParse(paymentMap['installments_number'] ?? "0") ?? 0; + payfortResponseInsertModel.status = paymentMap['status'] ?? ""; + payfortResponseInsertModel.merchantRef = paymentMap['merchant_reference'] ?? ""; + payfortResponseInsertModel.isRefund = false; + payfortResponseInsertModel.remmeberMe = true; + payfortResponseInsertModel.reconciliationReference = ""; + + payfortResponseInsert(payfortResponseInsertModel: payfortResponseInsertModel); + } + } diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index 5b7e4c80..bef2df93 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -1283,6 +1283,7 @@ class _AppointmentPaymentPageState extends State { currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED", onFailed: (failureResult) async { log("failureResult: ${failureResult.message.toString()}"); + payfortViewModel.addApplePayPayfortResponse(failureResult.response); LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( context, @@ -1293,10 +1294,94 @@ class _AppointmentPaymentPageState extends State { ); }, onSucceeded: (successResult) async { + payfortViewModel.addApplePayPayfortResponse(successResult); LoaderBottomSheet.hideLoader(); log("successResult: ${successResult.responseMessage.toString()}"); selectedPaymentMethod = successResult.paymentOption ?? "VISA"; checkPaymentStatus(); + + // LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingPaymentStatusPleaseWait.tr(context: context)); + // await myAppointmentsViewModel.createAdvancePayment( + // paymentMethodName: selectedPaymentMethod, + // projectID: widget.patientAppointmentHistoryResponseModel.projectID, + // clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, + // appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), + // payedAmount: num.parse(myAppointmentsViewModel.patientAppointmentShareResponseModel!.patientShareWithTax!.toString()), + // paymentReference: successResult.fortId!, + // patientID: appState.getAuthenticatedUser()!.patientId.toString(), + // patientType: appState.getAuthenticatedUser()!.patientType!, + // onSuccess: (value) async { + // print(value); + // await myAppointmentsViewModel.addAdvanceNumberRequest( + // advanceNumber: Utils.isVidaPlusProject(widget.patientAppointmentHistoryResponseModel.projectID) + // ? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + // : value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + // paymentReference: successResult.fortId!, + // appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), + // onSuccess: (value) async { + // if (widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!) { + // //TODO: Implement LiveCare Check-In API Call + // await myAppointmentsViewModel.insertLiveCareVIDARequest( + // clientRequestID: transID, + // patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, + // onSuccess: (apiResponse) { + // Future.delayed(Duration(milliseconds: 500), () { + // myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + // myAppointmentsViewModel.initAppointmentsViewModel(); + // myAppointmentsViewModel.getPatientAppointments(true, false); + // + // getIt.get().setIsWalletAmountToBeLoaded(true); + // getIt.get().initHabibWalletProvider(); + // getIt.get().getPatientBalanceAmount(); + // + // LoaderBottomSheet.hideLoader(); + // Navigator.pushAndRemoveUntil( + // context, + // CustomPageRoute( + // page: LandingNavigation(), + // ), + // (r) => false); + // }); + // }, + // onError: (error) {}); + // } else { + // await myAppointmentsViewModel.generateAppointmentQR( + // clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, + // projectID: widget.patientAppointmentHistoryResponseModel.projectID, + // appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), + // isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!, + // onSuccess: (apiResponse) { + // Future.delayed(Duration(milliseconds: 500), () { + // myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + // myAppointmentsViewModel.initAppointmentsViewModel(); + // myAppointmentsViewModel.getPatientAppointments(true, false); + // + // getIt.get().setIsWalletAmountToBeLoaded(true); + // getIt.get().initHabibWalletProvider(); + // getIt.get().getPatientBalanceAmount(); + // + // LoaderBottomSheet.hideLoader(); + // Navigator.pushAndRemoveUntil( + // context, + // CustomPageRoute( + // page: LandingNavigation(), + // ), + // (r) => false); + // }); + // }); + // } + // }); + // }, + // onError: (err) { + // LoaderBottomSheet.hideLoader(); + // showCommonBottomSheetWithoutHeight( + // context, + // child: Utils.getErrorWidget(loadingText: err.toString()), + // callBackFunc: () {}, + // isFullScreen: false, + // isCloseButtonVisible: true, + // ); + // }); }, // projectId: appo.projectID, // serviceTypeEnum: ServiceTypeEnum.appointmentPayment, diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart index 9d30f976..b205063c 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart @@ -1077,6 +1077,7 @@ class _ImmediateLiveCarePaymentPageState extends State { currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED", onFailed: (failureResult) async { log("failureResult: ${failureResult.message.toString()}"); + payfortViewModel.addApplePayPayfortResponse(failureResult.response); showCommonBottomSheetWithoutHeight( context, child: Utils.getErrorWidget(loadingText: failureResult.message.toString()), @@ -678,6 +679,7 @@ class _WalletPaymentConfirmPageState extends State { }, onSucceeded: (successResult) async { log("successResult: ${successResult.responseMessage.toString()}"); + payfortViewModel.addApplePayPayfortResponse(successResult); selectedPaymentMethod = successResult.paymentOption ?? "VISA"; checkPaymentStatus(); }, diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 629ff15c..add423d8 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -280,7 +280,7 @@ class _MedicalFilePageState extends State { AppCustomChipWidget( icon: AppAssets.blood_icon, labelText: appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup, - iconColor: AppColors.primaryRedColor, + iconColor: AppColors.primaryRedColorBase, labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), padding: EdgeInsets.zero, ), diff --git a/lib/presentation/todo_section/ancillary_order_payment_page.dart b/lib/presentation/todo_section/ancillary_order_payment_page.dart index 365dff2b..e6665037 100644 --- a/lib/presentation/todo_section/ancillary_order_payment_page.dart +++ b/lib/presentation/todo_section/ancillary_order_payment_page.dart @@ -819,6 +819,7 @@ class _AncillaryOrderPaymentPageState extends State { applePayShaRequestPhrase: payfortViewModel.payfortProjectDetailsRespModel!.shaRequest, currency: appState.getAuthenticatedUser()!.outSa! == 0 ? "SAR" : "AED", onFailed: (failureResult) async { + payfortViewModel.addApplePayPayfortResponse(failureResult.response); log("failureResult: ${failureResult.message.toString()}"); LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( @@ -830,6 +831,7 @@ class _AncillaryOrderPaymentPageState extends State { ); }, onSucceeded: (successResult) async { + payfortViewModel.addApplePayPayfortResponse(successResult); LoaderBottomSheet.hideLoader(); log("successResult: ${successResult.responseMessage.toString()}"); selectedPaymentMethod = successResult.paymentOption ?? "VISA"; diff --git a/lib/splashPage.dart b/lib/splashPage.dart index 8ebe655e..88c247b6 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -93,7 +93,7 @@ class _SplashScreenState extends State { if (isAppOpenedFromCall) { navigateToTeleConsult(); } else { - if (Utils.havePrivilege(124)) { + if (!kDebugMode && Utils.havePrivilege(124)) { Navigator.of(getIt.get().navigatorKey.currentContext!).pushAndRemoveUntil(CustomPageRoute(page: AppClosedPage()), (r) => false); } else { if (await Utils.getBoolFromPrefs(CacheConst.firstLaunch)) {