From 484ab56a8e1020119d775fe713674f990a3298a6 Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Mon, 8 Sep 2025 16:20:06 +0300 Subject: [PATCH] fixes for signup --- lib/core/api/api_client.dart | 8 +- lib/core/api_consts.dart | 3 + lib/core/app_state.dart | 9 + lib/core/dependencies.dart | 2 +- lib/core/enums.dart | 37 ++ lib/core/utils/request_utils.dart | 53 ++- lib/core/utils/utils.dart | 13 + lib/extensions/util_extensions.dart | 2 + .../authentication/authentication_repo.dart | 71 ++++ .../authentication_view_model.dart | 252 ++++++++++-- .../send_activation_request_model.dart | 4 +- .../check_user_staus_nhic_response_model.dart | 381 ++++++++++++++++++ lib/presentation/authentication/register.dart | 67 +-- lib/widgets/input_widget.dart | 10 +- 14 files changed, 779 insertions(+), 133 deletions(-) create mode 100644 lib/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 5056930..10c5d23 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -139,10 +139,12 @@ class ApiClientImp implements ApiClient { body['PatientID'] = body['PatientID'] ?? user.patientId; body['PatientOutSA'] = body.containsKey('PatientOutSA') ? body['PatientOutSA'] ?? user.outSa : user.outSa; - // body['SessionID'] = body['TokenID'] == null - // ? ApiConsts.sessionID //Added By Aamir - // : getSessionId(body['TokenID'] ?? ""); //getSe + body['SessionID'] = body['TokenID'] == null ? ApiConsts.sessionID : getSessionId(body['TokenID'] ?? ""); //getSe } + // else { + // body['SessionID'] = body['TokenID'] == null ? ApiConsts.sessionID : getSessionId(body['TokenID'] ?? ""); //getSe + // + // } } } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index b9f6a96..67c07d7 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -768,6 +768,9 @@ class ApiConsts { static final String checkUsageAgreement = 'Services/Patients.svc/REST/CheckForUsageAgreement'; static final String getUserAgreementContent = 'Services/Patients.svc/REST/GetUsageAgreementText'; + static final String checkPatientForRegistration = 'Services/Authentication.svc/REST/CheckPatientForRegisteration'; + static final String checkUserStatus= 'Services/NHIC.svc/REST/GetPatientInfo'; + // static values for Api static final double appVersionID = 18.7; static final int appChannelId = 3; diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index cf8f8e5..86a6a52 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_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/services/navigation_service.dart'; @@ -82,4 +83,12 @@ class AppState { String deviceTypeID = ""; set setDeviceTypeID(v) => deviceTypeID = v; + + CheckUserStatusResponseNHIC? _nHICUserData; + + CheckUserStatusResponseNHIC get getNHICUserData => _nHICUserData!; + + set setNHICUserData(CheckUserStatusResponseNHIC value) { + _nHICUserData = value; + } } diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index a900742..330f01c 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -102,7 +102,7 @@ class AppDependencies { ); getIt.registerLazySingleton( - () => InsuranceViewModel( + () => InsuranceViewModel( insuranceRepo: getIt(), errorHandlerService: getIt(), ), diff --git a/lib/core/enums.dart b/lib/core/enums.dart index ab5cac1..4303b42 100644 --- a/lib/core/enums.dart +++ b/lib/core/enums.dart @@ -24,6 +24,8 @@ enum ViewStateEnum { enum CountryEnum { saudiArabia, unitedArabEmirates } +enum CalenderEnum { gregorian, hijri } + enum SelectionTypeEnum { dropdown, calendar } enum GenderTypeEnum { male, female } @@ -38,6 +40,41 @@ enum LoginTypeEnum { sms, whatsapp, face, fingerprint } enum AppEnvironmentTypeEnum { dev, uat, preProd, qa, staging, prod } +extension CalenderExtension on CalenderEnum { + int get toInt { + switch (this) { + case CalenderEnum.hijri: + return 1; + case CalenderEnum.gregorian: + return 0; + } + } + + String get displayName { + switch (this) { + case CalenderEnum.hijri: + return 'Hijri'; + case CalenderEnum.gregorian: + return 'Gregorian'; + } + } + + static LoginTypeEnum? fromValue(int value) { + switch (value) { + case 1: + return LoginTypeEnum.sms; + case 2: + return LoginTypeEnum.fingerprint; + case 3: + return LoginTypeEnum.face; + case 4: + return LoginTypeEnum.whatsapp; + default: + return null; + } + } +} + extension LoginTypeExtension on LoginTypeEnum { int get toInt { switch (this) { diff --git a/lib/core/utils/request_utils.dart b/lib/core/utils/request_utils.dart index 8f33fad..5d6819a 100644 --- a/lib/core/utils/request_utils.dart +++ b/lib/core/utils/request_utils.dart @@ -14,6 +14,8 @@ class RequestUtils { required bool isForRegister, required int? patientId, required String zipCode, + required CalenderEnum calenderType, + String? dob, }) { bool fileNo = false; if (nationId.isNotEmpty) { @@ -27,20 +29,22 @@ class RequestUtils { request.zipCode = zipCode; // or countryCode if defined elsewhere if (isForRegister) { - // request.searchType = registeredData.searchType ?? 1; - // request.patientID = registeredData.patientID ?? 0; - // request.patientIdentificationID = request.nationalID = registeredData.patientIdentificationID ?? '0'; - // request.dob = registeredData.dob; - // request.isRegister = registeredData.isRegister; + request.patientIdentificationID = int.parse(nationId); + request.searchType = 1; + request.isHijri = calenderType.toInt; + request.patientID = patientId; + request.dob = dob; + request.patientOutSA = patientOutSA ? 1 : 0; + request.isDentalAllowedBackend = false; } else { if (fileNo) { request.patientID = patientId ?? int.parse(nationId); - request.patientIdentificationID = request.nationalID = ""; + request.patientIdentificationID = request.nationalID; request.searchType = 2; } else { request.patientID = 0; request.searchType = 1; - request.patientIdentificationID = request.nationalID = nationId.isNotEmpty ? nationId : '0'; + request.patientIdentificationID = request.nationalID = nationId.isNotEmpty ? int.parse(nationId) : 0; } request.isRegister = false; } @@ -81,12 +85,12 @@ class RequestUtils { } else { if (fileNo) { request.patientID = patientId ?? int.parse(nationIdText); - request.patientIdentificationID = request.nationalID = ""; + request.patientIdentificationID = request.nationalID = "" as int?; request.searchType = 2; } else { request.patientID = 0; request.searchType = 1; - request.patientIdentificationID = request.nationalID = nationIdText.isNotEmpty ? nationIdText : '0'; + request.patientIdentificationID = request.nationalID = (nationIdText.isNotEmpty ? nationIdText : '0') as int?; } request.isRegister = false; } @@ -100,12 +104,14 @@ class RequestUtils { required String mobileNumber, required String zipCode, required int? patientId, - required String? nationalId, + required int? nationalId, required bool patientOutSA, required int selectedLoginType, required bool isForRegister, required bool isFileNo, + dynamic payload, }) { + AppState _appState = getIt.get(); var request = SendActivationRequest(); if (mobileNumber.isNotEmpty) { request.patientMobileNumber = int.parse(mobileNumber); @@ -116,23 +122,34 @@ class RequestUtils { request.oTPSendType = otpTypeEnum.toInt(); //this.selectedOption == 1 ? 1 : 2; request.zipCode = zipCode; - if (isForRegister) { - // request.searchType = registeredData.searchType ?? 1; - // request.patientID = registeredData.patientID ?? 0; - // request.patientIdentificationID = request.nationalID = registeredData.patientIdentificationID ?? '0'; - // request.dob = registeredData.dob; - // request.isRegister = registeredData.isRegister; + if (isForRegister && payload != null) { + request.searchType = isFileNo ? 2 : 1; + // request.searchType = payload["SearchType"]; + request.patientID = payload["PatientID"]; + request.patientIdentificationID = request.nationalID = payload["PatientIdentificationID"] ?? '0'; + request.dob = payload["DOB"]; + request.isRegister = payload["isRegister"]; + request.healthId = _appState.getNHICUserData.healthId; + request.isHijri = payload["IsHijri"]; + request.deviceToken = _appState.deviceToken; } else { request.searchType = isFileNo ? 2 : 1; request.patientID = patientId ?? 0; - request.nationalID = nationalId ?? '0'; - request.patientIdentificationID = nationalId ?? '0'; + request.nationalID = nationalId ?? 0; + request.patientIdentificationID = (nationalId ?? '0') as int?; request.isRegister = false; } request.deviceTypeID = request.searchType; return request; } + //DeviceToken":"" + // + + //{"PatientMobileNumber":530896018,"MobileNo":"0530896018","DeviceToken":"","ProjectOutSA":false,"LoginType":1,"ZipCode":"966","isRegister":true,"LogInTokenID":"","SearchType":2,"PatientID":0,"NationalID":"2599865082","PatientIdentificationID":"2599865082","OTP_SendType":1,"LanguageID":2,"VersionID":18.7,"Channel":3,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"isDentalAllowedBackend":false,"DeviceTypeID":1,"DOB":"19/07/1997","IsHijri":0,"HealthId":"30000541803510","Latitude":0.0,"Longitude":0.0,"PatientType":1} + + //{"PatientMobileNumber":530896018,"MobileNo":"0530896018","DeviceToken":"","ProjectOutSA":false,"LoginType":1,"ZipCode":"966","isRegister":true,"LogInTokenID":"","SearchType":1,"PatientID":0,"NationalID":"2599865082","PatientIdentificationID":"2599865082","OTP_SendType":1,"LanguageID":"2","VersionID":"18.7","Channel":"3","IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"TMRhVmkGhOsvamErw","isDentalAllowedBackend":false,"DeviceTypeID":"1","SMSSignature":"enKTDcqbOVd","DOB":"19/07/1997","PatientType":"1","Latitude":"0.0","Longitude":"0.0"} + static getAuthanticatedCommonRequest() { AppState _appState = getIt.get(); var request = CommonAuthanticatedRequest(); diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index b539630..35fe4b5 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -367,6 +367,19 @@ class Utils { } } + static String formatDateForApi(String isoDateString) { + try { + final dateTime = DateTime.parse(isoDateString); + final year = dateTime.year.toString(); + final month = dateTime.month.toString().padLeft(2, '0'); + final day = dateTime.day.toString().padLeft(2, '0'); + return '$day/$month/$year'; + } catch (e) { + log("Error formatting date for API: $e"); + return ""; + } + } + static String formatHijriDateToDisplay(String hijriDateString) { try { // Assuming hijriDateString is in the format yyyy-MM-dd diff --git a/lib/extensions/util_extensions.dart b/lib/extensions/util_extensions.dart index 49efca5..4ca5060 100644 --- a/lib/extensions/util_extensions.dart +++ b/lib/extensions/util_extensions.dart @@ -31,3 +31,5 @@ // } // } // } + + diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 030b75e..21061dc 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -24,6 +24,10 @@ abstract class AuthenticationRepo { Future>> checkIfUserAgreed({required dynamic commonAuthanticatedRequest}); Future>> getUserAgreementContent({required dynamic commonAuthanticatedRequest}); + + Future>> checkPatientForRegistration({required dynamic commonAuthanticatedRequest}); + + Future>> checkUserStatus({required dynamic commonAuthanticatedRequest}); } class AuthenticationRepoImp implements AuthenticationRepo { @@ -266,4 +270,71 @@ class AuthenticationRepoImp implements AuthenticationRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>> checkPatientForRegistration({required dynamic commonAuthanticatedRequest}) async { + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + ApiConsts.checkPatientForRegistration, + body: commonAuthanticatedRequest, + 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>> checkUserStatus({required dynamic commonAuthanticatedRequest}) async { + commonAuthanticatedRequest['Region'] = 1; + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + ApiConsts.checkUserStatus, + body: commonAuthanticatedRequest, + 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())); + } + } } diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 4ce1400..cb655b8 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -2,16 +2,19 @@ import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:hijri_gregorian_calendar/hijri_gregorian_calendar.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.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'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/core/utils/validation_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_repo.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/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/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; @@ -48,8 +51,12 @@ class AuthenticationViewModel extends ChangeNotifier { GenderTypeEnum? genderType; bool isTermsAccepted = false; List? countriesList; + String? dob = ""; NationalityCountries? pickedCountryByUAEUser; + CalenderEnum calenderType = CalenderEnum.gregorian; + + //================== bool isDubai = false; bool authenticated = false; @@ -67,8 +74,7 @@ class AuthenticationViewModel extends ChangeNotifier { late int selectedOption = 1; bool onlySMSBox = false; int fingrePrintBefore = 0; - var dob; - late int isHijri; + var healthId; Future onLoginPressed() async { @@ -106,6 +112,24 @@ class AuthenticationViewModel extends ChangeNotifier { notifyListeners(); } + void onCalenderTypeChange(bool isGregorian) { + calenderType = isGregorian ? CalenderEnum.gregorian : CalenderEnum.hijri; + notifyListeners(); + } + + void onDobChange(String? date) { + if (calenderType == CalenderEnum.hijri) { + var hijriDate = HijriGregConverter.gregorianToHijri(DateTime.parse(date!)); + DateTime hijriDateTimeForController = DateTime(hijriDate.year, hijriDate.month, hijriDate.day); + dob = Utils.formatDateForApi(date); + dobController.text = Utils.formatHijriDateToDisplay(hijriDateTimeForController.toIso8601String()); // Or directly hijriDate.toString() if that's what your formatter expects + } else { + dobController.text = Utils.formatDateToDisplay(date!); + dob = Utils.formatDateForApi(date); + } + notifyListeners(); + } + void loadCountriesData({required BuildContext context}) async { final String response = await DefaultAssetBundle.of(context).loadString('assets/json/countriesList.json'); final List data = json.decode(response); @@ -224,14 +248,14 @@ class AuthenticationViewModel extends ChangeNotifier { LoadingUtils.showFullScreenLoader(); dynamic checkPatientAuthenticationReq = RequestUtils.getPatientAuthenticationRequest( - phoneNumber: phoneNumberController.text, - nationId: nationalIdController.text, - isForRegister: false, - patientOutSA: false, - otpTypeEnum: otpTypeEnum, - patientId: 0, - zipCode: selectedCountrySignup.countryCode, - ); + phoneNumber: phoneNumberController.text, + nationId: nationalIdController.text, + isForRegister: false, + patientOutSA: false, + otpTypeEnum: otpTypeEnum, + patientId: 0, + zipCode: selectedCountrySignup.countryCode, + calenderType: calenderType); final result = await _authenticationRepo.checkPatientAuthentication(checkPatientAuthenticationReq: checkPatientAuthenticationReq); LoadingUtils.hideFullScreenLoader(); @@ -262,45 +286,41 @@ class AuthenticationViewModel extends ChangeNotifier { ); } - Future sendActivationCode({ - required OTPTypeEnum otpTypeEnum, - required String nationalIdOrFileNumber, - required String phoneNumber, - }) async { + Future sendActivationCode({required OTPTypeEnum otpTypeEnum, required String nationalIdOrFileNumber, required String phoneNumber, dynamic payload}) async { + bool isForRegister = await checkIsUserComingForRegister(request: payload); + bool isPatientOutSA = await isPatientOutsideSA(request: payload); + bool isFileNo = await isPatientHasFile(request: payload); + var request = RequestUtils.getCommonRequestSendActivationCode( - otpTypeEnum: otpTypeEnum, - mobileNumber: phoneNumber, - selectedLoginType: otpTypeEnum.toInt(), - zipCode: selectedCountrySignup.countryCode, - nationalId: nationalIdOrFileNumber, - isFileNo: false, - patientId: 0, - isForRegister: false, - patientOutSA: false, - ); + otpTypeEnum: otpTypeEnum, + mobileNumber: phoneNumber, + selectedLoginType: otpTypeEnum.toInt(), + zipCode: selectedCountrySignup.countryCode, + nationalId: int.parse(nationalIdOrFileNumber), + isFileNo: isFileNo, + patientId: 0, + isForRegister: isForRegister, + patientOutSA: isPatientOutSA, + payload: payload); // TODO: GET APP SMS SIGNATURE HERE request.sMSSignature = "enKTDcqbOVd"; // GifLoaderDialogUtils.showMyDialog(context); - bool isForRegister = healthId != null || isDubai; - if (isForRegister) { - if (!isDubai) { - request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); - } - request.healthId = healthId; - request.isHijri = isHijri; - } else { - // request.dob = ""; - // request.healthId = ""; - // request.isHijri = 0; - } - - final resultEither = await _authenticationRepo.sendActivationCodeRepo( - sendActivationCodeReq: request, - isRegister: isForRegister, - languageID: 'er', - ); + // bool isForRegister = healthId != null || isDubai; + // if (isForRegister) { + // if (!isDubai) { + // request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); + // } + // request.healthId = healthId; + // request.isHijri = calenderType.toInt; + // } else { + // // request.dob = ""; + // // request.healthId = ""; + // // request.isHijri = 0; + // } + + final resultEither = await _authenticationRepo.sendActivationCodeRepo(sendActivationCodeReq: request, isRegister: isForRegister, languageID: 'er'); resultEither.fold( (failure) async => await _errorHandlerService.handleError(failure: failure), @@ -319,6 +339,15 @@ class AuthenticationViewModel extends ChangeNotifier { ); } + Future checkIsUserComingForRegister({required dynamic request}) async { + bool isUserComingForRegister = false; + print(request); + if (request != null && request['isRegister']) { + isUserComingForRegister = true; + } + return isUserComingForRegister; + } + Future checkActivationCode({ required int activationCode, required OTPTypeEnum otpTypeEnum, @@ -339,7 +368,7 @@ class AuthenticationViewModel extends ChangeNotifier { if (isForRegister) { if (isDubai) request['DOB'] = dob; request['HealthId'] = healthId; - request['IsHijri'] = isHijri; + request['IsHijri'] = calenderType.toInt; final resultEither = await _authenticationRepo.checkActivationCodeRepo(newRequest: request, activationCode: activationCode.toString(), isRegister: true); @@ -460,6 +489,141 @@ class AuthenticationViewModel extends ChangeNotifier { // TODO: HANDLE THIS VIA BOTTOM SHEET } + Future onRegisterPress({required OTPTypeEnum otpTypeEnum}) async { + bool isOutSidePatient = selectedCountrySignup.countryCode == CountryEnum.unitedArabEmirates.countryCode ? true : false; + + final request = await RequestUtils.getPatientAuthenticationRequest( + phoneNumber: phoneNumberController.text, + nationId: nationalIdController.text, + patientOutSA: isOutSidePatient, + otpTypeEnum: otpTypeEnum, + isForRegister: true, + patientId: 0, + zipCode: selectedCountrySignup.countryCode, + calenderType: calenderType, + dob: dob) + .toJson(); + var nRequest = Map.from(request); + + if (true) { + request.removeWhere((key, value) => value == null); + nRequest.removeWhere((key, value) => value == null); + nRequest.removeWhere((key, value) => key == "SearchType"); + nRequest.removeWhere((key, value) => key == "PatientID"); + nRequest.removeWhere((key, value) => key == "OTP_SendType"); + nRequest.removeWhere((key, value) => key == "LanguageID"); + } + + final resultEither = await _authenticationRepo.checkPatientForRegistration(commonAuthanticatedRequest: nRequest); + resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { + checkUserStatusForRegistration(response: apiResponse.data, request: request); + }); + } + + Future checkUserStatusForRegistration({required dynamic response, required dynamic request}) async { + if (response is Map) { + _appState.setAppAuthToken = response["LogInTokenID"]; + if (response["MessageStatus"] == 2) { + print(response["ErrorEndUserMessage"]); + return; + } + if (response['hasFile'] == true) { + //TODO: Show Here Ok And Cancel Dialog and On OKPress it will go for sendActivationCode + } else { + request['forRegister'] = true; + request['isRegister'] = true; + if (await isPatientOutsideSA(request: response)) { + print("=======IN SA======="); + chekUserNHICData(request: request); + } else { + print("=======OUT SA======="); + _appState.setAppLoginTokenID = response['LogInTokenID']; + sendActivationCode( + otpTypeEnum: OTPTypeEnumExtension.fromInt(request["OTP_SendType"]), + nationalIdOrFileNumber: request["PatientIdentificationID"].toString(), + phoneNumber: request["PatientMobileNumber"].toString()); + } + } + } else { + //TODO: Here Hide Loader And Show TOAST + //TODO: if (response['ErrorCode'] == '-986') Toast With OK, And Show response as Output. + } + } + + Future isPatientOutsideSA({required dynamic request}) { + try { + if (request is Map && request.containsKey("PatientOutSA")) { + if (!request["PatientOutSA"]) { + return Future.value(true); + } else { + return Future.value(false); + } + } else { + return Future.value(false); + } + } catch (e) { + return Future.value(false); + } + } + + Future isPatientHasFile({required dynamic request}) async { + bool isFile = false; + if (request != null && request["NationalID"] != null) { + isFile = request["NationalID"].length < 10; + } + return isFile; + } + + Future chekUserNHICData({required dynamic request}) async { + final resultEither = await _authenticationRepo.checkUserStatus(commonAuthanticatedRequest: request); + resultEither.fold((failure) async => await _errorHandlerService.handleError(failure: failure), (apiResponse) async { + if (apiResponse.data is Map) { + _appState.setNHICUserData = CheckUserStatusResponseNHIC.fromJson(apiResponse.data as Map); + sendActivationCode( + otpTypeEnum: OTPTypeEnumExtension.fromInt(request["OTP_SendType"]), + nationalIdOrFileNumber: request["PatientIdentificationID"].toString(), + phoneNumber: request["PatientMobileNumber"].toString(), + payload: request, + ); + } + }); + + // this.authService.checkUserStatus(request).then((result) { + // // Keep loader active, continue to next step + // if (result is Map) { + // RegisterInfoResponse? resultSet; + // CheckUserStatusResponse res = CheckUserStatusResponse.fromJson(result as Map); + // nHICData = res; + // sharedPref.setObject(NHIC_DATA, res.toJson()); + // resultSet = RegisterInfoResponse.fromJson(res.toJson()); + // + // sendActivationCode(type, loginToken, resultSet, isSkipRegistration); + // } else { + // GifLoaderDialogUtils.hideDialog(context); + // context.showBottomSheet( + // child: ExceptionBottomSheet( + // message: result != null ? result : TranslationBase.of(context).somethingWentWrong, + // showCancel: false, + // onOkPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // } + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // context.showBottomSheet( + // child: ExceptionBottomSheet( + // message: err.toString(), + // showCancel: false, + // onOkPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // }); + } + @override void dispose() { nationalIdController.dispose(); diff --git a/lib/features/authentication/models/request_models/send_activation_request_model.dart b/lib/features/authentication/models/request_models/send_activation_request_model.dart index 360efd4..6bd48b4 100644 --- a/lib/features/authentication/models/request_models/send_activation_request_model.dart +++ b/lib/features/authentication/models/request_models/send_activation_request_model.dart @@ -9,8 +9,8 @@ class SendActivationRequest { String? logInTokenID; int? searchType; int? patientID; - String? nationalID; - String? patientIdentificationID; + int? nationalID; + int? patientIdentificationID; int? oTPSendType; int? languageID; double? versionID; diff --git a/lib/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart b/lib/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart new file mode 100644 index 0000000..bd5323d --- /dev/null +++ b/lib/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart @@ -0,0 +1,381 @@ +import 'dart:convert'; + +class CheckUserStatusResponseNHIC { + dynamic date; + int? languageId; + int? serviceName; + dynamic time; + dynamic androidLink; + dynamic authenticationTokenId; + dynamic data; + bool? dataw; + int? dietType; + int? dietTypeId; + dynamic errorCode; + dynamic errorEndUserMessage; + dynamic errorEndUserMessageN; + dynamic errorMessage; + int? errorStatusCode; + int? errorType; + int? foodCategory; + dynamic iosLink; + bool? isAuthenticated; + int? mealOrderStatus; + int? mealType; + int? messageStatus; + int? numberOfResultRecords; + dynamic patientBlodType; + dynamic successMsg; + dynamic successMsgN; + dynamic vidaUpdatedResponse; + dynamic accessTokenObject; + int? age; + dynamic clientIdentifierId; + int? createdBy; + String? dateOfBirth; + String? firstNameAr; + String? firstNameEn; + String? gender; + dynamic genderAr; + dynamic genderEn; + String? healthId; + String? idNumber; + String? idType; + bool? isHijri; + int? isInstertedOrUpdated; + int? isNull; + int? isPatientExistNhic; + bool? isRecordLockedByCurrentUser; + String? lastNameAr; + String? lastNameEn; + dynamic listActiveAccessToken; + String? maritalStatus; + String? maritalStatusCode; + String? nationalDateOfBirth; + String? nationality; + String? nationalityCode; + String? occupation; + dynamic pcdTransactionDataResultList; + dynamic pcdGetVidaPatientForManualVerificationList; + dynamic pcdNhicHmgPatientDetailsMatchCalulationList; + int? pcdReturnValue; + dynamic patientStatus; + String? placeofBirth; + dynamic practitionerStatusCode; + dynamic practitionerStatusDescAr; + dynamic practitionerStatusDescEn; + int? rowCount; + String? secondNameAr; + String? secondNameEn; + String? thirdNameAr; + String? thirdNameEn; + dynamic yakeenDoctorDataGetSourceList; + dynamic yakeenVidaPatientDataStatisticsByPatientIdList; + dynamic yakeenVidaPatientDataStatisticsList; + dynamic yakeenVidaPatientDataStatisticsPrefferedList; + dynamic accessToken; + int? categoryCode; + dynamic categoryNameAr; + dynamic categoryNameEn; + int? constraintCode; + dynamic constraintNameAr; + dynamic constraintNameEn; + dynamic content; + dynamic errorList; + dynamic licenseExpiryDate; + dynamic licenseIssuedDate; + dynamic licenseStatusCode; + dynamic licenseStatusDescAr; + dynamic licenseStatusDescEn; + dynamic organizations; + dynamic registrationNumber; + int? specialtyCode; + dynamic specialtyNameAr; + dynamic specialtyNameEn; + + CheckUserStatusResponseNHIC({ + this.date, + this.languageId, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenId, + this.data, + this.dataw, + this.dietType, + this.dietTypeId, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorStatusCode, + this.errorType, + this.foodCategory, + this.iosLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.accessTokenObject, + this.age, + this.clientIdentifierId, + this.createdBy, + this.dateOfBirth, + this.firstNameAr, + this.firstNameEn, + this.gender, + this.genderAr, + this.genderEn, + this.healthId, + this.idNumber, + this.idType, + this.isHijri, + this.isInstertedOrUpdated, + this.isNull, + this.isPatientExistNhic, + this.isRecordLockedByCurrentUser, + this.lastNameAr, + this.lastNameEn, + this.listActiveAccessToken, + this.maritalStatus, + this.maritalStatusCode, + this.nationalDateOfBirth, + this.nationality, + this.nationalityCode, + this.occupation, + this.pcdTransactionDataResultList, + this.pcdGetVidaPatientForManualVerificationList, + this.pcdNhicHmgPatientDetailsMatchCalulationList, + this.pcdReturnValue, + this.patientStatus, + this.placeofBirth, + this.practitionerStatusCode, + this.practitionerStatusDescAr, + this.practitionerStatusDescEn, + this.rowCount, + this.secondNameAr, + this.secondNameEn, + this.thirdNameAr, + this.thirdNameEn, + this.yakeenDoctorDataGetSourceList, + this.yakeenVidaPatientDataStatisticsByPatientIdList, + this.yakeenVidaPatientDataStatisticsList, + this.yakeenVidaPatientDataStatisticsPrefferedList, + this.accessToken, + this.categoryCode, + this.categoryNameAr, + this.categoryNameEn, + this.constraintCode, + this.constraintNameAr, + this.constraintNameEn, + this.content, + this.errorList, + this.licenseExpiryDate, + this.licenseIssuedDate, + this.licenseStatusCode, + this.licenseStatusDescAr, + this.licenseStatusDescEn, + this.organizations, + this.registrationNumber, + this.specialtyCode, + this.specialtyNameAr, + this.specialtyNameEn, + }); + + factory CheckUserStatusResponseNHIC.fromRawJson(String str) => CheckUserStatusResponseNHIC.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory CheckUserStatusResponseNHIC.fromJson(Map json) => CheckUserStatusResponseNHIC( + date: json["Date"], + languageId: json["LanguageID"], + serviceName: json["ServiceName"], + time: json["Time"], + androidLink: json["AndroidLink"], + authenticationTokenId: json["AuthenticationTokenID"], + data: json["Data"], + dataw: json["Dataw"], + dietType: json["DietType"], + dietTypeId: json["DietTypeID"], + errorCode: json["ErrorCode"], + errorEndUserMessage: json["ErrorEndUserMessage"], + errorEndUserMessageN: json["ErrorEndUserMessageN"], + errorMessage: json["ErrorMessage"], + errorStatusCode: json["ErrorStatusCode"], + errorType: json["ErrorType"], + foodCategory: json["FoodCategory"], + iosLink: json["IOSLink"], + isAuthenticated: json["IsAuthenticated"], + mealOrderStatus: json["MealOrderStatus"], + mealType: json["MealType"], + messageStatus: json["MessageStatus"], + numberOfResultRecords: json["NumberOfResultRecords"], + patientBlodType: json["PatientBlodType"], + successMsg: json["SuccessMsg"], + successMsgN: json["SuccessMsgN"], + vidaUpdatedResponse: json["VidaUpdatedResponse"], + accessTokenObject: json["AccessTokenObject"], + age: json["Age"], + clientIdentifierId: json["ClientIdentifierId"], + createdBy: json["CreatedBy"], + dateOfBirth: json["DateOfBirth"], + firstNameAr: json["FirstNameAr"], + firstNameEn: json["FirstNameEn"], + gender: json["Gender"], + genderAr: json["GenderAr"], + genderEn: json["GenderEn"], + healthId: json["HealthId"], + idNumber: json["IdNumber"], + idType: json["IdType"], + isHijri: json["IsHijri"], + isInstertedOrUpdated: json["IsInstertedOrUpdated"], + isNull: json["IsNull"], + isPatientExistNhic: json["IsPatientExistNHIC"], + isRecordLockedByCurrentUser: json["IsRecordLockedByCurrentUser"], + lastNameAr: json["LastNameAr"], + lastNameEn: json["LastNameEn"], + listActiveAccessToken: json["List_ActiveAccessToken"], + maritalStatus: json["MaritalStatus"], + maritalStatusCode: json["MaritalStatusCode"], + nationalDateOfBirth: json["NationalDateOfBirth"], + nationality: json["Nationality"], + nationalityCode: json["NationalityCode"], + occupation: json["Occupation"], + pcdTransactionDataResultList: json["PCDTransactionDataResultList"], + pcdGetVidaPatientForManualVerificationList: json["PCD_GetVidaPatientForManualVerificationList"], + pcdNhicHmgPatientDetailsMatchCalulationList: json["PCD_NHIC_HMG_PatientDetailsMatchCalulationList"], + pcdReturnValue: json["PCD_ReturnValue"], + patientStatus: json["PatientStatus"], + placeofBirth: json["PlaceofBirth"], + practitionerStatusCode: json["PractitionerStatusCode"], + practitionerStatusDescAr: json["PractitionerStatusDescAr"], + practitionerStatusDescEn: json["PractitionerStatusDescEn"], + rowCount: json["RowCount"], + secondNameAr: json["SecondNameAr"], + secondNameEn: json["SecondNameEn"], + thirdNameAr: json["ThirdNameAr"], + thirdNameEn: json["ThirdNameEn"], + yakeenDoctorDataGetSourceList: json["YakeenDoctorData_GetSourceList"], + yakeenVidaPatientDataStatisticsByPatientIdList: json["YakeenVidaPatientDataStatisticsByPatientIdList"], + yakeenVidaPatientDataStatisticsList: json["YakeenVidaPatientDataStatisticsList"], + yakeenVidaPatientDataStatisticsPrefferedList: json["YakeenVidaPatientDataStatisticsPrefferedList"], + accessToken: json["accessToken"], + categoryCode: json["categoryCode"], + categoryNameAr: json["categoryNameAr"], + categoryNameEn: json["categoryNameEn"], + constraintCode: json["constraintCode"], + constraintNameAr: json["constraintNameAr"], + constraintNameEn: json["constraintNameEn"], + content: json["content"], + errorList: json["errorList"], + licenseExpiryDate: json["licenseExpiryDate"], + licenseIssuedDate: json["licenseIssuedDate"], + licenseStatusCode: json["licenseStatusCode"], + licenseStatusDescAr: json["licenseStatusDescAr"], + licenseStatusDescEn: json["licenseStatusDescEn"], + organizations: json["organizations"], + registrationNumber: json["registrationNumber"], + specialtyCode: json["specialtyCode"], + specialtyNameAr: json["specialtyNameAr"], + specialtyNameEn: json["specialtyNameEn"], + ); + + Map toJson() => { + "Date": date, + "LanguageID": languageId, + "ServiceName": serviceName, + "Time": time, + "AndroidLink": androidLink, + "AuthenticationTokenID": authenticationTokenId, + "Data": data, + "Dataw": dataw, + "DietType": dietType, + "DietTypeID": dietTypeId, + "ErrorCode": errorCode, + "ErrorEndUserMessage": errorEndUserMessage, + "ErrorEndUserMessageN": errorEndUserMessageN, + "ErrorMessage": errorMessage, + "ErrorStatusCode": errorStatusCode, + "ErrorType": errorType, + "FoodCategory": foodCategory, + "IOSLink": iosLink, + "IsAuthenticated": isAuthenticated, + "MealOrderStatus": mealOrderStatus, + "MealType": mealType, + "MessageStatus": messageStatus, + "NumberOfResultRecords": numberOfResultRecords, + "PatientBlodType": patientBlodType, + "SuccessMsg": successMsg, + "SuccessMsgN": successMsgN, + "VidaUpdatedResponse": vidaUpdatedResponse, + "AccessTokenObject": accessTokenObject, + "Age": age, + "ClientIdentifierId": clientIdentifierId, + "CreatedBy": createdBy, + "DateOfBirth": dateOfBirth, + "FirstNameAr": firstNameAr, + "FirstNameEn": firstNameEn, + "Gender": gender, + "GenderAr": genderAr, + "GenderEn": genderEn, + "HealthId": healthId, + "IdNumber": idNumber, + "IdType": idType, + "IsHijri": isHijri, + "IsInstertedOrUpdated": isInstertedOrUpdated, + "IsNull": isNull, + "IsPatientExistNHIC": isPatientExistNhic, + "IsRecordLockedByCurrentUser": isRecordLockedByCurrentUser, + "LastNameAr": lastNameAr, + "LastNameEn": lastNameEn, + "List_ActiveAccessToken": listActiveAccessToken, + "MaritalStatus": maritalStatus, + "MaritalStatusCode": maritalStatusCode, + "NationalDateOfBirth": nationalDateOfBirth, + "Nationality": nationality, + "NationalityCode": nationalityCode, + "Occupation": occupation, + "PCDTransactionDataResultList": pcdTransactionDataResultList, + "PCD_GetVidaPatientForManualVerificationList": pcdGetVidaPatientForManualVerificationList, + "PCD_NHIC_HMG_PatientDetailsMatchCalulationList": pcdNhicHmgPatientDetailsMatchCalulationList, + "PCD_ReturnValue": pcdReturnValue, + "PatientStatus": patientStatus, + "PlaceofBirth": placeofBirth, + "PractitionerStatusCode": practitionerStatusCode, + "PractitionerStatusDescAr": practitionerStatusDescAr, + "PractitionerStatusDescEn": practitionerStatusDescEn, + "RowCount": rowCount, + "SecondNameAr": secondNameAr, + "SecondNameEn": secondNameEn, + "ThirdNameAr": thirdNameAr, + "ThirdNameEn": thirdNameEn, + "YakeenDoctorData_GetSourceList": yakeenDoctorDataGetSourceList, + "YakeenVidaPatientDataStatisticsByPatientIdList": yakeenVidaPatientDataStatisticsByPatientIdList, + "YakeenVidaPatientDataStatisticsList": yakeenVidaPatientDataStatisticsList, + "YakeenVidaPatientDataStatisticsPrefferedList": yakeenVidaPatientDataStatisticsPrefferedList, + "accessToken": accessToken, + "categoryCode": categoryCode, + "categoryNameAr": categoryNameAr, + "categoryNameEn": categoryNameEn, + "constraintCode": constraintCode, + "constraintNameAr": constraintNameAr, + "constraintNameEn": constraintNameEn, + "content": content, + "errorList": errorList, + "licenseExpiryDate": licenseExpiryDate, + "licenseIssuedDate": licenseIssuedDate, + "licenseStatusCode": licenseStatusCode, + "licenseStatusDescAr": licenseStatusDescAr, + "licenseStatusDescEn": licenseStatusDescEn, + "organizations": organizations, + "registrationNumber": registrationNumber, + "specialtyCode": specialtyCode, + "specialtyNameAr": specialtyNameAr, + "specialtyNameEn": specialtyNameEn, + }; +} diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index e51792c..00f4808 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -98,9 +98,6 @@ class _RegisterNew extends State { autoFocus: true, padding: EdgeInsets.symmetric(vertical: 8.h), leadingIcon: AppAssets.student_card, - // onChange: (value) { - // print(value); - // } ).withVerticalPadding(8), Divider(height: 1), TextInputWidget( @@ -115,6 +112,8 @@ class _RegisterNew extends State { padding: EdgeInsets.symmetric(vertical: 8.h), leadingIcon: AppAssets.birthday_cake, selectionType: SelectionTypeEnum.calendar, + onCalendarTypeChanged: authVm.onCalenderTypeChange, + onChange: authVm.onDobChange, ).withVerticalPadding(8), ], ), @@ -222,38 +221,8 @@ class _RegisterNew extends State { padding: const EdgeInsets.only(bottom: 10), child: CustomButton( text: LocaleKeys.sendOTPSMS.tr(), - onPressed: () { - Navigator.of(context).push(MaterialPageRoute( - builder: (BuildContext context) => OTPVerificationScreen( - phoneNumber: '504278212', - checkActivationCode: (int code) {}, - onResendOTPPressed: (String phone) {}, - ), - )); - - // if (mobileNo.isEmpty) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else if (!Utils.validateMobileNumber(mobileNo)) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterValidMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else { - // registerUser(1); - // } + onPressed: () async { + await authVM.onRegisterPress(otpTypeEnum: OTPTypeEnum.sms); }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedBorderColor, @@ -275,32 +244,8 @@ class _RegisterNew extends State { padding: EdgeInsets.only(bottom: 10.h, top: 10.h), child: CustomButton( text: LocaleKeys.sendOTPWHATSAPP.tr(), - onPressed: () { - // if (mobileNo.isEmpty) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else if (!Utils.validateMobileNumber(mobileNo)) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: TranslationBase.of(context).pleaseEnterValidMobile, - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } else { - // registerUser(4); - // } - // int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, mobileNo, context); - // registerUser(val); + onPressed: () async { + await authVM.onRegisterPress(otpTypeEnum: OTPTypeEnum.whatsapp); }, backgroundColor: AppColors.whiteColor, borderColor: AppColors.borderOnlyColor, diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 53a0130..4fcf6f3 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -19,6 +19,7 @@ class TextInputWidget extends StatelessWidget { final String hintText; final TextEditingController? controller; final Function(String?)? onChange; + final Function(bool)? onCalendarTypeChanged; final String? prefix; final bool isEnable; final bool isBorderAllowed; @@ -45,6 +46,7 @@ class TextInputWidget extends StatelessWidget { required this.hintText, this.controller, this.onChange, + this.onCalendarTypeChanged, this.prefix, this.isEnable = true, this.isBorderAllowed = true, @@ -157,10 +159,10 @@ class TextInputWidget extends StatelessWidget { isGregorian = value; }); if (picked != null && onChange != null) { - // if (onCalendarTypeChanged != null) { - // onCalendarTypeChanged.call(isGregorian); - // } - onChange!(picked.toIso8601String()); + if (onCalendarTypeChanged != null) { + onCalendarTypeChanged!.call(isGregorian); + } + onChange!(picked.toString()); } }, child: Utils.buildSvgWithAssets(icon: AppAssets.calendar),