From d8bd7d145da84659bc011097b15ac5b8300dadbc Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Thu, 17 Dec 2020 18:30:04 +0300 Subject: [PATCH 01/14] no message --- ios/GoogleService-Info.plist | 20 +++++++------- ios/Podfile.lock | 10 +++---- ios/Runner.xcodeproj/project.pbxproj | 10 ++++--- ios/Runner/Helper/HMG_Geofence.swift | 2 +- ios/gpx.gpx | 2 +- lib/pages/landing/landing_page.dart | 30 ++++++++++----------- lib/pages/medical/medical_profile_page.dart | 2 +- lib/widgets/drawer/app_drawer_widget.dart | 2 +- 8 files changed, 41 insertions(+), 37 deletions(-) diff --git a/ios/GoogleService-Info.plist b/ios/GoogleService-Info.plist index 0c093a2a..633037cb 100644 --- a/ios/GoogleService-Info.plist +++ b/ios/GoogleService-Info.plist @@ -3,21 +3,23 @@ CLIENT_ID - 864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com API_KEY - AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA GCM_SENDER_ID - 864393916058 + 815750722565 PLIST_VERSION 1 BUNDLE_ID - com.cloud.diplomaticquarterapp + com.HMG.HMG-Smartphone PROJECT_ID - diplomaticquarter-d2385 + api-project-815750722565 STORAGE_BUCKET - diplomaticquarter-d2385.appspot.com + api-project-815750722565.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -29,8 +31,8 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:864393916058:ios:13f787bbfe6051f8b97923 + 1:815750722565:ios:328ec247a81a2ca23c186c DATABASE_URL - https://diplomaticquarter-d2385.firebaseio.com + https://api-project-815750722565.firebaseio.com \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d65de659..668711ce 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -20,7 +20,7 @@ PODS: - Firebase/Messaging (6.33.0): - Firebase/CoreOnly - FirebaseMessaging (~> 4.7.0) - - firebase_core (0.5.3): + - firebase_core (0.5.2): - Firebase/CoreOnly (~> 6.33.0) - Flutter - firebase_core_web (0.1.0): @@ -70,7 +70,7 @@ PODS: - Flutter - flutter_tts (0.0.1): - Flutter - - geolocator (6.1.9): + - "geolocator (6.0.0+4)": - Flutter - google_maps_flutter (0.0.1): - Flutter @@ -375,7 +375,7 @@ SPEC CHECKSUMS: device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 + firebase_core: 350ba329d1641211bc6183a3236893cafdacfea7 firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd @@ -390,7 +390,7 @@ SPEC CHECKSUMS: flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d - geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899 + geolocator: 1ae40084cc6c1586ce5ad12cfc3fd38c64d05f2f google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac @@ -440,4 +440,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 -COCOAPODS: 1.8.4 +COCOAPODS: 1.10.0 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 009006ed..77d42044 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */; }; E923EFD82588D17700E3E751 /* gpx.gpx in Resources */ = {isa = PBXBuildFile; fileRef = E923EFD72588D17700E3E751 /* gpx.gpx */; }; E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9620804255C2ED100D3A35D /* NetworkExtension.framework */; }; + E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */; }; E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */; }; E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; }; /* End PBXBuildFile section */ @@ -78,6 +79,7 @@ E923EFD72588D17700E3E751 /* gpx.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = gpx.gpx; sourceTree = ""; }; E9620803255C2ED100D3A35D /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; E9620804255C2ED100D3A35D /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; + E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_Guest.swift; sourceTree = ""; }; E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedFromFlutter.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -128,6 +130,7 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */, E923EFD72588D17700E3E751 /* gpx.gpx */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, @@ -265,6 +268,7 @@ files = ( E91B53A0256AAC1400E96549 /* GuestPOC_Certificate.cer in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, E923EFD82588D17700E3E751 /* gpx.gpx in Resources */, E91B539F256AAC1400E96549 /* GuestPOC_Certificate.p12 in Resources */, @@ -472,7 +476,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -611,7 +615,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -644,7 +648,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index fb469165..0c39fe5a 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -156,7 +156,7 @@ extension HMG_Geofence{ func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ df.dateFormat = "MMM/dd/yyyy hh:mm:ss" - if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.user-profile"), + if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.imei-user-data"), let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ diff --git a/ios/gpx.gpx b/ios/gpx.gpx index 9cc26956..6121e536 100644 --- a/ios/gpx.gpx +++ b/ios/gpx.gpx @@ -1 +1 @@ - Sverrir Sigmundarson Office Office Mahmoud Home Mahmoud Home Panorama Mall Panorama Mall Saudi Architects Crossing Saudi Architects Crossing Office Office \ No newline at end of file + Sverrir Sigmundarson 617.71 620.95 643.70 677.84 \ No newline at end of file diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index acbf8d78..a45f24eb 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -146,7 +146,6 @@ class _LandingPageState extends State with WidgetsBindingObserver { _firebaseMessaging.requestNotificationPermissions(); } - // Flip Permission Checks [Zohaib Kambrani] requestPermissions().then((results) { if (results[Permission.notification].isGranted) _firebaseMessaging.getToken().then((String token) { @@ -436,7 +435,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { void checkUserStatus(token) async { var result = await authService.selectDeviceImei(token); - setUserValues(result); + await setUserValues(result); registerGeofences(); if (await sharedPref.getObject(USER_PROFILE) != null) { @@ -472,7 +471,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { } Future getUserInformation() async { - var userInfoJson = sharedPref.getObject(IMEI_USER_DATA); + var userInfoJson = await sharedPref.getObject(IMEI_USER_DATA); return userInfoJson; } @@ -484,23 +483,22 @@ class _LandingPageState extends State with WidgetsBindingObserver { registerGeofences() async { await locator().getAllGeoZones(GeoZonesRequestModel()); + var userInfo = await getUserInformation(); void doIt() { - getUserInformation().then((value) { - if (value != null) projectViewModel.platformBridge().registerHmgGeofences(); - }); + projectViewModel.platformBridge().registerHmgGeofences(); } - if (await Permission.location.isGranted) { - doIt(); - } else { - [Permission.location].request().then((value) async { - if (await Permission.location.isGranted) { - doIt(); - } - }); + if (userInfo != null) { + if (await Permission.location.isGranted) { + doIt(); + } else { + [Permission.location].request().then((value) async { + if (await Permission.location.isGranted) { + doIt(); + } + }); + } } - - requestPermissions().then((results) {}); } } diff --git a/lib/pages/medical/medical_profile_page.dart b/lib/pages/medical/medical_profile_page.dart index 6dabf9d3..3260303c 100644 --- a/lib/pages/medical/medical_profile_page.dart +++ b/lib/pages/medical/medical_profile_page.dart @@ -430,7 +430,7 @@ class _MedicalProfilePageState extends State { child: InkWell( //TODO onTap: () { - if (authProvider.isLogin) { + if (projectViewModel.isLogin) { String patientID = authProvider.getAuthenticatedUser().patientID.toString(); GifLoaderDialogUtils.showMyDialog(context); projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}); diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 9c6375e4..05ae92e3 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -331,7 +331,7 @@ class _AppDrawerState extends State { await sharedPref.clear(); this.user = null; Navigator.of(context).pushNamed(HOME); - projectProvider.platformBridge().unRegisterHmgGeofences(); + // projectProvider.platformBridge().unRegisterHmgGeofences(); } login() async { From 508bc191bea7ec1d6749fe9748fcb24bbc0e48b8 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani <> Date: Sun, 20 Dec 2020 13:44:29 +0300 Subject: [PATCH 02/14] geofencing login check fix --- android/app/src/main/AndroidManifest.xml | 2 +- .../geofence/GeoZoneModel.kt | 2 + .../geofence/GeofenceBroadcastReceiver.kt | 17 +++++++- .../GeofenceBroadcastReceiverWithService.kt | 13 ++++++ .../GeofenceTransitionsJobIntentService.kt | 37 +++-------------- .../GeofencingRebootBroadcastReceiver.kt | 3 +- .../geofence/HMG_Geofence.kt | 41 ++++++++++++++++++- .../diplomaticquarterapp/utils/HMGUtils.kt | 35 ++++++++++++++-- ios/Runner/AppDelegate.swift | 22 ---------- ios/Runner/Helper/Extensions.swift | 10 +++++ ios/Runner/Helper/GlobalHelper.swift | 30 +++++++++++++- ios/Runner/Helper/HMG_Geofence.swift | 14 ++++--- lib/pages/landing/landing_page.dart | 30 ++++++-------- 13 files changed, 169 insertions(+), 87 deletions(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1032b29b..c114b44d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -80,7 +80,7 @@ - + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt index 7eba1ead..328014e6 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt @@ -37,6 +37,7 @@ class GeoZoneModel { val rad = Radius.toFloat() if(lat != null && long != null){ + val loiteringDelayMinutes:Int = 5 // in Minutes return Geofence.Builder() .setRequestId(identifier()) .setCircularRegion( @@ -46,6 +47,7 @@ class GeoZoneModel { ) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) // .setNotificationResponsiveness(0) +// .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) .setExpirationDuration(Geofence.NEVER_EXPIRE) .build() } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt index 8fc1faae..f8a861bb 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt @@ -5,9 +5,24 @@ package com.cloud.diplomaticquarterapp.geofence import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.util.Log +import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofencingEvent class GeofenceBroadcastReceiver : BroadcastReceiver() { + private val LOG_TAG = "GeofenceBroadcastReceiver" override fun onReceive(context: Context, intent: Intent) { - GeofenceTransitionsJobIntentService.enqueueWork(context, intent) + + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) + saveLog(context,LOG_TAG,errorMessage) + return + } + + HMG_Geofence.shared(context).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + } + } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt new file mode 100644 index 00000000..0332f745 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt @@ -0,0 +1,13 @@ + + +package com.cloud.diplomaticquarterapp.geofence + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class GeofenceBroadcastReceiverWithService : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + GeofenceTransitionsJobIntentService.enqueueWork(context, intent) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt index f28e1720..18ee92d9 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt @@ -52,8 +52,9 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { private const val LOG_TAG = "GeoTrIntentService" private const val JOB_ID = 573 - + var context_: Context? = null fun enqueueWork(context: Context, intent: Intent) { + context_ = context enqueueWork( context, GeofenceTransitionsJobIntentService::class.java, JOB_ID, @@ -70,37 +71,9 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { } if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { - handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); - } - } - - private fun handleEvent(triggerGeofences: List, location:Location, transition:GeofenceTransition) { - val hmg = HMG_Geofence.shared(this) - hmg.getPatientID()?.let { patientId -> - - hmg.getActiveGeofences({ activeGeofences -> - - triggerGeofences.forEach { geofence -> - // Extract PointID from 'geofence.requestId' and find from active geofences - val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first() - if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){ - - val body = mapOf( - "PointsID" to pointID.toIntOrNull(), - "GeoType" to transition.value, - "PatientID" to patientId - ) - - httpPost>(API.LOG_GEOFENCE, body, { response -> - sendNotification(this, transition.named(), geofence.requestId, "Notified to server.😎") - },{ exception -> - sendNotification(this, transition.named(), geofence.requestId, "Failed to notify server.😔") - }) - - } - } - - },null) + context_?.let { + HMG_Geofence.shared(it).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + } } } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt index 08a0c93f..4534b08f 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt @@ -13,7 +13,8 @@ import com.cloud.diplomaticquarterapp.utils.HMGUtils class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { - if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { +// if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { + if (intent.action.equals("android.intent.action.BOOT_COMPLETE")) { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("REBOOT_DETECTED","YES").apply() diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt index 4d2c48b3..24639c6c 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -6,7 +6,9 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.content.pm.PackageManager +import android.location.Location import androidx.core.content.ContextCompat +import com.cloud.diplomaticquarterapp.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient import com.google.android.gms.location.GeofencingRequest @@ -37,6 +39,7 @@ const val PREFS_STORAGE = "FlutterSharedPreferences" const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences" +const val PREF_KEY_LANGUAGE = "flutter.language" class HMG_Geofence { // https://developer.android.com/training/location/geofencing#java @@ -99,6 +102,7 @@ class HMG_Geofence { } .addOnFailureListener { print(it.localizedMessage) + saveLog(context,"error:ADD_GEOFENCES", it.localizedMessage) } } },null) @@ -107,7 +111,6 @@ class HMG_Geofence { fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ getActiveGeofences({ success -> val mList = success.toMutableList() - mList.add("12345") geofencingClient .removeGeofences(success) .addOnSuccessListener { @@ -115,6 +118,7 @@ class HMG_Geofence { } .addOnFailureListener { completion(false, it) + saveLog(context,"error:REMOVE_GEOFENCES", it.localizedMessage) } removeActiveGeofences() }, { failed -> @@ -154,7 +158,10 @@ class HMG_Geofence { } fun getPatientID():Int?{ - val profileJson = preferences.getString("flutter.imei-user-data", "{}") + var profileJson = preferences.getString("flutter.imei-user-data", null) + if (profileJson == null) + profileJson = preferences.getString("flutter.user-profile", null) + val type = object : TypeToken?>() {}.type return gson.fromJson?>(profileJson,type) ?.get("PatientID") @@ -162,4 +169,34 @@ class HMG_Geofence { .toDoubleOrNull() ?.toInt() } + + + fun handleEvent(triggerGeofences: List, location: Location, transition:GeofenceTransition) { + getPatientID()?.let { patientId -> + getActiveGeofences({ activeGeofences -> + + triggerGeofences.forEach { geofence -> + // Extract PointID from 'geofence.requestId' and find from active geofences + val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first() + if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){ + + val body = mutableMapOf( + "PointsID" to pointID.toIntOrNull(), + "GeoType" to transition.value, + "PatientID" to patientId + ) + body.putAll(HMGUtils.defaultHTTPParams(context)) + + httpPost>(API.LOG_GEOFENCE, body, { response -> + sendNotification(context, transition.named(), geofence.requestId, "Notified to server.😎") + },{ exception -> + sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server.😔") + }) + + } + } + + },null) + } + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index bebd0101..413e8c09 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -16,6 +16,7 @@ import com.cloud.diplomaticquarterapp.R import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES +import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost import com.google.android.gms.location.Geofence @@ -76,6 +77,26 @@ class HMGUtils { return geoZones } + fun getLanguageCode(context: Context) : Int{ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + val lang = pref.getString(PREF_KEY_LANGUAGE,"ar") + return if(lang == "ar") 2 else 1 + } + + fun defaultHTTPParams(context: Context) : Map{ + return mapOf( + "ZipCode" to "966", + "VersionID" to 5.6, + "Channel" to 3, + "LanguageID" to getLanguageCode(context), + "IPAdress" to "10.20.10.20", + "generalid" to "Cs2020@2016$2958", + "PatientOutSA" to 0, + "SessionID" to null, + "isDentalAllowedBackend" to false, + "DeviceTypeID" to 2) + } + } } @@ -117,7 +138,9 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, notificationManager.notify(getUniqueId(), notification.build()) } - +//------------------------- +// Open Helper Methods +//------------------------- private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) fun isJSONValid(jsonString: String?): Boolean { @@ -129,11 +152,18 @@ fun isJSONValid(jsonString: String?): Boolean { return true } +fun saveLog(context:Context, tag:String, message:String){ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + var logs = pref.getString("GEO_LOGS","") + logs += "$tag -> $message \n" + pref.edit().putString("PLATFORM_LOGS", logs).apply(); +} + class HTTPResponse(data: T){ final var data:T = data } -fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit){ +fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit){ val gson = Gson() val type = object : TypeToken() {}.type val jsonBody = gson.toJson(body) @@ -153,7 +183,6 @@ fun httpPost(url: String, body: Map, onSuccess: (response: HTTP } }, { onError(it) - it.localizedMessage }) } diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index e686619c..a9252ee5 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -8,7 +8,6 @@ import GoogleMaps let locationManager = CLLocationManager() override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { -// initLocationManager() GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") GeneratedPluginRegistrant.register(with: self) @@ -24,24 +23,3 @@ import GoogleMaps return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } - -extension AppDelegate: CLLocationManagerDelegate { - - func initLocationManager(){ - locationManager.allowsBackgroundLocationUpdates = true - locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters - locationManager.activityType = .other - locationManager.delegate = self - locationManager.requestAlwaysAuthorization() - } - - func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { - if region is CLCircularRegion { - } - } - - func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) { - if region is CLCircularRegion { - } - } -} diff --git a/ios/Runner/Helper/Extensions.swift b/ios/Runner/Helper/Extensions.swift index a8793617..5c1de7c3 100644 --- a/ios/Runner/Helper/Extensions.swift +++ b/ios/Runner/Helper/Extensions.swift @@ -18,6 +18,16 @@ extension String{ } } +extension Dictionary{ + func merge(dict:[String:Any?]) -> [String:Any?]{ + var self_ = self as! [String:Any?] + dict.forEach { (kv) in + self_.updateValue(kv.value, forKey: kv.key) + } + return self_ + } +} + extension Bundle { func certificate(named name: String) -> SecCertificate { diff --git a/ios/Runner/Helper/GlobalHelper.swift b/ios/Runner/Helper/GlobalHelper.swift index c5eb7295..35f89991 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -49,9 +49,35 @@ func showNotification(identifier:String? = nil, title:String?, subtitle:String?, } } +func appLanguageCode() -> Int{ + let lang = UserDefaults.standard.string(forKey: "language") ?? "ar" + return lang == "ar" ? 2 : 1 +} + +func userProfile() -> [String:Any?]?{ + var userProf = UserDefaults.standard.string(forKey: "flutter.imei-user-data") + if(userProf == nil){ + userProf = UserDefaults.standard.string(forKey: "flutter.user-profile") + } + return dictionary(from: userProf ?? "{}") +} + +fileprivate let defaultHTTPParams:[String : Any?] = [ + "ZipCode" : "966", + "VersionID" : 5.6, + "Channel" : 3, + "LanguageID" : appLanguageCode(), + "IPAdress" : "10.20.10.20", + "generalid" : "Cs2020@2016$2958", + "PatientOutSA" : 0, + "SessionID" : nil, + "isDentalAllowedBackend" : false, + "DeviceTypeID" : 2 +] -func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool,[String:Any]?)->Void)?){ - let json: [String: Any] = jsonBody +func httpPostRequest(urlString:String, jsonBody:[String:Any?], completion:((Bool,[String:Any]?)->Void)?){ + var json: [String: Any?] = jsonBody + json = json.merge(dict: defaultHTTPParams) let jsonData = try? JSONSerialization.data(withJSONObject: json) // create post request diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index 0c39fe5a..3299fa1a 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -156,8 +156,13 @@ extension HMG_Geofence{ func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ df.dateFormat = "MMM/dd/yyyy hh:mm:ss" - if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.imei-user-data"), - let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ + var userInfo = UserDefaults.standard.string(forKey: "flutter.imei-user-data") + if(userInfo == nil){ + userInfo = UserDefaults.standard.string(forKey: "flutter.user-profile") + } + + if let userProfile = userProfile(), + let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ let body:[String:Any] = [ @@ -172,15 +177,14 @@ extension HMG_Geofence{ showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_) - var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "LOGS") ?? [:] + var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "GEOFENCE_LOGS") ?? [:] if var geo = logs[forRegion.identifier] as? [String]{ geo.append("\(status_) at \(df.string(from: Date()))") }else{ logs.updateValue(["\(status_) at \(df.string(from: Date()))"], forKey: forRegion.identifier) } - UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "LOGS") - + UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "GEOFENCE_LOGS") } } } diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index a45f24eb..7625bcf6 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -142,11 +142,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)}); }).checkAndConnectIfNoInternet(); + if (Platform.isIOS) { _firebaseMessaging.requestNotificationPermissions(); } requestPermissions().then((results) { + registerGeofences(); + if (results[Permission.notification].isGranted) _firebaseMessaging.getToken().then((String token) { sharedPref.setString(PUSH_TOKEN, token); @@ -156,7 +159,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { } }); - if (results[Permission.location].isGranted) ; + if (results[Permission.locationAlways].isGranted) ; if (results[Permission.storage].isGranted) ; if (results[Permission.camera].isGranted) ; if (results[Permission.photos].isGranted) ; @@ -436,7 +439,6 @@ class _LandingPageState extends State with WidgetsBindingObserver { void checkUserStatus(token) async { var result = await authService.selectDeviceImei(token); await setUserValues(result); - registerGeofences(); if (await sharedPref.getObject(USER_PROFILE) != null) { var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); @@ -483,22 +485,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { registerGeofences() async { await locator().getAllGeoZones(GeoZonesRequestModel()); - var userInfo = await getUserInformation(); - - void doIt() { - projectViewModel.platformBridge().registerHmgGeofences(); - } - - if (userInfo != null) { - if (await Permission.location.isGranted) { - doIt(); - } else { - [Permission.location].request().then((value) async { - if (await Permission.location.isGranted) { - doIt(); - } - }); - } + if (await Permission.location.isGranted) { + PlatformBridge().registerHmgGeofences(); + } else { + [Permission.location].request().then((results) async { + if (results[Permission.locationAlways].isGranted){ + PlatformBridge().registerHmgGeofences(); + } + }); } } } From 7b4a2b9e64a91e6951e537aaa49b5a76351c52de Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Sun, 20 Dec 2020 14:18:03 +0300 Subject: [PATCH 03/14] no message --- .../src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt | 2 +- ios/gpx.gpx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt index 30f57dde..924bda91 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt @@ -2,7 +2,7 @@ package com.cloud.diplomaticquarterapp.utils class API { companion object{ - private val BASE = "https://uat.hmgwebservices.com" + private val BASE = "https://hmgwebservices.com" private val SERVICE = "Services/Patients.svc/REST" val WIFI_CREDENTIALS = "$BASE/$SERVICE/Hmg_SMS_Get_By_ProjectID_And_PatientID" diff --git a/ios/gpx.gpx b/ios/gpx.gpx index 6121e536..ed8e9be6 100644 --- a/ios/gpx.gpx +++ b/ios/gpx.gpx @@ -1 +1 @@ - Sverrir Sigmundarson 617.71 620.95 643.70 677.84 \ No newline at end of file + Sverrir Sigmundarson 608.26 620.97 617.77 643.86 \ No newline at end of file From a11d93332d6a77fabc5eff95327b6d0e7d9b4492 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Mon, 21 Dec 2020 17:19:40 +0300 Subject: [PATCH 04/14] Wifi check network available - android tweaking at geofence code --- android/app/src/main/AndroidManifest.xml | 9 +++-- .../geofence/HMG_Geofence.kt | 1 + .../GeofenceBroadcastReceiver.kt | 4 +- ...eofenceBroadcastReceiverWithJobService.kt} | 4 +- .../GeofenceErrorMessages.kt | 2 +- .../GeofenceJobIntentService.kt | 29 ++++++++++++++ .../GeofenceTransitionsJobIntentService.kt | 12 ++---- .../GeofencingRebootBroadcastReceiver.kt | 9 ++--- .../diplomaticquarterapp/utils/HMGUtils.kt | 6 +-- ios/Flutter/.last_build_id | 2 +- ios/Runner/AppDelegate.swift | 14 +++++++ ios/Runner/Helper/Extensions.swift | 8 ++++ ios/Runner/Helper/GlobalHelper.swift | 36 ++++++++++------- ios/Runner/Helper/HMG_Geofence.swift | 40 +++++++------------ lib/uitl/HMGNetworkConnectivity.dart | 34 ++++++++++------ 15 files changed, 133 insertions(+), 77 deletions(-) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofenceBroadcastReceiver.kt (82%) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{GeofenceBroadcastReceiverWithService.kt => intent_receivers/GeofenceBroadcastReceiverWithJobService.kt} (63%) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofenceErrorMessages.kt (94%) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofenceTransitionsJobIntentService.kt (87%) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofencingRebootBroadcastReceiver.kt (73%) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c114b44d..68975071 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -76,11 +76,12 @@ - - - + + + - + + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt index 24639c6c..919d478f 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -8,6 +8,7 @@ import android.content.SharedPreferences import android.content.pm.PackageManager import android.location.Location import androidx.core.content.ContextCompat +import com.cloud.diplomaticquarterapp.geofence.intent_receivers.GeofenceBroadcastReceiver import com.cloud.diplomaticquarterapp.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt similarity index 82% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt index f8a861bb..11fc4850 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt @@ -1,11 +1,13 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.utils.saveLog import com.google.android.gms.location.GeofencingEvent diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt similarity index 63% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt index 0332f745..250040f6 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt @@ -1,12 +1,12 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -class GeofenceBroadcastReceiverWithService : BroadcastReceiver() { +class GeofenceBroadcastReceiverWithJobService : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { GeofenceTransitionsJobIntentService.enqueueWork(context, intent) } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt similarity index 94% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 4890f7cb..74a88f87 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -1,6 +1,6 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt new file mode 100644 index 00000000..84d3f230 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt @@ -0,0 +1,29 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.Intent +import android.util.Log +import androidx.core.app.JobIntentService +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofencingEvent + +class GeofenceJobIntentService : JobIntentService(){ + + private val LOG_TAG = "GeofenceBroadcastReceiver" + override fun onHandleWork(intent: Intent) { + + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) + saveLog(this, LOG_TAG,errorMessage) + return + } + + HMG_Geofence.shared(this).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)) + } + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt similarity index 87% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index 18ee92d9..2be216a1 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -29,22 +29,16 @@ */ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import android.content.Intent -import android.location.Location import android.util.Log import androidx.core.app.JobIntentService -import com.cloud.diplomaticquarterapp.utils.API -import com.cloud.diplomaticquarterapp.utils.httpPost -import com.cloud.diplomaticquarterapp.utils.sendNotification -import com.github.kittinunf.fuel.core.extensions.jsonBody -import com.github.kittinunf.fuel.core.isSuccessful -import com.github.kittinunf.fuel.httpPost +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingEvent -import com.google.gson.Gson class GeofenceTransitionsJobIntentService : JobIntentService() { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt similarity index 73% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index 4534b08f..e1eda3b9 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -1,20 +1,19 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import android.os.Handler -import android.os.Message import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.utils.HMGUtils class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { -// if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { - if (intent.action.equals("android.intent.action.BOOT_COMPLETE")) { + if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { +// if (intent.action.equals("android.intent.action.BOOT_COMPLETE")) { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("REBOOT_DETECTED","YES").apply() diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index 413e8c09..0dc0234c 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -126,7 +126,7 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, .addNextIntent(intent) 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 + ".geofence") .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(notificationPendingIntent) .setAutoCancel(true) @@ -154,9 +154,9 @@ fun isJSONValid(jsonString: String?): Boolean { fun saveLog(context:Context, tag:String, message:String){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - var logs = pref.getString("GEO_LOGS","") + var logs = pref.getString("GEOFENCE_LOGS","") logs += "$tag -> $message \n" - pref.edit().putString("PLATFORM_LOGS", logs).apply(); + pref.edit().putString("GEOFENCE_LOGS", logs).apply(); } class HTTPResponse(data: T){ diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index 3aa2cd1e..a7923797 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -3f3d14a0ae775b56806906c2cb14a1f0 \ No newline at end of file +d9d141e787a8aa802f90b776d75f04fc \ No newline at end of file diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index a9252ee5..d8f4c0c7 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,6 +2,7 @@ import UIKit import Flutter import GoogleMaps +var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -12,6 +13,7 @@ import GoogleMaps GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") GeneratedPluginRegistrant.register(with: self) + if let mainViewController = window.rootViewController as? MainFlutterVC{ HMGPlatformBridge.initialize(flutterViewController: mainViewController) } @@ -20,6 +22,18 @@ import GoogleMaps HMG_Geofence.initGeofencing() } + UNUserNotificationCenter.current().delegate = self + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } + +extension AppDelegate{ + override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + if (notification.request.content.categoryIdentifier == HmgLocalNotificationCategoryIdentifier){ + completionHandler([.alert,.sound]) + }else{ + super.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler) + } + } +} diff --git a/ios/Runner/Helper/Extensions.swift b/ios/Runner/Helper/Extensions.swift index 5c1de7c3..de67f9b9 100644 --- a/ios/Runner/Helper/Extensions.swift +++ b/ios/Runner/Helper/Extensions.swift @@ -18,6 +18,14 @@ extension String{ } } +extension Date{ + func toString(format:String) -> String{ + let df = DateFormatter() + df.dateFormat = format + return df.string(from: self) + } +} + extension Dictionary{ func merge(dict:[String:Any?]) -> [String:Any?]{ var self_ = self as! [String:Any?] diff --git a/ios/Runner/Helper/GlobalHelper.swift b/ios/Runner/Helper/GlobalHelper.swift index 35f89991..2e323a2a 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -31,20 +31,26 @@ func dictionary(from:String) -> [String:Any]?{ } -func showNotification(identifier:String? = nil, title:String?, subtitle:String?, message:String?, sound:UNNotificationSound = UNNotificationSound.default){ - let notificationContent = UNMutableNotificationContent() - - if identifier != nil { notificationContent.categoryIdentifier = identifier! } - if title != nil { notificationContent.title = title! } - if subtitle != nil { notificationContent.body = message! } - if message != nil { notificationContent.subtitle = subtitle! } - - notificationContent.sound = UNNotificationSound.default - let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) - let request = UNNotificationRequest(identifier: "\(Date().timeIntervalSinceNow)", content: notificationContent, trigger: trigger) - UNUserNotificationCenter.current().add(request) { error in - if let error = error { - print("Error: \(error)") +let HmgLocalNotificationCategoryIdentifier = "hmg.local.notification" +func showNotification(identifier:String? = nil, title:String?, subtitle:String?, message:String?, sound:UNNotificationSound = UNNotificationSound.default, categoryIdentifier:String = HmgLocalNotificationCategoryIdentifier){ + DispatchQueue.main.async { + let notificationContent = UNMutableNotificationContent() + notificationContent.categoryIdentifier = categoryIdentifier + + if identifier != nil { notificationContent.categoryIdentifier = identifier! } + if title != nil { notificationContent.title = title! } + if subtitle != nil { notificationContent.body = message! } + if message != nil { notificationContent.subtitle = subtitle! } + + notificationContent.sound = UNNotificationSound.default + let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) + let request = UNNotificationRequest(identifier: "\(Date().timeIntervalSinceNow)", content: notificationContent, trigger: trigger) + + + UNUserNotificationCenter.current().add(request) { error in + if let error = error { + print("Error: \(error)") + } } } } @@ -103,6 +109,8 @@ func httpPostRequest(urlString:String, jsonBody:[String:Any?], completion:((Bool completion?(false,responseJSON) } + }else{ + completion?(false,nil) } } diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index 3299fa1a..47454d3e 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -129,8 +129,10 @@ extension HMG_Geofence : CLLocationManagerDelegate{ extension HMG_Geofence{ func handleEvent(for region: CLRegion!, transition:Transition, location:CLLocation?) { - notifyUser(forRegion: region, transition: transition, location: locationManager.location) - notifyServer(forRegion: region, transition: transition, location: locationManager.location) + if let userProfile = userProfile(){ + notifyUser(forRegion: region, transition: transition, location: locationManager.location, userProfile: userProfile) + notifyServer(forRegion: region, transition: transition, location: locationManager.location, userProfile: userProfile) + } } func geoZone(by id: String) -> GeoZoneModel? { @@ -144,25 +146,14 @@ extension HMG_Geofence{ } - func notifyUser(forRegion:CLRegion, transition:Transition, location:CLLocation?){ - if let zone = geoZone(by: forRegion.identifier){ - if UIApplication.shared.applicationState == .active { - mainViewController.showAlert(withTitle: transition.name(), message: zone.message()) - }else{ - - } + func notifyUser(forRegion:CLRegion, transition:Transition, location:CLLocation?, userProfile:[String:Any?]){ + if let patientId = userProfile["PatientID"] as? Int{ + } } - func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ - df.dateFormat = "MMM/dd/yyyy hh:mm:ss" - var userInfo = UserDefaults.standard.string(forKey: "flutter.imei-user-data") - if(userInfo == nil){ - userInfo = UserDefaults.standard.string(forKey: "flutter.user-profile") - } - - if let userProfile = userProfile(), - let patientId = userProfile["PatientID"] as? Int{ + func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?, userProfile:[String:Any?]){ + if let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ let body:[String:Any] = [ @@ -170,19 +161,18 @@ extension HMG_Geofence{ "GeoType":transition.rawValue, "PatientID":patientId ] + + var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "GEOFENCE_LOGS") ?? [:] + var geo = (logs[forRegion.identifier] as? [String]) ?? [] let url = "https://hmgwebservices.com/Services/Patients.svc/REST/GeoF_InsertPatientFileInfo" httpPostRequest(urlString: url, jsonBody: body){ (status,json) in - let status_ = status ? "Notified" : "Not notified" + let status_ = status ? "Notified successfully:" : "Failed to notify:" showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_) - var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "GEOFENCE_LOGS") ?? [:] - if var geo = logs[forRegion.identifier] as? [String]{ - geo.append("\(status_) at \(df.string(from: Date()))") - }else{ - logs.updateValue(["\(status_) at \(df.string(from: Date()))"], forKey: forRegion.identifier) - } + geo.append("\(status_) \(transition.name()) at \(Date().toString(format: "dd/MMM/yyy hh:mm:ss"))") + logs.updateValue( geo, forKey: forRegion.identifier) UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "GEOFENCE_LOGS") } diff --git a/lib/uitl/HMGNetworkConnectivity.dart b/lib/uitl/HMGNetworkConnectivity.dart index 228edf93..c4044573 100644 --- a/lib/uitl/HMGNetworkConnectivity.dart +++ b/lib/uitl/HMGNetworkConnectivity.dart @@ -47,18 +47,28 @@ class HMGNetworkConnectivity { void confirmFromUser() { TranslationBase translator = TranslationBase.of(context); - ConfirmDialog( - context: context, - confirmMessage: translator.wantToConnectWithHmgNetwork, - okText: translator.yes, - okFunction: () { - ConfirmDialog.closeAlertDialog(context); - callBack(); - }, - cancelText: translator.no, - cancelFunction: () { - ConfirmDialog.closeAlertDialog(context); - }).showAlertDialog(context); + + void doIt() { + ConfirmDialog( + context: context, + confirmMessage: translator.wantToConnectWithHmgNetwork, + okText: translator.yes, + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + callBack(); + }, + cancelText: translator.no, + cancelFunction: () { + ConfirmDialog.closeAlertDialog(context); + }).showAlertDialog(context); + } + + if (Platform.isAndroid) + Wifi.list(SSID).then((value) { + if (!value.indexWhere((element) => element.ssid == SSID).isNegative) doIt(); + }); + else + doIt(); } void showFailDailog(String message) { From 187d2bcd8b6e61a6febf185fc3d7fe46a66c8a9a Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Mon, 21 Dec 2020 18:01:13 +0300 Subject: [PATCH 05/14] Geofence error logging in shared_preferences --- .../intent_receivers/GeofenceErrorMessages.kt | 13 ++++++++++++- android/app/src/main/res/values/strings.xml | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 74a88f87..08d5ba62 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -4,6 +4,7 @@ package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R +import com.cloud.diplomaticquarterapp.utils.saveLog import com.google.android.gms.common.api.ApiException import com.google.android.gms.location.GeofenceStatusCodes @@ -18,7 +19,7 @@ object GeofenceErrorMessages { fun getErrorString(context: Context, errorCode: Int): String { val resources = context.resources - return when (errorCode) { + val errorMessage = when (errorCode) { GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE -> resources.getString(R.string.geofence_not_available) @@ -28,7 +29,17 @@ object GeofenceErrorMessages { GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS -> resources.getString(R.string.geofence_too_many_pending_intents) + GeofenceStatusCodes.GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION -> + resources.getString(R.string.GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION) + + GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT -> + resources.getString(R.string.GEOFENCE_REQUEST_TOO_FREQUENT) + else -> resources.getString(R.string.geofence_unknown_error) } + + saveLog(context,"GeofenceErrorMessages","$errorCode | $errorMessage") + + return errorMessage } } \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 8acc0c12..4e107030 100755 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -13,4 +13,10 @@ You have provided too many PendingIntents to the addGeofences() call. + + App do not have permission to access location service. + + + Geofence requests happened too frequently. + From 3392a2431b8e9d5deb12e82ccd4a64af92aa68e0 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Mon, 21 Dec 2020 18:42:50 +0300 Subject: [PATCH 06/14] Added Location Provider Changed Receiver to Reregister the geofences --- android/app/src/main/AndroidManifest.xml | 6 +++- .../LocationProviderChangeReceiver.kt | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 68975071..649af435 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -81,7 +81,11 @@ - + + + + + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt new file mode 100644 index 00000000..9de0cd6f --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt @@ -0,0 +1,32 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.location.LocationManager +import android.util.Log +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE +import com.cloud.diplomaticquarterapp.utils.HMGUtils +import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofencingEvent + +class LocationProviderChangeReceiver : BroadcastReceiver() { + private val LOG_TAG = "LocationProviderChangeReceiver" + override fun onReceive(context: Context, intent: Intent) { + + if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.action)) { + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + pref.edit().putString("LOCATION_PROVIDER_CHANGE","YES").apply() + + HMG_Geofence.shared(context).unRegisterAll { status, exception -> + val geoZones = HMGUtils.getGeoZonesFromPreference(context) + HMG_Geofence.shared(context).register(geoZones) + } + } + } + +} \ No newline at end of file From 57925e3b02c9bb2f565150c94e5a39ddf8511783 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Thu, 24 Dec 2020 18:01:32 +0300 Subject: [PATCH 07/14] Geofence fixes by JobScheduler --- android/app/src/main/AndroidManifest.xml | 3 + .../diplomaticquarterapp/MainActivity.kt | 13 +- .../geofence/GeoZoneModel.kt | 6 +- .../geofence/HMG_Geofence.kt | 74 ++++++--- .../GeofenceBroadcastReceiver.kt | 22 ++- ...GeofenceBroadcastReceiverWithJobService.kt | 3 + .../intent_receivers/GeofenceErrorMessages.kt | 4 +- .../GeofenceJobIntentService.kt | 29 ---- .../GeofenceTransitionsJobIntentService.kt | 32 +++- .../GeofencingRebootBroadcastReceiver.kt | 6 +- .../ReregisterGeofenceJobService.kt | 23 +++ .../diplomaticquarterapp/utils/HMGUtils.kt | 84 +++++++--- .../cloud/diplomaticquarterapp/utils/Logs.kt | 146 ++++++++++++++++++ ios/Flutter/.last_build_id | 2 +- ios/Runner.xcodeproj/project.pbxproj | 4 + ios/Runner/AppDelegate.swift | 39 ++++- ios/Runner/Helper/API.swift | 7 +- ios/Runner/Helper/FlutterConstants.swift | 36 +++++ ios/Runner/Helper/GlobalHelper.swift | 2 +- ios/Runner/Helper/HMGPlatformBridge.swift | 3 + lib/config/config.dart | 6 +- 21 files changed, 442 insertions(+), 102 deletions(-) delete mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt create mode 100644 ios/Runner/Helper/FlutterConstants.swift diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 649af435..79bc3dc4 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -81,6 +81,7 @@ + @@ -88,6 +89,8 @@ + + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt index 8b73b0c7..e67f646f 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt @@ -2,8 +2,7 @@ package com.cloud.diplomaticquarterapp import android.os.Bundle import android.util.Log import androidx.annotation.NonNull; -import com.cloud.diplomaticquarterapp.utils.FlutterText -import com.cloud.diplomaticquarterapp.utils.PlatformBridge +import com.cloud.diplomaticquarterapp.utils.* import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel @@ -15,6 +14,16 @@ class MainActivity: FlutterFragmentActivity() { // Create Flutter Platform Bridge PlatformBridge(flutterEngine.dartExecutor.binaryMessenger, this).create() + val time = timeToMillis("04:00:00", "HH:mm:ss") + print(time) + +// val d1 = Logs.list(this) +// val d2 = Logs.raw(this) +// val d3 = Logs.RegisterGeofence.list(this) +// val d4 = Logs.RegisterGeofence.raw(this) +// val d5 = Logs.GeofenceEvent.list(this) +// val d6 = Logs.GeofenceEvent.raw(this) + print("") } override fun onResume() { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt index 328014e6..b3fb4f56 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt @@ -37,7 +37,7 @@ class GeoZoneModel { val rad = Radius.toFloat() if(lat != null && long != null){ - val loiteringDelayMinutes:Int = 5 // in Minutes + val loiteringDelayMinutes:Int = 2 // in Minutes return Geofence.Builder() .setRequestId(identifier()) .setCircularRegion( @@ -46,8 +46,8 @@ class GeoZoneModel { rad ) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) -// .setNotificationResponsiveness(0) -// .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) + .setNotificationResponsiveness(0) + .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) .setExpirationDuration(Geofence.NEVER_EXPIRE) .build() } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt index 919d478f..ba6691f7 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -9,6 +9,7 @@ import android.content.pm.PackageManager import android.location.Location import androidx.core.content.ContextCompat import com.cloud.diplomaticquarterapp.geofence.intent_receivers.GeofenceBroadcastReceiver +import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService import com.cloud.diplomaticquarterapp.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient @@ -20,8 +21,10 @@ import com.google.gson.reflect.TypeToken enum class GeofenceTransition(val value: Int) { ENTER(1), EXIT(2), + DWELL(4), + ENTER_EXIT((ENTER.value or EXIT.value)), - DWELL(4); + DWELL_EXIT((DWELL.value or EXIT.value)); companion object { fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value } @@ -30,8 +33,9 @@ enum class GeofenceTransition(val value: Int) { fun named():String{ if (value == 1)return "Enter" if (value == 2)return "Exit" - if (value == (ENTER.value or EXIT.value))return "Enter or Exit" if (value == 4)return "dWell" + if (value == (ENTER.value or EXIT.value))return "Enter or Exit" + if (value == (DWELL.value or EXIT.value))return "DWell or Exit" return "unknown" } } @@ -73,13 +77,22 @@ class HMG_Geofence { } } + fun limitize(zones: List):List{ + var geoZones_ = zones + if(zones.size > 100) + geoZones_ = zones.subList(0, 99) + return geoZones_ + } + fun register(geoZones: List){ if (geoZones.isEmpty()) return + var geoZones_ = limitize(geoZones) + fun buildGeofencingRequest(geofences: List): GeofencingRequest { return GeofencingRequest.Builder() - .setInitialTrigger(0) + .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL) .addGeofences(geofences) .build() } @@ -87,9 +100,9 @@ class HMG_Geofence { getActiveGeofences({ active -> val geofences = mutableListOf() - geoZones.forEach { - it.toGeofence()?.let { geof -> - if(!active.contains(geof.requestId)){ // if not already registered then register + geoZones_.forEach { + it.toGeofence()?.let { geof -> + if (!active.contains(geof.requestId)) { // if not already registered then register geofences.add(geof) } } @@ -99,19 +112,25 @@ class HMG_Geofence { geofencingClient .addGeofences(buildGeofencingRequest(geofences), geofencePendingIntent) .addOnSuccessListener { + Logs.RegisterGeofence.save(context,"SUCCESS", "Successfuly registered the geofences", Logs.STATUS.SUCCESS) saveActiveGeofence(geofences.map { it.requestId }, listOf()) } .addOnFailureListener { - print(it.localizedMessage) - saveLog(context,"error:ADD_GEOFENCES", it.localizedMessage) + Logs.RegisterGeofence.save(context,"FAILED_TO_REGISTER", "Failed to register geofence",Logs.STATUS.ERROR) } + + // Schedule the job to register after specified duration (due to: events not calling after long period.. days or days [Needs to register fences again]) + HMGUtils.scheduleJob(context, ReregisterGeofenceJobService::class.java,ReregisterGeofenceJobService.JobID, ReregisterGeofenceJobService.TriggerIntervalMillis) } - },null) + + }, null) + } - fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ + fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ getActiveGeofences({ success -> val mList = success.toMutableList() + removeActiveGeofences() geofencingClient .removeGeofences(success) .addOnSuccessListener { @@ -119,14 +138,20 @@ class HMG_Geofence { } .addOnFailureListener { completion(false, it) - saveLog(context,"error:REMOVE_GEOFENCES", it.localizedMessage) + saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) } - removeActiveGeofences() }, { failed -> // Nothing to do with failed geofences. }) } + fun reRegister(){ + unRegisterAll { status, exception -> + val geoZones = HMGUtils.getGeoZonesFromPreference(context) + register(geoZones) + } + } + fun saveActiveGeofence(success: List, failed: List){ val jsonSuccess = gson.toJson(success) val jsonFailure = gson.toJson(failed) @@ -135,8 +160,8 @@ class HMG_Geofence { } fun removeActiveGeofences(){ - preferences.edit().putString(PREF_KEY_SUCCESS,"[]").apply() - preferences.edit().putString(PREF_KEY_FAILED,"[]").apply() + preferences.edit().putString(PREF_KEY_SUCCESS, "[]").apply() + preferences.edit().putString(PREF_KEY_FAILED, "[]").apply() } fun getActiveGeofences(success: (success: List) -> Unit, failure: ((failed: List) -> Unit)?){ @@ -164,7 +189,7 @@ class HMG_Geofence { profileJson = preferences.getString("flutter.user-profile", null) val type = object : TypeToken?>() {}.type - return gson.fromJson?>(profileJson,type) + return gson.fromJson?>(profileJson, type) ?.get("PatientID") .toString() .toDoubleOrNull() @@ -172,32 +197,35 @@ class HMG_Geofence { } - fun handleEvent(triggerGeofences: List, location: Location, transition:GeofenceTransition) { + fun handleEvent(triggerGeofences: List, location: Location, transition: GeofenceTransition) { getPatientID()?.let { patientId -> getActiveGeofences({ activeGeofences -> triggerGeofences.forEach { geofence -> // Extract PointID from 'geofence.requestId' and find from active geofences - val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first() - if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){ + val pointID = activeGeofences.firstOrNull { it == geofence.requestId }?.split('_')?.first() + if (!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null) { - val body = mutableMapOf( + val body = mutableMapOf( "PointsID" to pointID.toIntOrNull(), "GeoType" to transition.value, "PatientID" to patientId ) body.putAll(HMGUtils.defaultHTTPParams(context)) - httpPost>(API.LOG_GEOFENCE, body, { response -> + httpPost>(API.LOG_GEOFENCE, body, { response -> + saveLog(context, "HMG_GEOFENCE_NOTIFY", "Success: Notified to server\uD83D\uDE0E.") sendNotification(context, transition.named(), geofence.requestId, "Notified to server.😎") - },{ exception -> - sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server.😔") + }, { exception -> + val errorMessage = "${transition.named()}, ${geofence.requestId}" + saveLog(context, "HMG_GEOFENCE_NOTIFY", "failed: $errorMessage | error: ${exception.localizedMessage}") + sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server😔 -> ${exception.localizedMessage}") }) } } - },null) + }, null) } } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt index 11fc4850..80ef2c96 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt @@ -8,7 +8,9 @@ import android.content.Intent import android.util.Log import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.Logs import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent class GeofenceBroadcastReceiver : BroadcastReceiver() { @@ -19,12 +21,28 @@ class GeofenceBroadcastReceiver : BroadcastReceiver() { if (geofencingEvent.hasError()) { val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) Log.e(LOG_TAG, errorMessage) - saveLog(context,LOG_TAG,errorMessage) + + Logs.GeofenceEvent.save(context,LOG_TAG,"Error while triggering geofence event",Logs.STATUS.ERROR) + doReRegisterIfRequired(context,geofencingEvent.errorCode) + return } - + + Logs.GeofenceEvent.save(context,LOG_TAG,"Geofence event triggered: ${GeofenceTransition.fromInt(geofencingEvent.geofenceTransition).value} for ${geofencingEvent.triggeringGeofences.map {it.requestId}}",Logs.STATUS.SUCCESS) HMG_Geofence.shared(context).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); } + fun doReRegisterIfRequired(context: Context, errorCode: Int){ + val errorRequiredReregister = listOf( + GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, + GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT + ) + + if(errorRequiredReregister.contains(errorCode)) + HMG_Geofence.shared(context).reRegister() + + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt index 250040f6..a9924ca1 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt @@ -5,9 +5,12 @@ package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.google.android.gms.location.GeofenceStatusCodes class GeofenceBroadcastReceiverWithJobService : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { GeofenceTransitionsJobIntentService.enqueueWork(context, intent) } + } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 08d5ba62..01377d49 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -4,7 +4,7 @@ package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R -import com.cloud.diplomaticquarterapp.utils.saveLog +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.google.android.gms.common.api.ApiException import com.google.android.gms.location.GeofenceStatusCodes @@ -38,8 +38,6 @@ object GeofenceErrorMessages { else -> resources.getString(R.string.geofence_unknown_error) } - saveLog(context,"GeofenceErrorMessages","$errorCode | $errorMessage") - return errorMessage } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt deleted file mode 100644 index 84d3f230..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt +++ /dev/null @@ -1,29 +0,0 @@ - - -package com.cloud.diplomaticquarterapp.geofence.intent_receivers - -import android.content.Intent -import android.util.Log -import androidx.core.app.JobIntentService -import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition -import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.saveLog -import com.google.android.gms.location.GeofencingEvent - -class GeofenceJobIntentService : JobIntentService(){ - - private val LOG_TAG = "GeofenceBroadcastReceiver" - override fun onHandleWork(intent: Intent) { - - val geofencingEvent = GeofencingEvent.fromIntent(intent) - if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) - Log.e(LOG_TAG, errorMessage) - saveLog(this, LOG_TAG,errorMessage) - return - } - - HMG_Geofence.shared(this).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)) - } - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index 2be216a1..c008c0a5 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -37,7 +37,9 @@ import android.util.Log import androidx.core.app.JobIntentService import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.saveLog import com.google.android.gms.location.Geofence +import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent class GeofenceTransitionsJobIntentService : JobIntentService() { @@ -45,7 +47,7 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { companion object { private const val LOG_TAG = "GeoTrIntentService" - private const val JOB_ID = 573 + private const val JOB_ID = 95902 var context_: Context? = null fun enqueueWork(context: Context, intent: Intent) { context_ = context @@ -59,15 +61,31 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { override fun onHandleWork(intent: Intent) { val geofencingEvent = GeofencingEvent.fromIntent(intent) if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) + val errorMessage = GeofenceErrorMessages.getErrorString(context_!!, geofencingEvent.errorCode) Log.e(LOG_TAG, errorMessage) + + + saveLog(context_!!,LOG_TAG,errorMessage) + doReRegisterIfRequired(context_!!, geofencingEvent.errorCode) + return } - if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { - context_?.let { - HMG_Geofence.shared(it).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); - } - } + HMG_Geofence.shared(context_!!).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + + } + + + fun doReRegisterIfRequired(context: Context, errorCode: Int){ + val errorRequiredReregister = listOf( + GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, + GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT + ) + + if(errorRequiredReregister.contains(errorCode)) + HMG_Geofence.shared(context).reRegister() + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index e1eda3b9..0663db3b 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.Intent import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE -import com.cloud.diplomaticquarterapp.utils.HMGUtils class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { @@ -17,10 +16,7 @@ class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("REBOOT_DETECTED","YES").apply() - HMG_Geofence.shared(context).unRegisterAll { status, exception -> - val geoZones = HMGUtils.getGeoZonesFromPreference(context) - HMG_Geofence.shared(context).register(geoZones) - } + HMG_Geofence.shared(context).reRegister() } } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt new file mode 100644 index 00000000..043c5c96 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt @@ -0,0 +1,23 @@ +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.app.job.JobParameters +import android.app.job.JobService +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.Logs +import com.cloud.diplomaticquarterapp.utils.timeToMillis + +class ReregisterGeofenceJobService : JobService(){ + companion object{ + val TriggerIntervalMillis:String = "24:00:00" + val JobID = 918273 + } + override fun onStartJob(params: JobParameters?): Boolean { + HMG_Geofence.shared(applicationContext).reRegister() + Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalMillis >> [HH:mm:ss]") + return true + } + + override fun onStopJob(params: JobParameters?): Boolean { + return true + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index 0dc0234c..7880a7ef 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -3,11 +3,15 @@ package com.cloud.diplomaticquarterapp.utils import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent +import android.app.job.JobInfo +import android.app.job.JobScheduler +import android.content.ComponentName import android.content.Context import android.content.Intent import android.os.Build import android.widget.Toast import androidx.annotation.Nullable +import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat import androidx.core.app.TaskStackBuilder import com.cloud.diplomaticquarterapp.BuildConfig @@ -17,15 +21,17 @@ import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE +import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost -import com.google.android.gms.location.Geofence import com.google.gson.Gson import com.google.gson.reflect.TypeToken import io.flutter.plugin.common.MethodChannel +import org.jetbrains.anko.doAsyncResult import org.json.JSONArray import org.json.JSONException import org.json.JSONObject +import java.text.SimpleDateFormat import java.util.* import kotlin.concurrent.timerTask @@ -71,7 +77,7 @@ class HMGUtils { fun getGeoZonesFromPreference(context: Context):List{ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val json = pref.getString(PREF_KEY_HMG_ZONES,"[]") + val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") val geoZones = GeoZoneModel().listFrom(json) return geoZones @@ -79,14 +85,14 @@ class HMGUtils { fun getLanguageCode(context: Context) : Int{ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val lang = pref.getString(PREF_KEY_LANGUAGE,"ar") + val lang = pref.getString(PREF_KEY_LANGUAGE, "ar") return if(lang == "ar") 2 else 1 } - fun defaultHTTPParams(context: Context) : Map{ + fun defaultHTTPParams(context: Context) : Map{ return mapOf( "ZipCode" to "966", - "VersionID" to 5.6, + "VersionID" to 5.8, "Channel" to 3, "LanguageID" to getLanguageCode(context), "IPAdress" to "10.20.10.20", @@ -97,16 +103,44 @@ class HMGUtils { "DeviceTypeID" to 2) } + + fun scheduleJob(context: Context, pendingIntentClassType:Class, jobId:Int, intervalDuration:String, deadlineMillis:Long = (30 * 1000)) { // default deadline: 30 Seconds + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + val jobScheduler: JobScheduler = context.getSystemService(JobScheduler::class.java) + + val serviceComponent = ComponentName(context, pendingIntentClassType) + val builder = JobInfo.Builder(jobId, serviceComponent) + builder.setPersisted(true) + + val intervalMillis = timeToMillis(intervalDuration,"HH:mm:ss") + builder.setMinimumLatency(intervalMillis) // wait at least + builder.setOverrideDeadline((intervalMillis + deadlineMillis)) // maximum delay + if (jobScheduler.schedule(builder.build()) == JobScheduler.RESULT_SUCCESS){ + Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Job scheduled to trigger after duration $intervalDuration >> HH:mm:ss --('MinimumLatency:$intervalMillis Deadline:${(intervalMillis + deadlineMillis)}')--",Logs.STATUS.SUCCESS) + }else{ + Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job",Logs.STATUS.ERROR) + } + + } else { + Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job on VERSION.SDK_INT < ${android.os.Build.VERSION_CODES.M}",Logs.STATUS.ERROR) + } + } + } } -private fun Timer.schedule(timerTask: TimerTask) { -} private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel" -fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, message:String?) { + +fun timeToMillis(time:String, format:String):Long{ + val sdf = SimpleDateFormat(format, Locale.US) + val millis = sdf.parse(time).time + TimeZone.getDefault().rawOffset + return millis +} + +fun sendNotification(context: Context, title: String, @Nullable subtitle: String?, message: String?) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O @@ -126,7 +160,7 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, .addNextIntent(intent) val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) - val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID + ".geofence") + val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(notificationPendingIntent) .setAutoCancel(true) @@ -141,7 +175,15 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, //------------------------- // Open Helper Methods //------------------------- -private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) +fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) + +object DateUtils { + @JvmStatic + fun dateTimeNow() : String { + val format = SimpleDateFormat("dd-MMM-yyy hh:mm:ss") + return format.format(Date()) + } +} fun isJSONValid(jsonString: String?): Boolean { try { JSONObject(jsonString) } catch (ex: JSONException) { @@ -152,11 +194,16 @@ fun isJSONValid(jsonString: String?): Boolean { return true } -fun saveLog(context:Context, tag:String, message:String){ +fun saveLog(context: Context, tag: String, message: String){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - var logs = pref.getString("GEOFENCE_LOGS","") + var logs = pref.getString("LOGS", "") logs += "$tag -> $message \n" - pref.edit().putString("GEOFENCE_LOGS", logs).apply(); + pref.edit().putString("LOGS", logs).apply(); +} + +fun getLogs(context: Context) : String?{ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + return pref.getString("LOGS", "") } class HTTPResponse(data: T){ @@ -170,15 +217,16 @@ fun httpPost(url: String, body: Map, onSuccess: (response: HTTP url.httpPost() .jsonBody(jsonBody, Charsets.UTF_8) .timeout(10000) - .header("Content-Type","application/json") - .header("Allow","*/*") + .header("Content-Type", "application/json") + .header("Allow", "*/*") .response { request, response, result -> + result.doAsyncResult { } result.fold({ data -> val dataString = String(data) - if(isJSONValid(dataString)){ - val responseData = gson.fromJson(dataString,type) + if (isJSONValid(dataString)) { + val responseData = gson.fromJson(dataString, type) onSuccess(HTTPResponse(responseData)) - }else{ + } else { onError(Exception("Invalid response from server (Not a valid JSON)")) } }, { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt new file mode 100644 index 00000000..5c11943e --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt @@ -0,0 +1,146 @@ +package com.cloud.diplomaticquarterapp.utils + +import android.content.Context +import android.content.SharedPreferences +import android.os.Build +import com.cloud.diplomaticquarterapp.BuildConfig +import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE +import com.google.gson.Gson + +class Logs { + + enum class STATUS{ + SUCCESS, + ERROR; + } + class GeofenceEvent{ + companion object{ + fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + Logs.Common.save(context,"GeofenceEvent", tag, message, status) + } + + fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ + return Logs.Common.list(context,"GeofenceEvent", tag, status) + } + + fun raw(context: Context):String{ + return Logs.Common.raw(context,"GeofenceEvent") + } + } + } + + class RegisterGeofence{ + companion object{ + fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + Logs.Common.save(context,"RegisterGeofence", tag, message, status) + } + + fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ + return Logs.Common.list(context,"RegisterGeofence", tag, status) + } + + fun raw(context: Context):String{ + return Logs.Common.raw(context,"RegisterGeofence"); + } + } + } + + + companion object{ + private var pref:SharedPreferences? = null + fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + Logs.Common.save(context,"Logs", tag, message, status) + } + + fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ + return Logs.Common.list(context,"Logs", tag, status) + } + + fun raw(context: Context):String{ + return Logs.Common.raw(context,"Logs"); + } + + private fun storage(context: Context):SharedPreferences{ + if(pref == null) { + pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + } + return pref!! + } + } + + private class Common{ + companion object{ + private val gson = Gson() + + fun save(context: Context, key:String, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + if(!BuildConfig.DEBUG) + return + + val pref = Logs.storage(context) + + val string = pref.getString(key,"{}") + val json = gson.fromJson(string,LogsContainerModel::class.java) + json.add( + LogModel().apply { + this.TAG = tag + this.MESSAGE = message + this.STATUS = status.name + this.DATE = DateUtils.dateTimeNow() + } + ) + + pref.edit().putString(key,gson.toJson(json)).apply() + } + + fun list(context: Context, key:String, tag:String? = null, status:Logs.STATUS? = null):List{ + val pref = Logs.storage(context) + val string = pref.getString(key,"{}") + val json = gson.fromJson(string,LogsContainerModel::class.java) + if(tag == null && status == null) { + return json.LOGS + }else if(tag != null && status != null){ + return json.LOGS.filter { (it.TAG == tag && it.STATUS == status.name) } + }else if(tag != null){ + return json.LOGS.filter { (it.TAG == tag) } + }else if(status != null){ + return json.LOGS.filter { (it.STATUS == status.name) } + } + return listOf() + } + + fun raw(context: Context, key:String):String{ + val pref = Logs.storage(context) + val string = pref.getString(key,"{}") + return string!! + } + + } + } + + class LogModel{ + lateinit var TAG:String + lateinit var MESSAGE:String + lateinit var STATUS:String + lateinit var DATE:String + + companion object{ + fun with(tag:String, message:String, status:String):LogModel{ + return LogModel().apply { + this.TAG = tag + this.MESSAGE = message + this.STATUS = status + this.DATE = DateUtils.dateTimeNow() + } + } + } + } + + class LogsContainerModel{ + var LOGS = mutableListOf() + fun add(log:LogModel){ + LOGS.add(log) + } + } + + +} \ No newline at end of file diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index a7923797..4e1980a7 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -d9d141e787a8aa802f90b776d75f04fc \ No newline at end of file +e7c24319209ad9049a87d4c83aeeb7de \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 77d42044..8ef5d511 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */; }; E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */; }; E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; }; + E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -82,6 +83,7 @@ E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_Guest.swift; sourceTree = ""; }; E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedFromFlutter.swift; sourceTree = ""; }; + E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterConstants.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -180,6 +182,7 @@ E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */, E923EFD3258645C100E3E751 /* HMG_Geofence.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, + E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, ); path = Helper; sourceTree = ""; @@ -378,6 +381,7 @@ E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, + E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index d8f4c0c7..2dc828d1 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -7,25 +7,39 @@ var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { let locationManager = CLLocationManager() + var flutterViewController:MainFlutterVC! override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") GeneratedPluginRegistrant.register(with: self) - - if let mainViewController = window.rootViewController as? MainFlutterVC{ - HMGPlatformBridge.initialize(flutterViewController: mainViewController) - } + initializePlatformChannel() if let _ = launchOptions?[.location] { HMG_Geofence.initGeofencing() } UNUserNotificationCenter.current().delegate = self - return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + + + func initializePlatformChannel(){ + if let mainViewController = window.rootViewController as? MainFlutterVC{ // platform initialization suppose to be in foreground + flutterViewController = mainViewController + HMGPlatformBridge.initialize(flutterViewController: flutterViewController) + + }else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background + flutterViewController = mainViewController + HMGPlatformBridge.initialize(flutterViewController: flutterViewController) + } + } + + + func initialViewController() -> MainFlutterVC?{ + return nil //UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController() as? MainFlutterVC + } } extension AppDelegate{ @@ -37,3 +51,18 @@ extension AppDelegate{ } } } + + +/* + let dart = FlutterDartProject(precompiledDartBundle: .main) + let engine = FlutterEngine(name: "com.hmg.cs", project: dart, allowHeadlessExecution: true) + if engine.run(){ + flutterMethodChannel = FlutterMethodChannel(name: "HMG-Platform-Bridge", binaryMessenger: engine.binaryMessenger) + + Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { (timer) in + FlutterText.with(key: "alreadyConnectedHmgNetwork"){ localized in + print(localized) + } + } + } + */ diff --git a/ios/Runner/Helper/API.swift b/ios/Runner/Helper/API.swift index 763147c8..b487f033 100644 --- a/ios/Runner/Helper/API.swift +++ b/ios/Runner/Helper/API.swift @@ -13,5 +13,10 @@ fileprivate let BASE_URL = "\(DOMAIN)/\(SERVICE)" struct API { static let WIFI_CREDENTIALS = "\(BASE_URL)/Hmg_SMS_Get_By_ProjectID_And_PatientID" - } + + +//struct API { +// static let WIFI_CREDENTIALS = FlutterConstants.WIFI_CREDENTIALS_URL +// static let LOG_GEOFENCE = FlutterConstants.LOG_GEOFENCE_URL +//} diff --git a/ios/Runner/Helper/FlutterConstants.swift b/ios/Runner/Helper/FlutterConstants.swift new file mode 100644 index 00000000..f1b3f098 --- /dev/null +++ b/ios/Runner/Helper/FlutterConstants.swift @@ -0,0 +1,36 @@ +// +// FlutterConstants.swift +// Runner +// +// Created by ZiKambrani on 22/12/2020. +// + +import UIKit + +class FlutterConstants{ + static var LOG_GEOFENCE_URL:String? + static var WIFI_CREDENTIALS_URL:String? + static var DEFAULT_HTTP_PARAMS:[String:Any?]? + + class func set(){ + + // (FiX) Take a start with FlutterMethodChannel (kikstart) + /* First call to flutter method is not returning the correct value (Always returning 'NSObject') then after it wroking fine and returning correct value*/ + FlutterText.with(key: "test") { (test) in + + flutterMethodChannel?.invokeMethod("getDefaultHttpParameters", arguments: nil){ (response) in + if let defaultHTTPParams = response as? [String:Any?]{ + DEFAULT_HTTP_PARAMS = defaultHTTPParams + } + + } + + flutterMethodChannel?.invokeMethod("getLogGeofenceFullUrl", arguments:nil){ (response) in + if let url = response as? String{ + LOG_GEOFENCE_URL = url + } + } + + } + } +} diff --git a/ios/Runner/Helper/GlobalHelper.swift b/ios/Runner/Helper/GlobalHelper.swift index 2e323a2a..37687806 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -70,7 +70,7 @@ func userProfile() -> [String:Any?]?{ fileprivate let defaultHTTPParams:[String : Any?] = [ "ZipCode" : "966", - "VersionID" : 5.6, + "VersionID" : 5.8, "Channel" : 3, "LanguageID" : appLanguageCode(), "IPAdress" : "10.20.10.20", diff --git a/ios/Runner/Helper/HMGPlatformBridge.swift b/ios/Runner/Helper/HMGPlatformBridge.swift index f897188c..f94f9b34 100644 --- a/ios/Runner/Helper/HMGPlatformBridge.swift +++ b/ios/Runner/Helper/HMGPlatformBridge.swift @@ -49,6 +49,9 @@ class HMGPlatformBridge{ print("") } + Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { (timer) in + FlutterConstants.set() + } } diff --git a/lib/config/config.dart b/lib/config/config.dart index 4a420ec8..10ec0b73 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -22,6 +22,9 @@ const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; +// Wifi Credentials +const WIFI_CREDENTIALS = "Services/Patients.svc/Hmg_SMS_Get_By_ProjectID_And_PatientID"; + ///Doctor const GET_MY_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; const GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles'; @@ -199,7 +202,7 @@ const UPDATE_HEALTH_TERMS = '/services/Patients.svc/REST/UpdatePateintHealthSumm const CHANNEL = 3; const GENERAL_ID = 'Cs2020@2016\$2958'; const IP_ADDRESS = '10.20.10.20'; -const VERSION_ID = 5.6; +const VERSION_ID = 5.8; const SETUP_ID = '91877'; const LANGUAGE = 2; const PATIENT_OUT_SA = 0; @@ -306,7 +309,6 @@ class AppGlobal { Request getPublicRequest() { Request request = new Request(); - request.VersionID = 5.6; //3.6; request.Channel = 3; request.IPAdress = "10.20.10.20"; request.generalid = 'Cs2020@2016\$2958'; From f03adb37ce46c6b704689a8968d021eec3dd68cc Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Sun, 27 Dec 2020 14:27:54 +0300 Subject: [PATCH 08/14] no message --- .../geofence/HMG_Geofence.kt | 76 +++++++++++-------- .../GeofenceBroadcastReceiver.kt | 5 +- .../GeofenceTransitionsJobIntentService.kt | 3 +- .../GeofencingRebootBroadcastReceiver.kt | 4 +- .../LocationProviderChangeReceiver.kt | 11 +-- .../ReregisterGeofenceJobService.kt | 9 ++- .../diplomaticquarterapp/utils/Constants.kt | 8 ++ .../diplomaticquarterapp/utils/HMGUtils.kt | 15 +--- .../cloud/diplomaticquarterapp/utils/Logs.kt | 1 - .../utils/PlatformBridge.kt | 2 +- 10 files changed, 66 insertions(+), 68 deletions(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt index ba6691f7..d2fb404a 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -40,12 +40,6 @@ enum class GeofenceTransition(val value: Int) { } } -const val PREFS_STORAGE = "FlutterSharedPreferences" -const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" -const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" -const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences" -const val PREF_KEY_LANGUAGE = "flutter.language" - class HMG_Geofence { // https://developer.android.com/training/location/geofencing#java @@ -84,11 +78,42 @@ class HMG_Geofence { return geoZones_ } - fun register(geoZones: List){ + + fun register(completion:((Boolean, java.lang.Exception?)->Unit)){ + unRegisterAll { status, exception -> + val geoZones = getGeoZonesFromPreference(context) + doRegister(geoZones){ status_, error -> + completion.let { it(status_, error) } + } + } + } + + fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ + getActiveGeofences({ success -> + removeActiveGeofences() + if(success.isNotEmpty()) + geofencingClient + .removeGeofences(success) + .addOnSuccessListener { + completion(true, null) + } + .addOnFailureListener { + completion(false, it) + saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) + } + else + completion(true, null) + + }, { failed -> + // Nothing to do with failed geofences. + }) + } + + private fun doRegister(geoZones: List, completion:((Boolean, java.lang.Exception?)->Unit)? = null){ if (geoZones.isEmpty()) return - var geoZones_ = limitize(geoZones) + val geoZones_ = limitize(geoZones) fun buildGeofencingRequest(geofences: List): GeofencingRequest { return GeofencingRequest.Builder() @@ -114,42 +139,27 @@ class HMG_Geofence { .addOnSuccessListener { Logs.RegisterGeofence.save(context,"SUCCESS", "Successfuly registered the geofences", Logs.STATUS.SUCCESS) saveActiveGeofence(geofences.map { it.requestId }, listOf()) + completion?.let { it(true,null) } } - .addOnFailureListener { + .addOnFailureListener { exc -> Logs.RegisterGeofence.save(context,"FAILED_TO_REGISTER", "Failed to register geofence",Logs.STATUS.ERROR) + completion?.let { it(false,exc) } } // Schedule the job to register after specified duration (due to: events not calling after long period.. days or days [Needs to register fences again]) - HMGUtils.scheduleJob(context, ReregisterGeofenceJobService::class.java,ReregisterGeofenceJobService.JobID, ReregisterGeofenceJobService.TriggerIntervalMillis) + HMGUtils.scheduleJob(context, ReregisterGeofenceJobService::class.java,ReregisterGeofenceJobService.JobID, ReregisterGeofenceJobService.TriggerIntervalDuration) } - + }, null) } - fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ - getActiveGeofences({ success -> - val mList = success.toMutableList() - removeActiveGeofences() - geofencingClient - .removeGeofences(success) - .addOnSuccessListener { - completion(true, null) - } - .addOnFailureListener { - completion(false, it) - saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) - } - }, { failed -> - // Nothing to do with failed geofences. - }) - } + fun getGeoZonesFromPreference(context: Context):List{ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") - fun reRegister(){ - unRegisterAll { status, exception -> - val geoZones = HMGUtils.getGeoZonesFromPreference(context) - register(geoZones) - } + val geoZones = GeoZoneModel().listFrom(json) + return geoZones } fun saveActiveGeofence(success: List, failed: List){ diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt index 80ef2c96..77df1572 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt @@ -9,7 +9,6 @@ import android.util.Log import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.utils.Logs -import com.cloud.diplomaticquarterapp.utils.saveLog import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent @@ -42,7 +41,9 @@ class GeofenceBroadcastReceiver : BroadcastReceiver() { ) if(errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).reRegister() + HMG_Geofence.shared(context).register(){ status, error -> + + } } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index c008c0a5..214957cf 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -38,7 +38,6 @@ import androidx.core.app.JobIntentService import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.utils.saveLog -import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent @@ -85,7 +84,7 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { ) if(errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).reRegister() + HMG_Geofence.shared(context).register(){ status, exc -> } } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index 0663db3b..6421b327 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -6,7 +6,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE +import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { @@ -16,7 +16,7 @@ class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("REBOOT_DETECTED","YES").apply() - HMG_Geofence.shared(context).reRegister() + HMG_Geofence.shared(context).register(){ status, error -> } } } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt index 9de0cd6f..273ca8f5 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt @@ -6,13 +6,9 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.location.LocationManager -import android.util.Log -import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.utils.HMGUtils -import com.cloud.diplomaticquarterapp.utils.saveLog -import com.google.android.gms.location.GeofencingEvent +import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE class LocationProviderChangeReceiver : BroadcastReceiver() { private val LOG_TAG = "LocationProviderChangeReceiver" @@ -22,10 +18,7 @@ class LocationProviderChangeReceiver : BroadcastReceiver() { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("LOCATION_PROVIDER_CHANGE","YES").apply() - HMG_Geofence.shared(context).unRegisterAll { status, exception -> - val geoZones = HMGUtils.getGeoZonesFromPreference(context) - HMG_Geofence.shared(context).register(geoZones) - } + HMG_Geofence.shared(context).register(){ s, e -> } } } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt index 043c5c96..0bc496bc 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt @@ -4,16 +4,17 @@ import android.app.job.JobParameters import android.app.job.JobService import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.utils.Logs -import com.cloud.diplomaticquarterapp.utils.timeToMillis class ReregisterGeofenceJobService : JobService(){ companion object{ - val TriggerIntervalMillis:String = "24:00:00" + val TriggerIntervalDuration:String = "06:00:00" val JobID = 918273 } override fun onStartJob(params: JobParameters?): Boolean { - HMG_Geofence.shared(applicationContext).reRegister() - Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalMillis >> [HH:mm:ss]") + Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalDuration >> [HH:mm:ss]") + HMG_Geofence.shared(applicationContext).register(){ status, error -> + jobFinished(params, true) + } return true } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt new file mode 100644 index 00000000..aa0f8ec2 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt @@ -0,0 +1,8 @@ +package com.cloud.diplomaticquarterapp.utils + + +const val PREFS_STORAGE = "FlutterSharedPreferences" +const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" +const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" +const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences" +const val PREF_KEY_LANGUAGE = "flutter.language" \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index 7880a7ef..1c661c19 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -11,17 +11,11 @@ import android.content.Intent import android.os.Build import android.widget.Toast import androidx.annotation.Nullable -import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat import androidx.core.app.TaskStackBuilder import com.cloud.diplomaticquarterapp.BuildConfig import com.cloud.diplomaticquarterapp.MainActivity import com.cloud.diplomaticquarterapp.R -import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE -import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES -import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE -import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost import com.google.gson.Gson @@ -75,14 +69,6 @@ class HMGUtils { } } - fun getGeoZonesFromPreference(context: Context):List{ - val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") - - val geoZones = GeoZoneModel().listFrom(json) - return geoZones - } - fun getLanguageCode(context: Context) : Int{ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) val lang = pref.getString(PREF_KEY_LANGUAGE, "ar") @@ -111,6 +97,7 @@ class HMGUtils { val serviceComponent = ComponentName(context, pendingIntentClassType) val builder = JobInfo.Builder(jobId, serviceComponent) builder.setPersisted(true) + builder.setBackoffCriteria(30000, JobInfo.BACKOFF_POLICY_LINEAR) val intervalMillis = timeToMillis(intervalDuration,"HH:mm:ss") builder.setMinimumLatency(intervalMillis) // wait at least diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt index 5c11943e..e74f463e 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.SharedPreferences import android.os.Build import com.cloud.diplomaticquarterapp.BuildConfig -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.google.gson.Gson class Logs { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt index ed1a62c8..eb2fff08 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt @@ -105,7 +105,7 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main override fun success(result: Any?) { if(result is String) { val geoZones = GeoZoneModel().listFrom(result) - HMG_Geofence.shared(mainActivity).register(geoZones) + HMG_Geofence.shared(mainActivity).register(){ s, e -> } } } From 52fa0f6f8966e7e1d80c3d77a3012da4c625d195 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Tue, 12 Jan 2021 14:47:06 +0300 Subject: [PATCH 09/14] fixed orders --- lib/config/config.dart | 1 + lib/config/localized_values.dart | 1 + lib/core/model/pharmacies/Prescriptions.dart | 157 ++++++++ lib/core/model/pharmacies/order_model.dart | 3 + lib/core/model/pharmacies/orders_model.dart | 68 ++++ .../parmacyModule/parmacy_module_service.dart | 5 + .../parmacyModule/prescription_service.dart | 53 +++ .../order_model_view_model.dart | 3 +- .../pharmacy_module_view_model.dart | 35 ++ lib/locator.dart | 5 + .../screens/pharmacy_module_page.dart | 339 +++++++++++++++--- lib/pages/pharmacy/order/Order.dart | 86 ++--- lib/pages/pharmacy/order/OrderDetails.dart | 1 + lib/pages/pharmacy/profile/profile.dart | 10 +- .../orderDetails_service.dart | 1 + .../pharmacy_services/order_service.dart | 52 +-- lib/uitl/translations_delegate_base.dart | 1 + 17 files changed, 698 insertions(+), 123 deletions(-) create mode 100644 lib/core/model/pharmacies/Prescriptions.dart create mode 100644 lib/core/model/pharmacies/orders_model.dart create mode 100644 lib/core/service/parmacyModule/prescription_service.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index abd1cee2..caf0bd5b 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -390,6 +390,7 @@ const TRANSFER_YAHALA_LOYALITY_POINTS = "Services/Patients.svc/REST/TransferYaHalaLoyaltyPoints"; const LAKUM_GET_USER_TERMS_AND_CONDITIONS = "Services/ERP.svc/REST/GetUserTermsAndConditionsForEPharmcy"; +const PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList'; // Home Health Care const HHC_GET_ALL_SERVICES = diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index b60a0f45..95711339 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -660,6 +660,7 @@ const Map localizedValues = { "cancelledOrder": {"en": " CANCELLED", "ar": "ملغي"}, "compare": {"en": " Compare", "ar": "مقارنه"}, "medicationsRefill": {"en": " Medication Refill", "ar": "طلب أعادة صرف"}, + "recommended": {"en": " Recommended For You", "ar": "موصى لك"}, "myPrescription": {"en": " My Prescriptions", "ar": "وصفاتي"}, "quantity": {"en": " QTY ", "ar": "الكمية"}, "backMyAccount": { diff --git a/lib/core/model/pharmacies/Prescriptions.dart b/lib/core/model/pharmacies/Prescriptions.dart new file mode 100644 index 00000000..80caff0a --- /dev/null +++ b/lib/core/model/pharmacies/Prescriptions.dart @@ -0,0 +1,157 @@ + + +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class Prescriptions { + String setupID; + int projectID; + int patientID; + int appointmentNo; + String appointmentDate; + String doctorName; + String clinicDescription; + String name; + int episodeID; + int actualDoctorRate; + int admission; + int clinicID; + String companyName; + String despensedStatus; + DateTime dischargeDate; + int dischargeNo; + int doctorID; + String doctorImageURL; + int doctorRate; + String doctorTitle; + int gender; + String genderDescription; + bool isActiveDoctorProfile; + bool isDoctorAllowVedioCall; + bool isExecludeDoctor; + bool isInOutPatient; + String isInOutPatientDescription; + String isInOutPatientDescriptionN; + bool isInsurancePatient; + String nationalityFlagURL; + int noOfPatientsRate; + String qR; + List speciality; + + Prescriptions( + {this.setupID, + this.projectID, + this.patientID, + this.appointmentNo, + this.appointmentDate, + this.doctorName, + this.clinicDescription, + this.name, + this.episodeID, + this.actualDoctorRate, + this.admission, + this.clinicID, + this.companyName, + this.despensedStatus, + this.dischargeDate, + this.dischargeNo, + this.doctorID, + this.doctorImageURL, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isDoctorAllowVedioCall, + this.isExecludeDoctor, + this.isInOutPatient, + this.isInOutPatientDescription, + this.isInOutPatientDescriptionN, + this.isInsurancePatient, + this.nationalityFlagURL, + this.noOfPatientsRate, + this.qR, + this.speciality}); + + Prescriptions.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = json['AppointmentDate']; + doctorName = json['DoctorName']; + clinicDescription = json['ClinicDescription']; + name = json['Name']; + episodeID = json['EpisodeID']; + actualDoctorRate = json['ActualDoctorRate']; + admission = json['Admission']; + clinicID = json['ClinicID']; + companyName = json['CompanyName']; + despensedStatus = json['Despensed_Status']; + dischargeDate = DateUtil.convertStringToDate(json['DischargeDate']); + dischargeNo = json['DischargeNo']; + doctorID = json['DoctorID']; + doctorImageURL = json['DoctorImageURL']; + doctorRate = json['DoctorRate']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isActiveDoctorProfile = json['IsActiveDoctorProfile']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + isExecludeDoctor = json['IsExecludeDoctor']; + isInOutPatient = json['IsInOutPatient']; + isInOutPatientDescription = json['IsInOutPatientDescription']; + isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; + isInsurancePatient = json['IsInsurancePatient']; + nationalityFlagURL = json['NationalityFlagURL']; + noOfPatientsRate = json['NoOfPatientsRate']; + qR = json['QR']; + // speciality = json['Speciality'].cast(); + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['DoctorName'] = this.doctorName; + data['ClinicDescription'] = this.clinicDescription; + data['Name'] = this.name; + data['EpisodeID'] = this.episodeID; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['Admission'] = this.admission; + data['ClinicID'] = this.clinicID; + data['CompanyName'] = this.companyName; + data['Despensed_Status'] = this.despensedStatus; + data['DischargeDate'] = this.dischargeDate; + data['DischargeNo'] = this.dischargeNo; + data['DoctorID'] = this.doctorID; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorRate'] = this.doctorRate; + data['DoctorTitle'] = this.doctorTitle; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; + data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; + data['IsExecludeDoctor'] = this.isExecludeDoctor; + data['IsInOutPatient'] = this.isInOutPatient; + data['IsInOutPatientDescription'] = this.isInOutPatientDescription; + data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; + data['IsInsurancePatient'] = this.isInsurancePatient; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['NoOfPatientsRate'] = this.noOfPatientsRate; + data['QR'] = this.qR; + data['Speciality'] = this.speciality; + return data; + } +} + +//class PrescriptionsList { +// String filterName = ""; +// List prescriptionsList = List(); +// +// PrescriptionsList({this.filterName, Prescriptions prescriptions}) { +// prescriptionsList.add(prescriptions); +// } +//} diff --git a/lib/core/model/pharmacies/order_model.dart b/lib/core/model/pharmacies/order_model.dart index 027d1f81..5b958e43 100644 --- a/lib/core/model/pharmacies/order_model.dart +++ b/lib/core/model/pharmacies/order_model.dart @@ -31,6 +31,7 @@ class OrderModel { this.taxRates, this.orderTax, this.orderDiscount, + this.productCount, this.orderTotal, this.refundedAmount, this.rewardPointsWereAdded, @@ -95,6 +96,7 @@ class OrderModel { String taxRates; double orderTax; dynamic orderDiscount; + dynamic productCount; double orderTotal; dynamic refundedAmount; dynamic rewardPointsWereAdded; @@ -159,6 +161,7 @@ class OrderModel { taxRates: json["tax_rates"], orderTax: json["order_tax"].toDouble(), orderDiscount: json["order_discount"], + productCount: json["product_count"], orderTotal: json["order_total"].toDouble(), refundedAmount: json["refunded_amount"], rewardPointsWereAdded: json["reward_points_were_added"], diff --git a/lib/core/model/pharmacies/orders_model.dart b/lib/core/model/pharmacies/orders_model.dart new file mode 100644 index 00000000..aaddf6f4 --- /dev/null +++ b/lib/core/model/pharmacies/orders_model.dart @@ -0,0 +1,68 @@ +class OrdersModel { + List orders; + + OrdersModel({this.orders}); + + OrdersModel.fromJson(Map json) { + if (json['orders'] != null) { + orders = new List(); + json['orders'].forEach((v) { + orders.add(new Orders.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.orders != null) { + data['orders'] = this.orders.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Orders { + String id; + int productCount; + double orderTotal; + String createdOnUtc; + int orderStatusId; + String orderStatus; + String orderStatusn; + + Orders( + {this.id, + this.productCount, + this.orderTotal, + this.createdOnUtc, + this.orderStatusId, + this.orderStatus, + this.orderStatusn}); + + Orders.fromJson(Map json) { + try { + id = json['id']; + productCount = json['product_count']; + orderTotal = json['order_total']; + createdOnUtc = json['created_on_utc']; + orderStatusId = json['order_status_id']; + orderStatus = json['order_status']; + orderStatusn = json['order_statusn']; + }catch(e){ + print(e); + } + + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['product_count'] = this.productCount; + data['order_total'] = this.orderTotal; + data['created_on_utc'] = this.createdOnUtc; + data['order_status_id'] = this.orderStatusId; + data['order_status'] = this.orderStatus; + data['order_statusn'] = this.orderStatusn; + return data; + } +} diff --git a/lib/core/service/parmacyModule/parmacy_module_service.dart b/lib/core/service/parmacyModule/parmacy_module_service.dart index c3bce324..7f0a1050 100644 --- a/lib/core/service/parmacyModule/parmacy_module_service.dart +++ b/lib/core/service/parmacyModule/parmacy_module_service.dart @@ -6,17 +6,21 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart' import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; + class PharmacyModuleService extends BaseService { final AppSharedPreferences sharedPref = AppSharedPreferences(); bool isFinished = true; bool hasError = false; String errorMsg = ''; + String url =""; List bannerItems = List(); List manufacturerList = List(); List bestSellerProducts = List(); List lastVisitedProducts = List(); + + Future makeVerifyCustomer(dynamic data) async { Map queryParams = {'FileNumber': data['PatientID'].toString()}; hasError = false; @@ -148,4 +152,5 @@ class PharmacyModuleService extends BaseService { } } } + } diff --git a/lib/core/service/parmacyModule/prescription_service.dart b/lib/core/service/parmacyModule/prescription_service.dart new file mode 100644 index 00000000..d03111a0 --- /dev/null +++ b/lib/core/service/parmacyModule/prescription_service.dart @@ -0,0 +1,53 @@ + +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Prescriptions.dart'; + + +class PrescriptionService extends BaseService { + final AppSharedPreferences sharedPref = AppSharedPreferences(); + bool isFinished = true; + bool hasError = false; + String errorMsg = ''; + String url = ""; + + List _prescriptionsList = List(); + List get prescriptionsList => _prescriptionsList; + + + Future getPrescription() async { + hasError = false; + url = PRESCRIPTION; + print("Print PRESCRIPTION url" + url); + await baseAppClient.getPharmacy(url, + onSuccess: (dynamic response, int statusCode) { + _prescriptionsList.clear(); + response['PatientPrescriptionList'].forEach((item) { + _prescriptionsList.add(Prescriptions.fromJson(item)); + }); + print(_prescriptionsList.length); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); + } +// Future getPrescription() async { +// hasError = false; +// Map body = Map(); +// body['isDentalAllowedBackend'] = false; +// await baseAppClient.post(PRESCRIPTION, +// onSuccess: (dynamic response, int statusCode) { +// prescriptionsList.clear(); +// response['PatientPrescriptionList'].forEach((prescriptions) { +// prescriptionsList.add(Prescriptions.fromJson(prescriptions)); +// }); +// }, onFailure: (String error, int statusCode) { +// hasError = true; +// super.error = error; +// }, body: body); +// } + +} \ No newline at end of file diff --git a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart index b7ddb528..5f36e9f6 100644 --- a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/services/pharmacy_services/cancelOrder_serv import 'package:diplomaticquarterapp/services/pharmacy_services/orderDetails_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:flutter/material.dart'; import '../../../locator.dart'; @@ -18,7 +19,7 @@ import '../base_view_model.dart'; class OrderModelViewModel extends BaseViewModel { OrderService _orderService = locator(); - List get order => _orderService.orderList; + List get orders => _orderService.orderList; OrderDetailsService _orderDetailsService = locator(); diff --git a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart index 4dfc6a26..bee7f654 100644 --- a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart @@ -3,7 +3,11 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Manufacturer.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Prescriptions.dart'; +//import 'package:diplomaticquarterapp/core/model/prescriptions/perscription_pharmacy.dart'; +//import 'package:diplomaticquarterapp/core/service/medical/prescriptions_service.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import '../../../locator.dart'; @@ -11,6 +15,8 @@ import '../../../locator.dart'; class PharmacyModuleViewModel extends BaseViewModel { PharmacyModuleService _pharmacyService = locator(); + PrescriptionService _prescriptionService = locator(); + List get bannerList => _pharmacyService.bannerItems; List get manufacturerList => _pharmacyService.manufacturerList; @@ -21,6 +27,11 @@ class PharmacyModuleViewModel extends BaseViewModel { List get lastVisitedProducts => _pharmacyService.lastVisitedProducts; + List get prescriptionsList => + _prescriptionService.prescriptionsList; + +// List get pharmacyPrescriptionsList => PharmacyProduct.pharmacyPrescriptionsList ; + Future getPharmacyHomeData() async { setState(ViewState.Busy); var data = await sharedPref.getObject(USER_PROFILE); @@ -92,6 +103,17 @@ class PharmacyModuleViewModel extends BaseViewModel { } } + /////////////RecommendedProducts +// _getRecommendedProducts() async { +// await _pharmacyService.getRecommendedProducts(); +// if (_pharmacyService.hasError) { +// error = _pharmacyService.error; +// setState(ViewState.Error); +// } else { +// setState(ViewState.Idle); +// } +// } + Future checkUserIsActivated() async { if (authenticatedUserObject.isLogin) { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); @@ -105,4 +127,17 @@ class PharmacyModuleViewModel extends BaseViewModel { return false; } } + + getPrescription() async { + print("Print PRESCRIPTION url"); + setState(ViewState.Busy); + await _prescriptionService.getPrescription(); + if (_prescriptionService.hasError) { + error = _prescriptionService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + } diff --git a/lib/locator.dart b/lib/locator.dart index c6ef1b32..12510f8a 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/service/qr_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; @@ -192,6 +193,10 @@ void setupLocator() { locator.registerLazySingleton(() => CustomerAddressesService()); locator.registerLazySingleton(() => TermsConditionService()); locator.registerLazySingleton(() => CancelOrderService()); + locator.registerLazySingleton(() => PrescriptionService()); + + + /// View Model locator.registerFactory(() => HospitalViewModel()); diff --git a/lib/pages/pharmacies/screens/pharmacy_module_page.dart b/lib/pages/pharmacies/screens/pharmacy_module_page.dart index 32a610f8..eb368cfa 100644 --- a/lib/pages/pharmacies/screens/pharmacy_module_page.dart +++ b/lib/pages/pharmacies/screens/pharmacy_module_page.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/pages/offers_categorise_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-page.dart'; @@ -14,10 +15,21 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.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/svg.dart'; +import 'package:rating_bar/rating_bar.dart'; import 'lacum-activitaion-vida-page.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; class PharmacyPage extends StatelessWidget { + + @override + void initState() { +// print("model prescription " + model.prescriptionsList.length); + +// cancelOrderDetail(order) + } + @override Widget build(BuildContext context) { return BaseView( @@ -37,6 +49,219 @@ class PharmacyPage extends StatelessWidget { children: [ BannerPager(model), GridViewButtons(model), + Container( + margin: EdgeInsets.fromLTRB(10, 10, 10, 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context).myPrescription, + bold: true, + ), + BorderedButton( + TranslationBase.of(context).viewAll, + hasBorder: true, + borderColor: Colors.green, + textColor: Colors.green, + vPadding: 6, + hPadding: 4, + handler: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => HomePrescriptionsPage())); + }, + ), + ], + ), + ), +// model.getPrescription(), + Container( + padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), + height: MediaQuery.of(context).size.height * 0.30, +// width: 200.0, +// height: MediaQuery.of(context).size.height / 4 + 20, + margin: EdgeInsets.only(left: 10), +// model.getPrescription(); + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), +// physics: NeverScrollableScrollPhysics(), +// itemCount: 4, + itemCount: model.prescriptionsList.length, + itemBuilder: (context, index){ + return + Container( +// width: 160.0, + height: MediaQuery.of(context).size.height * 0.6, + padding: EdgeInsets.only(bottom: 5.0, left: 5.0), + margin: EdgeInsets.only(right: 10.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey, + style: BorderStyle.solid, + width: 1.0, + ), + color: Colors.white, + borderRadius: BorderRadius.circular(10.0) + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Column( + children: [ + Container( + padding:EdgeInsets.only(top:10.0, left:10.0, right:3.0, bottom:15.0,), + child: Image.network( + model.prescriptionsList[index].doctorImageURL, + width: 60, + height: 60, + ), + ),] + ), + Column( +// crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.only(left: 1), + padding: EdgeInsets.only(left: 15.0, right: 15.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 4.0, + ), + color: Colors.green, + borderRadius: BorderRadius.circular(30.0) + ), + + child:Text(model.prescriptionsList[index].isInOutPatientDescription.toString(), + style: TextStyle( + color: Colors.white, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ), + ) + ), + Row( + children: [ + Image.asset( + 'assets/images/Icon-awesome-calendar.png', + width: 30, + height: 30, + ), + Text(model.prescriptionsList[index].appointmentDate.toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ), + ) + ] + ), + ], + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Row( + children: [ + Text(model.prescriptionsList[index].doctorTitle.toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ),), + Text(model.prescriptionsList[index].doctorName.toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ),), + ] ), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Text(model.prescriptionsList[index].clinicDescription.toString(), + style: TextStyle( + color: Colors.green, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ),), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar.readOnly( +// initialRating: productRate, + size: 15.0, + filledColor: Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), + ) + ] + ), + ] + ), + ); + } + ), + ), + + Container( + margin: EdgeInsets.fromLTRB(10, 10, 10, 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context).recommended, + bold: true, + ), + BorderedButton( + TranslationBase.of(context).viewAll, + hasBorder: true, + borderColor: Colors.green, + textColor: Colors.green, + vPadding: 6, + hPadding: 4, + handler: () {}, + ), + ], + ), + ), + Container( + height: MediaQuery.of(context).size.height / 4 + 20, + child: ListView.builder( + itemBuilder: (ctx, i) => + ProductTileItem(model.bestSellerProduct[i]), + scrollDirection: Axis.horizontal, + itemCount: model.bestSellerProduct.length, + ), + ), + Container( margin: EdgeInsets.fromLTRB(10, 0, 10, 0), child: Row( @@ -147,62 +372,62 @@ class GridViewButtons extends StatelessWidget { Widget build(BuildContext context) { final gridHeight = (MediaQuery.of(context).size.width * 0.3) * 1.8; return Container( - child: SizedBox( - height: gridHeight, - child: GridView.count( - childAspectRatio: 2.2, - crossAxisSpacing: 10, - mainAxisSpacing: 10, - controller: new ScrollController(keepScrollOffset: false), - shrinkWrap: true, - padding: const EdgeInsets.all(4.0), - crossAxisCount: 2, - children: [ - DashboardItem( - imageName: 'pharmacy_module/bg_1.png', - hasColorFilter: false, - opacity: 0.8, - child: GridViewCard( - TranslationBase.of(context).offersAndPromotions, - 'assets/images/pharmacy_module/offer_icon.png', () { - Navigator.push(context, FadePage(page: OffersCategorisePage())); - }), - ), - DashboardItem( - imageName: 'pharmacy_module/bg_2.png', - opacity: 0, - hasColorFilter: false, - child: GridViewCard(TranslationBase.of(context).medicationRefill, - 'assets/images/pharmacy_module/medication_icon.png', () { - model.checkUserIsActivated().then((isActivated) { - if (isActivated) { - Navigator.push(context, FadePage(page: LakumMainPage())); - } else { - Navigator.push( - context, FadePage(page: LakumActivationVidaPage())); - } - }); - }), - ), - DashboardItem( - imageName: 'pharmacy_module/bg_3.png', - opacity: 0, - hasColorFilter: false, - child: GridViewCard(TranslationBase.of(context).myPrescriptions, - 'assets/images/pharmacy_module/prescription_icon.png', () {}), - ), - DashboardItem( - imageName: 'pharmacy_module/bg_4.png', - opacity: 0, - hasColorFilter: false, - child: GridViewCard( - TranslationBase.of(context).searchAndScanMedication, - 'assets/images/pharmacy_module/search_scan_icon.png', - () {}), - ), - ], - ), - ), +// child: SizedBox( +// height: gridHeight, +// child: GridView.count( +// childAspectRatio: 2.2, +// crossAxisSpacing: 10, +// mainAxisSpacing: 10, +// controller: new ScrollController(keepScrollOffset: false), +// shrinkWrap: true, +// padding: const EdgeInsets.all(4.0), +// crossAxisCount: 2, +// children: [ +// DashboardItem( +// imageName: 'pharmacy_module/bg_1.png', +// hasColorFilter: false, +// opacity: 0.8, +// child: GridViewCard( +// TranslationBase.of(context).offersAndPromotions, +// 'assets/images/pharmacy_module/offer_icon.png', () { +// Navigator.push(context, FadePage(page: OffersCategorisePage())); +// }), +// ), +// DashboardItem( +// imageName: 'pharmacy_module/bg_2.png', +// opacity: 0, +// hasColorFilter: false, +// child: GridViewCard(TranslationBase.of(context).medicationRefill, +// 'assets/images/pharmacy_module/medication_icon.png', () { +// model.checkUserIsActivated().then((isActivated) { +// if (isActivated) { +// Navigator.push(context, FadePage(page: LakumMainPage())); +// } else { +// Navigator.push( +// context, FadePage(page: LakumActivationVidaPage())); +// } +// }); +// }), +// ), +// DashboardItem( +// imageName: 'pharmacy_module/bg_3.png', +// opacity: 0, +// hasColorFilter: false, +// child: GridViewCard(TranslationBase.of(context).myPrescriptions, +// 'assets/images/pharmacy_module/prescription_icon.png', () {}), +// ), +// DashboardItem( +// imageName: 'pharmacy_module/bg_4.png', +// opacity: 0, +// hasColorFilter: false, +// child: GridViewCard( +// TranslationBase.of(context).searchAndScanMedication, +// 'assets/images/pharmacy_module/search_scan_icon.png', +// () {}), +// ), +// ], +// ), +// ), ); } } diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index 576bf2a0..e472aa18 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -9,6 +9,7 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/OrderDetails.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; @@ -31,11 +32,11 @@ class _OrderPageState extends State with SingleTickerProviderStateMix String customerId = ""; String order =""; - List orderList = [] ; - List deliveredOrderList = [] ; - List processingOrderList = []; - List cancelledOrderList = []; - List pendingOrderList = []; + List orderList = [] ; + List deliveredOrderList = [] ; + List processingOrderList = []; + List cancelledOrderList = []; + List pendingOrderList = []; TabController _tabController; // AppSharedPreferences sharedPref = AppSharedPreferences(); @@ -66,6 +67,8 @@ class _OrderPageState extends State with SingleTickerProviderStateMix child: Column( children: [ TabBar( + labelPadding: + EdgeInsets.only(left: 3.0, right: 3.0), tabs: [ Tab(text: TranslationBase.of(context).delivered), Tab(text: TranslationBase.of(context).processing), @@ -103,16 +106,16 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Widget getDeliveredOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 30 || model.order[i].orderStatusId == 997 - || model.order[i].orderStatusId == 994 + for(int i=0 ; i< model.orders.length; i++){ + if( model.orders[i].orderStatusId == 30 || model.orders[i].orderStatusId == 997 + || model.orders[i].orderStatusId == 994 ){ - deliveredOrderList.add(model.order[i]); + deliveredOrderList.add(model.orders[i]); } } return Container( width: MediaQuery.of(context).size.width, - child: model.order.length != 0 + child: model.orders.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -175,10 +178,10 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Container( margin: EdgeInsets.all(8.0), child: InkWell( - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:deliveredOrderList[index]))); - }, +// onTap: () { +// Navigator.push(context, +// MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel: deliveredOrderList[index]),)); +// }, child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -260,7 +263,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Row( children: [ Container( - child: Text(deliveredOrderList[index].orderItems.length.toString(), + child: Text(deliveredOrderList[index].productCount.toString(), style: TextStyle(fontSize: 14.0, ), ), @@ -317,15 +320,15 @@ class _OrderPageState extends State with SingleTickerProviderStateMix } Widget getProcessingOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 20 || model.order[i].orderStatusId == 995 || - model.order[i].orderStatusId == 998 || model.order[i].orderStatusId == 999){ - processingOrderList.add(model.order[i]); + for(int i=0 ; i< model.orders.length; i++){ + if( model.orders[i].orderStatusId == 20 || model.orders[i].orderStatusId == 995 || + model.orders[i].orderStatusId == 998 || model.orders[i].orderStatusId == 999){ + processingOrderList.add(model.orders[i]); } } return Container( width: MediaQuery.of(context).size.width, - child: model.order.length != 0 + child: model.orders.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -389,9 +392,10 @@ class _OrderPageState extends State with SingleTickerProviderStateMix margin: EdgeInsets.all(8.0), child: InkWell( onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:processingOrderList[index]))); - }, +// Navigator.push(context, +// MaterialPageRoute(builder: (context) => OrderDetailsPage(Orders:processingOrderList[index]))); +// + }, child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -473,7 +477,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Row( children: [ Container( - child: Text(processingOrderList[index].orderItems.length.toString(), + child: Text(processingOrderList[index].productCount.toString(), style: TextStyle(fontSize: 14.0, ), ), @@ -709,13 +713,13 @@ class _OrderPageState extends State with SingleTickerProviderStateMix } Widget getPendingOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 10){ - pendingOrderList.add(model.order[i]); + for(int i=0 ; i< model.orders.length; i++){ + if( model.orders[i].orderStatusId == 10){ + pendingOrderList.add(model.orders[i]); } } return Container( - child: model.order.length != 0 + child: model.orders.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -780,9 +784,10 @@ class _OrderPageState extends State with SingleTickerProviderStateMix margin: EdgeInsets.all( 8.0), child: InkWell( onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:pendingOrderList[index]))); - }, +// Navigator.push(context, +// MaterialPageRoute(builder: (context) => OrderDetailsPage(Orders:pendingOrderList[index]))); +// + }, child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -864,7 +869,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Row( children: [ Container( - child: Text(pendingOrderList[index].orderItems.length.toString(), + child: Text(pendingOrderList[index].productCount.toString(), style: TextStyle(fontSize: 14.0, ), ), @@ -924,14 +929,14 @@ class _OrderPageState extends State with SingleTickerProviderStateMix } Widget getCancelledOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 40 || model.order[i].orderStatusId == 996 - || model.order[i].orderStatusId == 200){ - cancelledOrderList.add(model.order[i]); + for(int i=0 ; i< model.orders.length; i++){ + if( model.orders[i].orderStatusId == 40 || model.orders[i].orderStatus == 996 + || model.orders[i].orderStatusId == 200){ + cancelledOrderList.add(model.orders[i]); } } return Container( - child: model.order.length != 0 + child: model.orders.length != 0 ? SingleChildScrollView( child: Column( children: [ @@ -996,8 +1001,9 @@ class _OrderPageState extends State with SingleTickerProviderStateMix margin: EdgeInsets.all(8.0), child: InkWell( onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:cancelledOrderList[index]))); +// Navigator.push(context, +// MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel: cancelledOrderList[index]))); +// }, child: SvgPicture.asset( languageID == "ar" @@ -1080,7 +1086,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Row( children: [ Container( - child: Text(cancelledOrderList[index].orderItems.length.toString(), + child: Text(cancelledOrderList[index].productCount.toString(), style: TextStyle(fontSize: 14.0, ), ), diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 1e4c5bb3..5438663d 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -328,6 +328,7 @@ class _OrderDetailsPageState extends State { totalPrice: "${(widget.orderModel.orderItems[index].product.price * widget.orderModel.orderItems[index].quantity).toStringAsFixed(2)}", qyt: widget.orderModel.orderItems[index].quantity.toString(), + isOrderDetails:true, imgs: widget.orderModel.orderItems[index].product.images != null && widget.orderModel.orderItems[index].product.images.length != 0 ? widget.orderModel.orderItems[index].product.images [0].src.toString() diff --git a/lib/pages/pharmacy/profile/profile.dart b/lib/pages/pharmacy/profile/profile.dart index d6fe35be..3a27a98d 100644 --- a/lib/pages/pharmacy/profile/profile.dart +++ b/lib/pages/pharmacy/profile/profile.dart @@ -5,6 +5,8 @@ import 'package:diplomaticquarterapp/pages/ContactUs/findus/findus_page.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/compare.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/my_reviews.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; @@ -237,6 +239,12 @@ class _ProfilePageState extends State { ), Expanded( child: InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MyReviewsPage())); + }, child: Column( children: [ SvgPicture.asset( @@ -328,7 +336,7 @@ class _ProfilePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => MyFamily())); + builder: (context) => ComparePage())); }, child: Row( children: [ diff --git a/lib/services/pharmacy_services/orderDetails_service.dart b/lib/services/pharmacy_services/orderDetails_service.dart index a3bb9976..1e9306d4 100644 --- a/lib/services/pharmacy_services/orderDetails_service.dart +++ b/lib/services/pharmacy_services/orderDetails_service.dart @@ -24,6 +24,7 @@ class OrderDetailsService extends BaseService{ Future getOrderDetails(orderId) async { print("step 2" + orderId); + print("this is what i need"+GET_ORDER_DETAILS + orderId); hasError = false; await baseAppClient.getPharmacy(GET_ORDER_DETAILS+orderId, onSuccess: (dynamic response, int statusCode) { diff --git a/lib/services/pharmacy_services/order_service.dart b/lib/services/pharmacy_services/order_service.dart index e426b801..abdeda20 100644 --- a/lib/services/pharmacy_services/order_service.dart +++ b/lib/services/pharmacy_services/order_service.dart @@ -5,7 +5,7 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; class OrderService extends BaseService{ @@ -14,21 +14,23 @@ class OrderService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _orderList = List(); - List get orderList => _orderList; + List _orderList = List(); + List get orderList => _orderList; String url =""; Future getOrder(customerId, pageId) async { hasError = false; // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; - url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$pageId&limit=200&customer_id=$customerId"; + // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$pageId&limit=200&customer_id=$customerId"; + url =GET_ORDER+"customer=1&fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc,product_count&page=$pageId&limit=200&customer_id=$customerId"; print(url); await baseAppClient.getPharmacy(url, onSuccess: (dynamic response, int statusCode) { _orderList.clear(); + response['orders'].forEach((item) { - _orderList.add(OrderModel.fromJson(item)); + _orderList.add(Orders.fromJson(item)); }); print(_orderList.length); print(response); @@ -39,25 +41,27 @@ class OrderService extends BaseService{ } - Future getProductReview(orderId) async { - print("step 1"); - hasError = false; - url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; -// url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$page_id&limit=200&customer_id=$custmerId"; - print(url); - await baseAppClient.getPharmacy(url, - onSuccess: (dynamic response, int statusCode) { - _orderList.clear(); - response['orders'].forEach((item) { - _orderList.add(OrderModel.fromJson(item)); - }); - print(_orderList.length); - print(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); - } +// Future getProductReview(orderId) async { +// print("step 1"); +// hasError = false; +// url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; +//// url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$page_id&limit=200&customer_id=$custmerId"; +// print(url); +// await baseAppClient.getPharmacy(url, +// onSuccess: (dynamic response, int statusCode) { +// _orderList.clear(); +// response['orders'].forEach((item) { +// _orderList.add(OrderModel.fromJson(item)); +// }); +// print(_orderList.length); +// print(response); +// }, onFailure: (String error, int statusCode) { +// hasError = true; +// super.error = error; +// }); +// } + + // Future getOrder(BuildContext context ) async { // // if (await this.sharedPref.getObject(USER_PROFILE) != null) { diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index f60d010f..d67a2e98 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -792,6 +792,7 @@ class TranslationBase { String get recentlyViewed => localizedValues['recentlyViewed'][locale.languageCode]; String get bestSellers => localizedValues['bestSellers'][locale.languageCode]; + String get recommended => localizedValues['recommended'][locale.languageCode]; String get deleteAllItems => localizedValues['deleteAllItems'][locale.languageCode]; String get selectAddress => From a1b2709ac8aa3b473bfb495bdd1771db07f55e83 Mon Sep 17 00:00:00 2001 From: Fatimah Alshammari Date: Wed, 13 Jan 2021 09:42:51 +0300 Subject: [PATCH 10/14] fixed orders --- lib/pages/pharmacy/order/Order.dart | 26 +-- lib/pages/pharmacy/order/OrderDetails.dart | 202 +++++++++++---------- 2 files changed, 116 insertions(+), 112 deletions(-) diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index e472aa18..33599516 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -178,10 +178,10 @@ class _OrderPageState extends State with SingleTickerProviderStateMix Container( margin: EdgeInsets.all(8.0), child: InkWell( -// onTap: () { -// Navigator.push(context, -// MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel: deliveredOrderList[index]),)); -// }, + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel: deliveredOrderList[index]),)); + }, child: SvgPicture.asset( languageID == "ar" ? 'assets/images/pharmacy/arrow_left.svg' @@ -392,9 +392,9 @@ class _OrderPageState extends State with SingleTickerProviderStateMix margin: EdgeInsets.all(8.0), child: InkWell( onTap: () { -// Navigator.push(context, -// MaterialPageRoute(builder: (context) => OrderDetailsPage(Orders:processingOrderList[index]))); -// + Navigator.push(context, + MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel :processingOrderList[index]))); + }, child: SvgPicture.asset( languageID == "ar" @@ -784,9 +784,9 @@ class _OrderPageState extends State with SingleTickerProviderStateMix margin: EdgeInsets.all( 8.0), child: InkWell( onTap: () { -// Navigator.push(context, -// MaterialPageRoute(builder: (context) => OrderDetailsPage(Orders:pendingOrderList[index]))); -// + Navigator.push(context, + MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:pendingOrderList[index]))); + }, child: SvgPicture.asset( languageID == "ar" @@ -1001,9 +1001,9 @@ class _OrderPageState extends State with SingleTickerProviderStateMix margin: EdgeInsets.all(8.0), child: InkWell( onTap: () { -// Navigator.push(context, -// MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel: cancelledOrderList[index]))); -// + Navigator.push(context, + MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel: cancelledOrderList[index]))); + }, child: SvgPicture.asset( languageID == "ar" diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 5438663d..6effb47b 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; @@ -22,9 +23,11 @@ import 'package:provider/provider.dart'; dynamic languageID; class OrderDetailsPage extends StatefulWidget { - OrderModel orderModel; + Orders orderModel; + OrderModel orderDetails; + + OrderDetailsPage({@required this.orderModel, this.orderDetails}); - OrderDetailsPage({@required this.orderModel}); @override _OrderDetailsPageState createState() => _OrderDetailsPageState(); @@ -51,9 +54,10 @@ class _OrderDetailsPageState extends State { @override void initState() { + getLanguageID(); super.initState(); - print(widget.orderModel.orderItems.length); +// print(widget.orderModel.orderItems.length); getCancelOrder(widget.orderModel.id); // cancelOrderDetail(order) } @@ -105,9 +109,9 @@ class _OrderDetailsPageState extends State { color: getStatusBackgroundColor(), borderRadius: BorderRadius.circular(30.0)), child: Text( - languageID == "ar" - ? widget.orderModel.orderStatusn.toString(): - widget.orderModel.orderStatus.toString().substring(12) , + languageID == "ar" + ? widget.orderModel.orderStatusn.toString(): + widget.orderModel.orderStatus.toString().substring(12) , // TranslationBase.of(context).delivered, style: TextStyle( color: Colors.white, @@ -124,11 +128,11 @@ class _OrderDetailsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.orderModel.shippingAddress.firstName - .toString() - .substring(10) + + widget.orderDetails.shippingAddress.firstName + .toString() + .substring(10) + ' ' + - widget.orderModel.shippingAddress.lastName + widget.orderDetails.shippingAddress.lastName .toString() .substring(9), style: TextStyle( @@ -141,18 +145,18 @@ class _OrderDetailsPageState extends State { Container( margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.orderModel.shippingAddress.address1 - .toString() - .substring(9), - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ),] + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.orderDetails.shippingAddress.address1 + .toString() + .substring(9), + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ),] ), ), Container( @@ -161,14 +165,14 @@ class _OrderDetailsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.orderModel.shippingAddress.address2 - .toString() - .substring(9) + + widget.orderDetails.shippingAddress.address2 + .toString() + .substring(9) + ' ' + - widget.orderModel.shippingAddress.country + widget.orderDetails.shippingAddress.country .toString() + ' ' + - widget.orderModel.shippingAddress.zipPostalCode + widget.orderDetails.shippingAddress.zipPostalCode .toString(), style: TextStyle( fontSize: 10.0, @@ -191,7 +195,7 @@ class _OrderDetailsPageState extends State { Container( margin: EdgeInsets.only(top: 5.0, bottom: 5.0), child: Text( - widget.orderModel.shippingAddress.phoneNumber + widget.orderDetails.shippingAddress.phoneNumber .toString(), style: TextStyle( fontSize: 15.0, @@ -230,8 +234,8 @@ class _OrderDetailsPageState extends State { ), Container( child: flutterImage.Image.asset( - widget.orderModel.shippingRateComputationMethodSystemName != - "Shipping.Aramex" + widget.orderDetails.shippingRateComputationMethodSystemName != + "Shipping.Aramex" ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", fit: BoxFit.contain, @@ -282,7 +286,7 @@ class _OrderDetailsPageState extends State { Container( margin: EdgeInsets.only(bottom: 10.0, top: 10.0), child: Text( - widget.orderModel.paymentName.toString().substring(12), + widget.orderDetails.paymentName.toString().substring(12), style: TextStyle( fontSize: 13.0, fontWeight: FontWeight.bold, @@ -318,23 +322,23 @@ class _OrderDetailsPageState extends State { scrollDirection: Axis.vertical, shrinkWrap: true, physics: ScrollPhysics(), - itemCount:widget.orderModel.orderItems.length, + itemCount:widget.orderDetails.orderItems.length, itemBuilder: (context, index){ - return Container( - child: productTile(productName: widget.orderModel.orderItems[index].product.name.toString(), - productPrice: widget.orderModel.orderItems[index].product.price.toString(), - productRate: widget.orderModel.orderItems[index].product.approvedRatingSum.toDouble(), - productReviews:widget.orderModel.orderItems[index].product.approvedTotalReviews, - totalPrice: "${(widget.orderModel.orderItems[index].product.price - * widget.orderModel.orderItems[index].quantity).toStringAsFixed(2)}", - qyt: widget.orderModel.orderItems[index].quantity.toString(), - isOrderDetails:true, - imgs: widget.orderModel.orderItems[index].product.images != null && - widget.orderModel.orderItems[index].product.images.length != 0 - ? widget.orderModel.orderItems[index].product.images [0].src.toString() - : null, - status: widget.orderModel.orderStatusId, - product: widget.orderModel.orderItems[index].product, + return Container( + child: productTile(productName: widget.orderDetails.orderItems[index].product.name.toString(), + productPrice: widget.orderDetails.orderItems[index].product.price.toString(), + productRate: widget.orderDetails.orderItems[index].product.approvedRatingSum.toDouble(), + productReviews:widget.orderDetails.orderItems[index].product.approvedTotalReviews, + totalPrice: "${(widget.orderDetails.orderItems[index].product.price + * widget.orderDetails.orderItems[index].quantity).toStringAsFixed(2)}", + qyt: widget.orderDetails.orderItems[index].quantity.toString(), + isOrderDetails:true, + imgs: widget.orderDetails.orderItems[index].product.images != null && + widget.orderDetails.orderItems[index].product.images.length != 0 + ? widget.orderDetails.orderItems[index].product.images [0].src.toString() + : null, + status: widget.orderDetails.orderStatusId, + product: widget.orderDetails.orderItems[index].product, ), ); }), @@ -383,7 +387,7 @@ class _OrderDetailsPageState extends State { ), ), Text( - widget.orderModel.orderSubtotalExclTax.toString(), + widget.orderDetails.orderSubtotalExclTax.toString(), style: TextStyle( fontSize: 13.0, ), @@ -421,7 +425,7 @@ class _OrderDetailsPageState extends State { ), ), Text( - widget.orderModel.orderShippingExclTax.toString(), + widget.orderDetails.orderShippingExclTax.toString(), style: TextStyle( fontSize: 13.0, ), @@ -459,7 +463,7 @@ class _OrderDetailsPageState extends State { ), ), Text( - widget.orderModel.orderTax.toString(), + widget.orderDetails.orderTax.toString(), style: TextStyle( fontSize: 13.0, ), @@ -510,58 +514,58 @@ class _OrderDetailsPageState extends State { ), widget.orderModel.orderStatusId == 10 ? InkWell( - onTap: () { - model.makeOrder(); - }, - child: Container( + onTap: () { + model.makeOrder(); + }, + child: Container( // margin: EdgeInsets.only(top: 20.0), - height: 50.0, - color: Colors.transparent, - child: Container( - padding: EdgeInsets.only(left: 130.0, right: 130.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.green, - style: BorderStyle.solid, - width: 4.0), - color: Colors.green, - borderRadius: BorderRadius.circular(5.0)), - child: Center( - child: Text( - TranslationBase.of(context).payOnline, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ), + height: 50.0, + color: Colors.transparent, + child: Container( + padding: EdgeInsets.only(left: 130.0, right: 130.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 4.0), + color: Colors.green, + borderRadius: BorderRadius.circular(5.0)), + child: Center( + child: Text( + TranslationBase.of(context).payOnline, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, ), ), - ) + ), + ), + ), + ) : Container(), // getCancelOrder(canCancel, canRefund), isCancel ? InkWell( - onTap: () { - presentConfirmDialog(model, - widget.orderModel.id); //(widget.orderModel.id)); + onTap: () { + presentConfirmDialog(model, + widget.orderModel.id); //(widget.orderModel.id)); // - }, - child: Container( + }, + child: Container( // padding: EdgeInsets.only(left: 13.0, right: 13.0, top: 5.0), - height: 50.0, - color: Colors.transparent, - child: Center( - child: Text( - TranslationBase.of(context).cancelOrder, - style: TextStyle( - color: Colors.red[900], - fontWeight: FontWeight.bold, - decoration: TextDecoration.underline), - ), - ), - ), - ) + height: 50.0, + color: Colors.transparent, + child: Center( + child: Text( + TranslationBase.of(context).cancelOrder, + style: TextStyle( + color: Colors.red[900], + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline), + ), + ), + ), + ) : Container(), ], ), @@ -591,17 +595,17 @@ class _OrderDetailsPageState extends State { } getCancelOrder(dataIsCancel) { - if (widget.orderModel.canCancel && widget.orderModel.canRefund) { + if (widget.orderDetails.canCancel && widget.orderDetails.canRefund) { setState(() { isCancel = true; isRefund = false; }); - } else if (widget.orderModel.canCancel) { + } else if (widget.orderDetails.canCancel) { setState(() { isCancel = true; isRefund = false; }); - } else if (widget.orderModel.canRefund) { + } else if (widget.orderDetails.canRefund) { setState(() { isCancel = false; isRefund = true; @@ -630,7 +634,7 @@ class _OrderDetailsPageState extends State { context, MaterialPageRoute( builder: (context) => OrderPage( - customerID: widget.orderModel.customerId.toString())), + customerID: widget.orderDetails.customerId.toString())), ); }), cancelFunction: () => {}); @@ -639,7 +643,7 @@ class _OrderDetailsPageState extends State { getCanceledOrder(order) { Navigator.pop(context); - if (widget.orderModel.canCancel && widget.orderModel.canRefund == false) { + if (widget.orderDetails.canCancel && widget.orderDetails.canRefund == false) { // getCanceledOrder(order); // AppToast.showSuccessToast(message: "Request Sent Successfully"); // Navigator.push(context, @@ -647,4 +651,4 @@ class _OrderDetailsPageState extends State { } } -} +} \ No newline at end of file From e2bce87e34195476195716ad4f974986388a8271 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Wed, 13 Jan 2021 14:39:36 +0300 Subject: [PATCH 11/14] resolve merge conflicts. --- ios/Flutter/.last_build_id | 6 +---- lib/config/config.dart | 4 +-- lib/pages/landing/landing_page.dart | 35 +++++++++++++++----------- lib/uitl/utils.dart | 38 ++++++++++++++++++----------- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index 6ccef9d4..b8024672 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1,5 +1 @@ -<<<<<<< HEAD -e7c24319209ad9049a87d4c83aeeb7de -======= -59a6c452ee075b50114918f17f1ad8f5 ->>>>>>> development +59a6c452ee075b50114918f17f1ad8f5 \ No newline at end of file diff --git a/lib/config/config.dart b/lib/config/config.dart index 795da85b..4315f13c 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi'; const PACKAGES_CATEGORIES = '/api/categories'; const PACKAGES_PRODUCTS = '/api/products'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; //const BASE_PHARMACY_URL = 'http://swd-pharapp-01:7200/api/'; const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index f45b3780..eabff77a 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -613,20 +613,27 @@ class _LandingPageState extends State with WidgetsBindingObserver { } } - void checkUserStatus(token) async { - var result = await authService.selectDeviceImei(token); - await setUserValues(result); + void checkUserStatus(token, {isLoader = true}) async { + if (isLoader) + //GifLoaderDialogUtils.showMyDialog(context); + authService + .selectDeviceImei(token) + .then((SelectDeviceIMEIRES value) => setUserValues(value)) + .catchError((err) { + //GifLoaderDialogUtils.hideDialog(context); + }); - if (await sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); - if (data != null) { - authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {print(res)}); - authService.getDashboard().then((value) => { - setState(() { - notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); - }) - }); - } - } + // if (await sharedPref.getObject(USER_PROFILE) != null) { + // var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + // if (data != null) { + // authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {print(res)}); + // authService.getDashboard().then((value) => { + // setState(() { + // notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); + // }) + // }); + // } + // } } + } diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index fdbb1314..b2c52b2b 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -4,7 +4,9 @@ import 'dart:typed_data'; import 'package:badges/badges.dart'; import 'package:connectivity/connectivity.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/Blood/my_balance_page.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/MyAppointments.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; @@ -33,6 +35,7 @@ import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../Constants.dart'; import 'app_shared_preferences.dart'; @@ -491,22 +494,24 @@ class Utils { ), )); } - if (projectViewModel.havePrivilege(32)) { + if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( onTap: () { - if (projectViewModel.isLogin) { - String patientID = AuthProvider().getAuthenticatedUser().patientID.toString(); - GifLoaderDialogUtils.showMyDialog(context); - projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}); - } else { - AlertDialogBox( - context: context, - confirmMessage: "Please login with your account first to use this feature", - okText: "OK", - okFunction: () { - AlertDialogBox.closeAlertDialog(context); - }).showAlertDialog(context); - } + userData().then((userData_){ + if (projectViewModel.isLogin && userData_ != null) { + String patientID = userData_.patientID.toString(); + GifLoaderDialogUtils.showMyDialog(context); + projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}); + } else { + AlertDialogBox( + context: context, + confirmMessage: "Please login with your account first to use this feature", + okText: "OK", + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + }).showAlertDialog(context); + } + }); }, child: MedicalProfileItem( title: TranslationBase.of(context).internet, @@ -534,6 +539,11 @@ class Utils { } } +Future userData() async { + var userData = AuthenticatedUser.fromJson(await AppSharedPreferences().getObject(MAIN_USER)); + return userData; +} + // extension function that use in iterations(list.. etc) to iterate items and get index and item it self extension IndexedIterable on Iterable { Iterable mapIndexed(T Function(E e, int i) f) { From 4457b5f109fb88693cd399d1bce82329354b6ca4 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Mon, 18 Jan 2021 14:05:35 +0200 Subject: [PATCH 12/14] add translation to ER service --- lib/config/localized_values.dart | 5 +- lib/core/enum/Ambulate.dart | 11 +- lib/pages/ErService/AmbulanceReq.dart | 2 +- .../AmbulanceRequestIndex.dart | 2 +- .../BillAmount.dart | 532 ++++++------- .../PickupLocation.dart | 705 +++++++++--------- .../SelectTransportationMethod.dart | 466 ++++++------ .../AmbulanceRequestIndexPages/Summary.dart | 147 ++-- lib/pages/ErService/OrderLogPage.dart | 10 +- lib/pages/ErService/widgets/StepsWidget.dart | 22 +- lib/uitl/translations_delegate_base.dart | 1 + 11 files changed, 981 insertions(+), 922 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index aaa7f16a..295a09f9 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1477,5 +1477,8 @@ const Map localizedValues = { "en": "Request ID:", "ar": " رقم الطلب" }, - + "RRT-orders-log": { + "en": "Orders Log", + "ar": "سجل الطلبات" + }, }; diff --git a/lib/core/enum/Ambulate.dart b/lib/core/enum/Ambulate.dart index f8b2e8be..e4714cb2 100644 --- a/lib/core/enum/Ambulate.dart +++ b/lib/core/enum/Ambulate.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; enum Ambulate { Wheelchair, Walker, Stretcher, None } @@ -6,19 +7,19 @@ extension SelectedAmbulate on Ambulate { String getAmbulateTitle(BuildContext context) { switch (this) { case Ambulate.Wheelchair: - return 'Wheelchair'; + return TranslationBase.of(context).wheelchair; break; case Ambulate.Walker: - return 'Walker'; + return TranslationBase.of(context).walker; break; case Ambulate.Stretcher: - return 'Stretcher'; + return TranslationBase.of(context).stretcher; break; case Ambulate.None: - return 'None'; + return TranslationBase.of(context).none; break; } - return 'None'; + return TranslationBase.of(context).none; } int selectAmbulateNumber() { diff --git a/lib/pages/ErService/AmbulanceReq.dart b/lib/pages/ErService/AmbulanceReq.dart index fe245133..1d4e78ee 100644 --- a/lib/pages/ErService/AmbulanceReq.dart +++ b/lib/pages/ErService/AmbulanceReq.dart @@ -107,7 +107,7 @@ class _AmbulanceReqState extends State Container( width: MediaQuery.of(context).size.width * 0.30, child: Center( - child: Texts("Orders Log"), + child: Texts(TranslationBase.of(context).ordersLog), ), ), ], diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart index c07adabc..1fb47cec 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart @@ -46,7 +46,7 @@ class _AmbulanceRequestIndexPageState extends State { @override Widget build(BuildContext context) { return AppScaffold( - body: false + body: widget.amRequestViewModel.pickUpRequestPresOrder != null ? Column( children: [ SizedBox( diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart index aeb61609..051f672e 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -45,306 +46,309 @@ class _BillAmountState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(TranslationBase.of(context).billAmount), - SizedBox( - height: 10, - ), - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 1.0, color: Colors.grey[300]), - outside: BorderSide(width: 1.0, color: Colors.grey[300])), - children: [ - TableRow( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + return AppScaffold( + isShowDecPage: false, + isShowAppBar: false, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).billAmount), + SizedBox( + height: 10, + ), + Table( + border: TableBorder.symmetric( + inside: BorderSide(width: 1.0, color: Colors.grey[300]), + outside: BorderSide(width: 1.0, color: Colors.grey[300])), + children: [ + TableRow( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.0), + ), ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).patientShareB, - textAlign: TextAlign.start, - color: Colors.black, - fontSize: 15, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).patientShareB, + textAlign: TextAlign.start, + color: Colors.black, + fontSize: 15, + ), ), ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(10.0), + ), ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.price}', - color: Colors.black, - textAlign: TextAlign.start, - fontSize: 15, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.price}', + color: Colors.black, + textAlign: TextAlign.start, + fontSize: 15, + ), ), ), - ), - ], - ), - TableRow( - children: [ - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.09, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).patientShareTax, - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - ), - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - color: Colors.white, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.vAT}', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, + ], + ), + TableRow( + children: [ + Container( + color: Colors.white, + height: MediaQuery.of(context).size.height * 0.09, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).patientShareTax, + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + ), ), ), - ), - ], - ), - TableRow( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( + Container( + height: MediaQuery.of(context).size.height * 0.09, color: Colors.white, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(10.0), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.vAT}', + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + ), ), ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).patientShareTotal, - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - bold: true, + ], + ), + TableRow( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.0), + ), ), - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(10.0), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).patientShareTotal, + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + bold: true, + ), ), ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10.0), + ), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}', + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + ), ), ), - ), - ], - ), - ], - ), - SizedBox( - height: 10, - ), - Texts(TranslationBase.of(context).selectAmbulate,bold: true,), - SizedBox(height: 5,), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Wheelchair; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).wheelchair), - leading: Radio( - value: Ambulate.Wheelchair, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + ], + ), + ], + ), + SizedBox( + height: 10, + ), + Texts(TranslationBase.of(context).selectAmbulate,bold: true,), + SizedBox(height: 5,), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Wheelchair; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).wheelchair), + leading: Radio( + value: Ambulate.Wheelchair, + groupValue: _ambulate, + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Walker; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).walker), - leading: Radio( - value: Ambulate.Walker, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Walker; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).walker), + leading: Radio( + value: Ambulate.Walker, + groupValue: _ambulate, + + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - ], - ), - SizedBox(height: 5,), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Stretcher; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).stretcher), - leading: Radio( - value: Ambulate.Stretcher, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + ], + ), + SizedBox(height: 5,), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Stretcher; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).stretcher), + leading: Radio( + value: Ambulate.Stretcher, + groupValue: _ambulate, + + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.None; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).none), - leading: Radio( - value: Ambulate.None, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.None; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).none), + leading: Radio( + value: Ambulate.None, + groupValue: _ambulate, + + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - ], - ), - SizedBox(height: 12,), - NewTextFields( - hintText: TranslationBase.of(context).notes, - initialValue: note, - onChanged: (value){ - setState(() { - note = value; - }); - }, - ), - - SizedBox( - height: 15, - ), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { + ], + ), + SizedBox(height: 12,), + NewTextFields( + hintText: TranslationBase.of(context).notes, + initialValue: note, + onChanged: (value){ setState(() { - widget.patientER.ambulate = _ambulate; - widget.patientER.requesterNote = note; - widget.patientER.selectedAmbulate = _ambulate.selectAmbulateNumber(); - widget.changeCurrentTab(3); + note = value; }); }, - label: TranslationBase.of(context).next, ), - ) - ], + + SizedBox( + height: 15, + ), + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child: SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.patientER.ambulate = _ambulate; + widget.patientER.requesterNote = note; + widget.patientER.selectedAmbulate = _ambulate.selectAmbulateNumber(); + widget.changeCurrentTab(3); + }); + }, + label: TranslationBase.of(context).next, ), ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart index f6ebfde9..1ea0f7f5 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart @@ -5,23 +5,20 @@ import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.da import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/Blood/dialogs/SelectHospitalDialog.dart'; import 'package:diplomaticquarterapp/pages/ErService/widgets/AppointmentCard.dart'; -import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; import 'package:diplomaticquarterapp/uitl/ProgressDialog.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/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; - -import '../AmbulanceReq.dart'; import '../AvailableAppointmentsPage.dart'; enum HaveAppointment { YES, NO } @@ -68,370 +65,397 @@ class _PickupLocationState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (widget.patientER.direction == 1) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(TranslationBase.of(context).pickupLocation), - SizedBox( - height: 15, - ), - InkWell( - onTap: (){ - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PickupLocationFromMap( - latitude: _latitude, - longitude: _longitude, - onPick: (value) { + return AppScaffold( + isShowAppBar: false, + isShowDecPage: false, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.patientER.direction == 1) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).pickupLocation), + SizedBox( + height: 15, + ), + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PickupLocationFromMap( + latitude: _latitude, + longitude: _longitude, + onPick: (value) { + setState(() { + _result = value; + }); + }, + ), + ), + ); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Texts(getSelectFromMapName(context))), + Icon( + FontAwesomeIcons.mapMarkerAlt, + size: 24, + color: Colors.black, + ) + ], + ), + ), + ), + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).pickupSpot), + SizedBox( + height: 5, + ), + InkWell( + onTap: () { + setState(() { + _isInsideHome = !_isInsideHome; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).insideHome), + leading: Checkbox( + value: _isInsideHome, + onChanged: (value) { setState(() { - _result = value; + _isInsideHome = value; }); }, ), ), - ); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getSelectFromMapName(context)), - Icon( - FontAwesomeIcons.mapMarkerAlt, - size: 24, - color: Colors.black, - ) - ], ), ), - ), - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).pickupSpot), - SizedBox( - height: 5, - ), - InkWell( - onTap: () { - setState(() { - _isInsideHome = !_isInsideHome; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Texts(TranslationBase.of(context).insideHome), - leading: Checkbox( - activeColor: Colors.red[800], - value: _isInsideHome, - onChanged: (value) { - setState(() { - _isInsideHome = value; - }); - }, - ), - ), + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).haveAppo), + SizedBox( + height: 5, ), - ), - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).haveAppo), - SizedBox( - height: 5, - ), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - if (myAppointment == null) { - getAppointment(); + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + if (myAppointment == null) { + getAppointment(); + setState(() { + _haveAppointment = HaveAppointment.YES; + }); + } + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).yes), + leading: Radio( + value: HaveAppointment.YES, + groupValue: _haveAppointment, + onChanged: (value) { + if (myAppointment == null) { + getAppointment(); + setState(() { + _haveAppointment = value; + }); + } + }, + ), + ), + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { setState(() { - _haveAppointment = HaveAppointment.YES; + _haveAppointment = HaveAppointment.NO; + myAppointment = null; }); - } - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Texts(TranslationBase.of(context).yes), - leading: Radio( - value: HaveAppointment.YES, - groupValue: _haveAppointment, - activeColor: Colors.red[800], - onChanged: (value) { - if (myAppointment == null) { - getAppointment(); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).no), + leading: Radio( + value: HaveAppointment.NO, + groupValue: _haveAppointment, + onChanged: (value) { setState(() { _haveAppointment = value; + myAppointment = null; }); - } - }, + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _haveAppointment = HaveAppointment.NO; - myAppointment = null; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Texts(TranslationBase.of(context).no), - leading: Radio( - value: HaveAppointment.NO, - groupValue: _haveAppointment, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _haveAppointment = value; - myAppointment = null; - }); - }, - ), - ), - ), - ), - ), - ], - ), - if (myAppointment != null) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - AppointmentCard( - appointment: myAppointment, - ) ], ), - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).dropoffLocation), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectHospitalDialog( - widget.amRequestViewModel.hospitals); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + if (myAppointment != null) + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(getHospitalName(TranslationBase.of(context).pickupLocation)), - Icon( - Icons.arrow_drop_down, - size: 24, - color: Colors.black, + SizedBox( + height: 12, + ), + AppointmentCard( + appointment: myAppointment, ) ], ), + SizedBox( + height: 12, ), - ), - ], - ), - if (widget.patientER.direction == 0) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(TranslationBase.of(context).pickupLocation), - SizedBox( - height: 15, - ), - InkWell( - onTap: () { - confirmSelectHospitalDialog( - widget.amRequestViewModel.hospitals); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, + Texts(TranslationBase.of(context).dropoffLocation), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectHospitalDialog( + widget.amRequestViewModel.hospitals); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(getHospitalName( + TranslationBase.of(context).pickupLocation)), + Icon( + Icons.arrow_drop_down, + size: 24, + color: Colors.black, + ) + ], + ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getHospitalName(TranslationBase.of(context).pickupLocation)), - Icon( - Icons.arrow_drop_down, - size: 24, - color: Colors.black, - ) - ], + ), + ], + ), + if (widget.patientER.direction == 0) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).pickupLocation), + SizedBox( + height: 15, + ), + InkWell( + onTap: () { + confirmSelectHospitalDialog( + widget.amRequestViewModel.hospitals); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(getHospitalName( + TranslationBase.of(context).pickupLocation)), + Icon( + Icons.arrow_drop_down, + size: 24, + color: Colors.black, + ) + ], + ), ), ), - ), - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).dropoffLocation), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PickupLocationFromMap( - latitude: _latitude, - longitude: _longitude, - onPick: (value) { - setState(() { - _result = value; - }); - }, + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).dropoffLocation), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PickupLocationFromMap( + latitude: _latitude, + longitude: _longitude, + onPick: (value) { + setState(() { + _result = value; + }); + }, + ), ), + ); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Texts(getSelectFromMapName(context))), + Icon( + FontAwesomeIcons.mapMarkerAlt, + size: 24, + color: Colors.black, + ) + ], ), - ); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getSelectFromMapName(context)), - Icon( - FontAwesomeIcons.mapMarkerAlt, - size: 24, - color: Colors.black, - ) - ], ), ), - ), - ], + ], + ), + SizedBox( + height: 45, ), - SizedBox( - height: 45, - ), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - if (_result == null || _selectedHospital == null) - AppToast.showErrorToast( - message: TranslationBase.of(context).selectAll); - else - setState(() { - widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; - if (widget.patientER.direction == 0) { - widget.patientER.pickupLocationLattitude = _result.geometry.location.lat.toString(); - widget.patientER.pickupLocationLongitude = _result.geometry.location.lng.toString(); - widget.patientER.dropoffLocationLattitude = _selectedHospital.latitude; - widget.patientER.dropoffLocationLongitude = _selectedHospital.longitude; - } else { - widget.patientER.pickupLocationLattitude = _selectedHospital.latitude; - widget.patientER.pickupLocationLongitude = _selectedHospital.longitude; - widget.patientER.dropoffLocationLattitude = _result.geometry.location.lat.toString(); - widget.patientER.dropoffLocationLongitude = _result.geometry.location.lng.toString(); - } + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child: SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + if (_result == null || _selectedHospital == null) + AppToast.showErrorToast( + message: TranslationBase.of(context).selectAll); + else + setState(() { + widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; + if (widget.patientER.direction == 0) { + widget.patientER.pickupLocationLattitude = + _result.geometry.location.lat.toString(); + widget.patientER.pickupLocationLongitude = + _result.geometry.location.lng.toString(); + widget.patientER.dropoffLocationLattitude = + _selectedHospital.latitude; + widget.patientER.dropoffLocationLongitude = + _selectedHospital.longitude; + } else { + widget.patientER.pickupLocationLattitude = + _selectedHospital.latitude; + widget.patientER.pickupLocationLongitude = + _selectedHospital.longitude; + widget.patientER.dropoffLocationLattitude = + _result.geometry.location.lat.toString(); + widget.patientER.dropoffLocationLongitude = + _result.geometry.location.lng.toString(); + } - widget.patientER.latitude = widget.patientER.pickupLocationLattitude; - widget.patientER.longitude = widget.patientER.pickupLocationLongitude; - widget.patientER.dropoffLocationName = _selectedHospital.name; - widget.patientER.createdBy = widget.amRequestViewModel.user.patientID; - widget.patientER.isOutPatient = widget.amRequestViewModel.user.outSA; - widget.patientER.patientIdentificationID = widget.amRequestViewModel.user.patientIdentificationNo; - widget.patientER.pickupDateTime = DateUtil.convertDateToStringLocation(DateTime.now()); - widget.patientER.pickupLocationName = _result.formattedAddress; - widget.patientER.projectID = widget.amRequestViewModel.user.projectID; - widget.patientER.requesterFileNo = widget.amRequestViewModel.user.patientID; - widget.patientER.requesterIsOutSA = false; - widget.patientER.lineItemNo =0; - widget.patientER.requesterMobileNo = widget.amRequestViewModel.user.mobileNumber; + widget.patientER.latitude = + widget.patientER.pickupLocationLattitude; + widget.patientER.longitude = + widget.patientER.pickupLocationLongitude; + widget.patientER.dropoffLocationName = + _selectedHospital.name; + widget.patientER.createdBy = + widget.amRequestViewModel.user.patientID; + widget.patientER.isOutPatient = + widget.amRequestViewModel.user.outSA; + widget.patientER.patientIdentificationID = widget + .amRequestViewModel.user.patientIdentificationNo; + widget.patientER.pickupDateTime = + DateUtil.convertDateToStringLocation(DateTime.now()); + widget.patientER.pickupLocationName = + _result.formattedAddress; + widget.patientER.projectID = + widget.amRequestViewModel.user.projectID; + widget.patientER.requesterFileNo = + widget.amRequestViewModel.user.patientID; + widget.patientER.requesterIsOutSA = false; + widget.patientER.lineItemNo = 0; + widget.patientER.requesterMobileNo = + widget.amRequestViewModel.user.mobileNumber; - if (_haveAppointment == HaveAppointment.YES) { - widget.patientER.appointmentNo = myAppointment.appointmentNo.toString(); - widget.patientER.appointmentClinicName = myAppointment.clinicName; - widget.patientER.appointmentDoctorName = myAppointment.doctorNameObj; - widget.patientER.appointmentBranch = myAppointment.projectName; - widget.patientER.appointmentTime = myAppointment.appointmentDate; - widget.patientER.haveAppointment = true; - } else { - widget.patientER.appointmentNo = "0"; - widget.patientER.appointmentClinicName = null; - widget.patientER.appointmentDoctorName = null; - widget.patientER.appointmentBranch = null; - widget.patientER.appointmentTime = null; - widget.patientER.haveAppointment = false; - } + if (_haveAppointment == HaveAppointment.YES) { + widget.patientER.appointmentNo = + myAppointment.appointmentNo.toString(); + widget.patientER.appointmentClinicName = + myAppointment.clinicName; + widget.patientER.appointmentDoctorName = + myAppointment.doctorNameObj; + widget.patientER.appointmentBranch = + myAppointment.projectName; + widget.patientER.appointmentTime = + myAppointment.appointmentDate; + widget.patientER.haveAppointment = true; + } else { + widget.patientER.appointmentNo = "0"; + widget.patientER.appointmentClinicName = null; + widget.patientER.appointmentDoctorName = null; + widget.patientER.appointmentBranch = null; + widget.patientER.appointmentTime = null; + widget.patientER.haveAppointment = false; + } - widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; - widget.changeCurrentTab(2); - }); - }, - label: TranslationBase.of(context).next, - ), - ) - ], + widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; + widget.changeCurrentTab(2); + }); + }, + label: TranslationBase.of(context).next, ), ), ); @@ -457,11 +481,13 @@ class _PickupLocationState extends State { } String getSelectFromMapName(context) { - return _result != null ? _result.formattedAddress : TranslationBase.of(context).selectMap; + return _result != null + ? _result.formattedAddress + : TranslationBase.of(context).selectMap; } getAppointment() { - ProgressDialogUtil.showProgressDialog(context); + GifLoaderDialogUtils.showMyDialog(context); widget.amRequestViewModel.getAppointmentHistory().then((value) { if (widget.amRequestViewModel.state == ViewState.Error || widget.amRequestViewModel.state == ViewState.ErrorLocal) { @@ -469,7 +495,7 @@ class _PickupLocationState extends State { } else if (widget .amRequestViewModel.appoitmentAllHistoryResultList.length > 0) { - ProgressDialogUtil.hideProgressDialog(context); + GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, MaterialPageRoute( @@ -491,14 +517,15 @@ class _PickupLocationState extends State { } }); } else { - ProgressDialogUtil.hideProgressDialog(context); + GifLoaderDialogUtils.hideDialog(context); setState(() { _haveAppointment = HaveAppointment.NO; }); - AppToast.showErrorToast(message: TranslationBase.of(context).noAppointment); + AppToast.showErrorToast( + message: TranslationBase.of(context).noAppointment); } }).catchError((e) { - ProgressDialogUtil.hideProgressDialog(context); + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: e); }); } diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart index 69669ed3..0770448e 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart @@ -1,15 +1,15 @@ import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; -import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; -import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; -import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; import 'package:diplomaticquarterapp/core/model/er/get_all_transportation_method_list_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; enum Direction { ToHospital, FromHospital } enum Way { OneWay, TwoWays } @@ -58,251 +58,267 @@ class _SelectTransportationMethodState @override Widget build(BuildContext context) { - return SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).transportHeading), - ...List.generate( - widget.amRequestViewModel.amRequestModeList.length, - (index) => InkWell( - onTap: () { - setState(() { - _erTransportationMethod = - widget.amRequestViewModel.amRequestModeList[index]; - }); - }, - child: Container( - margin: EdgeInsets.all(5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - children: [ - Expanded( - flex: 3, - child: ListTile( - title: Text(widget.amRequestViewModel - .amRequestModeList[index].title), - leading: Radio( - value: widget - .amRequestViewModel.amRequestModeList[index], - groupValue: _erTransportationMethod, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _erTransportationMethod = value; - }); - }, + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: false, + isShowDecPage: false, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).transportHeading), + ...List.generate( + widget.amRequestViewModel.amRequestModeList.length, + (index) => InkWell( + onTap: () { + setState(() { + _erTransportationMethod = + widget.amRequestViewModel.amRequestModeList[index]; + }); + }, + child: Container( + margin: EdgeInsets.all(5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + children: [ + Expanded( + flex: 3, + child: ListTile( + title: Texts(projectViewModel.isArabic + ? widget.amRequestViewModel + .amRequestModeList[index].titleAR + : widget.amRequestViewModel + .amRequestModeList[index].title), + leading: Radio( + value: widget + .amRequestViewModel.amRequestModeList[index], + groupValue: _erTransportationMethod, + onChanged: (value) { + setState(() { + _erTransportationMethod = value; + }); + }, + ), ), ), - ), - Expanded( - flex: 1, - child: Texts( - TranslationBase.of(context).sar+' ${widget.amRequestViewModel.amRequestModeList[index].price}'), - ) - ], + Expanded( + flex: 1, + child: Texts(TranslationBase.of(context).sar + + ' ${widget.amRequestViewModel.amRequestModeList[index].price}'), + ) + ], + ), ), ), ), - ), - SizedBox( - height: 12, - ), - Texts(TranslationBase.of(context).directionHeading), - SizedBox( - height: 5, - ), - Container( - width: double.maxFinite, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _direction = Direction.ToHospital; - }); - }, - child: Container( - width: double.maxFinite, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).toHospital), - leading: Radio( - value: Direction.ToHospital, - groupValue: _direction, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _direction = value; - }); - }, + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).directionHeading), + SizedBox( + height: 5, + ), + Container( + width: double.maxFinite, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _direction = Direction.ToHospital; + }); + }, + child: Container( + width: double.maxFinite, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).toHospital), + leading: Radio( + value: Direction.ToHospital, + groupValue: _direction, + onChanged: (value) { + setState(() { + _direction = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _direction = Direction.FromHospital; - }); - }, - child: Container( - width: double.maxFinite, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).fromHospital), - leading: Radio( - value: Direction.FromHospital, - groupValue: _direction, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _direction = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _direction = Direction.FromHospital; + }); + }, + child: Container( + width: double.maxFinite, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).fromHospital), + leading: Radio( + value: Direction.FromHospital, + groupValue: _direction, + onChanged: (value) { + setState(() { + _direction = value; + }); + }, + ), ), ), ), ), - ), - ], + ], + ), ), - ), - if (_direction == Direction.ToHospital) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, - ), - Texts(TranslationBase.of(context).directionHeading), - SizedBox( - height: 5, - ), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _way = Way.OneWay; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).oneDirec), - leading: Radio( - value: Way.OneWay, - groupValue: _way, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _way = value; - }); - }, + if (_direction == Direction.ToHospital) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 8, + ), + Texts(TranslationBase.of(context).directionHeading), + SizedBox( + height: 5, + ), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _way = Way.OneWay; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).oneDirec), + leading: Radio( + value: Way.OneWay, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _way = Way.TwoWays; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text(TranslationBase.of(context).twoDirec), - leading: Radio( - value: Way.TwoWays, - groupValue: _way, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _way = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _way = Way.TwoWays; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).twoDirec), + leading: Radio( + value: Way.TwoWays, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value; + }); + }, + ), ), ), ), ), - ), - ], - ), - ], - ), - SizedBox( - height: 15, - ), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.patientER.transportationMethodId =(widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); - widget.patientER.direction = _direction == Direction.ToHospital ? 1 : 0; - widget.patientER.tripType = _way == Way.TwoWays ? 0 : 1; - widget.patientER.selectedAmbulate = (widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); - widget.patientER.patientERTransportationMethod = _erTransportationMethod; - widget.patientER.orderServiceID = _orderService.getIdOrderService(); - widget.patientER.pickupUrgency = 1; - widget.patientER.lineItemNo = 1; - widget.patientER.cost = _erTransportationMethod.price; - widget.patientER.vAT = _erTransportationMethod.vAT ?? 0; - widget.patientER.totalPrice = _erTransportationMethod.totalPrice; - widget.changeCurrentTab(1); - }); - }, - label: TranslationBase.of(context).next, + ], + ), + ], + ), + SizedBox( + height: 15, ), - ) - ], + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child: SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.patientER.transportationMethodId = (widget + .amRequestViewModel.amRequestModeList + .indexOf(_erTransportationMethod) + + 1); + widget.patientER.direction = + _direction == Direction.ToHospital ? 1 : 0; + widget.patientER.tripType = _way == Way.TwoWays ? 0 : 1; + widget.patientER.selectedAmbulate = (widget + .amRequestViewModel.amRequestModeList + .indexOf(_erTransportationMethod) + + 1); + widget.patientER.patientERTransportationMethod = + _erTransportationMethod; + widget.patientER.orderServiceID = + _orderService.getIdOrderService(); + widget.patientER.pickupUrgency = 1; + widget.patientER.lineItemNo = 1; + widget.patientER.cost = _erTransportationMethod.price; + widget.patientER.vAT = _erTransportationMethod.vAT ?? 0; + widget.patientER.totalPrice = + _erTransportationMethod.totalPrice; + widget.changeCurrentTab(1); + }); + }, + label: TranslationBase.of(context).next, ), ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart index 8fd72b8f..6140dc62 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.da import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/core/enum/Ambulate.dart'; @@ -18,89 +19,93 @@ class Summary extends StatefulWidget { _SummaryState createState() => _SummaryState(); } -//TODO it should be dynamic class _SummaryState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(TranslationBase.of(context).RRTSummary), - SizedBox(height: 5,), - Container( - width: double.infinity, - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts(TranslationBase.of(context).transportMethod,color: Colors.grey,), - Texts('${widget.patientER.patientERTransportationMethod.title}',bold: true,), - SizedBox(height: 8,), + return AppScaffold( + isShowDecPage: false, + isShowAppBar: false, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).RRTSummary), + SizedBox(height: 5,), + Container( + width: double.infinity, + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).transportMethod,color: Colors.grey,), + Texts('${widget.patientER.patientERTransportationMethod.title}',bold: true,), + SizedBox(height: 8,), - Texts(TranslationBase.of(context).directions,color: Colors.grey,), - Texts('From Hospital',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).directions,color: Colors.grey,), + Texts(widget.patientER.direction ==0? TranslationBase.of(context).toHospital:TranslationBase.of(context).fromHospital,bold: true,), + SizedBox(height: 8,), - Texts('Pickup Location',color: Colors.grey,), - Texts('SZR Medical Center',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).pickupLocation,color: Colors.grey,), + Texts('${widget.patientER.pickupLocationName}',bold: true,), + SizedBox(height: 8,), - Texts('Drop off location',color: Colors.grey,), - Texts('6199, Al Ameen wlfn nif',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).dropoffLocation,color: Colors.grey,), + Texts('${widget.patientER.dropoffLocationName}',bold: true,), + SizedBox(height: 8,), - Texts('Select Ambulate',color: Colors.grey,), - Texts('${widget.patientER.ambulate.getAmbulateTitle(context)}',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).selectAmbulate,color: Colors.grey,), + Texts('${widget.patientER.ambulate.getAmbulateTitle(context)}',bold: true,), + SizedBox(height: 8,), - Texts('Note',color: Colors.grey,), - Texts('${widget.patientER.requesterNote?? '---'}',bold: true,), - SizedBox(height: 8,), - ], - ), - ), - SizedBox(height: 20,), - Texts('Bill Amount',textAlign: TextAlign.start,), - SizedBox(height: 5,), - Container( - height: 55, - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8) + Texts(TranslationBase.of(context).notes,color: Colors.grey,), + Texts('${widget.patientER.requesterNote?? '---'}',bold: true,), + SizedBox(height: 8,), + ], + ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts('Total amount payable:'), - Texts('SR ${widget.patientER.patientERTransportationMethod.totalPrice}') - ], + SizedBox(height: 20,), + Texts(TranslationBase.of(context).billAmount,textAlign: TextAlign.start,), + SizedBox(height: 5,), + Container( + height: 55, + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8) + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).patientShareTotal+':'), + Texts(TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}') + ], + ), ), - ), - SizedBox(height: 45,), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child:SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - label: TranslationBase.of(context).send, - onTap: () async { - await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER); + SizedBox(height: 45,), - } - ), - ) - ], + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child:SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + label: TranslationBase.of(context).send, + onTap: () async { + await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER); + + } ), ), ); diff --git a/lib/pages/ErService/OrderLogPage.dart b/lib/pages/ErService/OrderLogPage.dart index 6929cd0b..7d2a4a5b 100644 --- a/lib/pages/ErService/OrderLogPage.dart +++ b/lib/pages/ErService/OrderLogPage.dart @@ -30,28 +30,28 @@ class OrderLogPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ OrderLogItem( - title: 'Request ID', + title: TranslationBase.of(context).reqId, value: amRequestViewModel.patientAllPresOrdersList[index].iD .toString(), ), OrderLogItem( - title: 'Status', + title: TranslationBase.of(context).orderStatus, value: amRequestViewModel .patientAllPresOrdersList[index].description, ), OrderLogItem( - title: 'Pickup Date', + title: TranslationBase.of(context).pickupDate, value: DateUtil.getDayMonthYearDateFormatted( DateUtil.convertStringToDate(amRequestViewModel .patientAllPresOrdersList[index].createdOn)), ), OrderLogItem( - title: 'Pickup Location', + title: TranslationBase.of(context).pickupLocation, value: amRequestViewModel .patientAllPresOrdersList[index].pickupLocationName, ), OrderLogItem( - title: 'Drop off Location', + title: TranslationBase.of(context).dropoffLocation, value: amRequestViewModel .patientAllPresOrdersList[index].dropoffLocationName, ), diff --git a/lib/pages/ErService/widgets/StepsWidget.dart b/lib/pages/ErService/widgets/StepsWidget.dart index c5864710..56b3de6b 100644 --- a/lib/pages/ErService/widgets/StepsWidget.dart +++ b/lib/pages/ErService/widgets/StepsWidget.dart @@ -13,7 +13,8 @@ class StepsWidget extends StatelessWidget { @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return projectViewModel.isArabic? Stack( + return projectViewModel.isArabic? + Stack( children: [ Container( height: 50, @@ -29,7 +30,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: 0, + right: 0, child: InkWell( onTap: () => changeCurrentTab(0), child: Container( @@ -51,7 +52,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: MediaQuery.of(context).size.width * 0.3, + right: MediaQuery.of(context).size.width * 0.3, child: InkWell( onTap: () => index >= 2 ? changeCurrentTab(1) : null, child: Container( @@ -73,7 +74,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: MediaQuery.of(context).size.width * 0.6, + right: MediaQuery.of(context).size.width * 0.6, child: InkWell( onTap: () => index >= 3 ? changeCurrentTab(2) : null, child: Container( @@ -95,7 +96,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: 0, + left: 0, child: InkWell( onTap: () => index == 2 ?changeCurrentTab(3):null, child: Container( @@ -117,7 +118,8 @@ class StepsWidget extends StatelessWidget { ), ), ], - ):Stack( + ): + Stack( children: [ Container( height: 50, @@ -133,7 +135,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: 0, + left: 0, child: InkWell( onTap: () => changeCurrentTab(0), child: Container( @@ -155,7 +157,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: MediaQuery.of(context).size.width * 0.3, + left: MediaQuery.of(context).size.width * 0.3, child: InkWell( onTap: () => index >= 2 ? changeCurrentTab(1) : null, child: Container( @@ -177,7 +179,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: MediaQuery.of(context).size.width * 0.6, + left: MediaQuery.of(context).size.width * 0.6, child: InkWell( onTap: () => index >= 3 ? changeCurrentTab(2) : null, child: Container( @@ -199,7 +201,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: 0, + right: 0, child: InkWell( onTap: () => index == 2 ?changeCurrentTab(3):null, child: Container( diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index cb08bd17..c5cf339b 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1250,6 +1250,7 @@ class TranslationBase { String get infoCMC => localizedValues['infoCMC'][locale.languageCode]; String get instructionAgree => localizedValues['instructionAgree'][locale.languageCode]; String get reqId => localizedValues['reqId'][locale.languageCode]; + String get ordersLog => localizedValues['RRT-orders-log'][locale.languageCode]; } From bbd953ae43cf5c49d3ec8df0e370d10ae653c1cf Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Tue, 19 Jan 2021 11:41:55 +0300 Subject: [PATCH 13/14] Order Delivery Driver tracking [inprogress] --- .../map_markers/destination_map_marker.png | Bin 0 -> 4974 bytes assets/images/map_markers/driver-pin.png | Bin 0 -> 13918 bytes .../images/map_markers/source_map_marker.png | Bin 0 -> 5311 bytes lib/config/config.dart | 4 +- lib/config/localized_values.dart | 5 + lib/core/model/pharmacies/order_model.dart | 28 ++- lib/pages/pharmacy/order/Order.dart | 17 +- lib/pages/pharmacy/order/OrderDetails.dart | 177 ++++++++------- lib/pages/pharmacy/order/TrackDriver.dart | 211 ++++++++++++++++++ lib/uitl/translations_delegate_base.dart | 1 + pubspec.yaml | 4 +- 11 files changed, 356 insertions(+), 91 deletions(-) create mode 100644 assets/images/map_markers/destination_map_marker.png create mode 100644 assets/images/map_markers/driver-pin.png create mode 100644 assets/images/map_markers/source_map_marker.png create mode 100644 lib/pages/pharmacy/order/TrackDriver.dart diff --git a/assets/images/map_markers/destination_map_marker.png b/assets/images/map_markers/destination_map_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..4f4eca3531d475b04944fc5341f98cd910e313eb GIT binary patch literal 4974 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 literal 0 HcmV?d00001 diff --git a/assets/images/map_markers/driver-pin.png b/assets/images/map_markers/driver-pin.png new file mode 100644 index 0000000000000000000000000000000000000000..9d16ceca4edf852f6c6e969dce7a63342a332073 GIT binary patch literal 13918 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 X{s0vkKK?KU0ihtHD%~h)9`^qMzf|}` literal 0 HcmV?d00001 diff --git a/assets/images/map_markers/source_map_marker.png b/assets/images/map_markers/source_map_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..4b493b097b087a641bfbadb013f4a59935c7f394 GIT binary patch literal 5311 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 R8VCRY002ovPDHLkV1k@%_;3IK literal 0 HcmV?d00001 diff --git a/lib/config/config.dart b/lib/config/config.dart index 4315f13c..795da85b 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi'; const PACKAGES_CATEGORIES = '/api/categories'; const PACKAGES_PRODUCTS = '/api/products'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; //const BASE_PHARMACY_URL = 'http://swd-pharapp-01:7200/api/'; const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 387dbcb1..b103825c 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1449,4 +1449,9 @@ const Map localizedValues = { "en": "View List of Children", "ar": "عرض قائمة الأطفال" }, + + "trackDeliveryDriver": { + "en": "Track Delivery Driver", + "ar": "trackDeliveryDriver" + }, }; diff --git a/lib/core/model/pharmacies/order_model.dart b/lib/core/model/pharmacies/order_model.dart index 027d1f81..c0a12caa 100644 --- a/lib/core/model/pharmacies/order_model.dart +++ b/lib/core/model/pharmacies/order_model.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; List orderModelFromJson(String str) => List.from(json.decode(str).map((x) => OrderModel.fromJson(x))); @@ -306,7 +307,22 @@ class IngAddress { String customerAttributes; DateTime createdOnUtc; dynamic province; - LatLong latLong; + String latLong; + + LatLng getLocation(){ + if(latLong.contains(',')){ + var parts = latLong.trim().split(','); + if(parts.length == 2){ + var lat = double.tryParse(parts.first); + var lng = double.tryParse(parts.last); + if(lat != null || lng != null) { + var location = LatLng(lat, lng); + return location; + } + } + } + return null; + } factory IngAddress.fromJson(Map json) => IngAddress( id: json["id"], @@ -326,7 +342,7 @@ class IngAddress { customerAttributes: json["customer_attributes"], createdOnUtc: DateTime.parse(json["created_on_utc"]), province: json["province"], - latLong: latLongValues.map[json["lat_long"]], + latLong: json["lat_long"], ); Map toJson() => { @@ -347,7 +363,7 @@ class IngAddress { "customer_attributes": customerAttributes, "created_on_utc": createdOnUtc.toIso8601String(), "province": province, - "lat_long": latLongValues.reverse[latLong], + "lat_long": latLong, }; } @@ -491,9 +507,9 @@ class OrderModelCustomer { isSystemAccount: json["is_system_account"], systemName: json["system_name"], lastIpAddress: lastIpAddressValues.map[json["last_ip_address"]], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - lastLoginDateUtc: DateTime.parse(json["last_login_date_utc"]), - lastActivityDateUtc: DateTime.parse(json["last_activity_date_utc"]), + createdOnUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["created_on_utc"]) : null, + lastLoginDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_login_date_utc"]) : null, + lastActivityDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_activity_date_utc"]) : null, registeredInStoreId: json["registered_in_store_id"], roleIds: List.from(json["role_ids"].map((x) => x)), ); diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index 576bf2a0..5bb4ea42 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -924,6 +924,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix } Widget getCancelledOrder(OrderModelViewModel model){ + for(int i=0 ; i< model.order.length; i++){ if( model.order[i].orderStatusId == 40 || model.order[i].orderStatusId == 996 || model.order[i].orderStatusId == 200){ @@ -1136,13 +1137,17 @@ class _OrderPageState extends State with SingleTickerProviderStateMix ), ), ); - } + int test = Test()["1"]; + } } - - - - - +class Test{ + static const values = { + "1":1, + "2":2, + "3":3 + }; + int operator [](String key) => values[key]; +} \ No newline at end of file diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 5438663d..d5d064a7 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/order/TrackDriver.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -46,6 +47,7 @@ class _OrderDetailsPageState extends State { var model; var isCancel = false; var isRefund = false; + var isActiveDelivery = true; var dataIsCancel; var dataIsRefund; @@ -105,9 +107,9 @@ class _OrderDetailsPageState extends State { color: getStatusBackgroundColor(), borderRadius: BorderRadius.circular(30.0)), child: Text( - languageID == "ar" - ? widget.orderModel.orderStatusn.toString(): - widget.orderModel.orderStatus.toString().substring(12) , + languageID == "ar" + ? widget.orderModel.orderStatusn.toString(): + widget.orderModel.orderStatus.toString().substring(12) , // TranslationBase.of(context).delivered, style: TextStyle( color: Colors.white, @@ -125,8 +127,8 @@ class _OrderDetailsPageState extends State { children: [ Text( widget.orderModel.shippingAddress.firstName - .toString() - .substring(10) + + .toString() + .substring(10) + ' ' + widget.orderModel.shippingAddress.lastName .toString() @@ -141,18 +143,18 @@ class _OrderDetailsPageState extends State { Container( margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.orderModel.shippingAddress.address1 - .toString() - .substring(9), - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ),] + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.orderModel.shippingAddress.address1 + .toString() + .substring(9), + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ),] ), ), Container( @@ -162,8 +164,8 @@ class _OrderDetailsPageState extends State { children: [ Text( widget.orderModel.shippingAddress.address2 - .toString() - .substring(9) + + .toString() + .substring(9) + ' ' + widget.orderModel.shippingAddress.country .toString() + @@ -231,7 +233,7 @@ class _OrderDetailsPageState extends State { Container( child: flutterImage.Image.asset( widget.orderModel.shippingRateComputationMethodSystemName != - "Shipping.Aramex" + "Shipping.Aramex" ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", fit: BoxFit.contain, @@ -320,19 +322,19 @@ class _OrderDetailsPageState extends State { physics: ScrollPhysics(), itemCount:widget.orderModel.orderItems.length, itemBuilder: (context, index){ - return Container( - child: productTile(productName: widget.orderModel.orderItems[index].product.name.toString(), - productPrice: widget.orderModel.orderItems[index].product.price.toString(), - productRate: widget.orderModel.orderItems[index].product.approvedRatingSum.toDouble(), - productReviews:widget.orderModel.orderItems[index].product.approvedTotalReviews, - totalPrice: "${(widget.orderModel.orderItems[index].product.price - * widget.orderModel.orderItems[index].quantity).toStringAsFixed(2)}", - qyt: widget.orderModel.orderItems[index].quantity.toString(), - isOrderDetails:true, - imgs: widget.orderModel.orderItems[index].product.images != null && - widget.orderModel.orderItems[index].product.images.length != 0 - ? widget.orderModel.orderItems[index].product.images [0].src.toString() - : null, + return Container( + child: productTile(productName: widget.orderModel.orderItems[index].product.name.toString(), + productPrice: widget.orderModel.orderItems[index].product.price.toString(), + productRate: widget.orderModel.orderItems[index].product.approvedRatingSum.toDouble(), + productReviews:widget.orderModel.orderItems[index].product.approvedTotalReviews, + totalPrice: "${(widget.orderModel.orderItems[index].product.price + * widget.orderModel.orderItems[index].quantity).toStringAsFixed(2)}", + qyt: widget.orderModel.orderItems[index].quantity.toString(), + isOrderDetails:true, + imgs: widget.orderModel.orderItems[index].product.images != null && + widget.orderModel.orderItems[index].product.images.length != 0 + ? widget.orderModel.orderItems[index].product.images [0].src.toString() + : null, status: widget.orderModel.orderStatusId, product: widget.orderModel.orderItems[index].product, ), @@ -510,58 +512,81 @@ class _OrderDetailsPageState extends State { ), widget.orderModel.orderStatusId == 10 ? InkWell( - onTap: () { - model.makeOrder(); - }, - child: Container( + onTap: () { + model.makeOrder(); + }, + child: Container( // margin: EdgeInsets.only(top: 20.0), - height: 50.0, - color: Colors.transparent, - child: Container( - padding: EdgeInsets.only(left: 130.0, right: 130.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.green, - style: BorderStyle.solid, - width: 4.0), - color: Colors.green, - borderRadius: BorderRadius.circular(5.0)), - child: Center( - child: Text( - TranslationBase.of(context).payOnline, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ), + height: 50.0, + color: Colors.transparent, + child: Container( + padding: EdgeInsets.only(left: 130.0, right: 130.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 4.0), + color: Colors.green, + borderRadius: BorderRadius.circular(5.0)), + child: Center( + child: Text( + TranslationBase.of(context).payOnline, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, ), ), - ) + ), + ), + ), + ) : Container(), // getCancelOrder(canCancel, canRefund), isCancel ? InkWell( - onTap: () { - presentConfirmDialog(model, - widget.orderModel.id); //(widget.orderModel.id)); + onTap: () { + presentConfirmDialog(model, + widget.orderModel.id); //(widget.orderModel.id)); // - }, - child: Container( + }, + child: Container( // padding: EdgeInsets.only(left: 13.0, right: 13.0, top: 5.0), - height: 50.0, - color: Colors.transparent, - child: Center( - child: Text( - TranslationBase.of(context).cancelOrder, - style: TextStyle( - color: Colors.red[900], - fontWeight: FontWeight.bold, - decoration: TextDecoration.underline), - ), - ), - ), - ) + height: 50.0, + color: Colors.transparent, + child: Center( + child: Text( + TranslationBase.of(context).cancelOrder, + style: TextStyle( + color: Colors.red[900], + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline), + ), + ), + ), + ) + : Container(), + isActiveDelivery + ? InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => TrackDriver(order: widget.orderModel), + )); + }, + child: Container( + height: 50.0, + color: Colors.transparent, + child: Center( + child: Text( + TranslationBase.of(context).trackDeliveryDriver, + style: TextStyle( + color: Colors.green[900], + fontWeight: FontWeight.normal, + decoration: TextDecoration.none), + ), + ), + ), + ) : Container(), ], ), diff --git a/lib/pages/pharmacy/order/TrackDriver.dart b/lib/pages/pharmacy/order/TrackDriver.dart new file mode 100644 index 00000000..b9a8056f --- /dev/null +++ b/lib/pages/pharmacy/order/TrackDriver.dart @@ -0,0 +1,211 @@ +import 'dart:async'; + +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_polyline_points/flutter_polyline_points.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:location/location.dart'; + + +class TrackDriver extends StatefulWidget { + final OrderModel order; + TrackDriver({this.order}); + + @override + State createState() => _TrackDriverState(); +} + +class _TrackDriverState extends State { + OrderModel _order; + + Completer _controller = Completer(); + + + double CAMERA_ZOOM = 16; + double CAMERA_TILT = 0; + double CAMERA_BEARING = 30; + LatLng SOURCE_LOCATION = null; + LatLng DEST_LOCATION = null; + + // for my drawn routes on the map + Set _polylines = Set(); + List polylineCoordinates = []; + PolylinePoints polylinePoints; + + Set _markers = Set(); + + BitmapDescriptor sourceIcon; // for my custom marker pins + BitmapDescriptor destinationIcon; // for my custom marker pins + Location location;// wrapper around the location API + + @override + void initState() { + _order = widget.order; + DEST_LOCATION = _order.shippingAddress.getLocation(); + location = new Location(); + polylinePoints = PolylinePoints(); + setSourceAndDestinationIcons(); + } + + @override + Widget build(BuildContext context) { + return new Scaffold( + body: GoogleMap( + myLocationEnabled: true, + compassEnabled: true, + markers: _markers, + polylines: _polylines, + mapType: MapType.normal, + initialCameraPosition: _orderDeliveryLocationCamera(), + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + showPinsOnMap(); + }, + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: _goToDriver, + label: Text('To the lake!'), + icon: Icon(Icons.directions_boat), + ), + ); + } + + + void setSourceAndDestinationIcons() async { + sourceIcon = await BitmapDescriptor.fromAssetImage( + ImageConfiguration(devicePixelRatio: 2.5), + 'assets/images/map_markers/source_map_marker.png'); + + destinationIcon = await BitmapDescriptor.fromAssetImage( + ImageConfiguration(devicePixelRatio: 2.5), + 'assets/images/map_markers/destination_map_marker.png'); + } + + CameraPosition _orderDeliveryLocationCamera(){ + + final CameraPosition orderDeliveryLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: DEST_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return orderDeliveryLocCamera; + } + + CameraPosition _driverLocationCamera(){ + final CameraPosition driverLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return driverLocCamera; + } + + + Future _goToOrderDeliveryLocation() async { + final GoogleMapController controller = await _controller.future; + final CameraPosition orderDeliveryLocCamera = _orderDeliveryLocationCamera(); + controller.animateCamera(CameraUpdate.newCameraPosition(orderDeliveryLocCamera)); + } + + Future _goToDriver() async { + final GoogleMapController controller = await _controller.future; + final CameraPosition driverLocCamera = _driverLocationCamera(); + controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); + } + + + Future _fitCameraBetweenBothPoints() async { + final GoogleMapController controller = await _controller.future; + final CameraPosition driverLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); + } + + void showPinsOnMap() { + // source pin + if(SOURCE_LOCATION != null){ + setState(() { + var pinPosition = SOURCE_LOCATION; + _markers.add(Marker( + markerId: MarkerId('sourcePin'), + position: pinPosition, + icon: sourceIcon + )); + }); + } + + // destination pin + if(DEST_LOCATION != null){ + setState(() { + var destPosition = DEST_LOCATION; + _markers.add(Marker( + markerId: MarkerId('destPin'), + position: destPosition, + icon: destinationIcon + )); + }); + } + // set the route lines on the map from source to destination + // for more info follow this tutorial + // drawRoute(); + } + + void updatePinOnMap() async { + // create a new CameraPosition instance + // every time the location changes, so the camera + // follows the pin as it moves with an animation + CameraPosition cPosition = CameraPosition( + zoom: CAMERA_ZOOM, + tilt: CAMERA_TILT, + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + ); + final GoogleMapController controller = await _controller.future; + controller.animateCamera(CameraUpdate.newCameraPosition(cPosition)); + // do this inside the setState() so Flutter gets notified + // that a widget update is due + setState(() { + // updated position + var pinPosition = SOURCE_LOCATION; + + // the trick is to remove the marker (by id) + // and add it again at the updated location + _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); + _markers.add(Marker( + markerId: MarkerId('sourcePin'), + position: pinPosition, // updated position + icon: sourceIcon + )); + }); + } + + void drawRoute() async { + return; // Ignore draw Route + + List result = await polylinePoints.getRouteBetweenCoordinates( + GOOGLE_API_KEY, + SOURCE_LOCATION.latitude, + SOURCE_LOCATION.longitude, + DEST_LOCATION.latitude, + DEST_LOCATION.longitude); + if(result.isNotEmpty){ + result.forEach((PointLatLng point){ + polylineCoordinates.add( + LatLng(point.latitude,point.longitude) + ); + }); + setState(() { + _polylines.add(Polyline( + width: 5, // set the width of the polylines + polylineId: PolylineId('poly'), + color: Color.fromARGB(255, 40, 122, 198), + points: polylineCoordinates + )); + }); + } + } +} \ No newline at end of file diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 63cf8a44..954af3b9 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -550,6 +550,7 @@ class TranslationBase { localizedValues['Prescriptions'][locale.languageCode]; String get history => localizedValues['History'][locale.languageCode]; String get orderNo => localizedValues['OrderNo'][locale.languageCode]; + String get trackDeliveryDriver => localizedValues['trackDeliveryDriver'][locale.languageCode]; String get orderDetails => localizedValues['OrderDetails'][locale.languageCode]; String get vitalSign => localizedValues['VitalSign'][locale.languageCode]; diff --git a/pubspec.yaml b/pubspec.yaml index 785e831d..24589cbb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -82,7 +82,8 @@ dependencies: google_maps_flutter: ^1.0.3 - + flutter_polyline_points: ^0.1.0 + location: ^2.3.5 # Qr code Scanner barcode_scan_fix: ^1.0.2 @@ -183,6 +184,7 @@ flutter: # assets: assets: - assets/images/ + - assets/images/map_markers/ - assets/images/pharmacy/ - assets/images/medical/ - assets/images/new-design/ From 0b1014a91cddd4482e4ac8e973cb9b373b932fef Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 19 Jan 2021 14:23:42 +0200 Subject: [PATCH 14/14] fix blood sugar service on my tracker --- lib/config/config.dart | 2 + lib/config/localized_values.dart | 44 ++ .../blood_sugar/DiabtecPatientResult.dart | 2 +- .../WeekDiabtectResultAverage.dart | 2 +- .../service/medical/BloodSugarService.dart | 31 +- .../medical/blood_sugar_view_model.dart | 27 +- .../blood_suger/AddBloodSugarPage.dart | 476 +++++++++--------- .../my_trackers/blood_suger/BloodMonthly.dart | 33 +- .../my_trackers/blood_suger/BloodYeaPage.dart | 33 +- .../blood_suger/blood_sugar_home_page.dart | 19 +- .../blood_suger/blood_sugar_weekly_page.dart | 82 ++- .../medical/my_trackers/my_trackers.dart | 10 +- lib/uitl/translations_delegate_base.dart | 11 + 13 files changed, 442 insertions(+), 330 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 0c6b5d59..5bfb8d49 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -289,6 +289,8 @@ const ADD_DIABTEC_RESULT = 'Services/Patients.svc/REST/Patient_AddDiabtecResult' const GET_BLOOD_PRESSURE_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage'; const GET_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_GetBloodPressureResult'; const ADD_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_AddBloodPressureResult'; +const UPDATE_DIABETIC_RESULT = 'Services/Patients.svc/REST/Patient_UpdateDiabeticResult'; + const GET_WEIGHT_PRESSURE_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage'; const GET_WEIGHT_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 295a09f9..970eb78d 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1481,4 +1481,48 @@ const Map localizedValues = { "en": "Orders Log", "ar": "سجل الطلبات" }, + "blood-sugar": { + "en": "Blood Sugar", + "ar": "سكر الدم" + }, + + "my-tracker": { + "en": "My Tracker", + "ar": "قراءاتي" + }, + "weekly": { + "en": "Weekly", + "ar": "أسبوعي" + }, + "monthly": { + "en": "Monthly", + "ar": "شهري" + }, + "yearly": { + "en": "Yearly", + "ar": "سنوي" + }, + "measured": { + "en": "Measured", + "ar": "قياس" + }, + "sugar-add": { + "en": "Enter Blood Sugar Value", + "ar": "أدخل قيمة قراءة السكر" + }, + "other": { + "en": "Other", + "ar": "آخر" + }, + "measure-unit": { + "en": "Measure unit", + "ar": "وحدة القياس" + }, + "measure-time": { + "en": "Measure time", + "ar": "وقت القياس" + },"update": { + "en": "Update", + "ar": "تعديل" + }, }; diff --git a/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart b/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart index 5b95409e..86263155 100644 --- a/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart +++ b/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart @@ -17,7 +17,7 @@ class DiabtecPatientResult { int patientID; var remark; var resultDesc; - int resultValue; + dynamic resultValue; String unit; var weekAverageResult; String weekDesc; diff --git a/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart b/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart index c18e5433..3b1a8d9c 100644 --- a/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart +++ b/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart @@ -1,7 +1,7 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class WeekDiabtectResultAverage { - int dailyAverageResult; + dynamic dailyAverageResult; DateTime dateChart; WeekDiabtectResultAverage({this.dailyAverageResult, this.dateChart}); diff --git a/lib/core/service/medical/BloodSugarService.dart b/lib/core/service/medical/BloodSugarService.dart index 09fe9fe9..e0c5007c 100644 --- a/lib/core/service/medical/BloodSugarService.dart +++ b/lib/core/service/medical/BloodSugarService.dart @@ -69,25 +69,34 @@ class BloodSugarService extends BaseService { }, body: Map()); } - addDiabtecResult( - {String bloodSugerDateChart, - String bloodSugerResult, - String diabtecUnit, - int measuredTime}) async { + addDiabtecResult({String bloodSugerDateChart, String bloodSugerResult, String diabtecUnit, int measuredTime}) async { hasError = false; super.error = ""; - Map body = Map(); body['BloodSugerDateChart'] = bloodSugerDateChart; body['BloodSugerResult'] = bloodSugerResult; body['DiabtecUnit'] = diabtecUnit; - body['MeasuredTime'] =2;// measuredTime; + body['MeasuredTime'] = measuredTime; body['isDentalAllowedBackend'] = false; - await baseAppClient.post(ADD_BLOOD_PRESSURE_RESULT, - onSuccess: (response, statusCode) async { - var asd =""; - }, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + updateDiabtecResult({DateTime month,DateTime hour,String bloodSugerResult,String diabtecUnit, int measuredTime,int lineItemNo}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['BloodSugerResult'] = bloodSugerResult; + body['DiabtecUnit'] = diabtecUnit; + body['BloodSugerDateChart'] = '${month.year}-${month.month}-${month.day} ${hour.hour}:${hour.minute}:00'; + body['isDentalAllowedBackend'] = false; + body['MeasuredTime'] = measuredTime; + body['LineItemNo'] = lineItemNo; + await baseAppClient.post(UPDATE_DIABETIC_RESULT, + onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/viewModels/medical/blood_sugar_view_model.dart b/lib/core/viewModels/medical/blood_sugar_view_model.dart index fb00f80e..29cc3249 100644 --- a/lib/core/viewModels/medical/blood_sugar_view_model.dart +++ b/lib/core/viewModels/medical/blood_sugar_view_model.dart @@ -45,7 +45,6 @@ class BloodSugarViewMode extends BaseViewModel { x: index, y: bloodSugarService .monthDiabtectResultAverageList[index].weekAverageResult)); - var asd=""; } bloodSugarService.yearDiabtecResultAverageList.forEach((element) { @@ -94,11 +93,7 @@ class BloodSugarViewMode extends BaseViewModel { ]; } - addDiabtecResult( - {String bloodSugerDateChart, - String bloodSugerResult, - String diabtecUnit, - int measuredTime}) async { + Future addDiabtecResult({String bloodSugerDateChart, String bloodSugerResult, String diabtecUnit, int measuredTime}) async { setState(ViewState.BusyLocal); await bloodSugarService.addDiabtecResult( bloodSugerDateChart: bloodSugerDateChart, @@ -113,7 +108,25 @@ class BloodSugarViewMode extends BaseViewModel { setState(ViewState.Idle); } } - + + Future updateDiabtecResult({DateTime month,DateTime hour,String bloodSugerResult,String diabtecUnit, int measuredTime,int lineItemNo}) async { + setState(ViewState.BusyLocal); + await bloodSugarService.updateDiabtecResult( + bloodSugerResult: bloodSugerResult , + diabtecUnit: diabtecUnit, + hour: hour, + measuredTime: measuredTime, + lineItemNo: lineItemNo, + month: month); + if (bloodSugarService.hasError) { + error = bloodSugarService.error; + setState(ViewState.Error); + } else { + await getBloodSugar(); + setState(ViewState.Idle); + } + } + } diff --git a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart index 00f06a25..f39479ac 100644 --- a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart @@ -3,18 +3,37 @@ import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_mo import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.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/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:feather_icons_flutter/feather_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:provider/provider.dart'; class AddBloodSugarPage extends StatefulWidget { + final DateTime bloodSugarDate; + final String measureUnitSelectedType; + final bool isUpdate; + final String measuredTime; + final String bloodSugarValue; + final int lineItemNo; + final BloodSugarViewMode bloodSugarViewMode; + + AddBloodSugarPage( + {Key key, + this.bloodSugarDate, + this.measureUnitSelectedType, + this.isUpdate = false, + this.measuredTime, + this.bloodSugarValue, this.lineItemNo, this.bloodSugarViewMode}) + : super(key: key); + @override _AddBloodSugarPageState createState() => _AddBloodSugarPageState(); } @@ -24,7 +43,7 @@ class _AddBloodSugarPageState extends State { DateTime bloodSugarDate = DateTime.now(); DateTime timeSugarDate = DateTime.now(); String measureUnitSelectedType = 'mg/dlt'; - int measuredTime=1; + int measuredTime = 1; final List measureUnitList = ['mg/dlt', 'mol/L']; final List measureTimeEnList = [ 'Before Breakfast', @@ -39,270 +58,229 @@ class _AddBloodSugarPageState extends State { 'Other', ]; final List measureTimeArList = [ - 'Before Breakfast', - 'After Breakfast', - 'Before Lunch', - 'After Lunch', - 'Before Dinner', - 'After Dinner', - 'Before Sleep', - 'After Sleep', - 'Fasting', - 'Other', + "قبل الإفطار", + "بعد الإفطار", + "بعد الغداء", + "بعد الغداء", + "قبل العشاء", + "بعد العشاء", + "قبل النوم", + "بعد النوم", + "صائم", + "آخر", ]; String measureTimeSelectedType; + @override + void initState() { + super.initState(); + if (widget.isUpdate) { + bloodSugarDate = widget.bloodSugarDate; + timeSugarDate = widget.bloodSugarDate; + measureUnitSelectedType = widget.measureUnitSelectedType; + if (measureTimeEnList.contains(widget.measuredTime)) + measuredTime = measureTimeEnList.indexOf(widget.measuredTime); + else if (measureTimeArList.contains(widget.measuredTime)) + measuredTime = measureTimeArList.indexOf(widget.measuredTime); + _bloodSugarValueController.text = widget.bloodSugarValue; + } + } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - showTaskOptions() { - showModalBottomSheet( - backgroundColor: Colors.white, - context: context, - builder: (BuildContext bc) { - return Container( - padding: EdgeInsets.symmetric(vertical: 12.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), - topRight: Radius.circular(16.0))), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(3.0)), - width: 40.0, - height: 6.0, - ), - InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 18.0, vertical: 18.0), - child: Row( - children: [ - Icon( - FeatherIcons.share, - color: Theme - .of(context) - .primaryColor, - size: 18.0, - ), - SizedBox(width: 24.0), - Texts('Share Task', - variant: "body2Link", color: Colors.grey[800]), - ], - ), - ), - ), - InkWell( - onTap: () { - Navigator.pop(context); - // Navigator.of(context).push(SlideUpPageRoute(widget: PostTaskIndex(task: new Task(category: task?.category, description: task?.description, title: task?.title)))); - }, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 18.0, vertical: 18.0), - child: Row( - children: [ - Icon( - FeatherIcons.copy, - color: Theme - .of(context) - .primaryColor, - size: 18.0, - ), - SizedBox(width: 24.0), - Texts('Post Similar Task', - variant: "body2Link", color: Colors.grey[800]), - ], - ), - ), + return AppScaffold( + isShowAppBar: true, + appBarTitle: widget.isUpdate + ? TranslationBase.of(context).update + : TranslationBase.of(context).add, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.all(15), + child: Column( + children: [ + SizedBox( + height: 15, + ), + NewTextFields( + hintText: TranslationBase.of(context).sugarAdd, + controller: _bloodSugarValueController, + keyboardType: TextInputType.number, + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectMeasureUnitDialog(); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureUnitSelectedType), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], ), - ], + ), ), - ); - }); - } - - return BaseView( - builder: (_, model, w) => - AppScaffold( - isShowAppBar: true, - appBarTitle: 'Add', - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: 'Enter Blood Sugar Value', - controller: _bloodSugarValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureUnitDialog(); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureUnitSelectedType), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], - ), - ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime(DateTime - .now() - .year - 1, 1, 1), - maxTime: DateTime.now(), - onConfirm: (date) { - print('confirm $date'); - setState(() { - bloodSugarDate = date; - }); - }, - currentTime: bloodSugarDate, - locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts('Date'), - Texts(getDate()), - ], - ), - ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showTimePicker( - context, showTitleActions: true, - onConfirm: (date) { - print('confirm $date'); - setState(() { - timeSugarDate = date; - }); - }, - currentTime: timeSugarDate, - locale: projectViewModel.localeType); + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showDatePicker(context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 1, 1, 1), + maxTime: DateTime.now(), onConfirm: (date) { + setState(() { + bloodSugarDate = date; + }); }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts('Time'), Texts(getTime())], - ), - ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic - ? measureTimeEnList - : measureTimeArList); + currentTime: bloodSugarDate, + locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).date), + Texts(getDate()), + ], + ), + ), + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showTimePicker(context, showTitleActions: true, + onConfirm: (date) { + setState(() { + timeSugarDate = date; + }); }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureTimeSelectedType ?? 'Others'), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], - ), - ), - ), - ], + currentTime: timeSugarDate, + locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).time), + Texts(getTime()) + ], + ), ), ), - ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery - .of(context) - .size - .width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - loading: model.state == ViewState.BusyLocal, - label: 'SAVE', textColor: Colors.white, onTap: () { - if (_bloodSugarValueController.text.isNotEmpty) { - model.addDiabtecResult(diabtecUnit: measureUnitSelectedType, - measuredTime: measuredTime, - bloodSugerResult:_bloodSugarValueController.text.toString(), - bloodSugerDateChart: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', - - ); - } - }), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectMeasureTimeDialog(projectViewModel.isArabic + ? measureTimeArList + : measureTimeEnList); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureTimeSelectedType ?? + TranslationBase.of(context).other), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], + ), + ), ), - ), + ], ), + ), + ), + bottomSheet: Container( + color: Colors.transparent, + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.2, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: SecondaryButton( + label: TranslationBase.of(context).save, + textColor: Colors.white, + onTap: () { + if (_bloodSugarValueController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + if (widget.isUpdate) + widget.bloodSugarViewMode.updateDiabtecResult( + month: bloodSugarDate, + hour: timeSugarDate, + diabtecUnit: measureUnitSelectedType, + measuredTime: measuredTime, + lineItemNo: widget.lineItemNo, + bloodSugerResult: + _bloodSugarValueController.text.toString()).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(widget.bloodSugarViewMode.state == ViewState.Error) + AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); + + }); + else + widget.bloodSugarViewMode.addDiabtecResult( + diabtecUnit: measureUnitSelectedType, + measuredTime: measuredTime, + bloodSugerResult: + _bloodSugarValueController.text.toString(), + bloodSugerDateChart: + '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', + ).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(widget.bloodSugarViewMode.state == ViewState.Error) + AppToast.showErrorToast(message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); + }); + } + }), + ), + ), ); } String getDate() { - return "${DateUtil.getMonth(bloodSugarDate.month)} ${bloodSugarDate - .day}, ${bloodSugarDate.year}"; + return "${DateUtil.getMonth(bloodSugarDate.month)} ${bloodSugarDate.day}, ${bloodSugarDate.year}"; } String getTime() { @@ -314,7 +292,7 @@ class _AddBloodSugarPageState extends State { context: context, child: RadioStringDialog( radioList: measureUnitList, - title: 'Measure unit', + title: TranslationBase.of(context).measureUnit, selectedValue: measureUnitSelectedType, onValueSelected: (value) { setState(() { @@ -330,7 +308,7 @@ class _AddBloodSugarPageState extends State { context: context, child: RadioStringDialog( radioList: list, - title: 'Measure time', + title: TranslationBase.of(context).measureTime, selectedValue: measureTimeSelectedType, onValueSelected: (value) { setState(() { diff --git a/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart b/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart index fdd7b348..fa49382f 100644 --- a/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart +++ b/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart @@ -1,13 +1,16 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class BloodMonthlyPage extends StatelessWidget { final List> data; @@ -17,6 +20,7 @@ class BloodMonthlyPage extends StatelessWidget { : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( body: ListView( children: [ @@ -34,7 +38,7 @@ class BloodMonthlyPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -46,7 +50,7 @@ class BloodMonthlyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context,projectViewModel), ), ], ), @@ -56,7 +60,7 @@ class BloodMonthlyPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context,ProjectViewModel projectViewModel) { List tableRow = []; tableRow.add( TableRow( @@ -64,14 +68,15 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), + topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +87,11 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -96,11 +101,11 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -110,20 +115,22 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), + topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), ), height: 40), ), + ], ), ); diff --git a/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart b/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart index 47f87847..69f00e61 100644 --- a/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart @@ -1,12 +1,15 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class BloodYearPage extends StatelessWidget { final List> data; @@ -17,6 +20,7 @@ class BloodYearPage extends StatelessWidget { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( body: ListView( children: [ @@ -34,7 +38,7 @@ class BloodYearPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -46,7 +50,7 @@ class BloodYearPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context,projectViewModel), ), ], ), @@ -56,7 +60,7 @@ class BloodYearPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context,ProjectViewModel projectViewModel) { List tableRow = []; tableRow.add( TableRow( @@ -64,14 +68,15 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), + topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +87,11 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -96,11 +101,11 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -110,20 +115,22 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), + topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), ), height: 40), ), + ], ), ); diff --git a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart index 71df9a3a..70cdea0f 100644 --- a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart +++ b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart @@ -43,7 +43,7 @@ class _BloodSugarHomePageState extends State onModelReady: (model) => model.getBloodSugar(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: 'Blood Sugar', + appBarTitle: TranslationBase.of(context).bloodSugar, baseViewModel: model, body: Scaffold( extendBodyBehindAppBar: true, @@ -81,21 +81,21 @@ class _BloodSugarHomePageState extends State unselectedLabelColor: Colors.grey[800], tabs: [ Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.33, child: Center( - child: Texts('Weekly'), + child: Texts(TranslationBase.of(context).weekly), ), ), Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.33, child: Center( - child: Texts('Monthly'), + child: Texts(TranslationBase.of(context).monthlyT), ), ), Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.34, child: Center( - child: Texts('Yearly'), + child: Texts(TranslationBase.of(context).yearly), ), ), ], @@ -116,6 +116,7 @@ class _BloodSugarHomePageState extends State BloodSugarWeeklyPage( data: model.getBloodWeeklySeries(), diabtecPatientResult: model.weekDiabtecPatientResult, + bloodSugarViewMode: model, ), BloodMonthlyPage( data: model.getBloodMonthlyTimeSeriesSales(), @@ -132,13 +133,13 @@ class _BloodSugarHomePageState extends State ), floatingActionButton: InkWell( onTap: () { - Navigator.push(context, FadePage(page: AddBloodSugarPage())); + Navigator.push(context, FadePage(page: AddBloodSugarPage(bloodSugarViewMode: model,))); }, child: Container( width: 55, height: 55, decoration: BoxDecoration( - shape: BoxShape.circle, color: HexColor('515B5D')), + shape: BoxShape.circle, color:Theme.of(context).primaryColor), child: Center( child: Icon( Icons.add, diff --git a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart index 4b007929..139548e1 100644 --- a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart +++ b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart @@ -1,22 +1,31 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; + +import 'AddBloodSugarPage.dart'; class BloodSugarWeeklyPage extends StatelessWidget { final List> data; final List diabtecPatientResult; + final BloodSugarViewMode bloodSugarViewMode; - const BloodSugarWeeklyPage({Key key, this.data, this.diabtecPatientResult}) + const BloodSugarWeeklyPage({Key key, this.data, this.diabtecPatientResult, this.bloodSugarViewMode}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( body: ListView( children: [ @@ -34,7 +43,7 @@ class BloodSugarWeeklyPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -46,7 +55,7 @@ class BloodSugarWeeklyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context, projectViewModel,bloodSugarViewMode), ), ], ), @@ -56,7 +65,8 @@ class BloodSugarWeeklyPage extends StatelessWidget { ); } - List fullData() { + List fullData( + BuildContext context, ProjectViewModel projectViewModel, BloodSugarViewMode bloodSugarViewMode) { List tableRow = []; tableRow.add( TableRow( @@ -64,14 +74,19 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +97,11 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -96,11 +111,11 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -110,11 +125,11 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -124,14 +139,19 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Edit', + TranslationBase.of(context).edit, color: Colors.white, fontSize: 15, ), @@ -203,12 +223,30 @@ class BloodSugarWeeklyPage extends StatelessWidget { ), ), Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Icon(Icons.edit), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodSugarPage( + isUpdate: true, + bloodSugarDate: diabtec.dateChart, + measuredTime: diabtec.measuredDesc, + bloodSugarValue: diabtec.resultValue.toString(), + lineItemNo: diabtec.lineItemNo, + measureUnitSelectedType: diabtec.unit, + bloodSugarViewMode: bloodSugarViewMode, + ), + ), + ); + }, + child: Container( + height: 70, + padding: EdgeInsets.all(10), + color: Colors.white, + child: Center( + child: Icon(Icons.edit), + ), ), ), ), diff --git a/lib/pages/medical/my_trackers/my_trackers.dart b/lib/pages/medical/my_trackers/my_trackers.dart index ecdf5a53..5e5c4527 100644 --- a/lib/pages/medical/my_trackers/my_trackers.dart +++ b/lib/pages/medical/my_trackers/my_trackers.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -11,7 +13,7 @@ class MyTrackers extends StatelessWidget { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: 'My Tracker', + appBarTitle: TranslationBase.of(context).myTracker, isShowAppBar: true, body: SingleChildScrollView( child: Container( @@ -41,7 +43,7 @@ class MyTrackers extends StatelessWidget { children: [ Image.asset('assets/tracker/blood-suger.png',width: 60.0,), SizedBox(height: 15,), - Text('Blood Sugar'), + Texts(TranslationBase.of(context).bloodSugar), ], ), ), @@ -65,7 +67,7 @@ class MyTrackers extends StatelessWidget { children: [ Image.asset('assets/tracker/blood-pressure.png',width: 60.0,), SizedBox(height: 15,), - Text('Blood Pressure'), + Texts(TranslationBase.of(context).bloodPressure), ], ), ), @@ -94,7 +96,7 @@ class MyTrackers extends StatelessWidget { children: [ Image.asset('assets/tracker/weight.png',width: 60.0,), SizedBox(height: 15,), - Text('Weight'), + Texts(TranslationBase.of(context).weight), ], ), ), diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index c5cf339b..b9be8fe4 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1251,6 +1251,17 @@ class TranslationBase { String get instructionAgree => localizedValues['instructionAgree'][locale.languageCode]; String get reqId => localizedValues['reqId'][locale.languageCode]; String get ordersLog => localizedValues['RRT-orders-log'][locale.languageCode]; + String get bloodSugar => localizedValues['blood-sugar'][locale.languageCode]; + String get myTracker => localizedValues['my-tracker'][locale.languageCode]; + String get weekly => localizedValues['weekly'][locale.languageCode]; + String get monthlyT => localizedValues['monthly'][locale.languageCode]; + String get yearly => localizedValues['yearly'][locale.languageCode]; + String get measured => localizedValues['measured'][locale.languageCode]; + String get sugarAdd => localizedValues['sugar-add'][locale.languageCode]; + String get other => localizedValues['other'][locale.languageCode]; + String get measureUnit => localizedValues['measure-unit'][locale.languageCode]; + String get measureTime => localizedValues['measure-time'][locale.languageCode]; + String get update => localizedValues['update'][locale.languageCode]; }