From d8bd7d145da84659bc011097b15ac5b8300dadbc Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Thu, 17 Dec 2020 18:30:04 +0300 Subject: [PATCH 01/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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/16] 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 f5d478fd27233d7cc996182dc4cb4edea39ae5dc Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 18 Jan 2021 17:55:49 +0200 Subject: [PATCH 13/16] re-design child vaccine and fix some funcrionalities --- lib/config/localized_values.dart | 34 ++ .../vaccination_table_service.dart | 15 +- .../vaccination_table_view_model.dart | 9 +- .../all_habib_medical_service_page.dart | 20 +- .../ChildVaccines/add_newchild_page.dart | 122 +++--- lib/pages/ChildVaccines/child_page.dart | 168 ++++---- .../ChildVaccines/child_vaccines_page.dart | 372 +++++++++--------- .../dialogs/SelectGenderDialog.dart | 16 +- .../ChildVaccines/vaccinationtable_page.dart | 217 ++++++---- .../vital_sing_chart_and_detials.dart | 1 + lib/uitl/date_uitl.dart | 2 +- lib/uitl/translations_delegate_base.dart | 15 +- 12 files changed, 563 insertions(+), 428 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 6245735d..596bb086 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -242,6 +242,10 @@ const Map localizedValues = { "en": "Email Sent Successfully", "ar": "تم إرسال البريد الإلكتروني بنجاح" }, + "EmailSentError": { + "en": "Error Sending Email", + "ar": "خطأ في إرسال البريد الإلكتروني" + }, "close": {"en": "Close", "ar": "مغلق"}, "booked": {"en": "Booked", "ar": "محجوز"}, "confirmed": {"en": "Confirmed", "ar": "مؤكد"}, @@ -1218,6 +1222,10 @@ const Map localizedValues = { "en": "Send a copy of this report to the email", "ar": "أرسل نسخة من هذا التقرير إلى البريد الإلكتروني" }, + "update-email-msg": { + "en": "Email updated", + "ar": "تم تحديث البريد الالكتروني" + }, "update-email": {"en": "Update Email", "ar": "تحديث البريد الالكتروني"}, "booked-success": { "en": "The appointment has been successfully booked.", @@ -1465,4 +1473,30 @@ const Map localizedValues = { "en": "Nearest ER", "ar": "أقرب ER" }, + "covid19_driveThrueTest": { + "en": "'Covid-19- Drive-Thru Test'", + "ar": "Covid-19- الفحص من خلال القيادة" + }, + "E-Referral": { + "en": "'E-Referral'", + "ar": "الإحالة الإلكترونية" + }, + "childName": { + "en": "'CHILD NAME'", + "ar": "إسم الطفل" + }, + "recordDeleted": { + "en": "'Record Deleted'", + "ar": "تم حذف السجل" + }, + "msg_email_address_up_to_date": { + "en": "Please ensure that the email address is up-to-date and process to view the schedule", + "ar": "يرجى التأكد من أن عنوان البريد الإلكتروني محدث وأن العملية لعرض الجدول الزمني" + }, + "add-new-child": {"en" : "ADD NEW CHILD", "ar": "إضافة طفل جديد"}, + "visit": {"en" : "Visit", "ar": "الزيارة"}, + "send-child-email-msg": {"en" : "Send the child's schedule to the email", "ar": "أرسل جدول الطفل إلى البريد الإلكتروني"}, + "vaccination-add-child-msg": {"en" : "Add the child's information below to receive the schedule of vaccinations.", "ar": "أضف معلومات الطفل أدناه للحصول على جدول التطعيمات."}, + "child_added_successfully": {"en" : "Child added successfully", "ar": "تمت إضافة الطفل بنجاح"}, + }; diff --git a/lib/core/service/childvaccines/vaccination_table_service.dart b/lib/core/service/childvaccines/vaccination_table_service.dart index 7f987b76..fc2b40e9 100644 --- a/lib/core/service/childvaccines/vaccination_table_service.dart +++ b/lib/core/service/childvaccines/vaccination_table_service.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_vaccination_table.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import '../base_service.dart'; class VaccinationTableService extends BaseService { @@ -10,19 +12,18 @@ class VaccinationTableService extends BaseService { - Future getCreateVaccinationTableOrders() async { + Future getCreateVaccinationTableOrders(List_BabyInformationModel babyInfo, bool sendEmail) async { + String babyBDFormatted = "${DateUtil.convertDateToString(babyInfo.dOB)}/"; + hasError = false; await getUser(); - body['BabyName']="fffffffffff eeeeeeeeeeeeee"; - body['DOB'] = "/Date(1585774800000+0300)/"; + body['BabyName']= babyInfo.babyName; + body['DOB'] = babyBDFormatted; body['EmailAddress'] = user.emailAddress; body['isDentalAllowedBackend'] = false; - body['SendEmail'] = false; + body['SendEmail'] = sendEmail; body['IsLogin'] =true; - - - await baseAppClient.post(GET_TABLE_REQUEST, onSuccess: (dynamic response, int statusCode) { createVaccinationTableModelList.clear(); diff --git a/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart b/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart index 3b72dd50..d0ccb8a1 100644 --- a/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart +++ b/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_vaccination_table.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/add_new_child_service.dart'; @@ -11,14 +12,12 @@ import '../base_view_model.dart'; class VaccinationTableViewModel extends BaseViewModel{ VaccinationTableService _creteVaccinationTableService = locator(); + List get creteVaccinationTableModelList=> _creteVaccinationTableService.createVaccinationTableModelList; - // String get creteVaccinationTableContent => _creteVaccinationTableService.userAgreementContent; - //String get userAgreementContent => _creteNewBabyService.v//_reportsService.userAgreementContent; - List get creteVaccinationTableModelList=> _creteVaccinationTableService.createVaccinationTableModelList;//.createNewBabyModelList; - getCreateVaccinationTable() async { + getCreateVaccinationTable(List_BabyInformationModel babyInfo, bool sendEmail) async { setState(ViewState.Busy); - await _creteVaccinationTableService.getCreateVaccinationTableOrders();//getCreateNewBabyOrders(); + await _creteVaccinationTableService.getCreateVaccinationTableOrders(babyInfo, sendEmail);//getCreateNewBabyOrders(); if ( _creteVaccinationTableService.hasError) { error = _creteVaccinationTableService.error; diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart index 1359ab8d..3c3c18c1 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart @@ -203,7 +203,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/al-habib_online_payment_service_icon.png', - title: 'Covid-19- Drive-Thru Test', + title: TranslationBase.of(context).covid19_driveThrueTest, ), ServicesContainer( onTap: () { @@ -227,7 +227,7 @@ class _AllHabibMedicalServiceState extends State { ), ), imageLocation: 'assets/images/pharmacy_logo.png', - title: 'Pharmacy'), + title: TranslationBase.of(context).pharmacy), ServicesContainer( onTap: () => Navigator.push( context, @@ -248,7 +248,7 @@ class _AllHabibMedicalServiceState extends State { : EReferralPage()), ), imageLocation: 'assets/images/ereferral_service_icon.png', - title: 'E-Referral', + title: TranslationBase.of(context).ereferral, ), ServicesContainer( onTap: () => Navigator.push( @@ -259,7 +259,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/family_menu_icon_red.png', - title: 'My Family', + title: TranslationBase.of(context).myFamily, ), if(projectViewModel.havePrivilege(35)) ServicesContainer( @@ -269,7 +269,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/children_vaccines_icon.png', - title: 'Child Vaccines', + title: TranslationBase.of(context).childVaccine, ), ServicesContainer( onTap: () => Navigator.push( @@ -289,7 +289,7 @@ class _AllHabibMedicalServiceState extends State { FadePage(page: SymptomInfo()), ), imageLocation: 'assets/images/new-design/body_icon.png', - title: 'Symptom Checker'), + title: TranslationBase.of(context).symptomCheckerTitle), if(projectViewModel.havePrivilege(36)) ServicesContainer( onTap: () => Navigator.push( @@ -297,7 +297,7 @@ class _AllHabibMedicalServiceState extends State { FadePage(page: BloodDonationPage()), ), imageLocation: 'assets/images/new-design/blood_icon.png', - title: 'Blood Donation', + title: TranslationBase.of(context).bloodD, ), ServicesContainer( onTap: () => Navigator.push( @@ -308,7 +308,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/health_calculator_icon.png', - title: 'Health Calculators', + title: TranslationBase.of(context).calculators, ), ServicesContainer( onTap: () => Navigator.push( @@ -319,7 +319,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/health_convertor_icon.png', - title: 'Health Converter', + title: TranslationBase.of(context).converters, ), if(projectViewModel.havePrivilege(38)) ServicesContainer( @@ -370,7 +370,7 @@ class _AllHabibMedicalServiceState extends State { }, imageLocation: 'assets/images/new-design/twitter_dashboard_icon.png', - title: 'Latest News', + title: TranslationBase.of(context).latestNews, ), ServicesContainer( onTap: () => Navigator.push( diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index 51b89f98..3c0d072b 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -11,6 +11,7 @@ import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/active_medications/DayCheckBoxDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.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'; @@ -84,10 +85,12 @@ class _AddNewChildPageState extends State { @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + return BaseView( builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: "Vaccintion", + appBarTitle: TranslationBase.of(context).vaccination, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -96,10 +99,10 @@ class _AddNewChildPageState extends State { // crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( - height: 50, + height: 20, ), Texts( - "Add the child's information below to recieve the schedule of vaccinations.", + TranslationBase.of(context).vaccinationAddChildMsg, //+model.user.firstName, textAlign: TextAlign.center, ), @@ -107,14 +110,14 @@ class _AddNewChildPageState extends State { height: 12, ), NewTextFields( - hintText: "First Name", + hintText: TranslationBase.of(context).firstName, controller: _firstTextController, ), SizedBox( height: 12, ), NewTextFields( - hintText: "Second Name", + hintText: TranslationBase.of(context).middleName, controller: _secondTextController, ), SizedBox( @@ -124,62 +127,57 @@ class _AddNewChildPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Gender:", + TranslationBase.of(context).gender, textAlign: TextAlign.end, ), ], ), Container( - height: MediaQuery.of(context).size.height * 0.12, width: double.infinity, + height: size.height * 0.12, padding: EdgeInsets.all(12), - - child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, children: [ - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: 175, - color: Colors.white, - child: SecondaryButton( - textColor: - checkedValue == 1 ? Colors.white : Colors.black, - color: checkedValue == 1 ? Colors.red : Colors.white, - - label: "Male", - // - onTap: () { + Expanded( + child: Container( + color: Colors.white, + child: SecondaryButton( + textColor: + checkedValue == 1 ? Colors.white : Colors.black, + color: checkedValue == 1 ? Colors.red : Colors.white, + label: TranslationBase.of(context).male, + onTap: () { + setState(() { + checkedValue = 1; + print("checkedValue=" + checkedValue.toString()); + }); - setState(() { - checkedValue = 1; - print("checkedValue=" + checkedValue.toString()); - }); - - // bloodDetails. - }, + // bloodDetails. + }, + ), ), ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: 175, - color: Colors.white, - child: SecondaryButton( - textColor: - checkedValue == 2 ? Colors.white : Colors.black, - color: checkedValue == 2 ? Colors.red : Colors.white, - label: "Female", - // - onTap: () { - setState(() { - checkedValue = 2; - print("checkedValue=" + checkedValue.toString()); - }); - // bloodDetails.city=_selectedHospital.toString(); + Expanded( + child: Container( + color: Colors.white, + child: SecondaryButton( + textColor: + checkedValue == 2 ? Colors.white : Colors.black, + color: checkedValue == 2 ? Colors.red : Colors.white, + label: TranslationBase.of(context).female, + // + onTap: () { + setState(() { + checkedValue = 2; + print("checkedValue=" + checkedValue.toString()); + }); + // bloodDetails.city=_selectedHospital.toString(); - // bloodDetails. - }, + // bloodDetails. + }, + ), ), ) ], @@ -193,7 +191,7 @@ class _AddNewChildPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Date Of Birth::", + TranslationBase.of(context).dob, textAlign: TextAlign.end, ), ], @@ -249,29 +247,29 @@ class _AddNewChildPageState extends State { color: checkedValue == false ? Colors.white24 : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: "Add", + 63, + 72, + 74, + 1, + ), + label: TranslationBase.of(context).add, // - onTap: () async{ - newChild.babyName = _firstTextController.text + " " + _secondTextController.text; + onTap: () async { + newChild.babyName = _firstTextController.text + + " " + + _secondTextController.text; newChild.gender = checkedValue.toString(); newChild.strDOB = getStartDay(); newChild.tempValue = true; newChild.isLogin = true; await model.createNewBabyOrders(newChild: newChild); - if(model.isAdded){ - AppToast.showSuccessToast(message: "Record Added"); - Navigator.pop(context,model.isAdded); - }else{ - + if (model.isAdded) { + AppToast.showSuccessToast(message: TranslationBase.of(context).childAddedSuccessfully); + Navigator.pop(context, model.isAdded); + } else { //TODO handling error } - }, ), ), @@ -280,7 +278,7 @@ class _AddNewChildPageState extends State { ), ), ), - // bottomSheet: + // bottomSheet: ), ); } diff --git a/lib/pages/ChildVaccines/child_page.dart b/lib/pages/ChildVaccines/child_page.dart index 806a5b71..ae33cc03 100644 --- a/lib/pages/ChildVaccines/child_page.dart +++ b/lib/pages/ChildVaccines/child_page.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/pages/ChildVaccines/add_newchild_page.dart' import 'package:diplomaticquarterapp/pages/ChildVaccines/vaccinationtable_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.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'; @@ -22,30 +23,51 @@ class ChildPage extends StatefulWidget { class _ChildPageState extends State with SingleTickerProviderStateMixin { - DeleteBaby deleteBaby = DeleteBaby(); @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double height = (size.height - kToolbarHeight - 60); + final double itemWidth = size.width / 2; + final double itemHeight = height / 2 + 40; + var checkedValue = true; return BaseView( onModelReady: (model) => model.getNewUserOrders(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: " Vaccination", + appBarTitle: TranslationBase.of(context).vaccination, baseViewModel: model, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 15, right: 15, top: 70), - child: Column( - children: [ - ...List.generate( + body: Container( + height: height * 0.85, + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 8, right: 8, top: 16), + child: GridView.count( + crossAxisCount: 2, + childAspectRatio: (itemWidth / (itemHeight + 0)), + crossAxisSpacing: 10, + mainAxisSpacing: 10, + controller: ScrollController(keepScrollOffset: true), + shrinkWrap: true, + padding: const EdgeInsets.all(4.0), + children: [ + ...List.generate( model.babyInformationModelList.length, - (index) => Container( - margin: EdgeInsets.only( - left: 0, right: 0, bottom: 20), - - decoration: BoxDecoration( + (index) => InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: VaccinationTablePage(model.babyInformationModelList[index]), + ), + ); + }, + child: Container( + margin: EdgeInsets.only( + left: 0, right: 0, bottom: 20), + decoration: BoxDecoration( shape: BoxShape.rectangle, border: Border.all( color: Colors.white, width: 0.5), @@ -54,11 +76,12 @@ class _ChildPageState extends State color: Colors.white, ), padding: EdgeInsets.all(12), - width: 200,//double.infinity, + //double.infinity, child: Column( children: [ Row(children: [ - Texts("CHILD NAME"), + Texts(TranslationBase.of(context) + .childName), ]), Row(children: [ Texts(model @@ -96,19 +119,14 @@ class _ChildPageState extends State Navigator.push( context, FadePage( - - - page: VaccinationTablePage(), - - + page: VaccinationTablePage(model.babyInformationModelList[index]), ), ); - }, ) ]), Row(children: [ - Texts("Birthday"), + Texts(TranslationBase.of(context).dob), ]), Row(children: [ IconButton( @@ -116,9 +134,7 @@ class _ChildPageState extends State 'assets/images/new-design/calender-secondary.png'), tooltip: '', onPressed: () { - setState(() { - - }); + setState(() {}); }, ), Texts(DateUtil.yearMonthDay(model @@ -130,73 +146,71 @@ class _ChildPageState extends State icon: new Image.asset( 'assets/images/new-design/garbage.png'), tooltip: '', - onPressed: ()async { - + onPressed: () async { //===================== - await model.deleteBabyOrders(newChild:deleteBaby ); - + await model.deleteBabyOrders( + newChild: deleteBaby); - deleteBaby.babyID=model.babyInformationModelList[index] + deleteBaby.babyID = model + .babyInformationModelList[index] .babyID; - await model.deleteBabyOrders(newChild:deleteBaby ); - if(model.isDeleted){ - AppToast.showSuccessToast(message: "Record Deleted"); - Navigator.pop(context,model.isDeleted); - }else{ - - //TODO handling error - } - - - - - + await model.deleteBabyOrders( + newChild: deleteBaby); + if (model.isDeleted) { + AppToast.showSuccessToast( + message: + TranslationBase.of(context) + .recordDeleted); + Navigator.pop( + context, model.isDeleted); + } else { + //TODO handling error + } }, ), - Texts("Delete"), + Texts(TranslationBase.of(context) + .deleteView), ]), SizedBox( height: 12, ), ], ), - + ), ), - - - ) - ], - )) + ) + ], + ))), ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue == false - ? Colors.white24 - : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: "ADD NEW CHILD ", - // - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddNewChildPage(), - ), - ).then((value) { - if (value) model.getNewUserOrders(); - }); - }, - ), + bottomSheet: Container( + height: height * 0.15, + width: double.infinity, + padding: EdgeInsets.all(16), + child: SecondaryButton( + textColor: Colors.white, + color: checkedValue == false + ? Colors.white24 + : Color.fromRGBO( + 63, + 72, + 74, + 1, ), + label: TranslationBase.of(context).addNewChild, + // + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddNewChildPage(), + ), + ).then((value) { + if (value) model.getNewUserOrders(); + }); + }, + ), + ), )); } } diff --git a/lib/pages/ChildVaccines/child_vaccines_page.dart b/lib/pages/ChildVaccines/child_vaccines_page.dart index 92f3a0be..38c6b5af 100644 --- a/lib/pages/ChildVaccines/child_vaccines_page.dart +++ b/lib/pages/ChildVaccines/child_vaccines_page.dart @@ -1,10 +1,10 @@ - import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/child_vaccines_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.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/input/text_field.dart'; @@ -13,214 +13,218 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - - class ChildVaccinesPage extends StatefulWidget { @override _ChildVaccinesPageState createState() => _ChildVaccinesPageState(); } class _ChildVaccinesPageState extends State - with SingleTickerProviderStateMixin{ + with SingleTickerProviderStateMixin { TextEditingController titleController = TextEditingController(); - var checkedValue=false; - String addEmail=""; + var checkedValue = false; + String addEmail = ""; + @override Widget build(BuildContext context) { - return BaseView( onModelReady: (model) => model.getUserInformationRequestOrders(), builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - baseViewModel: model, - appBarTitle: " Vaccination",//TranslationBase.of(context).advancePayment, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - SizedBox( - height: 20, - ), - - Padding( - padding: const EdgeInsets.all(10.0), - child:Container( - child: Texts("Welcome back",fontSize: 20,), - ) , - ), - Divider(color:Colors.black , indent: 10, - endIndent: 10,), - SizedBox( - height: 20, - ), - Padding( - padding: const EdgeInsets.all(10.0), - child:Container( - child: Texts("Please ensure that the email address is up-to-date and process to view the schedule",fontSize: 20,), - ) , + isShowAppBar: true, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).vaccination, + //TranslationBase.of(context).advancePayment, + body: SingleChildScrollView( + physics: ScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + child: Texts( + TranslationBase.of(context).welcomeBack, + fontSize: 20, ), - - Divider(color:Colors.black , indent: 10, - endIndent: 10,), - Padding( - padding: const EdgeInsets.all(10.0), - child:Container( - - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - child: TextFields( - fillColor: Colors.red, - - hintText: model.user.emailAddress, - controller: titleController, - fontSize: 20, - hintColor: Colors.black, - fontWeight: FontWeight.w600, - onChanged: (text) { - addEmail=text; - model.user.emailAddress==addEmail?checkedValue=false:checkedValue=true; - - - }, - validator: (value) { - - if (value == null) - { - return model.user.emailAddress; - - } - else - - { - return model.user.emailAddress;} - }, - ), - ), + ), + ), + Divider( + color: Colors.black, + indent: 10, + endIndent: 10, + ), + SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + child: Texts( + TranslationBase.of(context).msg_email_address_up_to_date, + fontSize: 20, ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue== false ?Colors.white24:Color.fromRGBO(63, 72, 74, 1,), - label: "UPDATE EMAIL", - // - onTap: (){ - model.user.emailAddress=addEmail.toString(); - AppToast.showSuccessToast( - message: "Email updated"); - // bloodDetails.city=_selectedHospital.toString(); - - // bloodDetails. - }, - + ), + ), - ), + Divider( + color: Colors.black, + indent: 10, + endIndent: 10, + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + margin: EdgeInsets.only(left: 10, right: 10, top: 15), + child: TextFields( + fillColor: Colors.red, + hintText: model.user.emailAddress, + controller: titleController, + fontSize: 20, + hintColor: Colors.black, + fontWeight: FontWeight.w600, + onChanged: (text) { + addEmail = text; + model.user.emailAddress == addEmail + ? checkedValue = false + : checkedValue = true; + }, + validator: (value) { + if (value == null) { + return model.user.emailAddress; + } else { + return model.user.emailAddress; + } + }, ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: Color.fromRGBO(63, 72, 74, 1,), - label: " VIEW LIST OF CHILDREN", - // - onTap: () => Navigator.push( - context, - FadePage( - page: ChildPage(), - - - - ), + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.12, + width: double.infinity, + padding: EdgeInsets.all(15), + child: SecondaryButton( + textColor: Colors.white, + color: checkedValue == false + ? Colors.white24 + : Color.fromRGBO( + 63, + 72, + 74, + 1, ), - - - ), - ), - - // Texts( - // // TranslationBase.of(context).advancePaymentLabel, - // model.user.emailAddress, - // textAlign: TextAlign.center, - // ), - SizedBox( - height: 12, - ), - SizedBox( - height: 12, - ), - SizedBox( - height: 12, + label: TranslationBase.of(context).updateEmail, + // + onTap: () { + model.user.emailAddress = addEmail.toString(); + AppToast.showSuccessToast( + message: TranslationBase.of(context).updateEmailMsg); + // bloodDetails.city=_selectedHospital.toString(); + + // bloodDetails. + }, + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.12, + width: double.infinity, + padding: EdgeInsets.all(15), + child: SecondaryButton( + textColor: Colors.white, + color: Color.fromRGBO( + 63, + 72, + 74, + 1, ), - - SizedBox( - height: 12, + label: TranslationBase.of(context).viewListChildren, + // + onTap: () => Navigator.push( + context, + FadePage( + page: ChildPage(), + ), ), + ), + ), - SizedBox( - height: 12, - ), + // Texts( + // // TranslationBase.of(context).advancePaymentLabel, + // model.user.emailAddress, + // textAlign: TextAlign.center, + // ), + SizedBox( + height: 12, + ), + SizedBox( + height: 12, + ), + SizedBox( + height: 12, + ), - SizedBox( - height: 10, - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // Center( - // child: Container( - // color: Colors.white, - // width: 350, - // child: InkWell( - // onTap: () { - // showDialog( - // context: context, - // builder: (_) => - // AssetGiffyDialog( - // title: Text( - // "", - // style: TextStyle( - // fontSize: 22.0, - // fontWeight: - // FontWeight - // .w600), - // ), - // image: Image.asset( - // 'assets/images/BloodChrt_EN.png'), - // buttonCancelText: - // Text('cancel'), - // buttonCancelColor: - // Colors.grey, - // onlyCancelButton: true, - // )); - // }, - // child: Container( - // width: 250, - // height: 200, - // child:Image.asset( - // 'assets/images/BloodChrt_EN.png')), - // ), - // ), - // ), - // ], - // ), + SizedBox( + height: 12, + ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ) - ], + SizedBox( + height: 12, ), + SizedBox( + height: 10, + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Center( + // child: Container( + // color: Colors.white, + // width: 350, + // child: InkWell( + // onTap: () { + // showDialog( + // context: context, + // builder: (_) => + // AssetGiffyDialog( + // title: Text( + // "", + // style: TextStyle( + // fontSize: 22.0, + // fontWeight: + // FontWeight + // .w600), + // ), + // image: Image.asset( + // 'assets/images/BloodChrt_EN.png'), + // buttonCancelText: + // Text('cancel'), + // buttonCancelColor: + // Colors.grey, + // onlyCancelButton: true, + // )); + // }, + // child: Container( + // width: 250, + // height: 200, + // child:Image.asset( + // 'assets/images/BloodChrt_EN.png')), + // ), + // ), + // ), + // ], + // ), + + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ) + ], ), - ), + ), + ), ); } } - diff --git a/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart b/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart index 259bbdb7..c08749b8 100644 --- a/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart +++ b/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart @@ -7,8 +7,11 @@ import 'package:flutter/material.dart'; class SelectGenderDialog extends StatefulWidget { final Email; + final Function okFunction; + + const SelectGenderDialog({Key key, this.Email, this.okFunction}) + : super(key: key); - const SelectGenderDialog({Key key, this.Email}) : super(key: key); @override _SelectGenderDialogState createState() => _SelectGenderDialogState(); } @@ -33,9 +36,8 @@ class _SelectGenderDialogState extends State { }); }, child: ListTile( - title: Text("Send the child's schedule to the email\n Tamer.dasdasdas@gmail.com "), - - + title: Text( + "${TranslationBase.of(context).sendChildEmailMsg}\n Tamer.dasdasdas@gmail.com "), ), ), ) @@ -44,7 +46,6 @@ class _SelectGenderDialogState extends State { SizedBox( height: 5.0, ), - SizedBox( height: 5.0, ), @@ -82,7 +83,7 @@ class _SelectGenderDialogState extends State { flex: 1, child: InkWell( onTap: () { - AppToast.showSuccessToast(message: "Email Sended"); + widget.okFunction(); // widget.onValueSelected(beneficiaryType); Navigator.pop(context); }, @@ -105,7 +106,4 @@ class _SelectGenderDialogState extends State { ], ); } - - - } diff --git a/lib/pages/ChildVaccines/vaccinationtable_page.dart b/lib/pages/ChildVaccines/vaccinationtable_page.dart index c160acfb..7b8499e0 100644 --- a/lib/pages/ChildVaccines/vaccinationtable_page.dart +++ b/lib/pages/ChildVaccines/vaccinationtable_page.dart @@ -1,8 +1,13 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/vaccination_table_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/reports_monthly_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.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'; @@ -12,91 +17,161 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'dialogs/SelectGenderDialog.dart'; class VaccinationTablePage extends StatelessWidget { + final List_BabyInformationModel babyInfo; + + VaccinationTablePage(this.babyInfo); + @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double height = (size.height - kToolbarHeight - 60); + var checkedValue; return BaseView( - onModelReady: (model) => model.getCreateVaccinationTable(),//getUserTermsAndConditions(), + onModelReady: (model) => model.getCreateVaccinationTable(babyInfo, false), builder: (_, model, w) => AppScaffold( isShowAppBar: true, baseViewModel: model, - appBarTitle: "Vaccination", - body: SingleChildScrollView( - child:Container( - margin: EdgeInsets.only(left: 15,right: 15,top: 70), - child: Column( - children: [//babyInformationModelList.length - ...List.generate(model.creteVaccinationTableModelList.length, (index) => - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.white, - - ), - padding: EdgeInsets.all(12), - width: double.infinity, - child: Column( - - children: [ - Row(children: [ - Text(model.creteVaccinationTableModelList[index].visit), - SizedBox(width: 10,), - - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Html( - // data:"
BCG
HEPATITIS B
"//model.creteVaccinationTableModelList[index].vaccinesDescription - data:model.creteVaccinationTableModelList[index].vaccinesDescription, - - ), - ],), - ), - Text(model.creteVaccinationTableModelList[index].givenAt), - - - ],), - Divider(color:Colors.black ,), - - ], - ) - - - ) - - ) - ], + appBarTitle: TranslationBase.of(context).vaccination, + body: Container( + height: height * 0.85, + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 16, right: 16, top: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Texts(TranslationBase.of(context).childName), + ), + Expanded( + child: Texts(TranslationBase.of(context).dob), + ), + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: Texts(babyInfo.babyName), + ), + Expanded( + child: Texts(DateUtil.getFormattedDate( + babyInfo.dOB, "MMM dd,yyyy")), + ), + ], + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.black, + ), + Row( + children: [ + Text(TranslationBase.of(context).visit), + SizedBox( + width: 25, + ), + Expanded( + child: Text(TranslationBase.of(context).description)), + Text(TranslationBase.of(context).dueDate), + ], + ), + ...List.generate( + model.creteVaccinationTableModelList.length, + (index) => Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + // border: Border.all(color: Colors.white, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(5)), + // color: Colors.white, + ), + padding: EdgeInsets.all(12), + width: double.infinity, + child: Column( + children: [ + Row( + children: [ + Text(model + .creteVaccinationTableModelList[index] + .visit), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Html( + // data:"
BCG
HEPATITIS B
"//model.creteVaccinationTableModelList[index].vaccinesDescription + data: model + .creteVaccinationTableModelList[ + index] + .vaccinesDescription, + ), + ], + ), + ), + Text(model + .creteVaccinationTableModelList[index] + .givenAt), + ], + ), + Divider( + color: Colors.black, + ), + ], + ))) + ], + ), ), - + ), ), - ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.12, + height: height * 0.15, width: double.infinity, - padding: EdgeInsets.all(12), child: SecondaryButton( - textColor: Colors.white, - color: checkedValue== false ?Colors.white24:Color.fromRGBO(63, 72, 74, 1,), - label: "Send Email ", - // - onTap: () { - //SelectGenderDialog(); + textColor: Colors.white, + color: checkedValue == false + ? Colors.white24 + : Color.fromRGBO( + 63, + 72, + 74, + 1, + ), + label: TranslationBase.of(context).sendEmail, + // + onTap: () { + //SelectGenderDialog(); //=============== - showDialog( - context: context, - child: SelectGenderDialog( - ), - ); - //========= - } - - - ), + showDialog( + context: context, + child: SelectGenderDialog( + okFunction: () async { + await model.getCreateVaccinationTable(babyInfo, true); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast( + message: TranslationBase.of(context) + .emailSentSuccessfully); + } else { + AppToast.showErrorToast( + message: TranslationBase.of(context) + .EmailSentError); + } + }, + ), + ); + //========= + }), ), ), ); diff --git a/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart b/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart index 43bc9f0a..b09a579d 100644 --- a/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart +++ b/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/model/vital_sign/vital_sign_res_model.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_wideget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:flutter/material.dart'; diff --git a/lib/uitl/date_uitl.dart b/lib/uitl/date_uitl.dart index 460a4066..9f959885 100644 --- a/lib/uitl/date_uitl.dart +++ b/lib/uitl/date_uitl.dart @@ -4,7 +4,7 @@ import 'package:intl/intl.dart'; class DateUtil { /// convert String To Date function /// [date] String we want to convert - static DateTime convertStringToDate(String date) { + static DateTime convertStringToDate(String date) { // /Date(1585774800000+0300)/ if (date != null) { const start = "/Date("; const end = "+0300)"; diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 257ceb8e..fe0b6bc3 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -581,6 +581,8 @@ class TranslationBase { localizedValues['UpdateSuccessfully'][locale.languageCode]; String get emailSentSuccessfully => localizedValues['EmailSentSuccessfully'][locale.languageCode]; + String get EmailSentError => + localizedValues['EmailSentError'][locale.languageCode]; String get checkVaccineAvailability => localizedValues['CHECK_VACCINE_AVAILABILITY'][locale.languageCode]; String get myVaccinesAvailability => @@ -1172,6 +1174,7 @@ class TranslationBase { String get infoInsurCards => localizedValues['info-insur-cards'][locale.languageCode]; String get scanNow => localizedValues['scan-now'][locale.languageCode]; String get pharmacyServiceTermsCondition => localizedValues['pharmacyServiceTermsCondition'][locale.languageCode]; + String get recordDeleted => localizedValues['recordDeleted'][locale.languageCode]; String get referralStatus => localizedValues['referralStatus'][locale.languageCode]; @@ -1214,7 +1217,6 @@ class TranslationBase { String get viewListChildren => localizedValues['view-list-children'][locale.languageCode]; String get addChild => localizedValues['add-child'][locale.languageCode]; - String get childName => localizedValues['child-name'][locale.languageCode]; String get childDob => localizedValues['childDob'][locale.languageCode]; String get deletedChildMes => localizedValues['deleted-child-mes'][locale.languageCode]; @@ -1247,7 +1249,16 @@ class TranslationBase { String get driveThru => localizedValues['driveThru'][locale.languageCode]; String get NearestErDesc => localizedValues['NearestErDesc'][locale.languageCode]; String get NearestEr => localizedValues['NearestEr'][locale.languageCode]; - + String get covid19_driveThrueTest => localizedValues['covid19_driveThrueTest'][locale.languageCode]; + String get eReferral => localizedValues['E-Referral'][locale.languageCode]; + String get vaccination => localizedValues["vaccination"][locale.languageCode]; + String get msg_email_address_up_to_date => localizedValues["msg_email_address_up_to_date"][locale.languageCode]; + String get updateEmailMsg => localizedValues["update-email-msg"][locale.languageCode]; + String get childName => localizedValues["childName"][locale.languageCode]; + String get addNewChild => localizedValues["add-new-child"][locale.languageCode]; + String get sendChildEmailMsg => localizedValues["send-child-email-msg"][locale.languageCode]; + String get vaccinationAddChildMsg => localizedValues["vaccination-add-child-msg"][locale.languageCode]; + String get childAddedSuccessfully => localizedValues["child_added_successfully"][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 14/16] 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 15/16] 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]; } From 174534d8a5ff5459e92d816b3ab8368b33847550 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Tue, 19 Jan 2021 18:00:34 +0200 Subject: [PATCH 16/16] fix Blood donation functionality and design --- lib/config/config.dart | 2 + lib/config/localized_values.dart | 4 +- .../service/medical/my_balance_service.dart | 50 ++- lib/core/service/termsConditionsService.dart | 18 ++ .../viewModels/TermsConditionsViewModel.dart | 29 ++ .../medical/my_balance_view_model.dart | 17 +- lib/locator.dart | 4 + lib/pages/Blood/blood_donation.dart | 302 ++++++++---------- .../Blood/dialogs/SelectGenderDialog.dart | 4 +- lib/pages/Blood/user_agreement_page.dart | 62 +--- .../balance/dialogs/SelectCiteisDialog.dart | 18 +- lib/uitl/translations_delegate_base.dart | 2 + 12 files changed, 282 insertions(+), 230 deletions(-) create mode 100644 lib/core/service/termsConditionsService.dart create mode 100644 lib/core/viewModels/TermsConditionsViewModel.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 0c6b5d59..454f05fc 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -373,6 +373,8 @@ const GET_PATIENT_ALL_PRES_ORD = const PATIENT_ER_INSERT_PRES_ORDER = 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; const PHARMACY_MAKE_REVIEW = 'epharmacy/api/insertreviews'; +const BLOOD_DONATION_REGISTER_BLOOD_TYPE = 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; +const ADD_USER_AGREEMENT_FOR_BLOOD_DONATION = 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; //Pharmacy wishlist const GET_WISHLIST = "shopping_cart_items/"; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index d32078a3..fdf84bf0 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1511,5 +1511,7 @@ const Map localizedValues = { "send-child-email-msg": {"en" : "Send the child's schedule to the email", "ar": "أرسل جدول الطفل إلى البريد الإلكتروني"}, "vaccination-add-child-msg": {"en" : "Add the child's information below to receive the schedule of vaccinations.", "ar": "أضف معلومات الطفل أدناه للحصول على جدول التطعيمات."}, "child_added_successfully": {"en" : "Child added successfully", "ar": "تمت إضافة الطفل بنجاح"}, - + "bloodD-enter-desc": {"en" : "Enter the required information, In order to register for Blood Donation Service", "ar": "أدخل المعلومات المطلوبة ، للتسجيل في خدمة التبرع بالدم"}, + "viewTermsConditions": {"en" : "To view the terms and conditions", "ar": "لعرض الشروط والأحكام"}, + // "visit": {"en" : "Visit", "ar": "الزيارة"}, }; diff --git a/lib/core/service/medical/my_balance_service.dart b/lib/core/service/medical/my_balance_service.dart index 86e925b8..e2744250 100644 --- a/lib/core/service/medical/my_balance_service.dart +++ b/lib/core/service/medical/my_balance_service.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_advance_balance_amount.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; @@ -23,11 +24,11 @@ class MyBalanceService extends BaseService { PatientInfoAndMobileNumber patientInfoAndMobileNumber; String logInTokenID; String verificationCode; - + String updatedRegisterBloodMessage = ""; AuthenticatedUserObject authenticatedUserObject = locator(); - MyBalanceService(){ + MyBalanceService() { getFamilyFiles(); } @@ -156,4 +157,49 @@ class MyBalanceService extends BaseService { return await getSharedRecordByStatus(); } } + + Future updateBloodGroup(List_BloodGroupDetailsModel detailsModel) async { + hasError = false; + await getUser(); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Map body = Map(); + body['City'] = detailsModel.city; + body['cityCode'] = detailsModel.cityCode; + body['Gender'] = detailsModel.gender; + body['BloodGroup'] = detailsModel.bloodGroup; + body['CellNumber'] = user.mobileNumber; + body['LanguageID'] = languageID; + body['NationalID'] = user.nationalityID; + body['ZipCode'] = user.zipCode ?? "+966"; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(BLOOD_DONATION_REGISTER_BLOOD_TYPE, + onSuccess: (dynamic response, int statusCode) { + updatedRegisterBloodMessage = response['ErrorEndUserMessage']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + if(error == null){ + super.error = "Something went wrong"; + } + }, body: body); + } + + Future addUserAgreementForBloodDonation() async { + hasError = false; + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Map body = Map(); + body['IsAgreed'] = true; + body['LanguageID'] = languageID; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(ADD_USER_AGREEMENT_FOR_BLOOD_DONATION, + onSuccess: (dynamic response, int statusCode) { + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/termsConditionsService.dart b/lib/core/service/termsConditionsService.dart new file mode 100644 index 00000000..1f806e22 --- /dev/null +++ b/lib/core/service/termsConditionsService.dart @@ -0,0 +1,18 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class TermsConditionsService extends BaseService { + + String userAgreementContent = ""; + + Future getUserTermsAndConditions() async { + hasError = false; + await baseAppClient.post(GET_USER_TERMS, + onSuccess: (dynamic response, int statusCode) { + userAgreementContent = response['UserAgreementContent']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: Map()); + } +} \ No newline at end of file diff --git a/lib/core/viewModels/TermsConditionsViewModel.dart b/lib/core/viewModels/TermsConditionsViewModel.dart new file mode 100644 index 00000000..0cd667cf --- /dev/null +++ b/lib/core/viewModels/TermsConditionsViewModel.dart @@ -0,0 +1,29 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/service/termsConditionsService.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../locator.dart'; + +class TermsConditionsViewModel extends BaseViewModel{ + + TermsConditionsService _service = locator(); + + String get userAgreementContent => _service.userAgreementContent; + + getUserTermsAndConditions() async { + setState(ViewState.Busy); + await _service.getUserTermsAndConditions(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + @override + void dispose() { + super.dispose(); + } + +} \ No newline at end of file diff --git a/lib/core/viewModels/medical/my_balance_view_model.dart b/lib/core/viewModels/medical/my_balance_view_model.dart index f9554d94..acbbee07 100644 --- a/lib/core/viewModels/medical/my_balance_view_model.dart +++ b/lib/core/viewModels/medical/my_balance_view_model.dart @@ -41,6 +41,9 @@ class MyBalanceViewModel extends BaseViewModel { double get totalAdvanceBalanceAmount => _myBalanceService.totalAdvanceBalanceAmount; + String get updatedRegisterBloodMessage => + _myBalanceService.updatedRegisterBloodMessage; + GetAllSharedRecordsByStatusResponse get getAllSharedRecordsByStatusResponse => _myBalanceService.getAllSharedRecordsByStatusResponse; @@ -74,7 +77,6 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getCities() async { setState(ViewState.Busy); await _bloodDonationService.getAllCitiesOrders(); @@ -159,4 +161,17 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Idle); } } + + Future updateBloodGroup(List_BloodGroupDetailsModel detailsModel) async { + setState(ViewState.Busy); + await _myBalanceService.updateBloodGroup(detailsModel); + if (_myBalanceService.hasError) { + error = _myBalanceService.error; + setState(ViewState.ErrorLocal); + } else { + await _myBalanceService.addUserAgreementForBloodDonation(); + setState(ViewState.Idle); + } + + } } diff --git a/lib/locator.dart b/lib/locator.dart index cfdad053..4a6733ae 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -59,12 +59,14 @@ import 'core/service/parmacyModule/order-preview-service.dart'; import 'core/service/notifications_service.dart'; import 'core/service/parmacyModule/terms-condition-service.dart'; import 'core/service/privilege_service.dart'; +import 'core/service/termsConditionsService.dart'; import 'core/service/weather_service.dart'; import 'core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'core/service/parmacyModule/parmacy_module_service.dart'; import 'core/service/offers_service.dart'; import 'core/service/pharmacy_categorise_service.dart'; +import 'core/viewModels/TermsConditionsViewModel.dart'; import 'core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'core/viewModels/appointment_rate_view_model.dart'; import 'core/viewModels/blooddonation/blood_details_view_model.dart'; @@ -204,6 +206,7 @@ void setupLocator() { locator.registerLazySingleton(() => CancelOrderService()); locator.registerLazySingleton(() => PrivilegeService()); locator.registerLazySingleton(() => WeatherService()); + locator.registerLazySingleton(() => TermsConditionsService()); /// View Model locator.registerFactory(() => HospitalViewModel()); @@ -278,4 +281,5 @@ void setupLocator() { // Geofencing // --------------------- locator.registerLazySingleton(() => GeofencingServices()); // Geofencing Services + locator.registerFactory(() => TermsConditionsViewModel()); } diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index 99e5242e..e6eae56c 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -1,14 +1,15 @@ - import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; + //import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; import 'package:diplomaticquarterapp/core/service/blood/blood_details_servies.dart'; import 'package:diplomaticquarterapp/core/viewModels/blooddonation/blood_details_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/pages/Blood/user_agreement_page.dart'; @@ -27,6 +28,7 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:giffy_dialog/giffy_dialog.dart'; +import 'package:provider/provider.dart'; import 'package:smart_progress_bar/smart_progress_bar.dart'; //import '../../../core/model/my_balance/AdvanceModel.dart'; @@ -39,8 +41,8 @@ import 'dialogs/SelectPatientInfoDialog.dart'; import 'new_text_Field.dart'; enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } -enum Gender{Male,Female,NON} -enum Blood{Oplus,Ominus,Aplus,Aminus,Bplus,Bminus,ABplus,ABminus,NON} +enum Gender { Male, Female, NON } +enum Blood { Oplus, Ominus, Aplus, Aminus, Bplus, Bminus, ABplus, ABminus, NON } class BloodDonationPage extends StatefulWidget { @override @@ -51,10 +53,11 @@ class _BloodDonationPageState extends State { TextEditingController _fileTextController = TextEditingController(); TextEditingController _notesTextController = TextEditingController(); BeneficiaryType beneficiaryType = BeneficiaryType.NON; - Gender gender = Gender.Male;//Gender.NON; - Blood blood = Blood.Aminus;//Blood.NON; + Gender gender = Gender.Male; //Gender.NON; + Blood blood = Blood.Aminus; //Blood.NON; //HospitalsModel _selectedHospital; - CitiesModel _selectedHospital; + CitiesModel _selectedHospital = + CitiesModel(description: "Riyadh", descriptionN: "الرياض", iD: 1); String amount = ""; String email; @@ -62,22 +65,27 @@ class _BloodDonationPageState extends State { AuthenticatedUser authenticatedUser; GetAllSharedRecordsByStatusList selectedPatientFamily; AdvanceModel advanceModel = AdvanceModel(); - List_BloodGroupDetailsModel bloodDetails=List_BloodGroupDetailsModel(); + List_BloodGroupDetailsModel bloodDetails = List_BloodGroupDetailsModel(); AppSharedPreferences sharedPref = AppSharedPreferences(); AuthenticatedUser authUser; - var checkedValue = false; + var checkedValue = false; + @override void initState() { super.initState(); getAuthUser(); } + @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + return BaseView( - onModelReady: (model) => model.getCities(),//model.getHospitals(), + onModelReady: (model) => model.getCities(), //model.getHospitals(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: "Blood Donation",//TranslationBase.of(context).advancePayment, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).bloodD, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -86,15 +94,16 @@ class _BloodDonationPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - // TranslationBase.of(context).advancePaymentLabel, - "Enter the required information, In order to register for Blood Donation Service",//+model.user.firstName, + TranslationBase.of(context).bloodDEnterDesc, textAlign: TextAlign.center, ), SizedBox( height: 12, ), InkWell( - onTap: () => confirmSelectHospitalDialog(model.CitiesModelList),//model.hospitals + onTap: () => + confirmSelectHospitalDialog(model.CitiesModelList), + //model.hospitals child: Container( padding: EdgeInsets.all(12), width: double.infinity, @@ -105,7 +114,7 @@ class _BloodDonationPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getHospitalName()), + Texts(getHospitalName(projectProvider)), Icon(Icons.arrow_drop_down) ], ), @@ -116,7 +125,8 @@ class _BloodDonationPageState extends State { ), InkWell( //======Gender======== - onTap: () => confirmSelectGenderDialog(),//confirmSelectBeneficiaryDialog(model), + onTap: () => confirmSelectGenderDialog(), + //confirmSelectBeneficiaryDialog(model), child: Container( padding: EdgeInsets.all(12), width: double.infinity, @@ -128,49 +138,19 @@ class _BloodDonationPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ //Texts(getBeneficiaryType()), - Texts(getGender()), + Texts(getGender(context)), Icon(Icons.arrow_drop_down) ], ), ), ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // SizedBox( - // height: 12, - // ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // InkWell( - // onTap: () { - // model.getFamilyFiles().then((value) { - // confirmSelectFamilyDialog(model - // .getAllSharedRecordsByStatusResponse - // .getAllSharedRecordsByStatusList); - // }).showProgressBar( - // text: "Loading", - // backgroundColor: Colors.blue.withOpacity(0.6)); - // }, - // 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(getFamilyMembersName()), - // Icon(Icons.arrow_drop_down) - // ], - // ), - // ), - // ), SizedBox( height: 12, ), InkWell( //======Gender======== - onTap: () => confirmSelectBloodDialog(),//confirmSelectBeneficiaryDialog(model), + onTap: () => confirmSelectBloodDialog(), + //confirmSelectBeneficiaryDialog(model), child: Container( padding: EdgeInsets.all(12), width: double.infinity, @@ -188,44 +168,14 @@ class _BloodDonationPageState extends State { ), ), ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // SizedBox( - // height: 12, - // ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // InkWell( - // onTap: () { - // model.getFamilyFiles().then((value) { - // confirmSelectFamilyDialog(model - // .getAllSharedRecordsByStatusResponse - // .getAllSharedRecordsByStatusList); - // }).showProgressBar( - // text: "Loading", - // backgroundColor: Colors.blue.withOpacity(0.6)); - // }, - // 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(getFamilyMembersName()), - // Icon(Icons.arrow_drop_down) - // ], - // ), - // ), - // ), SizedBox( height: 12, ), Row( children: [ Container( - child: Text(" To view the terms and conditions "), + child: Text( + TranslationBase.of(context).viewTermsConditions), ), SizedBox( width: MediaQuery.of(context).size.height * 0.10, @@ -233,10 +183,14 @@ class _BloodDonationPageState extends State { InkWell( onTap: () { Navigator.of(context).push(MaterialPageRoute( - builder: (BuildContext context) => UserAgreementPage())); + builder: (BuildContext context) => + UserAgreementPage())); }, child: Container( - child: Texts(" Click here ",color: Colors.blue,), + child: Texts( + TranslationBase.of(context).clickHere, + color: Colors.blue, + ), ), ) ], @@ -247,25 +201,31 @@ class _BloodDonationPageState extends State { Row( children: [ Checkbox( - onChanged: (bool value) { + onChanged: (bool value) { setState(() { checkedValue = value; }); }, - // tristate: checkedValue==true,//i == 1, + // tristate: checkedValue==true,//i == 1, value: checkedValue, - activeColor: Colors.red,//Color(0xFF6200EE), + activeColor: Color(0xFFc5272d), //Color(0xFF6200EE), + ), + SizedBox( + height: 10, + ), + Row( + children: [], ), - SizedBox(height: 10,), - Row(children: [ - - ],), SizedBox( width: 10, ), Text( - 'I agree to the terms and conditions ', - style: Theme.of(context).textTheme.subtitle1.copyWith(color: checkedValue? Colors.red : Colors.black), + TranslationBase.of(context) + .iAgreeToTheTermsAndConditions, + style: Theme.of(context).textTheme.subtitle1.copyWith( + color: checkedValue + ? Color(0xFFc5272d) + : Colors.black), ), ], ), @@ -355,29 +315,25 @@ class _BloodDonationPageState extends State { onTap: () { showDialog( context: context, - builder: (_) => - AssetGiffyDialog( + builder: (_) => AssetGiffyDialog( title: Text( "", style: TextStyle( fontSize: 22.0, - fontWeight: - FontWeight - .w600), + fontWeight: FontWeight.w600), ), image: Image.asset( 'assets/images/BloodChrt_EN.png'), - buttonCancelText: - Text('cancel'), - buttonCancelColor: - Colors.grey, + buttonCancelText: Text( + TranslationBase.of(context).cancel), + buttonCancelColor: Colors.grey, onlyCancelButton: true, )); }, child: Container( width: 250, height: 200, - child:Image.asset( + child: Image.asset( 'assets/images/BloodChrt_EN.png')), ), ), @@ -395,25 +351,37 @@ class _BloodDonationPageState extends State { bottomSheet: Container( height: MediaQuery.of(context).size.height * 0.12, width: double.infinity, - padding: EdgeInsets.all(12), child: SecondaryButton( textColor: Colors.white, - color: checkedValue== false ?Colors.white24:Color.fromRGBO(63, 72, 74, 1,), - label: "Save", - // - onTap: (){ - - bloodDetails.city=_selectedHospital.toString(); - - // bloodDetails. + color: checkedValue == false + ? Color(0xFFa0a4a6) + : Color.fromRGBO( + 63, + 72, + 74, + 1, + ), + label: TranslationBase.of(context).save, + onTap: () async { + bloodDetails.city = projectProvider.isArabic + ? _selectedHospital.descriptionN + : _selectedHospital.description; + bloodDetails.cityCode = _selectedHospital.iD.toString(); + bloodDetails.gender = gender == Gender.Male ? 1 : 2; + await model.updateBloodGroup(bloodDetails); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast( + message: model.updatedRegisterBloodMessage); + } else { + AppToast.showErrorToast(message: model.error); + } }, - - ), )), ); } + //============== void confirmSelectBeneficiaryDialog(MyBalanceViewModel model) { showDialog( @@ -435,94 +403,85 @@ class _BloodDonationPageState extends State { ), ); } - void confirmSelectBloodDialog(){ + + void confirmSelectBloodDialog() { showDialog( context: context, - child: SelectBloodDialog(bloodType: blood, + child: SelectBloodDialog( + bloodType: blood, onValueSelected: (value) { setState(() { if (value == Blood.Oplus) { - bloodDetails.bloodGroup="O+"; + bloodDetails.bloodGroup = "O+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Ominus) { + } else if (value == Blood.Ominus) { // _fileTextController.text = model.user.patientID.toString(); - bloodDetails.bloodGroup="O-"; + bloodDetails.bloodGroup = "O-"; // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.ABplus) { - bloodDetails.bloodGroup="AB+"; + } else if (value == Blood.ABplus) { + bloodDetails.bloodGroup = "AB+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.ABminus) { - bloodDetails.bloodGroup="AB-"; + } else if (value == Blood.ABminus) { + bloodDetails.bloodGroup = "AB-"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Aplus) { - bloodDetails.bloodGroup="A+"; + } else if (value == Blood.Aplus) { + bloodDetails.bloodGroup = "A+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Aminus) { - bloodDetails.bloodGroup="A-"; + } else if (value == Blood.Aminus) { + bloodDetails.bloodGroup = "A-"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Bplus) { - bloodDetails.bloodGroup="B+"; + } else if (value == Blood.Bplus) { + bloodDetails.bloodGroup = "B+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Bminus) { - bloodDetails.bloodGroup="B-"; + } else if (value == Blood.Bminus) { + bloodDetails.bloodGroup = "B-"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - } - - - else + } else _fileTextController.text = ""; // beneficiaryType = value; - blood=value; - } - - - - - ); + blood = value; + }); }, ), ); } - void confirmSelectGenderDialog(){ + + void confirmSelectGenderDialog() { showDialog( context: context, - child: SelectGenderDialog(beneficiaryType: gender, + child: SelectGenderDialog( + beneficiaryType: gender, onValueSelected: (value) { setState(() { if (value == Gender.Male) { // _fileTextController.text = model.user.patientID.toString(); - bloodDetails.patientType=1; + bloodDetails.patientType = 1; // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; } else - // _fileTextController.text = ""; - {bloodDetails.gender=2;} + // _fileTextController.text = ""; + { + bloodDetails.gender = 2; + } - // beneficiaryType = value; - gender=value; + // beneficiaryType = value; + gender = value; }); }, ), @@ -591,23 +550,25 @@ class _BloodDonationPageState extends State { return TranslationBase.of(context).otherAccount; break; case BeneficiaryType.NON: - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectBeneficiary; } - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectBeneficiary; } - String getGender() { + + String getGender(BuildContext context) { switch (gender) { case Gender.Male: - return "Male"; + return TranslationBase.of(context).male; case Gender.Female: - return "Female"; + return TranslationBase.of(context).female; break; case Gender.NON: - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectGender; } - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectGender; } + String getBlood() { switch (blood) { case Blood.Oplus: @@ -639,18 +600,19 @@ class _BloodDonationPageState extends State { break; case Blood.NON: - return "Select Blood Type";//TranslationBase.of(context).selectBeneficiary; + return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; } - return "Select Blood Type";//TranslationBase.of(context).selectBeneficiary; + return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; } - String getHospitalName() { + String getHospitalName(ProjectViewModel projectProvider) { if (_selectedHospital != null) - return _selectedHospital.description; + return projectProvider.isArabic + ? _selectedHospital.descriptionN + : _selectedHospital.description; else - return - "Riyadh"; - // return List_BloodGroupDetailsModel.fromJson(0).city.toString();//"Select City";//TranslationBase.of(context).selectHospital; + return projectProvider.isArabic ? "الرياض" : "Riyadh"; + // return List_BloodGroupDetailsModel.fromJson(0).city.toString();//"Select City";//TranslationBase.of(context).selectHospital; } String getPatientName() { @@ -677,8 +639,6 @@ class _BloodDonationPageState extends State { return TranslationBase.of(context).selectFamilyPatientName; } - - //================ - +//================ } diff --git a/lib/pages/Blood/dialogs/SelectGenderDialog.dart b/lib/pages/Blood/dialogs/SelectGenderDialog.dart index 295c6dcd..a097ae8e 100644 --- a/lib/pages/Blood/dialogs/SelectGenderDialog.dart +++ b/lib/pages/Blood/dialogs/SelectGenderDialog.dart @@ -38,7 +38,7 @@ class _SelectGenderDialogState extends State { }); }, child: ListTile( - title: Text("Male"), + title: Text(TranslationBase.of(context).male), leading: Radio( value: Gender.Male, groupValue: beneficiaryType, @@ -68,7 +68,7 @@ class _SelectGenderDialogState extends State { }); }, child: ListTile( - title: Text("Female"), + title: Text(TranslationBase.of(context).female), leading: Radio( value: Gender.Female, groupValue: beneficiaryType, diff --git a/lib/pages/Blood/user_agreement_page.dart b/lib/pages/Blood/user_agreement_page.dart index d05725b4..36989ea5 100644 --- a/lib/pages/Blood/user_agreement_page.dart +++ b/lib/pages/Blood/user_agreement_page.dart @@ -1,55 +1,23 @@ +import 'package:diplomaticquarterapp/core/viewModels/TermsConditionsViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter_html/flutter_html.dart'; class UserAgreementPage extends StatelessWidget { @override Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: "User Agreement", - - body: - Container( - child:ListView( - scrollDirection: Axis.vertical, - children: [ - /////////// - Column( - children: [ - SizedBox( - height: 20, - ), - Container( - child:Text("Communication via email, text messages and phone calls",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - SizedBox( - height: 20, - ), - Container( - child: - Text("I understand that the contact number or Email that \n I have provided on registration will be used for communication by HMG.\n I hereby agree to be notified by HMG through SMS, Email or any other method for appointments notifications, current HMG’s medical services, and any services introduced by the HMG in the future or any modifications made to the services offered by the HMG. And these messages may be submitted as evidence where the HMG has the right to use at any time whatsoever and as it sees fit.",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - SizedBox( - height: 20, - ), - Container( - child: - Text("I understand the risks of communicating by email and text messages, in particular the privacy risks. \nI understand that HMG cannot guarantee the security and confidentiality of email or text communication. HMG will not be responsible for messages that are not received or delivered due to technical failure, or for disclosure of confidential information unless caused by intentional misconduct.",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - SizedBox( - height: 20, - ), - Container( - child: - Text("\b I hereby agree to receive emails, text messages, phone calls for appointments notifications, special promotions and new features or products introduced by HMG or any third party.",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - ], - ) - /////////// - ]) - - - - )); + return BaseView( + onModelReady: (model) => model.getUserTermsAndConditions(), + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).userAgreement, + body: SingleChildScrollView( + child: Html( + data: model.userAgreementContent, + ), + )), + ); } } diff --git a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart index 3d07c08c..19e4fea4 100644 --- a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart @@ -1,9 +1,11 @@ //import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class SelectCiteisDialog extends StatefulWidget { final List hospitals; @@ -12,6 +14,7 @@ class SelectCiteisDialog extends StatefulWidget { SelectCiteisDialog( {Key key, this.hospitals, this.onValueSelected, this.selectedHospital}); + @override _SelectCiteisDialogState createState() => _SelectCiteisDialogState(); } @@ -24,9 +27,10 @@ class _SelectCiteisDialogState extends State { widget.selectedHospital = widget.selectedHospital ?? widget.hospitals[0]; } - @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + return SimpleDialog( children: [ Column( @@ -34,7 +38,7 @@ class _SelectCiteisDialogState extends State { Divider(), ...List.generate( widget.hospitals.length, - (index) => Column( + (index) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( @@ -53,7 +57,9 @@ class _SelectCiteisDialogState extends State { child: ListTile( // title: Text(widget.hospitals[index].description + // ' ${widget.hospitals[index].distanceInKilometers} KM'), - title: Text(widget.hospitals[index].description), + title: Text(projectProvider.isArabic + ? widget.hospitals[index].descriptionN + : widget.hospitals[index].description), leading: Radio( value: widget.hospitals[index], groupValue: widget.selectedHospital, @@ -116,9 +122,9 @@ class _SelectCiteisDialogState extends State { padding: const EdgeInsets.all(8.0), child: Center( child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), + TranslationBase.of(context).ok, + fontWeight: FontWeight.w400, + )), ), ), ), diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 72ab198b..f6f2c664 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1263,6 +1263,8 @@ class TranslationBase { String get sendChildEmailMsg => localizedValues["send-child-email-msg"][locale.languageCode]; String get vaccinationAddChildMsg => localizedValues["vaccination-add-child-msg"][locale.languageCode]; String get childAddedSuccessfully => localizedValues["child_added_successfully"][locale.languageCode]; + String get bloodDEnterDesc => localizedValues["bloodD-enter-desc"][locale.languageCode]; + String get viewTermsConditions => localizedValues["viewTermsConditions"][locale.languageCode]; }