diff --git a/assets/images/png/body_parts/female/abdomin.png b/assets/images/png/body_parts/female/abdomin.png
new file mode 100644
index 0000000..f4918d7
Binary files /dev/null and b/assets/images/png/body_parts/female/abdomin.png differ
diff --git a/assets/images/png/body_parts/female/anal.png b/assets/images/png/body_parts/female/anal.png
new file mode 100644
index 0000000..d96ef28
Binary files /dev/null and b/assets/images/png/body_parts/female/anal.png differ
diff --git a/assets/images/png/body_parts/female/axilla.png b/assets/images/png/body_parts/female/axilla.png
new file mode 100644
index 0000000..f38be6b
Binary files /dev/null and b/assets/images/png/body_parts/female/axilla.png differ
diff --git a/assets/images/png/body_parts/female/back.png b/assets/images/png/body_parts/female/back.png
new file mode 100644
index 0000000..65d9ef1
Binary files /dev/null and b/assets/images/png/body_parts/female/back.png differ
diff --git a/assets/images/png/body_parts/female/bikini.png b/assets/images/png/body_parts/female/bikini.png
new file mode 100644
index 0000000..a1a6842
Binary files /dev/null and b/assets/images/png/body_parts/female/bikini.png differ
diff --git a/assets/images/png/body_parts/female/bikini_line.png b/assets/images/png/body_parts/female/bikini_line.png
new file mode 100644
index 0000000..12fc0e6
Binary files /dev/null and b/assets/images/png/body_parts/female/bikini_line.png differ
diff --git a/assets/images/png/body_parts/female/buttocks.png b/assets/images/png/body_parts/female/buttocks.png
new file mode 100644
index 0000000..b83576f
Binary files /dev/null and b/assets/images/png/body_parts/female/buttocks.png differ
diff --git a/assets/images/png/body_parts/female/cheeks.svg b/assets/images/png/body_parts/female/cheeks.svg
new file mode 100644
index 0000000..6305ce6
--- /dev/null
+++ b/assets/images/png/body_parts/female/cheeks.svg
@@ -0,0 +1,130 @@
+
diff --git a/assets/images/png/body_parts/female/chest.png b/assets/images/png/body_parts/female/chest.png
new file mode 100644
index 0000000..727ebe7
Binary files /dev/null and b/assets/images/png/body_parts/female/chest.png differ
diff --git a/assets/images/png/body_parts/female/chest_line.png b/assets/images/png/body_parts/female/chest_line.png
new file mode 100644
index 0000000..0b4fecb
Binary files /dev/null and b/assets/images/png/body_parts/female/chest_line.png differ
diff --git a/assets/images/png/body_parts/female/chin.svg b/assets/images/png/body_parts/female/chin.svg
new file mode 100644
index 0000000..37da45b
--- /dev/null
+++ b/assets/images/png/body_parts/female/chin.svg
@@ -0,0 +1,129 @@
+
diff --git a/assets/images/png/body_parts/female/ears.svg b/assets/images/png/body_parts/female/ears.svg
new file mode 100644
index 0000000..758a69e
--- /dev/null
+++ b/assets/images/png/body_parts/female/ears.svg
@@ -0,0 +1,130 @@
+
diff --git a/assets/images/png/body_parts/female/eyebrows.svg b/assets/images/png/body_parts/female/eyebrows.svg
new file mode 100644
index 0000000..9657daa
--- /dev/null
+++ b/assets/images/png/body_parts/female/eyebrows.svg
@@ -0,0 +1,130 @@
+
diff --git a/assets/images/png/body_parts/female/full_body_female.png b/assets/images/png/body_parts/female/full_body_female.png
new file mode 100644
index 0000000..fb6a375
Binary files /dev/null and b/assets/images/png/body_parts/female/full_body_female.png differ
diff --git a/assets/images/png/body_parts/female/full_legs.png b/assets/images/png/body_parts/female/full_legs.png
new file mode 100644
index 0000000..5a365a7
Binary files /dev/null and b/assets/images/png/body_parts/female/full_legs.png differ
diff --git a/assets/images/png/body_parts/female/full_neck.svg b/assets/images/png/body_parts/female/full_neck.svg
new file mode 100644
index 0000000..f73f07f
--- /dev/null
+++ b/assets/images/png/body_parts/female/full_neck.svg
@@ -0,0 +1,129 @@
+
diff --git a/assets/images/png/body_parts/female/half_neck.svg b/assets/images/png/body_parts/female/half_neck.svg
new file mode 100644
index 0000000..78e4cfa
--- /dev/null
+++ b/assets/images/png/body_parts/female/half_neck.svg
@@ -0,0 +1,129 @@
+
diff --git a/assets/images/png/body_parts/female/hydra_facial.svg b/assets/images/png/body_parts/female/hydra_facial.svg
new file mode 100644
index 0000000..6a46821
--- /dev/null
+++ b/assets/images/png/body_parts/female/hydra_facial.svg
@@ -0,0 +1,128 @@
+
diff --git a/assets/images/png/body_parts/female/lower_arm.png b/assets/images/png/body_parts/female/lower_arm.png
new file mode 100644
index 0000000..717b2cd
Binary files /dev/null and b/assets/images/png/body_parts/female/lower_arm.png differ
diff --git a/assets/images/png/body_parts/female/lower_leg.png b/assets/images/png/body_parts/female/lower_leg.png
new file mode 100644
index 0000000..88ccace
Binary files /dev/null and b/assets/images/png/body_parts/female/lower_leg.png differ
diff --git a/assets/images/png/body_parts/female/shoulders.png b/assets/images/png/body_parts/female/shoulders.png
new file mode 100644
index 0000000..e1f253a
Binary files /dev/null and b/assets/images/png/body_parts/female/shoulders.png differ
diff --git a/assets/images/png/body_parts/female/side_burn.svg b/assets/images/png/body_parts/female/side_burn.svg
new file mode 100644
index 0000000..123216e
--- /dev/null
+++ b/assets/images/png/body_parts/female/side_burn.svg
@@ -0,0 +1,130 @@
+
diff --git a/assets/images/png/body_parts/female/upper_arm.png b/assets/images/png/body_parts/female/upper_arm.png
new file mode 100644
index 0000000..1edb873
Binary files /dev/null and b/assets/images/png/body_parts/female/upper_arm.png differ
diff --git a/assets/images/png/body_parts/female/upper_legs.png b/assets/images/png/body_parts/female/upper_legs.png
new file mode 100644
index 0000000..a8aa2ec
Binary files /dev/null and b/assets/images/png/body_parts/female/upper_legs.png differ
diff --git a/assets/images/png/body_parts/female/upper_lips.svg b/assets/images/png/body_parts/female/upper_lips.svg
new file mode 100644
index 0000000..7204337
--- /dev/null
+++ b/assets/images/png/body_parts/female/upper_lips.svg
@@ -0,0 +1,129 @@
+
diff --git a/assets/images/png/body_parts/male/abdomin.png b/assets/images/png/body_parts/male/abdomin.png
new file mode 100644
index 0000000..1b180b4
Binary files /dev/null and b/assets/images/png/body_parts/male/abdomin.png differ
diff --git a/assets/images/png/body_parts/male/axilla.png b/assets/images/png/body_parts/male/axilla.png
new file mode 100644
index 0000000..61af949
Binary files /dev/null and b/assets/images/png/body_parts/male/axilla.png differ
diff --git a/assets/images/png/body_parts/male/back.png b/assets/images/png/body_parts/male/back.png
new file mode 100644
index 0000000..224147e
Binary files /dev/null and b/assets/images/png/body_parts/male/back.png differ
diff --git a/assets/images/png/body_parts/male/back.svg b/assets/images/png/body_parts/male/back.svg
new file mode 100644
index 0000000..7d9aeb4
--- /dev/null
+++ b/assets/images/png/body_parts/male/back.svg
@@ -0,0 +1,188 @@
+
diff --git a/assets/images/png/body_parts/male/bikini.png b/assets/images/png/body_parts/male/bikini.png
new file mode 100644
index 0000000..aa98ea7
Binary files /dev/null and b/assets/images/png/body_parts/male/bikini.png differ
diff --git a/assets/images/png/body_parts/male/bikini_line.png b/assets/images/png/body_parts/male/bikini_line.png
new file mode 100644
index 0000000..60ed64e
Binary files /dev/null and b/assets/images/png/body_parts/male/bikini_line.png differ
diff --git a/assets/images/png/body_parts/male/cheek.svg b/assets/images/png/body_parts/male/cheek.svg
new file mode 100644
index 0000000..984a59f
--- /dev/null
+++ b/assets/images/png/body_parts/male/cheek.svg
@@ -0,0 +1,87 @@
+
diff --git a/assets/images/png/body_parts/male/chest.png b/assets/images/png/body_parts/male/chest.png
new file mode 100644
index 0000000..b7cec07
Binary files /dev/null and b/assets/images/png/body_parts/male/chest.png differ
diff --git a/assets/images/png/body_parts/male/chest_line.png b/assets/images/png/body_parts/male/chest_line.png
new file mode 100644
index 0000000..41e779f
Binary files /dev/null and b/assets/images/png/body_parts/male/chest_line.png differ
diff --git a/assets/images/png/body_parts/male/chin.svg b/assets/images/png/body_parts/male/chin.svg
new file mode 100644
index 0000000..9fdee93
--- /dev/null
+++ b/assets/images/png/body_parts/male/chin.svg
@@ -0,0 +1,86 @@
+
diff --git a/assets/images/png/body_parts/male/ears.svg b/assets/images/png/body_parts/male/ears.svg
new file mode 100644
index 0000000..1c9600c
--- /dev/null
+++ b/assets/images/png/body_parts/male/ears.svg
@@ -0,0 +1,87 @@
+
diff --git a/assets/images/png/body_parts/male/eyebrows.svg b/assets/images/png/body_parts/male/eyebrows.svg
new file mode 100644
index 0000000..ea38523
--- /dev/null
+++ b/assets/images/png/body_parts/male/eyebrows.svg
@@ -0,0 +1,87 @@
+
diff --git a/assets/images/png/body_parts/male/full_body_male.png b/assets/images/png/body_parts/male/full_body_male.png
new file mode 100644
index 0000000..df30472
Binary files /dev/null and b/assets/images/png/body_parts/male/full_body_male.png differ
diff --git a/assets/images/png/body_parts/male/full_legs.png b/assets/images/png/body_parts/male/full_legs.png
new file mode 100644
index 0000000..eee2fa0
Binary files /dev/null and b/assets/images/png/body_parts/male/full_legs.png differ
diff --git a/assets/images/png/body_parts/male/full_neck.png b/assets/images/png/body_parts/male/full_neck.png
new file mode 100644
index 0000000..a75159f
Binary files /dev/null and b/assets/images/png/body_parts/male/full_neck.png differ
diff --git a/assets/images/png/body_parts/male/full_neck.svg b/assets/images/png/body_parts/male/full_neck.svg
new file mode 100644
index 0000000..33b755e
--- /dev/null
+++ b/assets/images/png/body_parts/male/full_neck.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/png/body_parts/male/half_neck.png b/assets/images/png/body_parts/male/half_neck.png
new file mode 100644
index 0000000..5ee0249
Binary files /dev/null and b/assets/images/png/body_parts/male/half_neck.png differ
diff --git a/assets/images/png/body_parts/male/half_neck.svg b/assets/images/png/body_parts/male/half_neck.svg
new file mode 100644
index 0000000..26b6bc3
--- /dev/null
+++ b/assets/images/png/body_parts/male/half_neck.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/png/body_parts/male/hydra_facial.svg b/assets/images/png/body_parts/male/hydra_facial.svg
new file mode 100644
index 0000000..1051630
--- /dev/null
+++ b/assets/images/png/body_parts/male/hydra_facial.svg
@@ -0,0 +1,85 @@
+
diff --git a/assets/images/png/body_parts/male/lower_arm.png b/assets/images/png/body_parts/male/lower_arm.png
new file mode 100644
index 0000000..120242e
Binary files /dev/null and b/assets/images/png/body_parts/male/lower_arm.png differ
diff --git a/assets/images/png/body_parts/male/lower_legs.png b/assets/images/png/body_parts/male/lower_legs.png
new file mode 100644
index 0000000..8367aa8
Binary files /dev/null and b/assets/images/png/body_parts/male/lower_legs.png differ
diff --git a/assets/images/png/body_parts/male/shoulders.png b/assets/images/png/body_parts/male/shoulders.png
new file mode 100644
index 0000000..907f2dd
Binary files /dev/null and b/assets/images/png/body_parts/male/shoulders.png differ
diff --git a/assets/images/png/body_parts/male/side_burn.svg b/assets/images/png/body_parts/male/side_burn.svg
new file mode 100644
index 0000000..156b30f
--- /dev/null
+++ b/assets/images/png/body_parts/male/side_burn.svg
@@ -0,0 +1,87 @@
+
diff --git a/assets/images/png/body_parts/male/upper_arm.png b/assets/images/png/body_parts/male/upper_arm.png
new file mode 100644
index 0000000..f80a75d
Binary files /dev/null and b/assets/images/png/body_parts/male/upper_arm.png differ
diff --git a/assets/images/png/body_parts/male/upper_legs.png b/assets/images/png/body_parts/male/upper_legs.png
new file mode 100644
index 0000000..e0c973b
Binary files /dev/null and b/assets/images/png/body_parts/male/upper_legs.png differ
diff --git a/assets/images/png/body_parts/male/upper_lips.svg b/assets/images/png/body_parts/male/upper_lips.svg
new file mode 100644
index 0000000..b7ae6e0
--- /dev/null
+++ b/assets/images/png/body_parts/male/upper_lips.svg
@@ -0,0 +1,86 @@
+
diff --git a/assets/images/png/dummy_user.png b/assets/images/png/dummy_user.png
new file mode 100644
index 0000000..b4bace4
Binary files /dev/null and b/assets/images/png/dummy_user.png differ
diff --git a/assets/images/svg/active-check.svg b/assets/images/svg/active-check.svg
new file mode 100644
index 0000000..c94a3a0
--- /dev/null
+++ b/assets/images/svg/active-check.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/alert-square.svg b/assets/images/svg/alert-square.svg
new file mode 100644
index 0000000..87b52e3
--- /dev/null
+++ b/assets/images/svg/alert-square.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/arrow-right.svg b/assets/images/svg/arrow-right.svg
new file mode 100644
index 0000000..8818d72
--- /dev/null
+++ b/assets/images/svg/arrow-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/delete_icon.svg b/assets/images/svg/delete_icon.svg
new file mode 100644
index 0000000..2e37d0d
--- /dev/null
+++ b/assets/images/svg/delete_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/switch_user.svg b/assets/images/svg/switch_user.svg
new file mode 100644
index 0000000..fa8e47e
--- /dev/null
+++ b/assets/images/svg/switch_user.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json
index 811a1af..787a718 100644
--- a/assets/langs/ar-SA.json
+++ b/assets/langs/ar-SA.json
@@ -874,5 +874,7 @@
"to": "إلى",
"startDate": "تاريخ البدء",
"endDate": "تاريخ الانتهاء",
- "walkin": "زيارة بدون موعد"
+ "walkin": "زيارة بدون موعد",
+ "laserClinic": "عيادة الليزر",
+ "continueString": "يكمل"
}
\ No newline at end of file
diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json
index 336c06c..7b8c4b8 100644
--- a/assets/langs/en-US.json
+++ b/assets/langs/en-US.json
@@ -685,8 +685,8 @@
"body": "Body Mass",
"bodyString": "Body",
"face": "Face",
- "retouch": "روتوش",
- "bikini": "بيكيني",
+ "retouch": "Re-touch",
+ "bikini": "Bikini",
"totalMinutes": "Total Minutes",
"feedback": "Feedback",
"send": "أرسل",
@@ -870,6 +870,8 @@
"clearAllFilters": "Clear all filters",
"filters": "Filters",
"searchClinic": "Search Clinic",
- "walkin": "Walk In"
+ "walkin": "Walk In",
+ "continueString": "Continue",
+ "laserClinic": "Laser Clinic"
}
\ No newline at end of file
diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart
index cd7b673..24f682b 100644
--- a/lib/core/api/api_client.dart
+++ b/lib/core/api/api_client.dart
@@ -88,16 +88,16 @@ class ApiClientImp implements ApiClient {
@override
post(
- String endPoint, {
- required Map body,
- required Function(dynamic response, int statusCode, {int? messageStatus, String? errorMessage}) onSuccess,
- required Function(String error, int statusCode, {int? messageStatus, Failure? failureType}) onFailure,
- bool isAllowAny = false,
- bool isExternal = false,
- bool isRCService = false,
- bool isPaymentServices = false,
- bool bypassConnectionCheck = false,
- }) async {
+ String endPoint, {
+ required Map body,
+ required Function(dynamic response, int statusCode, {int? messageStatus, String? errorMessage}) onSuccess,
+ required Function(String error, int statusCode, {int? messageStatus, Failure? failureType}) onFailure,
+ bool isAllowAny = false,
+ bool isExternal = false,
+ bool isRCService = false,
+ bool isPaymentServices = false,
+ bool bypassConnectionCheck = false,
+ }) async {
String url;
if (isExternal) {
url = endPoint;
@@ -173,8 +173,8 @@ class ApiClientImp implements ApiClient {
body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken;
}
- body['TokenID'] = "@dm!n";
- body['PatientID'] = 4767884;
+ // body['TokenID'] = "@dm!n";
+ // body['PatientID'] = 4772172;
// body['PatientTypeID'] = 1;
//
// body['PatientOutSA'] = 0;
diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart
index 511cb37..9591cfe 100644
--- a/lib/core/api_consts.dart
+++ b/lib/core/api_consts.dart
@@ -727,7 +727,7 @@ const FAMILY_FILES= 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatu
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
@@ -745,6 +745,7 @@ class ApiConsts {
static String TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
static String GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
+ static String GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
// static String GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
@@ -760,6 +761,7 @@ class ApiConsts {
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
+ GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
break;
case AppEnvironmentTypeEnum.dev:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -768,6 +770,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
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=';
break;
case AppEnvironmentTypeEnum.uat:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -776,6 +779,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
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=';
break;
case AppEnvironmentTypeEnum.preProd:
@@ -785,6 +789,7 @@ class ApiConsts {
SERVICE_URL = "https://hmgwebservices.com/PayFortWebLive/pages/SendPayFortRequest.aspx";
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=';
break;
case AppEnvironmentTypeEnum.qa:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -793,6 +798,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
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=';
break;
case AppEnvironmentTypeEnum.staging:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -801,6 +807,7 @@ class ApiConsts {
SERVICE_URL = 'https://hmgwebservices.com/PayFortWeb/pages/SendPayFortRequest.aspx';
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=';
break;
}
}
@@ -825,6 +832,13 @@ class ApiConsts {
static final String registerUser = 'Services/Authentication.svc/REST/PatientRegistration';
static final String addFamilyFile = 'Services/Patients.svc/REST/ShareFamilyFileService';
+ static final String sendFamilyFileActivation = 'Services/Authentication.svc/REST/SendActivationCodeForFamilyFile';
+ static final String checkActivationCodeForFamily = 'Services/Authentication.svc/REST/CheckActivationCodeForFamilyFile';
+ static final String getAllPendingRecordsByResponseId = 'Services/Authentication.svc/REST/GetAllPendingRecordsByResponseId';
+ static final String getAllSharedRecordsByStatus = 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatus';
+ static final String removeFileFromFamilyMembers = 'Services/Authentication.svc/REST/ActiveDeactive_PatientFile';
+ static final String acceptAndRejectFamilyFile = 'Services/Authentication.svc/REST/Update_FileStatus';
+
// static values for Api
static final double appVersionID = 18.7;
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index d1b8b93..1e9eaa4 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -152,6 +152,9 @@ class AppAssets {
static const String ic_filters = '$svgBasePath/filters.svg';
static const String ic_close = '$svgBasePath/ic_close.svg';
static const String ic_cross_circle = '$svgBasePath/cross_circle.svg';
+ static const String switch_user = '$svgBasePath/switch_user.svg';
+ static const String activeCheck = '$svgBasePath/active-check.svg';
+ static const String deleteIcon = '$svgBasePath/delete_icon.svg';
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';
@@ -163,6 +166,8 @@ class AppAssets {
static const String feedback = '$svgBasePath/feedback.svg';
static const String news = '$svgBasePath/news.svg';
static const String heart = '$svgBasePath/heart.svg';
+ static const String alertSquare = '$svgBasePath/alert-square.svg';
+ static const String arrowRight = '$svgBasePath/arrow-right.svg';
// PNGS //
static const String hmg_logo = '$pngBasePath/hmg_logo.png';
@@ -177,6 +182,7 @@ class AppAssets {
static const String tamara_en = '$pngBasePath/tamara_en.png';
static const String visa = '$pngBasePath/visa.png';
static const String lockIcon = '$pngBasePath/lock-icon.png';
+ static const String dummy_user = '$pngBasePath/dummy_user.png';
}
class AppAnimations {
diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart
index c906374..404e22b 100644
--- a/lib/core/app_state.dart
+++ b/lib/core/app_state.dart
@@ -37,14 +37,16 @@ class AppState {
AuthenticatedUser? _authenticatedRootUser;
AuthenticatedUser? _authenticatedChildUser;
- void setAuthenticatedUser(AuthenticatedUser authenticatedUser, {bool isFamily = false}) {
+ int? _superUserID;
+ bool isChildLoggedIn = false;
+
+ void setAuthenticatedUser(AuthenticatedUser? authenticatedUser, {bool isFamily = false}) {
if (isFamily) {
_authenticatedChildUser = authenticatedUser;
} else {
setIsAuthenticated = true;
_authenticatedRootUser = authenticatedUser;
}
-
}
AuthenticatedUser? getAuthenticatedUser({bool isFamily = false}) {
@@ -55,6 +57,14 @@ class AppState {
}
}
+ int? get getSuperUserID => _superUserID;
+
+ bool get getIsChildLoggedIn => isChildLoggedIn;
+
+ set setSuperUserID(int? value) => _superUserID = value;
+
+ set setIsChildLoggedIn(bool value) => isChildLoggedIn = value;
+
String _userBloodGroup = "";
String get getUserBloodGroup => _userBloodGroup;
@@ -97,6 +107,14 @@ class AppState {
set setDeviceTypeID(v) => deviceTypeID = v;
+ String _familyFileTokenID = "";
+
+ String get getFamilyFileTokenID => _familyFileTokenID;
+
+ set setFamilyFileTokenID(String value) {
+ _familyFileTokenID = value;
+ }
+
List vidaPlusProjectList = [];
List privilegeModelList = [];
List hMCProjectListModel = [];
@@ -135,9 +153,8 @@ class AppState {
}
///this will be called if there is any problem in getting the user location
- void resetLocation(){
+ void resetLocation() {
userLong = 0.0;
userLong = 0.0;
}
-
}
diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart
index f2f6183..7337dfa 100644
--- a/lib/core/dependencies.dart
+++ b/lib/core/dependencies.dart
@@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/features/authentication/authentication_view_
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/common/common_repo.dart';
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_repo.dart';
@@ -18,12 +19,14 @@ import 'package:hmg_patient_app_new/features/lab/lab_repo.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_repo.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
+import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_repo.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart';
import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart';
@@ -34,6 +37,7 @@ import 'package:hmg_patient_app_new/services/firebase_service.dart';
import 'package:hmg_patient_app_new/services/localauth_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
+import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart';
import 'package:local_auth/local_auth.dart';
import 'package:logger/web.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -100,11 +104,7 @@ class AppDependencies {
// Global/shared VMs → LazySingleton
getIt.registerLazySingleton(
- () => LabViewModel(
- labRepo: getIt(),
- errorHandlerService: getIt(),
- navigationService: getIt()
- ),
+ () => LabViewModel(labRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()),
);
getIt.registerLazySingleton(
@@ -154,7 +154,7 @@ class AppDependencies {
);
getIt.registerLazySingleton(
- () => BookAppointmentsViewModel(bookAppointmentsRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt(), myAppointmentsViewModel: getIt(), locationUtils: getIt()),
+ () => BookAppointmentsViewModel(bookAppointmentsRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt(), myAppointmentsViewModel: getIt(), locationUtils: getIt(), dialogService: getIt()),
);
getIt.registerLazySingleton(
@@ -165,11 +165,30 @@ class AppDependencies {
myAppointmentsViewModel: getIt(),
),
);
+ getIt.registerLazySingleton(
+ () => AppointmentViaRegionViewmodel(
+ navigationService: getIt(),
+ appState: getIt(),
+ ),
+ );
getIt.registerLazySingleton(
() => AuthenticationViewModel(
authenticationRepo: getIt(), cacheService: getIt(), navigationService: getIt(), dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), localAuthService: getIt()),
);
+ getIt.registerLazySingleton(() => ProfileSettingsViewModel());
+
+ getIt.registerLazySingleton(
+ () => DateRangeSelectorRangeViewModel(),
+ );
+
+ getIt.registerLazySingleton(
+ () => DoctorFilterViewModel(),
+ );
+
+ getIt.registerLazySingleton(
+ () => AppointmentViaRegionViewmodel(navigationService: getIt(), appState: getIt()),
+ );
// Screen-specific VMs → Factory
// getIt.registerFactory(
diff --git a/lib/core/enums.dart b/lib/core/enums.dart
index bb6c6fe..4151bed 100644
--- a/lib/core/enums.dart
+++ b/lib/core/enums.dart
@@ -30,6 +30,8 @@ enum LoginTypeEnum { sms, whatsapp, face, fingerprint }
enum AppEnvironmentTypeEnum { dev, uat, preProd, qa, staging, prod }
+enum FamilyFileEnum { active, inactive, blocked, deleted, pending, rejected }
+
extension CalenderExtension on CalenderEnum {
int get toInt {
switch (this) {
@@ -138,6 +140,61 @@ extension OTPTypeEnumExtension on OTPTypeEnum {
}
}
+extension FamilyFileEnumExtenshion on FamilyFileEnum {
+ int get toInt {
+ switch (this) {
+ case FamilyFileEnum.active:
+ return 3;
+ case FamilyFileEnum.blocked:
+ return 1;
+ case FamilyFileEnum.deleted:
+ return 0;
+ case FamilyFileEnum.pending:
+ return 2;
+ case FamilyFileEnum.inactive:
+ return 6;
+ case FamilyFileEnum.rejected:
+ return 4;
+ }
+ }
+
+ String get displayName {
+ AppState appState = getIt.get();
+ bool isArabic = appState.getLanguageID() == 1 ? true : false;
+ switch (this) {
+ case FamilyFileEnum.active:
+ return isArabic ? 'نشط' : 'Active';
+ case FamilyFileEnum.inactive:
+ return isArabic ? 'غير نشط' : 'Inactive';
+ case FamilyFileEnum.blocked:
+ return isArabic ? 'محظور' : 'Blocked';
+ case FamilyFileEnum.deleted:
+ return isArabic ? 'محذوف' : 'Deleted';
+ case FamilyFileEnum.pending:
+ return isArabic ? 'قيد الانتظار' : 'Pending';
+ case FamilyFileEnum.rejected:
+ return isArabic ? 'مرفوض' : 'Rejected';
+ }
+ }
+
+ static FamilyFileEnum? fromValue(int value) {
+ switch (value) {
+ case 0:
+ return FamilyFileEnum.pending;
+ case 2:
+ return FamilyFileEnum.blocked;
+ case 1:
+ return FamilyFileEnum.deleted;
+ case 3:
+ return FamilyFileEnum.active;
+ case 4:
+ return FamilyFileEnum.inactive;
+ default:
+ return null;
+ }
+ }
+}
+
enum ServiceTypeEnum {
advancePayment, //3
ancillaryOrder, //3
diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart
index 1eb3d9f..2fbbd09 100644
--- a/lib/core/utils/date_util.dart
+++ b/lib/core/utils/date_util.dart
@@ -485,3 +485,11 @@ class DateUtil {
return "";
}
}
+
+
+extension OnlyDate on DateTime{
+
+ DateTime provideDateOnly(){
+ return DateTime(this.year, month, day);
+ }
+}
\ No newline at end of file
diff --git a/lib/core/utils/request_utils.dart b/lib/core/utils/request_utils.dart
index 8b993f1..a4ea936 100644
--- a/lib/core/utils/request_utils.dart
+++ b/lib/core/utils/request_utils.dart
@@ -9,6 +9,7 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/registration_payload_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/send_activation_request_model.dart';
import 'package:hmg_patient_app_new/features/common/models/commong_authanticated_req_model.dart';
+import 'package:hmg_patient_app_new/features/common/models/family_file_request.dart';
class RequestUtils {
static dynamic getPatientAuthenticationRequest({
@@ -125,6 +126,9 @@ class RequestUtils {
required bool isForRegister,
required bool isFileNo,
dynamic payload,
+ required bool isExcludedUser,
+ required bool isFormFamilyFile,
+ int? responseID,
}) {
AppState _appState = getIt.get();
var request = SendActivationRequest();
@@ -156,6 +160,15 @@ class RequestUtils {
request.isRegister = false;
}
request.deviceTypeID = request.searchType;
+
+ if (isFormFamilyFile) {
+ //INFO: Only for Excluded User Family Member Addition
+ request.isPatientExcluded = isExcludedUser;
+ request.responseID = responseID;
+ request.status = 2;
+ request.familyRegionID = zipCode == CountryEnum.saudiArabia.countryCode ? 1 : 2;
+ }
+
return request;
}
@@ -247,19 +260,29 @@ class RequestUtils {
};
}
- static dynamic getAddFamilyRequest({required String nationalIDorFile, required String mobileNo, required String countryCode, required int loginType}) {
- var request = {};
+ static Future getAddFamilyRequest({required String nationalIDorFile, required String mobileNo, required String countryCode}) async {
+ FamilyFileRequest request = FamilyFileRequest();
+ int? loginType = 0;
+
+ if (countryCode == CountryEnum.saudiArabia.countryCode || countryCode == '+966') {
+ loginType = (nationalIDorFile.length == 10) ? 1 : 2;
+ } else if (countryCode == CountryEnum.unitedArabEmirates.countryCode || countryCode == '+971') {
+ loginType = (nationalIDorFile.length == 15) ? 1 : 2;
+ }
+
if (loginType == 1) {
- request["sharedPatientID"] = 0;
- request["sharedPatientIdentificationID"] = nationalIDorFile;
+ request.sharedPatientId = 0;
+ request.sharedPatientIdentificationId = nationalIDorFile;
} else if (loginType == 2) {
- request["sharedPatientID"] = int.parse(nationalIDorFile);
- request["sharedPatientIdentificationID"] = '';
+ request.sharedPatientId = int.parse(nationalIDorFile);
+ request.sharedPatientIdentificationId = '';
}
- request["searchType"] = loginType;
- request["sharedPatientMobileNumber"] = mobileNo;
- request["zipCode"] = countryCode;
- request["isRegister"] = false;
- request["patientStatus"] = 2;
+ request.searchType = loginType;
+ request.sharedPatientMobileNumber = mobileNo;
+ request.zipCode = countryCode;
+ request.isRegister = false;
+ request.patientStatus = 2;
+ request.isDentalAllowedBackend = false;
+ return request;
}
}
diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart
index 6ad1835..e569021 100644
--- a/lib/core/utils/size_utils.dart
+++ b/lib/core/utils/size_utils.dart
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; // These are the Viewport values of your Figma Design.
// These are used in the code as a reference to create your UI Responsively.
-const num FIGMA_DESIGN_WIDTH = 375;
-const num FIGMA_DESIGN_HEIGHT = 667;
+final num FIGMA_DESIGN_WIDTH = SizeUtils.width;
+final num FIGMA_DESIGN_HEIGHT = SizeUtils.height;
const num FIGMA_DESIGN_STATUS_BAR = 0;
extension ResponsiveExtension on num {
@@ -70,10 +70,10 @@ class SizeUtils {
static late DeviceType deviceType;
/// Device's Height
- static late double height;
+ static double height = 667;
/// Device's Width
- static late double width;
+ static double width = 375;
static void setScreenSize(
BoxConstraints constraints,
diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart
index 2bff2ac..c4a2db8 100644
--- a/lib/core/utils/utils.dart
+++ b/lib/core/utils/utils.dart
@@ -629,8 +629,17 @@ class Utils {
double width = 24,
double height = 24,
BoxFit fit = BoxFit.cover,
+ double? border,
+ double? borderRadius,
}) {
- return Image.asset(icon, width: width, height: height, fit: fit);
+ return Container(
+ decoration: BoxDecoration(
+ border: border != null ? Border.all(color: AppColors.whiteColor, width: border) : null,
+ borderRadius: border != null ? BorderRadius.circular(borderRadius ?? 0) : null,
+ ),
+ child: Image.asset(icon, width: width, height: height, fit: fit),
+ );
+ // return Image.asset(icon, width: width, height: height, fit: fit, );
}
/// Widget to build an SVG from network
@@ -757,4 +766,5 @@ class Utils {
}
return isHavePrivilege;
}
+
}
diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart
index 059e553..4432737 100644
--- a/lib/extensions/string_extensions.dart
+++ b/lib/extensions/string_extensions.dart
@@ -1,4 +1,6 @@
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/enums.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:auto_size_text/auto_size_text.dart';
@@ -365,7 +367,8 @@ extension DynamicTextStyleExtension on BuildContext {
TextBaseline? textBaseline,
FontStyle? fontStyle,
bool isLanguageSwitcher = false}) {
- final family = FontUtils.getFontFamilyForLanguage(false); // TODO: @Aamir make it dynamic based on app language
+ AppState appState = getIt.get();
+ final family = appState.getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins';
return TextStyle(
fontFamily: family,
fontSize: fontSize,
diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart
index 2eaeb80..bec5470 100644
--- a/lib/features/authentication/authentication_repo.dart
+++ b/lib/features/authentication/authentication_repo.dart
@@ -3,8 +3,10 @@ import 'dart:async';
import 'package:dartz/dartz.dart';
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/app_state.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/common_models/privilege/PrivilegeModel.dart';
+import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_activation_code_register_request_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart';
@@ -17,12 +19,18 @@ abstract class AuthenticationRepo {
Future>> checkPatientAuthentication({required dynamic checkPatientAuthenticationReq});
- Future>> sendActivationCodeRepo({required dynamic sendActivationCodeReq, String? languageID, bool isRegister = false});
+ Future>> sendActivationCodeRepo({required dynamic sendActivationCodeReq, String? languageID, bool isRegister = false, bool isFormFamilyFile = false});
Future>> checkActivationCodeRepo(
- {required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq
+ {required dynamic newRequest,
required String? activationCode,
- required bool isRegister});
+ required bool isRegister,
+ bool isFormFamilyFile = false,
+ int? patientShareRequestID,
+ int? responseID,
+ bool isSwitchUser = false,
+ int? patientID,
+ int? loginType});
Future>> checkIfUserAgreed({required dynamic commonAuthanticatedRequest});
@@ -134,18 +142,33 @@ class AuthenticationRepoImp implements AuthenticationRepo {
required dynamic sendActivationCodeReq,
String? languageID,
bool isRegister = false,
+ bool isFormFamilyFile = false,
}) async {
int isOutKsa = (sendActivationCodeReq.zipCode == '966' || sendActivationCodeReq.zipCode == '+966') ? 0 : 1;
sendActivationCodeReq.patientOutSA = isOutKsa;
sendActivationCodeReq.isDentalAllowedBackend = false;
+ final payload = sendActivationCodeReq.toJson();
+ if (isFormFamilyFile) {
+ payload.remove("MobileNo");
+ payload.remove("NationalID");
+ payload.remove("SMSSignature");
+ payload.remove("ResponseID");
+ print("=================== Final Payload ===================");
+ print(payload);
+ print("=====================================================");
+ }
try {
GenericApiModel? apiResponse;
Failure? failure;
await apiClient.post(
- isRegister ? ApiConsts.sendActivationCodeRegister : ApiConsts.sendActivationCode,
- body: sendActivationCodeReq.toJson(),
+ isFormFamilyFile
+ ? ApiConsts.sendFamilyFileActivation
+ : isRegister
+ ? ApiConsts.sendActivationCodeRegister
+ : ApiConsts.sendActivationCode,
+ body: isFormFamilyFile ? payload : sendActivationCodeReq.toJson(),
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
@@ -172,24 +195,122 @@ class AuthenticationRepoImp implements AuthenticationRepo {
}
@override
- Future>> checkActivationCodeRepo({
- required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq
- required String? activationCode,
- required bool isRegister,
- }) async {
+ Future>> checkActivationCodeRepo(
+ {required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq
+ required String? activationCode,
+ required bool isRegister,
+ bool isFormFamilyFile = false,
+ int? patientShareRequestID,
+ int? responseID,
+ bool isSwitchUser = false,
+ int? patientID,
+ int? loginType}) async {
+ AppState appState = getIt.get();
+ // if (isRegister) {
+ // newRequest["activationCode"] = activationCode ?? "0000";
+ // newRequest["isSilentLogin"] = activationCode != null ? false : true;
+ // } else {
+ // newRequest.activationCode = activationCode ?? "0000";
+ // newRequest.isSilentLogin = activationCode != null ? false : true;
+ // newRequest.projectOutSA = newRequest.zipCode == '966' ? false : true;
+ // newRequest.isDentalAllowedBackend = false;
+ // newRequest.forRegisteration = newRequest.isRegister ?? false;
+ // newRequest.isRegister = false;
+ // }
+ // Map familyRequest = {};
+ // if (isFormFamilyFile) {
+ // AppState appState = getIt.get();
+ // familyRequest = {};
+ // familyRequest['PatientShareRequestID'] = patientShareRequestID;
+ // familyRequest['ResponseID'] = responseID;
+ // familyRequest['Status'] = 3;
+ // familyRequest["PatientID"] = appState.getAuthenticatedUser()!.patientId ?? 0;
+ // familyRequest["LogInTokenID"] = appState.getFamilyFileTokenID;
+ // familyRequest["activationCode"] = activationCode ?? "0000";
+ // familyRequest["PatientMobileNumber"] = newRequest.patientMobileNumber;
+ // familyRequest["PatientIdentificationID"] = newRequest.patientIdentificationID;
+ // }
+ // Map switchRequest = {};
+ // if (isSwitchUser) {
+ // switchRequest = newRequest.toJson();
+ //
+ // switchRequest['PatientID'] = responseID;
+ // switchRequest['IsSilentLogin'] = true;
+ // switchRequest['LogInTokenID'] = null;
+ // switchRequest['SearchType'] = 2;
+ // if (loginType != 0) {
+ // switchRequest['SuperUser'] = patientID;
+ // switchRequest['DeviceToken'] = null;
+ // } else {
+ // switchRequest["LoginType"] = 2;
+ // }
+ //
+ // if (appState.getSuperUserID == responseID) {
+ // // switchRequest['LoginType'] = 3;
+ // switchRequest['PatientIdentificationID'] = "";
+ // // switchRequest['ProjectOutSA'] = newRequest.zipCode == '966' ? false : true;
+ // switchRequest.remove('NationalID');
+ // switchRequest.remove('isDentalAllowedBackend');
+ // switchRequest.remove('ProjectOutSA');
+ // switchRequest.remove('ForRegisteration');
+ // appState.setSuperUserID = null;
+ // }
+ // }
+
if (isRegister) {
newRequest["activationCode"] = activationCode ?? "0000";
- newRequest["isSilentLogin"] = activationCode != null ? false : true;
+ newRequest["isSilentLogin"] = activationCode == null;
} else {
newRequest.activationCode = activationCode ?? "0000";
- newRequest.isSilentLogin = activationCode != null ? false : true;
- newRequest.projectOutSA = newRequest.zipCode == '966' ? false : true;
+ newRequest.isSilentLogin = activationCode == null;
+ newRequest.projectOutSA = newRequest.zipCode != '966';
newRequest.isDentalAllowedBackend = false;
newRequest.forRegisteration = newRequest.isRegister ?? false;
newRequest.isRegister = false;
}
- final endpoint = isRegister ? ApiConsts.checkActivationCodeRegister : ApiConsts.checkActivationCode;
+ Map familyRequest = {};
+ if (isFormFamilyFile) {
+ familyRequest = {
+ 'PatientShareRequestID': patientShareRequestID,
+ 'ResponseID': responseID,
+ 'Status': 3,
+ // 'PatientID': appState.getAuthenticatedUser()?.patientId ?? 0,
+ 'LogInTokenID': appState.getFamilyFileTokenID,
+ 'activationCode': activationCode ?? "0000",
+ 'PatientMobileNumber': newRequest.patientMobileNumber,
+ 'PatientIdentificationID': newRequest.patientIdentificationID,
+ };
+ }
+
+ Map switchRequest = {};
+ if (isSwitchUser) {
+ switchRequest = newRequest.toJson();
+ switchRequest.addAll({
+ 'PatientID': responseID,
+ 'IsSilentLogin': true,
+ 'LogInTokenID': null,
+ 'SearchType': 2,
+ });
+
+ if (loginType != 0) {
+ switchRequest['SuperUser'] = patientID;
+ switchRequest['DeviceToken'] = null;
+ } else {
+ switchRequest['LoginType'] = 2;
+ }
+
+ if (appState.getSuperUserID == responseID) {
+ switchRequest['PatientIdentificationID'] = "";
+ switchRequest.removeWhere((key, value) => ['NationalID', 'isDentalAllowedBackend', 'ProjectOutSA', 'ForRegisteration'].contains(key));
+ }
+ }
+
+ final endpoint = isFormFamilyFile
+ ? ApiConsts.checkActivationCodeForFamily
+ : isRegister
+ ? ApiConsts.checkActivationCodeRegister
+ : ApiConsts.checkActivationCode;
try {
GenericApiModel? apiResponse;
@@ -197,7 +318,13 @@ class AuthenticationRepoImp implements AuthenticationRepo {
await apiClient.post(
endpoint,
- body: isRegister ? newRequest : newRequest.toJson(),
+ body: isFormFamilyFile
+ ? familyRequest
+ : isRegister
+ ? newRequest
+ : isSwitchUser
+ ? switchRequest
+ : newRequest.toJson(),
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
@@ -226,7 +353,6 @@ class AuthenticationRepoImp implements AuthenticationRepo {
@override
Future>> checkIfUserAgreed({required dynamic commonAuthanticatedRequest}) async {
commonAuthanticatedRequest['Region'] = 1;
- print("dsfsdd");
try {
GenericApiModel? apiResponse;
Failure? failure;
@@ -261,7 +387,6 @@ class AuthenticationRepoImp implements AuthenticationRepo {
@override
Future>> getUserAgreementContent({required dynamic commonAuthanticatedRequest}) async {
commonAuthanticatedRequest['Region'] = 1;
- print("dsfsdd");
try {
GenericApiModel? apiResponse;
Failure? failure;
diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart
index b43858c..e643c5d 100644
--- a/lib/features/authentication/authentication_view_model.dart
+++ b/lib/features/authentication/authentication_view_model.dart
@@ -13,6 +13,7 @@ import 'package:hmg_patient_app_new/core/common_models/nationality_country_model
import 'package:hmg_patient_app_new/core/common_models/privilege/HMCProjectListModel.dart';
import 'package:hmg_patient_app_new/core/common_models/privilege/ProjectDetailListModel.dart';
import 'package:hmg_patient_app_new/core/common_models/privilege/VidaPlusProjectListModel.dart';
+import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/loading_utils.dart';
import 'package:hmg_patient_app_new/core/utils/request_utils.dart';
@@ -26,6 +27,9 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/a
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart';
+import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart';
+import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/authentication/saved_login_screen.dart';
@@ -243,7 +247,7 @@ class AuthenticationViewModel extends ChangeNotifier {
await selectDeviceImei(onSuccess: (dynamic respData) async {
try {
if (respData != null) {
- dynamic data = SelectDeviceByImeiRespModelElement.fromJson(respData.toJson());
+ dynamic data = await SelectDeviceByImeiRespModelElement.fromJson(respData.toJson());
_appState.setSelectDeviceByImeiRespModelElement(data);
LoaderBottomSheet.hideLoader();
@@ -342,24 +346,33 @@ class AuthenticationViewModel extends ChangeNotifier {
);
}
- Future sendActivationCode(
- {required OTPTypeEnum otpTypeEnum, required String nationalIdOrFileNumber, required String phoneNumber, required bool isForRegister, dynamic payload, bool isComingFromResendOTP = false}) async {
+ Future sendActivationCode({required OTPTypeEnum otpTypeEnum,
+ required String nationalIdOrFileNumber,
+ required String phoneNumber,
+ required bool isForRegister,
+ dynamic payload,
+ bool isComingFromResendOTP = false,
+ bool isExcludedUser = false,
+ bool isFormFamilyFile = false,
+ int? responseID}) async {
var request = RequestUtils.getCommonRequestSendActivationCode(
- otpTypeEnum: otpTypeEnum,
- mobileNumber: phoneNumber,
- selectedLoginType: otpTypeEnum.toInt(),
- zipCode: selectedCountrySignup.countryCode,
- nationalId: int.parse(nationalIdOrFileNumber),
- isFileNo: isForRegister ? isPatientHasFile(request: payload) : false,
- patientId: 0,
- isForRegister: isForRegister,
- patientOutSA: isForRegister
- ? isPatientOutsideSA(request: payload)
- : selectedCountrySignup.countryCode == CountryEnum.saudiArabia
- ? false
- : true,
- payload: payload,
- );
+ otpTypeEnum: otpTypeEnum,
+ mobileNumber: phoneNumber,
+ selectedLoginType: otpTypeEnum.toInt(),
+ zipCode: selectedCountrySignup.countryCode,
+ nationalId: int.parse(nationalIdOrFileNumber),
+ isFileNo: isForRegister ? isPatientHasFile(request: payload) : false,
+ patientId: 0,
+ isForRegister: isForRegister,
+ patientOutSA: isForRegister
+ ? isPatientOutsideSA(request: payload)
+ : selectedCountrySignup.countryCode == CountryEnum.saudiArabia.countryCode
+ ? false
+ : true,
+ payload: payload,
+ isExcludedUser: isExcludedUser,
+ isFormFamilyFile: isFormFamilyFile,
+ responseID: responseID);
// TODO: GET APP SMS SIGNATURE HERE
request.sMSSignature = await getSignature();
@@ -368,11 +381,17 @@ class AuthenticationViewModel extends ChangeNotifier {
_appState.setUserRegistrationPayload = RegistrationDataModelPayload.fromJson(payload);
}
- final resultEither = await _authenticationRepo.sendActivationCodeRepo(sendActivationCodeReq: request, isRegister: checkIsUserComingForRegister(request: payload), languageID: 'er');
+ final resultEither = await _authenticationRepo.sendActivationCodeRepo(
+ sendActivationCodeReq: request, isRegister: checkIsUserComingForRegister(request: payload), languageID: 'er', isFormFamilyFile: isFormFamilyFile);
resultEither.fold(
(failure) async => await _errorHandlerService.handleError(failure: failure),
(apiResponse) async {
+ int? patientShareRequestID = 0;
+ if (isFormFamilyFile) {
+ patientShareRequestID = apiResponse.data['PatientShareRequestID'];
+ _appState.setFamilyFileTokenID = apiResponse.data['LogInTokenID'];
+ }
if (apiResponse.messageStatus == 2) {
LoaderBottomSheet.hideLoader();
await _dialogService.showCommonBottomSheetWithoutH(
@@ -383,7 +402,18 @@ class AuthenticationViewModel extends ChangeNotifier {
} else {
if (apiResponse.data != null && apiResponse.data['isSMSSent'] == true) {
LoaderBottomSheet.hideLoader();
- if (!isComingFromResendOTP) navigateToOTPScreen(otpTypeEnum: otpTypeEnum, phoneNumber: phoneNumber, isComingFromRegister: checkIsUserComingForRegister(request: payload), payload: payload);
+ if (!isComingFromResendOTP) {
+ navigateToOTPScreen(
+ otpTypeEnum: otpTypeEnum,
+ phoneNumber: phoneNumber,
+ isComingFromRegister: checkIsUserComingForRegister(request: payload),
+ payload: payload,
+ isFormFamilyFile: isFormFamilyFile,
+ isExcludedUser: isExcludedUser,
+ responseID: responseID,
+ patientShareRequestID: patientShareRequestID,
+ );
+ }
} else {
// TODO: Handle isSMSSent false
// navigateToOTPScreen(otpTypeEnum: otpTypeEnum, phoneNumber: phoneNumber);
@@ -401,8 +431,17 @@ class AuthenticationViewModel extends ChangeNotifier {
return isUserComingForRegister;
}
- Future checkActivationCode(
- {required String? activationCode, required OTPTypeEnum otpTypeEnum, required Function(String? message) onWrongActivationCode, Function()? onResendActivation}) async {
+ Future checkActivationCode({
+ required String? activationCode,
+ required OTPTypeEnum otpTypeEnum,
+ required Function(String? message) onWrongActivationCode,
+ Function()? onResendActivation,
+ bool isFormFamilyFile = false,
+ dynamic patientShareRequestID,
+ dynamic responseID,
+ bool isSwitchUser = false,
+ int? patientID,
+ }) async {
bool isForRegister = (_appState.getUserRegistrationPayload.healthId != null || _appState.getUserRegistrationPayload.patientOutSa == true || _appState.getUserRegistrationPayload.patientOutSa == 1);
final request = RequestUtils.getCommonRequestWelcome(
@@ -428,6 +467,7 @@ class AuthenticationViewModel extends ChangeNotifier {
//TODO: Error Here IN Zip Code.
loginType: loginTypeEnum.toInt)
.toJson();
+
LoaderBottomSheet.showLoader();
if (isForRegister) {
if (_appState.getUserRegistrationPayload.patientOutSa == 0) request['DOB'] = _appState.getUserRegistrationPayload.dob;
@@ -463,7 +503,17 @@ class AuthenticationViewModel extends ChangeNotifier {
}
});
} else {
- final resultEither = await _authenticationRepo.checkActivationCodeRepo(newRequest: CheckActivationCodeRegisterReq.fromJson(request), activationCode: activationCode, isRegister: false);
+ final resultEither = await _authenticationRepo.checkActivationCodeRepo(
+ newRequest: CheckActivationCodeRegisterReq.fromJson(request),
+ activationCode: activationCode,
+ isRegister: false,
+ isFormFamilyFile: isFormFamilyFile,
+ patientShareRequestID: patientShareRequestID,
+ responseID: responseID,
+ isSwitchUser: isSwitchUser,
+ patientID: patientID,
+ loginType: _appState.getSuperUserID != null ? 0 : 2,
+ );
resultEither.fold(
(failure) async => await _errorHandlerService.handleError(
@@ -494,48 +544,86 @@ class AuthenticationViewModel extends ChangeNotifier {
// Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew));
return;
} else {
- if (activation.list != null && activation.list!.isNotEmpty) {
- _appState.setAuthenticatedUser(activation.list!.first);
- _appState.setPrivilegeModelList(activation.list!.first.listPrivilege!);
- }
- _appState.setUserBloodGroup = (activation.patientBlodType ?? "");
- _appState.setAppAuthToken = activation.authenticationTokenId;
- final request = RequestUtils.getAuthanticatedCommonRequest().toJson();
- bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request);
-
- //updating the last login type in app state to show the fingerprint/face id option on home screen
- if (_appState.getSelectDeviceByImeiRespModelElement != null) {
- _appState.getSelectDeviceByImeiRespModelElement!.logInType = loginTypeEnum.toInt;
- }
- LoaderBottomSheet.hideLoader();
- insertPatientIMEIData(loginTypeEnum.toInt);
- await clearDefaultInputValues();
- if (isUserAgreedBefore) {
- navigateToHomeScreen();
+ if (isFormFamilyFile) {
+ // await navigateToFamilyFilePage();
+ MedicalFileViewModel medicalVm = getIt();
+ if (!_appState.getIsChildLoggedIn) {
+ await medicalVm.getFamilyFiles(status: 0);
+ await medicalVm.getAllPendingRecordsByResponseId();
+ _navigationService.popUntilNamed(AppRoutes.landingScreen);
+ }
} else {
- navigateToHomeScreen();
- //Agreement page not designed yet so we are navigating to home screen directly
- // getUserAgreementContent(request: request);
+ if (activation.list != null && activation.list!.isNotEmpty) {
+ if (isSwitchUser) {
+ if (_appState.getIsChildLoggedIn) {
+ _appState.setSuperUserID = null;
+ _appState.setIsChildLoggedIn = false;
+ activation.list!.first.isParentUser = true;
+ } else {
+ _appState.setSuperUserID = _appState.getAuthenticatedUser()?.patientId;
+ _appState.setIsChildLoggedIn = true;
+ activation.list!.first.isParentUser = false;
+ }
+ } else {
+ activation.list!.first.isParentUser = true;
+ }
+ activation.list!.first.bloodGroup = activation.patientBlodType;
+ _appState.setAuthenticatedUser(activation.list!.first);
+ _appState.setPrivilegeModelList(activation.list!.first.listPrivilege!);
+ }
+ // _appState.setUserBloodGroup = (activation.patientBlodType ?? "");
+ _appState.setAppAuthToken = activation.authenticationTokenId;
+ final request = await RequestUtils.getAuthanticatedCommonRequest().toJson();
+ bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request);
+
+ //updating the last login type in app state to show the fingerprint/face id option on home screen
+ if (_appState.getSelectDeviceByImeiRespModelElement != null) {
+ _appState.getSelectDeviceByImeiRespModelElement!.logInType = loginTypeEnum.toInt;
+ }
+ LoaderBottomSheet.hideLoader();
+//
+ if (!isSwitchUser && !_appState.getIsChildLoggedIn) {
+ MedicalFileViewModel medicalVm = getIt();
+ await insertPatientIMEIData(loginTypeEnum.toInt);
+ await medicalVm.getFamilyFiles(status: 0); //TODO: Remove status: 1 by Aamir Need to Discuss With Sultan
+ await medicalVm.getAllPendingRecordsByResponseId();
+ }
+
+ await clearDefaultInputValues();
+ if (isUserAgreedBefore) {
+ navigateToHomeScreen();
+ } else {
+ MyAppointmentsViewModel myAppointmentsVM = getIt();
+ myAppointmentsVM.setIsAppointmentDataToBeLoaded(true);
+ navigateToHomeScreen();
+ //Agreement page not designed yet so we are navigating to home screen directly
+ // getUserAgreementContent(request: request);
+ }
+ // TODO: setPreferences and stuff
+ // sharedPref.remove(FAMILY_FILE);
+ // activation.list!.isFamily = false;
+ // userData = activation.list;
+ // sharedPref.setString(BLOOD_TYPE, activation.patientBloodType ?? "");
+ // authenticatedUserObject.user = activation.list!;
+ // projectViewModel.setPrivilege(privilegeList: res);
+ // await sharedPref.setObject(MAIN_USER, activation.list);
+ // await sharedPref.setObject(USER_PROFILE, activation.list);
+ // loginTokenID = activation.logInTokenID;
+ // await sharedPref.setObject(LOGIN_TOKEN_ID, activation.logInTokenID);
+ // await sharedPref.setString(TOKEN, activation.authenticationTokenID!);
+
+ // projectViewModel.analytics.loginRegistration.login_successful();
}
- // TODO: setPreferences and stuff
- // sharedPref.remove(FAMILY_FILE);
- // activation.list!.isFamily = false;
- // userData = activation.list;
- // sharedPref.setString(BLOOD_TYPE, activation.patientBloodType ?? "");
- // authenticatedUserObject.user = activation.list!;
- // projectViewModel.setPrivilege(privilegeList: res);
- // await sharedPref.setObject(MAIN_USER, activation.list);
- // await sharedPref.setObject(USER_PROFILE, activation.list);
- // loginTokenID = activation.logInTokenID;
- // await sharedPref.setObject(LOGIN_TOKEN_ID, activation.logInTokenID);
- // await sharedPref.setString(TOKEN, activation.authenticationTokenID!);
-
- // projectViewModel.analytics.loginRegistration.login_successful();
}
});
}
}
+ Future navigateToFamilyFilePage() async {
+ MedicalFileViewModel medicalFileVM = GetIt.instance();
+ medicalFileVM.handleFamilyFileRequestOTPVerification();
+ }
+
Future checkIfUserAgreedBefore({required dynamic request}) async {
bool isAgreed = false;
if (havePrivilege(109)) {
@@ -573,13 +661,25 @@ class AuthenticationViewModel extends ChangeNotifier {
_navigationService.pushAndReplace(AppRoutes.landingScreen);
}
- Future navigateToOTPScreen({required OTPTypeEnum otpTypeEnum, required String phoneNumber, required bool isComingFromRegister, dynamic payload}) async {
+ Future navigateToOTPScreen(
+ {required OTPTypeEnum otpTypeEnum,
+ required String phoneNumber,
+ required bool isComingFromRegister,
+ dynamic payload,
+ bool isFormFamilyFile = false,
+ bool isExcludedUser = false,
+ int? responseID,
+ int? patientShareRequestID}) async {
_navigationService.pushToOtpScreen(
phoneNumber: phoneNumber,
+ isFormFamilyFile: isFormFamilyFile,
checkActivationCode: (int activationCode) async {
await checkActivationCode(
activationCode: activationCode.toString(),
+ isFormFamilyFile: isFormFamilyFile,
otpTypeEnum: otpTypeEnum,
+ responseID: responseID,
+ patientShareRequestID: patientShareRequestID,
onWrongActivationCode: (String? value) {
onWrongActivationCode(message: value);
},
@@ -587,12 +687,16 @@ class AuthenticationViewModel extends ChangeNotifier {
},
onResendOTPPressed: (String phoneNumber) async {
await sendActivationCode(
- otpTypeEnum: otpTypeEnum,
- phoneNumber: phoneNumberController.text,
- nationalIdOrFileNumber: nationalIdController.text,
- isForRegister: isComingFromRegister,
- isComingFromResendOTP: true,
- payload: payload);
+ otpTypeEnum: otpTypeEnum,
+ phoneNumber: phoneNumberController.text,
+ nationalIdOrFileNumber: nationalIdController.text,
+ isForRegister: isComingFromRegister,
+ isComingFromResendOTP: true,
+ payload: payload,
+ isFormFamilyFile: isFormFamilyFile,
+ isExcludedUser: isExcludedUser,
+ responseID: responseID,
+ );
},
);
}
diff --git a/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart b/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart
index 8848fde..8209a0f 100644
--- a/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart
+++ b/lib/features/authentication/models/resp_models/authenticated_user_resp_model.dart
@@ -69,6 +69,8 @@ class AuthenticatedUser {
dynamic authenticatedUserPatientPayType;
dynamic authenticatedUserPatientType;
dynamic authenticatedUserStatus;
+ int? superUser;
+ bool? isParentUser;
AuthenticatedUser({
this.setupId,
@@ -139,6 +141,8 @@ class AuthenticatedUser {
this.authenticatedUserPatientPayType,
this.authenticatedUserPatientType,
this.authenticatedUserStatus,
+ this.superUser,
+ this.isParentUser,
});
factory AuthenticatedUser.fromRawJson(String str) => AuthenticatedUser.fromJson(json.decode(str));
@@ -146,146 +150,150 @@ class AuthenticatedUser {
String toRawJson() => json.encode(toJson());
factory AuthenticatedUser.fromJson(Map json) => AuthenticatedUser(
- setupId: json["SetupID"],
- patientType: json["PatientType"],
- patientId: json["PatientID"],
- firstName: json["FirstName"],
- middleName: json["MiddleName"],
- lastName: json["LastName"],
- firstNameN: json["FirstNameN"],
- middleNameN: json["MiddleNameN"],
- lastNameN: json["LastNameN"],
- relationshipId: json["RelationshipID"],
- gender: json["Gender"],
- dateofBirth: json["DateofBirth"],
- dateofBirthN: json["DateofBirthN"],
- nationalityId: json["NationalityID"],
- phoneResi: json["PhoneResi"],
- phoneOffice: json["PhoneOffice"],
- mobileNumber: json["MobileNumber"],
- faxNumber: json["FaxNumber"],
- emailAddress: json["EmailAddress"],
- bloodGroup: json["BloodGroup"],
- rhFactor: json["RHFactor"],
- isEmailAlertRequired: json["IsEmailAlertRequired"],
- isSmsAlertRequired: json["IsSMSAlertRequired"],
- preferredLanguage: json["PreferredLanguage"],
- isPrivilegedMember: json["IsPrivilegedMember"],
- memberId: json["MemberID"],
- expiryDate: json["ExpiryDate"],
- isHmgEmployee: json["IsHmgEmployee"],
- employeeId: json["EmployeeID"],
- emergencyContactName: json["EmergencyContactName"],
- emergencyContactNo: json["EmergencyContactNo"],
- patientPayType: json["PatientPayType"],
- dhccPatientRefId: json["DHCCPatientRefID"],
- isPatientDummy: json["IsPatientDummy"],
- status: json["Status"],
- isStatusCleared: json["IsStatusCleared"],
- patientIdentificationType: json["PatientIdentificationType"],
- patientIdentificationNo: json["PatientIdentificationNo"],
- projectId: json["ProjectID"],
- infoSourceId: json["InfoSourceID"],
- address: json["Address"],
- age: json["Age"],
- ageDesc: json["AgeDesc"],
- areaId: json["AreaID"],
- crsVerificationStatus: json["CRSVerificationStatus"],
- crsVerificationStatusDesc: json["CRSVerificationStatusDesc"],
- crsVerificationStatusDescN: json["CRSVerificationStatusDescN"],
- createdBy: json["CreatedBy"],
- genderDescription: json["GenderDescription"],
- healthIdFromNhicViaVida: json["HealthIDFromNHICViaVida"],
- ir: json["IR"],
- isoCityId: json["ISOCityID"],
- isoCountryId: json["ISOCountryID"],
- isVerfiedFromNhic: json["IsVerfiedFromNHIC"],
- listPrivilege: json["ListPrivilege"] == null ? [] : List.from(json["ListPrivilege"]!.map((x) => ListPrivilege.fromJson(x))),
- marital: json["Marital"],
- occupationId: json["OccupationID"],
- outSa: json["OutSA"],
- poBox: json["POBox"],
- receiveHealthSummaryReport: json["ReceiveHealthSummaryReport"],
- sourceType: json["SourceType"],
- strDateofBirth: json["StrDateofBirth"],
- tempAddress: json["TempAddress"],
- zipCode: json["ZipCode"],
- eHealthIdField: json["eHealthIDField"],
- authenticatedUserPatientPayType: json["patientPayType"],
- authenticatedUserPatientType: json["patientType"],
- authenticatedUserStatus: json["status"],
- );
+ setupId: json["SetupID"],
+ patientType: json["PatientType"],
+ patientId: json["PatientID"],
+ firstName: json["FirstName"],
+ middleName: json["MiddleName"],
+ lastName: json["LastName"],
+ firstNameN: json["FirstNameN"],
+ middleNameN: json["MiddleNameN"],
+ lastNameN: json["LastNameN"],
+ relationshipId: json["RelationshipID"],
+ gender: json["Gender"],
+ dateofBirth: json["DateofBirth"],
+ dateofBirthN: json["DateofBirthN"],
+ nationalityId: json["NationalityID"],
+ phoneResi: json["PhoneResi"],
+ phoneOffice: json["PhoneOffice"],
+ mobileNumber: json["MobileNumber"],
+ faxNumber: json["FaxNumber"],
+ emailAddress: json["EmailAddress"],
+ bloodGroup: json["BloodGroup"],
+ rhFactor: json["RHFactor"],
+ isEmailAlertRequired: json["IsEmailAlertRequired"],
+ isSmsAlertRequired: json["IsSMSAlertRequired"],
+ preferredLanguage: json["PreferredLanguage"],
+ isPrivilegedMember: json["IsPrivilegedMember"],
+ memberId: json["MemberID"],
+ expiryDate: json["ExpiryDate"],
+ isHmgEmployee: json["IsHmgEmployee"],
+ employeeId: json["EmployeeID"],
+ emergencyContactName: json["EmergencyContactName"],
+ emergencyContactNo: json["EmergencyContactNo"],
+ patientPayType: json["PatientPayType"],
+ dhccPatientRefId: json["DHCCPatientRefID"],
+ isPatientDummy: json["IsPatientDummy"],
+ status: json["Status"],
+ isStatusCleared: json["IsStatusCleared"],
+ patientIdentificationType: json["PatientIdentificationType"],
+ patientIdentificationNo: json["PatientIdentificationNo"],
+ projectId: json["ProjectID"],
+ infoSourceId: json["InfoSourceID"],
+ address: json["Address"],
+ age: json["Age"],
+ ageDesc: json["AgeDesc"],
+ areaId: json["AreaID"],
+ crsVerificationStatus: json["CRSVerificationStatus"],
+ crsVerificationStatusDesc: json["CRSVerificationStatusDesc"],
+ crsVerificationStatusDescN: json["CRSVerificationStatusDescN"],
+ createdBy: json["CreatedBy"],
+ genderDescription: json["GenderDescription"],
+ healthIdFromNhicViaVida: json["HealthIDFromNHICViaVida"],
+ ir: json["IR"],
+ isoCityId: json["ISOCityID"],
+ isoCountryId: json["ISOCountryID"],
+ isVerfiedFromNhic: json["IsVerfiedFromNHIC"],
+ listPrivilege: json["ListPrivilege"] == null ? [] : List.from(json["ListPrivilege"]!.map((x) => ListPrivilege.fromJson(x))),
+ marital: json["Marital"],
+ occupationId: json["OccupationID"],
+ outSa: json["OutSA"],
+ poBox: json["POBox"],
+ receiveHealthSummaryReport: json["ReceiveHealthSummaryReport"],
+ sourceType: json["SourceType"],
+ strDateofBirth: json["StrDateofBirth"],
+ tempAddress: json["TempAddress"],
+ zipCode: json["ZipCode"],
+ eHealthIdField: json["eHealthIDField"],
+ authenticatedUserPatientPayType: json["patientPayType"],
+ authenticatedUserPatientType: json["patientType"],
+ authenticatedUserStatus: json["status"],
+ superUser: json["superUser"],
+ isParentUser: json["isParentUser"] ?? false,
+ );
Map toJson() => {
- "SetupID": setupId,
- "PatientType": patientType,
- "PatientID": patientId,
- "FirstName": firstName,
- "MiddleName": middleName,
- "LastName": lastName,
- "FirstNameN": firstNameN,
- "MiddleNameN": middleNameN,
- "LastNameN": lastNameN,
- "RelationshipID": relationshipId,
- "Gender": gender,
- "DateofBirth": dateofBirth,
- "DateofBirthN": dateofBirthN,
- "NationalityID": nationalityId,
- "PhoneResi": phoneResi,
- "PhoneOffice": phoneOffice,
- "MobileNumber": mobileNumber,
- "FaxNumber": faxNumber,
- "EmailAddress": emailAddress,
- "BloodGroup": bloodGroup,
- "RHFactor": rhFactor,
- "IsEmailAlertRequired": isEmailAlertRequired,
- "IsSMSAlertRequired": isSmsAlertRequired,
- "PreferredLanguage": preferredLanguage,
- "IsPrivilegedMember": isPrivilegedMember,
- "MemberID": memberId,
- "ExpiryDate": expiryDate,
- "IsHmgEmployee": isHmgEmployee,
- "EmployeeID": employeeId,
- "EmergencyContactName": emergencyContactName,
- "EmergencyContactNo": emergencyContactNo,
- "PatientPayType": patientPayType,
- "DHCCPatientRefID": dhccPatientRefId,
- "IsPatientDummy": isPatientDummy,
- "Status": status,
- "IsStatusCleared": isStatusCleared,
- "PatientIdentificationType": patientIdentificationType,
- "PatientIdentificationNo": patientIdentificationNo,
- "ProjectID": projectId,
- "InfoSourceID": infoSourceId,
- "Address": address,
- "Age": age,
- "AgeDesc": ageDesc,
- "AreaID": areaId,
- "CRSVerificationStatus": crsVerificationStatus,
- "CRSVerificationStatusDesc": crsVerificationStatusDesc,
- "CRSVerificationStatusDescN": crsVerificationStatusDescN,
- "CreatedBy": createdBy,
- "GenderDescription": genderDescription,
- "HealthIDFromNHICViaVida": healthIdFromNhicViaVida,
- "IR": ir,
- "ISOCityID": isoCityId,
- "ISOCountryID": isoCountryId,
- "IsVerfiedFromNHIC": isVerfiedFromNhic,
- "ListPrivilege": listPrivilege == null ? [] : List.from(listPrivilege!.map((x) => x.toJson())),
- "Marital": marital,
- "OccupationID": occupationId,
- "OutSA": outSa,
- "POBox": poBox,
- "ReceiveHealthSummaryReport": receiveHealthSummaryReport,
- "SourceType": sourceType,
- "StrDateofBirth": strDateofBirth,
- "TempAddress": tempAddress,
- "ZipCode": zipCode,
- "eHealthIDField": eHealthIdField,
- "patientPayType": authenticatedUserPatientPayType,
- "patientType": authenticatedUserPatientType,
- "status": authenticatedUserStatus,
- };
+ "SetupID": setupId,
+ "PatientType": patientType,
+ "PatientID": patientId,
+ "FirstName": firstName,
+ "MiddleName": middleName,
+ "LastName": lastName,
+ "FirstNameN": firstNameN,
+ "MiddleNameN": middleNameN,
+ "LastNameN": lastNameN,
+ "RelationshipID": relationshipId,
+ "Gender": gender,
+ "DateofBirth": dateofBirth,
+ "DateofBirthN": dateofBirthN,
+ "NationalityID": nationalityId,
+ "PhoneResi": phoneResi,
+ "PhoneOffice": phoneOffice,
+ "MobileNumber": mobileNumber,
+ "FaxNumber": faxNumber,
+ "EmailAddress": emailAddress,
+ "BloodGroup": bloodGroup,
+ "RHFactor": rhFactor,
+ "IsEmailAlertRequired": isEmailAlertRequired,
+ "IsSMSAlertRequired": isSmsAlertRequired,
+ "PreferredLanguage": preferredLanguage,
+ "IsPrivilegedMember": isPrivilegedMember,
+ "MemberID": memberId,
+ "ExpiryDate": expiryDate,
+ "IsHmgEmployee": isHmgEmployee,
+ "EmployeeID": employeeId,
+ "EmergencyContactName": emergencyContactName,
+ "EmergencyContactNo": emergencyContactNo,
+ "PatientPayType": patientPayType,
+ "DHCCPatientRefID": dhccPatientRefId,
+ "IsPatientDummy": isPatientDummy,
+ "Status": status,
+ "IsStatusCleared": isStatusCleared,
+ "PatientIdentificationType": patientIdentificationType,
+ "PatientIdentificationNo": patientIdentificationNo,
+ "ProjectID": projectId,
+ "InfoSourceID": infoSourceId,
+ "Address": address,
+ "Age": age,
+ "AgeDesc": ageDesc,
+ "AreaID": areaId,
+ "CRSVerificationStatus": crsVerificationStatus,
+ "CRSVerificationStatusDesc": crsVerificationStatusDesc,
+ "CRSVerificationStatusDescN": crsVerificationStatusDescN,
+ "CreatedBy": createdBy,
+ "GenderDescription": genderDescription,
+ "HealthIDFromNHICViaVida": healthIdFromNhicViaVida,
+ "IR": ir,
+ "ISOCityID": isoCityId,
+ "ISOCountryID": isoCountryId,
+ "IsVerfiedFromNHIC": isVerfiedFromNhic,
+ "ListPrivilege": listPrivilege == null ? [] : List.from(listPrivilege!.map((x) => x.toJson())),
+ "Marital": marital,
+ "OccupationID": occupationId,
+ "OutSA": outSa,
+ "POBox": poBox,
+ "ReceiveHealthSummaryReport": receiveHealthSummaryReport,
+ "SourceType": sourceType,
+ "StrDateofBirth": strDateofBirth,
+ "TempAddress": tempAddress,
+ "ZipCode": zipCode,
+ "eHealthIDField": eHealthIdField,
+ "patientPayType": authenticatedUserPatientPayType,
+ "patientType": authenticatedUserPatientType,
+ "status": authenticatedUserStatus,
+ "superUser": superUser,
+ "isParentUser": isParentUser,
+ };
}
class ListPrivilege {
@@ -306,16 +314,16 @@ class ListPrivilege {
String toRawJson() => json.encode(toJson());
factory ListPrivilege.fromJson(Map json) => ListPrivilege(
- id: json["ID"],
- serviceName: json["ServiceName"],
- previlege: json["Previlege"],
- region: json["Region"],
- );
+ id: json["ID"],
+ serviceName: json["ServiceName"],
+ previlege: json["Previlege"],
+ region: json["Region"],
+ );
Map toJson() => {
- "ID": id,
- "ServiceName": serviceName,
- "Previlege": previlege,
- "Region": region,
- };
+ "ID": id,
+ "ServiceName": serviceName,
+ "Previlege": previlege,
+ "Region": region,
+ };
}
diff --git a/lib/features/authentication/widgets/otp_verification_screen.dart b/lib/features/authentication/widgets/otp_verification_screen.dart
index e7f8d72..10e34cd 100644
--- a/lib/features/authentication/widgets/otp_verification_screen.dart
+++ b/lib/features/authentication/widgets/otp_verification_screen.dart
@@ -428,13 +428,9 @@ class OTPVerificationScreen extends StatefulWidget {
final String phoneNumber;
final Function(int code) checkActivationCode;
final Function(String phoneNumber) onResendOTPPressed;
+ final bool isFormFamilyFile;
- const OTPVerificationScreen({
- super.key,
- required this.phoneNumber,
- required this.checkActivationCode,
- required this.onResendOTPPressed,
- });
+ const OTPVerificationScreen({super.key, required this.phoneNumber, required this.checkActivationCode, required this.onResendOTPPressed, required this.isFormFamilyFile});
@override
State createState() => _OTPVerificationScreenState();
@@ -559,7 +555,7 @@ class _OTPVerificationScreenState extends State {
LocaleKeys.weHaveSendOTP.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4),
_getMaskedPhoneNumber().toText15(color: AppColors.inputLabelTextColor, isBold: true),
LocaleKeys.via.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4),
- authVM.loginTypeEnum.displayName.toText15(color: AppColors.inputLabelTextColor, isBold: true, letterSpacing: -0.4),
+ (widget.isFormFamilyFile ? LoginTypeEnum.sms.displayName : authVM.loginTypeEnum.displayName).toText15(color: AppColors.inputLabelTextColor, isBold: true, letterSpacing: -0.4),
appState.getUserRegistrationPayload.isRegister != null && appState.getUserRegistrationPayload.isRegister == true
? LocaleKeys.forRegistrationVerification.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4)
: LocaleKeys.forLoginVerification.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4),
diff --git a/lib/features/book_appointments/book_appointments_repo.dart b/lib/features/book_appointments/book_appointments_repo.dart
index 82ca921..1783556 100644
--- a/lib/features/book_appointments/book_appointments_repo.dart
+++ b/lib/features/book_appointments/book_appointments_repo.dart
@@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
@@ -15,6 +16,8 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
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';
+import 'models/resp_models/laser_body_parts.dart';
+
abstract class BookAppointmentsRepo {
Future>>> getClinics();
@@ -72,6 +75,15 @@ abstract class BookAppointmentsRepo {
Future>>> getPatientDentalEstimation(
{required int projectID, Function(dynamic)? onSuccess, Function(String)? onError});
+
+ Future>>> getDentalChiefComplaintsList(
+ {required int projectID, required int clinicID, required int patientID, Function(dynamic)? onSuccess, Function(String)? onError});
+
+ Future>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID,
+ {Function(dynamic)? onSuccess, Function(String)? onError});
+
+ Future>>> getLaserClinics(int laserCategoryID, int projectID, int languageID,
+ {Function(dynamic)? onSuccess, Function(String)? onError});
}
class BookAppointmentsRepoImp implements BookAppointmentsRepo {
@@ -701,4 +713,139 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>>> getDentalChiefComplaintsList(
+ {required int projectID, required int clinicID, required int patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ Map mapDevice = {
+ "PatientID": patientID,
+ "ClinicID": clinicID,
+ "ProjectID": projectID,
+ "isDentalAllowedBackend": true,
+ "ContinueDentalPlan": false,
+ "IsSearchAppointmnetByClinicID": false,
+ };
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_DOCTORS_LIST_URL,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ onError!(error);
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['List_DentalChiefComplain'];
+
+ final chiefComplaintsList = list.map((item) => DentalChiefComplaintsListResponseModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: chiefComplaintsList,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID,
+ {Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ Map mapDevice = {
+ "ProjectID": projectID,
+ "ChiefComplaintID": chiefComplaintID,
+ "isDentalAllowedBackend": true,
+ "IsPublicRequest": true,
+ };
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_DENTAL_DOCTORS_LIST_URL,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ onError!(error);
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['List_DentalDoctorChiefComplaintMapping'];
+
+ final doctorsList = list.map((item) => DoctorsListResponseModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: doctorsList,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> getLaserClinics(int laserCategoryID, int projectID, int languageID, {Function(dynamic p1)? onSuccess, Function(String p1)? onError}) async {
+ Map mapDevice = {
+ "LaserCategoryID": laserCategoryID,
+ "ProjectID": projectID,
+ "LanguageID": languageID,
+ };
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ LASER_BODY_PARTS,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ onError!(error);
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['Laser_GetBodyPartsByCategoryList'];
+
+ final doctorsList = list.map((item) => LaserBodyPart.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: doctorsList,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
}
diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart
index a6c741f..20b64fd 100644
--- a/lib/features/book_appointments/book_appointments_view_model.dart
+++ b/lib/features/book_appointments/book_appointments_view_model.dart
@@ -1,3 +1,5 @@
+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';
@@ -11,11 +13,14 @@ 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/features/book_appointments/book_appointments_repo.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/models/LaserCategoryType.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/free_slot.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_patient_dental_plan_response_model.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/laser_body_parts.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/timeslots.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';
@@ -23,6 +28,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
+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/widgets/common_bottom_sheet.dart';
@@ -31,6 +37,7 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'models/resp_models/get_livecare_clinics_response_model.dart';
class BookAppointmentsViewModel extends ChangeNotifier {
+ final DialogService dialogService;
int selectedTabIndex = 0;
bool isClinicsListLoading = false;
@@ -57,8 +64,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
List liveCareDoctorsList = [];
List patientDentalPlanEstimationList = [];
+ List dentalChiefComplaintsList = [];
int totalTimeNeededForDentalProcedure = 0;
bool isContinueDentalPlan = false;
+ bool isChiefComplaintsListLoading = false;
+ int selectedChiefComplaintID = 0;
GetClinicsListResponseModel selectedClinic = GetClinicsListResponseModel();
DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel();
@@ -104,8 +114,31 @@ class BookAppointmentsViewModel extends ChangeNotifier {
String? selectedClinicForFilters;
bool applyFilters = false;
+
+ ///variables for laser clinic
+ List femaleLaserCategory = [
+ LaserCategoryType(1, 'bodyString'),
+ LaserCategoryType(2, 'face'),
+ LaserCategoryType(10,'bikini'),
+ LaserCategoryType(11, 'retouch'),
+ ];
+ List maleLaserCategory =[
+ LaserCategoryType(1, 'body'),
+ LaserCategoryType(2, 'face'),
+ LaserCategoryType(11, 'retouch'),
+ ];
+ List> bodyTypes = [];
+
+ List laserBodyPartsList = [];
+ List selectedBodyPartList = [];
+ int selectedBodyTypeIndex = 0;
+ int selectedCategory = 0;
+ bool isBodyPartsLoading = false;
+ int duration = 0;
+
+
BookAppointmentsViewModel(
- {required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils}) {
+ {required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils, required this.dialogService }) {
initBookAppointmentViewModel();
}
@@ -134,7 +167,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
doctorsList.clear();
liveCareClinicsList.clear();
patientDentalPlanEstimationList.clear();
+ dentalChiefComplaintsList.clear();
isContinueDentalPlan = false;
+ isChiefComplaintsListLoading = true;
+ bodyTypes = [maleLaserCategory, femaleLaserCategory];
// getLocation();
notifyListeners();
}
@@ -201,6 +237,16 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
+ setIsChiefComplaintsListLoading(bool value) {
+ isChiefComplaintsListLoading = value;
+ notifyListeners();
+ }
+
+ setSelectedChiefComplaintID(int id) {
+ selectedChiefComplaintID = id;
+ notifyListeners();
+ }
+
void onTabChanged(int index) {
selectedTabIndex = index;
notifyListeners();
@@ -294,7 +340,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
result.fold(
(failure) async {
+ isDoctorsListLoading = false;
+
onError!("No doctors found for the search criteria".needTranslation);
+ notifyListeners();
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
@@ -326,7 +375,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
result.fold(
(failure) async {
- onError!("No doctors found for the search criteria".needTranslation);
+ onError?.call("No doctors found for the search criteria".needTranslation);
},
(apiResponse) async {
if (apiResponse.messageStatus == 2) {
@@ -949,4 +998,157 @@ class BookAppointmentsViewModel extends ChangeNotifier {
},
);
}
+
+ Future getDentalChiefComplaintsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ dentalChiefComplaintsList.clear();
+ notifyListeners();
+ int patientID = _appState.isAuthenticated ? _appState.getAuthenticatedUser()!.patientId ?? -1 : -1;
+ final result = await bookAppointmentsRepo.getDentalChiefComplaintsList(patientID: patientID, projectID: int.parse(currentlySelectedHospitalFromRegionFlow ?? "0"), clinicID: 17);
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ onError!(apiResponse.errorMessage!);
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ dentalChiefComplaintsList = apiResponse.data!;
+ isChiefComplaintsListLoading = false;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
+
+ Future getDentalChiefComplaintDoctorsList({int projectID = 0, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ doctorsList.clear();
+ projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
+ final result = await bookAppointmentsRepo.getDentalChiefComplaintDoctorsList(projectID, selectedChiefComplaintID);
+
+ result.fold(
+ (failure) async {
+ onError!("No doctors found for the search criteria...".needTranslation);
+ },
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ doctorsList = apiResponse.data!;
+ filteredDoctorList = doctorsList;
+ isDoctorsListLoading = false;
+ // initializeFilteredList();
+ // clearSearchFilters();
+ // getFiltersFromDoctorList();
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
+
+ setBodyType(int bodyType){
+ selectedBodyTypeIndex = bodyType;
+ selectedCategory = 0;
+ selectedBodyPartList = [];
+ duration = 0;
+ notifyListeners();
+ }
+
+ 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) {
+ isBodyPartsLoading = false;
+ notifyListeners();
+ },
+ (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);
+ laserBodyPartsList = response;
+ }
+ notifyListeners();
+
+ },
+ );
+ }
+
+ int getDuration() {
+ 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() ?? [];
+
+ if (selectedBodyPartList.isNotEmpty) {
+ duration = selectedBodyPartList.fold(0, (previousValue, element) => previousValue + int.parse(element.timeDuration!));
+ }
+ if (lowerUpperLegsList.length == 2) {
+ duration -= 30;
+ }
+ if (upperLowerArmsList.length == 2) {
+ duration -= 15;
+ }
+
+ return duration;
+ }
+
+ void setSelectedCategory(category) {
+ selectedCategory = category;
+ notifyListeners();
+ getLaserClinic();
+ }
+
+ void setSelectedBodyPart(LaserBodyPart 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,);
+ return;
+ }
+ selectedBodyPartList.add(part);
+ var duration = getDuration();
+ if(duration > 90){
+ selectedBodyPartList.remove(part);
+ dialogService.showErrorBottomSheet(message: "Duration Exceeds 90 min".needTranslation,);
+ return;
+ }
+ this.duration = duration;
+ notifyListeners();
+ }
+ }
+
+ readCurrentLaserCategoryID() {
+ return bodyTypes[selectedBodyTypeIndex][selectedCategory].laserCategoryID;
+ }
+
+ String getLaserProcedureNameWRTLanguage(LaserBodyPart part) {
+ if(_appState.isArabic()){
+ return part.bodyPartN??"";
+ }else {
+ return part.bodyPart??"";
+ }
+ }
+
+ void resetLaserData() {
+ selectedCategory = 0;
+ selectedBodyTypeIndex = 0;
+ selectedBodyPartList = [];
+ laserBodyPartsList = [];
+ duration = 0;
+ }
}
diff --git a/lib/features/book_appointments/models/LaserCategoryType.dart b/lib/features/book_appointments/models/LaserCategoryType.dart
new file mode 100644
index 0000000..df85620
--- /dev/null
+++ b/lib/features/book_appointments/models/LaserCategoryType.dart
@@ -0,0 +1,6 @@
+class LaserCategoryType {
+ int laserCategoryID;
+ String title;
+
+ LaserCategoryType(this.laserCategoryID, this.title);
+}
diff --git a/lib/features/book_appointments/models/laser_body_parts_data.dart b/lib/features/book_appointments/models/laser_body_parts_data.dart
new file mode 100644
index 0000000..2f8b32d
--- /dev/null
+++ b/lib/features/book_appointments/models/laser_body_parts_data.dart
@@ -0,0 +1,135 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class LaserBodyParts {
+ static final LaserBodyParts _instance = LaserBodyParts._internal();
+
+ LaserBodyParts._internal();
+
+ factory LaserBodyParts() => _instance;
+
+ static Widget image(String assetUri) {
+ return new SvgPicture.asset(assetUri, fit: BoxFit.cover, width: 88, height: 88);
+ }
+
+ static Widget imagePng(String assetUri) {
+ return Image.asset(assetUri, fit: BoxFit.cover, width: 88, height: 88);
+ }
+
+ Map maleBodyMap = {
+ "1": imagePng("assets/images/png/body_parts/male/full_body_male.png"),
+ "40": imagePng("assets/images/png/body_parts/male/upper_arm.png"),
+ "41": imagePng("assets/images/png/body_parts/male/lower_arm.png"),
+ "42": imagePng("assets/images/png/body_parts/male/chest.png"),
+ "43": imagePng("assets/images/png/body_parts/male/chest_line.png"),
+ "44": imagePng("assets/images/png/body_parts/male/shoulders.png"),
+ "45": imagePng("assets/images/png/body_parts/male/back.png"),
+ "46": imagePng("assets/images/png/body_parts/male/abdomin.png"),
+ "47": imagePng("assets/images/png/body_parts/male/upper_legs.png"),
+ "48": imagePng("assets/images/png/body_parts/male/lower_legs.png"),
+ "49": imagePng("assets/images/png/body_parts/male/axilla.png")
+ };
+
+ Map maleFaceMap = {
+ "62": image("assets/images/png/body_parts/male/hydra_facial.svg"),
+ "5": image("assets/images/png/body_parts/male/upper_lips.svg"),
+ "6": image("assets/images/png/body_parts/male/chin.svg"),
+ "7": image("assets/images/png/body_parts/male/cheek.svg"),
+ "8": image("assets/images/png/body_parts/male/side_burn.svg"),
+ "9": image("assets/images/png/body_parts/male/ears.svg"),
+ "10": image("assets/images/png/body_parts/male/full_neck.svg"),
+ "11": image("assets/images/png/body_parts/male/half_neck.svg"),
+ "12": image("assets/images/png/body_parts/male/eyebrows.svg")
+ };
+
+ Map maleBodyRetouchMap = {
+ "50": imagePng("assets/images/png/body_parts/male/full_body_male.png"),
+ "51": imagePng("assets/images/png/body_parts/male/upper_arm.png"),
+ "52": imagePng("assets/images/png/body_parts/male/lower_arm.png"),
+ "53": imagePng("assets/images/png/body_parts/male/chest.png"),
+ "54": imagePng("assets/images/png/body_parts/male/shoulders.png"),
+ "55": imagePng("assets/images/png/body_parts/male/back.png"),
+ "56": imagePng("assets/images/png/body_parts/male/abdomin.png"),
+ "57": imagePng("assets/images/png/body_parts/male/full_legs.png"),
+ "58": imagePng("assets/images/png/body_parts/male/upper_legs.png"),
+ "59": imagePng("assets/images/png/body_parts/male/lower_legs.png"),
+ "60": imagePng("assets/images/png/body_parts/male/bikini.png"),
+ "61": imagePng("assets/images/png/body_parts/male/bikini_line.png")
+ };
+
+ Map femaleBodyMap = {
+ "1": imagePng("assets/images/png/body_parts/female/full_body_female.png"),
+ "40": imagePng("assets/images/png/body_parts/female/upper_arm.png"),
+ "41": imagePng("assets/images/png/body_parts/female/lower_arm.png"),
+ "42": imagePng("assets/images/png/body_parts/female/chest.png"),
+ "43": imagePng("assets/images/png/body_parts/female/chest_line.png"),
+ "44": imagePng("assets/images/png/body_parts/female/shoulders.png"),
+ "45": imagePng("assets/images/png/body_parts/female/back.png"),
+ "46": imagePng("assets/images/png/body_parts/female/abdomin.png"),
+ "47": imagePng("assets/images/png/body_parts/female/upper_legs.png"),
+ "48": imagePng("assets/images/png/body_parts/female/lower_leg.png"),
+ "49": imagePng("assets/images/png/body_parts/female/axilla.png")
+ };
+
+ Map femaleFaceMap = {
+ "62": image("assets/images/png/body_parts/female/hydra_facial.svg"),
+ "5": image("assets/images/png/body_parts/female/upper_lips.svg"),
+ "6": image("assets/images/png/body_parts/female/chin.svg"),
+ "7": image("assets/images/png/body_parts/female/cheeks.svg"),
+ "8": image("assets/images/png/body_parts/female/side_burn.svg"),
+ "9": image("assets/images/png/body_parts/female/ears.svg"),
+ "10": image("assets/images/png/body_parts/female/full_neck.svg"),
+ "11": image("assets/images/png/body_parts/female/half_neck.svg"),
+ "12": image("assets/images/png/body_parts/female/eyebrows.svg")
+ };
+
+ Map femaleBodyBikiniMap = {
+ "34": imagePng("assets/images/png/body_parts/female/bikini.png"),
+ "36": imagePng("assets/images/png/body_parts/female/bikini_line.png"),
+ "38": imagePng("assets/images/png/body_parts/female/buttocks.png"),
+ "39": imagePng("assets/images/png/body_parts/female/anal.png")
+ };
+
+ Map femaleBodyRetouchMap = {
+ "50": imagePng("assets/images/png/body_parts/female/full_body_female.png"),
+ "51": imagePng("assets/images/png/body_parts/female/upper_arm.png"),
+ "52": imagePng("assets/images/png/body_parts/female/lower_arm.png"),
+ "53": imagePng("assets/images/png/body_parts/female/chest.png"),
+ "54": imagePng("assets/images/png/body_parts/female/shoulders.png"),
+ "55": imagePng("assets/images/png/body_parts/female/back.png"),
+ "56": imagePng("assets/images/png/body_parts/female/abdomin.png"),
+ "57": imagePng("assets/images/png/body_parts/female/full_legs.png"),
+ "58": imagePng("assets/images/png/body_parts/female/upper_legs.png"),
+ "59": imagePng("assets/images/png/body_parts/female/lower_leg.png"),
+ "60": imagePng("assets/images/png/body_parts/female/bikini.png"),
+ "61": imagePng("assets/images/png/body_parts/female/bikini_line.png")
+ };
+
+ Widget? getCategoryImage(bool isMale, int category, String mappingCode) {
+ if (isMale) {
+ if (category == 1) {
+ return maleBodyMap![mappingCode]!;
+ }
+ if (category == 2) {
+ return maleFaceMap![mappingCode]!;
+ }
+ if (category == 11) {
+ return maleBodyRetouchMap![mappingCode]!;
+ }
+ } else {
+ if (category == 1) {
+ return femaleBodyMap![mappingCode]!;
+ }
+ if (category == 2) {
+ return femaleFaceMap![mappingCode]!;
+ }
+ if (category == 10) {
+ return femaleBodyBikiniMap![mappingCode]!;
+ }
+ if (category == 11) {
+ return femaleBodyRetouchMap![mappingCode]!;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/lib/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart b/lib/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart
new file mode 100644
index 0000000..99d5cd7
--- /dev/null
+++ b/lib/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart
@@ -0,0 +1,24 @@
+class DentalChiefComplaintsListResponseModel {
+ int? projectID;
+ int? iD;
+ String? name;
+ dynamic nameN;
+
+ DentalChiefComplaintsListResponseModel({this.projectID, this.iD, this.name, this.nameN});
+
+ DentalChiefComplaintsListResponseModel.fromJson(Map json) {
+ projectID = json['ProjectID'];
+ iD = json['ID'];
+ name = json['Name'];
+ nameN = json['NameN'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ProjectID'] = this.projectID;
+ data['ID'] = this.iD;
+ data['Name'] = this.name;
+ data['NameN'] = this.nameN;
+ return data;
+ }
+}
diff --git a/lib/features/book_appointments/models/resp_models/laser_body_parts.dart b/lib/features/book_appointments/models/resp_models/laser_body_parts.dart
new file mode 100644
index 0000000..d7d3fbd
--- /dev/null
+++ b/lib/features/book_appointments/models/resp_models/laser_body_parts.dart
@@ -0,0 +1,64 @@
+class LaserBodyPart {
+ int? id;
+ int? category;
+ String? bodyPart;
+ bool? fullBoadyPart;
+ bool? isRetouch;
+ String? timeDuration;
+ String? bodyPartN;
+ bool? isActive;
+ String? mappingCode;
+ int? procedureID;
+ int? orderNum;
+ String? categoryName;
+ String? categoryNameN;
+
+ LaserBodyPart(
+ {this.id,
+ this.category,
+ this.bodyPart,
+ this.fullBoadyPart,
+ this.isRetouch,
+ this.timeDuration,
+ this.bodyPartN,
+ this.isActive,
+ this.mappingCode,
+ this.procedureID,
+ this.orderNum,
+ this.categoryName,
+ this.categoryNameN});
+
+ LaserBodyPart.fromJson(Map json) {
+ id = json['Id'];
+ category = json['Category'];
+ bodyPart = json['BodyPart'];
+ fullBoadyPart = json['FullBoadyPart'];
+ isRetouch = json['IsRetouch'];
+ timeDuration = json['TimeDuration'];
+ bodyPartN = json['BodyPartN'];
+ isActive = json['IsActive'];
+ mappingCode = json['MappingCode'];
+ procedureID = json['ProcedureID'];
+ orderNum = json['OrderNum'];
+ categoryName = json['CategoryName'];
+ categoryNameN = json['CategoryNameN'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['Id'] = this.id;
+ data['Category'] = this.category;
+ data['BodyPart'] = this.bodyPart;
+ data['FullBoadyPart'] = this.fullBoadyPart;
+ data['IsRetouch'] = this.isRetouch;
+ data['TimeDuration'] = this.timeDuration;
+ data['BodyPartN'] = this.bodyPartN;
+ data['IsActive'] = this.isActive;
+ data['MappingCode'] = this.mappingCode;
+ data['ProcedureID'] = this.procedureID;
+ data['OrderNum'] = this.orderNum;
+ data['CategoryName'] = this.categoryName;
+ data['CategoryNameN'] = this.categoryNameN;
+ return data;
+ }
+}
diff --git a/lib/features/common/models/family_file_request.dart b/lib/features/common/models/family_file_request.dart
new file mode 100644
index 0000000..047b9af
--- /dev/null
+++ b/lib/features/common/models/family_file_request.dart
@@ -0,0 +1,57 @@
+import 'dart:convert';
+
+class FamilyFileRequest {
+ int? sharedPatientId;
+ String? sharedPatientIdentificationId;
+ int? searchType;
+ String? sharedPatientMobileNumber;
+ String? zipCode;
+ bool? isRegister;
+ int? patientStatus;
+ bool? isDentalAllowedBackend;
+ bool? isPatientExcluded;
+ int? responseID;
+
+ FamilyFileRequest({
+ this.sharedPatientId,
+ this.sharedPatientIdentificationId,
+ this.searchType,
+ this.sharedPatientMobileNumber,
+ this.zipCode,
+ this.isRegister,
+ this.patientStatus,
+ this.isDentalAllowedBackend,
+ this.isPatientExcluded,
+ this.responseID,
+ });
+
+ factory FamilyFileRequest.fromRawJson(String str) => FamilyFileRequest.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory FamilyFileRequest.fromJson(Map json) => FamilyFileRequest(
+ sharedPatientId: json["sharedPatientID"],
+ sharedPatientIdentificationId: json["sharedPatientIdentificationID"],
+ searchType: json["searchType"],
+ sharedPatientMobileNumber: json["sharedPatientMobileNumber"],
+ zipCode: json["zipCode"],
+ isRegister: json["isRegister"],
+ patientStatus: json["patientStatus"],
+ isDentalAllowedBackend: json["isDentalAllowedBackend"],
+ isPatientExcluded: json["IsPatientExcluded"],
+ responseID: json["ReponseID"],
+ );
+
+ Map toJson() => {
+ "SharedPatientID": sharedPatientId,
+ "SharedPatientIdentificationID": sharedPatientIdentificationId,
+ "SearchType": searchType,
+ "SharedPatientMobileNumber": sharedPatientMobileNumber,
+ "zipCode": zipCode,
+ "isRegister": isRegister,
+ "PatientStatus": patientStatus,
+ "isDentalAllowedBackend": isDentalAllowedBackend,
+ "IsPatientExcluded": isPatientExcluded,
+ "ReponseID": responseID,
+ };
+}
diff --git a/lib/features/insurance/insurance_repo.dart b/lib/features/insurance/insurance_repo.dart
index d367509..1aeb769 100644
--- a/lib/features/insurance/insurance_repo.dart
+++ b/lib/features/insurance/insurance_repo.dart
@@ -3,6 +3,7 @@ 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/insurance/models/resp_models/patient_insurance_approval_response_model.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_card_history.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_update_response_model.dart';
@@ -14,6 +15,8 @@ abstract class InsuranceRepo {
Future>>> getPatientInsuranceCardHistory();
Future>> getPatientInsuranceDetailsForUpdate({required String patientId, required String identificationNo});
+
+ Future>>> getPatientInsuranceApprovalsList();
}
class InsuranceRepoImp implements InsuranceRepo {
@@ -66,7 +69,6 @@ class InsuranceRepoImp implements InsuranceRepo {
@override
Future>>> getPatientInsuranceCardHistory() async {
Map mapDevice = {};
-
try {
GenericApiModel>? apiResponse;
Failure? failure;
@@ -144,4 +146,41 @@ class InsuranceRepoImp implements InsuranceRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>>> getPatientInsuranceApprovalsList() async {
+ Map mapDevice = {};
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_PAtIENTS_INSURANCE_APPROVALS,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['HIS_Approval_List'];
+
+ final insuranceCardsList = list.map((item) => InsuranceApprovalResponseModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: insuranceCardsList,
+ );
+ } 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/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart
index 0bcf30f..363ad28 100644
--- a/lib/features/insurance/insurance_view_model.dart
+++ b/lib/features/insurance/insurance_view_model.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart';
+import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_card_history.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart';
import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_update_response_model.dart';
@@ -14,11 +15,14 @@ class InsuranceViewModel extends ChangeNotifier {
bool isInsuranceDataToBeLoaded = true;
+ bool isInsuranceApprovalsLoading = false;
+
InsuranceRepo insuranceRepo;
ErrorHandlerService errorHandlerService;
List patientInsuranceList = [];
List patientInsuranceCardHistoryList = [];
+ List patientInsuranceApprovalsList = [];
PatientInsuranceUpdateResponseModel? patientInsuranceUpdateResponseModel;
@@ -34,6 +38,7 @@ class InsuranceViewModel extends ChangeNotifier {
isInsuranceHistoryLoading = true;
isInsuranceDetailsLoading = true;
isInsuranceUpdateDetailsLoading = true;
+ isInsuranceApprovalsLoading = true;
notifyListeners();
}
@@ -57,6 +62,11 @@ class InsuranceViewModel extends ChangeNotifier {
notifyListeners();
}
+ setIsInsuranceApprovalsLoading(bool val) {
+ isInsuranceApprovalsLoading = val;
+ notifyListeners();
+ }
+
Future getPatientInsuranceDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isInsuranceDataToBeLoaded) return;
@@ -130,4 +140,27 @@ class InsuranceViewModel extends ChangeNotifier {
},
);
}
+
+ Future getPatientInsuranceApprovalsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await insuranceRepo.getPatientInsuranceApprovalsList();
+
+ result.fold(
+ (failure) async {
+ isInsuranceApprovalsLoading = false;
+ notifyListeners();
+ },
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ patientInsuranceApprovalsList = apiResponse.data!;
+ isInsuranceApprovalsLoading = false;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
}
diff --git a/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart b/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart
new file mode 100644
index 0000000..f272f2d
--- /dev/null
+++ b/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart
@@ -0,0 +1,465 @@
+class InsuranceApprovalResponseModel {
+ String? setupID;
+ int? projectID;
+ int? approvalNo;
+ String? approvalDate;
+ int? patientType;
+ int? patientID;
+ int? companyID;
+ int? subCategoryID;
+ int? doctorID;
+ int? clinicID;
+ int? approvalType;
+ String? inpatientApprovalSubType;
+ String? validFrom;
+ String? vaildDays;
+ String? validTo;
+ bool? isApprovalOnGross;
+ bool? isPackage;
+ int? requestedAmount;
+ int? actualApprovedAmount;
+ int? aviliableAmount;
+ String? companyApprovalNo;
+ int? progNoteOrderNo;
+ String? submitOn;
+ String? receiptOn;
+ String? remarks1;
+ String? remarks2;
+ int? status;
+ String? feedbackStatusBy;
+ String? feedbackStatus;
+ String? feedbackStatusOn;
+ int? authorizerID;
+ String? expiryDate;
+ int? appointmentNo;
+ int? admissionNo;
+ int? admissionRequestNo;
+ int? createdBy;
+ String? createdOn;
+ int? editedBy;
+ String? editedOn;
+ String? rowVer;
+ bool? isAddlDiscApplied;
+ int? inProgressReasonID;
+ String? extendedBy;
+ String? extendedOn;
+ int? subPolicyNo;
+ int? noOrderAuthorizerID;
+ bool? isVerbalApproval;
+ String? subStatus;
+ bool? isNotificationSend;
+ String? eApprovalStatus;
+ String? eApprovalRemarks;
+ bool? isEmailSentOnDelayApproval;
+ int? eAuthorizationID;
+ InsuranceApprovalDetails? apporvalDetails;
+ String? approvalStatusDescption;
+ String? clinicName;
+ String? clinicNameN;
+ String? companyName;
+ String? doctorImageURL;
+ String? doctorName;
+ String? doctorNameN;
+ int? doctorRate;
+ String? doctorTitle;
+ int? gender;
+ String? genderDescription;
+ bool? isActiveDoctorProfile;
+ bool? isExecludeDoctor;
+ bool? isInOutPatient;
+ String? isInOutPatientDescription;
+ String? isInOutPatientDescriptionN;
+ bool? isLiveCareAppointment;
+ String? projectName;
+ String? projectNameN;
+ String? qR;
+ List? speciality;
+ String? strApprovalDate;
+ String? strExpiryDate;
+ String? strSubmitDate;
+ int? totaUnUsedCount;
+ int? unUsedCount;
+
+ InsuranceApprovalResponseModel(
+ {this.setupID,
+ this.projectID,
+ this.approvalNo,
+ this.approvalDate,
+ this.patientType,
+ this.patientID,
+ this.companyID,
+ this.subCategoryID,
+ this.doctorID,
+ this.clinicID,
+ this.approvalType,
+ this.inpatientApprovalSubType,
+ this.validFrom,
+ this.vaildDays,
+ this.validTo,
+ this.isApprovalOnGross,
+ this.isPackage,
+ this.requestedAmount,
+ this.actualApprovedAmount,
+ this.aviliableAmount,
+ this.companyApprovalNo,
+ this.progNoteOrderNo,
+ this.submitOn,
+ this.receiptOn,
+ this.remarks1,
+ this.remarks2,
+ this.status,
+ this.feedbackStatusBy,
+ this.feedbackStatus,
+ this.feedbackStatusOn,
+ this.authorizerID,
+ this.expiryDate,
+ this.appointmentNo,
+ this.admissionNo,
+ this.admissionRequestNo,
+ this.createdBy,
+ this.createdOn,
+ this.editedBy,
+ this.editedOn,
+ this.rowVer,
+ this.isAddlDiscApplied,
+ this.inProgressReasonID,
+ this.extendedBy,
+ this.extendedOn,
+ this.subPolicyNo,
+ this.noOrderAuthorizerID,
+ this.isVerbalApproval,
+ this.subStatus,
+ this.isNotificationSend,
+ this.eApprovalStatus,
+ this.eApprovalRemarks,
+ this.isEmailSentOnDelayApproval,
+ this.eAuthorizationID,
+ this.apporvalDetails,
+ this.approvalStatusDescption,
+ this.clinicName,
+ this.clinicNameN,
+ this.companyName,
+ this.doctorImageURL,
+ this.doctorName,
+ this.doctorNameN,
+ this.doctorRate,
+ this.doctorTitle,
+ this.gender,
+ this.genderDescription,
+ this.isActiveDoctorProfile,
+ this.isExecludeDoctor,
+ this.isInOutPatient,
+ this.isInOutPatientDescription,
+ this.isInOutPatientDescriptionN,
+ this.isLiveCareAppointment,
+ this.projectName,
+ this.projectNameN,
+ this.qR,
+ this.speciality,
+ this.strApprovalDate,
+ this.strExpiryDate,
+ this.strSubmitDate,
+ this.totaUnUsedCount,
+ this.unUsedCount});
+
+ InsuranceApprovalResponseModel.fromJson(Map json) {
+ setupID = json['SetupID'];
+ projectID = json['ProjectID'];
+ approvalNo = json['ApprovalNo'];
+ approvalDate = json['ApprovalDate'];
+ patientType = json['PatientType'];
+ patientID = json['PatientID'];
+ companyID = json['CompanyID'];
+ subCategoryID = json['SubCategoryID'];
+ doctorID = json['DoctorID'];
+ clinicID = json['ClinicID'];
+ approvalType = json['ApprovalType'];
+ inpatientApprovalSubType = json['InpatientApprovalSubType'];
+ validFrom = json['ValidFrom'];
+ vaildDays = json['VaildDays'];
+ validTo = json['ValidTo'];
+ isApprovalOnGross = json['IsApprovalOnGross'];
+ isPackage = json['IsPackage'];
+ requestedAmount = json['RequestedAmount'];
+ actualApprovedAmount = json['ActualApprovedAmount'];
+ aviliableAmount = json['AviliableAmount'];
+ companyApprovalNo = json['CompanyApprovalNo'];
+ progNoteOrderNo = json['ProgNoteOrderNo'];
+ submitOn = json['SubmitOn'];
+ receiptOn = json['ReceiptOn'];
+ remarks1 = json['Remarks1'];
+ remarks2 = json['Remarks2'];
+ status = json['Status'];
+ feedbackStatusBy = json['FeedbackStatusBy'];
+ feedbackStatus = json['FeedbackStatus'];
+ feedbackStatusOn = json['FeedbackStatusOn'];
+ authorizerID = json['AuthorizerID'];
+ expiryDate = json['ExpiryDate'];
+ appointmentNo = json['AppointmentNo'];
+ admissionNo = json['AdmissionNo'];
+ admissionRequestNo = json['AdmissionRequestNo'];
+ createdBy = json['CreatedBy'];
+ createdOn = json['CreatedOn'];
+ editedBy = json['EditedBy'];
+ editedOn = json['EditedOn'];
+ rowVer = json['RowVer'];
+ isAddlDiscApplied = json['IsAddlDiscApplied'];
+ inProgressReasonID = json['InProgressReasonID'];
+ extendedBy = json['ExtendedBy'];
+ extendedOn = json['ExtendedOn'];
+ subPolicyNo = json['SubPolicyNo'];
+ noOrderAuthorizerID = json['NoOrderAuthorizerID'];
+ isVerbalApproval = json['isVerbalApproval'];
+ subStatus = json['SubStatus'];
+ isNotificationSend = json['IsNotificationSend'];
+ eApprovalStatus = json['EApprovalStatus'];
+ eApprovalRemarks = json['EApprovalRemarks'];
+ isEmailSentOnDelayApproval = json['IsEmailSentOnDelayApproval'];
+ eAuthorizationID = json['EAuthorizationID'];
+ if (json['ApporvalDetails'] != null && json['ApporvalDetails'].length != 0) {
+ apporvalDetails = InsuranceApprovalDetails.fromJson(json['ApporvalDetails'][0]);
+ }
+ approvalStatusDescption = json['ApprovalStatusDescption'];
+ clinicName = json['ClinicName'];
+ clinicNameN = json['ClinicNameN'];
+ companyName = json['CompanyName'];
+ doctorImageURL = json['DoctorImageURL'];
+ doctorName = json['DoctorName'];
+ doctorNameN = json['DoctorNameN'];
+ doctorRate = json['DoctorRate'];
+ doctorTitle = json['DoctorTitle'];
+ gender = json['Gender'];
+ genderDescription = json['GenderDescription'];
+ isActiveDoctorProfile = json['IsActiveDoctorProfile'];
+ isExecludeDoctor = json['IsExecludeDoctor'];
+ isInOutPatient = json['IsInOutPatient'];
+ isInOutPatientDescription = json['IsInOutPatientDescription'];
+ isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN'];
+ isLiveCareAppointment = json['IsLiveCareAppointment'];
+ projectName = json['ProjectName'];
+ projectNameN = json['ProjectNameN'];
+ qR = json['QR'];
+ if (json['Speciality'] != null) speciality = json['Speciality'].cast();
+ strApprovalDate = json['StrApprovalDate'];
+ strExpiryDate = json['StrExpiryDate'];
+ strSubmitDate = json['StrSubmitDate'];
+ totaUnUsedCount = json['TotaUnUsedCount'];
+ unUsedCount = json['UnUsedCount'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['SetupID'] = this.setupID;
+ data['ProjectID'] = this.projectID;
+ data['ApprovalNo'] = this.approvalNo;
+ data['ApprovalDate'] = this.approvalDate;
+ data['PatientType'] = this.patientType;
+ data['PatientID'] = this.patientID;
+ data['CompanyID'] = this.companyID;
+ data['SubCategoryID'] = this.subCategoryID;
+ data['DoctorID'] = this.doctorID;
+ data['ClinicID'] = this.clinicID;
+ data['ApprovalType'] = this.approvalType;
+ data['InpatientApprovalSubType'] = this.inpatientApprovalSubType;
+ data['ValidFrom'] = this.validFrom;
+ data['VaildDays'] = this.vaildDays;
+ data['ValidTo'] = this.validTo;
+ data['IsApprovalOnGross'] = this.isApprovalOnGross;
+ data['IsPackage'] = this.isPackage;
+ data['RequestedAmount'] = this.requestedAmount;
+ data['ActualApprovedAmount'] = this.actualApprovedAmount;
+ data['AviliableAmount'] = this.aviliableAmount;
+ data['CompanyApprovalNo'] = this.companyApprovalNo;
+ data['ProgNoteOrderNo'] = this.progNoteOrderNo;
+ data['SubmitOn'] = this.submitOn;
+ data['ReceiptOn'] = this.receiptOn;
+ data['Remarks1'] = this.remarks1;
+ data['Remarks2'] = this.remarks2;
+ data['Status'] = this.status;
+ data['FeedbackStatusBy'] = this.feedbackStatusBy;
+ data['FeedbackStatus'] = this.feedbackStatus;
+ data['FeedbackStatusOn'] = this.feedbackStatusOn;
+ data['AuthorizerID'] = this.authorizerID;
+ data['ExpiryDate'] = this.expiryDate;
+ data['AppointmentNo'] = this.appointmentNo;
+ data['AdmissionNo'] = this.admissionNo;
+ data['AdmissionRequestNo'] = this.admissionRequestNo;
+ data['CreatedBy'] = this.createdBy;
+ data['CreatedOn'] = this.createdOn;
+ data['EditedBy'] = this.editedBy;
+ data['EditedOn'] = this.editedOn;
+ data['RowVer'] = this.rowVer;
+ data['IsAddlDiscApplied'] = this.isAddlDiscApplied;
+ data['InProgressReasonID'] = this.inProgressReasonID;
+ data['ExtendedBy'] = this.extendedBy;
+ data['ExtendedOn'] = this.extendedOn;
+ data['SubPolicyNo'] = this.subPolicyNo;
+ data['NoOrderAuthorizerID'] = this.noOrderAuthorizerID;
+ data['isVerbalApproval'] = this.isVerbalApproval;
+ data['SubStatus'] = this.subStatus;
+ data['IsNotificationSend'] = this.isNotificationSend;
+ data['EApprovalStatus'] = this.eApprovalStatus;
+ data['EApprovalRemarks'] = this.eApprovalRemarks;
+ data['IsEmailSentOnDelayApproval'] = this.isEmailSentOnDelayApproval;
+ data['EAuthorizationID'] = this.eAuthorizationID;
+ if (this.apporvalDetails != null) {
+ data['ApporvalDetails'] = this.apporvalDetails!.toJson;
+ }
+ data['ApprovalStatusDescption'] = this.approvalStatusDescption;
+ data['ClinicName'] = this.clinicName;
+ data['ClinicNameN'] = this.clinicNameN;
+ data['CompanyName'] = this.companyName;
+ data['DoctorImageURL'] = this.doctorImageURL;
+ data['DoctorName'] = this.doctorName;
+ data['DoctorNameN'] = this.doctorNameN;
+ data['DoctorRate'] = this.doctorRate;
+ data['DoctorTitle'] = this.doctorTitle;
+ data['Gender'] = this.gender;
+ data['GenderDescription'] = this.genderDescription;
+ data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile;
+ data['IsExecludeDoctor'] = this.isExecludeDoctor;
+ data['IsInOutPatient'] = this.isInOutPatient;
+ data['IsInOutPatientDescription'] = this.isInOutPatientDescription;
+ data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN;
+ data['IsLiveCareAppointment'] = this.isLiveCareAppointment;
+ data['ProjectName'] = this.projectName;
+ data['ProjectNameN'] = this.projectNameN;
+ data['QR'] = this.qR;
+ data['Speciality'] = this.speciality;
+ data['StrApprovalDate'] = this.strApprovalDate;
+ data['StrExpiryDate'] = this.strExpiryDate;
+ data['StrSubmitDate'] = this.strSubmitDate;
+ data['TotaUnUsedCount'] = this.totaUnUsedCount;
+ data['UnUsedCount'] = this.unUsedCount;
+ return data;
+ }
+}
+
+class InsuranceApprovalDetails {
+ int? setupID;
+ int? projectID;
+ int? approvalNo;
+ int? lineItemNo;
+ int? orderType;
+ int? procedureID;
+ int? toothNo;
+ int? price;
+ int? approvedAmount;
+ String? unapprovedPatientShare;
+ int? waivedAmount;
+ String? discountType;
+ int? discountValue;
+ String? shareType;
+ String? patientShareTypeValue;
+ String? companyShareTypeValue;
+ String? patientShare;
+ String? companyShare;
+ int? deductableAmount;
+ String? disapprovedRemarks;
+ int? progNoteOrderNo;
+ int? progNoteLineItemNo;
+ String? invoiceTransactionType;
+ int? invoiceNo;
+ String? procedureName;
+ String? procedureNameN;
+ String? status;
+ bool? isInvoiced;
+ String? isInvoicedDesc;
+
+ InsuranceApprovalDetails(
+ {this.setupID,
+ this.projectID,
+ this.approvalNo,
+ this.lineItemNo,
+ this.orderType,
+ this.procedureID,
+ this.toothNo,
+ this.price,
+ this.approvedAmount,
+ this.unapprovedPatientShare,
+ this.waivedAmount,
+ this.discountType,
+ this.discountValue,
+ this.shareType,
+ this.patientShareTypeValue,
+ this.companyShareTypeValue,
+ this.patientShare,
+ this.companyShare,
+ this.deductableAmount,
+ this.disapprovedRemarks,
+ this.progNoteOrderNo,
+ this.progNoteLineItemNo,
+ this.invoiceTransactionType,
+ this.invoiceNo,
+ this.procedureName,
+ this.procedureNameN,
+ this.status,
+ this.isInvoiced,
+ this.isInvoicedDesc});
+
+ InsuranceApprovalDetails.fromJson(Map json) {
+ setupID = json['SetupID'];
+ projectID = json['ProjectID'];
+ approvalNo = json['ApprovalNo'];
+ lineItemNo = json['LineItemNo'];
+ orderType = json['OrderType'];
+ procedureID = json['ProcedureID'];
+ toothNo = json['ToothNo'];
+ price = json['Price'];
+ approvedAmount = json['ApprovedAmount'];
+ unapprovedPatientShare = json['UnapprovedPatientShare'];
+ waivedAmount = json['WaivedAmount'];
+ discountType = json['DiscountType'];
+ discountValue = json['DiscountValue'];
+ shareType = json['ShareType'];
+ patientShareTypeValue = json['PatientShareTypeValue'];
+ companyShareTypeValue = json['CompanyShareTypeValue'];
+ patientShare = json['PatientShare'];
+ companyShare = json['CompanyShare'];
+ deductableAmount = json['DeductableAmount'];
+ disapprovedRemarks = json['DisapprovedRemarks'];
+ progNoteOrderNo = json['ProgNoteOrderNo'];
+ progNoteLineItemNo = json['ProgNoteLineItemNo'];
+ invoiceTransactionType = json['InvoiceTransactionType'];
+ invoiceNo = json['InvoiceNo'];
+ procedureName = json['ProcedureName'];
+ procedureNameN = json['ProcedureNameN'];
+ status = json['Status'];
+ isInvoiced = json['IsInvoiced'];
+ isInvoicedDesc = json['IsInvoicedDesc'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['SetupID'] = this.setupID;
+ data['ProjectID'] = this.projectID;
+ data['ApprovalNo'] = this.approvalNo;
+ data['LineItemNo'] = this.lineItemNo;
+ data['OrderType'] = this.orderType;
+ data['ProcedureID'] = this.procedureID;
+ data['ToothNo'] = this.toothNo;
+ data['Price'] = this.price;
+ data['ApprovedAmount'] = this.approvedAmount;
+ data['UnapprovedPatientShare'] = this.unapprovedPatientShare;
+ data['WaivedAmount'] = this.waivedAmount;
+ data['DiscountType'] = this.discountType;
+ data['DiscountValue'] = this.discountValue;
+ data['ShareType'] = this.shareType;
+ data['PatientShareTypeValue'] = this.patientShareTypeValue;
+ data['CompanyShareTypeValue'] = this.companyShareTypeValue;
+ data['PatientShare'] = this.patientShare;
+ data['CompanyShare'] = this.companyShare;
+ data['DeductableAmount'] = this.deductableAmount;
+ data['DisapprovedRemarks'] = this.disapprovedRemarks;
+ data['ProgNoteOrderNo'] = this.progNoteOrderNo;
+ data['ProgNoteLineItemNo'] = this.progNoteLineItemNo;
+ data['InvoiceTransactionType'] = this.invoiceTransactionType;
+ data['InvoiceNo'] = this.invoiceNo;
+ data['ProcedureName'] = this.procedureName;
+ data['ProcedureNameN'] = this.procedureNameN;
+ data['Status'] = this.status;
+ data['IsInvoiced'] = this.isInvoiced;
+ data['IsInvoicedDesc'] = this.isInvoicedDesc;
+ return data;
+ }
+}
diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart
index 8a397e3..9f713ac 100644
--- a/lib/features/lab/lab_view_model.dart
+++ b/lib/features/lab/lab_view_model.dart
@@ -25,6 +25,8 @@ class LabViewModel extends ChangeNotifier {
bool isGraphVisible = true;
bool shouldShowGraph = true;
+ bool isLabNeedToLoad = true;
+
LabRepo labRepo;
ErrorHandlerService errorHandlerService;
NavigationService navigationService;
@@ -33,6 +35,7 @@ class LabViewModel extends ChangeNotifier {
List filteredLabOrders = [];
List tempLabOrdersList = [];
String labSpecialResult = "";
+ List labOrderTests = [];
PatientLabOrdersResponseModel? currentlySelectedPatientOrder;
@@ -71,17 +74,29 @@ class LabViewModel extends ChangeNotifier {
required this.navigationService});
initLabProvider() {
- patientLabOrders.clear();
- filteredLabOrders.clear();
- isLabOrdersLoading = true;
- isLabResultsLoading = true;
- getPatientLabOrders();
+ if (isLabNeedToLoad) {
+ patientLabOrders.clear();
+ filteredLabOrders.clear();
+ labOrderTests.clear();
+ isLabOrdersLoading = true;
+ isLabResultsLoading = true;
+ getPatientLabOrders();
+ }
+ notifyListeners();
+ }
+
+ setIsLabNeedToLoad(bool value) {
+ isLabNeedToLoad = value;
notifyListeners();
}
Future getPatientLabOrders({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ if (!isLabNeedToLoad) return;
+
+ isLabOrdersLoading = true;
patientLabOrders.clear();
uniqueTests.clear();
+ labOrderTests.clear();
uniqueTests = {};
notifyListeners();
@@ -105,6 +120,7 @@ class LabViewModel extends ChangeNotifier {
isLabResultsLoading = false;
filterSuggestions();
getUniqueTestDescription();
+ isLabNeedToLoad = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
@@ -151,6 +167,9 @@ class LabViewModel extends ChangeNotifier {
createdOn: item.createdOn,
model: item))
};
+ for (var element in uniqueTests) {
+ labOrderTests.add(element.description ?? "");
+ }
}
Future getPatientLabResultByHospital(
@@ -165,6 +184,7 @@ class LabViewModel extends ChangeNotifier {
result.fold(
(failure) async {
isLabResultByHospitalLoading = false;
+ notifyListeners();
// await errorHandlerService.handleError(failure: failure);
},
(apiResponse) {
diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart
index 7077fd0..a460d9f 100644
--- a/lib/features/medical_file/medical_file_repo.dart
+++ b/lib/features/medical_file/medical_file_repo.dart
@@ -25,13 +25,19 @@ abstract class MedicalFileRepo {
Future>> getPatientMedicalReportPDF(PatientMedicalReportResponseModel patientMedicalReportResponseModel, AuthenticatedUser authenticatedUser);
- Future>>> getPatientFamilyFiles();
+ Future>>> getPatientFamilyFiles(int? status, int patientId);
- Future>>> addFamilyFile({required dynamic request});
+ Future>>> getAllPendingRecordsByResponseId({required Map request});
+
+ Future>> addFamilyFile({required dynamic request});
Future>>> getPatientAppointmentsForMedicalReport();
Future>> insertRequestForMedicalReport({required PatientAppointmentHistoryResponseModel appointmentHistoryResponseModel});
+
+ Future>> removeFamilyFile({required int? id});
+
+ Future>> acceptRejectFamilyFile({required int? id, required int? status});
}
class MedicalFileRepoImp implements MedicalFileRepo {
@@ -279,13 +285,13 @@ class MedicalFileRepoImp implements MedicalFileRepo {
}
@override
- Future>>> getPatientFamilyFiles() async {
+ Future>>> getPatientFamilyFiles(int? status, int patientID) async {
try {
GenericApiModel>? apiResponse;
Failure? failure;
await apiClient.post(
- FAMILY_FILES,
- body: {"Status": 3},
+ ApiConsts.getAllSharedRecordsByStatus,
+ body: {if (status != null) "Status": status, "PatientID": patientID},
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
@@ -318,9 +324,44 @@ class MedicalFileRepoImp implements MedicalFileRepo {
}
@override
- Future>>> addFamilyFile({dynamic request}) async {
+ Future>>> getAllPendingRecordsByResponseId({required Map request}) async {
try {
- GenericApiModel>? apiResponse;
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.getAllPendingRecordsByResponseId,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['GetAllPendingRecordsList'];
+ final familyLists = list.map((item) => FamilyFileResponseModelLists.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: familyLists,
+ );
+ } 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>> addFamilyFile({dynamic request}) async {
+ try {
+ GenericApiModel? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.addFamilyFile,
@@ -330,17 +371,82 @@ class MedicalFileRepoImp implements MedicalFileRepo {
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
- print(response);
- // final list = response['GetAllSharedRecordsByStatusList'];
- //
- // final familyLists = list.map((item) => FamilyFileResponseModelLists.fromJson(item as Map)).toList().cast();
- //
- // apiResponse = GenericApiModel>(
- // messageStatus: messageStatus,
- // statusCode: statusCode,
- // errorMessage: null,
- // data: familyLists,
- // );
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: response["ShareFamilyFileObj"] ?? null,
+ );
+ } 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>> removeFamilyFile({required int? id}) async {
+ Map request = {};
+ request["ID"] = id;
+ request['IsActive'] = false;
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.removeFileFromFamilyMembers,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>> acceptRejectFamilyFile({required int? id, required int? status}) async {
+ Map request = {};
+ request["ID"] = id;
+ request['Status'] = status;
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.acceptAndRejectFamilyFile,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: response,
+ );
} catch (e) {
failure = DataParsingFailure(e.toString());
}
diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart
index 3f0573f..b5d9d03 100644
--- a/lib/features/medical_file/medical_file_view_model.dart
+++ b/lib/features/medical_file/medical_file_view_model.dart
@@ -1,7 +1,15 @@
+import 'dart:convert';
+import 'dart:developer';
+
import 'package:flutter/material.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/enums.dart';
+import 'package:hmg_patient_app_new/core/utils/request_utils.dart';
+import 'package:hmg_patient_app_new/extensions/string_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/common/models/family_file_request.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart';
@@ -10,6 +18,8 @@ import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine
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/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/widgets/loader/bottomsheet_loader.dart';
class MedicalFileViewModel extends ChangeNotifier {
int selectedTabIndex = 0;
@@ -34,13 +44,26 @@ class MedicalFileViewModel extends ChangeNotifier {
PatientAppointmentHistoryResponseModel? patientMedicalReportSelectedAppointment;
List patientFamilyFiles = [];
+ List pendingFamilyFiles = [];
String patientSickLeavePDFBase64 = "";
String patientMedicalReportPDFBase64 = "";
int selectedMedicalReportsTabIndex = 0;
+ int _selectedFamilyFileTabIndex = 0;
+
+ int get getSelectedFamilyFileTabIndex => _selectedFamilyFileTabIndex;
+
+ set setSelectedFamilyFileTabIndex(int value) {
+ if (_selectedFamilyFileTabIndex != value) {
+ _selectedFamilyFileTabIndex = value;
+ notifyListeners();
+ }
+ }
+
static final DialogService _dialogService = getIt.get();
- AppState _appState = getIt();
+ final AppState _appState = getIt();
+ AuthenticationViewModel authVM = getIt.get();
MedicalFileViewModel({required this.medicalFileRepo, required this.errorHandlerService});
@@ -64,6 +87,11 @@ class MedicalFileViewModel extends ChangeNotifier {
notifyListeners();
}
+ void onFamilyFileTabChange(int index) {
+ setSelectedFamilyFileTabIndex = index;
+ notifyListeners();
+ }
+
setIsPatientVaccineListLoading(bool isLoading) {
isPatientVaccineListLoading = isLoading;
notifyListeners();
@@ -247,8 +275,8 @@ class MedicalFileViewModel extends ChangeNotifier {
);
}
- Future getFamilyFiles({Function(dynamic)? onSuccess, Function(String)? onError}) async {
- final result = await medicalFileRepo.getPatientFamilyFiles();
+ Future getFamilyFiles({int? status, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await medicalFileRepo.getPatientFamilyFiles(status, _appState.getSuperUserID != null ? _appState.getSuperUserID! : _appState.getAuthenticatedUser()!.patientId!);
result.fold(
(failure) async => await errorHandlerService.handleError(
@@ -261,16 +289,85 @@ class MedicalFileViewModel extends ChangeNotifier {
if (apiResponse.messageStatus == 2) {
_dialogService.showErrorBottomSheet(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
- patientFamilyFiles = apiResponse.data!;
- patientFamilyFiles.insert(
- 0,
- FamilyFileResponseModelLists(
- patientId: _appState.getAuthenticatedUser()!.patientId,
- patientName: '${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}',
- isActive: true,
- gender: _appState.getAuthenticatedUser()!.gender!,
- responseId: _appState.getAuthenticatedUser()!.patientId),
- );
+ if (apiResponse.data != null) {
+ // Add current user as the first active family file
+ final currentUser = _appState.getAuthenticatedUser()!;
+ final currentUserFamilyFile = FamilyFileResponseModelLists(
+ patientId: currentUser.patientId,
+ patientName: '${currentUser.firstName!} ${currentUser.lastName!}',
+ isActive: true,
+ gender: currentUser.gender!,
+ responseId: currentUser.patientId,
+ age: currentUser.age,
+ mobileNumber: currentUser.mobileNumber,
+ patientIdenficationNumber: currentUser.patientIdentificationNo,
+ emaiLAddress: currentUser.emailAddress,
+ genderDescription: currentUser.genderDescription,
+ );
+
+ // Clear and start fresh with current user
+ patientFamilyFiles.clear();
+ patientFamilyFiles.add(currentUserFamilyFile);
+
+ final List activeFamilyFiles = [];
+ final List pendingFamilyFiles = [];
+
+ for (var element in apiResponse.data!) {
+ if (element.status == null) {
+ continue;
+ }
+
+ final isPending = element.status == FamilyFileEnum.pending.toInt || element.status == FamilyFileEnum.rejected.toInt;
+ final isActive = element.status == FamilyFileEnum.active.toInt;
+
+ if (!isPending && !isActive) {
+ continue;
+ }
+
+ final familyFile = FamilyFileResponseModelLists(
+ id: element.id,
+ patientId: element.patientId,
+ patientName: element.patientName!,
+ isActive: element.isActive,
+ gender: element.gender!,
+ responseId: element.responseId,
+ mobileNumber: element.mobileNumber,
+ age: element.age,
+ patientIdenficationNumber: element.patientIdenficationNumber,
+ relationship: element.relationship,
+ relationshipId: element.relationshipId,
+ relationshipN: element.relationshipN,
+ status: element.status,
+ statusDescription: element.statusDescription,
+ createdOn: element.createdOn,
+ editedOn: element.editedOn,
+ patientDataVerified: element.patientDataVerified,
+ regionId: element.regionId,
+ familyRegionId: element.familyRegionId,
+ genderDescription: element.genderDescription,
+ genderImage: element.genderImage,
+ emaiLAddress: element.emaiLAddress,
+ );
+
+ if (isPending) {
+ familyFile.isRequestFromMySide = true;
+ pendingFamilyFiles.add(familyFile);
+ }
+ if (isActive) {
+ activeFamilyFiles.add(familyFile);
+ }
+ }
+
+ for (var activeFile in activeFamilyFiles) {
+ if (!patientFamilyFiles.any((e) => e.responseId == activeFile.responseId)) {
+ patientFamilyFiles.add(activeFile);
+ }
+ }
+
+ this.pendingFamilyFiles.clear();
+ this.pendingFamilyFiles.addAll(pendingFamilyFiles);
+ }
+
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
@@ -280,39 +377,151 @@ class MedicalFileViewModel extends ChangeNotifier {
);
}
- Future switchFamilyFiles({Function(dynamic)? onSuccess, Function(String)? onError}) async {
- final result = await medicalFileRepo.getPatientFamilyFiles();
+ Future getAllPendingRecordsByResponseId() async {
+ AppState appState = getIt();
+ final result = await medicalFileRepo.getAllPendingRecordsByResponseId(request: {'ResponseID': appState.getAuthenticatedUser()!.patientId ?? "0", "Status": 2});
result.fold(
- (failure) async => await errorHandlerService.handleError(
- failure: failure,
- onOkPressed: () {
- onError!(failure.message);
- },
- ),
+ (failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
_dialogService.showErrorBottomSheet(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
- patientFamilyFiles = apiResponse.data!;
- patientFamilyFiles.insert(
- 0,
- FamilyFileResponseModelLists(
- patientId: _appState.getAuthenticatedUser()!.patientId,
- patientName: '${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}',
- isActive: true,
- gender: _appState.getAuthenticatedUser()!.gender!,
- responseId: _appState.getAuthenticatedUser()!.patientId),
- );
- notifyListeners();
- if (onSuccess != null) {
- onSuccess(apiResponse);
+ if (apiResponse.data != null) {
+ final List tempPendingFamilyFiles = [];
+ for (var element in apiResponse.data!) {
+ if (element.status != null && element.status == FamilyFileEnum.pending.toInt || element.status == FamilyFileEnum.active.toInt) {
+ tempPendingFamilyFiles.add(FamilyFileResponseModelLists(
+ id: element.id,
+ patientId: element.patientId,
+ patientName: element.patientName!,
+ isActive: element.status,
+ gender: element.gender,
+ responseId: element.patientId,
+ mobileNumber: element.mobileNumber,
+ age: element.age,
+ patientIdenficationNumber: element.patientIdenficationNumber,
+ relationship: element.relationship,
+ relationshipId: element.relationshipId,
+ relationshipN: element.relationshipN,
+ status: element.status,
+ statusDescription: element.statusDescription,
+ createdOn: element.createdOn,
+ editedOn: element.editedOn,
+ patientDataVerified: element.patientDataVerified,
+ regionId: element.regionId,
+ familyRegionId: element.familyRegionId,
+ genderDescription: element.genderDescription,
+ genderImage: element.genderImage,
+ emaiLAddress: element.emaiLAddress));
+ }
+ }
+ // pendingFamilyFiles.addAll(tempPendingFamilyFiles.where((element) => !pendingFamilyFiles.any((e) => e.responseId == element.responseId)));
+ pendingFamilyFiles.addAll(tempPendingFamilyFiles.where((element) => !pendingFamilyFiles.any((e) => e.patientId == element.patientId)));
}
+ notifyListeners();
}
},
);
}
+ Future switchFamilyFiles({Function(dynamic)? onSuccess, int? responseID, int? patientID, String? phoneNumber, Function(String)? onError}) async {
+ authVM.phoneNumberController.text = phoneNumber!.startsWith("0") ? phoneNumber.replaceFirst("0", "") : phoneNumber;
+
+ await authVM.checkActivationCode(
+ activationCode: '0000',
+ otpTypeEnum: OTPTypeEnum.sms,
+ onWrongActivationCode: (String? str) {},
+ responseID: responseID,
+ isFormFamilyFile: false,
+ isSwitchUser: true,
+ patientID: patientID,
+ );
+ }
+
+ Future addFamilyFile({required OTPTypeEnum otpTypeEnum}) async {
+ LoaderBottomSheet.showLoader();
+ AuthenticationViewModel authVM = getIt.get();
+ NavigationService navigationService = getIt.get();
+ FamilyFileRequest request =
+ await RequestUtils.getAddFamilyRequest(nationalIDorFile: authVM.nationalIdController.text, mobileNo: authVM.phoneNumberController.text, countryCode: authVM.selectedCountrySignup.countryCode);
+
+ final resultEither = await medicalFileRepo.addFamilyFile(request: request.toJson());
+ resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) async {
+ if (apiResponse.messageStatus == 2) {
+ LoaderBottomSheet.hideLoader();
+ _dialogService.showErrorBottomSheet(
+ message: apiResponse.errorMessage!,
+ onOkPressed: () {
+ navigationService.pop();
+ });
+ } else if (apiResponse.messageStatus == 1) {
+ if (apiResponse.data != null) {
+ request.isPatientExcluded = apiResponse.data["IsPatientExcluded"];
+ request.responseID = apiResponse.data["ReponseID"];
+ LoaderBottomSheet.hideLoader();
+ _dialogService.showExceptionBottomSheet(
+ message: apiResponse.data["Message"],
+ onOkPressed: () {
+ LoaderBottomSheet.showLoader();
+ authVM.sendActivationCode(
+ otpTypeEnum: otpTypeEnum,
+ nationalIdOrFileNumber: request.sharedPatientIdentificationId!,
+ phoneNumber: request.sharedPatientMobileNumber!,
+ isForRegister: false,
+ isExcludedUser: apiResponse.data['IsPatientExcluded'],
+ responseID: apiResponse.data["ReponseID"],
+ isFormFamilyFile: true);
+ },
+ onCancelPressed: () {
+ navigationService.pop();
+ });
+ }
+ }
+ });
+ }
+
+ Future handleFamilyFileRequestOTPVerification() async {
+ LoaderBottomSheet.showLoader();
+ if (!_appState.getIsChildLoggedIn) {
+ await getFamilyFiles(status: 0);
+ await getAllPendingRecordsByResponseId();
+ }
+
+ LoaderBottomSheet.hideLoader();
+ }
+
+ Future removeFileFromFamilyMembers({int? id}) async {
+ NavigationService navigationService = getIt.get();
+ _dialogService.showExceptionBottomSheet(
+ message: "Remove this member?",
+ onOkPressed: () async {
+ LoaderBottomSheet.showLoader();
+ final result = await medicalFileRepo.removeFamilyFile(id: id);
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ LoaderBottomSheet.hideLoader();
+ _dialogService.showErrorBottomSheet(
+ message: apiResponse.errorMessage!,
+ onOkPressed: () {
+ navigationService.pop();
+ });
+ } else if (apiResponse.messageStatus == 1) {
+ patientFamilyFiles.removeWhere((element) => element.id == id);
+ LoaderBottomSheet.hideLoader();
+ notifyListeners();
+ navigationService.pop();
+ }
+ },
+ );
+ },
+ onCancelPressed: () {
+ navigationService.pop();
+ });
+ }
+
Future getPatientMedicalReportAppointmentsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
patientMedicalReportAppointmentHistoryList.clear();
notifyListeners();
@@ -357,8 +566,33 @@ class MedicalFileViewModel extends ChangeNotifier {
);
}
- Future addFamilyFile() async {
- final resultEither = await medicalFileRepo.addFamilyFile(request: {});
- resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) async {});
+ Future acceptRejectFileFromFamilyMembers({int? id, int? status}) async {
+ NavigationService navigationService = getIt.get();
+ LoaderBottomSheet.showLoader();
+ final result = await medicalFileRepo.acceptRejectFamilyFile(id: id, status: status);
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ LoaderBottomSheet.hideLoader();
+ _dialogService.showErrorBottomSheet(
+ message: apiResponse.errorMessage!,
+ onOkPressed: () {
+ navigationService.pop();
+ });
+ } else if (apiResponse.messageStatus == 1) {
+ // FamilyFileResponseModelLists moveProfile = pendingFamilyFiles.firstWhere((element) => element.id == patientID);
+ // moveProfile.status = 3;
+ // moveProfile.statusDescription = "Approved";
+ // patientFamilyFiles.add(moveProfile);
+ pendingFamilyFiles.removeWhere((element) => element.id == id);
+ //TODO: Call Api Here To Load Family Members
+ getFamilyFiles(status: 0);
+ getAllPendingRecordsByResponseId();
+ LoaderBottomSheet.hideLoader();
+ onFamilyFileTabChange(0);
+ }
+ },
+ );
}
}
diff --git a/lib/features/medical_file/models/family_file_response_model.dart b/lib/features/medical_file/models/family_file_response_model.dart
index 82fe3d8..f4aa557 100644
--- a/lib/features/medical_file/models/family_file_response_model.dart
+++ b/lib/features/medical_file/models/family_file_response_model.dart
@@ -23,83 +23,90 @@ class FamilyFileResponseModelLists {
String? patientIdenficationNumber;
String? patientName;
String? statusDescription;
+ bool? isSuperUser = false;
+ bool? isRequestFromMySide;
- FamilyFileResponseModelLists({
- this.id,
- this.patientId,
- this.responseId,
- this.relationshipId,
- this.relationship,
- this.relationshipN,
- this.regionId,
- this.familyRegionId,
- this.status,
- this.isActive,
- this.editedOn,
- this.createdOn,
- this.age,
- this.emaiLAddress,
- this.gender,
- this.genderDescription,
- this.genderImage,
- this.mobileNumber,
- this.patientDataVerified,
- this.patientIdenficationNumber,
- this.patientName,
- this.statusDescription,
- });
+ FamilyFileResponseModelLists(
+ {this.id,
+ this.patientId,
+ this.responseId,
+ this.relationshipId,
+ this.relationship,
+ this.relationshipN,
+ this.regionId,
+ this.familyRegionId,
+ this.status,
+ this.isActive,
+ this.editedOn,
+ this.createdOn,
+ this.age,
+ this.emaiLAddress,
+ this.gender,
+ this.genderDescription,
+ this.genderImage,
+ this.mobileNumber,
+ this.patientDataVerified,
+ this.patientIdenficationNumber,
+ this.patientName,
+ this.statusDescription,
+ this.isSuperUser,
+ this.isRequestFromMySide});
factory FamilyFileResponseModelLists.fromRawJson(String str) => FamilyFileResponseModelLists.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory FamilyFileResponseModelLists.fromJson(Map json) => FamilyFileResponseModelLists(
- id: json["ID"],
- patientId: json["PatientID"],
- responseId: json["ResponseID"],
- relationshipId: json["RelationshipID"],
- relationship: json["Relationship"],
- relationshipN: json["RelationshipN"],
- regionId: json["RegionID"],
- familyRegionId: json["FamilyRegionID"],
- status: json["Status"],
- isActive: json["IsActive"],
- editedOn: json["EditedOn"],
- createdOn: json["CreatedOn"],
- age: json["Age"],
- emaiLAddress: json["EmaiLAddress"],
- gender: json["Gender"],
- genderDescription: json["GenderDescription"],
- genderImage: json["GenderImage"],
- mobileNumber: json["MobileNumber"],
- patientDataVerified: json["PatientDataVerified"],
- patientIdenficationNumber: json["PatientIdenficationNumber"],
- patientName: json["PatientName"],
- statusDescription: json["StatusDescription"],
- );
+ id: json["ID"],
+ patientId: json["PatientID"],
+ responseId: json["ResponseID"],
+ relationshipId: json["RelationshipID"],
+ relationship: json["Relationship"],
+ relationshipN: json["RelationshipN"],
+ regionId: json["RegionID"],
+ familyRegionId: json["FamilyRegionID"],
+ status: json["Status"],
+ isActive: json["IsActive"],
+ editedOn: json["EditedOn"],
+ createdOn: json["CreatedOn"],
+ age: json["Age"],
+ emaiLAddress: json["EmaiLAddress"],
+ gender: json["Gender"],
+ genderDescription: json["GenderDescription"],
+ genderImage: json["GenderImage"],
+ mobileNumber: json["MobileNumber"],
+ patientDataVerified: json["PatientDataVerified"],
+ patientIdenficationNumber: json["PatientIdenficationNumber"],
+ patientName: json["PatientName"],
+ statusDescription: json["StatusDescription"],
+ isSuperUser: json["isSuperUser"] ?? false,
+ isRequestFromMySide: json["isRequestFromMySide"] ?? false,
+ );
Map toJson() => {
- "ID": id,
- "PatientID": patientId,
- "ResponseID": responseId,
- "RelationshipID": relationshipId,
- "Relationship": relationship,
- "RelationshipN": relationshipN,
- "RegionID": regionId,
- "FamilyRegionID": familyRegionId,
- "Status": status,
- "IsActive": isActive,
- "EditedOn": editedOn,
- "CreatedOn": createdOn,
- "Age": age,
- "EmaiLAddress": emaiLAddress,
- "Gender": gender,
- "GenderDescription": genderDescription,
- "GenderImage": genderImage,
- "MobileNumber": mobileNumber,
- "PatientDataVerified": patientDataVerified,
- "PatientIdenficationNumber": patientIdenficationNumber,
- "PatientName": patientName,
- "StatusDescription": statusDescription,
- };
+ "ID": id,
+ "PatientID": patientId,
+ "ResponseID": responseId,
+ "RelationshipID": relationshipId,
+ "Relationship": relationship,
+ "RelationshipN": relationshipN,
+ "RegionID": regionId,
+ "FamilyRegionID": familyRegionId,
+ "Status": status,
+ "IsActive": isActive,
+ "EditedOn": editedOn,
+ "CreatedOn": createdOn,
+ "Age": age,
+ "EmaiLAddress": emaiLAddress,
+ "Gender": gender,
+ "GenderDescription": genderDescription,
+ "GenderImage": genderImage,
+ "MobileNumber": mobileNumber,
+ "PatientDataVerified": patientDataVerified,
+ "PatientIdenficationNumber": patientIdenficationNumber,
+ "PatientName": patientName,
+ "StatusDescription": statusDescription,
+ "isSuperUser": isSuperUser,
+ "isRequestFromMySide": isRequestFromMySide,
+ };
}
diff --git a/lib/features/my_appointments/appointment_via_region_viewmodel.dart b/lib/features/my_appointments/appointment_via_region_viewmodel.dart
index 9ffb544..3e3c3cd 100644
--- a/lib/features/my_appointments/appointment_via_region_viewmodel.dart
+++ b/lib/features/my_appointments/appointment_via_region_viewmodel.dart
@@ -1,6 +1,8 @@
import 'package:flutter/foundation.dart' show ChangeNotifier;
import 'package:hmg_patient_app_new/core/app_state.dart' show AppState;
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/dental_chief_complaints_page.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/laser/laser_appointment.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
@@ -96,9 +98,30 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier {
),);
}
- void handleLastStepForClinicForDentalAndLaser() {
- //todo handle the routing here
+ void handleLastStepForClinicForDentalAndLaser(int clinicId) {
navigationService.pop();
+
+ if (clinicId == 17) {
+ if (!appState.isAuthenticated) {
+ navigationService.push(
+ CustomPageRoute(
+ page: DentalChiefComplaintsPage(),
+ ),
+ );
+ }
+ }
+
+ if (clinicId == 253) {
+ {
+
+
+ navigationService.push(
+ CustomPageRoute(
+ page: LaserAppointment(),
+ ),
+ );
+ }
+ }
}
void handleLastStepForDentalAndLaser() {
diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart
index 916327c..60fbff2 100644
--- a/lib/features/my_appointments/my_appointments_view_model.dart
+++ b/lib/features/my_appointments/my_appointments_view_model.dart
@@ -50,6 +50,8 @@ class MyAppointmentsViewModel extends ChangeNotifier {
void onTabChange(int index) {
previouslySelectedTab = selectedTabIndex;
selectedTabIndex = index;
+ start = null;
+ end = null;
notifyListeners();
}
@@ -90,6 +92,9 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
setIsAppointmentDataToBeLoaded(bool val) {
+ if (val) {
+ isMyAppointmentsLoading = true;
+ }
isAppointmentDataToBeLoaded = val;
notifyListeners();
}
@@ -110,9 +115,11 @@ class MyAppointmentsViewModel extends ChangeNotifier {
Future getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isAppointmentDataToBeLoaded) return;
+ filteredAppointmentList.clear();
patientAppointmentsHistoryList.clear();
patientUpcomingAppointmentsHistoryList.clear();
patientArrivedAppointmentsHistoryList.clear();
+ notifyListeners();
final result = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments);
final resultArrived = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: false, isArrivedAppointments: true);
@@ -153,6 +160,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
patientAppointmentsHistoryList.addAll(patientUpcomingAppointmentsHistoryList);
patientAppointmentsHistoryList.addAll(patientArrivedAppointmentsHistoryList);
filteredAppointmentList.addAll(patientAppointmentsHistoryList);
+
print('Upcoming Appointments: ${patientUpcomingAppointmentsHistoryList.length}');
print('Arrived Appointments: ${patientArrivedAppointmentsHistoryList.length}');
print('All Appointments: ${patientAppointmentsHistoryList.length}');
@@ -451,12 +459,12 @@ class MyAppointmentsViewModel extends ChangeNotifier {
filteredAppointmentList.add(element);
}
});
- filteredAppointmentList.addAll(sourceList);
} else {
filteredAppointmentList.clear();
sourceList.forEach((element) {
try {
- var dateTime = DateUtil.convertStringToDate(element.appointmentDate);
+ var dateTime = DateUtil.convertStringToDate(element.appointmentDate).provideDateOnly();
+
if (start != null && end == null) {
if (dateTime.isAtSameMomentAs(start)) {
if (isUnderFilter(element)) {
@@ -464,7 +472,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
}
} else if (start != null && end != null) {
- if ((dateTime.isAfter(start)) && (dateTime.isBefore(end))) {
+ if ((dateTime.isAfter(start)) && ((dateTime.isBefore(end))||((dateTime.isAtSameMomentAs(end))))) {
if (isUnderFilter(element)) {
filteredAppointmentList.add(element);
}
diff --git a/lib/features/payfort/payfort_repo.dart b/lib/features/payfort/payfort_repo.dart
index 9f836d1..74a323a 100644
--- a/lib/features/payfort/payfort_repo.dart
+++ b/lib/features/payfort/payfort_repo.dart
@@ -18,6 +18,13 @@ abstract class PayfortRepo {
Future>> generateSdkSignatureFromAPI({required SdkTokenRequest tokenRequest});
Future>> checkPaymentStatus({required String transactionID});
+
+ Future>> checkTamaraPaymentStatus({required String transactionID});
+
+ Future>> markAppointmentAsTamaraPaid({required int projectID, required int appointmentNo});
+
+ Future>> updateTamaraRequestStatus(
+ {required String responseMessage, required String status, required String clientRequestID, required String tamaraOrderID});
}
class PayfortRepoImp implements PayfortRepo {
@@ -147,4 +154,100 @@ class PayfortRepoImp implements PayfortRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future> checkTamaraPaymentStatus({required String transactionID}) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.get(
+ '${ApiConsts.GET_TAMARA_PAYMENT_STATUS}$transactionID',
+ isExternal: true,
+ isAllowAny: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future> updateTamaraRequestStatus({required String responseMessage, required String status, required String clientRequestID, required String tamaraOrderID}) async {
+ Map body = {
+ "Response_Message": responseMessage,
+ "ClientRequestID": clientRequestID,
+ "Status": status,
+ "FortID": tamaraOrderID, // Tamara order ID
+ "LanguageID": 1,
+ "Installments_Number": 3,
+ };
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(UPDATE_TAMARA_STATUS, body: body, onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ }, isAllowAny: true, isPaymentServices: true);
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future> markAppointmentAsTamaraPaid({required int projectID, required int appointmentNo}) async {
+ Map body = {"ProjectID": projectID, "AppointmentNo": appointmentNo, "LanguageID": 1};
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(MARK_APPOINTMENT_TAMARA_STATUS, body: body, onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ }, isAllowAny: true, isPaymentServices: true);
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
}
diff --git a/lib/features/payfort/payfort_view_model.dart b/lib/features/payfort/payfort_view_model.dart
index 6b67ce9..89effcd 100644
--- a/lib/features/payfort/payfort_view_model.dart
+++ b/lib/features/payfort/payfort_view_model.dart
@@ -94,6 +94,40 @@ class PayfortViewModel extends ChangeNotifier {
);
}
+ Future checkTamaraPaymentStatus({required String transactionID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await payfortRepo.checkTamaraPaymentStatus(transactionID: transactionID);
+
+ result.fold(
+ (failure) async {
+ onError!(failure.message);
+ },
+ (apiResponse) {
+ print(apiResponse.data);
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ // }
+ },
+ );
+ }
+
+ Future updateTamaraRequestStatus(
+ {required String responseMessage, required String status, required String clientRequestID, required String tamaraOrderID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await payfortRepo.updateTamaraRequestStatus(responseMessage: responseMessage, status: status, clientRequestID: clientRequestID, tamaraOrderID: tamaraOrderID);
+
+ result.fold(
+ (failure) async {
+ onError!(failure.message);
+ },
+ (apiResponse) {
+ print(apiResponse.data);
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ },
+ );
+ }
+
Future _generateSdkResponse({
String? applePayAccessCode,
String? merchantIdentifier,
@@ -199,4 +233,20 @@ class PayfortViewModel extends ChangeNotifier {
onFailed!(e.toString() as PayFortFailureResult);
}
}
+
+ Future markAppointmentAsTamaraPaid({required int projectID, required int appointmentNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await payfortRepo.markAppointmentAsTamaraPaid(projectID: projectID, appointmentNo: appointmentNo);
+
+ result.fold(
+ (failure) async {
+ onError!(failure.message);
+ },
+ (apiResponse) {
+ print(apiResponse.data);
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ },
+ );
+ }
}
diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart
index d14a021..798f94d 100644
--- a/lib/generated/locale_keys.g.dart
+++ b/lib/generated/locale_keys.g.dart
@@ -189,6 +189,7 @@ abstract class LocaleKeys {
static const firstName = 'firstName';
static const middleName = 'middleName';
static const lastName = 'lastName';
+ static const female = 'female';
static const preferredLanguage = 'preferredLanguage';
static const locationsRegister = 'locationsRegister';
static const ksa = 'ksa';
@@ -863,7 +864,6 @@ abstract class LocaleKeys {
static const clearAllFilters = 'clearAllFilters';
static const filters = 'filters';
static const searchClinic = 'searchClinic';
- static const walkin = 'walkin';
static const normal = 'normal';
static const attention = 'attention';
static const monitor = 'monitor';
@@ -873,5 +873,8 @@ abstract class LocaleKeys {
static const to = 'to';
static const startDate = 'startDate';
static const endDate = 'endDate';
+ static const walkin = 'walkin';
+ static const laserClinic = 'laserClinic';
+ static const continueString = 'continueString';
}
diff --git a/lib/main.dart b/lib/main.dart
index ac11f8f..20507d0 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -79,94 +79,53 @@ void main() async {
fallbackLocale: Locale('en', 'US'),
child: MultiProvider(providers: [
ChangeNotifierProvider(
- create: (_) => LabViewModel(
- labRepo: getIt(),
- errorHandlerService: getIt(),
- navigationService: getIt()),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => RadiologyViewModel(
- radiologyRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => PrescriptionsViewModel(
- prescriptionsRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => InsuranceViewModel(
- insuranceRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => MedicalFileViewModel(
- medicalFileRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => ProfileSettingsViewModel(),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => MyAppointmentsViewModel(
- myAppointmentsRepo: getIt(),
- errorHandlerService: getIt(),
- appState: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => PayfortViewModel(
- payfortRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => HabibWalletViewModel(
- habibWalletRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => BookAppointmentsViewModel(
- bookAppointmentsRepo: getIt(),
- errorHandlerService: getIt(),
- navigationService: getIt(),
- myAppointmentsViewModel: getIt(),
- locationUtils: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => ImmediateLiveCareViewModel(
- immediateLiveCareRepo: getIt(),
- errorHandlerService: getIt(),
- navigationService: getIt(),
- myAppointmentsViewModel: getIt(),
- ),
+ create: (_) => getIt.get(),
),
ChangeNotifierProvider(
- create: (_) => AuthenticationViewModel(
- authenticationRepo: getIt(),
- appState: getIt(),
- dialogService: getIt(),
- errorHandlerService: getIt(),
- navigationService: getIt(),
- cacheService: getIt(),
- localAuthService: getIt(),
- ),
+ create: (_) => getIt.get