Merge branch 'dev_v3.13.6' into dev_v_3.13.6_CR_6804

# Conflicts:
#	lib/config/localized_values.dart
#	lib/pages/BookAppointment/BookConfirm.dart
#	lib/pages/BookAppointment/QRCode.dart
merge-update-with-lab-changes
Haroon Amjad 1 year ago
commit 69493934b1

1
.gitignore vendored

@ -31,6 +31,7 @@ pubspec.lock
.pub-cache/ .pub-cache/
.pub/ .pub/
/build/ /build/
/ios/Frameworks/
# Web related # Web related
lib/generated_plugin_registrant.dart lib/generated_plugin_registrant.dart

@ -56,6 +56,10 @@ android {
compileSdkVersion 34 compileSdkVersion 34
// ndkVersion "24.0.8215888" // ndkVersion "24.0.8215888"
buildFeatures {
viewBinding true
}
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
@ -69,7 +73,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.ejada.hmg" applicationId "com.ejada.hmg"
minSdkVersion 24 minSdkVersion 26
targetSdkVersion 34 targetSdkVersion 34
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
@ -117,15 +121,16 @@ android {
packagingOptions { packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro' exclude 'META-INF/proguard/androidx-annotations.pro'
// pickFirst 'lib/x86/libc++_shared.so' pickFirst 'lib/x86/libc++_shared.so'
// pickFirst 'lib/x86_64/libc++_shared.so' pickFirst 'lib/x86_64/libc++_shared.so'
// pickFirst 'lib/armeabi-v7a/libc++_shared.so' pickFirst 'lib/armeabi-v7a/libc++_shared.so'
// pickFirst 'lib/arm64-v8a/libc++_shared.so' pickFirst 'lib/arm64-v8a/libc++_shared.so'
// pickFirst '**/*.so' pickFirst '**/*.so'
} }
compileOptions { compileOptions {
// coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
@ -136,13 +141,15 @@ flutter {
} }
dependencies { dependencies {
// coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.firebase:firebase-messaging:21.0.0" implementation "com.google.firebase:firebase-messaging:21.0.0"
// implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{ // implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{
// exclude group: 'com.google.protobuf',module: 'protobuf-javalite' // exclude group: 'com.google.protobuf',module: 'protobuf-javalite'
// exclude group: 'com.google.protobuf',module: 'protobuf-lite' // exclude group: 'com.google.protobuf',module: 'protobuf-lite'
// }) // })
implementation 'pub.devrel:easypermissions:0.4.0' implementation 'pub.devrel:easypermissions:3.0.0'
// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
implementation 'com.google.guava:guava:27.0.1-android' implementation 'com.google.guava:guava:27.0.1-android'
@ -163,9 +170,34 @@ dependencies {
// implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11" // implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11"
// implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '1.10.11' // implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '1.10.11'
implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1" // implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1" // implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1" // implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1"
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-java8:2.4.0'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.android.gms:play-services-location:21.3.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'androidx.test.ext:junit:1.1.5'
implementation 'com.android.volley:volley:1.2.1'
def room_version = "2.4.0-alpha04"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation 'net.zetetic:android-database-sqlcipher:4.5.2'
implementation 'com.intuit.ssp:ssp-android:1.1.0'
implementation 'com.intuit.sdp:sdp-android:1.1.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
// implementation "com.mapbox.maps:android:10.16.6"
implementation 'com.mapbox.maps:android:11.3.1'
implementation files('libs/PenNavUI.aar')
implementation files('libs/Penguin.aar')
implementation files('libs/PenguinRenderer.aar')
implementation "org.jetbrains.anko:anko-commons:0.10.4" implementation "org.jetbrains.anko:anko-commons:0.10.4"
implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM
@ -177,6 +209,7 @@ dependencies {
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1' implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'
implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.9.0'
androidTestImplementation "androidx.test:core:1.4.0" androidTestImplementation "androidx.test:core:1.4.0"
} }

Binary file not shown.

Binary file not shown.

@ -53,4 +53,20 @@
} }
-dontwarn com.opentok.android.** -dontwarn com.opentok.android.**
-dontwarn com.opentok.otc.** -dontwarn com.opentok.otc.**
-dontwarn penguin.com.pennav.Model.Navigation.NearLandmark
-keep,includedescriptorclasses class net.sqlcipher.** { *; }
-keep,includedescriptorclasses interface net.sqlcipher.** { *; }
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-dontwarn retrofit2.**
-keep class com.google.gson.** { *; }
-dontwarn com.google.gson.**
# Penguin classes
-keep class com.peng.pennavmap.models.** { *; }
-keep class com.peng.pennavmap.db.** { *; }

@ -8,21 +8,36 @@
FlutterApplication and put your custom class here. --> FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove"/> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/> <!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/>-->
<uses-permission android:name="android.permission.BROADCAST_STICKY" tools:node="remove"/> <uses-permission android:name="android.permission.BROADCAST_STICKY" tools:node="remove"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/> <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />
<!-- <uses-permission android:name="android.permission.INTERNET" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@ -42,6 +57,7 @@
<uses-feature android:name="android.hardware.location.network" android:required="false" /> <uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/> <uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<!-- <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" />-->
@ -59,13 +75,13 @@
</queries> </queries>
<application <application
android:name=".Application" android:name=".Application"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher_local"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:showOnLockScreen="true" android:showOnLockScreen="true"
android:screenOrientation="sensorPortrait" android:screenOrientation="sensorPortrait"
android:allowBackup="false" android:allowBackup="false"
android:extractNativeLibs="true" android:extractNativeLibs="true"
tools:replace="android:extractNativeLibs" tools:replace="android:extractNativeLibs,android:label"
android:label="Dr. Alhabib"> android:label="Dr. Alhabib">
<meta-data android:name="push_kit_auto_init_enabled" android:value="true" /> <meta-data android:name="push_kit_auto_init_enabled" android:value="true" />

@ -1,21 +1,19 @@
package com.ejada.hmg package com.ejada.hmg
import android.app.NotificationChannel import android.content.Intent
import android.app.NotificationManager import android.content.pm.PackageManager
import android.content.ContentResolver
import android.media.AudioAttributes
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.os.Build import android.os.Build
import android.util.Log
import android.view.WindowManager import android.view.WindowManager
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.PenguinInPlatformBridge
import com.ejada.hmg.utils.* import com.ejada.hmg.utils.*
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() { class MainActivity: FlutterFragmentActivity() {
@RequiresApi(Build.VERSION_CODES.O)
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine); GeneratedPluginRegistrant.registerWith(flutterEngine);
// Create Flutter Platform Bridge // Create Flutter Platform Bridge
@ -23,6 +21,7 @@ class MainActivity: FlutterFragmentActivity() {
PlatformBridge(flutterEngine, this).create() PlatformBridge(flutterEngine, this).create()
OpenTokPlatformBridge(flutterEngine, this).create() OpenTokPlatformBridge(flutterEngine, this).create()
PenguinInPlatformBridge(flutterEngine, this).create()
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH) // val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH)
@ -43,6 +42,25 @@ class MainActivity: FlutterFragmentActivity() {
// val time = timeToMillis("04:00:00", "HH:mm:ss") // val time = timeToMillis("04:00:00", "HH:mm:ss")
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
val granted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
val intent = Intent("PERMISSION_RESULT_ACTION").apply {
putExtra("PERMISSION_GRANTED", granted)
}
sendBroadcast(intent)
// Log the request code and permission results
Log.d("PermissionsResult", "Request Code: $requestCode")
Log.d("PermissionsResult", "Permissions: ${permissions.joinToString()}")
Log.d("PermissionsResult", "Grant Results: ${grantResults.joinToString()}")
} }
override fun onResume() { override fun onResume() {

@ -0,0 +1,52 @@
package com.cloud.diplomaticquarterapp
import com.ejada.hmg.MainActivity
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.penguin.PenguinView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
class PenguinInPlatformBridge(
private var flutterEngine: FlutterEngine,
private var mainActivity: MainActivity
) {
private lateinit var channel: MethodChannel
companion object {
private const val CHANNEL = "launch_penguin_ui"
}
@RequiresApi(Build.VERSION_CODES.O)
fun create() {
// openTok = OpenTok(mainActivity, flutterEngine)
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
when (call.method) {
"launchPenguin" -> {
print("the platform channel is being called")
val args = call.arguments as Map<String, Any>?
Log.d("TAG", "configureFlutterEngine: $args")
println("args")
args?.let {
PenguinView(
mainActivity,
100,
args,
flutterEngine.dartExecutor.binaryMessenger,
activity = mainActivity,
channel
)
}
}
else -> {
result.notImplemented()
}
}
}
}
}

@ -0,0 +1,28 @@
package com.cloud.diplomaticquarterapp.PermissionManager
import android.Manifest
import android.os.Build
object PermissionHelper {
fun getRequiredPermissions(): Array<String> {
val permissions = mutableListOf(
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
// Manifest.permission.ACTIVITY_RECOGNITION
)
// For Android 12 (API level 31) and above, add specific permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (API 31) and above
permissions.add(Manifest.permission.BLUETOOTH_SCAN)
permissions.add(Manifest.permission.BLUETOOTH_CONNECT)
permissions.add(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS)
}
return permissions.toTypedArray()
}
}

@ -0,0 +1,50 @@
package com.cloud.diplomaticquarterapp.PermissionManager
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class PermissionManager(
private val context: Context,
val listener: PermissionListener,
private val requestCode: Int,
vararg permissions: String
) {
private val permissionsArray = permissions
interface PermissionListener {
fun onPermissionGranted()
fun onPermissionDenied()
}
fun arePermissionsGranted(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
permissionsArray.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
} else {
true
}
}
fun requestPermissions(activity: Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(activity, permissionsArray, requestCode)
}
}
fun handlePermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (this.requestCode == requestCode) {
val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
if (allGranted) {
listener.onPermissionGranted()
} else {
listener.onPermissionDenied()
}
}
}
}

@ -0,0 +1,15 @@
package com.cloud.diplomaticquarterapp.PermissionManager
// PermissionResultReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class PermissionResultReceiver(
private val callback: (Boolean) -> Unit
) : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val granted = intent?.getBooleanExtra("PERMISSION_GRANTED", false) ?: false
callback(granted)
}
}

@ -0,0 +1,13 @@
package com.cloud.diplomaticquarterapp.penguin
enum class PenguinMethod {
// initializePenguin("initializePenguin"),
// configurePenguin("configurePenguin"),
// showPenguinUI("showPenguinUI"),
// onPenNavUIDismiss("onPenNavUIDismiss"),
// onReportIssue("onReportIssue"),
// onPenNavSuccess("onPenNavSuccess"),
onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"),
// navigateToPOI("navigateToPOI"),
// openSharedLocation("openSharedLocation");
}

@ -0,0 +1,97 @@
package com.cloud.diplomaticquarterapp.penguin
import android.content.Context
import com.google.gson.Gson
import com.peng.pennavmap.PlugAndPlaySDK
import com.peng.pennavmap.connections.ApiController
import com.peng.pennavmap.interfaces.RefIdDelegate
import com.peng.pennavmap.models.TokenModel
import com.peng.pennavmap.models.postmodels.PostToken
import com.peng.pennavmap.utils.AppSharedData
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import android.util.Log
class PenguinNavigator() {
fun navigateTo(mContext: Context, refID: String, delegate: RefIdDelegate,clientID : String,clientKey : String ) {
val postToken = PostToken(clientID, clientKey)
getToken(mContext, postToken, object : RefIdDelegate {
override fun onRefByIDSuccess(PoiId: String?) {
Log.e("navigateTo", "PoiId is+++++++ $PoiId")
PlugAndPlaySDK.navigateTo(mContext, refID, object : RefIdDelegate {
override fun onRefByIDSuccess(PoiId: String?) {
Log.e("navigateTo", "PoiId 2is+++++++ $PoiId")
delegate.onRefByIDSuccess(refID)
}
override fun onGetByRefIDError(error: String?) {
delegate.onRefByIDSuccess(error)
}
})
}
override fun onGetByRefIDError(error: String?) {
delegate.onRefByIDSuccess(error)
}
})
}
fun getToken(mContext: Context, postToken: PostToken?, apiTokenCallBack: RefIdDelegate) {
try {
// Create the API call
val purposesCall: Call<ResponseBody> = ApiController.getInstance(mContext)
.apiMethods
.getToken(postToken)
// Enqueue the call for asynchronous execution
purposesCall.enqueue(object : Callback<ResponseBody?> {
override fun onResponse(
call: Call<ResponseBody?>,
response: Response<ResponseBody?>
) {
if (response.isSuccessful() && response.body() != null) {
try {
response.body()?.use { responseBody ->
val responseBodyString: String = responseBody.string() // Use `string()` to get the actual response content
if (responseBodyString.isNotEmpty()) {
val tokenModel = Gson().fromJson(responseBodyString, TokenModel::class.java)
if (tokenModel != null && tokenModel.token != null) {
AppSharedData.apiToken = tokenModel.token
apiTokenCallBack.onRefByIDSuccess(tokenModel.token)
} else {
apiTokenCallBack.onGetByRefIDError("Failed to parse token model")
}
} else {
apiTokenCallBack.onGetByRefIDError("Response body is empty")
}
}
} catch (e: Exception) {
apiTokenCallBack.onGetByRefIDError("An error occurred: ${e.message}")
}
} else {
apiTokenCallBack.onGetByRefIDError("Unsuccessful response: " + response.code())
}
}
override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
apiTokenCallBack.onGetByRefIDError(t.message)
}
})
} catch (error: Exception) {
apiTokenCallBack.onGetByRefIDError("Exception during API call: $error")
}
}
}

@ -0,0 +1,316 @@
package com.cloud.diplomaticquarterapp.penguin
import android.app.Activity
import android.content.Context
import android.content.Context.RECEIVER_EXPORTED
import android.content.IntentFilter
import android.graphics.Color
import android.os.Build
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.cloud.diplomaticquarterapp.PermissionManager.PermissionHelper
import com.cloud.diplomaticquarterapp.PermissionManager.PermissionManager
import com.cloud.diplomaticquarterapp.PermissionManager.PermissionResultReceiver
import com.ejada.hmg.MainActivity
import com.peng.pennavmap.PlugAndPlayConfiguration
import com.peng.pennavmap.PlugAndPlaySDK
import com.peng.pennavmap.enums.InitializationErrorType
import com.peng.pennavmap.interfaces.PenNavUIDelegate
import com.peng.pennavmap.utils.Languages
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView
import com.cloud.diplomaticquarterapp.penguin.PenguinNavigator
import com.peng.pennavmap.interfaces.PIEventsDelegate
import com.peng.pennavmap.interfaces.PILocationDelegate
import com.peng.pennavmap.interfaces.RefIdDelegate
import com.peng.pennavmap.models.PIReportIssue
/**
* Custom PlatformView for displaying Penguin UI components within a Flutter app.
* Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls,
* and `PenNavUIDelegate` for handling SDK events.
*/
@RequiresApi(Build.VERSION_CODES.O)
internal class PenguinView(
context: Context,
id: Int,
val creationParams: Map<String, Any>,
messenger: BinaryMessenger,
activity: MainActivity,
val channel: MethodChannel
) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate {
// The layout for displaying the Penguin UI
private val mapLayout: RelativeLayout = RelativeLayout(context)
private val _context: Context = context
private val permissionResultReceiver: PermissionResultReceiver
private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION")
private companion object {
const val PERMISSIONS_REQUEST_CODE = 1
}
private lateinit var permissionManager: PermissionManager
// Reference to the main activity
private var _activity: Activity = activity
private lateinit var mContext: Context
lateinit var navigator: PenguinNavigator
init {
// Set layout parameters for the mapLayout
mapLayout.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
mContext = context
permissionResultReceiver = PermissionResultReceiver { granted ->
if (granted) {
onPermissionsGranted()
} else {
onPermissionsDenied()
}
}
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
mContext.registerReceiver(
permissionResultReceiver,
permissionIntentFilter,
RECEIVER_EXPORTED
)
} else {
mContext.registerReceiver(
permissionResultReceiver,
permissionIntentFilter,
)
}
// Set the background color of the layout
mapLayout.setBackgroundColor(Color.RED)
permissionManager = PermissionManager(
context = mContext,
listener = object : PermissionManager.PermissionListener {
override fun onPermissionGranted() {
// Handle permissions granted
onPermissionsGranted()
}
override fun onPermissionDenied() {
// Handle permissions denied
onPermissionsDenied()
}
},
requestCode = PERMISSIONS_REQUEST_CODE,
*PermissionHelper.getRequiredPermissions()
)
if (!permissionManager.arePermissionsGranted()) {
permissionManager.requestPermissions(_activity)
} else {
// Permissions already granted
permissionManager.listener.onPermissionGranted()
}
}
private fun onPermissionsGranted() {
// Handle the actions when permissions are granted
Log.d("PermissionsResult", "onPermissionsGranted")
// Register the platform view factory for creating custom views
// Initialize the Penguin SDK
initPenguin()
}
private fun onPermissionsDenied() {
// Handle the actions when permissions are denied
Log.d("PermissionsResult", "onPermissionsDenied")
}
/**
* Returns the view associated with this PlatformView.
*
* @return The main view for this PlatformView.
*/
override fun getView(): View {
return mapLayout
}
/**
* Cleans up resources associated with this PlatformView.
*/
override fun dispose() {
// Cleanup code if needed
}
/**
* Handles method calls from Dart code.
*
* @param call The method call from Dart.
* @param result The result callback to send responses back to Dart.
*/
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
// Handle method calls from Dart code here
}
/**
* Initializes the Penguin SDK with custom configuration and delegates.
*/
private fun initPenguin() {
navigator = PenguinNavigator()
// Configure the PlugAndPlaySDK
val language = when (creationParams["languageCode"] as String) {
"ar" -> Languages.ar
"en" -> Languages.en
else -> {
Languages.en
}
}
Log.d(
"TAG",
"initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}"
)
PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder()
.setBaseUrl(
creationParams["dataURL"] as String,
creationParams["positionURL"] as String
)
.setServiceName(
creationParams["dataServiceName"] as String,
creationParams["positionServiceName"] as String
)
.setClientData(
creationParams["clientID"] as String,
creationParams["clientKey"] as String
)
.setUserName(creationParams["username"] as String)
// .setLanguageID(Languages.en)
.setLanguageID(language)
.setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean)
.setEnableBackButton(true)
// .setDeepLinkData("deeplink")
.setCustomizeColor("#2CA0AF")
.setDeepLinkSchema("")
.build()
// Set location delegate to handle location updates
PlugAndPlaySDK.setPiLocationDelegate {
// Example code to handle location updates
// Uncomment and modify as needed
// if (location.size() > 0)
// Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show()
}
// Set events delegate for reporting issues
PlugAndPlaySDK.setPiEventsDelegate { }
// Start the Penguin SDK
PlugAndPlaySDK.start(mContext, this)
}
/**
* Navigates to the specified reference ID.
*
* @param refID The reference ID to navigate to.
*/
fun navigateTo(refID: String) {
try {
if (refID.isBlank()) {
Log.e("navigateTo", "Invalid refID: The reference ID is blank.")
}
// referenceId = refID
navigator.navigateTo(mContext, refID,object : RefIdDelegate {
override fun onRefByIDSuccess(PoiId: String?) {
Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId")
// channelFlutter.invokeMethod(
// PenguinMethod.navigateToPOI.name,
// "navigateTo Success"
// )
}
override fun onGetByRefIDError(error: String?) {
Log.e("navigateTo", "error is penguin view+++++++ $error")
// channelFlutter.invokeMethod(
// PenguinMethod.navigateToPOI.name,
// "navigateTo Failed: Invalid refID"
// )
}
} , creationParams["clientID"] as String, creationParams["clientKey"] as String )
} catch (e: Exception) {
Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e)
// channelFlutter.invokeMethod(
// PenguinMethod.navigateToPOI.name,
// "Failed: Exception - ${e.message}"
// )
}
}
/**
* Called when Penguin UI setup is successful.
*
* @param warningCode Optional warning code received from the SDK.
*/
override fun onPenNavSuccess(warningCode: String?) {
val clinicId = creationParams["clinicID"] as String
if(clinicId.isEmpty()) return
navigateTo(clinicId)
}
/**
* Called when there is an initialization error with Penguin UI.
*
* @param description Description of the error.
* @param errorType Type of initialization error.
*/
override fun onPenNavInitializationError(
description: String?,
errorType: InitializationErrorType?
) {
val arguments: Map<String, Any?> = mapOf(
"description" to description,
"type" to errorType?.name
)
channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments)
Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show()
}
/**
* Called when Penguin UI is dismissed.
*/
override fun onPenNavUIDismiss() {
// Handle UI dismissal if needed
try {
mContext.unregisterReceiver(permissionResultReceiver)
dispose();
} catch (e: IllegalArgumentException) {
Log.e("PenguinView", "Receiver not registered: $e")
}
}
}

@ -22,7 +22,7 @@ import com.github.kittinunf.fuel.httpPost
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import org.jetbrains.anko.doAsyncResult //import org.jetbrains.anko.doAsyncResult
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
@ -149,7 +149,7 @@ fun sendNotification(context: Context, title: String, @Nullable subtitle: String
val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher) .setSmallIcon(R.mipmap.ic_launcher_local)
.setContentIntent(notificationPendingIntent) .setContentIntent(notificationPendingIntent)
.setAutoCancel(true) .setAutoCancel(true)
.setContentTitle(title) .setContentTitle(title)
@ -208,7 +208,6 @@ fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTP
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.header("Allow", "*/*") .header("Allow", "*/*")
.response { request, response, result -> .response { request, response, result ->
result.doAsyncResult { }
result.fold({ data -> result.fold({ data ->
val dataString = String(data) val dataString = String(data)
if (isJSONValid(dataString)) { if (isJSONValid(dataString)) {

@ -19,4 +19,5 @@
<string name="GEOFENCE_REQUEST_TOO_FREQUENT"> <string name="GEOFENCE_REQUEST_TOO_FREQUENT">
Geofence requests happened too frequently. Geofence requests happened too frequently.
</string> </string>
<string name="mapbox_access_token" translatable="false">sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg</string>
</resources> </resources>

@ -13,6 +13,20 @@ buildscript {
google() google()
jcenter() jcenter()
maven { url 'https://developer.huawei.com/repo/' } maven { url 'https://developer.huawei.com/repo/' }
maven {
url 'https://api.mapbox.com/downloads/v2/releases/maven'
credentials {
username = 'mapbox'
password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
if (password == null || password == "") {
throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.")
}
}
authentication {
basic(BasicAuthentication)
}
}
// maven { // maven {
// url "https://dl.bintray.com/kotlin/kotlin-eap/" // url "https://dl.bintray.com/kotlin/kotlin-eap/"
@ -26,6 +40,7 @@ buildscript {
// classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' // classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath 'com.huawei.agconnect:agcp:1.5.2.300' classpath 'com.huawei.agconnect:agcp:1.5.2.300'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12'
classpath "com.mapbox.gradle.plugins:access-token:0.4.0"
} }
} }
@ -34,12 +49,29 @@ allprojects {
google() google()
// jcenter() // jcenter()
mavenCentral() mavenCentral()
flatDir {
dirs 'libs'
}
maven { maven {
url 'https://developer.huawei.com/repo/' url 'https://developer.huawei.com/repo/'
} }
maven { maven {
url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local"
} }
maven {
url 'https://api.mapbox.com/downloads/v2/releases/maven'
credentials {
username = 'mapbox'
password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"
if (password == null || password == "") {
throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the enviroment variables.")
}
}
authentication {
basic(BasicAuthentication)
}
}
} }
} }

@ -3,3 +3,5 @@ org.gradle.jvmargs=-Xmx4096m
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
android.suppressUnsupportedCompileSdk=33 android.suppressUnsupportedCompileSdk=33
MAPBOX_USER_NAME = "mapbox"
MAPBOX_DOWNLOADS_TOKEN="sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg"

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>11.0</string> <string>13.0</string>
</dict> </dict>
</plist> </plist>

@ -33,6 +33,7 @@ target 'Runner' do
pod 'OpenTok', '~> 2.22.0' pod 'OpenTok', '~> 2.22.0'
pod 'VTO2Lib' pod 'VTO2Lib'
pod 'MapboxMaps', '10.18.2'
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end end
@ -54,6 +55,7 @@ post_install do |installer|
] ]
build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386' build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'
build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
build_configuration.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
xcconfig_path = build_configuration.base_configuration_reference.real_path xcconfig_path = build_configuration.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path) xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR") xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR")
@ -62,6 +64,17 @@ post_install do |installer|
if build_configuration.build_settings['WRAPPER_EXTENSION'] == 'bundle' if build_configuration.build_settings['WRAPPER_EXTENSION'] == 'bundle'
build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF' build_configuration.build_settings['DEVELOPMENT_TEAM'] = '3A359E86ZF'
end end
if target.name == 'MapboxMobileEvents'
`xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents -o Pods/MapboxMobileEvents/MapboxMobileEvents.xcframework/ios-arm64_armv7/MapboxMobileEvents.framework/MapboxMobileEvents`
end
if target.name == 'MapboxCommon'
`xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon -o Pods/MapboxCommon/MapboxCommon.xcframework/ios-arm64/MapboxCommon.framework/MapboxCommon`
end
if target.name == 'MapboxCoreMaps'
`xcrun -sdk iphoneos bitcode_strip -r Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps -o Pods/MapboxCoreMaps/MapboxCoreMaps.xcframework/ios-arm64/MapboxCoreMaps.framework/MapboxCoreMaps`
end
end end
end end
end end

@ -8,18 +8,30 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */; };
301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; }; 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */; };
301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; }; 301C79B027200DED0016307B /* OpenTokLocalVideoFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */; };
306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; }; 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */; };
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; }; 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4EE411B2E3CB5D4F81AE5078 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */; }; 47C935002C91766800981BA7 /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FC2C91766400981BA7 /* Penguin.xcframework */; };
47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FC2C91766400981BA7 /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
47C935022C91766900981BA7 /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */; };
47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
47C935042C91766A00981BA7 /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */; };
47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C934FB2C91766400981BA7 /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 762D738C274E42650063CE73 /* ring_30Sec.caf */; }; 762D738E274E42650063CE73 /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 762D738C274E42650063CE73 /* ring_30Sec.caf */; };
762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 762D738D274E42650063CE73 /* ring_30Sec.mp3 */; }; 762D738F274E42650063CE73 /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 762D738D274E42650063CE73 /* ring_30Sec.mp3 */; };
76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; }; 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76815B26275F381C00E66E94 /* HealthKit.framework */; };
76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */; }; 76962ECE28AE5C10004EAE09 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */; };
76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */; };
76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B692C6B819000DAFB84 /* PenguinModel.swift */; };
76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */; };
76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */; };
76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */; };
76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F2556027F1FFED0062C1CD /* PassKit.framework */; }; 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F2556027F1FFED0062C1CD /* PassKit.framework */; };
76F9B0E22C6DED310064C51B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13E5B711BC29EB6ECCE1964C /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -43,12 +55,15 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = { 768D81742C6DF6E4005C655F /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
47C935032C91766900981BA7 /* PenguinINRenderer.xcframework in Embed Frameworks */,
47C935012C91766800981BA7 /* Penguin.xcframework in Embed Frameworks */,
47C935052C91766A00981BA7 /* PenNavUI.xcframework in Embed Frameworks */,
); );
name = "Embed Frameworks"; name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -56,14 +71,18 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
13E5B711BC29EB6ECCE1964C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = "<group>"; };
301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = "<group>"; }; 301C79AD27200D9F0016307B /* OpenTokRemoteVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokRemoteVideoFactory.swift; sourceTree = "<group>"; };
301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = "<group>"; }; 301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = "<group>"; };
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = "<group>"; }; 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = "<group>"; };
306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = "<group>"; }; 306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenguinINRenderer.xcframework; path = Frameworks/PenguinINRenderer.xcframework; sourceTree = "<group>"; };
47C934FB2C91766400981BA7 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PenNavUI.xcframework; path = Frameworks/PenNavUI.xcframework; sourceTree = "<group>"; };
47C934FC2C91766400981BA7 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Penguin.xcframework; path = Frameworks/Penguin.xcframework; sourceTree = "<group>"; };
6EE8819867EC2775AB578377 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; 6EE8819867EC2775AB578377 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -74,6 +93,11 @@
7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = "<group>"; }; 7643E4062BE0D0B400BD2F25 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
76815B26275F381C00E66E94 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 76815B26275F381C00E66E94 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; }; 76962ECD28AE5C10004EAE09 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = "<group>"; };
76D71B692C6B819000DAFB84 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = "<group>"; };
76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinView.swift; sourceTree = "<group>"; };
76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinPlugin.swift; sourceTree = "<group>"; };
76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinViewFactory.swift; sourceTree = "<group>"; };
76F2556027F1FFED0062C1CD /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; 76F2556027F1FFED0062C1CD /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
838788A2BEDC4910F4B029A6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 838788A2BEDC4910F4B029A6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
@ -110,10 +134,13 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
76F9B0E22C6DED310064C51B /* Pods_Runner.framework in Frameworks */,
76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */, 76F2556127F1FFED0062C1CD /* PassKit.framework in Frameworks */,
76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */, 76815B27275F381C00E66E94 /* HealthKit.framework in Frameworks */,
E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */, E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */,
4EE411B2E3CB5D4F81AE5078 /* Pods_Runner.framework in Frameworks */, 47C935042C91766A00981BA7 /* PenNavUI.xcframework in Frameworks */,
47C935002C91766800981BA7 /* Penguin.xcframework in Frameworks */,
47C935022C91766900981BA7 /* PenguinINRenderer.xcframework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -133,10 +160,13 @@
555EAAA626EFB641859EF0BE /* Frameworks */ = { 555EAAA626EFB641859EF0BE /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
47C934FC2C91766400981BA7 /* Penguin.xcframework */,
47C934FA2C91766400981BA7 /* PenguinINRenderer.xcframework */,
47C934FB2C91766400981BA7 /* PenNavUI.xcframework */,
76F2556027F1FFED0062C1CD /* PassKit.framework */, 76F2556027F1FFED0062C1CD /* PassKit.framework */,
76815B26275F381C00E66E94 /* HealthKit.framework */, 76815B26275F381C00E66E94 /* HealthKit.framework */,
E9620804255C2ED100D3A35D /* NetworkExtension.framework */, E9620804255C2ED100D3A35D /* NetworkExtension.framework */,
3D1513E0724DAFB89C198BDD /* Pods_Runner.framework */, 13E5B711BC29EB6ECCE1964C /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -151,6 +181,18 @@
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
76D71B682C6B817500DAFB84 /* Penguin */ = {
isa = PBXGroup;
children = (
76D71B692C6B819000DAFB84 /* PenguinModel.swift */,
76D71B6B2C6B81B300DAFB84 /* PenguinView.swift */,
76D71B6D2C6B81CC00DAFB84 /* PenguinPlugin.swift */,
76D71B6F2C6B81EA00DAFB84 /* PenguinViewFactory.swift */,
29631B9D2C96C7F600DF5916 /* PenguinNavigator.swift */,
);
path = Penguin;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -186,6 +228,7 @@
97C146F01CF9000F007C117D /* Runner */ = { 97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
76D71B682C6B817500DAFB84 /* Penguin */,
762D738C274E42650063CE73 /* ring_30Sec.caf */, 762D738C274E42650063CE73 /* ring_30Sec.caf */,
762D738D274E42650063CE73 /* ring_30Sec.mp3 */, 762D738D274E42650063CE73 /* ring_30Sec.mp3 */,
306FE6C9271D8B54002D6EFC /* OpenTok */, 306FE6C9271D8B54002D6EFC /* OpenTok */,
@ -220,6 +263,7 @@
E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */,
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */, 306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */,
E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */,
76D71B662C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift */,
); );
path = Helper; path = Helper;
sourceTree = "<group>"; sourceTree = "<group>";
@ -254,7 +298,7 @@
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 768D81742C6DF6E4005C655F /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
487FDD6493EB9AE7D8E39485 /* [CP] Embed Pods Frameworks */, 487FDD6493EB9AE7D8E39485 /* [CP] Embed Pods Frameworks */,
4671D3CD126F6635F4B75A6E /* [CP] Copy Pods Resources */, 4671D3CD126F6635F4B75A6E /* [CP] Copy Pods Resources */,
@ -274,7 +318,7 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1430; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
@ -419,12 +463,18 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */, 306FE6C8271D790C002D6EFC /* OpenTokPlatformBridge.swift in Sources */,
76D71B6E2C6B81CC00DAFB84 /* PenguinPlugin.swift in Sources */,
E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */, E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */,
E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */, E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */,
76D71B672C6B7F9C00DAFB84 /* HMGPenguinInPlatformBridge.swift in Sources */,
E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */, E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */,
E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */,
E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */,
E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */,
76D71B6C2C6B81B300DAFB84 /* PenguinView.swift in Sources */,
29631B9E2C96C7F600DF5916 /* PenguinNavigator.swift in Sources */,
76D71B6A2C6B819000DAFB84 /* PenguinModel.swift in Sources */,
76D71B702C6B81EA00DAFB84 /* PenguinViewFactory.swift in Sources */,
301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */, 301C79AE27200D9F0016307B /* OpenTokRemoteVideoFactory.swift in Sources */,
E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */,
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */, 306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */,
@ -528,6 +578,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
@ -553,10 +604,13 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile; SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Profile; name = Profile;
@ -675,6 +729,7 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
@ -700,10 +755,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile; SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Debug; name = Debug;
@ -713,6 +772,7 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
@ -738,11 +798,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_COMPILATION_MODE = singlefile; SWIFT_COMPILATION_MODE = singlefile;
"SWIFT_COMPILATION_MODE[arch=*]" = singlefile; "SWIFT_COMPILATION_MODE[arch=*]" = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Release; name = Release;

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1430" LastUpgradeVersion = "1510"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

@ -4,7 +4,7 @@ import GoogleMaps
var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
@UIApplicationMain @main
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate {
let locationManager = CLLocationManager() let locationManager = CLLocationManager()
var flutterViewController:MainFlutterVC! var flutterViewController:MainFlutterVC!
@ -30,11 +30,13 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil
flutterViewController = mainViewController flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController) HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
HMGPenguinInPlatformBridge.initialize(flutterViewController: flutterViewController)
}else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background }else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background
flutterViewController = mainViewController flutterViewController = mainViewController
HMGPlatformBridge.initialize(flutterViewController: flutterViewController) HMGPlatformBridge.initialize(flutterViewController: flutterViewController)
OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok")) OpenTokPlatformBridge.initialize(flutterViewController: flutterViewController, registrar: self.registrar(forPlugin: "open-tok"))
HMGPenguinInPlatformBridge.initialize(flutterViewController: flutterViewController)
} }
} }

@ -0,0 +1,61 @@
//
// HMGPenguinInPlatformBridge.swift
// Runner
//
// Created by Haroon Amjad on 13/08/2024.
//
import Foundation
var flutterMethodChannelPenguinIn:FlutterMethodChannel? = nil
fileprivate var mainViewController:MainFlutterVC!
class HMGPenguinInPlatformBridge{
private let channelName = "launch_penguin_ui"
private static var shared_:HMGPenguinInPlatformBridge?
class func initialize(flutterViewController:MainFlutterVC){
shared_ = HMGPenguinInPlatformBridge()
mainViewController = flutterViewController
shared_?.openChannel()
}
func shared() -> HMGPenguinInPlatformBridge{
assert((HMGPenguinInPlatformBridge.shared_ != nil), "HMGPenguinInPlatformBridge is not initialized, call initialize(mainViewController:MainFlutterVC) function first.")
return HMGPenguinInPlatformBridge.shared_!
}
private func openChannel(){
flutterMethodChannelPenguinIn = FlutterMethodChannel(name: channelName, binaryMessenger: mainViewController.binaryMessenger)
flutterMethodChannelPenguinIn?.setMethodCallHandler { (methodCall, result) in
print("Called function \(methodCall.method)")
if let arguments = methodCall.arguments as Any? {
if methodCall.method == "launchPenguin"{
self.launchPenguinView(arguments: arguments, result: result)
}
} else {
result(FlutterError(code: "INVALID_ARGUMENT", message: "Storyboard name is required", details: nil))
}
}
}
private func launchPenguinView(arguments: Any, result: @escaping FlutterResult) {
let penguinView = PenguinView(
frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height),
viewIdentifier: 0,
arguments: arguments,
binaryMessenger: mainViewController.binaryMessenger
)
let penguinUIView = penguinView.view()
penguinUIView.frame = mainViewController.view.bounds
penguinUIView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mainViewController.view.addSubview(penguinUIView)
result(nil) // Call result to indicate the method was successfully handled
}
}

@ -39,7 +39,7 @@
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>11.0</string> <string>13.0</string>
<key>NFCReaderUsageDescription</key> <key>NFCReaderUsageDescription</key>
<string>This app requires NFC Usage access to allow for Online CheckIn for appointments.</string> <string>This app requires NFC Usage access to allow for Online CheckIn for appointments.</string>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>
@ -60,7 +60,7 @@
<key>NSCalendarsUsageDescription</key> <key>NSCalendarsUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string> <string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCalendarsWriteOnlyAccessUsageDescription</key> <key>NSCalendarsWriteOnlyAccessUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string> <string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCalendarsFullAccessUsageDescription</key> <key>NSCalendarsFullAccessUsageDescription</key>
<string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string> <string>This app requires calendar access to set reminders for Virtual &amp; Normal Appointments.</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>

@ -0,0 +1,76 @@
//
// PenguinModel.swift
// Runner
//
// Created by Amir on 06/08/2024.
//
import Foundation
// Define the model class
struct PenguinModel {
let baseURL: String
let dataURL: String
let dataServiceName: String
let positionURL: String
let clientKey: String
let storyboardName: String
let mapBoxKey: String
let clientID: String
let positionServiceName: String
let username: String
let isSimulationModeEnabled: Bool
let isShowUserName: Bool
let isUpdateUserLocationSmoothly: Bool
let isEnableReportIssue: Bool
let languageCode: String
let clinicID: String
let patientID: String
let projectID: String
// Initialize the model from a dictionary
init?(from dictionary: [String: Any]) {
guard
let baseURL = dictionary["baseURL"] as? String,
let dataURL = dictionary["dataURL"] as? String,
let dataServiceName = dictionary["dataServiceName"] as? String,
let positionURL = dictionary["positionURL"] as? String,
let clientKey = dictionary["clientKey"] as? String,
let storyboardName = dictionary["storyboardName"] as? String,
let mapBoxKey = dictionary["mapBoxKey"] as? String,
let clientID = dictionary["clientID"] as? String,
let positionServiceName = dictionary["positionServiceName"] as? String,
let username = dictionary["username"] as? String,
let isSimulationModeEnabled = dictionary["isSimulationModeEnabled"] as? Bool,
let isShowUserName = dictionary["isShowUserName"] as? Bool,
let isUpdateUserLocationSmoothly = dictionary["isUpdateUserLocationSmoothly"] as? Bool,
let isEnableReportIssue = dictionary["isEnableReportIssue"] as? Bool,
let languageCode = dictionary["languageCode"] as? String,
let clinicID = dictionary["clinicID"] as? String,
let patientID = dictionary["patientID"] as? String,
let projectID = dictionary["projectID"] as? String
else {
print("Initialization failed due to missing or invalid keys.")
return nil
}
self.baseURL = baseURL
self.dataURL = dataURL
self.dataServiceName = dataServiceName
self.positionURL = positionURL
self.clientKey = clientKey
self.storyboardName = storyboardName
self.mapBoxKey = mapBoxKey
self.clientID = clientID
self.positionServiceName = positionServiceName
self.username = username
self.isSimulationModeEnabled = isSimulationModeEnabled
self.isShowUserName = isShowUserName
self.isUpdateUserLocationSmoothly = isUpdateUserLocationSmoothly
self.isEnableReportIssue = isEnableReportIssue
self.languageCode = languageCode
self.clinicID = clinicID
self.patientID = patientID
self.projectID = projectID
}
}

@ -0,0 +1,57 @@
import PenNavUI
import UIKit
class PenguinNavigator {
private var config: PenguinModel
init(config: PenguinModel) {
self.config = config
}
private func logError(_ message: String) {
// Centralized logging function
print("PenguinSDKNavigator Error: \(message)")
}
func navigateToPOI( referenceId:String,completion: @escaping (Bool, String?) -> Void) {
PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in
if let error = error {
let errorMessage = "Token error while getting the for Navigate to method"
completion(false, "Failed to get token: \(errorMessage)")
print("Failed to get token: \(errorMessage)")
return
}
guard let token = token else {
completion(false, "Token is nil")
print("Token is nil")
return
}
print("Token Generated")
print(token);
}
}
private func handleNavigation(referenceId: String, token: String, completion: @escaping (Bool, String?) -> Void) {
DispatchQueue.main.async {
PenNavUIManager.shared.setToken(token: token)
PenNavUIManager.shared.navigate(to: referenceId) { [weak self] _, navError in
guard let self = self else { return }
if let navError = navError {
self.logError("Navigation error: Reference ID invalid")
completion(false, "Navigation error: \(navError.localizedDescription)")
return
}
// Navigation successful
completion(true, nil)
}
}
}
}

@ -0,0 +1,31 @@
//
// BlueGpsPlugin.swift
// Runner
//
// Created by Penguin .
//
//import Foundation
//import Flutter
//
///**
// * A Flutter plugin for integrating Penguin SDK functionality.
// * This class registers a view factory with the Flutter engine to create native views.
// */
//class PenguinPlugin: NSObject, FlutterPlugin {
//
// /**
// * Registers the plugin with the Flutter engine.
// *
// * @param registrar The [FlutterPluginRegistrar] used to register the plugin.
// * This method is called when the plugin is initialized, and it sets up the communication
// * between Flutter and native code.
// */
// public static func register(with registrar: FlutterPluginRegistrar) {
// // Create an instance of PenguinViewFactory with the binary messenger from the registrar
// let factory = PenguinViewFactory(messenger: registrar.messenger())
//
// // Register the view factory with a unique ID for use in Flutter code
// registrar.register(factory, withId: "penguin_native")
// }
//}

@ -0,0 +1,224 @@
//
// BlueGpsView.swift
// Runner
//
// Created by Penguin.
//
import Foundation
import UIKit
import Flutter
import PenNavUI
import Foundation
import Flutter
import UIKit
/**
* A custom Flutter platform view for displaying Penguin UI components.
* This class integrates with the Penguin navigation SDK and handles UI events.
*/
class PenguinView: NSObject, FlutterPlatformView
, PIEventsDelegate, PenNavInitializationDelegate
{
// The main view displayed within the platform view
private var _view: UIView
private var model: PenguinModel?
/**
* Initializes the PenguinView with the provided parameters.
*
* @param frame The frame of the view, specifying its size and position.
* @param viewId A unique identifier for this view instance.
* @param args Optional arguments provided for creating the view.
* @param messenger The [FlutterBinaryMessenger] used for communication with Dart.
*/
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?
) {
_view = UIView()
super.init()
// Get the screen's width and height to set the view's frame
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
// Uncomment to set the background color of the view
// _view.backgroundColor = UIColor.red
// Set the frame of the view to cover the entire screen
_view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
print("========Inside Penguin View ========")
print(args)
guard let arguments = args as? [String: Any] else {
print("Error: Arguments are not in the expected format.")
return
}
print("===== i got tha Args=======")
// Initialize the model from the arguments
if let penguinModel = PenguinModel(from: arguments) {
self.model = penguinModel
initPenguin(args: penguinModel)
} else {
print("Error: Failed to initialize PenguinModel from arguments ")
}
// Initialize the Penguin SDK with required configurations
// initPenguin( arguments: args)
}
/**
* Initializes the Penguin SDK with custom configuration settings.
*/
func initPenguin(args: PenguinModel) {
// Set the initialization delegate to handle SDK initialization events
PenNavUIManager.shared.initializationDelegate = self
// Configure the Penguin SDK with necessary parameters
PenNavUIManager.shared
.setClientKey(args.clientKey)
.setClientID(args.clientID)
.setUsername(args.username)
.setSimulationModeEnabled(isEnable: args.isSimulationModeEnabled)
.setBaseURL(dataURL: args.dataURL, positionURL: args.positionURL)
.setServiceName(dataServiceName: args.dataServiceName, positionServiceName: args.positionServiceName)
.setIsShowUserName(args.isShowUserName)
.setIsUpdateUserLocationSmoothly(args.isUpdateUserLocationSmoothly)
.setEnableReportIssue(enable: args.isEnableReportIssue)
.setLanguage(args.languageCode)
.setBackButtonVisibility(true)
.build()
}
/**
* Returns the main view associated with this platform view.
*
* @return The UIView instance that represents this platform view.
*/
func view() -> UIView {
return _view
}
// MARK: - PIEventsDelegate Methods
/**
* Called when the Penguin UI is dismissed.
*/
func onPenNavUIDismiss() {
// Handle UI dismissal if needed
print("====== onPenNavUIDismiss =========")
self.view().removeFromSuperview()
}
/**
* Called when a report issue is generated.
*
* @param issue The type of issue reported.
*/
func onReportIssue(_ issue: PenNavUI.IssueType) {
// Handle report issue events if needed
print("====== onReportIssueError =========")
}
/**
* Called when the Penguin UI setup is successful.
*/
func onPenNavSuccess() {
print("====== onPenNavSuccess =========")
// Obtain the FlutterViewController instance
let controller: FlutterViewController = UIApplication.shared.windows.first?.rootViewController as! FlutterViewController
print("====== after contoller onPenNavSuccess =========")
// Set the events delegate to handle SDK events
PenNavUIManager.shared.eventsDelegate = self
print("====== after eventsDelegate onPenNavSuccess =========")
// Present the Penguin UI on top of the Flutter view controller
PenNavUIManager.shared.present(root: controller, view: _view)
print("====== after present onPenNavSuccess =========")
print(model?.clinicID)
print("====== after present onPenNavSuccess =========")
guard let config = self.model else {
print("Error: Config Model is nil")
return
}
guard let clinicID = self.model?.clinicID,
let clientID = self.model?.clientID, !clientID.isEmpty else {
print("Error: Config Client ID is nil or empty")
return
}
let navigator = PenguinNavigator(config: config)
PenNavUIManager.shared.getToken(clientID: config.clientID, clientKey: config.clientKey) { [weak self] token, error in
if let error = error {
let errorMessage = "Token error while getting the for Navigate to method"
print("Failed to get token: \(errorMessage)")
return
}
guard let token = token else {
print("Token is nil")
return
}
print("Token Generated")
print(token);
self?.handleNavigation(clinicID: clinicID, token: token) { success, errorMessage in
if success {
print("Navigation successful")
} else {
print("Navigation failed: \(errorMessage ?? "Unknown error")")
}
}
print("====== after Token onPenNavSuccess =========")
}
}
private func handleNavigation(clinicID: String, token: String, completion: @escaping (Bool, String?) -> Void) {
DispatchQueue.main.async {
PenNavUIManager.shared.setToken(token: token)
PenNavUIManager.shared.navigate(to: clinicID)
completion(true,nil)
}
}
/**
* Called when there is an initialization error with the Penguin UI.
*
* @param errorType The type of initialization error.
* @param errorDescription A description of the error.
*/
func onPenNavInitializationError(errorType: PenNavUI.PenNavUIError, errorDescription: String) {
// Handle initialization errors if needed
print("onPenNavInitializationErrorType: \(errorType.rawValue)")
print("onPenNavInitializationError: \(errorDescription)")
}
}

@ -0,0 +1,59 @@
//
// BlueGpsViewFactory.swift
// Runner
//
// Created by Penguin .
//
import Foundation
import Flutter
/**
* A factory class for creating instances of [PenguinView].
* This class implements `FlutterPlatformViewFactory` to create and manage native views.
*/
class PenguinViewFactory: NSObject, FlutterPlatformViewFactory {
// The binary messenger used for communication with the Flutter engine
private var messenger: FlutterBinaryMessenger
/**
* Initializes the PenguinViewFactory with the given messenger.
*
* @param messenger The [FlutterBinaryMessenger] used to communicate with Dart code.
*/
init(messenger: FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
/**
* Creates a new instance of [PenguinView].
*
* @param frame The frame of the view, specifying its size and position.
* @param viewId A unique identifier for this view instance.
* @param args Optional arguments provided for creating the view.
* @return An instance of [PenguinView] configured with the provided parameters.
*/
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return PenguinView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger)
}
/**
* Returns the codec used for encoding and decoding method channel arguments.
* This method is required when `arguments` in `create` is not `nil`.
*
* @return A [FlutterMessageCodec] instance used for serialization.
*/
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}

@ -335,18 +335,25 @@ var GET_PATIENT_HEALTH_STATS = 'Services/Patients.svc/REST/Med_GetTransactionsSt
var SEND_CHECK_IN_NFC_REQUEST = 'Services/Patients.svc/REST/Patient_CheckAppointmentValidation_ForNFC'; var SEND_CHECK_IN_NFC_REQUEST = 'Services/Patients.svc/REST/Patient_CheckAppointmentValidation_ForNFC';
var CHECK_SCANNED_NFC_QR_CODE = 'Services/Patients.svc/REST/Patient_ValidationMachine_ForNFC';
var HAS_DENTAL_PLAN = 'Services/Doctors.svc/REST/Dental_IsPatientHasOnGoingEstimation'; var HAS_DENTAL_PLAN = 'Services/Doctors.svc/REST/Dental_IsPatientHasOnGoingEstimation';
var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory'; var LASER_BODY_PARTS = 'Services/Patients.svc/REST/Laser_GetBodyPartsByCategory';
var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert'; var INSERT_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Insert';
var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Update'; var UPDATE_COVID_QUESTIONNAIRE = 'Services/Doctors.svc/REST/COVID19_Questionnarie_Update';
var GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForWalkIn';
var CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT = 'Services/Doctors.svc/REST/CanPayForWalkinAppointment';
//URL to get medicine and pharmacies list //URL to get medicine and pharmacies list
var CHANNEL = 3; var CHANNEL = 3;
var GENERAL_ID = 'Cs2020@2016\$2958'; var GENERAL_ID = 'Cs2020@2016\$2958';
var IP_ADDRESS = '10.20.10.20'; var IP_ADDRESS = '10.20.10.20';
var VERSION_ID = 16.3; var VERSION_ID = 16.4;
var SETUP_ID = '91877'; var SETUP_ID = '91877';
var LANGUAGE = 2; var LANGUAGE = 2;
// var PATIENT_OUT_SA = 0; // var PATIENT_OUT_SA = 0;
@ -603,9 +610,9 @@ var GET_DENTAL_APPOINTMENT_INVOICE = "Services/Patients.svc/REST/HIS_eInvoiceFor
var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental"; var SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = "Services/Notifications.svc/REST/SendInvoiceForDental";
var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamaralive/Home/GetInstallments'; var GET_TAMARA_PLAN = 'https://mdlaboratories.com/tamara/Home/GetInstallments';
var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid='; var GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamara/api/OnlineTamara/order_status?orderid=';
var UPDATE_TAMARA_STATUS = 'Services/PayFort_Serv.svc/REST/Tamara_UpdateRequestStatus'; var UPDATE_TAMARA_STATUS = 'Services/PayFort_Serv.svc/REST/Tamara_UpdateRequestStatus';
@ -667,6 +674,8 @@ var GET_WE_CARE_TOUR_URL = 'Services/Consent.svc/Rest/Consent_VirtualJurny_Url_G
var GET_DENTAL_INSTRUCTIONS = 'Services/OUTPs.svc/Rest/getProcedureNotification'; var GET_DENTAL_INSTRUCTIONS = 'Services/OUTPs.svc/Rest/getProcedureNotification';
var INSERT_WALKIN_APPOINTMENT = "Services/Doctors.svc/REST/InsertWalkinAppointment";
//PAYFORT //PAYFORT
var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails"; var getPayFortProjectDetails = "Services/PayFort_Serv.svc/REST/GetPayFortProjectDetails";
var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse"; var addPayFortApplePayResponse = "Services/PayFort_Serv.svc/REST/AddResponse";

@ -1981,5 +1981,16 @@ const Map localizedValues = {
"newAppointment":{"en":"New Appointment","ar":"موعد جديد"}, "newAppointment":{"en":"New Appointment","ar":"موعد جديد"},
"proceedPackage":{"en":"Proceed with package","ar":"المضي قدما في الحزمة"}, "proceedPackage":{"en":"Proceed with package","ar":"المضي قدما في الحزمة"},
"clinicLocation": {"en": "Clinic Location", "ar": "موقع العيادة"},
"waitingAppointment": {"en": "Waiting appointment", "ar": "انتظار الموعد"},
"whatWaitingAppointment": {"en": "What is Waiting appointment?", "ar": "ما هو انتظار الموعد؟"},
"waitingAppointmentText1": {"en": "The waiting appointments feature allows you to book an appointment while you are inside the hospital building, and in case there is no available slot in the doctors schedule.", "ar": "تتيح لك خاصية انتظار المواعيد حجز موعد أثناء تواجدك داخل مبنى المستشفى، وفي حالة عدم وجود وقت متاح في جدول الطبيب."},
"waitingAppointmentText2": {"en": "The appointment with the doctor is confirmed, but the time of entry is uncertain", "ar": "دخول الموعد مؤكد, التوقيت غير محدد."},
"waitingAppointmentText3": {"en": "Note: You must have to pay within 10 minutes of booking, otherwise your appointment will be cancelled automatically", "ar": "ملحوظة: يجب عليك الدفع خلال 10 دقائق من الحجز، وإلا سيتم إلغاء موعدك تلقائيًا"},
"waitingAppointmentVerificationMethod": {"en": "Please select verification method", "ar": "الرجاء تحديد طريقة التحقق"},
"howToUseVerificationMethod": {"en": "How to use verification methods?", "ar": "كيفية استخدام طرق التحقق؟"},
"addToWaitingList": {"en": "Add to waiting list", "ar": "اضافه الى قائمة الانتظار"},
"searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"}, "searchClinic": {"en": "Search Clinic", "ar": "بحث العيادة"},
"selectBranch":{"en":"Select Branch", "ar":"اختر الفرع"},
"searchByBranch":{"en":"Search By Branch Name", "ar":"البحث عن طريق اسم الفرع"}
}; };

@ -31,8 +31,7 @@ AppSharedPreferences sharedPref = new AppSharedPreferences();
/// onFailure: (String error, int statusCode) {}, /// onFailure: (String error, int statusCode) {},
/// body: Map(); /// body: Map();
/// ///
AuthenticatedUserObject authenticatedUserObject = AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>();
locator<AuthenticatedUserObject>();
VitalSignService _vitalSignService = locator<VitalSignService>(); VitalSignService _vitalSignService = locator<VitalSignService>();
class BaseAppClient { class BaseAppClient {
@ -40,12 +39,12 @@ class BaseAppClient {
post(String endPoint, post(String endPoint,
{required Map<String, dynamic> body, {required Map<String, dynamic> body,
required Function(dynamic response, int statusCode) onSuccess, required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
bool isAllowAny = false, bool isAllowAny = false,
bool isExternal = false, bool isExternal = false,
bool isRCService = false, bool isRCService = false,
bool bypassConnectionCheck = false}) async { bool bypassConnectionCheck = false}) async {
String url; String url;
if (isExternal) { if (isExternal) {
url = endPoint; url = endPoint;
@ -56,25 +55,20 @@ class BaseAppClient {
url = BASE_URL + endPoint; url = BASE_URL + endPoint;
} }
try { try {
String? pharmacyToken = String? pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
Map<String, String> headers = { Map<String, String> headers = {'Content-Type': 'application/json', 'Accept': 'application/json'};
'Content-Type': 'application/json',
'Accept': 'application/json'
};
if (!isExternal) { if (!isExternal) {
String? token = await sharedPref.getString(TOKEN); String? token = await sharedPref.getString(TOKEN);
String? languageID = String? languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
if (endPoint == SEND_ACTIVATION_CODE) { if (endPoint == SEND_ACTIVATION_CODE) {
languageID = 'en'; languageID = 'en';
} }
if (body.containsKey('SetupID')) { if (body.containsKey('SetupID')) {
body['SetupID'] = body.containsKey('SetupID') body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null ? body['SetupID'] != null
? body['SetupID'] ? body['SetupID']
: SETUP_ID : SETUP_ID
: SETUP_ID; : SETUP_ID;
} }
@ -87,8 +81,8 @@ class BaseAppClient {
body['LanguageID'] = body['LanguageID'] == 'ar' body['LanguageID'] = body['LanguageID'] == 'ar'
? 1 ? 1
: body['LanguageID'] == 'en' : body['LanguageID'] == 'en'
? 2 ? 2
: body['LanguageID']; : body['LanguageID'];
} else { } else {
body['LanguageID'] = Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isArabic ? 1 : 2; body['LanguageID'] = Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isArabic ? 1 : 2;
} }
@ -120,16 +114,16 @@ class BaseAppClient {
if (body.containsKey('isDentalAllowedBackend')) { if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] != null ? body['isDentalAllowedBackend'] != null
? body['isDentalAllowedBackend'] ? body['isDentalAllowedBackend']
: IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND; : IS_DENTAL_ALLOWED_BACKEND;
} }
body['DeviceTypeID'] = Platform.isIOS body['DeviceTypeID'] = Platform.isIOS
? 1 ? 1
: await Utils.isGoogleServicesAvailable() : await Utils.isGoogleServicesAvailable()
? 2 ? 2
: 3; : 3;
if (!body.containsKey('IsPublicRequest')) { if (!body.containsKey('IsPublicRequest')) {
// if (!body.containsKey('PatientType')) { // if (!body.containsKey('PatientType')) {
@ -166,17 +160,14 @@ class BaseAppClient {
if (user != null) { if (user != null) {
body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token; body['TokenID'] = body['TokenID'] != null ? body['TokenID'] : token;
body['PatientID'] = body['PatientID'] != null body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID'];
? body['PatientID']
: user['PatientID'];
body['PatientOutSA'] = body.containsKey('PatientOutSA') body['PatientOutSA'] = body.containsKey('PatientOutSA')
? body['PatientOutSA'] != null ? body['PatientOutSA'] != null
? body['PatientOutSA'] ? body['PatientOutSA']
: user['OutSA'] : user['OutSA']
: user['OutSA']; : user['OutSA'];
body['SessionID'] = getSessionId( body['SessionID'] = getSessionId(body['TokenID'] != null ? body['TokenID'] : ""); //getSe
body['TokenID'] != null ? body['TokenID'] : ""); //getSe
// body['SessionID'] = body['TokenID']; //getSe // body['SessionID'] = body['TokenID']; //getSe
// headers = { // headers = {
@ -193,7 +184,7 @@ class BaseAppClient {
// body['IdentificationNo'] = 1023854217; // body['IdentificationNo'] = 1023854217;
// body['MobileNo'] = "531940021"; //0560717232 // body['MobileNo'] = "531940021"; //0560717232
// body['PatientID'] = 283093; //4609100 // body['PatientID'] = 4768303; //4609100
// body['TokenID'] = "@dm!n"; // body['TokenID'] = "@dm!n";
// Patient ID: 3027574 // Patient ID: 3027574
@ -202,21 +193,23 @@ class BaseAppClient {
body.removeWhere((key, value) => key == null || value == null); body.removeWhere((key, value) => key == null || value == null);
// if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') {
// url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo";
// body['TokenID'] = "@dm!n";
// }
// if (AppGlobal.isNetworkDebugEnabled) { // if (AppGlobal.isNetworkDebugEnabled) {
print("URL : $url"); print("URL : $url");
final jsonBody = json.encode(body); final jsonBody = json.encode(body);
print(jsonBody); print(jsonBody);
// } // }
if (await Utils.checkConnection( if (await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck)) {
bypassConnectionCheck: bypassConnectionCheck)) { final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
final response = await http.post(Uri.parse(url.trim()),
body: json.encode(body), headers: headers);
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure('Error While Fetching data', statusCode); onFailure('Error While Fetching data', statusCode);
logApiEndpointError( logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
endPoint, 'Error While Fetching data', statusCode);
} else { } else {
// var decoded = utf8.decode(response.bodyBytes); // var decoded = utf8.decode(response.bodyBytes);
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -230,12 +223,8 @@ class BaseAppClient {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
navigateToAppUpdate( navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
AppGlobal.context, parsed['ErrorEndUserMessage']); logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
if (parsed['ErrorType'] == 2) { if (parsed['ErrorType'] == 2) {
await logout(); await logout();
@ -254,46 +243,28 @@ class BaseAppClient {
// if (parsed != null) { // if (parsed != null) {
// onSuccess(parsed, statusCode); // onSuccess(parsed, statusCode);
// } else { // } else {
onFailure( onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
// logout(); // logout();
// } // }
} }
} else if (parsed['MessageStatus'] == 1 || } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
parsed['SMSLoginRequired'] == true) {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) { if (parsed['SameClinicApptList'] != null) {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['message'] == null && if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", onFailure("Server Error found with no available message", statusCode);
statusCode); logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
logApiEndpointError(
endPoint,
"Server Error found with no available message",
statusCode);
} else { } else {
onFailure(parsed['ErrorSearchMsg'], statusCode); onFailure(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
endPoint, parsed['ErrorSearchMsg'], statusCode);
} }
} else { } else {
onFailure( onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['message'] ?? logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
logApiEndpointError(endPoint,
parsed['message'] ?? parsed['message'], statusCode);
} }
} }
} }
@ -305,18 +276,11 @@ class BaseAppClient {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure( onFailure(parsed['message'] ?? parsed['message'], statusCode);
parsed['message'] ?? parsed['message'], statusCode); logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint,
parsed['message'] ?? parsed['message'], statusCode);
} else { } else {
onFailure( onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -325,23 +289,17 @@ class BaseAppClient {
} }
} else { } else {
onFailure('Please Check The Internet Connection', -1); onFailure('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} catch (e) { } catch (e) {
print(e); print(e);
onFailure(e.toString(), -1); onFailure(e.toString(), -1);
_analytics.errorTracking _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url");
.log(endPoint, error: "api exception: $e - API Path: $url");
} }
} }
postPharmacy(String endPoint, postPharmacy(String endPoint,
{Map<String, dynamic>? body, {Map<String, dynamic>? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async {
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
bool isAllowAny = false,
bool isExternal = false}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
String url; String url;
@ -358,16 +316,13 @@ class BaseAppClient {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': pharmacyToken ?? '', 'Authorization': pharmacyToken ?? '',
'Mobilenumber': user != null 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "", 'Username': user != null ? user['PatientID'].toString() : "",
}; };
if (!isExternal) { if (!isExternal) {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
// if (body.containsKey('SetupID')) { // if (body.containsKey('SetupID')) {
// body['SetupID'] = body.containsKey('SetupID') // body['SetupID'] = body.containsKey('SetupID')
@ -429,14 +384,12 @@ class BaseAppClient {
print("Headers : ${json.encode(headers)}"); print("Headers : ${json.encode(headers)}");
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
final response = await http.post(Uri.parse(url.trim()), final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
body: json.encode(body), headers: headers);
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
logApiEndpointError( logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
endPoint, 'Error While Fetching data', statusCode);
} else { } else {
// var parsed = json.decode(response.body.toString()); // var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -444,12 +397,8 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
navigateToAppUpdate( navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
AppGlobal.context, parsed['ErrorEndUserMessage']); logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
if (isAllowAny) { if (isAllowAny) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
@ -464,56 +413,29 @@ class BaseAppClient {
if (parsed != null) { if (parsed != null) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode); logApiEndpointError(endPoint, 'session logged out', statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
logApiEndpointError(
endPoint, 'session logged out', statusCode);
logout(); logout();
} }
} }
} else if (parsed['MessageStatus'] == 1 || } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
parsed['SMSLoginRequired'] == true) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) { if (parsed['SameClinicApptList'] != null) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['message'] == null && if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure!("Server Error found with no available message", onFailure!("Server Error found with no available message", statusCode);
statusCode); logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
logApiEndpointError(
endPoint,
"Server Error found with no available message",
statusCode);
} else { } else {
onFailure!(parsed['ErrorSearchMsg'], statusCode); onFailure!(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, parsed['ErrorSearchMsg'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
endPoint,
parsed['ErrorSearchMsg'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} else { } else {
onFailure!( onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['message'] ?? logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
logApiEndpointError(
endPoint,
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} }
} else if (!parsed['IsAuthenticated']) { } else if (!parsed['IsAuthenticated']) {
@ -525,22 +447,11 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure!( onFailure!(parsed['message'] ?? parsed['message'], statusCode);
parsed['message'] ?? parsed['message'], statusCode); logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
logApiEndpointError(
endPoint,
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -548,8 +459,7 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} catch (e) { } catch (e) {
print(e); print(e);
@ -560,18 +470,18 @@ class BaseAppClient {
Future navigateToAppUpdate(context, String text) async { Future navigateToAppUpdate(context, String text) async {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
locator<NavigationService>().navigatorKey.currentContext!, locator<NavigationService>().navigatorKey.currentContext!,
MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)), MaterialPageRoute(builder: (context) => AppUpdatePage(appUpdateText: text)),
(Route<dynamic> route) => false, (Route<dynamic> route) => false,
); );
} }
get(String endPoint, get(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess, {required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
Map<String, dynamic>? queryParams, Map<String, dynamic>? queryParams,
bool isExternal = false, bool isExternal = false,
bool isRCService = false}) async { bool isRCService = false}) async {
String url; String url;
if (isExternal) { if (isExternal) {
url = endPoint; url = endPoint;
@ -592,10 +502,7 @@ class BaseAppClient {
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
final response = await http.get( final response = await http.get(
Uri.parse(url.trim()), Uri.parse(url.trim()),
headers: { headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
'Content-Type': 'application/json',
'Accept': 'application/json'
},
); );
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
@ -609,17 +516,16 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
getPharmacy(String endPoint, getPharmacy(String endPoint,
{required Function(dynamic response, int statusCode) onSuccess, {required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
bool isAllowAny = false, bool isAllowAny = false,
bool isExternal = false, bool isExternal = false,
Map<String, dynamic>? queryParams}) async { Map<String, dynamic>? queryParams}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
@ -642,9 +548,7 @@ class BaseAppClient {
'Content-Type': 'text/html; charset=utf-8', 'Content-Type': 'text/html; charset=utf-8',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': token ?? '', 'Authorization': token ?? '',
'Mobilenumber': user != null 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "", 'Username': user != null ? user['PatientID'].toString() : "",
// 'Host': "mdlaboratories.com", // 'Host': "mdlaboratories.com",
@ -654,19 +558,14 @@ class BaseAppClient {
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
if (statusCode == 401) { if (statusCode == 401) {
onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, onFailure!(TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
statusCode); logApiEndpointError(endPoint, TranslationBase.of(AppGlobal.context).pharmacyRelogin, statusCode);
logApiEndpointError(
endPoint,
TranslationBase.of(AppGlobal.context).pharmacyRelogin,
statusCode);
Navigator.of(AppGlobal.context).pushNamed(HOME); Navigator.of(AppGlobal.context).pushNamed(HOME);
} else { } else {
var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); var bodyUtf = json.decode(utf8.decode(response.bodyBytes));
// print(bodyUtf); // print(bodyUtf);
onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode); onFailure!(bodyUtf['error']['ErrorEndUserMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
endPoint, bodyUtf['error']['ErrorEndUserMsg'], statusCode);
} }
} else { } else {
// var parsed = json.decode(response.body.toString()); // var parsed = json.decode(response.body.toString());
@ -675,25 +574,23 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simplePost( simplePost(
String fullUrl, { String fullUrl, {
required Map<dynamic, dynamic> body, required Map<dynamic, dynamic> body,
required Map<String, String> headers, required Map<String, String> headers,
required Function(dynamic response, int statusCode) onSuccess, required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure, required Function(String error, int statusCode) onFailure,
}) async { }) async {
String url = fullUrl; String url = fullUrl;
// print("URL Query String: $url"); // print("URL Query String: $url");
// print("body: $body"); // print("body: $body");
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers!.addAll( headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.post( final response = await http.post(
Uri.parse(url.trim()), Uri.parse(url.trim()),
body: json.encode(body), body: json.encode(body),
@ -701,12 +598,7 @@ class BaseAppClient {
); );
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers);
simplePost(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
body: body,
headers: headers);
// print(response.body.toString()); // print(response.body.toString());
@ -718,16 +610,12 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simpleGet(String fullUrl, simpleGet(String fullUrl,
{Function(dynamic response, int statusCode)? onSuccess, {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map<String, dynamic>? queryParams, Map<String, String>? headers}) async {
Function(String error, int statusCode)? onFailure,
Map<String, dynamic>? queryParams,
Map<String, String>? headers}) async {
headers = headers ?? {}; headers = headers ?? {};
String url = fullUrl; String url = fullUrl;
@ -739,8 +627,7 @@ class BaseAppClient {
} }
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers.addAll( headers.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.get( final response = await http.get(
Uri.parse(url.trim()), Uri.parse(url.trim()),
headers: headers, headers: headers,
@ -748,12 +635,7 @@ class BaseAppClient {
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleGet(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, queryParams: queryParams);
simpleGet(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
headers: headers,
queryParams: queryParams);
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
@ -763,22 +645,17 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simplePut(String fullUrl, simplePut(String fullUrl,
{Map<String, dynamic>? body, {Map<String, dynamic>? body, Map<String, String>? headers, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure}) async {
Map<String, String>? headers,
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure}) async {
String url = fullUrl; String url = fullUrl;
// print("URL Query String: $url"); // print("URL Query String: $url");
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers!.addAll( headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.put( final response = await http.put(
Uri.parse(url.trim()), Uri.parse(url.trim()),
body: json.encode(body), body: json.encode(body),
@ -787,12 +664,7 @@ class BaseAppClient {
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePut(fullUrl, onFailure: onFailure, onSuccess: onSuccess, headers: headers, body: body);
simplePut(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
headers: headers,
body: body);
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
@ -802,16 +674,12 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
simpleDelete(String fullUrl, simpleDelete(String fullUrl,
{Function(dynamic response, int statusCode)? onSuccess, {Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, Map<String, String>? queryParams, Map<String, String>? headers}) async {
Function(String error, int statusCode)? onFailure,
Map<String, String>? queryParams,
Map<String, String>? headers}) async {
String url = fullUrl; String url = fullUrl;
// print("URL Query String: $url"); // print("URL Query String: $url");
@ -823,8 +691,7 @@ class BaseAppClient {
} }
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
headers!.addAll( headers!.addAll({'Content-Type': 'application/json', 'Accept': 'application/json'});
{'Content-Type': 'application/json', 'Accept': 'application/json'});
final response = await http.delete( final response = await http.delete(
Uri.parse(url.trim()), Uri.parse(url.trim()),
headers: headers, headers: headers,
@ -832,12 +699,7 @@ class BaseAppClient {
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (await handleUnauthorized(statusCode, forUrl: fullUrl)) if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simpleDelete(fullUrl, onFailure: onFailure, onSuccess: onSuccess, queryParams: queryParams, headers: headers);
simpleDelete(fullUrl,
onFailure: onFailure,
onSuccess: onSuccess,
queryParams: queryParams,
headers: headers);
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
onFailure!('Error While Fetching data', statusCode); onFailure!('Error While Fetching data', statusCode);
@ -847,13 +709,11 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} }
Future<bool> handleUnauthorized(int statusCode, Future<bool> handleUnauthorized(int statusCode, {required String forUrl}) async {
{required String forUrl}) async {
if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) { if (forUrl.startsWith(EXA_CART_API_BASE_URL) && statusCode == 401) {
final token = await generatePackagesToken(); final token = await generatePackagesToken();
packagesAuthHeader['Authorization'] = 'Bearer $token'; packagesAuthHeader['Authorization'] = 'Bearer $token';
@ -866,10 +726,8 @@ class BaseAppClient {
await sharedPref.remove(LOGIN_TOKEN_ID); await sharedPref.remove(LOGIN_TOKEN_ID);
await sharedPref.remove(PHARMACY_CUSTOMER_ID); await sharedPref.remove(PHARMACY_CUSTOMER_ID);
await authenticatedUserObject.getUser(); await authenticatedUserObject.getUser();
Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isLogin = Provider.of<ProjectViewModel>(AppGlobal.context, listen: false).isLogin = false;
false; var model = Provider.of<ToDoCountProviderModel>(AppGlobal.context, listen: false);
var model =
Provider.of<ToDoCountProviderModel>(AppGlobal.context, listen: false);
_vitalSignService.weightKg = ""; _vitalSignService.weightKg = "";
_vitalSignService.heightCm = ""; _vitalSignService.heightCm = "";
model.setState(0, 0, false, null); model.setState(0, 0, false, null);
@ -884,8 +742,7 @@ class BaseAppClient {
static defaultHttpParameters() async { static defaultHttpParameters() async {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
var params = {}; var params = {};
if (user != null) { if (user != null) {
@ -905,11 +762,7 @@ class BaseAppClient {
} }
pharmacyPost(String endPoint, pharmacyPost(String endPoint,
{Map<String, dynamic>? body, {Map<String, dynamic>? body, Function(dynamic response, int statusCode)? onSuccess, Function(String error, int statusCode)? onFailure, bool isAllowAny = false, bool isExternal = false}) async {
Function(dynamic response, int statusCode)? onSuccess,
Function(String error, int statusCode)? onFailure,
bool isAllowAny = false,
bool isExternal = false}) async {
var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN);
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
String url; String url;
@ -921,14 +774,13 @@ class BaseAppClient {
try { try {
if (isExternal) { if (isExternal) {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
var user = await sharedPref.getObject(USER_PROFILE); var user = await sharedPref.getObject(USER_PROFILE);
if (body!.containsKey('SetupID')) { if (body!.containsKey('SetupID')) {
body['SetupID'] = body.containsKey('SetupID') body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null ? body['SetupID'] != null
? body['SetupID'] ? body['SetupID']
: SETUP_ID : SETUP_ID
: SETUP_ID; : SETUP_ID;
} }
@ -940,15 +792,15 @@ class BaseAppClient {
body['generalid'] = GENERAL_ID; body['generalid'] = GENERAL_ID;
body['PatientOutSA'] = body.containsKey('PatientOutSA') body['PatientOutSA'] = body.containsKey('PatientOutSA')
? body['PatientOutSA'] != null ? body['PatientOutSA'] != null
? body['PatientOutSA'] ? body['PatientOutSA']
: user['OutSA'] : user['OutSA']
: user['OutSA']; : user['OutSA'];
if (body.containsKey('isDentalAllowedBackend')) { if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] != null ? body['isDentalAllowedBackend'] != null
? body['isDentalAllowedBackend'] ? body['isDentalAllowedBackend']
: IS_DENTAL_ALLOWED_BACKEND : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND; : IS_DENTAL_ALLOWED_BACKEND;
} }
@ -957,24 +809,22 @@ class BaseAppClient {
if (!body.containsKey('IsPublicRequest')) { if (!body.containsKey('IsPublicRequest')) {
body['PatientType'] = body.containsKey('PatientType') body['PatientType'] = body.containsKey('PatientType')
? body['PatientType'] != null ? body['PatientType'] != null
? body['PatientType'] ? body['PatientType']
: user['PatientType'] != null : user['PatientType'] != null
? user['PatientType'] ? user['PatientType']
: user['PatientType'] : user['PatientType']
: user['PatientType']; : user['PatientType'];
body['PatientTypeID'] = body.containsKey('PatientTypeID') body['PatientTypeID'] = body.containsKey('PatientTypeID')
? body['PatientTypeID'] != null ? body['PatientTypeID'] != null
? body['PatientTypeID'] ? body['PatientTypeID']
: user['PatientType'] != null : user['PatientType'] != null
? user['PatientType'] ? user['PatientType']
: user['PatientType'] : user['PatientType']
: user['PatientType']; : user['PatientType'];
if (user != null) { if (user != null) {
body['TokenID'] = token; body['TokenID'] = token;
body['PatientID'] = body['PatientID'] != null body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : user['PatientID'];
? body['PatientID']
: user['PatientID'];
body['PatientOutSA'] = user['OutSA']; body['PatientOutSA'] = user['OutSA'];
// body['SessionID'] = SESSION_ID; //getSessionId(token); // body['SessionID'] = SESSION_ID; //getSessionId(token);
} }
@ -986,14 +836,11 @@ class BaseAppClient {
var ss = json.encode(body); var ss = json.encode(body);
if (await Utils.checkConnection()) { if (await Utils.checkConnection()) {
final response = await http final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: {
.post(Uri.parse(url.trim()), body: json.encode(body), headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': token ?? '', 'Authorization': token ?? '',
'Mobilenumber': user != null 'Mobilenumber': user != null ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) : "",
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user != null ? user['PatientID'].toString() : "", 'Username': user != null ? user['PatientID'].toString() : "",
}); });
@ -1001,15 +848,8 @@ class BaseAppClient {
// print("statusCode :$statusCode"); // print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
onFailure!( onFailure!(parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
parsed['error']['ErrorEndUserMsgN'] ?? logApiEndpointError(endPoint, parsed['error']['ErrorEndUserMsgN'] ?? 'Error While Fetching data', statusCode);
'Error While Fetching data',
statusCode);
logApiEndpointError(
endPoint,
parsed['error']['ErrorEndUserMsgN'] ??
'Error While Fetching data',
statusCode);
} else { } else {
// var parsed = json.decode(response.body.toString()); // var parsed = json.decode(response.body.toString());
var parsed = json.decode(utf8.decode(response.bodyBytes)); var parsed = json.decode(utf8.decode(response.bodyBytes));
@ -1017,8 +857,7 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
navigateToAppUpdate( navigateToAppUpdate(AppGlobal.context, parsed['ErrorEndUserMessage']);
AppGlobal.context, parsed['ErrorEndUserMessage']);
} }
if (isAllowAny) { if (isAllowAny) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
@ -1033,47 +872,25 @@ class BaseAppClient {
if (parsed != null) { if (parsed != null) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
logout(); logout();
} }
} }
} else if (parsed['MessageStatus'] == 1 || } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) {
parsed['SMSLoginRequired'] == true) {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) {
parsed['IsAuthenticated']) { if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) {
if (parsed['message'] == null &&
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure!("Server Error found with no available message", onFailure!("Server Error found with no available message", statusCode);
statusCode); logApiEndpointError(endPoint, "Server Error found with no available message", statusCode);
logApiEndpointError(
endPoint,
"Server Error found with no available message",
statusCode);
} else { } else {
onFailure!(parsed['ErrorSearchMsg'], statusCode); onFailure!(parsed['ErrorSearchMsg'], statusCode);
logApiEndpointError( logApiEndpointError(endPoint, parsed['ErrorSearchMsg'], statusCode);
endPoint, parsed['ErrorSearchMsg'], statusCode);
} }
} else { } else {
onFailure!( onFailure!(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['message'] ?? logApiEndpointError(endPoint, parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
logApiEndpointError(
endPoint,
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} else if (!parsed['IsAuthenticated']) { } else if (!parsed['IsAuthenticated']) {
await logout(); await logout();
@ -1084,18 +901,11 @@ class BaseAppClient {
onSuccess!(parsed, statusCode); onSuccess!(parsed, statusCode);
} else { } else {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure!( onFailure!(parsed['message'] ?? parsed['message'], statusCode);
parsed['message'] ?? parsed['message'], statusCode); logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode);
logApiEndpointError(endPoint,
parsed['message'] ?? parsed['message'], statusCode);
} else { } else {
onFailure!( onFailure!(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode);
statusCode);
logApiEndpointError(
endPoint,
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -1103,8 +913,7 @@ class BaseAppClient {
} }
} else { } else {
onFailure!('Please Check The Internet Connection', -1); onFailure!('Please Check The Internet Connection', -1);
_analytics.errorTracking _analytics.errorTracking.log("internet_connectivity", error: "no internet available");
.log("internet_connectivity", error: "no internet available");
} }
} catch (e) { } catch (e) {
print(e); print(e);
@ -1116,15 +925,11 @@ class BaseAppClient {
Future<String> generatePackagesToken() async { Future<String> generatePackagesToken() async {
var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN; var url = EXA_CART_API_BASE_URL + PACKAGES_TOKEN;
var body = { var body = {
"api_client": { "api_client": {"client_id": "a4ab6be4-424f-4836-b032-46caed88e184", "client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"}
"client_id": "a4ab6be4-424f-4836-b032-46caed88e184",
"client_secret": "3c1a3e07-4a40-4510-9fb0-ee5f0a72752c"
}
}; };
String? token; String? token;
final completer = Completer(); final completer = Completer();
simplePost(url, body: body, headers: {}, simplePost(url, body: body, headers: {}, onSuccess: (dynamic stringResponse, int statusCode) {
onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) { if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse); var jsonResponse = json.decode(stringResponse);
token = jsonResponse['auth_token']; token = jsonResponse['auth_token'];

@ -18,7 +18,10 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
import '../../models/Appointments/DoctorListResponse.dart';
bool isAppArabic = false; bool isAppArabic = false;
class ProjectViewModel extends BaseViewModel { class ProjectViewModel extends BaseViewModel {
GAnalytics get analytics => locator<GAnalytics>(); GAnalytics get analytics => locator<GAnalytics>();
@ -45,6 +48,27 @@ class ProjectViewModel extends BaseViewModel {
GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel(); GetAdmissionInfoResponseModel getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel();
GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel(); GetAdmissionRequestInfoResponseModel getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel();
bool isIndoorNavigationEnabled = false;
int waitingAppointmentProjectID = 0;
DoctorList? waitingAppointmentDoctor;
String waitingAppointmentNFCCode = "";
setWaitingAppointmentDoctor(DoctorList waitingAppointmentDoctor) {
this.waitingAppointmentDoctor = waitingAppointmentDoctor;
notifyListeners();
}
setWaitingAppointmentNFCCode(String waitingAppointmentNFCCode) {
this.waitingAppointmentNFCCode = waitingAppointmentNFCCode;
notifyListeners();
}
setWaitingAppointmentProjectID(int projectID) {
this.waitingAppointmentProjectID = projectID;
notifyListeners();
}
void setIsAllAppointmentsLoaded(bool value) { void setIsAllAppointmentsLoaded(bool value) {
_isAllAppointmentsLoaded = value; _isAllAppointmentsLoaded = value;
notifyListeners(); notifyListeners();
@ -137,6 +161,11 @@ class ProjectViewModel extends BaseViewModel {
notifyListeners(); notifyListeners();
} }
setIsIndoorNavigationEnabled(bool isEnabled) {
this.isIndoorNavigationEnabled = isEnabled;
notifyListeners();
}
setPatientHasAdmissionRequest(bool hasAdmissionRequest) { setPatientHasAdmissionRequest(bool hasAdmissionRequest) {
this.patientHasAdmissionRequest = hasAdmissionRequest; this.patientHasAdmissionRequest = hasAdmissionRequest;
notifyListeners(); notifyListeners();

@ -37,6 +37,7 @@ class _AllHabibMedicalSevicePage2State extends State<AllHabibMedicalSevicePage2>
AuthProvider authProvider = new AuthProvider(); AuthProvider authProvider = new AuthProvider();
WeatherService _weatherService = WeatherService(); WeatherService _weatherService = WeatherService();
double weatherNum = 30; double weatherNum = 30;
late ProjectViewModel projectViewModel;
@override @override
void initState() { void initState() {
@ -235,7 +236,7 @@ class _AllHabibMedicalSevicePage2State extends State<AllHabibMedicalSevicePage2>
itemCount: hmgServices.length, itemCount: hmgServices.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, false); return ServicesView(hmgServices[index], index, false, projectViewModel);
}, },
), ),
), ),

@ -445,7 +445,7 @@ class _BloodDonationBookAppointmentState extends State<BloodDonationBookAppointm
_events!.forEach((key, value) { _events!.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20)); final DateTime endTime = startTime.add(const Duration(minutes: 20));
meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
}); });
return meetings; return meetings;
} }
@ -492,11 +492,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { class Meeting {
Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -1,26 +1,38 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/enum/PayfortEnums.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/LiveCare/ApplePayInsertRequest.dart';
import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/widgets/paymentDialog.dart';
import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
@ -42,7 +54,10 @@ class BookConfirm extends StatefulWidget {
bool isLiveCareAppointment; bool isLiveCareAppointment;
int initialSlotDuration; int initialSlotDuration;
BookConfirm({required this.doctor, required this.selectedDate, required this.isLiveCareAppointment, required this.selectedTime, required this.initialSlotDuration}); bool isWalkinAppointment = false;
BookConfirm(
{required this.doctor, required this.selectedDate, required this.isLiveCareAppointment, required this.selectedTime, required this.initialSlotDuration, required this.isWalkinAppointment});
late DoctorsListService service; late DoctorsListService service;
late PatientShareResponse patientShareResponse; late PatientShareResponse patientShareResponse;
@ -63,6 +78,13 @@ class _BookConfirmState extends State<BookConfirm> {
bool isEligible = false; bool isEligible = false;
bool isCash = false; bool isCash = false;
String? selectedPaymentMethod = "";
String? selectedInstallments = "";
String? tamaraPaymentStatus;
String? tamaraOrderID;
String? transID;
late MyInAppBrowser browser;
@override @override
void initState() { void initState() {
// widget.authUser = new AuthenticatedUser(); // widget.authUser = new AuthenticatedUser();
@ -213,13 +235,18 @@ class _BookConfirmState extends State<BookConfirm> {
elevation: 0, elevation: 0,
onPressed: () async { onPressed: () async {
bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false; bool isLiveCareSchedule = await this.sharedPref.getBool(IS_LIVECARE_APPOINTMENT) ?? false;
if (isLiveCareSchedule) {
insertLiveCareScheduledAppointment(context, widget.doctor); if (widget.isWalkinAppointment) {
getWalkinAppointmentPatientShare();
} else { } else {
checkPatientHasDermaPackage(widget.doctor, projectViewModel.user.patientID!); if (isLiveCareSchedule) {
insertLiveCareScheduledAppointment(context, widget.doctor);
} else {
checkPatientHasDermaPackage(widget.doctor, projectViewModel.user.patientID!);
}
} }
}, },
child: Text(TranslationBase.of(context).bookAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)), child: Text(widget.isWalkinAppointment ? TranslationBase.of(context).addToWaitingList : TranslationBase.of(context).bookAppo, style: TextStyle(fontSize: 16.0, letterSpacing: -0.48, color: Colors.white)),
), ),
), ),
), ),
@ -227,6 +254,405 @@ class _BookConfirmState extends State<BookConfirm> {
); );
} }
getWalkinAppointmentPatientShare() {
String errorMsg = "";
AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
GifLoaderDialogUtils.showMyDialog(context);
appo.doctorTitle = widget.doctor.doctorTitle;
appo.doctorNameObj = widget.doctor.name;
appo.appointmentDate = DateUtil.convertDateToString(DateTime.now());
appo.projectName = widget.doctor.projectName;
widget.service
.getPatientShareForWalkInAppointment(
widget.doctor.clinicID!,
widget.doctor.projectID!,
widget.doctor.doctorID!,
)
.then((res) {
widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]);
GifLoaderDialogUtils.hideDialog(context);
isInsured = res["IsInsured"];
isEligible = res["IsEligible"];
isCash = res["IsCash"];
if (isCash) {
if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
openPaymentDialog(appo, widget.patientShareResponse!);
} else {
insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null);
}
} else {
if (isInsured && isEligible) {
if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
openPaymentDialog(appo, widget.patientShareResponse!);
} else {
insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null);
}
} else {
if (isInsured && !isEligible) {
errorMsg = TranslationBase.of(context).invalidEligibility;
} else {
errorMsg = TranslationBase.of(context).invalidInsurance;
}
ConfirmDialog dialog = new ConfirmDialog(
isDissmissable: false,
context: context,
confirmMessage: errorMsg,
okText: TranslationBase.of(context).updateInsuranceText,
cancelText: TranslationBase.of(context).continueCash,
okFunction: () => {openUpdateInsurance()},
cancelFunction: () => {continueAsCashForWalkIn(widget.doctor.projectID!)});
dialog.showAlertDialog(context);
}
}
// widget.patientShareResponse = new PatientShareResponse.fromJson(res["OnlineCheckInAppointmentsWalkInModel"]);
// GifLoaderDialogUtils.hideDialog(context);
// if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
// openPaymentDialog(appo, widget.patientShareResponse!);
// } else {
// insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, null);
// }
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
openPaymentDialog(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) {
showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.5),
transitionBuilder: (context, a1, a2, widget) {
final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0;
return Transform(
transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0),
child: Opacity(
opacity: a1.value,
child: PaymentDialog(
appo: appo,
patientShareResponse: patientShareResponse,
isCashPatient: isCash,
onPaymentMethodSelected: () {},
),
),
);
},
transitionDuration: Duration(milliseconds: 500),
barrierDismissible: false,
barrierLabel: '',
context: context,
pageBuilder: (context, animation1, animation2) => SizedBox()).then((value) {
print(value);
if (value != null) {
navigateToPaymentMethod(context, value as PatientShareResponse);
// projectViewModel.analytics.todoList.to_do_list_confirm_payment_details(appo);
} else {
// projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo);
}
});
}
Future navigateToPaymentMethod(context, PatientShareResponse patientShareResponse) async {
AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
appo.projectID = widget.doctor.projectID;
appo.clinicID = widget.doctor.clinicID;
appo.clinicName = widget.doctor.clinicName;
appo.projectName = widget.doctor.projectName;
appo.appointmentNo = DateTime.now().millisecondsSinceEpoch;
appo.isLiveCareAppointment = false;
appo.doctorID = widget.doctor.doctorID;
appo.appointmentDate = DateUtil.convertDateToString(DateTime.now()); //widget.patientShareResponse.appointmentDate;
appo.serviceID = widget.patientShareResponse.serviceID;
Navigator.push(
context,
FadePage(
page: PaymentMethod(
onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) {
setState(() {});
},
patientShare: widget.patientShareResponse.patientShareWithTax)))
.then((value) {
selectedPaymentMethod = value[0];
if (value != null) {
if (selectedPaymentMethod == "ApplePay") {
if (projectViewModel.havePrivilege(103)) {
startApplePay(appo, patientShareResponse);
} else {
openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo);
}
} else {
openPayment(value, projectViewModel.user, double.parse(patientShareResponse.patientShareWithTax.toString()), patientShareResponse, appo);
}
projectViewModel.analytics.appointment.payment_method(appointment_type: 'Walk-In', clinic: widget.doctor.clinicName, payment_method: value[0], payment_type: 'appointment');
}
});
}
void startApplePay(AppoitmentAllHistoryResultList appo, PatientShareResponse patientShareResponse) async {
transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo);
print("TransactionID: $transID");
GifLoaderDialogUtils.showMyDialog(context);
LiveCareService service = new LiveCareService();
ApplePayInsertRequest applePayInsertRequest = new ApplePayInsertRequest();
PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel;
await context.read<PayfortViewModel>().getProjectDetailsForPayfort(projectId: appo.projectID, serviceId: ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum()).then((value) {
payfortProjectDetailsRespModel = value!;
});
applePayInsertRequest.clientRequestID = transID;
applePayInsertRequest.clinicID = appo.clinicID;
applePayInsertRequest.currency = projectViewModel.user.outSA == 1 ? "AED" : "SAR";
// applePayInsertRequest.customerEmail = projectViewModel.authenticatedUserObject.user.emailAddress;
applePayInsertRequest.customerEmail = "CustID_${projectViewModel.user.patientID}@HMG.com";
applePayInsertRequest.customerID = projectViewModel.user.patientID;
applePayInsertRequest.customerName = projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!;
applePayInsertRequest.deviceToken = await AppSharedPreferences().getString(PUSH_TOKEN);
applePayInsertRequest.voipToken = await AppSharedPreferences().getString(ONESIGNAL_APNS_TOKEN);
applePayInsertRequest.doctorID = appo.doctorID;
applePayInsertRequest.projectID = appo.projectID.toString();
applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString();
applePayInsertRequest.channelID = 3;
applePayInsertRequest.patientID = projectViewModel.user.patientID;
applePayInsertRequest.patientTypeID = projectViewModel.user.patientType;
applePayInsertRequest.patientOutSA = projectViewModel.user.outSA;
applePayInsertRequest.appointmentDate = appo.appointmentDate;
applePayInsertRequest.appointmentNo = appo.appointmentNo;
applePayInsertRequest.orderDescription = "Appointment Payment";
applePayInsertRequest.liveServiceID = "0";
applePayInsertRequest.latitude = "0.0";
applePayInsertRequest.longitude = "0.0";
applePayInsertRequest.amount = patientShareResponse.patientShareWithTax.toString();
applePayInsertRequest.isSchedule = appo.isLiveCareAppointment! ? "1" : "0";
applePayInsertRequest.language = projectViewModel.isArabic ? 'ar' : 'en';
applePayInsertRequest.languageID = projectViewModel.isArabic ? 1 : 2;
applePayInsertRequest.userName = projectViewModel.user.patientID;
applePayInsertRequest.responseContinueURL = "http://hmg.com/Documents/success.html";
applePayInsertRequest.backClickUrl = "http://hmg.com/Documents/success.html";
applePayInsertRequest.paymentOption = "ApplePay";
applePayInsertRequest.isMobSDK = true;
applePayInsertRequest.merchantReference = transID;
applePayInsertRequest.merchantIdentifier = payfortProjectDetailsRespModel!.merchantIdentifier!;
applePayInsertRequest.commandType = "PURCHASE";
applePayInsertRequest.signature = payfortProjectDetailsRespModel!.signature;
applePayInsertRequest.accessCode = payfortProjectDetailsRespModel!.accessCode;
applePayInsertRequest.shaRequestPhrase = payfortProjectDetailsRespModel!.shaRequest;
applePayInsertRequest.shaResponsePhrase = payfortProjectDetailsRespModel!.shaResponse;
applePayInsertRequest.returnURL = "";
service.applePayInsertRequest(applePayInsertRequest, context).then((res) async {
if (res["MessageStatus"] == 1) {
await context.read<PayfortViewModel>().initiateApplePayWithPayfort(
customerName: projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!,
// customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress,
customerEmail: "CustID_${projectViewModel.user.patientID}@HMG.com",
orderDescription: "Walk-In appointment payment",
orderAmount: double.parse(patientShareResponse.patientShareWithTax.toString()),
merchantReference: transID,
payfortProjectDetailsRespModel: payfortProjectDetailsRespModel,
currency: projectViewModel.user.outSA == 1 ? "AED" : "SAR",
onFailed: (failureResult) async {
log("failureResult: ${failureResult.toString()}");
AppToast.showErrorToast(message: failureResult.toString());
},
onSuccess: (successResult) async {
log("Payfort: ${successResult.responseMessage}");
await context.read<PayfortViewModel>().addPayfortApplePayResponse(projectViewModel.user.patientID!, result: successResult);
checkPaymentStatus(appo);
},
projectId: appo.projectID,
serviceTypeEnum: ServiceTypeEnum.appointmentPayment,
);
} else {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: "An error occurred while processing your request");
}
}).catchError((err) {
print(err);
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
});
}
openPayment(List<String?> paymentMethod, AuthenticatedUser authenticatedUser, num amount, PatientShareResponse patientShareResponse, AppoitmentAllHistoryResultList appo) async {
browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart, context: context);
selectedPaymentMethod = paymentMethod[0];
selectedInstallments = paymentMethod[1];
transID = Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo);
browser.openPaymentBrowser(
amount,
"Walk-In appointment payment",
transID!,
appo.projectID.toString(),
authenticatedUser.emailAddress!,
paymentMethod[0]!,
authenticatedUser.patientType,
authenticatedUser.firstName!,
authenticatedUser.patientID,
authenticatedUser,
browser,
widget.patientShareResponse.isLiveCareAppointment!,
"2",
widget.patientShareResponse.isLiveCareAppointment! ? widget.patientShareResponse.clinicID.toString() : "",
context,
widget.patientShareResponse.appointmentDate,
widget.patientShareResponse.appointmentNo,
widget.patientShareResponse.clinicID,
widget.patientShareResponse.doctorID,
paymentMethod[1]);
// }
}
onBrowserLoadStart(String url) {
if (selectedPaymentMethod == "TAMARA") {
if (Platform.isAndroid) {
Uri uri = new Uri.dataFromString(url);
tamaraPaymentStatus = uri.queryParameters['status'];
tamaraOrderID = uri.queryParameters['AuthorizePaymentId'];
} else {
Uri uri = new Uri.dataFromString(url);
tamaraPaymentStatus = uri.queryParameters['paymentStatus'];
tamaraOrderID = uri.queryParameters['orderId'];
}
}
MyInAppBrowser.successURLS.forEach((element) {
if (url.contains(element)) {
if (browser.isOpened()) browser.close();
MyInAppBrowser.isPaymentDone = true;
return;
}
});
MyInAppBrowser.errorURLS.forEach((element) {
if (url.contains(element)) {
if (browser.isOpened()) browser.close();
MyInAppBrowser.isPaymentDone = false;
return;
}
});
}
onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) {
try {
if (selectedPaymentMethod == "TAMARA") {
checkTamaraPaymentStatus(transID!, appo);
// if (tamaraPaymentStatus != null && tamaraPaymentStatus!.toLowerCase() == "approved") {
// updateTamaraRequestStatus("success", "14", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID!, num.parse(selectedInstallments!), appo);
// } else {
// updateTamaraRequestStatus(
// "Failed", "00", Utils.getAppointmentTransID(appo.projectID, appo.clinicID, appo.appointmentNo), tamaraOrderID! != null ? tamaraOrderID! : "", num.parse(selectedInstallments!), appo);
// }
} else {
checkPaymentStatus(appo);
}
} catch (err) {
print(err);
}
}
checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.getTamaraPaymentStatus(orderID).then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (res["status"].toString().toLowerCase() == "success") {
updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(selectedInstallments!), appo);
} else {
updateTamaraRequestStatus(
"Failed", "00", Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), tamaraOrderID != null ? tamaraOrderID! : "", int.parse(selectedInstallments!), appo);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, num selectedInstallments, AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(context);
try {
DoctorsListService service = new DoctorsListService();
service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (tamaraPaymentStatus!.toLowerCase() == "approved") {
insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, tamaraOrderID);
}
}).catchError((err) {
print(err);
AppToast.showErrorToast(message: err);
GifLoaderDialogUtils.hideDialog(context);
});
} catch (err) {
print(err);
}
}
addAdvancedNumberRequestTamara(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) {
DoctorsListService service = new DoctorsListService();
service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
markAppointmentForTamara(AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.markAppointmentForTamara(appo.projectID!, appo.appointmentNo.toString()).then((res) {
GifLoaderDialogUtils.hideDialog(context);
sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appo.appointmentNo), projectViewModel.waitingAppointmentProjectID);
}).catchError((err) {
print(err);
AppToast.showErrorToast(message: err);
GifLoaderDialogUtils.hideDialog(context);
});
}
checkPaymentStatus(AppoitmentAllHistoryResultList appo) {
String txn_ref;
num amount;
String payment_method;
final currency = projectViewModel.user!.outSA == 0 ? "sar" : 'aed';
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.checkPaymentStatus(transID!, false, context).then((res) {
String paymentInfo = res['Response_Message'];
if (paymentInfo == 'Success') {
txn_ref = res['Merchant_Reference'];
amount = res['Amount'];
payment_method = res['PaymentMethod'];
GifLoaderDialogUtils.hideDialog(context);
insertWalkInAppointment(context, widget.doctor, widget.initialSlotDuration, res);
projectViewModel.analytics.appointment.payment_success(
appointment_type: 'Walk-In', payment_method: payment_method, clinic: appo.clinicName, hospital: appo.projectName, txn_amount: "$amount", txn_currency: currency, txn_number: txn_ref);
} else {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: res['Response_Message']);
projectViewModel.analytics.appointment.payment_fail(
appointment_type: 'Walk-In',
payment_method: selectedPaymentMethod,
clinic: appo.clinicName,
hospital: appo.projectName,
txn_amount: widget.patientShareResponse.patientShareWithTax.toString(),
txn_currency: currency,
error_type: res['Response_Message']);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err.toString());
print(err);
});
}
Widget showInfo(String title, String des) { Widget showInfo(String title, String des) {
return Container( return Container(
child: Row( child: Row(
@ -266,7 +692,7 @@ class _BookConfirmState extends State<BookConfirm> {
if (isLiveCareSchedule != null && isLiveCareSchedule) { if (isLiveCareSchedule != null && isLiveCareSchedule) {
insertLiveCareScheduledAppointment(context, widget.doctor); insertLiveCareScheduledAppointment(context, widget.doctor);
} else { } else {
insertAppointment(widget.doctor, widget.initialSlotDuration, invoiceNumber: invoiceNumber, lineItemNo: lineItemNo); insertAppointment(context, widget.doctor, widget.initialSlotDuration);
} }
}); });
} else { } else {
@ -322,6 +748,111 @@ class _BookConfirmState extends State<BookConfirm> {
}); });
} }
void continueAsCashForWalkIn(int projectID) {
GifLoaderDialogUtils.showMyDialog(context);
widget.service.convertPatientToCash(projectID).then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (res["MessageStatus"] == 1) {
getWalkinAppointmentPatientShare();
} else {
AppToast.showErrorToast(message: res["ErrorEndUserMessage"]);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
insertWalkInAppointment(context, DoctorList docObject, int initialSlotDuration, paymentRes) async {
GifLoaderDialogUtils.showMyDialog(
context,
);
AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList();
appo.doctorID = docObject.doctorID;
appo.clinicID = docObject.clinicID;
appo.projectID = docObject.projectID;
widget.service
.insertWalkInAppointment(
docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, projectViewModel.isArabic ? 1 : 2, context)
.then((res) {
if (res['MessageStatus'] == 1) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess);
appo.appointmentNo = res["AppointmentNo"]; // Add appointment No to the appointment project
Future.delayed(Duration(milliseconds: 500), () {
if (selectedPaymentMethod == "TAMARA") {
markAppointmentForTamara(appo);
addAdvancedNumberRequestTamara("Tamara-Advance-0000", paymentRes, res["AppointmentNo"].toString(), appo);
} else {
if (widget.patientShareResponse.patientShareWithTax != 0 || widget.patientShareResponse.patientShareWithTax != 0.0) {
createAdvancePayment(paymentRes, appo);
} else {
sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(res["AppointmentNo"]), projectViewModel.waitingAppointmentProjectID);
}
}
});
} else {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
});
}
createAdvancePayment(res, AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(
context,
);
DoctorsListService service = new DoctorsListService();
String paymentReference = res['Fort_id'].toString();
service.createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], context).then((res) {
GifLoaderDialogUtils.hideDialog(context);
addAdvancedNumberRequest(
Utils.isVidaPlusProject(projectViewModel, appo.projectID!)
? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString()
: res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(),
paymentReference,
appo.appointmentNo.toString(),
appo);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
addAdvancedNumberRequest(String advanceNumber, String paymentReference, String appointmentID, AppoitmentAllHistoryResultList appo) {
GifLoaderDialogUtils.showMyDialog(
context,
);
DoctorsListService service = new DoctorsListService();
service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, context).then((res) {
GifLoaderDialogUtils.hideDialog(context);
sendNfcCheckInRequest(projectViewModel.waitingAppointmentNFCCode, 2, int.parse(appointmentID), projectViewModel.waitingAppointmentProjectID);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err);
print(err);
});
}
sendNfcCheckInRequest(String nfcId, int checkInBy, int appoNo, int projectID) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.sendCheckinNfcRequest(appoNo, nfcId, projectID, checkInBy, context as int).then((res) {
GifLoaderDialogUtils.hideDialog(context);
_showMyDialog(res["SuccessMsg"], this.context);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
print(err);
_showMyDialog(err, this.context);
});
}
checkPatientHasDermaPackage(DoctorList doctor, int patientID) { checkPatientHasDermaPackage(DoctorList doctor, int patientID) {
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
widget.service widget.service
@ -358,11 +889,11 @@ class _BookConfirmState extends State<BookConfirm> {
}); });
} }
insertAppointment(DoctorList docObject, int initialSlotDuration, {int? invoiceNumber, int? lineItemNo}) async { insertAppointment(context, DoctorList docObject, int initialSlotDuration) async {
final timeSlot = DocAvailableAppointments.selectedAppoDateTime; final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
String logs = await sharedPref.getString('selectedLogSlots'); String logs = await sharedPref.getString('selectedLogSlots');
List<dynamic> decodedLogs = json.decode(logs); List<dynamic> decodedLogs = json.decode(logs);
GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: true); GifLoaderDialogUtils.showMyDialog(context, barrierDismissible: false);
AppoitmentAllHistoryResultList appo; AppoitmentAllHistoryResultList appo;
widget.service widget.service
// .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, context, 'null', null, null, projectViewModel) // .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, widget.selectedTime, widget.selectedDate, initialSlotDuration, context, 'null', null, null, projectViewModel)
@ -613,4 +1144,32 @@ class _BookConfirmState extends State<BookConfirm> {
), ),
); );
} }
Future<void> _showMyDialog(String message, BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(message),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route<dynamic> r) => false);
},
),
],
);
},
);
}
} }

@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Clinics/ClinicListResponse.dart';
import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/DentalComplaints.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart';
import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart';
import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
@ -520,15 +521,9 @@ class _DoctorProfileState extends State<DoctorProfile> with TickerProviderStateM
// if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) { // if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17) {
// navigateToDentalComplaints(context); // navigateToDentalComplaints(context);
// } else { // } else {
if (DocAvailableAppointments.areSlotsAvailable) { if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) {
if (projectViewModel.isLogin) { if (projectViewModel.isLogin) {
if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) { canPayForWalkInAppointment();
navigateToDentalComplaints(context);
} else {
final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
navigateToBookConfirm(context);
projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor);
}
} else { } else {
ConfirmDialog dialog = new ConfirmDialog( ConfirmDialog dialog = new ConfirmDialog(
context: context, context: context,
@ -539,9 +534,30 @@ class _DoctorProfileState extends State<DoctorProfile> with TickerProviderStateM
cancelFunction: () => {}); cancelFunction: () => {});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
} else } else {
AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); if (DocAvailableAppointments.areSlotsAvailable) {
// } if (projectViewModel.isLogin) {
if (widget.isDoctorNameSearch && widget.doctor.clinicID == 17 && projectViewModel.user!.age! > 12) {
navigateToDentalComplaints(context);
} else {
final timeSlot = DocAvailableAppointments.selectedAppoDateTime;
navigateToBookConfirm(context);
projectViewModel.analytics.appointment.book_appointment_review(appointment_type: 'regular', dateTime: timeSlot!, doctor: widget.doctor);
}
} else {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
confirmMessage: TranslationBase.of(context).loginToUseService,
okText: TranslationBase.of(context).confirm,
cancelText: TranslationBase.of(context).cancel_nocaps,
okFunction: () => {navigateToLogin()},
cancelFunction: () => {});
dialog.showAlertDialog(context);
}
} else {
AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
}
}
} }
Future navigateToDentalComplaints(BuildContext context) async { Future navigateToDentalComplaints(BuildContext context) async {
@ -586,8 +602,33 @@ class _DoctorProfileState extends State<DoctorProfile> with TickerProviderStateM
selectedDate: DocAvailableAppointments.selectedDate!, selectedDate: DocAvailableAppointments.selectedDate!,
selectedTime: DocAvailableAppointments.selectedTime!, selectedTime: DocAvailableAppointments.selectedTime!,
initialSlotDuration: DocAvailableAppointments.initialSlotDuration!, initialSlotDuration: DocAvailableAppointments.initialSlotDuration!,
isWalkinAppointment: false,
), ),
), ),
); );
} }
Future navigateToWaitingAppointment(context) async {
projectViewModel.setWaitingAppointmentProjectID(widget.doctor.projectID!);
projectViewModel.setWaitingAppointmentDoctor(widget.doctor);
Navigator.push(
context,
FadePage(
page: WaitingAppointmentInfo(),
),
);
}
canPayForWalkInAppointment() {
DoctorsListService service = new DoctorsListService();
GifLoaderDialogUtils.showMyDialog(context);
service.canPayForWalkInAppointment(widget.doctor.clinicID!, widget.doctor.projectID!, widget.doctor.doctorID!).then((res) {
GifLoaderDialogUtils.hideDialog(context);
navigateToWaitingAppointment(context);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err, localContext: context);
print(err);
});
}
} }

@ -60,6 +60,8 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
var language; var language;
bool isLiveCareSchedule = false; bool isLiveCareSchedule = false;
bool isWaitingAppointmentAvailable = false;
// String selectedLogSlots =''; // String selectedLogSlots ='';
@override @override
@ -198,7 +200,7 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
_events.forEach((key, value) { _events.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(hours: 2)); final DateTime endTime = startTime.add(const Duration(hours: 2));
meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
}); });
return meetings; return meetings;
} }
@ -206,7 +208,9 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
openTimeSlotsPickerForDate(DateTime dateStart, List<TimeSlot> freeSlots) { openTimeSlotsPickerForDate(DateTime dateStart, List<TimeSlot> freeSlots) {
dayEvents.clear(); dayEvents.clear();
DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0); DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0);
if (isWaitingAppointmentAvailable && DateUtils.isSameDay(dateStart, DateTime.now())) {
dayEvents.add(TimeSlot(isoTime: TranslationBase.of(context).waitingAppointment, start: DateTime.now(), end: DateTime.now(), vidaDate: ""));
}
freeSlots.forEach((v) { freeSlots.forEach((v) {
if (v.start == dateStartObj) dayEvents.add(v); if (v.start == dateStartObj) dayEvents.add(v);
}); });
@ -349,20 +353,22 @@ class _DocAvailableAppointmentsState extends State<DocAvailableAppointments> wit
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
if (res['FreeTimeSlots'].length != 0) { if (res['FreeTimeSlots'].length != 0) {
isWaitingAppointmentAvailable = res['IsAllowToBookWaitingAppointment']; // true;
// isWaitingAppointmentAvailable = true; // true;
DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration']; DocAvailableAppointments.initialSlotDuration = res['InitialSlotDuration'];
DocAvailableAppointments.areAppointmentsAvailable = true; DocAvailableAppointments.areAppointmentsAvailable = true;
freeSlotsResponse = res['FreeTimeSlots']; freeSlotsResponse = res['FreeTimeSlots'];
_getJSONSlots().then((value) { _getJSONSlots().then((value) {
setState(() => { setState(() {
_events.clear(), _events.clear();
_events = value, _events = value;
if (widget.doctorSchedule != null) if (widget.doctorSchedule != null)
{ {
_onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date'])), _onDaySelected(DateUtil.convertStringToDate(widget.doctorSchedule['Date']));
_calendarController.selectedDate = DateUtil.convertStringToDate( _calendarController.selectedDate = DateUtil.convertStringToDate(
widget.doctorSchedule['Date'], widget.doctorSchedule['Date'],
) );
} };
}); });
}); });
} else { } else {
@ -464,11 +470,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { class Meeting {
Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -0,0 +1,113 @@
import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_verification.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class WaitingAppointmentInfo extends StatelessWidget {
const WaitingAppointmentInfo({super.key});
@override
Widget build(BuildContext context) {
return AppScaffold(
appBarTitle: TranslationBase.of(context).waitingAppointment,
isShowAppBar: true,
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
backgroundColor: CustomColors.appBackgroudGreyColor,
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: containerRadius(Colors.white, 10),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset(
"assets/images/new/waitingAppo.svg",
width: 52.0,
height: 52.0,
),
mHeight(11),
Text(
TranslationBase.of(context).whatWaitingAppointment,
maxLines: 1,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.44, height: 35 / 24),
),
mHeight(11),
Container(
width: MediaQuery.of(context).size.width * 0.8,
child: Text(
TranslationBase.of(context).waitingAppointmentText1,
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
),
),
mHeight(18),
Container(
width: MediaQuery.of(context).size.width * 0.8,
child: Text(
TranslationBase.of(context).waitingAppointmentText2,
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
),
),
mHeight(24),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
Icons.warning,
size: 20,
color: Color(0xffA78618),
),
mWidth(10),
Container(
width: MediaQuery.of(context).size.width * 0.7,
child: Text(
TranslationBase.of(context).waitingAppointmentText3,
style: TextStyle(
fontSize: 14, fontStyle: FontStyle.italic, fontWeight: FontWeight.w600, color: Color(0xffA78618), letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
),
),
],
),
],
),
),
),
],
),
),
),
bottomSheet: Container(
height: 80,
color: CustomColors.white,
padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0),
child: Container(
child: DefaultButton(
TranslationBase.of(context).continues,
() {
Navigator.push(
context,
FadePage(
page: WaitingAppointmentVerification(),
),
);
},
color: CustomColors.accentColor,
),
),
),
);
}
}

@ -0,0 +1,292 @@
import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/location_util.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../../../uitl/utils.dart';
class WaitingAppointmentVerification extends StatefulWidget {
const WaitingAppointmentVerification({super.key});
@override
State<WaitingAppointmentVerification> createState() => _WaitingAppointmentVerificationState();
}
class _WaitingAppointmentVerificationState extends State<WaitingAppointmentVerification> {
String selectedVerificationMethod = "QR";
late ProjectViewModel projectViewModel;
late LocationUtils locationUtils;
ProjectDetailListModel projectDetailListModel = ProjectDetailListModel();
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
return AppScaffold(
appBarTitle: TranslationBase.of(context).waitingAppointment,
isShowAppBar: true,
isShowDecPage: false,
showNewAppBar: true,
showNewAppBarTitle: true,
backgroundColor: CustomColors.appBackgroudGreyColor,
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
mHeight(11),
Text(
TranslationBase.of(context).waitingAppointmentVerificationMethod,
maxLines: 1,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24),
),
mHeight(12),
Container(
width: MediaQuery.of(context).size.width,
decoration: containerRadius(Colors.white, 10),
child: Padding(
padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: () {
setState(() {
selectedVerificationMethod = "QR";
});
},
child: Row(
children: [
Container(
width: 20,
height: 20,
decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "QR" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5),
),
mWidth(6),
Container(
height: 40.0,
width: 40.0,
padding: EdgeInsets.all(7.0),
child: SvgPicture.asset(
"assets/images/new/services/qr_code.svg",
),
),
Text(
TranslationBase.of(context).pharmaLiveCareScanQR,
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
),
],
),
),
Divider(),
InkWell(
onTap: () {
setState(() {
selectedVerificationMethod = "NFC";
});
},
child: Row(
children: [
Container(
width: 20,
height: 20,
decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "NFC" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5),
),
mWidth(6),
Container(
height: 40.0,
width: 40.0,
padding: EdgeInsets.all(7.0),
child: SvgPicture.asset(
"assets/images/new/services/contactless.svg",
),
),
Text(
TranslationBase.of(context).scanNFC,
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
),
],
),
),
Divider(),
InkWell(
onTap: () {
setState(() {
selectedVerificationMethod = "Location";
});
},
child: Row(
children: [
Container(
width: 20,
height: 20,
decoration: containerColorRadiusBorderWidth(selectedVerificationMethod == "Location" ? CustomColors.accentColor : Colors.transparent, 100, Colors.grey, 0.5),
),
mWidth(6),
Container(
height: 40.0,
width: 40.0,
padding: EdgeInsets.all(7.0),
child: SvgPicture.asset(
"assets/images/new/services/location.svg",
),
),
Text(
TranslationBase.of(context).checkInViaLocation,
style: TextStyle(fontSize: 14, color: CustomColors.textDarkColor, fontWeight: FontWeight.w600, letterSpacing: -1.04, height: 35 / 24, overflow: TextOverflow.clip),
),
],
),
),
mHeight(6),
],
),
),
),
mHeight(12),
Container(
width: MediaQuery.of(context).size.width,
decoration: containerRadius(Colors.white, 10),
child: Padding(
padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
mHeight(12),
Text(
TranslationBase.of(context).howToUseVerificationMethod,
maxLines: 1,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -1.04, height: 35 / 24),
),
mHeight(12),
Image.asset(
'assets/images/new/NFCCheckIn_QR_gps_HMG.png',
fit: BoxFit.fitWidth,
width: MediaQuery.of(context).size.width,
),
mHeight(12),
],
),
),
),
],
),
),
),
bottomSheet: Container(
height: 80,
color: CustomColors.white,
padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 25.0),
child: Container(
child: DefaultButton(
TranslationBase.of(context).continues,
() {
startVerification();
},
color: CustomColors.accentColor,
),
),
),
);
}
startVerification() {
switch (selectedVerificationMethod) {
case "QR":
startQRCodeScan();
break;
case "NFC":
startNFCScan();
break;
case "Location":
startLocationCheckIn();
break;
}
}
checkScannedNFCAndQRCode(String nfcId) {
GifLoaderDialogUtils.showMyDialog(context);
DoctorsListService service = new DoctorsListService();
service.checkScannedNFCAndQRCode(nfcId, projectViewModel.waitingAppointmentDoctor!.projectID!).then((res) {
GifLoaderDialogUtils.hideDialog(context);
projectViewModel.setWaitingAppointmentNFCCode(nfcId);
if (res["returnValue"] == 1) {
navigateToBookConfirm(context);
} else {
AppToast.showErrorToast(message: "Invalid verification point scanned.");
}
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
print(err);
});
}
Future navigateToBookConfirm(context) async {
final DateFormat formatter = DateFormat('yyyy-MM-dd');
Navigator.push(
context,
FadePage(
page: BookConfirm(
doctor: projectViewModel.waitingAppointmentDoctor!,
isLiveCareAppointment: false,
selectedDate: formatter.format(DateTime.now()),
selectedTime: TranslationBase.of(context).waitingAppointment,
initialSlotDuration: 15,
isWalkinAppointment: true,
),
),
);
}
startLocationCheckIn() async {
locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context);
locationUtils.getCurrentLocation(callBack: (value) {
projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, projectViewModel.waitingAppointmentProjectID);
double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000;
projectViewModel.setWaitingAppointmentNFCCode(projectDetailListModel.checkInQrCode!);
print(dist);
if (dist <= projectDetailListModel.geofenceRadius!) {
navigateToBookConfirm(context);
} else {
AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError);
}
});
}
startNFCScan() {
Future.delayed(const Duration(milliseconds: 500), () {
showNfcReader(context, onNcfScan: (String nfcId) {
Future.delayed(const Duration(milliseconds: 100), () {
checkScannedNFCAndQRCode(nfcId);
});
}, onCancel: () {
// Navigator.of(context).pop();
// locator<GAnalytics>().todoList.to_do_list_nfc_cancel(widget.appointment!);
});
});
}
startQRCodeScan() async {
String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent));
if (onlineCheckInQRCode != "") {
checkScannedNFCAndQRCode(onlineCheckInQRCode);
} else {}
}
}

@ -260,7 +260,7 @@ class _CovidTimeSlotsState extends State<CovidTimeSlots> with TickerProviderStat
_events.forEach((key, value) { _events.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20)); final DateTime endTime = startTime.add(const Duration(minutes: 20));
meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
}); });
return meetings; return meetings;
} }
@ -584,11 +584,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { class Meeting {
Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -272,7 +272,7 @@ class _InPatientPendingAdvancePaymentState extends State<InPatientPendingAdvance
if (isCopy) { if (isCopy) {
Share.share(paymentLink); Share.share(paymentLink);
} else { } else {
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(paymentLink)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(paymentLink))), options: _InAppBrowserOptions);
} }
} else { } else {
AppToast.showErrorToast(message: res["endUserMessage"]); AppToast.showErrorToast(message: res["endUserMessage"]);

@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.
import 'package:diplomaticquarterapp/models/header_model.dart'; import 'package:diplomaticquarterapp/models/header_model.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/BookConfirm.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/components/DocAvailableAppointments.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/DocAvailableAppointments.dart';
import 'package:diplomaticquarterapp/pages/BookAppointment/waiting_appointment/waiting_appointment_info.dart';
import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/SchedulePage.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
@ -299,23 +300,68 @@ class _AppointmentDetailsState extends State<AppointmentDetails> with SingleTick
} }
void goToBookConfirm() { void goToBookConfirm() {
if (DocAvailableAppointments.areSlotsAvailable) if (DocAvailableAppointments.selectedTime == TranslationBase.of(context).waitingAppointment) {
navigateToBookConfirm(context); canPayForWalkInAppointment();
else } else {
AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot); if (DocAvailableAppointments.areSlotsAvailable)
navigateToBookConfirm(context);
else
AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
}
}
canPayForWalkInAppointment() {
DoctorsListService service = new DoctorsListService();
GifLoaderDialogUtils.showMyDialog(context);
service.canPayForWalkInAppointment(widget.appo.clinicID!, widget.appo.projectID!, widget.appo.doctorID!).then((res) {
GifLoaderDialogUtils.hideDialog(context);
navigateToWaitingAppointment(context);
}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err, localContext: context);
print(err);
});
}
Future navigateToWaitingAppointment(context) async {
DoctorList doctor = new DoctorList();
doctor.name = widget.appo.doctorNameObj;
doctor.clinicID = widget.appo.clinicID;
doctor.projectID = widget.appo.projectID;
doctor.doctorID = widget.appo.doctorID;
doctor.clinicName = widget.appo.clinicName;
doctor.projectName = widget.appo.projectName;
doctor.doctorTitle = widget.appo.doctorTitle;
doctor.doctorImageURL = widget.appo.doctorImageURL;
doctor.speciality = widget.appo.doctorSpeciality;
doctor.nationalityFlagURL = "";
doctor.doctorRate = widget.appo.doctorRate;
doctor.noOfPatientsRate = widget.appo.noOfPatientsRate;
projectViewModel?.setWaitingAppointmentProjectID(widget.appo.projectID!);
projectViewModel?.setWaitingAppointmentDoctor(doctor);
Navigator.push(
context,
FadePage(
page: WaitingAppointmentInfo(),
),
);
} }
Future navigateToBookConfirm(context) async { Future navigateToBookConfirm(context) async {
Navigator.push( Navigator.push(
context, context,
FadePage( FadePage(
page: BookConfirm( page: BookConfirm(
doctor: getDoctorObject(), doctor: getDoctorObject(),
isLiveCareAppointment: widget.appo.isLiveCareAppointment!, isLiveCareAppointment: widget.appo.isLiveCareAppointment!,
selectedDate: DocAvailableAppointments.selectedDate!, selectedDate: DocAvailableAppointments.selectedDate!,
selectedTime: DocAvailableAppointments.selectedTime!, selectedTime: DocAvailableAppointments.selectedTime!,
initialSlotDuration: 0, initialSlotDuration: 0,
))); isWalkinAppointment: false,
),
),
);
} }
void getDoctorRatingsDetails() { void getDoctorRatingsDetails() {

@ -39,6 +39,7 @@ class BookedButtons {
"icon": "hosp_location.svg", "icon": "hosp_location.svg",
"caller": "navigateToProject", "caller": "navigateToProject",
}, },
{"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"} {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"},
// {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"}
]; ];
} }

@ -19,6 +19,7 @@ class ConfirmedButtons {
// "icon": "assets/images/new-design/generate_visit_ticket.png", // "icon": "assets/images/new-design/generate_visit_ticket.png",
// "caller": "visitTicket" // "caller": "visitTicket"
// }, // },
{"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"} {"title": TranslationBase.of(AppGlobal.context).online, "subtitle": TranslationBase.of(AppGlobal.context).payment, "icon": "online_payment.svg", "caller": "goToTodoList"},
// {"title": TranslationBase.of(AppGlobal.context).clinic, "subtitle": TranslationBase.of(AppGlobal.context).locationa, "icon": "hosp_location.svg", "caller": "goToNavigation"}
]; ];
} }

@ -27,9 +27,11 @@ import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_it
import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart'; import 'package:diplomaticquarterapp/pages/medical/radiology/radiology_details_page.dart';
import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart';
@ -40,6 +42,7 @@ import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:huawei_map/huawei_map.dart' as hmsMap; import 'package:huawei_map/huawei_map.dart' as hmsMap;
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:map_launcher/map_launcher.dart'; import 'package:map_launcher/map_launcher.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -178,6 +181,31 @@ class _AppointmentActionsState extends State<AppointmentActions> {
navigateToInsertComplaint(); navigateToInsertComplaint();
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint'); locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'raise complaint');
break; break;
case "goToNavigation":
initPenguinSDK();
locator<GAnalytics>().appointment.appointment_detail_action(appointment: widget.appo, action: 'navigate to clinic');
break;
}
}
initPenguinSDK() async {
NavigationClinicDetails data = NavigationClinicDetails();
// data.clinicId = widget.appo.clinicID.toString();
data.clinicId = "49";
data.patientId = widget.appo.patientID.toString();
data.projectId = widget.appo.projectID.toString();
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", widget.projectViewModel!.isArabic ? "ar" : "en", widget.projectViewModel!.authenticatedUserObject.user.patientID.toString(), details: data);
});
} }
} }

@ -253,7 +253,7 @@ class _CovidTimeSlotsState extends State<ObGyneTimeSlots> with TickerProviderSta
_events!.forEach((key, value) { _events!.forEach((key, value) {
final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0); final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
final DateTime endTime = startTime.add(const Duration(minutes: 20)); final DateTime endTime = startTime.add(const Duration(minutes: 20));
meetings.add(Meeting("", startTime, endTime, CustomColors.green, false)); meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
}); });
return meetings; return meetings;
} }
@ -534,11 +534,12 @@ class MeetingDataSource extends CalendarDataSource {
} }
class Meeting { class Meeting {
Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);
String eventName; String eventName;
DateTime from; DateTime from;
DateTime to; DateTime to;
Color background; Color background;
bool isAllDay; bool isAllDay;
String notes;
} }

@ -29,10 +29,12 @@ import 'package:diplomaticquarterapp/services/livecare_services/livecare_provide
import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart'; import 'package:diplomaticquarterapp/services/payfort_services/payfort_project_details_resp_model.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
@ -50,6 +52,7 @@ import 'package:flutter_countdown_timer/current_remaining_time.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ToDo extends StatefulWidget { class ToDo extends StatefulWidget {
@ -354,23 +357,56 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16), style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 25 / 16),
), ),
), ),
InkWell( Row(
onTap: () { mainAxisAlignment: MainAxisAlignment.spaceBetween,
navigateToAppointmentDetails(context, appoList[index]); children: [
}, InkWell(
child: Padding( onTap: () {
padding: const EdgeInsets.only(top: 0.0), navigateToAppointmentDetails(context, appoList[index]);
child: Text( },
TranslationBase.of(context).moreDetails, child: Padding(
style: TextStyle( padding: const EdgeInsets.only(top: 0.0),
fontSize: 10, child: Text(
fontWeight: FontWeight.w600, TranslationBase.of(context).moreDetails,
color: CustomColors.accentColor, style: TextStyle(
letterSpacing: -0.48, fontSize: 10,
height: 25 / 16, fontWeight: FontWeight.w600,
decoration: TextDecoration.underline), color: CustomColors.accentColor,
letterSpacing: -0.48,
height: 25 / 16,
decoration: TextDecoration.underline),
),
),
), ),
), if (projectViewModel.isIndoorNavigationEnabled)
InkWell(
onTap: () {
NavigationClinicDetails data = NavigationClinicDetails();
// data.clinicId = appoList[index].clinicID.toString();
data.clinicId = "46";
data.patientId = appoList[index].patientID.toString();
data.projectId = appoList[index].projectID.toString();
initPenguinSDK(data);
},
child: Column(
children: [
SvgPicture.asset(
"assets/images/new/Indoor_nav_appo.svg",
),
Text(
TranslationBase.of(context).clinicLocation,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
color: CustomColors.accentColor,
letterSpacing: -0.48,
height: 25 / 16,
decoration: TextDecoration.underline),
),
],
),
),
],
), ),
], ],
), ),
@ -530,6 +566,21 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
); );
} }
initPenguinSDK(NavigationClinicDetails data) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", projectViewModel.isArabic ? "ar" : "en", projectViewModel.authenticatedUserObject.user.patientID.toString(), details: data);
});
}
}
String getNextActionImage(nextAction) { String getNextActionImage(nextAction) {
switch (nextAction) { switch (nextAction) {
case 0: case 0:
@ -1115,7 +1166,6 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo); projectViewModel.analytics.todoList.to_do_list_cancel_payment_details(appo);
} }
}); });
projectViewModel.analytics.todoList.to_do_list_pay_now(appo); projectViewModel.analytics.todoList.to_do_list_pay_now(appo);
} }
@ -1465,7 +1515,7 @@ class _ToDoState extends State<ToDo> with SingleTickerProviderStateMixin {
}).catchError((err) { }).catchError((err) {
print(err); print(err);
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
AppToast.showErrorToast(message: err); AppToast.showErrorToast(message: err.toString());
}); });
} }

@ -167,7 +167,7 @@ class _InsuranceUpdateState extends State<InsuranceUpdate> with SingleTickerProv
Container( Container(
margin: EdgeInsets.only(top: 6.5, left: 2.0), margin: EdgeInsets.only(top: 6.5, left: 2.0),
child: Text( child: Text(
model.insuranceUpdate[index].statusDescription!, model.insuranceUpdate[index].statusDescription ?? "",
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,

@ -52,7 +52,11 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
hmgServices.add(HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin)); hmgServices.add(HmgServices(0, TranslationBase.of(context).book, TranslationBase.of(context).appointmentLabel, "assets/images/new/book appointment.svg", isLogin));
hmgServices.add(HmgServices(1, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin)); hmgServices.add(HmgServices(1, TranslationBase.of(context).liveCare, TranslationBase.of(context).onlineConsulting, "assets/images/new/Live_Care.svg", isLogin));
hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin));
projectViewModel.isIndoorNavigationEnabled
? hmgServices.add(HmgServices(2, "Hospital", "Navigation", "assets/images/new/indoor_nav_home.svg", isLogin))
: hmgServices.add(HmgServices(2, TranslationBase.of(context).emergencyTitle, TranslationBase.of(context).emergencySubtitle, "assets/images/new/emergency.svg", isLogin));
hmgServices.add(HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin)); hmgServices.add(HmgServices(3, TranslationBase.of(context).hhcHome, TranslationBase.of(context).healthCare, "assets/images/new/HHC.svg", isLogin));
hmgServices.add(HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin)); hmgServices.add(HmgServices(4, TranslationBase.of(context).checkup, TranslationBase.of(context).comprehensive, "assets/images/new/comprehensive_checkup.svg", isLogin));
hmgServices.add(HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin)); hmgServices.add(HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", isLogin));
@ -296,15 +300,16 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
child: ServicesView( child: ServicesView(
new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false), new HmgServices(23, TranslationBase.of(context).InPatient, TranslationBase.of(context).inPatientServices, "assets/images/new/InPatient.svg", false),
23, 23,
true)), true,
projectViewModel)),
), ),
), ),
Expanded( Expanded(
flex: 4, flex: 4,
child: AspectRatio( child: AspectRatio(
aspectRatio: 1.0, aspectRatio: 1.0,
child: ServicesView( child: ServicesView(new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2,
new HmgServices(5, TranslationBase.of(context).online, TranslationBase.of(context).payment, "assets/images/new/paymentMethods.png", false), 2, true)), true, projectViewModel)),
), ),
], ],
), ),
@ -322,7 +327,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
itemCount: hmgServices.length, itemCount: hmgServices.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, true); return ServicesView(hmgServices[index], index, true, projectViewModel);
}, },
), ),
), ),
@ -341,7 +346,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
itemCount: hmgServices.length, itemCount: hmgServices.length,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ServicesView(hmgServices[index], index, true); return ServicesView(hmgServices[index], index, true, projectViewModel, isLocked: hmgServices[index].action == 2 ? !projectViewModel.havePrivilege(107) : false);
}, },
), ),
), ),
@ -489,8 +494,7 @@ class _HomePageFragment2State extends State<HomePageFragment2> {
flex: 1, flex: 1,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
if (projectViewModel.havePrivilege(100)) if (projectViewModel.havePrivilege(100)) widget.onPharmacyClick!();
widget.onPharmacyClick!();
}, },
child: Stack(children: [ child: Stack(children: [
Container( Container(

@ -22,7 +22,8 @@ import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doct
import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart'; import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart' as family; import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart'
as family;
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart'; import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart';
@ -43,7 +44,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart'; // import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart';
@ -664,7 +665,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString();
model.setState(model.count, 0, true, notificationCount); model.setState(model.count, 0, true, notificationCount);
sharedPref.setString(NOTIFICATION_COUNT, notificationCount); sharedPref.setString(NOTIFICATION_COUNT, notificationCount);
FlutterAppIconBadge.updateBadge(int.parse(notificationCount)); // FlutterAppIconBadge.updateBadge(int.parse(notificationCount));
} }
}); });
// if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) { // if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) {

@ -4,7 +4,9 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/hmg_services.dart'; import 'package:diplomaticquarterapp/models/hmg_services.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart';
@ -31,14 +33,20 @@ import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart
import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/covid_consent_dialog.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/location_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../locator.dart'; import '../../../locator.dart';
@ -52,8 +60,10 @@ class ServicesView extends StatelessWidget {
PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>(); PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>();
late LocationUtils locationUtils; late LocationUtils locationUtils;
bool isHomePage; bool isHomePage;
late ProjectViewModel projectViewModel;
bool isLocked;
ServicesView(this.hmgServices, this.index, this.isHomePage); ServicesView(this.hmgServices, this.index, this.isHomePage, this.projectViewModel, {this.isLocked = false});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -159,12 +169,57 @@ class ServicesView extends StatelessWidget {
], ],
), ),
), ),
isLocked
? Container(
width: double.infinity,
height: double.infinity,
decoration: containerRadiusWithGradientServices(20, lightColor: Colors.grey.withOpacity(0.6), darkColor: Colors.grey.withOpacity(0.6)),
child: Icon(
Icons.lock_outline,
size: 40,
),
)
: Container()
], ],
), ),
), ),
); );
} }
openNavigationProjectSelection(BuildContext context) {
int _selectedHospitalIndex = 0;
List<HospitalsModel> projectsListLocal = [];
Utils.navigationProjectsList.forEach((v) {
projectsListLocal.add(new HospitalsModel.fromJson(v));
});
showDialog(
context: context,
builder: (cxt) => LocationSelectionDialog(
data: projectsListLocal,
selectedIndex: _selectedHospitalIndex,
onValueSelected: (index) {
_selectedHospitalIndex = index;
initPenguinSDK(projectsListLocal[index].iD);
},
),
);
}
initPenguinSDK(int projectID) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", projectViewModel.isArabic ? "ar" : "en", "1231755");
});
} //
}
handleHomePageServices(HmgServices hmgServices, BuildContext context) { handleHomePageServices(HmgServices hmgServices, BuildContext context) {
if (hmgServices.action == 0) { if (hmgServices.action == 0) {
Navigator.push(context, FadePage(page: Search())); Navigator.push(context, FadePage(page: Search()));
@ -172,8 +227,13 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 1) { } else if (hmgServices.action == 1) {
openLiveCare(context); openLiveCare(context);
} else if (hmgServices.action == 2) { } else if (hmgServices.action == 2) {
Navigator.push(context, FadePage(page: ErOptions(isAppbar: true))); // initPenguinSDK();
locator<GAnalytics>().hmgServices.logServiceName('emergency service'); if (projectViewModel.isIndoorNavigationEnabled) {
if (!isLocked) openNavigationProjectSelection(context);
} else {
Navigator.push(context, FadePage(page: ErOptions(isAppbar: true)));
locator<GAnalytics>().hmgServices.logServiceName('emergency service');
}
} else if (hmgServices.action == 3) { } else if (hmgServices.action == 3) {
Navigator.push(context, FadePage(page: HomeHealthCarePage())); Navigator.push(context, FadePage(page: HomeHealthCarePage()));
locator<GAnalytics>().hmgServices.logServiceName('home health care'); locator<GAnalytics>().hmgServices.logServiceName('home health care');
@ -266,10 +326,8 @@ class ServicesView extends StatelessWidget {
} else if (hmgServices.action == 21) { } else if (hmgServices.action == 21) {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (BuildContext context) => MyWebView( builder: (BuildContext context) => MyWebView(title: "HMG News", selectedUrl: "https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live",
title: "HMG News", ),
selectedUrl:"https://twitter.com/hmg" //"https://twitter.com/hashtag/مجموعة_د_سليمان_الحبيب_الطبية?src=hashtag_click&f=live",
),
), ),
); );
locator<GAnalytics>().hmgServices.logServiceName('latest news'); locator<GAnalytics>().hmgServices.logServiceName('latest news');

@ -14,7 +14,7 @@ class VideoCallWebPage extends StatelessWidget{
final String receiverId; final String receiverId;
final String callerId; final String callerId;
VideoCallWebPage({required this.receiverId, required this.callerId}){ VideoCallWebPage({required this.receiverId, required this.callerId}){
request = URLRequest(url: Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId")); request = URLRequest(url: WebUri.uri(Uri.parse("https://vcallapi.hmg.com/Mobileindex.html?username=$receiverId&doctorid=$callerId")));
} }
InAppWebViewGroupOptions options = InAppWebViewGroupOptions( InAppWebViewGroupOptions options = InAppWebViewGroupOptions(

@ -373,15 +373,17 @@ class _clinic_listState extends State<ClinicList> {
String pharmaLiveCareQRCodeValue = widget.pharmacyLiveCareQRCode; String pharmaLiveCareQRCodeValue = widget.pharmacyLiveCareQRCode;
Navigator.push( Navigator.push(
context, context,
FadePage( FadePage(
page: PaymentMethod( page: PaymentMethod(
onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) { onSelectedMethod: (String metohd, [String? selectedInstallmentPlan]) {
setState(() {}); setState(() {});
}, },
patientShare: num.parse(getERAppointmentFeesList.total!), patientShare: num.parse(getERAppointmentFeesList.total!),
isFromAdvancePayment: widget.isPharmacyLiveCare, isFromAdvancePayment: widget.isPharmacyLiveCare,
))).then((value) { ),
),
).then((value) {
if (value != null) { if (value != null) {
selectedPaymentMethod = value[0]; selectedPaymentMethod = value[0];
print(value); print(value);

@ -393,7 +393,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
var availableBiometrics; var availableBiometrics;
try { try {
availableBiometrics = await auth.getAvailableBiometrics(); availableBiometrics = await auth.getAvailableBiometrics();
print(availableBiometrics); // print(availableBiometrics);
} on PlatformException catch (e) { } on PlatformException catch (e) {
AppToast.showErrorToast(message: e.message!); AppToast.showErrorToast(message: e.message!);
print(e); print(e);
@ -1125,7 +1125,6 @@ class _ConfirmLogin extends State<ConfirmLogin> {
} }
bool checkIfBiometricAvailable(BiometricType biometricType) { bool checkIfBiometricAvailable(BiometricType biometricType) {
print(biometricType);
bool isAvailable = false; bool isAvailable = false;
if (_availableBiometrics != null) { if (_availableBiometrics != null) {
for (var i = 0; i < _availableBiometrics.length; i++) { for (var i = 0; i < _availableBiometrics.length; i++) {

@ -455,10 +455,10 @@ class _RegisterInfo extends State<RegisterInfo> {
this this
.authService .authService
.registerUser(request) .registerUser(request)
.then((result) => { .then((result) async => {
GifLoaderDialogUtils.hideDialog(context),
if (result is String) if (result is String)
{ {
GifLoaderDialogUtils.hideDialog(context),
new ConfirmDialog( new ConfirmDialog(
context: context, context: context,
confirmMessage: result, confirmMessage: result,
@ -480,14 +480,14 @@ class _RegisterInfo extends State<RegisterInfo> {
sharedPref.remove(FAMILY_FILE), sharedPref.remove(FAMILY_FILE),
result.list.isFamily = false, result.list.isFamily = false,
sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), await sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""),
authenticatedUserObject.user = result.list, authenticatedUserObject.user = result.list,
projectViewModel.setPrivilege(privilegeList: res), projectViewModel.setPrivilege(privilegeList: res),
sharedPref.setObject(MAIN_USER, result.list), await sharedPref.setObject(MAIN_USER, result.list),
sharedPref.setObject(USER_PROFILE, result.list), await sharedPref.setObject(USER_PROFILE, result.list),
sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), await sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID),
sharedPref.setString(TOKEN, result.authenticationTokenID), await sharedPref.setString(TOKEN, result.authenticationTokenID),
AppToast.showSuccessToast(message: TranslationBase.of(context).successRegister), AppToast.showSuccessToast(message: TranslationBase.of(context).successRegister),
checkIfUserAgreedBefore(result), checkIfUserAgreedBefore(result),
projectViewModel.analytics.loginRegistration.registration_confirmation() projectViewModel.analytics.loginRegistration.registration_confirmation()
@ -695,6 +695,7 @@ class _RegisterInfo extends State<RegisterInfo> {
insertIMEI() async { insertIMEI() async {
var selectedOption = await sharedPref.getInt(LAST_LOGIN); var selectedOption = await sharedPref.getInt(LAST_LOGIN);
authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) { authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context);
print(err); print(err);
}); });
} }
@ -705,45 +706,70 @@ class _RegisterInfo extends State<RegisterInfo> {
projectViewModel.isLogin = true; projectViewModel.isLogin = true;
projectViewModel.user = authenticatedUserObject.user; projectViewModel.user = authenticatedUserObject.user;
await authenticatedUserObject.getUser(getUser: true); await authenticatedUserObject.getUser(getUser: true);
int languageID = Provider.of<ProjectViewModel>(context, listen: false).isArabic ? 1 : 2; getToDoCount();
appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) { GifLoaderDialogUtils.hideDialog(AppGlobal.context);
getToDoCount(); ConfirmDialog dialog = new ConfirmDialog(
GifLoaderDialogUtils.hideDialog(AppGlobal.context); context: context,
if (appointmentRateViewModel.isHaveAppointmentNotRate) { confirmMessage: TranslationBase.of(context).validInsurance,
Navigator.pushAndRemoveUntil( okText: TranslationBase.of(context).yes,
cancelText: TranslationBase.of(context).no,
okFunction: () {
ConfirmDialog.closeAlertDialog(context);
Navigator.pushAndRemoveUntil(
context, context,
FadePage( MaterialPageRoute(builder: (context) => LandingPage()),
page: RateAppointmentDoctor(isFromRegistration: true),
),
(r) => false);
} else {
ConfirmDialog dialog = new ConfirmDialog(
context: context,
confirmMessage: TranslationBase.of(context).validInsurance,
okText: TranslationBase.of(context).yes,
cancelText: TranslationBase.of(context).no,
okFunction: () {
ConfirmDialog.closeAlertDialog(context);
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LandingPage()),
(Route<dynamic> route) => false, (Route<dynamic> route) => false,
); );
Navigator.push(context, FadePage(page: InsuranceUpdate())); Navigator.push(context, FadePage(page: InsuranceUpdate()));
}, },
cancelFunction: () { cancelFunction: () {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
context, context,
MaterialPageRoute(builder: (context) => LandingPage()), MaterialPageRoute(builder: (context) => LandingPage()),
(Route<dynamic> route) => false, (Route<dynamic> route) => false,
); );
}); });
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
}
}).catchError((err) { // int languageID = Provider.of<ProjectViewModel>(context, listen: false).isArabic ? 1 : 2;
print(err); // appointmentRateViewModel.getIsLastAppointmentRatedList(languageID).then((value) {
//GifLoaderDialogUtils.hideDialog(context); // getToDoCount();
}); // GifLoaderDialogUtils.hideDialog(AppGlobal.context);
// if (appointmentRateViewModel.isHaveAppointmentNotRate) {
// Navigator.pushAndRemoveUntil(
// context,
// FadePage(
// page: RateAppointmentDoctor(isFromRegistration: true),
// ),
// (r) => false);
// } else {
// ConfirmDialog dialog = new ConfirmDialog(
// context: context,
// confirmMessage: TranslationBase.of(context).validInsurance,
// okText: TranslationBase.of(context).yes,
// cancelText: TranslationBase.of(context).no,
// okFunction: () {
// ConfirmDialog.closeAlertDialog(context);
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(builder: (context) => LandingPage()),
// (Route<dynamic> route) => false,
// );
// Navigator.push(context, FadePage(page: InsuranceUpdate()));
// },
// cancelFunction: () {
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(builder: (context) => LandingPage()),
// (Route<dynamic> route) => false,
// );
// });
// dialog.showAlertDialog(context);
// }
// }).catchError((err) {
// print(err);
// //GifLoaderDialogUtils.hideDialog(context);
// });
// SMSOTP.showLoadingDialog(context, false), // SMSOTP.showLoadingDialog(context, false),
} }

@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/analytics/flows/login_registration.dart';
import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; import 'package:diplomaticquarterapp/analytics/google-analytics.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart';
import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart';
@ -25,6 +26,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart'; import 'package:flutter_datetime_picker_plus/flutter_datetime_picker_plus.dart';
import 'package:intl/intl.dart' as intl; import 'package:intl/intl.dart' as intl;
import 'package:provider/provider.dart';
class Register extends StatefulWidget { class Register extends StatefulWidget {
final Function? changePageViewIndex; final Function? changePageViewIndex;
@ -297,8 +299,9 @@ class _Register extends State<Register> {
} }
checkPatientForRegisteration(request) { checkPatientForRegisteration(request) {
int languageID = Provider.of<ProjectViewModel>(context, listen: false).isArabic ? 1 : 2;
GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context);
this.authService.checkPatientForRegisteration(request).then((response) => {checkUserStatus(response, request)}).catchError((err) { this.authService.checkPatientForRegisteration(request, languageID).then((response) => {checkUserStatus(response, request)}).catchError((err) {
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.hideDialog(context);
ConfirmDialog dialog = new ConfirmDialog( ConfirmDialog dialog = new ConfirmDialog(
context: context, context: context,

@ -34,7 +34,7 @@ class _syncHealthDataButtonState extends State<syncHealthDataButton> {
int MedCategoryID = 0; int MedCategoryID = 0;
HealthFactory health = HealthFactory(); // HealthFactory health = HealthFactory();
List<HealthDataType> types = [HealthDataType.STEPS, HealthDataType.HEART_RATE, Platform.isAndroid ? HealthDataType.DISTANCE_DELTA : HealthDataType.DISTANCE_WALKING_RUNNING]; List<HealthDataType> types = [HealthDataType.STEPS, HealthDataType.HEART_RATE, Platform.isAndroid ? HealthDataType.DISTANCE_DELTA : HealthDataType.DISTANCE_WALKING_RUNNING];
@override @override
@ -48,29 +48,29 @@ class _syncHealthDataButtonState extends State<syncHealthDataButton> {
} }
checkPermissions() async { checkPermissions() async {
if (Platform.isAndroid) { // if (Platform.isAndroid) {
if (await PermissionService.isHealthDataPermissionEnabled()) { // if (await PermissionService.isHealthDataPermissionEnabled()) {
await health.requestAuthorization(types).then((value) { // await health.requestAuthorization(types).then((value) {
if (value) { // if (value) {
readAll(); // readAll();
} // }
}); // });
} else { // } else {
Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async { // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).physicalActivityPermission, () async {
await health.requestAuthorization(types).then((value) { // await health.requestAuthorization(types).then((value) {
if (value) { // if (value) {
readAll(); // readAll();
} // }
}); // });
}); // });
} // }
} else { // } else {
await health.requestAuthorization(types).then((value) { // await health.requestAuthorization(types).then((value) {
if (value) { // if (value) {
readAll(); // readAll();
} // }
}); // });
} // }
} }
void readAll() async { void readAll() async {
@ -83,13 +83,13 @@ class _syncHealthDataButtonState extends State<syncHealthDataButton> {
DateTime startDate = DateTime.now().subtract(new Duration(days: 30)); DateTime startDate = DateTime.now().subtract(new Duration(days: 30));
try { try {
List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types); // List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(startDate, DateTime.now(), types);
_healthDataList.addAll(healthData); // _healthDataList.addAll(healthData);
} catch (e) { } catch (e) {
print("Caught exception in getHealthDataFromTypes: $e"); print("Caught exception in getHealthDataFromTypes: $e");
} }
_healthDataList = HealthFactory.removeDuplicates(_healthDataList); // _healthDataList = HealthFactory.removeDuplicates(_healthDataList);
_healthDataList.forEach((x) { _healthDataList.forEach((x) {
if (x.type == HealthDataType.STEPS) { if (x.type == HealthDataType.STEPS) {

@ -334,6 +334,58 @@ class DoctorsListService extends BaseService {
return Future.value(localRes); return Future.value(localRes);
} }
Future<Map> insertWalkInAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context) async {
Map<String, dynamic> request;
if (await this.sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE));
authUser = data;
}
Request req = appGlobal.getPublicRequest();
request = {
"IsForLiveCare": false,
"ProjectID": projectID,
"ClinicID": clinicID,
"DoctorID": docID,
"StartTime": selectedTime,
"SelectedTime": selectedTime,
"EndTime": selectedTime,
"InitialSlotDuration": initialSlotDuration,
"StrAppointmentDate": selectedDate,
"IsVirtual": false,
"DeviceType": Platform.isIOS ? 'iOS' : 'Android',
"BookedBy": 102,
"VisitType": 1,
"VisitFor": 1,
"GenderID": authUser.gender,
"Age": authUser.age != null ? authUser.age : 0,
"VersionID": req.VersionID,
"Channel": req.Channel,
"IPAdress": req.IPAdress,
"generalid": req.generalid,
"PatientOutSA": authUser.outSA,
"SessionID": "YckwoXhUmWBsnHKEKig",
"isDentalAllowedBackend": false,
"DeviceTypeID": req.DeviceTypeID,
"PatientID": authUser.patientID,
"PatientTypeID": authUser.patientType,
"PatientType": authUser.patientType
};
dynamic localRes;
try {
await baseAppClient.post(INSERT_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
} catch (e) {
return Future.error(e);
}
}
Future<Map> insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context, Future<Map> insertAppointment(int docID, int clinicID, int projectID, String selectedTime, String selectedDate, int initialSlotDuration, int languageID, BuildContext context,
[String? procedureID, num? testTypeEnum, num? testProcedureEnum, ProjectViewModel? projectViewModel, int? invoiceNumber, int? lineItemNo]) async { [String? procedureID, num? testTypeEnum, num? testProcedureEnum, ProjectViewModel? projectViewModel, int? invoiceNumber, int? lineItemNo]) async {
Map<String, dynamic> request; Map<String, dynamic> request;
@ -638,6 +690,32 @@ class DoctorsListService extends BaseService {
return Future.value(localRes); return Future.value(localRes);
} }
Future<Map> getPatientShareForWalkInAppointment(int clinicID, int projectID, int doctorID) async {
Map<String, dynamic> request;
request = {"ProjectID": projectID, "ClinicID": clinicID, "DoctorID": doctorID};
dynamic localRes;
await baseAppClient.post(GET_PATIENT_SHARE_FOR_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> canPayForWalkInAppointment(int clinicID, int projectID, int doctorID) async {
Map<String, dynamic> request;
request = {"ProjectID": projectID, "ClinicID": clinicID, "DoctorID": doctorID, "StartTime": "12:00", "EndTime": "12:00"};
dynamic localRes;
await baseAppClient.post(CAN_PAY_FOR_FOR_WALKIN_APPOINTMENT, onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> getPatientAppointmentHistory(bool isActiveAppointment, int languageID, BuildContext context, {bool isForCOC = false, isForUpcomming = false, IsForArrived = false}) async { Future<Map> getPatientAppointmentHistory(bool isActiveAppointment, int languageID, BuildContext context, {bool isForCOC = false, isForUpcomming = false, IsForArrived = false}) async {
Map<String, dynamic> request; Map<String, dynamic> request;
@ -1571,6 +1649,19 @@ class DoctorsListService extends BaseService {
return Future.value(localRes); return Future.value(localRes);
} }
Future<Map> checkScannedNFCAndQRCode(String nfcCode, int projectId) async {
Map<String, dynamic> request;
request = {"NFC_Code": nfcCode, "ProjectID": projectId};
dynamic localRes;
await baseAppClient.post(CHECK_SCANNED_NFC_QR_CODE, onSuccess: (response, statusCode) async {
localRes = response;
}, onFailure: (String error, int statusCode) {
throw error;
}, body: request);
return Future.value(localRes);
}
Future<Map> checkIfHasDentalPlan(int projectID, BuildContext context) async { Future<Map> checkIfHasDentalPlan(int projectID, BuildContext context) async {
Map<String, dynamic> request; Map<String, dynamic> request;

File diff suppressed because it is too large Load Diff

@ -54,7 +54,7 @@ class PayfortService extends BaseService {
"Pat_Token": result.tokenName, "Pat_Token": result.tokenName,
"IsRefund": false, "IsRefund": false,
"RemmeberMe": false, "RemmeberMe": false,
"Reconciliation_Reference": result.reconciliationReference, // "Reconciliation_Reference": result.reconciliationReference,
"LanguageID": 1, "LanguageID": 1,
"PatientID": patientID "PatientID": patientID
}; };

@ -3,7 +3,7 @@ import 'package:diplomaticquarterapp/core/service/base_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:localstorage/localstorage.dart'; import 'package:localstorage/localstorage.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:vibration/vibration.dart'; // import 'package:vibration/vibration.dart';
import 'package:geolocator/geolocator.dart' as geo; import 'package:geolocator/geolocator.dart' as geo;
class PermissionService extends BaseService { class PermissionService extends BaseService {
@ -25,10 +25,10 @@ class PermissionService extends BaseService {
vibrate(callback, context) async { vibrate(callback, context) async {
if (callback == null) return null; if (callback == null) return null;
if (isVibrationEnabled() == true) { if (isVibrationEnabled() == true) {
if (await Vibration.hasVibrator() !=null) { // if (await Vibration.hasVibrator() !=null) {
Vibration.vibrate(duration: 100); // Vibration.vibrate(duration: 100);
callback(); // callback();
} // }
} else { } else {
callback(); callback();
} }

@ -7,9 +7,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'PlatformBridge.dart'; import 'PlatformBridge.dart';
class AppPermission{ class AppPermission {
static Future<bool> askVideoCallPermission(BuildContext context) async { static Future<bool> askVideoCallPermission(BuildContext context) async {
if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) {
return false; return false;
@ -21,6 +19,30 @@ class AppPermission{
return true; return true;
} }
//
// Manifest.permission.INTERNET,
// Manifest.permission.ACCESS_FINE_LOCATION,
// Manifest.permission.ACCESS_COARSE_LOCATION,
// Manifest.permission.ACCESS_NETWORK_STATE,
// Manifest.permission.BLUETOOTH,
// Manifest.permission.BLUETOOTH_ADMIN,
// Manifest.permission.BLUETOOTH_SCAN,
// Manifest.permission.BLUETOOTH_CONNECT,
// Manifest.permission.HIGH_SAMPLING_RATE_SENSORS,
// Manifest.permission.ACTIVITY_RECOGNITION
static Future<bool> askPenguinPermissions() async {
if (!(await Permission.location.request().isGranted) ||
!(await Permission.bluetooth.request().isGranted) ||
!(await Permission.bluetoothScan.request().isGranted) ||
!(await Permission.bluetoothConnect.request().isGranted) ||
!(await Permission.activityRecognition.request().isGranted)) {
return false;
}
return true;
}
static Future _drawOverAppsMessageDialog(BuildContext context) async { static Future _drawOverAppsMessageDialog(BuildContext context) async {
ConfirmDialog dialog = new ConfirmDialog( ConfirmDialog dialog = new ConfirmDialog(
context: context, context: context,
@ -34,4 +56,4 @@ class AppPermission{
cancelFunction: () => {}); cancelFunction: () => {});
dialog.showAlertDialog(context); dialog.showAlertDialog(context);
} }
} }

@ -0,0 +1,98 @@
import 'package:flutter/services.dart';
class PenguinMethodChannel {
static const MethodChannel _channel = MethodChannel('launch_penguin_ui');
static Future<void> launch(String storyboardName, String languageCode, String username, {NavigationClinicDetails? details}) async {
try {
await _channel.invokeMethod('launchPenguin', {
"storyboardName": storyboardName,
"baseURL": "https://prod.hmg.nav.penguinin.com",
// "dataURL": "https://hmg.nav.penguinin.com",
// "positionURL": "https://hmg.nav.penguinin.com",
// "dataURL": "https://hmg-v33.local.penguinin.com",
// "positionURL": "https://hmg-v33.local.penguinin.com",
"dataURL": "https://prod.hmg.nav.penguinin.com",
"positionURL": "https://prod.hmg.nav.penguinin.com",
"dataServiceName": "api",
"positionServiceName": "pe",
"clientID": "HMG",
"username": "test",
"isSimulationModeEnabled": false,
"isShowUserName": false,
"isUpdateUserLocationSmoothly": true,
"isEnableReportIssue": true,
"languageCode": languageCode,
"clientKey": "UGVuZ3VpbklOX1Blbk5hdl9QSUY=",
"mapBoxKey": "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg",
// "clinicID": details?.clinicId ?? "",
"clinicID": details?.clinicId ?? "", // 46 ,49, 133
"patientID": details?.patientId ?? "",
"projectID": details?.projectId ?? "",
});
} on PlatformException catch (e) {
print("Failed to launch PenguinIn: '${e.message}'.");
}
}
void setMethodCallHandler(){
_channel.setMethodCallHandler((MethodCall call) async {
try {
print(call.method);
switch (call.method) {
case PenguinMethodNames.onPenNavInitializationError:
_handleInitializationError(call.arguments); // Handle onPenNavInitializationError errors.
break;
case PenguinMethodNames.onPenNavUIDismiss:
//todo handle pen dismissable
// _handlePenNavUIDismiss(); // Handle UI dismissal event.
break;
case PenguinMethodNames.onReportIssue:
// Handle the report issue event.
_handleInitializationError(call.arguments);
break;
default:
_handleUnknownMethod(call.method); // Handle unknown method calls.
}
} catch (e) {
print("Error handling method call '${call.method}': $e");
// Optionally, log this error to an external service
}
});
}
static void _handleUnknownMethod(String method) {
print("Unknown method: $method");
// Optionally, handle this unknown method case, such as reporting or ignoring it
}
static void _handleInitializationError(Map<dynamic, dynamic> error) {
final type = error['type'] as String?;
final description = error['description'] as String?;
print("Initialization Error: ${type ?? 'Unknown Type'}, ${description ?? 'No Description'}");
}
}
// Define constants for method names
class PenguinMethodNames {
static const String showPenguinUI = 'showPenguinUI';
static const String openSharedLocation = 'openSharedLocation';
// ---- Handler Method
static const String onPenNavSuccess = 'onPenNavSuccess'; // Tested Android,iOS
static const String onPenNavInitializationError = 'onPenNavInitializationError'; // Tested Android,iOS
static const String onPenNavUIDismiss = 'onPenNavUIDismiss'; //Tested Android,iOS
static const String onReportIssue = 'onReportIssue'; // Tested Android,iOS
static const String onLocationOffCampus = 'onLocationOffCampus'; // Tested iOS,Android
static const String navigateToPOI = 'navigateToPOI'; // Tested Android,iOS
}
class NavigationClinicDetails {
String? clinicId;
String? patientId;
String? projectId;
}

@ -15,6 +15,7 @@ import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart';
import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/penguin_method_channel.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir; import 'package:firebase_messaging/firebase_messaging.dart' as fir;
@ -388,9 +389,16 @@ class PushNotificationHandler {
if (remoteMessage.data.isEmpty) { if (remoteMessage.data.isEmpty) {
return; return;
} }
debugPrint('the value of the remote message is ${remoteMessage.data}');
if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) { if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) {
_incomingCall(remoteMessage.data); _incomingCall(remoteMessage.data);
// showCallkitIncoming(remoteMessage.data); // showCallkitIncoming(remoteMessage.data);
}if(remoteMessage.data['is_navigation'] == 'true' || remoteMessage.data['is_navigation'] == true ){
NavigationClinicDetails data = NavigationClinicDetails();
data.clinicId = remoteMessage.data['clinic_Id'];
data.patientId = remoteMessage.data['patient_Id'];
data.projectId = remoteMessage.data['project_Id'];
initPenguinSDK(data);
} else { } else {
GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); GetNotificationsResponseModel notification = new GetNotificationsResponseModel();
@ -408,6 +416,21 @@ class PushNotificationHandler {
} }
} }
initPenguinSDK(NavigationClinicDetails data) async {
final bool permited = await AppPermission.askPenguinPermissions();
if (!permited) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.activityRecognition,
].request().whenComplete(() {
PenguinMethodChannel.launch("penguin", "en", "1231755", details: data);
});
}
}
onToken(String token) async { onToken(String token) async {
// print("Push Notification Token: " + token); // print("Push Notification Token: " + token);
await AppSharedPreferences().setString(PUSH_TOKEN, token); await AppSharedPreferences().setString(PUSH_TOKEN, token);

@ -2963,7 +2963,18 @@ class TranslationBase {
String get selectHospitalBloodDonation => localizedValues["selectHospitalBloodDonation"][locale.languageCode]; String get selectHospitalBloodDonation => localizedValues["selectHospitalBloodDonation"][locale.languageCode];
String get wecare => localizedValues["wecare"][locale.languageCode]; String get wecare => localizedValues["wecare"][locale.languageCode];
String get myinstructions => localizedValues["myinstructions"][locale.languageCode]; String get myinstructions => localizedValues["myinstructions"][locale.languageCode];
String get clinicLocation => localizedValues["clinicLocation"][locale.languageCode];
String get waitingAppointment => localizedValues["waitingAppointment"][locale.languageCode];
String get whatWaitingAppointment => localizedValues["whatWaitingAppointment"][locale.languageCode];
String get waitingAppointmentText1 => localizedValues["waitingAppointmentText1"][locale.languageCode];
String get waitingAppointmentText2 => localizedValues["waitingAppointmentText2"][locale.languageCode];
String get waitingAppointmentText3 => localizedValues["waitingAppointmentText3"][locale.languageCode];
String get waitingAppointmentVerificationMethod => localizedValues["waitingAppointmentVerificationMethod"][locale.languageCode];
String get howToUseVerificationMethod => localizedValues["howToUseVerificationMethod"][locale.languageCode];
String get addToWaitingList => localizedValues["addToWaitingList"][locale.languageCode];
String get searchClinic => localizedValues["searchClinic"][locale.languageCode]; String get searchClinic => localizedValues["searchClinic"][locale.languageCode];
String get selectBranch => localizedValues["selectBranch"][locale.languageCode];
String get searchByBranch => localizedValues["searchByBranch"][locale.languageCode];
String get existingPackage => localizedValues["existingPackage"][locale.languageCode]; String get existingPackage => localizedValues["existingPackage"][locale.languageCode];
String get continueOrbookNew => localizedValues["continueOrbookNew"][locale.languageCode]; String get continueOrbookNew => localizedValues["continueOrbookNew"][locale.languageCode];

@ -65,6 +65,30 @@ AppSharedPreferences sharedPref = new AppSharedPreferences();
class Utils { class Utils {
// static ProgressDialog pr; // static ProgressDialog pr;
static var navigationProjectsList = [
{
"Desciption": "Sahafa Hospital",
"DesciptionN": null,
"ID": 130,
"LegalName": "Sahafa Hospital",
"LegalNameN": "مستشفى الصحافة",
"Name": "Sahafa Hospital",
"NameN": null,
"PhoneNumber": "+966115222222",
"SetupID": "013311",
"DistanceInKilometers": 0,
"HasVida3": false,
"IsActive": true,
"IsHmg": true,
"IsVidaPlus": false,
"Latitude": "24.8113774",
"Longitude": "46.6239813",
"MainProjectID": 130,
"ProjectOutSA": false,
"UsingInDoctorApp": false
}
];
///show custom Error Toast ///show custom Error Toast
/// [message] to show for user /// [message] to show for user
static showErrorToast([String? message]) { static showErrorToast([String? message]) {
@ -909,7 +933,7 @@ class Utils {
return projectDetailListModel; return projectDetailListModel;
} }
//static String generateSignature() {} //static String generateSignature() {}
} }
Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) { Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) {

@ -0,0 +1,290 @@
import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/medical/radiology_view_model.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:flutter/material.dart';
import '../../uitl/translations_delegate_base.dart';
class LocationSelectionDialog extends StatelessWidget {
final List<HospitalsModel> data;
final Function(int)? onValueSelected;
final int? selectedIndex;
const LocationSelectionDialog(
{super.key,
required this.data,
this.onValueSelected,
this.selectedIndex});
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: LocationDialogBody(
data: data,
onValueSelected: onValueSelected,
selectedIndex: selectedIndex,
));
}
}
class LocationDialogBody extends StatefulWidget {
final List<HospitalsModel> data;
final Function(int)? onValueSelected;
final int? selectedIndex;
const LocationDialogBody(
{super.key,
required this.data,
this.onValueSelected,
this.selectedIndex});
@override
State<LocationDialogBody> createState() => _LocationDialogBodyState();
}
class _LocationDialogBodyState extends State<LocationDialogBody> {
bool isListVisible = false;
int currentlySelected = -1;
@override
Widget build(BuildContext context) {
return isListVisible
? LocationListExpandedBody(
data: widget.data,
onItemClick: (data) {
if (data.isEmpty) return;
var selected = widget.data.indexWhere(
(item) => item.name == data,
);
if (selected == -1) return;
setState(() {
currentlySelected = selected;
isListVisible = false;
});
},
)
: LocationListWrapBody(
onConfirmClicked: () {
widget.onValueSelected?.call(currentlySelected);
},
onTextBoxClicked: () {
setState(() {
isListVisible = true;
});
},
selectedText: currentlySelected == -1
? ""
: widget.data[currentlySelected].name ?? "");
}
}
class LocationListExpandedBody extends StatefulWidget {
final List<HospitalsModel> data;
final Function(String) onItemClick;
const LocationListExpandedBody(
{super.key, required this.data, required this.onItemClick});
@override
State<LocationListExpandedBody> createState() =>
_LocationListExpandedBodyState();
}
class _LocationListExpandedBodyState extends State<LocationListExpandedBody> {
List<HospitalsModel> tempListData = [];
TextEditingController controller = new TextEditingController();
@override
void initState() {
super.initState();
setState(() {
tempListData.addAll(widget.data);
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SelectBranchHeader(),
SizedBox(height: 8,),
TextField(
controller: controller,
onChanged: (v) {
tempListData.clear();
if (v.length > 0) {
for (int i = 0; i < widget.data.length; i++) {
if (widget.data[i].name
?.toLowerCase()
.contains(v.toLowerCase()) ==
true) {
tempListData.add(widget.data[i]);
}
}
} else {
tempListData.addAll(widget.data);
}
setState(() {});
},
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 12),
hintText: TranslationBase.of(context).searchByBranch,
suffixIcon: Icon(Icons.search),
contentPadding: EdgeInsets.symmetric(vertical: 9,horizontal: 14),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: Colors.grey, // Normal border color
width: 1.0,
),
),
),
),
SizedBox(
height: 16,
),
ListView.builder(
itemCount: tempListData.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(bottom: 8),
child: SizedBox(
height: 24,
child: InkWell(
onTap: () {
widget
.onItemClick(tempListData[index].name ?? "");
},
child: Text(
"${tempListData[index].name ?? ""} ( ${tempListData[index].distanceInKilometers} km )",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.black,
letterSpacing: -0.96),
),
),
),
);
})
],
),
),
);
}
}
class LocationListWrapBody extends StatelessWidget {
final VoidCallback? onConfirmClicked;
final VoidCallback? onTextBoxClicked;
final String selectedText;
const LocationListWrapBody(
{super.key,
this.onConfirmClicked,
this.onTextBoxClicked,
required this.selectedText});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SelectBranchHeader(),
SizedBox(
height: 24,
),
ListTile(
onTap: () {
onTextBoxClicked?.call();
},
title: Text(
TranslationBase.of(context).selectBranch,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.black,
letterSpacing: -0.96),
),
subtitle: selectedText.isEmpty
? null
: Text(
selectedText,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black,
letterSpacing: -0.96),
),
trailing: Icon(
Icons.arrow_drop_down_outlined,
color: Colors.black,
),
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.grey, width: 1),
borderRadius: BorderRadius.circular(8),
),
),
SizedBox(
height: 24,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: DefaultButton(
TranslationBase.of(context).confirm,
() {
Navigator.pop(context);
onConfirmClicked?.call();
},
color: CustomColors.accentColor,
),
),
],
),
],
),
);
}
}
class SelectBranchHeader extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
TranslationBase.of(context).selectBranch,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w600,
color: Colors.black,
letterSpacing: -0.96),
),
InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(Icons.close),
))
],
);
}
}

@ -171,7 +171,7 @@ class _AppDrawerState extends State<AppDrawer> {
// ), // ),
mHeight(20.0), mHeight(20.0),
(user != null && projectProvider!.isLogin) (user != null && projectProvider!.isLogin)
? Image.network("https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${user!.patientID.toString()}", fit: BoxFit.fill, height: 73.5, width: 73.5) ? Image.network("https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${user!.patientID.toString()}", fit: BoxFit.fill, height: 70, width: 70)
: Container(), : Container(),
], ],
), ),
@ -719,7 +719,7 @@ class _AppDrawerState extends State<AppDrawer> {
// result.list.cRSVerificationStatus = result['CRSVerificationStatus']; // result.list.cRSVerificationStatus = result['CRSVerificationStatus'];
await this.sharedPref.setString(APP_LANGUAGE, currentLang); await this.sharedPref.setString(APP_LANGUAGE, currentLang);
await this.sharedPref.setString(BLOOD_TYPE, bloodType); await this.sharedPref.setString(BLOOD_TYPE, bloodType);
await this.sharedPref.setInt(LAST_LOGIN, loginType ?? 1 ); await this.sharedPref.setInt(LAST_LOGIN, loginType ?? 1);
await this.sharedPref.setObject(MAIN_USER, mainUser); await this.sharedPref.setObject(MAIN_USER, mainUser);
await this.sharedPref.setObject(USER_PROFILE, result.list); await this.sharedPref.setObject(USER_PROFILE, result.list);
await this.sharedPref.setObject(FAMILY_FILE, familyFile); await this.sharedPref.setObject(FAMILY_FILE, familyFile);

@ -138,7 +138,7 @@ class MyInAppBrowser extends InAppBrowser {
openPackagesPaymentBrowser({required int customer_id, required int order_id}) { openPackagesPaymentBrowser({required int customer_id, required int order_id}) {
paymentType = _PAYMENT_TYPE.PACKAGES; paymentType = _PAYMENT_TYPE.PACKAGES;
var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id'; var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id';
this.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(full_url)), options: _InAppBrowserOptions); this.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(full_url))), options: _InAppBrowserOptions);
} }
openPaymentBrowser(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID, openPaymentBrowser(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID,
@ -190,7 +190,7 @@ class MyInAppBrowser extends InAppBrowser {
String url = "https://hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // Prod String url = "https://hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // Prod
// String url = "https://uat.hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // UAT // String url = "https://uat.hmgwebservices.com/HMGApplePayLive/applepay/pay?apq=" + res['result']; // UAT
// safariBrowser.open(url: Uri.parse(url)); // safariBrowser.open(url: Uri.parse(url));
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(url)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(url))), options: _InAppBrowserOptions);
}).catchError((err) { }).catchError((err) {
print(err); print(err);
if (context != null) GifLoaderDialogUtils.hideDialog(context); if (context != null) GifLoaderDialogUtils.hideDialog(context);
@ -233,7 +233,7 @@ class MyInAppBrowser extends InAppBrowser {
appoNo, clinicID, doctorID, "", installments) appoNo, clinicID, doctorID, "", installments)
.then((value) { .then((value) {
paymentType = _PAYMENT_TYPE.PATIENT; paymentType = _PAYMENT_TYPE.PATIENT;
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions);
}); });
}).catchError((err) { }).catchError((err) {
print(err); print(err);
@ -245,7 +245,7 @@ class MyInAppBrowser extends InAppBrowser {
clinicID, doctorID) clinicID, doctorID)
.then((value) { .then((value) {
paymentType = _PAYMENT_TYPE.PATIENT; paymentType = _PAYMENT_TYPE.PATIENT;
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions);
}); });
} }
} }
@ -258,16 +258,16 @@ class MyInAppBrowser extends InAppBrowser {
// getPatientData(); // getPatientData();
generatePharmacyURL(order, amount, orderDesc, transactionID, emailId, paymentMethod, patientName, patientID, authenticatedUser).then((value) { generatePharmacyURL(order, amount, orderDesc, transactionID, emailId, paymentMethod, patientName, patientID, authenticatedUser).then((value) {
if (order.customValuesXml!.contains("ApplePay")) { if (order.customValuesXml!.contains("ApplePay")) {
safariBrowser.open(url: Uri.parse(value)); safariBrowser.open(url: WebUri.uri(Uri.parse(value)));
} else { } else {
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(value)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(value))), options: _InAppBrowserOptions);
} }
}); });
} }
openBrowser(String url) { openBrowser(String url) {
this.browser = browser; this.browser = browser;
this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(url)), options: _InAppBrowserOptions); this.browser.openUrlRequest(urlRequest: URLRequest(url: WebUri.uri(Uri.parse(url))), options: _InAppBrowserOptions);
} }
Future<String> generateURL(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID, Future<String> generateURL(num amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID,
@ -343,7 +343,7 @@ class MyInAppBrowser extends InAppBrowser {
form = form.replaceFirst('PROJECT_ID_VALUE', projId); form = form.replaceFirst('PROJECT_ID_VALUE', projId);
form = form.replaceFirst('PAYMENT_OPTION_VALUE', paymentMethod); form = form.replaceFirst('PAYMENT_OPTION_VALUE', paymentMethod);
form = form.replaceFirst('LANG_VALUE', currentLanguageID); form = form.replaceFirst('LANG_VALUE', currentLanguageID);
form = form.replaceFirst('SERVICE_URL_VALUE', "https://mdlaboratories.com/tamaralive/Home/Checkout"); form = form.replaceFirst('SERVICE_URL_VALUE', "https://mdlaboratories.com/tamara/Home/Checkout");
form = form.replaceFirst('INSTALLMENTS_VALUE', installments); form = form.replaceFirst('INSTALLMENTS_VALUE', installments);
form = form.replaceFirst('CUSTNATIONALID_VALUE', authUser.patientIdentificationNo!); form = form.replaceFirst('CUSTNATIONALID_VALUE', authUser.patientIdentificationNo!);
@ -489,7 +489,7 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser {
} }
@override @override
void onCompletedInitialLoad() { void onCompletedInitialLoad(bool? didLoadSuccessfully) {
print("ChromeSafari browser initial load completed"); print("ChromeSafari browser initial load completed");
onLoadStartCallback!("ApplePay"); onLoadStartCallback!("ApplePay");
} }

@ -1,7 +1,7 @@
name: diplomaticquarterapp name: diplomaticquarterapp
description: A new Flutter application. description: A new Flutter application.
version: 4.5.063+4050063 version: 4.5.065+4050065
environment: environment:
sdk: ">=3.0.0 <3.13.0" sdk: ">=3.0.0 <3.13.0"
@ -34,7 +34,8 @@ dependencies:
get_it: ^7.2.0 get_it: ^7.2.0
#Google Fit & Apple HealthKit #Google Fit & Apple HealthKit
health: ^3.0.3 # health: ^3.0.3
health: ^11.1.0
#chart #chart
fl_chart: ^0.64.0 fl_chart: ^0.64.0
@ -99,7 +100,7 @@ dependencies:
flutter_rating_bar: ^4.0.1 flutter_rating_bar: ^4.0.1
# Calendar # Calendar
# syncfusion_flutter_calendar: ^23.1.42 # syncfusion_flutter_calendar: ^23.1.42
syncfusion_flutter_calendar: ^24.1.47 syncfusion_flutter_calendar: ^24.1.47
# SVG Images # SVG Images
@ -109,7 +110,7 @@ dependencies:
manage_calendar_events: ^2.0.3 manage_calendar_events: ^2.0.3
#InAppBrowser #InAppBrowser
flutter_inappwebview: ^5.8.0 flutter_inappwebview: ^6.1.5
#Circular progress bar for reverse timer #Circular progress bar for reverse timer
circular_countdown_timer: ^0.2.0 circular_countdown_timer: ^0.2.0
@ -124,7 +125,7 @@ dependencies:
flutter_datetime_picker_plus: ^2.1.0 flutter_datetime_picker_plus: ^2.1.0
carousel_pro_nullsafety: ^2.0.0 carousel_pro_nullsafety: ^2.0.0
flutter_local_notifications: any flutter_local_notifications: any
device_calendar: ^4.3.2 device_calendar: ^4.3.3
geolocator: ^9.0.2 geolocator: ^9.0.2
geocoding: ^2.0.1 geocoding: ^2.0.1
jiffy: ^6.2.1 jiffy: ^6.2.1
@ -135,13 +136,15 @@ dependencies:
google_maps_place_picker_mb: ^3.0.0 google_maps_place_picker_mb: ^3.0.0
map_launcher: ^3.0.1 map_launcher: ^3.0.1
flutter_countdown_timer: ^4.1.0 flutter_countdown_timer: ^4.1.0
carousel_slider: ^5.0.0
#Dependencies for video call implementation #Dependencies for video call implementation
native_device_orientation: ^1.0.0 native_device_orientation: ^1.0.0
wakelock: ^0.6.2 # wakelock: ^0.6.2
wakelock_plus: ^1.1.4
after_layout: ^1.1.0 after_layout: ^1.1.0
cached_network_image: ^3.3.0 cached_network_image: ^3.3.0
flutter_tts: ^3.6.1 flutter_tts: ^3.6.1
vibration: ^1.7.3 # vibration: ^1.7.3
flutter_nfc_kit: ^3.3.1 flutter_nfc_kit: ^3.3.1
#geofencing: any #geofencing: any
speech_to_text: ^6.1.1 speech_to_text: ^6.1.1
@ -151,16 +154,16 @@ dependencies:
in_app_review: ^2.0.3 in_app_review: ^2.0.3
badges: ^3.1.2 badges: ^3.1.2
flutter_app_icon_badge: ^2.0.0 # flutter_app_icon_badge: ^2.0.0
# dropdown_search: 5.0.6 # dropdown_search: 5.0.6
youtube_player_flutter: ^8.1.2 youtube_player_flutter: ^9.1.0
# shimmer: ^3.0.0 # shimmer: ^3.0.0
carousel_slider: ^4.0.0 # carousel_slider: ^4.0.0
# flutter_staggered_grid_view: ^0.7.0 # flutter_staggered_grid_view: ^0.7.0
huawei_hmsavailability: ^6.11.0+301 huawei_hmsavailability: ^6.11.0+301
huawei_location: ^6.11.0+301 huawei_location: ^6.11.0+301
share_plus: ^6.3.4 share_plus: ^10.0.2
# Marker Animation # Marker Animation
auto_size_text: ^3.0.0 auto_size_text: ^3.0.0
equatable: ^2.0.3 equatable: ^2.0.3
@ -170,12 +173,13 @@ dependencies:
google_api_availability: ^5.0.0 google_api_availability: ^5.0.0
open_filex: ^4.3.2 open_filex: ^4.3.2
path_provider: ^2.0.8 path_provider: ^2.0.8
amazon_payfort: ^1.1.0 amazon_payfort: ^1.1.3
logger: ^2.0.2+1 logger: ^2.0.2+1
network_info_plus: any network_info_plus: any
flutter_zoom_videosdk: ^1.10.11 flutter_zoom_videosdk: ^1.11.2
dart_jsonwebtoken: ^2.14.0 dart_jsonwebtoken: ^2.14.0
win32: ^5.5.4
cloudflare_turnstile: ^2.0.1 cloudflare_turnstile: ^2.0.1

Loading…
Cancel
Save