Merge remote-tracking branch 'origin/main_latest_merged' into main_latest_merged

# Conflicts:
#	ios/Podfile.lock
#	ios/Runner.xcodeproj/project.pbxproj
design_3.0_demo_module
Sikander Saleem 3 years ago
commit c6c6aa5bce

@ -49,30 +49,30 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 33
versionCode 1 versionCode 3
versionName '1.0.0' versionName '1.0.3'
} }
signingConfigs { signingConfigs {
// release { release {
// keyAlias keystoreProperties['keyAlias'] keyAlias keystoreProperties['keyAlias']
// keyPassword keystoreProperties['keyPassword'] keyPassword keystoreProperties['keyPassword']
// storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
// storePassword keystoreProperties['storePassword'] storePassword keystoreProperties['storePassword']
// } }
} }
buildTypes { buildTypes {
debug { debug {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
release {
signingConfig signingConfigs.debug
}
// release { // release {
// minifyEnabled true // signingConfig signingConfigs.debug
// shrinkResources true
// signingConfig signingConfigs.release
// } // }
release {
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.release
}
} }
} }

@ -1,5 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.6.10' ext.kotlin_version = '1.8.20'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@ -167,7 +167,7 @@
"newServiceReport": "تقرير خدمة جديد", "newServiceReport": "تقرير خدمة جديد",
"number": "رقم", "number": "رقم",
"operatingHours": "ساعات العمل", "operatingHours": "ساعات العمل",
"partNumber": "رقم القطعة", "partNumberName": "رقم/اسم القطعة",
"quantity": "كمية", "quantity": "كمية",
"reasons": "الاسباب", "reasons": "الاسباب",
"reportStatus": "حالة التقرير", "reportStatus": "حالة التقرير",
@ -201,5 +201,9 @@
"floor": "طابق", "floor": "طابق",
"department": "قسم", "department": "قسم",
"room": "غرفه", "room": "غرفه",
"actions": "اجراءات" "actions": "اجراءات",
"deviceFiles": "ملفات الجهاز",
"pickFromFiles" : "اختر من الملفات",
"requiredFile" : "الملف مطلوب",
"pickFile" : "اختر ملف"
} }

@ -73,7 +73,7 @@
"deviceImages": "Asset Images", "deviceImages": "Asset Images",
"deviceModel": "Asset Model", "deviceModel": "Asset Model",
"deviceRequired": "Asset Required", "deviceRequired": "Asset Required",
"deviceSN": "Asset SN", "deviceSN": "Asset Serial Number",
"engineerName": "Engineer Name", "engineerName": "Engineer Name",
"engineerPhone": "Engineer Phone", "engineerPhone": "Engineer Phone",
"facebook": "facebook", "facebook": "facebook",
@ -167,7 +167,7 @@
"newServiceReport": "New Work Order", "newServiceReport": "New Work Order",
"number": "Number", "number": "Number",
"operatingHours": "Operating Hours", "operatingHours": "Operating Hours",
"partNumber": "Part Number", "partNumberName": "Part Number/Name",
"quantity": "Quantity", "quantity": "Quantity",
"reasons": "Reasons", "reasons": "Reasons",
"reportStatus": "Report Status", "reportStatus": "Report Status",
@ -201,5 +201,9 @@
"floor": "Floor", "floor": "Floor",
"department": "Department", "department": "Department",
"room": "Room", "room": "Room",
"actions": "Actions" "actions": "Actions",
"deviceFiles": "Asset Files",
"pickFromFiles" : "Pick From Files",
"requiredFile" : "File Required",
"pickFile" : "Pick File"
} }

@ -41,4 +41,16 @@ post_install do |installer|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
end end
end end
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
]
end
end
end
end end

@ -0,0 +1,268 @@
PODS:
- audioplayers_darwin (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.4):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.4)
- DKImagePickerController/PhotoGallery (4.3.4):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.4)
- DKPhotoGallery (0.0.17):
- DKPhotoGallery/Core (= 0.0.17)
- DKPhotoGallery/Model (= 0.0.17)
- DKPhotoGallery/Preview (= 0.0.17)
- DKPhotoGallery/Resource (= 0.0.17)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.17):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.17):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/CoreOnly (10.12.0):
- FirebaseCore (= 10.12.0)
- Firebase/Messaging (10.12.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 10.12.0)
- firebase_core (2.15.0):
- Firebase/CoreOnly (= 10.12.0)
- Flutter
- firebase_messaging (14.6.5):
- Firebase/Messaging (= 10.12.0)
- firebase_core
- Flutter
- FirebaseCore (10.12.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreInternal (10.12.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseInstallations (10.12.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- PromisesObjC (~> 2.1)
- FirebaseMessaging (10.12.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Reachability (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- nanopb (< 2.30910.0, >= 2.30908.0)
- Flutter (1.0.0)
- flutter_keyboard_visibility (0.0.1):
- Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_sound (9.2.13):
- Flutter
- flutter_sound_core (= 9.2.13)
- flutter_sound_core (9.2.13)
- fluttertoast (0.0.2):
- Flutter
- Toast
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- GoogleDataTransport (9.2.3):
- GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30910.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/AppDelegateSwizzler (7.11.4):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.11.4):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.11.4):
- GoogleUtilities/Environment
- GoogleUtilities/Network (7.11.4):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.11.4)"
- GoogleUtilities/Reachability (7.11.4):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.11.4):
- GoogleUtilities/Logger
- image_picker_ios (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- nanopb (2.30909.0):
- nanopb/decode (= 2.30909.0)
- nanopb/encode (= 2.30909.0)
- nanopb/decode (2.30909.0)
- nanopb/encode (2.30909.0)
- package_info (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.1.1):
- Flutter
- PromisesObjC (2.3.1)
- qr_code_scanner (0.2.0):
- Flutter
- MTBBarcodeScanner
- SDWebImage (5.17.0):
- SDWebImage/Core (= 5.17.0)
- SDWebImage/Core (5.17.0)
- share (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- speech_to_text (0.0.1):
- Flutter
- Try
- sqflite (0.0.3):
- Flutter
- FMDB (>= 2.7.5)
- SwiftyGif (5.4.4)
- Toast (4.0.0)
- Try (2.1.1)
- url_launcher_ios (0.0.1):
- Flutter
DEPENDENCIES:
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_sound (from `.symlinks/plugins/flutter_sound/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
- share (from `.symlinks/plugins/share/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
- speech_to_text (from `.symlinks/plugins/speech_to_text/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- Firebase
- FirebaseCore
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
- flutter_sound_core
- FMDB
- GoogleDataTransport
- GoogleUtilities
- MTBBarcodeScanner
- nanopb
- PromisesObjC
- SDWebImage
- SwiftyGif
- Toast
- Try
EXTERNAL SOURCES:
audioplayers_darwin:
:path: ".symlinks/plugins/audioplayers_darwin/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_sound:
:path: ".symlinks/plugins/flutter_sound/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
package_info:
:path: ".symlinks/plugins/package_info/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
qr_code_scanner:
:path: ".symlinks/plugins/qr_code_scanner/ios"
share:
:path: ".symlinks/plugins/share/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
speech_to_text:
:path: ".symlinks/plugins/speech_to_text/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
Firebase: 07150e75d142fb9399f6777fa56a187b17f833a0
firebase_core: e477125798fc37cd4ab43ca6a8536bf7e0929c00
firebase_messaging: 334d68c3a36b6d4d5cd91e4f42509e0d4ae49828
FirebaseCore: f86a1394906b97ac445ae49c92552a9425831bed
FirebaseCoreInternal: 950500ad8a08963657f6d8c67b579740c06d6aa1
FirebaseInstallations: 7b99ef103f013624444c614397038219c45f8e63
FirebaseMessaging: bb2c4f6422a753038fe137d90ae7c1af57251316
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
flutter_sound: c60effa2a350fb977885f0db2fbc4c1ad5160900
flutter_sound_core: 26c10e5832e76aaacfae252d8925232281c486ae
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
GoogleDataTransport: f0308f5905a745f94fb91fea9c6cbaf3831cb1bd
GoogleUtilities: c63691989bf362ba0505507da00eeb326192e83e
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9
share: 0b2c3e82132f5888bccca3351c504d0003b3b410
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
PODFILE CHECKSUM: 9addd1ae6176ca7bfe24f8bac9acf6aeb76cd8f5
COCOAPODS: 1.12.1

@ -7,7 +7,7 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Atoms SA</string> <string>Atoms</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -15,7 +15,7 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>Atoms SA</string> <string>Atoms</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
@ -28,6 +28,8 @@
<false/> <false/>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>This app requires permission to access Camera to allow user to attach images</string> <string>This app requires permission to access Camera to allow user to attach images</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
@ -36,6 +38,8 @@
<string>This app requires permission to access photo gallery to allow user to attach images</string> <string>This app requires permission to access photo gallery to allow user to attach images</string>
<key>NSSpeechRecognitionUsageDescription</key> <key>NSSpeechRecognitionUsageDescription</key>
<string>This app requires permission for Speech Recognition for speech to text functionality.</string> <string>This app requires permission for Speech Recognition for speech to text functionality.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>fetch</string> <string>fetch</string>
@ -58,9 +62,9 @@
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>UISupportsDocumentBrowser</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict> </dict>
</plist> </plist>

@ -4,5 +4,7 @@
<dict> <dict>
<key>aps-environment</key> <key>aps-environment</key>
<string>development</string> <string>development</string>
<key>inter-app-audio</key>
<true/>
</dict> </dict>
</plist> </plist>

@ -1,7 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -23,6 +21,7 @@ class ApiManager {
Future<http.Response> get( Future<http.Response> get(
String url, { String url, {
Map<String, String> headers, Map<String, String> headers,
enableToastMessage = true,
}) async { }) async {
headers ??= {}; headers ??= {};
@ -34,7 +33,7 @@ class ApiManager {
http.Response response = await http.get(_url, headers: headers); http.Response response = await http.get(_url, headers: headers);
if (jsonDecode(response.body) is Map<String, dynamic>) { if (jsonDecode(response.body) is Map<String, dynamic>) {
final message = jsonDecode(response.body)["message"]; final message = jsonDecode(response.body)["message"];
if (message != null && message.toString().isNotEmpty) { if (message != null && message.toString().isNotEmpty && enableToastMessage) {
Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG);
} }
} }

@ -1,8 +1,12 @@
class URLs { class URLs {
URLs._(); URLs._();
static const host2 = "http://194.163.164.213/atoms/api"; static const host2 = "http://194.163.164.213/atoms/api"; // todo @sikander will remove after confirmation
static const host1 = "https://atomsuat.hmg.com"; // uat url
//static const host1 = "https://atomsuat.hmg.com"; // old uat url
//static const host1 = "https://atomsm.hmg.com"; // production url
static const host1 = "https://atomsmdev.hmg.com"; // local UAT url
// static const host1 = "http://109.123.243.118:9000"; // static const host1 = "http://109.123.243.118:9000";
@ -12,7 +16,9 @@ class URLs {
set host(String value) => _host = value; set host(String value) => _host = value;
static String getFileUrl(String file) => (file == null || file.isEmpty) ? null : (file.contains("/") ? file : "$_host/attachment/$file"); static String getFileUrl(String file) => (file == null || file.isEmpty) ? null : (file.contains("/") ? file : "$_baseUrl/Files/DownloadFile?fileName=$file");
// static String getFileUrl(String file) => (file == null || file.isEmpty) ? null :1 (file.contains("/") ? file : "$_host/attachment/$file");
// API Routes // API Routes
static get login => "$_baseUrl/MobileAuth/LoginIntegration"; // post static get login => "$_baseUrl/MobileAuth/LoginIntegration"; // post
@ -50,6 +56,8 @@ class URLs {
static get updateRegularVisits => "$_baseUrl/Visit/UpdateVisits"; // get static get updateRegularVisits => "$_baseUrl/Visit/UpdateVisits"; // get
static get getSingleServiceRequest => "$_baseUrl/return/call/information"; // get static get getSingleServiceRequest => "$_baseUrl/return/call/information"; // get
static get getSuppliersAutoComplete => "$_baseUrl/Supplier/GetSuppliersAutoComplete";
static get getNotifications => "$_baseUrl/return/user/notification"; // get static get getNotifications => "$_baseUrl/return/user/notification"; // get
static get getRecentNotifications => "$_baseUrl/return/user/recent/notification"; // get static get getRecentNotifications => "$_baseUrl/return/user/recent/notification"; // get
static get createRequest => "$_baseUrl/CallRequest/AddCallRequest"; // get static get createRequest => "$_baseUrl/CallRequest/AddCallRequest"; // get
@ -63,13 +71,15 @@ class URLs {
static get createDuplicatedReport => "$_baseUrl/handle/duplicate/request"; // get static get createDuplicatedReport => "$_baseUrl/handle/duplicate/request"; // get
static get searchWorkOrders => "$_baseUrl/WorkOrder/SearchWorkOrders"; static get searchWorkOrders => "$_baseUrl/WorkOrder/SearchWorkOrders";
static get getSubWorkerInfoAccordingToPreviousStep => "$_baseUrl/WorkOrder/GetDataPreviousStep";
static get getServiceReportReasons => "$_baseUrl/Lookups/GetLookup?lookupEnum=522"; // get static get getServiceReportReasons => "$_baseUrl/Lookups/GetLookup?lookupEnum=522"; // get
static get getServiceReportTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=501"; // get static get getServiceReportTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=501"; // get
static get getServiceReportStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=521"; // get static get getServiceReportStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=521"; // get
static get getServiceReportLastCalls => "$_baseUrl/WorkOrder/GetLookupCallLastSituationBasedOnCase"; // get static get getServiceReportLastCalls => "$_baseUrl/WorkOrder/GetLookupCallLastSituationBasedOnCase"; // get
static get getAssetTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=500"; // get static get getAssetTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=500"; // get
static get getPartNumber => "$_baseUrl/PartCatalog/GetPartAutoComplete"; // get static get getPartNumber => "$_baseUrl/PartCatalog/GetPartAutoComplete"; // get
static get getServiceReportPriority => "$_baseUrl/Lookups/GetLookup?lookupEnum=602"; // get static get getServiceReportPriority => "$_baseUrl/Lookups/GetLookup?lookupEnum=4"; // get
static get getServiceReportDefectTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; // get static get getServiceReportDefectTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; // get
static get getCallRequestForWorkOrder => "$_baseUrl/CallRequest/GetCallRequestForWorkOrder"; // get static get getCallRequestForWorkOrder => "$_baseUrl/CallRequest/GetCallRequestForWorkOrder"; // get
@ -87,6 +97,8 @@ class URLs {
static get requestDeviceTransfer => "$_baseUrl/AssetTransfer/AddAssetTransfer"; // get static get requestDeviceTransfer => "$_baseUrl/AssetTransfer/AddAssetTransfer"; // get
static get updateDeviceTransfer => "$_baseUrl/AssetTransfer/UpdateAssetTransfer"; // get static get updateDeviceTransfer => "$_baseUrl/AssetTransfer/UpdateAssetTransfer"; // get
static get getDeviceTransfer => "$_baseUrl/AssetTransfer/GetAssetTransfers"; // get static get getDeviceTransfer => "$_baseUrl/AssetTransfer/GetAssetTransfers"; // get
static get getAssetTransferById => "$_baseUrl/AssetTransfer/GetAssetTransferById"; // get
static get getAssetTransferStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=406"; // get
// employee // employee
static get getEmployees => "$_baseUrl/Lookups/GetLookup?lookupEnum=33"; // get static get getEmployees => "$_baseUrl/Lookups/GetLookup?lookupEnum=33"; // get

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
@ -6,6 +7,7 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device_transfer.dart'; import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/models/device/device_transfer_info.dart'; import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/device/device_transfer_search.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import '../../../models/hospital.dart'; import '../../../models/hospital.dart';
@ -14,6 +16,8 @@ class DeviceTransferProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 12; final pageItemNumber = 12;
DeviceTransferSearch deviceTransferSearch = DeviceTransferSearch();
//reset provider data //reset provider data
void reset() { void reset() {
items = null; items = null;
@ -63,16 +67,15 @@ class DeviceTransferProvider extends ChangeNotifier {
}) async { }) async {
if (isLoading == true) return -2; if (isLoading == true) return -2;
isLoading = true; isLoading = true;
if (items?.isEmpty ?? true) notifyListeners();
Response response; Response response;
try { try {
Map<String, dynamic> body = {}; Map<String, dynamic> body = {};
body["pageNumber"] = (items?.length ?? 0) ~/ pageItemNumber + 1; body["pageNumber"] = (items?.length ?? 0) ~/ pageItemNumber + 1;
body["pageSize"] = pageItemNumber; body["pageSize"] = pageItemNumber;
body.addAll(deviceTransferSearch.toMap());
response = await ApiManager.instance.post( response = await ApiManager.instance.post(URLs.getDeviceTransfer, body: body);
URLs.getDeviceTransfer,
body: body,
);
stateCode = response.statusCode; stateCode = response.statusCode;
if (stateCode >= 200 && stateCode < 300) { if (stateCode >= 200 && stateCode < 300) {
@ -80,8 +83,8 @@ class DeviceTransferProvider extends ChangeNotifier {
List listJson = json.decode(response.body)["data"]; List listJson = json.decode(response.body)["data"];
List<DeviceTransfer> itemsPage = listJson.map((request) => DeviceTransfer.fromJson(request)).toList(); List<DeviceTransfer> itemsPage = listJson.map((request) => DeviceTransfer.fromJson(request)).toList();
items ??= []; items ??= [];
items.addAll(itemsPage); items.addAll(itemsPage.toSet().toList());
print(listJson); notifyListeners();
if (itemsPage.length == pageItemNumber) { if (itemsPage.length == pageItemNumber) {
nextPage = true; nextPage = true;
} else { } else {
@ -99,6 +102,23 @@ class DeviceTransferProvider extends ChangeNotifier {
} }
} }
Future<DeviceTransfer> getRequestById({int assetTransferId}) async {
Response response;
try {
response = await ApiManager.instance.get(
URLs.getAssetTransferById + "?assetTransferId=$assetTransferId",
enableToastMessage: false,
);
if (response.statusCode >= 200 && response.statusCode < 300) {
return DeviceTransfer.fromJson(json.decode(response.body)["data"]);
}
return null;
} catch (error) {
print(error);
return null;
}
}
Future<int> createRequest({ Future<int> createRequest({
@required String host, @required String host,
@required User user, @required User user,
@ -107,18 +127,22 @@ class DeviceTransferProvider extends ChangeNotifier {
Map<String, dynamic> body = { Map<String, dynamic> body = {
"id": 0, "id": 0,
"assetId": model.device.id ?? "", "assetId": model.device.id ?? "",
"destSiteId": model.receiver.client.id ?? "", "destSiteId": hospital.id ?? "",
"destDepartmentId": model.receiver.department.id ?? "", "destDepartmentId": department.id ?? "",
"senderSiteId": model.receiver.client.id ?? "", "senderSiteId": model.sender.client.id ?? "",
// "transferNo": 0, // "transferNo": 0,
// "transferCode": "string", // "transferCode": "string",
"destBuildingId": building?.id, "destBuildingId": building?.id,
"destFloorId": floor.id, "destFloorId": floor.id,
"destRoom": room, "destRoom": room,
// "senderBuildingId": 0, /////
// "senderFloorId": 0, "senderBuildingId": model.device.destBuildingId,
// "senderDepartmentId": 0, "senderFloorId": model.device.destFloorId,
// "senderRoom": "string", "senderDepartmentId": model.device.destDepartmentId,
"senderRoom": model.device.destRoom,
if (model?.sender?.attachments?.isNotEmpty ?? false)
"senderAttachments":
model?.sender?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(),
// "senderAssignedEmployeeId": "string", // "senderAssignedEmployeeId": "string",
// "senderMachineStatusId": 0, // "senderMachineStatusId": 0,
// "senderComment": "string", // "senderComment": "string",
@ -181,17 +205,27 @@ class DeviceTransferProvider extends ChangeNotifier {
"senderStartDate": newModel.timer?.startAt?.toIso8601String(), "senderStartDate": newModel.timer?.startAt?.toIso8601String(),
"senderEndDate": newModel.timer?.endAt?.toIso8601String(), "senderEndDate": newModel.timer?.endAt?.toIso8601String(),
"senderTravelingHours": newModel.travelingHours, "senderTravelingHours": newModel.travelingHours,
"senderAttachmentName": newModel?.signature ?? "", "senderEngSignature": newModel.engSignature,
"destSiteId": oldModel.receiver.client.id, if (newModel?.attachments?.isNotEmpty ?? false)
"destDepartmentId": oldModel.receiver.department.id, "senderAttachments":
newModel?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(),
"destSiteId": oldModel.receiver.client?.id,
"destDepartmentId": oldModel.receiver.department?.id,
"destBuildingId": oldModel.device?.destBuildingId,
"destFloorId": oldModel.device?.destFloorId,
"destRoom": oldModel.device?.destRoom,
"receiverAssignedEmployeeId": oldModel.receiver.userId, "receiverAssignedEmployeeId": oldModel.receiver.userId,
"receiverMachineStatusId": oldModel.receiver.status.id ?? "", "receiverMachineStatusId": oldModel.receiver.status.id ?? "",
"receiverComment": oldModel.receiver.comment, "receiverComment": oldModel.receiver.comment,
"receiverWorkingHours": oldModel.receiver.workingHours, "receiverWorkingHours": oldModel.receiver.workingHours,
"receiverStartDate": oldModel.receiver.timer?.startAt?.toIso8601String(), "receiverStartDate": oldModel.receiver.timer?.startAt?.toIso8601String(),
"receiverEndDate": oldModel.receiver.timer?.endAt?.toIso8601String(), "receiverEndDate": oldModel.receiver.timer?.endAt?.toIso8601String(),
"receiverTravelingHours": oldModel.receiver.travelingHours, "receiverTravelingHours": oldModel.receiver?.travelingHours,
"receiverAttachmentName": oldModel.receiver?.signature ?? "", "receiverEngSignature": oldModel.receiver?.engSignature,
if (oldModel.receiver?.attachments?.isNotEmpty ?? false)
"receiverAttachments": oldModel.receiver?.attachments
?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})
?.toList(),
}); });
} else { } else {
body.addAll({ body.addAll({
@ -203,10 +237,16 @@ class DeviceTransferProvider extends ChangeNotifier {
"senderWorkingHours": oldModel.sender.workingHours, "senderWorkingHours": oldModel.sender.workingHours,
"senderStartDate": oldModel.sender.timer?.startAt?.toIso8601String(), "senderStartDate": oldModel.sender.timer?.startAt?.toIso8601String(),
"senderEndDate": oldModel.sender.timer?.endAt?.toIso8601String(), "senderEndDate": oldModel.sender.timer?.endAt?.toIso8601String(),
"senderTravelingHours": oldModel.sender.travelingHours, "senderTravelingHours": oldModel.sender?.travelingHours,
"senderAttachmentName": oldModel.sender?.signature ?? "", "senderEngSignature": oldModel.sender?.engSignature,
"destSiteId": newModel.client.id, if (oldModel.sender?.attachments?.isNotEmpty ?? false)
"destDepartmentId": newModel.department.id, "senderAttachments":
oldModel.sender?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(),
"destSiteId": newModel.client?.id,
"destDepartmentId": newModel.department?.id,
"destBuildingId": oldModel.device?.destBuildingId,
"destFloorId": oldModel.device?.destFloorId,
"destRoom": oldModel.device?.destRoom,
"receiverAssignedEmployeeId": newModel.userId, "receiverAssignedEmployeeId": newModel.userId,
"receiverMachineStatusId": newModel.status?.id ?? "", "receiverMachineStatusId": newModel.status?.id ?? "",
"receiverComment": newModel.comment, "receiverComment": newModel.comment,
@ -214,18 +254,20 @@ class DeviceTransferProvider extends ChangeNotifier {
"receiverStartDate": newModel.timer?.startAt?.toIso8601String(), "receiverStartDate": newModel.timer?.startAt?.toIso8601String(),
"receiverEndDate": newModel.timer?.endAt?.toIso8601String(), "receiverEndDate": newModel.timer?.endAt?.toIso8601String(),
"receiverTravelingHours": newModel.travelingHours, "receiverTravelingHours": newModel.travelingHours,
"receiverAttachmentName": newModel?.signature ?? "", "receiverEngSignature": newModel.engSignature,
if (newModel?.attachments?.isNotEmpty ?? false)
"receiverAttachments":
newModel?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(),
}); });
} }
//body.addAll(newModel.toJson(isSender)); //body.addAll(newModel.toJson(isSender));
print(body); log(body?.toString());
Response response; Response response;
try { try {
response = await ApiManager.instance.put(URLs.updateDeviceTransfer, body: body); response = await ApiManager.instance.put(URLs.updateDeviceTransfer, body: body);
print(response.body); print(response.body);
print("${newModel.signature}.png"); print("${newModel.engSignature}.png");
// response = await post( // response = await post(
// Uri.parse("$host${URLs.updateDeviceTransfer}/$requestId"), // Uri.parse("$host${URLs.updateDeviceTransfer}/$requestId"),
// body: body, // body: body,
@ -246,4 +288,9 @@ class DeviceTransferProvider extends ChangeNotifier {
return -1; return -1;
} }
} }
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
} }

@ -17,20 +17,25 @@ class DevicesProvider extends ChangeNotifier {
final pageItemNumber = 10; final pageItemNumber = 10;
bool nextPage = true; bool nextPage = true;
// state code of current request to defied error message // state code of current request to defied error message
// like 400 customer request failed // like 400 customer request failed
// 500 service not available // 500 service not available
int _stateCode; int _stateCode;
int get stateCode => _stateCode; int get stateCode => _stateCode;
List<Device> _devices = []; List<Device> _devices = [];
List<Device> get devices => _devices; List<Device> get devices => _devices;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
// failed _loading = false // failed _loading = false
bool _loading; bool _loading;
bool get isLoading => _loading; bool get isLoading => _loading;
set isLoading(bool isLoading) { set isLoading(bool isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
@ -47,6 +52,7 @@ class DevicesProvider extends ChangeNotifier {
@required int hospitalId, @required int hospitalId,
String serialNumber, String serialNumber,
String number, String number,
bool isQr = false,
}) async { }) async {
if (_loading == true) return -2; if (_loading == true) return -2;
_loading = true; _loading = true;
@ -70,7 +76,15 @@ class DevicesProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List equipmentListJson = json.decode(response.body)["data"]; List equipmentListJson = json.decode(response.body)["data"];
_devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device)).toList()); var dList = equipmentListJson.map<Device>((device) => Device.fromJson(device, startKeyWithDest: false)).toList();
try {
if (isQr) {
dList = dList.where((element) => number?.toLowerCase() == element?.number?.toLowerCase())?.toList() ?? [];
}
} catch (e) {
print(e);
}
_devices.addAll(dList);
nextPage = true; nextPage = true;
} else { } else {
nextPage = false; nextPage = false;
@ -111,8 +125,8 @@ class DevicesProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List equipmentListJson = json.decode(response.body)["data"]; List equipmentListJson = json.decode(response.body)["data"];
page = equipmentListJson.map((device) => Device.fromJson(device)).toList(); page = equipmentListJson.map((device) => Device.fromJson(device, startKeyWithDest: false)).toList();
_devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device)).toList()); _devices.addAll(equipmentListJson.map<Device>((device) => Device.fromJson(device, startKeyWithDest: false)).toList());
notifyListeners(); notifyListeners();
} }
return page; return page;
@ -147,31 +161,31 @@ class DevicesProvider extends ChangeNotifier {
} }
} }
// /// return -2 if request in progress // /// return -2 if request in progress
// /// return -1 if error happen when sending request // /// return -1 if error happen when sending request
// /// return state code if request complete may be 200, 404 or 403 // /// return state code if request complete may be 200, 404 or 403
// /// for more details check http state manager // /// for more details check http state manager
// /// lib\controllers\http_status_manger\http_status_manger.dart // /// lib\controllers\http_status_manger\http_status_manger.dart
// Future<List<Device>> getDevicesListBySN({@required String host, @required User user, @required int hospitalId, @required String sn}) async { // Future<List<Device>> getDevicesListBySN({@required String host, @required User user, @required int hospitalId, @required String sn}) async {
// Response response; // Response response;
// try { // try {
// response = await get( // response = await get(
// Uri.parse(URLs.getEquipment + "?client=$hospitalId" + (sn == null || sn.isEmpty ? "" : "&serial_qr=$sn")), // Uri.parse(URLs.getEquipment + "?client=$hospitalId" + (sn == null || sn.isEmpty ? "" : "&serial_qr=$sn")),
// ); // );
// //
// _stateCode = response.statusCode; // _stateCode = response.statusCode;
// List<Device> _page = []; // List<Device> _page = [];
// if (response.statusCode >= 200 && response.statusCode < 300) { // if (response.statusCode >= 200 && response.statusCode < 300) {
// // client's request was successfully received // // client's request was successfully received
// List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); // List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
// _page = categoriesListJson.map((device) => Device.fromJson(device)).toList(); // _page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
// } // }
// return _page; // return _page;
// } catch (error) { // } catch (error) {
// _loading = false; // _loading = false;
// _stateCode = -1; // _stateCode = -1;
// notifyListeners(); // notifyListeners();
// return []; // return [];
// } // }
// } // }
} }

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
@ -6,6 +7,7 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart'; import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
class GasRefillProvider extends ChangeNotifier { class GasRefillProvider extends ChangeNotifier {
@ -47,20 +49,19 @@ class GasRefillProvider extends ChangeNotifier {
Future<int> getRequests({ Future<int> getRequests({
@required String host, @required String host,
@required User user, @required User user,
@required bool mostRecent,
}) async { }) async {
if (isLoading == true) return -2; if (isLoading == true) return -2;
isLoading = true; isLoading = true;
if (items?.isEmpty ?? true) notifyListeners();
Response response; Response response;
Map<String, dynamic> body = {}; Map<String, dynamic> body = {};
body["pageNumber"] = (items?.length ?? 0) ~/ pageItemNumber + 1; body["pageNumber"] = (items?.length ?? 0) ~/ pageItemNumber + 1;
body["pageSize"] = pageItemNumber; body["pageSize"] = pageItemNumber;
print("url:${URLs.getGasRefill}:body:$body"); body["mostRecent"] = mostRecent;
response = await ApiManager.instance.post( response = await ApiManager.instance.post(URLs.getGasRefill, body: body);
URLs.getGasRefill,
body: body,
);
stateCode = response.statusCode; stateCode = response.statusCode;
if (stateCode >= 200 && stateCode < 300) { if (stateCode >= 200 && stateCode < 300) {
// client's request was successfully received // client's request was successfully received
@ -68,6 +69,7 @@ class GasRefillProvider extends ChangeNotifier {
List<GasRefillModel> itemsPage = requestsListJson.map((request) => GasRefillModel.fromJson(request)).toList(); List<GasRefillModel> itemsPage = requestsListJson.map((request) => GasRefillModel.fromJson(request)).toList();
items ??= []; items ??= [];
items.addAll(itemsPage); items.addAll(itemsPage);
notifyListeners();
if (itemsPage.length == pageItemNumber) { if (itemsPage.length == pageItemNumber) {
nextPage = true; nextPage = true;
} else { } else {
@ -91,24 +93,22 @@ class GasRefillProvider extends ChangeNotifier {
@required User user, @required User user,
@required GasRefillModel model, @required GasRefillModel model,
}) async { }) async {
print("ss");
Map<String, dynamic> body = { Map<String, dynamic> body = {
"uid": user.id.toString(), "uid": user.id.toString(),
"token": user.token ?? "", "token": user.token ?? "",
"site": hospital?.toMap(), "site": hospital?.toMap(),
"building": {"id": building?.id, "name": building?.name, "value": building?.value}, "building": {"id": building?.id, "name": building?.name, "value": building?.value},
"floor": {"id": floor?.id, "name": floor?.name, "value": floor?.value}, "floor": {"id": floor?.id, "name": floor?.name, "value": floor?.value},
if (expectedDateTime != null) "expectedDate": expectedDateTime?.toIso8601String(), //if (expectedDateTime != null) "expectedDate": expectedDateTime?.toIso8601String(),
if (expectedDateTime != null) "expectedTime": expectedDateTime?.toIso8601String(), if (expectedDateTime != null) "expectedTime": expectedDateTime?.toIso8601String(),
if (startDate != null) "startDate": startDate?.toIso8601String(), if (timer?.startAt != null) "startDate": timer.startAt.toIso8601String(),
if (startDate != null) "startTime": startDate?.toIso8601String(), if (timer?.startAt != null) "startTime": timer.startAt.toIso8601String(),
if (endDate != null) "endDate": endDate?.toIso8601String(), if (timer?.endAt != null) "endDate": timer.endAt.toIso8601String(),
if (endDate != null) "endTime": endDate?.toIso8601String(), if (timer?.endAt != null) "endTime": timer.endAt.toIso8601String(),
"department": {"id": department?.id, "departmentName": department?.name, "departmentCode": "", "ntCode": ""}, "department": {"id": department?.id, "departmentName": department?.name, "departmentCode": "", "ntCode": ""},
"GazRefillNo": "GR-${DateTime.now().toString().split(" ").first}", "GazRefillNo": "GR-${DateTime.now().toString().split(" ").first}",
"status": model.status.toMap(), "status": model.status.toMap(),
}; };
print("ss1");
body["gazRefillDetails"] = model.details body["gazRefillDetails"] = model.details
.map((model) => { .map((model) => {
"gasType": model.type.toMap(), "gasType": model.type.toMap(),
@ -121,7 +121,6 @@ class GasRefillProvider extends ChangeNotifier {
Response response; Response response;
try { try {
response = await ApiManager.instance.post(URLs.requestGasRefill, body: body); response = await ApiManager.instance.post(URLs.requestGasRefill, body: body);
print("ss2");
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
if (items != null) { if (items != null) {
@ -146,13 +145,14 @@ class GasRefillProvider extends ChangeNotifier {
"id": newModel.id, "id": newModel.id,
"gazRefillNo": newModel.title ?? "", "gazRefillNo": newModel.title ?? "",
"status": newModel.status.toMap(), "status": newModel.status.toMap(),
"expectedDate": oldModel.expectedDate?.toIso8601String(), //"expectedDate": newModel.expectedDate?.toIso8601String(),
"expectedTime": oldModel.expectedDate?.toIso8601String(), "expectedTime": newModel.expectedDate?.toIso8601String(),
"startDate": startDate?.toIso8601String(), if (timer?.startAt != null) "startDate": timer.startAt.toIso8601String(),
"startTime": startDate?.toIso8601String(), if (timer?.startAt != null) "startTime": timer.startAt.toIso8601String(),
"endDate": endDate?.toIso8601String(), if (timer?.endAt != null) "endDate": timer.endAt.toIso8601String(),
"endTime": endDate?.toIso8601String(), if (timer?.endAt != null) "endTime": timer.endAt.toIso8601String(),
"workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60), // "workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60),
'workingHours': timer.durationInSecond != null ? timer.durationInSecond / 60 / 60 : newModel.workingHours,
"assignedEmployee": oldModel?.assignedEmployee?.id == null ? null : oldModel?.assignedEmployee?.toJson(), "assignedEmployee": oldModel?.assignedEmployee?.id == null ? null : oldModel?.assignedEmployee?.toJson(),
"site": hospital?.toMap(), "site": hospital?.toMap(),
"building": building?.toJson(includeFloors: false), "building": building?.toJson(includeFloors: false),
@ -171,7 +171,7 @@ class GasRefillProvider extends ChangeNotifier {
"deliverdQty": model.deliveredQuantity, "deliverdQty": model.deliveredQuantity,
}) })
.toList(); .toList();
log(body.toString());
Response response; Response response;
try { try {
response = await ApiManager.instance.put(URLs.updateGasRefill, body: body); response = await ApiManager.instance.put(URLs.updateGasRefill, body: body);
@ -196,6 +196,5 @@ class GasRefillProvider extends ChangeNotifier {
Floors floor; Floors floor;
Departments department; Departments department;
DateTime expectedDateTime; DateTime expectedDateTime;
DateTime startDate; TimerModel timer;
DateTime endDate;
} }

@ -22,22 +22,27 @@ class HospitalsProvider extends ChangeNotifier {
// like 400 customer request failed // like 400 customer request failed
// 500 service not available // 500 service not available
int _stateCode; int _stateCode;
int get stateCode => _stateCode; int get stateCode => _stateCode;
// true if there is next page in product list and false if not // true if there is next page in product list and false if not
bool _nextPage = true; bool _nextPage = true;
bool get nextPage => _nextPage; bool get nextPage => _nextPage;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Hospital> _hospitals; List<Hospital> _hospitals;
List<Hospital> get hospitals => _hospitals; List<Hospital> get hospitals => _hospitals;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
// failed _loading = false // failed _loading = false
bool _loading; bool _loading;
bool get isLoading => _loading; bool get isLoading => _loading;
set isLoading(bool isLoading) { set isLoading(bool isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();

@ -22,22 +22,27 @@ class PartsProvider extends ChangeNotifier {
// like 400 customer request failed // like 400 customer request failed
// 500 service not available // 500 service not available
int _stateCode; int _stateCode;
int get stateCode => _stateCode; int get stateCode => _stateCode;
// true if there is next page in product list and false if not // true if there is next page in product list and false if not
bool _nextPage = true; bool _nextPage = true;
bool get nextPage => _nextPage; bool get nextPage => _nextPage;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Part> _parts; List<Part> _parts;
List<Part> get parts => _parts; List<Part> get parts => _parts;
// when categories in-process _loading = true // when categories in-process _loading = true
// done _loading = true // done _loading = true
// failed _loading = false // failed _loading = false
bool _loading; bool _loading;
bool get isLoading => _loading; bool get isLoading => _loading;
set isLoading(bool isLoading) { set isLoading(bool isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
@ -85,17 +90,21 @@ class PartsProvider extends ChangeNotifier {
/// return state code if request complete may be 200, 404 or 403 /// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager /// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart /// lib\controllers\http_status_manger\http_status_manger.dart
Future<List<Part>> getPartsList({String host, User user, String title}) async { Future<List<Part>> getPartsList({String host, User user, num assetId, String title}) async {
Response response; Response response;
try { try {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partName": title}); if (int.tryParse(title) != null) {
List<Part> _page = []; response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partNo": title, "assetId": assetId});
} else {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partName": title, "assetId": assetId});
}
List<Part> page = [];
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List categoriesListJson = json.decode(response.body)["data"]; List categoriesListJson = json.decode(response.body)["data"];
_page = categoriesListJson.map((part) => Part.fromJson(part)).toList(); page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
} }
return _page; return page;
} catch (error) { } catch (error) {
return []; return [];
} }

@ -69,7 +69,7 @@ class PreventiveMaintenanceVisitsProvider extends ChangeNotifier {
// client's request was successfully received // client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes)); List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<Visit> _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); List<Visit> _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList();
if (visits == null) visits = []; visits ??= [];
visits.addAll(_visits); visits.addAll(_visits);
if (_visits.length == pageItemNumber) { if (_visits.length == pageItemNumber) {
nextPage = true; nextPage = true;

@ -13,7 +13,7 @@ import 'package:test_sa/models/visits/visits_search.dart';
class RegularVisitsProvider extends ChangeNotifier { class RegularVisitsProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 20; final pageItemNumber = 12;
//reset provider data //reset provider data
void reset() { void reset() {
@ -52,7 +52,7 @@ class RegularVisitsProvider extends ChangeNotifier {
}) async { }) async {
if (isLoading == true) return -2; if (isLoading == true) return -2;
isLoading = true; isLoading = true;
if (visits == null) notifyListeners(); if (visits?.isEmpty ?? true) notifyListeners();
Response response; Response response;
//userId = 397.toString(); // testing id to view data //userId = 397.toString(); // testing id to view data
@ -77,10 +77,11 @@ class RegularVisitsProvider extends ChangeNotifier {
// client's request was successfully received // client's request was successfully received
try { try {
List requestsListJson = json.decode(response.body)["data"]; List requestsListJson = json.decode(response.body)["data"];
List<Visit> _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); List<Visit> visits = requestsListJson.map((request) => Visit.fromJson(request)).toList();
visits ??= []; this.visits ??= [];
visits.addAll(_visits); this.visits.addAll(visits);
if (_visits.length == pageItemNumber) { notifyListeners();
if (visits.length == pageItemNumber) {
nextPage = true; nextPage = true;
} else { } else {
nextPage = false; nextPage = false;

@ -16,6 +16,7 @@ import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/timer_model.dart'; import 'package:test_sa/models/timer_model.dart';
import '../../../models/service_request/search_work_order.dart'; import '../../../models/service_request/search_work_order.dart';
import '../../../models/service_request/sub_work_order_details.dart';
import '../../../models/user.dart'; import '../../../models/user.dart';
class ServiceRequestsProvider extends ChangeNotifier { class ServiceRequestsProvider extends ChangeNotifier {
@ -57,7 +58,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
Future<int> getRequests({@required int hospitalId}) async { Future<int> getRequests({@required int hospitalId}) async {
if (isLoading == true) return -2; if (isLoading == true) return -2;
isLoading = true; isLoading = true;
if (serviceRequests == null) notifyListeners(); if (serviceRequests?.isEmpty ?? false) notifyListeners();
Response response; Response response;
try { try {
Map<String, dynamic> body = {}; Map<String, dynamic> body = {};
@ -77,6 +78,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
List<ServiceRequest> serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList(); List<ServiceRequest> serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList();
serviceRequests ??= []; serviceRequests ??= [];
serviceRequests.addAll(serviceRequestsPage); serviceRequests.addAll(serviceRequestsPage);
notifyListeners();
if (serviceRequestsPage.length == pageItemNumber) { if (serviceRequestsPage.length == pageItemNumber) {
nextPage = true; nextPage = true;
} else { } else {
@ -144,10 +146,10 @@ class ServiceRequestsProvider extends ChangeNotifier {
"client": user.clientId, "client": user.clientId,
"callComments": serviceRequest.callComments, "callComments": serviceRequest.callComments,
if (serviceRequest.devicePhotos.isNotEmpty) "attachmentsCallRequest": serviceRequest.devicePhotos.map((e) => {"name": e}).toList(), if (serviceRequest.devicePhotos.isNotEmpty) "attachmentsCallRequest": serviceRequest.devicePhotos.map((e) => {"name": e}).toList(),
"priority": serviceRequest.priority.toMap(), "priority": serviceRequest.priority?.toMap(),
"defectType": serviceRequest.defectType.toMap(), "defectType": serviceRequest.defectType?.toMap(),
"typeofRequest": serviceRequest.type.toMap(), "typeofRequest": serviceRequest.type?.toMap(),
"requestedThrough": serviceRequest.requestedThrough.toMap(), "requestedThrough": serviceRequest.requestedThrough?.toMap(),
"reviewComment": null, "reviewComment": null,
if (serviceRequest.audio != null) "voiceNote": serviceRequest.audio, if (serviceRequest.audio != null) "voiceNote": serviceRequest.audio,
"callSiteContactPerson": [ "callSiteContactPerson": [
@ -176,17 +178,26 @@ class ServiceRequestsProvider extends ChangeNotifier {
body["voiceNote"] = serviceRequest.audio; body["voiceNote"] = serviceRequest.audio;
} }
Response response; Response response;
try { //try {
response = await ApiManager.instance.post(URLs.createRequest, body: body); response = await ApiManager.instance.post(URLs.createRequest, body: body);
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
if (serviceRequests != null) serviceRequests.insert(0, ServiceRequest.fromJson(json.decode(utf8.decode(response.bodyBytes))[0])); if (serviceRequests != null) {
var data = json.decode(utf8.decode(response.bodyBytes));
if (data is List) {
serviceRequests.insert(0, ServiceRequest.fromJson(data[0]));
} else {
if (data["data"] != null && data["data"] == true) {
// serviceRequests.insert(0, ServiceRequest.fromJson(data[0]));
}
}
}
notifyListeners(); notifyListeners();
} }
return response.statusCode; return response.statusCode;
} catch (error) { // } catch (error) {
return -1; // return -1;
} // }
} }
Future<int> createIssueReport({ Future<int> createIssueReport({
@ -221,7 +232,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
Map<String, dynamic> serviceRequest = await getServiceRequestById(requestId: request.id) ?? ""; Map<String, dynamic> serviceRequest = await getServiceRequestById(requestId: request.id) ?? "";
final List callSiteContacts = (serviceRequest['callSiteContactPerson'] as List); final List callSiteContacts = (serviceRequest['callSiteContactPerson'] as List);
final Map<String, dynamic> callSiteContactPerson = callSiteContacts.isEmpty ? {} : callSiteContacts[0]; final Map<String, dynamic> callSiteContactPerson = callSiteContacts.isEmpty ? {} : callSiteContacts[0];
print(callSiteContactPerson);
Response response; Response response;
var body = { var body = {
"id": request.id, "id": request.id,
@ -305,7 +315,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
}, },
"assetType": report.assetType?.toMap(), "assetType": report.assetType?.toMap(),
"assignedEmployee": {"id": report.engineer?.id, "name": report.engineer?.name ?? ""}, "assignedEmployee": {"id": report.engineer?.id, "name": report.engineer?.name ?? ""},
"visitDate": report.visitDate?.toIso8601String() ?? "", "visitDate": report.returnToService?.toIso8601String() ?? "",
// "assistantEmployees": [ // "assistantEmployees": [
// {"id": report.engineer.id, "name": report.engineer.name}, // {"id": report.engineer.id, "name": report.engineer.name},
// ], // ],
@ -337,7 +347,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
?.map( ?.map(
(p) => { (p) => {
"id": p.reportPartID ?? 0, "id": p.reportPartID ?? 0,
"sparePart": {"id": p.id, "partNo": p.code, "partName": p.name}, "sparePart": {"id": p.id, "partNo": p.partNo, "partName": p.partName},
"qty": p.quantity "qty": p.quantity
}, },
) )
@ -354,7 +364,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
// body["uid"] = user.id; // body["uid"] = user.id;
// body["token"] = user.token; // body["token"] = user.token;
response = await ApiManager.instance.post(URLs.createServiceReport, body: body); response = await ApiManager.instance.post(URLs.createServiceReport, body: body);
print(response.body);
// response = await post( // response = await post(
// Uri.parse( // Uri.parse(
// host+URLs.createServiceReport), // host+URLs.createServiceReport),
@ -380,8 +389,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
try { try {
Map<String, dynamic> body = workOrder.toJson(); Map<String, dynamic> body = workOrder.toJson();
response = await ApiManager.instance.post(URLs.createServiceReport, body: body); response = await ApiManager.instance.post(URLs.createServiceReport, body: body);
print(response.body);
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
reset(); reset();
@ -432,7 +439,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List workOrdersJson = json.decode(response.body)["data"]; List workOrdersJson = json.decode(response.body)["data"];
print(workOrdersJson);
workOrders = workOrdersJson.map<SearchWorkOrder>((request) => SearchWorkOrder.fromJson(request)).toList(); workOrders = workOrdersJson.map<SearchWorkOrder>((request) => SearchWorkOrder.fromJson(request)).toList();
if (workOrders.length == pageItemNumber) { if (workOrders.length == pageItemNumber) {
nextPage = true; nextPage = true;
@ -446,6 +452,23 @@ class ServiceRequestsProvider extends ChangeNotifier {
} }
} }
Future<SubWorkOrderDetails> getSubWorkOrderDetails({@required String parentId}) async {
Response response;
try {
response = await ApiManager.instance.get(URLs.getSubWorkerInfoAccordingToPreviousStep + "?parentId=$parentId");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
final workOrderJson = json.decode(response.body)["data"];
return SubWorkOrderDetails.fromJson(workOrderJson);
}
return null;
} catch (e) {
print("getSubWorkOrderDetails [error] : $e");
return null;
}
}
Future<int> createDuplicatedReport({ Future<int> createDuplicatedReport({
@required String host, @required String host,
@required User user, @required User user,
@ -595,6 +618,19 @@ class ServiceRequestsProvider extends ChangeNotifier {
} }
} }
Future<ServiceRequest> getServiceRequestObjectById({@required String requestId}) async {
try {
Response response = await ApiManager.instance.get(URLs.getServiceRequestById + "?callRequestId=$requestId");
if (response.statusCode >= 200 && response.statusCode < 300) {
return ServiceRequest.fromJson(json.decode(response.body)["data"]);
} else {
return null;
}
} catch (error) {
return null;
}
}
Future<Map<String, dynamic>> getServiceRequestById({@required String requestId}) async { Future<Map<String, dynamic>> getServiceRequestById({@required String requestId}) async {
Response response; Response response;
try { try {
@ -651,7 +687,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List workOrdersJson = json.decode(response.body)["data"]; List workOrdersJson = json.decode(response.body)["data"];
print(workOrdersJson);
workOrders ??= []; workOrders ??= [];
workOrders.addAll(workOrdersJson.map<SearchWorkOrder>((request) => SearchWorkOrder.fromJson(request)).toList()); workOrders.addAll(workOrdersJson.map<SearchWorkOrder>((request) => SearchWorkOrder.fromJson(request)).toList());
if (workOrders.length == pageItemNumber) { if (workOrders.length == pageItemNumber) {

@ -0,0 +1,75 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class AssetTransferStatusProvider extends ChangeNotifier {
//reset provider data
void reset() {
_items = null;
_loading = null;
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading) {
_loading = isLoading;
notifyListeners();
}
/// return -2 if request in progress
/// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData({
String host,
User user,
}) async {
if (_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try {
response = await ApiManager.instance.get(URLs.getAssetTransferStatus);
_stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(response.body)["data"];
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -1,13 +1,12 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/engineer.dart'; import 'package:test_sa/models/engineer.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class EngineersProvider extends ChangeNotifier { class EngineersProvider extends ChangeNotifier {
//reset provider data //reset provider data

@ -1,8 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';

@ -1,8 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';

@ -1,12 +1,9 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';

@ -1,12 +1,9 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';

@ -0,0 +1,53 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/service_request/search_work_order.dart';
class VendorProvider extends ChangeNotifier {
void reset() {
_vendors = null;
_loading = null;
_stateCode = null;
}
int _stateCode;
int get stateCode => _stateCode;
List<Supplier> _vendors;
List<Supplier> get vendors => _vendors;
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading) {
_loading = isLoading;
notifyListeners();
}
Future<int> getVendors(String text) async {
if (_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try {
response = await ApiManager.instance.get("${URLs.getSuppliersAutoComplete}?searchText=$text");
_stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List suppliersJson = json.decode(response.body)["data"];
_vendors = suppliersJson.map((type) => Supplier.fromJson(type)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -66,4 +66,8 @@ class ServiceRequestedThroughProvider extends ChangeNotifier {
return -1; return -1;
} }
} }
Lookup getDefaultItem() {
return items?.firstWhere((element) => element.name.toLowerCase().contains("app"));
}
} }

@ -66,4 +66,8 @@ class ServiceRequestTypeProvider extends ChangeNotifier {
return -1; return -1;
} }
} }
Lookup getDefaultItem() {
return items?.firstWhere((element) => element.name.toLowerCase().contains("maintenance"));
}
} }

@ -63,6 +63,7 @@ class UserProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch (error) { } catch (error) {
print(error);
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return -1; return -1;
@ -112,45 +113,45 @@ class UserProvider extends ChangeNotifier {
/// return state code if request complete may be 200, 404 or 403 /// return state code if request complete may be 200, 404 or 403
/// for more details about state codes check http state manager /// for more details about state codes check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart /// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> updateProfile({ // Future<int> updateProfile({
@required String host, // @required String host,
@required User user, // @required User user,
}) async { // }) async {
if (_loading == true) return -2; // if (_loading == true) return -2;
_loading = true; // _loading = true;
notifyListeners(); // notifyListeners();
Response response; // Response response;
//
Map<String, dynamic> jsonObject = {}; // Map<String, dynamic> jsonObject = {};
jsonObject["uid"] = user.id; // jsonObject["uid"] = user.id;
jsonObject["token"] = user.token; // jsonObject["token"] = user.token;
if (user.departmentId != _user.departmentId) jsonObject["department"] = user.departmentId; // if (user.departmentId != _user.departmentId) jsonObject["department"] = user.departmentId;
// if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp; // // if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp;
if (user.phoneNumber != _user.phoneNumber) jsonObject["phone"] = user.phoneNumber; // if (user.phoneNumber != _user.phoneNumber) jsonObject["phone"] = user.phoneNumber;
try { // try {
response = response = await ApiManager.instance.post( // response = response = await ApiManager.instance.post(
URLs.login, // URLs.login,
body: jsonObject, // body: jsonObject,
); // );
} catch (error) { // } catch (error) {
_loading = false; // _loading = false;
notifyListeners(); // notifyListeners();
return -1; // return -1;
} // }
//
_loading = false; // _loading = false;
notifyListeners(); // notifyListeners();
//
if (response.statusCode >= 200 && response.statusCode < 300) { // if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // // client's request was successfully received
_user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); // _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
_user.clientId = user.clientId; // _user.clientId = user.clientId;
_user.clientName = user.clientName; // _user.clientName = user.clientName;
_user.departmentName = user.departmentName; // _user.departmentName = user.departmentName;
_user.departmentId = user.departmentId; // _user.departmentId = user.departmentId;
notifyListeners(); // notifyListeners();
return response.statusCode; // return response.statusCode;
} // }
return response.statusCode; // return response.statusCode;
} // }
} }

@ -1,10 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.dart';
import '../settings/app_settings.dart'; import '../settings/app_settings.dart';
class SettingProvider extends ChangeNotifier { class SettingProvider extends ChangeNotifier {

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
extension WidgetExtensions on Widget { extension WidgetExtensions on Widget {
Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this);

@ -13,6 +13,7 @@ import 'package:test_sa/controllers/providers/api/hospitals_provider.dart';
import 'package:test_sa/controllers/providers/api/notifications_provider.dart'; import 'package:test_sa/controllers/providers/api/notifications_provider.dart';
import 'package:test_sa/controllers/providers/api/regular_visits_provider.dart'; import 'package:test_sa/controllers/providers/api/regular_visits_provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/asset_transfer_status_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/assigned_to_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/employee/assigned_to_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/engineers_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/employee/engineers_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_cylinder_size_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_cylinder_size_provider.dart';
@ -63,6 +64,7 @@ import 'controllers/providers/api/status_drop_down/report/service_report_repair_
import 'controllers/providers/api/status_drop_down/report/service_report_status_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_status_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_report_types_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_types_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_types_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import 'controllers/providers/api/status_drop_down/report/vendor_provider.dart';
import 'controllers/providers/api/user_provider.dart'; import 'controllers/providers/api/user_provider.dart';
import 'controllers/providers/settings/setting_provider.dart'; import 'controllers/providers/settings/setting_provider.dart';
import 'views/pages/device_transfer/request_device_transfer.dart'; import 'views/pages/device_transfer/request_device_transfer.dart';
@ -81,20 +83,23 @@ void main() async {
} }
runApp(ChangeNotifierProvider( runApp(ChangeNotifierProvider(
create: (_) => SettingProvider(), create: (_) => SettingProvider(),
child: MyApp(), child: const MyApp(),
)); ));
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
// This widget is the root of your application. // This widget is the root of your application.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _settingProvider = Provider.of<SettingProvider>(context); final settingProvider = Provider.of<SettingProvider>(context);
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (_) => UserProvider()), ChangeNotifierProvider(create: (_) => UserProvider()),
ChangeNotifierProvider(create: (_) => HospitalsProvider()), ChangeNotifierProvider(create: (_) => HospitalsProvider()),
ChangeNotifierProvider(create: (_) => DevicesProvider()), ChangeNotifierProvider(create: (_) => DevicesProvider()),
ChangeNotifierProvider(create: (_) => AssetTransferStatusProvider()),
ChangeNotifierProvider(create: (_) => ServiceRequestsProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestsProvider()),
ChangeNotifierProvider(create: (_) => DepartmentsProvider()), ChangeNotifierProvider(create: (_) => DepartmentsProvider()),
ChangeNotifierProvider(create: (_) => NotificationsProvider()), ChangeNotifierProvider(create: (_) => NotificationsProvider()),
@ -131,6 +136,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => ServiceReportMaintenanceSituationProvider()), ChangeNotifierProvider(create: (_) => ServiceReportMaintenanceSituationProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportUsersProvider()), ChangeNotifierProvider(create: (_) => ServiceReportUsersProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()), ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()),
ChangeNotifierProvider(create: (_) => VendorProvider()),
], ],
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
@ -160,7 +166,7 @@ class MyApp extends StatelessWidget {
Locale('en'), Locale('en'),
Locale('ar'), Locale('ar'),
], ],
locale: Locale(_settingProvider.language ?? 'en'), locale: Locale(settingProvider.language ?? 'en'),
initialRoute: SplashScreen.id, initialRoute: SplashScreen.id,
routes: { routes: {
SplashScreen.id: (_) => const SplashScreen(), SplashScreen.id: (_) => const SplashScreen(),

@ -1,3 +1,5 @@
import 'package:test_sa/models/lookup.dart';
class CallRequestForWorkOrder { class CallRequestForWorkOrder {
int id; int id;
String callNo; String callNo;
@ -71,11 +73,11 @@ class Asset {
String ipAddress; String ipAddress;
String macAddress; String macAddress;
String portNumber; String portNumber;
String assetReplace; Lookup assetReplace;
String oldAsset; String oldAsset;
bool isParent; Lookup isParent;
String parentAsset; String parentAsset;
int assetType; Lookup assetType;
Site site; Site site;
Building building; Building building;
String floor; String floor;
@ -171,11 +173,11 @@ class Asset {
ipAddress = json['ipAddress']; ipAddress = json['ipAddress'];
macAddress = json['macAddress']; macAddress = json['macAddress'];
portNumber = json['portNumber']; portNumber = json['portNumber'];
assetReplace = json['assetReplace']; assetReplace = json['assetReplace'] != null ? Lookup.fromJson(json['assetReplace']) : null;
oldAsset = json['oldAsset']; oldAsset = json['oldAsset'];
isParent = json['isParent']; isParent = json['isParent'] != null ? Lookup.fromJson(json['isParent']) : null;
parentAsset = json['parentAsset']; parentAsset = json['parentAsset'];
assetType = json['assetType']; assetType = json['assetType'] != null ? Lookup.fromJson(json['assetType']) : null;
site = json['site'] != null ? new Site.fromJson(json['site']) : null; site = json['site'] != null ? new Site.fromJson(json['site']) : null;
building = json['building']; building = json['building'];
floor = json['floor']; floor = json['floor'];
@ -457,12 +459,12 @@ class AssignedEmployee {
class CallSiteContactPerson { class CallSiteContactPerson {
int id; int id;
Null employeeCode; String employeeCode;
String name; String name;
String telephone; String telephone;
String job; String job;
String email; String email;
Null land; String land;
String contactUserId; String contactUserId;
CallSiteContactPerson({this.id, this.employeeCode, this.name, this.telephone, this.job, this.email, this.land, this.contactUserId}); CallSiteContactPerson({this.id, this.employeeCode, this.name, this.telephone, this.job, this.email, this.land, this.contactUserId});

@ -9,10 +9,14 @@ class Device {
String number; String number;
String assetName; String assetName;
String destBuildingName; String destBuildingName;
int destBuildingId;
String destDepartmentName; String destDepartmentName;
int destDepartmentId;
String destRoom; String destRoom;
String destFloor; String destFloor;
int destFloorId;
String destSiteName; String destSiteName;
// String brand; // String brand;
// String model; // String model;
ModelDefinition modelDefinition; ModelDefinition modelDefinition;
@ -32,10 +36,12 @@ class Device {
// this.brand, // this.brand,
// this.model, // this.model,
this.modelDefinition, this.modelDefinition,
this.destFloorId,
this.destDepartmentId,
this.destBuildingId,
}); });
factory Device.fromJson(Map<String, dynamic> parsedJson) { factory Device.fromJson(Map<String, dynamic> parsedJson, {bool startKeyWithDest = true}) {
print("parsedJson:$parsedJson");
return Device( return Device(
id: parsedJson["id"], id: parsedJson["id"],
serialNumber: parsedJson["assetSerialNo"], serialNumber: parsedJson["assetSerialNo"],
@ -43,10 +49,13 @@ class Device {
assetName: parsedJson["assetName"], assetName: parsedJson["assetName"],
modelDefinition: ModelDefinition.fromJson(parsedJson["modelDefinition"]), modelDefinition: ModelDefinition.fromJson(parsedJson["modelDefinition"]),
hospital: Hospital.fromJson(parsedJson["site"]), hospital: Hospital.fromJson(parsedJson["site"]),
destBuildingName: parsedJson["destBuildingName"], destBuildingName: startKeyWithDest ? parsedJson["destBuildingName"] : parsedJson['building']['name'],
destDepartmentName: parsedJson["destDepartmentName"], destBuildingId: startKeyWithDest ? parsedJson["destBuildingName"] : parsedJson['building']['id'],
destRoom: parsedJson["destRoom"], destDepartmentName: startKeyWithDest ? parsedJson["destDepartmentName"] : parsedJson['department']['departmentName'],
destFloor: parsedJson["destFloor"], destDepartmentId: startKeyWithDest ? parsedJson["destDepartmentName"] : parsedJson['department']['id'],
destRoom: startKeyWithDest ? parsedJson["destRoom"] : parsedJson['room'],
destFloor: startKeyWithDest ? parsedJson["destFloor"] : parsedJson['floor']['name'],
destFloorId: startKeyWithDest ? null : parsedJson['floor']['id'],
destSiteName: parsedJson['destSiteName'] destSiteName: parsedJson['destSiteName']
// parsedJson["modelDefinition"] == null ? "" : // parsedJson["modelDefinition"] == null ? "" :
// parsedJson["modelDefinition"]["manufacturerName"], // parsedJson["modelDefinition"]["manufacturerName"],

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/department.dart'; import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/models/device/device.dart';
@ -14,6 +16,7 @@ class DeviceTransfer {
Device device; Device device;
DeviceTransferInfo sender; DeviceTransferInfo sender;
DeviceTransferInfo receiver; DeviceTransferInfo receiver;
String createdOn;
DeviceTransfer({ DeviceTransfer({
this.id, this.id,
@ -22,6 +25,7 @@ class DeviceTransfer {
this.userId, this.userId,
this.sender, this.sender,
this.receiver, this.receiver,
this.createdOn,
}); });
bool validate() { bool validate() {
@ -40,20 +44,35 @@ class DeviceTransfer {
final receiver = DeviceTransferInfo(); final receiver = DeviceTransferInfo();
receiver.fromDetails(old.receiver); receiver.fromDetails(old.receiver);
this.receiver = receiver; this.receiver = receiver;
createdOn = old.createdOn;
} }
factory DeviceTransfer.fromJson(Map<String, dynamic> parsedJson) { factory DeviceTransfer.fromJson(Map<String, dynamic> parsedJson) {
List<String> senderFiles = [];
if (parsedJson["senderAttachments"] != null && parsedJson["senderAttachments"] is List) {
List list = parsedJson["senderAttachments"];
senderFiles = list.map((e) => (URLs.getFileUrl(e["attachmentName"]))).toList();
}
List<String> receiverFiles = [];
if (parsedJson["receiverAttachments"] != null && parsedJson["receiverAttachments"] is List) {
List list = parsedJson["receiverAttachments"];
receiverFiles = list.map((e) => (URLs.getFileUrl(e["attachmentName"]))).toList();
}
return DeviceTransfer( return DeviceTransfer(
id: parsedJson["id"], id: parsedJson["id"],
title: parsedJson["transferCode"], title: parsedJson["transferCode"],
userId: parsedJson["uid"], userId: parsedJson["uid"],
createdOn: parsedJson['createdOn'],
device: Device( device: Device(
id: parsedJson["assetId"], id: parsedJson["assetId"],
number: parsedJson["assetNumber"], number: parsedJson["assetNumber"],
assetName: parsedJson["assetName"], assetName: parsedJson["assetName"],
serialNumber: parsedJson["assetSerialNo"], serialNumber: parsedJson["assetSerialNo"],
destBuildingId: parsedJson["destBuildingId"],
destBuildingName: parsedJson["destBuildingName"], destBuildingName: parsedJson["destBuildingName"],
destDepartmentId: parsedJson["destDepartmentId"],
destDepartmentName: parsedJson["destDepartmentName"], destDepartmentName: parsedJson["destDepartmentName"],
destFloorId: parsedJson["destFloorId"],
destFloor: parsedJson["destFloorName"], destFloor: parsedJson["destFloorName"],
destRoom: parsedJson["destRoom"], destRoom: parsedJson["destRoom"],
destSiteName: parsedJson["destSiteName"], destSiteName: parsedJson["destSiteName"],
@ -62,6 +81,7 @@ class DeviceTransfer {
travelingHours: parsedJson["senderTravelingHours"], travelingHours: parsedJson["senderTravelingHours"],
comment: parsedJson["senderComment"], comment: parsedJson["senderComment"],
workingHours: parsedJson["senderWorkingHours"], workingHours: parsedJson["senderWorkingHours"],
attachments: senderFiles?.map((e) => File(e))?.toList(),
timer: TimerModel( timer: TimerModel(
startAt: DateTime.tryParse(parsedJson["senderStartDate"] ?? ""), startAt: DateTime.tryParse(parsedJson["senderStartDate"] ?? ""),
endAt: DateTime.tryParse(parsedJson["senderEndDate"] ?? ""), endAt: DateTime.tryParse(parsedJson["senderEndDate"] ?? ""),
@ -77,8 +97,7 @@ class DeviceTransfer {
id: parsedJson["senderDepartmentId"], id: parsedJson["senderDepartmentId"],
name: parsedJson["senderDepartmentName"], name: parsedJson["senderDepartmentName"],
), ),
// todo add segnature engSignature: URLs.getFileUrl(parsedJson["senderEngSignature"]),
signature: URLs.getFileUrl(parsedJson["senderAttachmentName"]),
status: Lookup( status: Lookup(
id: parsedJson["senderMachineStatusId"], id: parsedJson["senderMachineStatusId"],
name: parsedJson["senderMachineStatusName"], name: parsedJson["senderMachineStatusName"],
@ -88,6 +107,7 @@ class DeviceTransfer {
travelingHours: parsedJson["receiverTravelingHours"], travelingHours: parsedJson["receiverTravelingHours"],
comment: parsedJson["receiverComment"], comment: parsedJson["receiverComment"],
workingHours: parsedJson["receiverWorkingHours"], workingHours: parsedJson["receiverWorkingHours"],
attachments: receiverFiles?.map((e) => File(e))?.toList(),
timer: parsedJson["receiverStartDate"] != null || parsedJson["receiverEndDate"] != null timer: parsedJson["receiverStartDate"] != null || parsedJson["receiverEndDate"] != null
? TimerModel(startAt: DateTime.tryParse(parsedJson["receiverStartDate"] ?? ""), endAt: DateTime.tryParse(parsedJson["receiverEndDate"] ?? "")) ? TimerModel(startAt: DateTime.tryParse(parsedJson["receiverStartDate"] ?? ""), endAt: DateTime.tryParse(parsedJson["receiverEndDate"] ?? ""))
: null, : null,
@ -101,8 +121,7 @@ class DeviceTransfer {
id: parsedJson["destDepartmentId"], id: parsedJson["destDepartmentId"],
name: parsedJson["destDepartmentName"], name: parsedJson["destDepartmentName"],
), ),
// todo add segnature engSignature: URLs.getFileUrl(parsedJson["receiverEngSignature"]),
signature: URLs.getFileUrl(parsedJson["receiverAttachmentName"]),
status: Lookup( status: Lookup(
id: parsedJson["receiverMachineStatusId"], id: parsedJson["receiverMachineStatusId"],
name: parsedJson["receiverMachineStatusName"], name: parsedJson["receiverMachineStatusName"],

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:test_sa/models/department.dart'; import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
@ -10,11 +12,13 @@ class DeviceTransferInfo {
Hospital client; Hospital client;
Department department; Department department;
String workingHours; String workingHours;
// DateTime startDate; // DateTime startDate;
// DateTime endDate; // DateTime endDate;
String travelingHours; String travelingHours;
String userName; String userName;
String signature; String engSignature;
List<File> attachments;
String assignedEmployeeName; String assignedEmployeeName;
Lookup status; Lookup status;
TimerModel timer; TimerModel timer;
@ -29,10 +33,11 @@ class DeviceTransferInfo {
// this.startDate, // this.startDate,
// this.endDate, // this.endDate,
this.workingHours, this.workingHours,
this.signature, this.engSignature,
this.status, this.status,
this.assignedEmployeeName, this.assignedEmployeeName,
this.timer, this.timer,
this.attachments,
}); });
Map<String, String> toJson(bool isSender) { Map<String, String> toJson(bool isSender) {
@ -47,7 +52,7 @@ class DeviceTransferInfo {
if (timer?.endAt != null) body["${baseKey}end_date"] = timer?.endAt?.toIso8601String(); if (timer?.endAt != null) body["${baseKey}end_date"] = timer?.endAt?.toIso8601String();
if (travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = travelingHours; if (travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = travelingHours;
if (status != null) body["${baseKey}status"] = status.id.toString(); if (status != null) body["${baseKey}status"] = status.id.toString();
if (signature != null && signature.isNotEmpty) body["${baseKey}image"] = signature; if (engSignature != null && engSignature.isNotEmpty) body["${baseKey}image"] = engSignature;
return body; return body;
} }
@ -63,40 +68,37 @@ class DeviceTransferInfo {
client = Hospital.fromHospital(old.client); client = Hospital.fromHospital(old.client);
department = Department.fromDepartment(old.department); department = Department.fromDepartment(old.department);
workingHours = old.workingHours; workingHours = old.workingHours;
attachments = old.attachments ?? [];
// startDate = old.startDate; // startDate = old.startDate;
// endDate = old.endDate; // endDate = old.endDate;
timer = old.timer; timer = old.timer;
travelingHours = old.travelingHours; travelingHours = old.travelingHours;
comment = old.comment; comment = old.comment;
if (withSignature) signature = old.signature; if (withSignature) engSignature = old.engSignature;
status = old.status; status = old.status;
} }
factory DeviceTransferInfo.fromJson(Map<String, dynamic> parsedJson, String key) { // factory DeviceTransferInfo.fromJson(Map<String, dynamic> parsedJson, String key) {
return DeviceTransferInfo( // return DeviceTransferInfo(
workingHours: parsedJson["${key}working_hours"], // workingHours: parsedJson["${key}working_hours"],
// startDate: parsedJson["${key}start_date"], // // startDate: parsedJson["${key}start_date"],
// endDate: parsedJson["${key}end_date"], // // endDate: parsedJson["${key}end_date"],
timer: TimerModel( // timer: TimerModel(
startAt: DateTime.tryParse(parsedJson["${key}start_date"] ?? ""), // startAt: DateTime.tryParse(parsedJson["${key}start_date"] ?? ""),
endAt: DateTime.tryParse(parsedJson["${key}end_date"] ?? ""), // endAt: DateTime.tryParse(parsedJson["${key}end_date"] ?? ""),
durationInSecond: ((parsedJson["${key}working_hours"] ?? 0) * 60 * 60).toInt(), // durationInSecond: ((parsedJson["${key}working_hours"] ?? 0) * 60 * 60).toInt(),
), // ),
travelingHours: parsedJson["${key}travel_hours"], // travelingHours: parsedJson["${key}travel_hours"],
userName: parsedJson["${key}name"], // userName: parsedJson["${key}name"],
signature: parsedJson["${key}image"], // signature: parsedJson["${key}image"],
userId: parsedJson["${key}id"], // userId: parsedJson["${key}id"],
comment: parsedJson["${key}comment"], // comment: parsedJson["${key}comment"],
assignedEmployeeName: parsedJson["${key}AssignedEmployeeName"], // assignedEmployeeName: parsedJson["${key}AssignedEmployeeName"],
client: Hospital(id: parsedJson["${key}SiteId"], name: parsedJson["${key}SiteName"]), // client: Hospital(id: parsedJson["${key}SiteId"], name: parsedJson["${key}SiteName"]),
department: Department( // department: Department(
id: parsedJson["${key}DepartmentId"], // id: parsedJson["${key}DepartmentId"],
name: parsedJson["${key}DepartmentName"], // name: parsedJson["${key}DepartmentName"],
), // ),
status: Lookup( // );
id: parsedJson["${key}status"], // }
name: parsedJson["${key}status"],
),
);
}
} }

@ -0,0 +1,67 @@
import 'package:test_sa/models/device/device.dart';
import '../hospital.dart';
class DeviceTransferSearch {
Device device;
String title, room;
bool mostRecent;
Hospital hospital;
Buildings building;
List<Buildings> buildingsList;
Floors floor;
List<Floors> floorsList;
Departments department;
List<Departments> departmentsList;
DeviceTransferSearch({
this.device,
this.hospital,
this.building,
this.floor,
this.department,
this.room,
this.title,
this.mostRecent = true,
});
Map<String, dynamic> toMap() {
Map<String, dynamic> search = {};
if (title != null && title.isNotEmpty) {
search["transferCode"] = title;
}
if (device != null) {
search["assetId"] = device.id;
}
if (mostRecent != null) {
search["mostRecent"] = mostRecent;
}
if (hospital?.id != null) {
search["destSiteId"] = hospital.id;
}
if (building?.id != null) {
search["destBuildingId"] = building.id;
}
if (floor?.id != null) {
search["destFloorId"] = floor.id;
}
if (department?.id != null) {
search["destDepartmentId"] = department.id;
}
if (room != null && room.isNotEmpty) {
search["destRoom"] = department.id;
}
return search;
}
void fromSearch(DeviceTransferSearch newSearch) {
title = newSearch.title;
room = newSearch.room;
mostRecent = newSearch.mostRecent;
device = newSearch.device;
hospital = newSearch.hospital;
building = newSearch.building;
floor = newSearch.floor;
department = newSearch.department;
}
}

@ -8,6 +8,7 @@ import '../call_request_for_work_order_model.dart';
class GasRefillModel { class GasRefillModel {
int id; int id;
//String userId; //String userId;
String clientName; String clientName;
String title; String title;
@ -21,8 +22,9 @@ class GasRefillModel {
String signatureEngineer; String signatureEngineer;
Uint8List localNurseSignature; Uint8List localNurseSignature;
Uint8List localEngineerSignature; Uint8List localEngineerSignature;
num workingHours;
DateTime startDate, endDate, expectedDate; DateTime startDate, endDate, expectedDate;
GasRefillModel({ GasRefillModel({
this.id, this.id,
//this.userId, //this.userId,
@ -41,6 +43,7 @@ class GasRefillModel {
this.signatureEngineer, this.signatureEngineer,
this.localEngineerSignature, this.localEngineerSignature,
this.localNurseSignature, this.localNurseSignature,
this.workingHours,
}); });
bool validate() { bool validate() {
@ -73,6 +76,7 @@ class GasRefillModel {
localNurseSignature = model.localNurseSignature; localNurseSignature = model.localNurseSignature;
signatureEngineer = model.signatureEngineer; signatureEngineer = model.signatureEngineer;
signatureNurse = model.signatureNurse; signatureNurse = model.signatureNurse;
workingHours = model.workingHours;
} }
factory GasRefillModel.fromJson(Map<String, dynamic> parsedJson) { factory GasRefillModel.fromJson(Map<String, dynamic> parsedJson) {
@ -97,6 +101,7 @@ class GasRefillModel {
assignedEmployee: AssignedEmployee.fromJson(parsedJson['assignedEmployee'] ?? {}), assignedEmployee: AssignedEmployee.fromJson(parsedJson['assignedEmployee'] ?? {}),
signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]), signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]),
signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]), signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]),
workingHours: parsedJson["workingHours"],
); );
} }
} }

@ -22,7 +22,7 @@ class CalibrationTool {
factory CalibrationTool.fromMap(Map<String, dynamic> map) { factory CalibrationTool.fromMap(Map<String, dynamic> map) {
return CalibrationTool( return CalibrationTool(
assetsNumber: Lookup(id: map["assetId"], name: map['assetSerialNo']), assetsNumber: Lookup(id: map["assetId"], name: map['assetNumber']),
dataOfTesting: DateTime.tryParse(map['calibrationDateOfTesters'] ?? ""), dataOfTesting: DateTime.tryParse(map['calibrationDateOfTesters'] ?? ""),
); );
} }

@ -18,7 +18,8 @@ class Pentry {
DateTime expectedVisitDate; DateTime expectedVisitDate;
String travelingHours; String travelingHours;
String image; String image;
File imageFile; List<File> files = [];
// List<Contact> contacts; // List<Contact> contacts;
List<PPMCheckList> ppmCheckLists; List<PPMCheckList> ppmCheckLists;
List<CalibrationTool> calibrationTools; List<CalibrationTool> calibrationTools;
@ -36,7 +37,7 @@ class Pentry {
this.actualVisitDate, this.actualVisitDate,
this.expectedVisitDate, this.expectedVisitDate,
this.image, this.image,
this.imageFile, this.files,
// this.contacts, // this.contacts,
this.ppmCheckLists, this.ppmCheckLists,
this.calibrationTools, this.calibrationTools,
@ -74,8 +75,8 @@ class Pentry {
Map<String, dynamic> toMap(int visitId) { Map<String, dynamic> toMap(int visitId) {
Map<String, dynamic> map = {}; Map<String, dynamic> map = {};
map["visitStatusId"] = ppmVisitStatus?.id.toString(); map["visitStatusId"] = ppmVisitStatus?.id?.toString();
if (status != null) map["deviceStatusId"] = status?.id.toString(); if (status != null) map["deviceStatusId"] = status?.id?.toString();
if (travelingHours != null) map["travelingHours"] = travelingHours; if (travelingHours != null) map["travelingHours"] = travelingHours;
//if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync()); //if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync());
map["actualDate"] = actualVisitDate.toIso8601String(); map["actualDate"] = actualVisitDate.toIso8601String();
@ -85,10 +86,8 @@ class Pentry {
map["endDate"] = timer.endAt?.toIso8601String() ?? DateTime.now().toIso8601String(); map["endDate"] = timer.endAt?.toIso8601String() ?? DateTime.now().toIso8601String();
map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5); map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
} }
if (imageFile != null) { if (files?.isNotEmpty ?? false) {
map["vAttachments"] = [ map["vAttachments"] = files.map((file) => {"attachmentName": _isLocalUrl(file.path) ? (file.path.split("/").last + "|" + base64Encode(file.readAsBytesSync())) : file.path}).toList();
{"attachmentName": (imageFile.path.split("/").last + base64Encode(imageFile.readAsBytesSync()))}
];
} }
map["travelingHours"] = travelingHours; map["travelingHours"] = travelingHours;
// if(contacts?.isNotEmpty == true) { // if(contacts?.isNotEmpty == true) {
@ -101,11 +100,16 @@ class Pentry {
map["vChecklists"] = ppmCheckLists.map((e) => e.toMap(visitId)).toList(); map["vChecklists"] = ppmCheckLists.map((e) => e.toMap(visitId)).toList();
map["vCalibrationTools"] = calibrationTools.map((e) => e.toMap(visitId)).toList(); map["vCalibrationTools"] = calibrationTools.map((e) => e.toMap(visitId)).toList();
map["vKits"] = pmKits.map((e) => e.toMap(visitId)).toList(); map["vKits"] = pmKits.map((e) => e.toMap(visitId)).toList();
map["nurseSignature"] = signatureNurse;//"${DateTime.now().toIso8601String()}.png|$signatureNurse"; map["nurseSignature"] = signatureNurse; //"${DateTime.now().toIso8601String()}.png|$signatureNurse";
map["engSignature"] = signatureEngineer;//"${DateTime.now().toIso8601String()}.png|$signatureEngineer"; map["engSignature"] = signatureEngineer; //"${DateTime.now().toIso8601String()}.png|$signatureEngineer";
return map; return map;
} }
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
factory Pentry.fromMap(Map<String, dynamic> map) { factory Pentry.fromMap(Map<String, dynamic> map) {
// List<Contact> contacts = []; // List<Contact> contacts = [];
// if(map['contacts'] != null){ // if(map['contacts'] != null){
@ -118,7 +122,12 @@ class Pentry {
if (map['vKits'] != null) { if (map['vKits'] != null) {
pmKits = (map['vKits'] as List<dynamic>).map((e) => PMKit.fromMap(e as Map<String, dynamic>)).toList(); pmKits = (map['vKits'] as List<dynamic>).map((e) => PMKit.fromMap(e as Map<String, dynamic>)).toList();
} }
List<String> files = [];
if (map["vAttachments"] != null) if (map["vAttachments"] is List) {
List list = map["vAttachments"];
list.removeWhere((element) => (element["attachmentURL"]?.toString() ?? "").isEmpty);
files = list.map((e) => URLs.getFileUrl(e["attachmentName"])).toList();
}
List<PPMCheckList> ppmCheckLists = []; List<PPMCheckList> ppmCheckLists = [];
if (map['vChecklists'] != null) { if (map['vChecklists'] != null) {
ppmCheckLists = (map['vChecklists'] as List<dynamic>).map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>)).toList(); ppmCheckLists = (map['vChecklists'] as List<dynamic>).map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>)).toList();
@ -129,7 +138,7 @@ class Pentry {
calibrationTools = (map['vCalibrationTools'] as List<dynamic>).map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>)).toList(); calibrationTools = (map['vCalibrationTools'] as List<dynamic>).map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>)).toList();
} }
return Pentry( return Pentry(
status: Lookup(id: map["taskStatusId"], name: map["taskStatusName"]), status: Lookup(id: map["deviceStatusId"], name: map["deviceStatusName"]),
ppmVisitStatus: Lookup(id: map["visitStatusId"], name: map["visitStatusName"]), ppmVisitStatus: Lookup(id: map["visitStatusId"], name: map["visitStatusName"]),
actualVisitDate: DateTime.tryParse(map["actualDate"] ?? ""), actualVisitDate: DateTime.tryParse(map["actualDate"] ?? ""),
expectedVisitDate: DateTime.tryParse(map["expectedDate"] ?? ""), expectedVisitDate: DateTime.tryParse(map["expectedDate"] ?? ""),
@ -143,6 +152,10 @@ class Pentry {
ppmCheckLists: ppmCheckLists, ppmCheckLists: ppmCheckLists,
calibrationTools: calibrationTools, calibrationTools: calibrationTools,
pmKits: pmKits, pmKits: pmKits,
files: files?.map((e) {
return File(e);
})?.toList() ??
[],
signatureNurse: URLs.getFileUrl(map["nurseSignature"]), signatureNurse: URLs.getFileUrl(map["nurseSignature"]),
signatureEngineer: URLs.getFileUrl(map["engSignature"]), signatureEngineer: URLs.getFileUrl(map["engSignature"]),
); );
@ -156,7 +169,7 @@ class Pentry {
DateTime expectedVisitDate, DateTime expectedVisitDate,
String travelingHours, String travelingHours,
String image, String image,
File imageFile, List<File> files,
List<PPMCheckList> ppmCheckLists, List<PPMCheckList> ppmCheckLists,
List<CalibrationTool> calibrationTools, List<CalibrationTool> calibrationTools,
List<PMKit> pmKits, List<PMKit> pmKits,
@ -171,11 +184,17 @@ class Pentry {
expectedVisitDate: expectedVisitDate ?? this.expectedVisitDate, expectedVisitDate: expectedVisitDate ?? this.expectedVisitDate,
travelingHours: travelingHours ?? this.travelingHours, travelingHours: travelingHours ?? this.travelingHours,
image: image ?? this.image, image: image ?? this.image,
imageFile: imageFile ?? this.imageFile, files: files ?? this.files,
ppmCheckLists: ppmCheckLists ?? this.ppmCheckLists?.map((e) => e.copyWith())?.toList(), ppmCheckLists: ppmCheckLists ?? this.ppmCheckLists?.map((e) => e.copyWith())?.toList(),
calibrationTools: calibrationTools ?? this.calibrationTools?.map((e) => e.copyWith())?.toList(), calibrationTools: calibrationTools ?? this.calibrationTools?.map((e) => e.copyWith())?.toList(),
pmKits: pmKits ?? this.pmKits.map((e) => e.copyWith()).toList(), pmKits: pmKits ?? this.pmKits.map((e) => e.copyWith()).toList(),
signatureNurse: signatureNurse ?? this.signatureNurse, signatureNurse: signatureNurse ?? this.signatureNurse,
signatureEngineer: signatureEngineer ?? this.signatureEngineer); signatureEngineer: signatureEngineer ?? this.signatureEngineer);
} }
void clearEmptyObjects() {
ppmCheckLists.removeWhere((element) => (element?.title?.isEmpty ?? true) && (element?.comment?.isEmpty ?? true) && (element?.measuredValue?.isEmpty ?? true) && element.status == null);
calibrationTools.removeWhere((element) => (element?.assetsNumber == null) && (element?.dataOfTesting == null));
pmKits.removeWhere((element) => (element?.itemCode == null));
}
} }

@ -1,23 +1,28 @@
class Part { class Part {
int id; int id;
int reportPartID; int reportPartID;
String code; String partNo;
String name; String partName;
int quantity; int quantity;
double returnQty, installQty;
Part({ Part({
this.id, this.id,
this.reportPartID, this.reportPartID,
this.code, this.partNo,
this.name, this.partName,
this.quantity = 1, this.quantity = 1,
this.installQty,
this.returnQty,
}); });
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
"id": reportPartID ?? 0, "id": reportPartID ?? 0,
"sparePart": {"id": id, "partNo": code, "partName": name}, "sparePart": {"id": id, "partNo": partNo, "partName": partName},
"qty": quantity "qty": quantity,
if (returnQty != null) "returnQty": returnQty,
if (installQty != null) "installQty": installQty,
}; };
} }
@ -25,9 +30,11 @@ class Part {
return Part( return Part(
id: parsedJson["id"], id: parsedJson["id"],
reportPartID: reportJson != null ? reportJson["id"] : null, reportPartID: reportJson != null ? reportJson["id"] : null,
code: parsedJson["partNo"], partNo: parsedJson["partNo"],
name: parsedJson["partName"], partName: parsedJson["partName"],
quantity: reportJson != null ? (reportJson["qty"] ?? 1).toInt() : 1, quantity: reportJson != null ? (reportJson["qty"] ?? 1).toInt() : 1,
returnQty: parsedJson["returnQty"],
installQty: parsedJson["installQty"],
); );
} }
} }

@ -14,6 +14,8 @@ class ServiceReport {
int id; int id;
double operatingHours; double operatingHours;
DateTime visitDate; DateTime visitDate;
DateTime returnToService;
// DateTime endDate; // DateTime endDate;
// DateTime startDate; // DateTime startDate;
Lookup assetType; Lookup assetType;
@ -32,7 +34,7 @@ class ServiceReport {
String invoiceNumber; String invoiceNumber;
String invoiceCode; String invoiceCode;
List<Part> parts; List<Part> parts;
String image; List<String> files;
Device device; Device device;
String quantity; String quantity;
String jobSheetNumber; String jobSheetNumber;
@ -46,8 +48,8 @@ class ServiceReport {
String reviewComment; String reviewComment;
FaultDescription faultDescription; FaultDescription faultDescription;
ServiceReport({ ServiceReport(
this.id, {this.id,
this.visitDate, this.visitDate,
// this.endDate, // this.endDate,
this.assetType, this.assetType,
@ -64,7 +66,7 @@ class ServiceReport {
this.callLastSituation, this.callLastSituation,
this.currentSituation, this.currentSituation,
this.jobSheetNumber, this.jobSheetNumber,
this.image, this.files,
this.device, this.device,
this.invoiceCode, this.invoiceCode,
this.invoiceNumber, this.invoiceNumber,
@ -80,12 +82,14 @@ class ServiceReport {
// this.startDate, // this.startDate,
this.reviewComment, this.reviewComment,
this.faultDescription, this.faultDescription,
}); this.returnToService});
Map<String, dynamic> toMap(ServiceRequest request) { Map<String, dynamic> toMap(ServiceRequest request) {
Map<String, dynamic> _map = {}; Map<String, dynamic> _map = {};
if (id != null) _map["id"] = id; if (id != null) _map["id"] = id;
if (visitDate != null) _map["visitDate"] = visitDate.toIso8601String(); if (visitDate != null) _map["visitDate"] = visitDate.toIso8601String();
if (returnToService != null) _map["replacementDate"] = returnToService.toIso8601String();
//if(serviceType != null) _map["service_type"] = serviceType.id.toString(); //if(serviceType != null) _map["service_type"] = serviceType.id.toString();
if (equipmentStatus != null) _map["equipmentStatus"] = equipmentStatus?.toMap(); if (equipmentStatus != null) _map["equipmentStatus"] = equipmentStatus?.toMap();
if (type != null) _map["typeOfWO"] = type?.toMap(); if (type != null) _map["typeOfWO"] = type?.toMap();
@ -132,10 +136,8 @@ class ServiceReport {
//if(image != null) _map["image"] = image; //if(image != null) _map["image"] = image;
//if(invoiceCode != null) _map["invoice_no"] = invoiceCode; //if(invoiceCode != null) _map["invoice_no"] = invoiceCode;
//if(invoiceNumber != null) _map["invoice_code"] = invoiceNumber; //if(invoiceNumber != null) _map["invoice_code"] = invoiceNumber;
if (image != null) { if (files != null) {
_map["attachmentsWorkOrder"] = [ _map["attachmentsWorkOrder"] = files.map((e) => {"name": e}).toList();
{"name": image}
];
} }
_map["nurseSignature"] = signatureNurse; _map["nurseSignature"] = signatureNurse;
_map["engSignature"] = signatureEngineer; _map["engSignature"] = signatureEngineer;
@ -152,15 +154,14 @@ class ServiceReport {
} }
Future<bool> validate() async { Future<bool> validate() async {
print("visitDate:$visitDate"); // if (visitDate == null) {
print("equipmentStatus:${equipmentStatus?.toMap()}"); // await Fluttertoast.showToast(msg: "Visit Date Required");
print("callLastSituation:${callLastSituation?.toMap()}"); // return false;
print("parts:$parts"); // }
print("reason:${reason?.toMap()}"); // if (returnToService == null) {
if (visitDate == null) { // await Fluttertoast.showToast(msg: "Return To Service Date Required");
await Fluttertoast.showToast(msg: "Visit Date Required"); // return false;
return false; // }
}
if (timer?.startAt == null) { if (timer?.startAt == null) {
await Fluttertoast.showToast(msg: "Working Hours Required"); await Fluttertoast.showToast(msg: "Working Hours Required");
return false; return false;
@ -196,6 +197,11 @@ class ServiceReport {
_parts = partsList.map((e) => Part.fromJson(e["sparePart"], reportJson: e)).toList(); _parts = partsList.map((e) => Part.fromJson(e["sparePart"], reportJson: e)).toList();
} }
} }
List<String> _files = [];
if (parsedJson["attachmentsWorkOrder"] != null && parsedJson["attachmentsWorkOrder"] is List) {
List list = parsedJson["attachmentsWorkOrder"];
_files = list.map((e) => (URLs.getFileUrl(e["name"]))).toList();
}
return ServiceReport( return ServiceReport(
id: id, id: id,
assetType: Lookup.fromJson(parsedJson["assetType"]), assetType: Lookup.fromJson(parsedJson["assetType"]),
@ -206,7 +212,7 @@ class ServiceReport {
equipmentStatus: Lookup.fromJson(parsedJson["equipmentStatus"]), equipmentStatus: Lookup.fromJson(parsedJson["equipmentStatus"]),
type: Lookup.fromJson(parsedJson["typeOfWO"]), type: Lookup.fromJson(parsedJson["typeOfWO"]),
faultDescription: parsedJson['faultDescription'] != null ? FaultDescription.fromJson(parsedJson['faultDescription']) : null, faultDescription: parsedJson['faultDescription'] != null ? FaultDescription.fromJson(parsedJson['faultDescription']) : null,
files: _files,
// faultDescription: parsedJson["faultDescription"], // faultDescription: parsedJson["faultDescription"],
// startDate: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""), // startDate: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""),
// endDate: DateTime.tryParse(parsedJson["endofWorkTime"] ?? ""), // endDate: DateTime.tryParse(parsedJson["endofWorkTime"] ?? ""),
@ -219,7 +225,8 @@ class ServiceReport {
//quantity: parsedJson["nid"], //quantity: parsedJson["nid"],
travelingHours: parsedJson["travelingHours"], travelingHours: parsedJson["travelingHours"],
travelingExpense: parsedJson["travelingExpenses"], travelingExpense: parsedJson["travelingExpenses"],
visitDate: DateTime.tryParse(parsedJson["visitDate"]), visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? ""),
returnToService: DateTime.tryParse(parsedJson["replacementDate"] ?? ""),
workingHours: parsedJson["workingHours"], workingHours: parsedJson["workingHours"],
timer: TimerModel( timer: TimerModel(
startAt: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""), startAt: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""),

File diff suppressed because it is too large Load Diff

@ -1,5 +1,6 @@
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/fault_description.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
class ServiceRequest { class ServiceRequest {
@ -27,8 +28,9 @@ class ServiceRequest {
bool viewReport; bool viewReport;
String engineerMobile; String engineerMobile;
String deviceModel; String deviceModel;
String faultDescription; FaultDescription faultDescription;
String workPerformed;
//String workPerformed;
String visitDate; String visitDate;
DateTime nextVisitDate; DateTime nextVisitDate;
String jobSheetNumber; String jobSheetNumber;
@ -68,7 +70,7 @@ class ServiceRequest {
this.jobSheetNumber, this.jobSheetNumber,
this.visitDate, this.visitDate,
this.nextVisitDate, this.nextVisitDate,
this.workPerformed, //this.workPerformed,
this.reportID, this.reportID,
this.defectType, this.defectType,
this.priority, this.priority,
@ -86,7 +88,7 @@ class ServiceRequest {
List<String> images = []; List<String> images = [];
if (parsedJson["attachmentsCallRequest"] != null) if (parsedJson["attachmentsCallRequest"] is List) { if (parsedJson["attachmentsCallRequest"] != null) if (parsedJson["attachmentsCallRequest"] is List) {
List list = parsedJson["attachmentsCallRequest"]; List list = parsedJson["attachmentsCallRequest"];
images = list.map((e) => URLs.getFileUrl(e["attachmentsCallRequest"])).toList(); images = list.map((e) => URLs.getFileUrl(e["name"])).toList();
} }
return ServiceRequest( return ServiceRequest(
id: parsedJson["id"].toString(), id: parsedJson["id"].toString(),
@ -114,16 +116,21 @@ class ServiceRequest {
viewReport: parsedJson["workOrder"] != null, viewReport: parsedJson["workOrder"] != null,
deviceModel: parsedJson["asset"]["modelDefinition"]["modelName"], deviceModel: parsedJson["asset"]["modelDefinition"]["modelName"],
engineerMobile: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["phone"], engineerMobile: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["phone"],
faultDescription: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["faultDescription"] : null, faultDescription: parsedJson["workOrder"] != null
? parsedJson["workOrder"]["faultDescription"] != null
? FaultDescription.fromJson(parsedJson["workOrder"]["faultDescription"])
: null
: null,
jobSheetNumber: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["jobSheetNumber"] : null, jobSheetNumber: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["jobSheetNumber"] : null,
visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? "").toString().split(" ").first, visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? "").toString().split(" ").first,
nextVisitDate: DateTime.tryParse(parsedJson["nextVisitDate"] ?? ""), nextVisitDate: DateTime.tryParse(parsedJson["nextVisitDate"] ?? ""),
workPerformed: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workPerformed"] : null, //workPerformed: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workPerformed"] : null,
device: Device.fromJson(parsedJson["asset"]), device: Device.fromJson(parsedJson["asset"]),
reviewComment: parsedJson["reviewComment"], reviewComment: parsedJson["reviewComment"],
type: Lookup.fromJson(parsedJson['typeofRequest']), type: Lookup.fromJson(parsedJson['typeofRequest']),
defectType: Lookup.fromJson(parsedJson['defectType']), defectType: Lookup.fromJson(parsedJson['defectType']),
loanAvailability: Lookup.fromJson(parsedJson['loanAvailability']), loanAvailability: Lookup.fromJson(parsedJson['loanAvailablity']),
firstAction: Lookup.fromJson(parsedJson['firstAction']), firstAction: Lookup.fromJson(parsedJson['firstAction']),
requestedThrough: Lookup.fromJson(parsedJson['requestedThrough']), requestedThrough: Lookup.fromJson(parsedJson['requestedThrough']),
priority: Lookup.fromJson(parsedJson['priority']), priority: Lookup.fromJson(parsedJson['priority']),

@ -1,13 +1,20 @@
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import '../call_request_for_work_order_model.dart';
class ServiceRequestSearch { class ServiceRequestSearch {
String callId;
String deviceSerialNumber; String deviceSerialNumber;
String deviceNumber; String deviceNumber;
String deviceName; String deviceName;
Hospital hospital; Hospital hospital;
String model; String model;
Lookup statusValue; Lookup statusValue;
bool mostRecent;
String from, to;
Lookup dateOperator;
AssignedEmployee assignedEmployee;
ServiceRequestSearch({ ServiceRequestSearch({
this.deviceSerialNumber, this.deviceSerialNumber,
@ -16,6 +23,12 @@ class ServiceRequestSearch {
this.deviceName, this.deviceName,
this.model, this.model,
this.hospital, this.hospital,
this.callId,
this.from,
this.to,
this.assignedEmployee,
this.dateOperator,
this.mostRecent = true,
}); });
fromSearch(ServiceRequestSearch newSearch) { fromSearch(ServiceRequestSearch newSearch) {
@ -24,6 +37,12 @@ class ServiceRequestSearch {
statusValue = newSearch.statusValue; statusValue = newSearch.statusValue;
hospital = newSearch.hospital; hospital = newSearch.hospital;
model = newSearch.model; model = newSearch.model;
mostRecent = newSearch.mostRecent;
callId = newSearch.callId;
from = newSearch.from;
to = newSearch.to;
assignedEmployee = newSearch.assignedEmployee;
dateOperator = newSearch.dateOperator;
} }
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
@ -32,6 +51,10 @@ class ServiceRequestSearch {
search["assetSerialNumber"] = deviceSerialNumber; search["assetSerialNumber"] = deviceSerialNumber;
} }
if (mostRecent != null) {
search["mostRecent"] = mostRecent;
}
if (deviceNumber != null && deviceNumber.isNotEmpty) { if (deviceNumber != null && deviceNumber.isNotEmpty) {
search["assetNo"] = deviceNumber; search["assetNo"] = deviceNumber;
} }
@ -48,9 +71,24 @@ class ServiceRequestSearch {
search["site"] = hospital.name; search["site"] = hospital.name;
} }
if (model != null) { if (model != null && model.isNotEmpty) {
search["modelDefinition"] = model; search["modelDefinition"] = model;
} }
if (callId != null && callId.isNotEmpty) {
search["callId"] = callId;
}
if (dateOperator != null && from != null) {
search["requestedDateSymbol"] = dateOperator.toMap();
search["requestedDateFrom"] = from;
}
if (dateOperator != null && to != null) {
search["requestedDateTo"] = to;
}
if (assignedEmployee != null) {
search["assignedEmployee"] = assignedEmployee.toJson();
}
return search; return search;
} }
} }

@ -0,0 +1,73 @@
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_request/search_work_order.dart';
import '../fault_description.dart';
class SubWorkOrderDetails {
Lookup equipmentStatus;
Lookup reason;
FaultDescription faultDescription;
List<SparePartsWorkOrders> sparePartsWorkOrders;
List<SuppEngineerWorkOrders> suppEngineerWorkOrders;
SupplierModel supplier;
SubWorkOrderDetails({
this.equipmentStatus,
this.reason,
this.faultDescription,
this.sparePartsWorkOrders,
this.supplier,
this.suppEngineerWorkOrders,
});
SubWorkOrderDetails.fromJson(dynamic json) {
if (json['equipmentStatus'] != null) equipmentStatus = Lookup.fromJson(json['equipmentStatus']);
if (json['reason'] != null) reason = Lookup.fromJson(json['reason']);
if (json['faultDescription'] != null) faultDescription = FaultDescription.fromJson(json['faultDescription']);
if (json['supplier'] != null) supplier = SupplierModel.fromJson(json['supplier']);
if (json['sparePartsWorkOrders'] != null) {
sparePartsWorkOrders = [];
json['sparePartsWorkOrders'].forEach((v) {
sparePartsWorkOrders.add(SparePartsWorkOrders.fromJson(v));
});
}
if (json['suppEngineerWorkOrders'] != null) {
suppEngineerWorkOrders = [];
json['suppEngineerWorkOrders'].forEach((v) {
suppEngineerWorkOrders.add(SuppEngineerWorkOrders.fromJson(v));
});
}
}
SubWorkOrderDetails copyWith({
Lookup equipmentStatus,
Lookup reason,
FaultDescription faultDescription,
List<SparePartsWorkOrders> sparePartsWorkOrders,
SupplierModel supplier,
SuppEngineerWorkOrders suppEngineerWorkOrders,
}) =>
SubWorkOrderDetails(
equipmentStatus: equipmentStatus ?? this.equipmentStatus,
reason: reason ?? this.reason,
faultDescription: faultDescription ?? this.faultDescription,
sparePartsWorkOrders: sparePartsWorkOrders ?? this.sparePartsWorkOrders,
supplier: supplier ?? this.supplier,
suppEngineerWorkOrders: suppEngineerWorkOrders ?? this.suppEngineerWorkOrders,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['equipmentStatus'] = equipmentStatus?.toMap();
map['reason'] = reason?.toMap();
map['faultDescription'] = faultDescription?.toJson();
if (sparePartsWorkOrders?.isNotEmpty ?? false) {
map['sparePartsWorkOrders'] = sparePartsWorkOrders?.map((e) => e.toJson())?.toList();
}
if (suppEngineerWorkOrders?.isNotEmpty ?? false) {
map['suppEngineerWorkOrders'] = suppEngineerWorkOrders?.map((e) => e.toJson())?.toList();
}
map['supplier'] = supplier?.toJson();
return map;
}
}

@ -84,6 +84,7 @@ class Subtitle {
String hospital; String hospital;
String device; String device;
String deviceImages; String deviceImages;
String deviceFiles;
String pickDevice; String pickDevice;
String maintenanceIssue; String maintenanceIssue;
String create; String create;
@ -186,6 +187,7 @@ class Subtitle {
String image; String image;
String pickImage; String pickImage;
String requiredImage; String requiredImage;
String requiredFile;
String taskStatus; String taskStatus;
String activationAlert; String activationAlert;
@ -205,7 +207,7 @@ class Subtitle {
String reasons; String reasons;
String attachImage; String attachImage;
String operatingHours; String operatingHours;
String partNumber; String partNumberName;
String number; String number;
String quantity; String quantity;
String orderWorkNumber; String orderWorkNumber;
@ -236,6 +238,8 @@ class Subtitle {
String department; String department;
String room; String room;
String actions; String actions;
String pickFromFiles;
String pickFile;
void setIssues(List<String> issues) { void setIssues(List<String> issues) {
issues.clear(); issues.clear();
@ -359,6 +363,7 @@ class Subtitle {
@required this.createServiceRequest, @required this.createServiceRequest,
@required this.delete, @required this.delete,
@required this.deviceImages, @required this.deviceImages,
@required this.deviceFiles,
@required this.deviceRequired, @required this.deviceRequired,
@required this.general, @required this.general,
@required this.maintenanceIssueRequired, @required this.maintenanceIssueRequired,
@ -404,6 +409,7 @@ class Subtitle {
@required this.image, @required this.image,
@required this.pickImage, @required this.pickImage,
@required this.requiredImage, @required this.requiredImage,
@required this.requiredFile,
@required this.activationAlert, @required this.activationAlert,
@required this.callId, @required this.callId,
@required this.requiredWord, @required this.requiredWord,
@ -417,7 +423,7 @@ class Subtitle {
@required this.newServiceReport, @required this.newServiceReport,
@required this.number, @required this.number,
@required this.operatingHours, @required this.operatingHours,
@required this.partNumber, @required this.partNumberName,
@required this.reasons, @required this.reasons,
@required this.reportStatus, @required this.reportStatus,
@required this.reportType, @required this.reportType,
@ -447,6 +453,8 @@ class Subtitle {
@required this.department, @required this.department,
@required this.room, @required this.room,
@required this.actions, @required this.actions,
@required this.pickFromFiles,
@required this.pickFile,
}); });
factory Subtitle.fromJson(Map<String, dynamic> parsedJson) { factory Subtitle.fromJson(Map<String, dynamic> parsedJson) {
@ -520,6 +528,7 @@ class Subtitle {
device: parsedJson["device"], device: parsedJson["device"],
deviceArName: parsedJson["deviceArName"], deviceArName: parsedJson["deviceArName"],
deviceImages: parsedJson["deviceImages"], deviceImages: parsedJson["deviceImages"],
deviceFiles: parsedJson["deviceFiles"],
deviceModel: parsedJson["deviceModel"], deviceModel: parsedJson["deviceModel"],
deviceName: parsedJson["deviceName"], deviceName: parsedJson["deviceName"],
deviceRequired: parsedJson["deviceRequired"], deviceRequired: parsedJson["deviceRequired"],
@ -607,6 +616,7 @@ class Subtitle {
image: parsedJson["image"], image: parsedJson["image"],
pickImage: parsedJson["pickImage"], pickImage: parsedJson["pickImage"],
requiredImage: parsedJson["requiredImage"], requiredImage: parsedJson["requiredImage"],
requiredFile: parsedJson["requiredFile"],
taskStatus: parsedJson["taskStatus"], taskStatus: parsedJson["taskStatus"],
activationAlert: parsedJson["activationAlert"], activationAlert: parsedJson["activationAlert"],
attachImage: parsedJson["attachImage"], attachImage: parsedJson["attachImage"],
@ -618,7 +628,7 @@ class Subtitle {
newServiceReport: parsedJson["newServiceReport"], newServiceReport: parsedJson["newServiceReport"],
number: parsedJson["number"], number: parsedJson["number"],
operatingHours: parsedJson["operatingHours"], operatingHours: parsedJson["operatingHours"],
partNumber: parsedJson["partNumber"], partNumberName: parsedJson["partNumberName"],
quantity: parsedJson["quantity"], quantity: parsedJson["quantity"],
reasons: parsedJson["reasons"], reasons: parsedJson["reasons"],
reportStatus: parsedJson["reportStatus"], reportStatus: parsedJson["reportStatus"],
@ -651,6 +661,8 @@ class Subtitle {
department: parsedJson["department"], department: parsedJson["department"],
room: parsedJson["room"], room: parsedJson["room"],
actions: parsedJson["actions"], actions: parsedJson["actions"],
pickFromFiles: parsedJson["pickFromFiles"],
pickFile: parsedJson["pickFile"],
); );
} }
} }

@ -2,6 +2,7 @@ class TimerModel {
DateTime startAt; DateTime startAt;
DateTime endAt; DateTime endAt;
int durationInSecond; int durationInSecond;
// bool stopped; // bool stopped;
TimerModel({this.startAt, this.endAt, this.durationInSecond}); TimerModel({this.startAt, this.endAt, this.durationInSecond});

@ -4,8 +4,8 @@ import 'package:test_sa/models/enums/user_types.dart';
class User { class User {
int clientId; int clientId;
String clientName; String clientName;
int departmentId; List<int> departmentId;
String departmentName; List<String> departmentName;
String message; String message;
String username; String username;
String userID; String userID;
@ -76,10 +76,10 @@ class User {
} }
UsersTypes get type { UsersTypes get type {
switch (userRoles?.first?.name) { switch (userRoles?.first?.value) {
case "Engineer": case "R-6":
return UsersTypes.engineer; return UsersTypes.engineer;
case "Hospital": case "R-7":
return UsersTypes.normal_user; return UsersTypes.normal_user;
default: default:
return null; return null;
@ -148,8 +148,18 @@ class User {
User.fromJson(dynamic json) { User.fromJson(dynamic json) {
clientId = json['client_id']; clientId = json['client_id'];
clientName = json['client_name']; clientName = json['client_name'];
departmentId = json['department_id']; if (json['department_id'] != null) {
departmentName = json['department_name']; departmentId = [];
json['department_id'].forEach((v) {
departmentId.add(v);
});
}
if (json['department_name'] != null) {
departmentId = [];
json['department_name'].forEach((v) {
departmentId.add(v);
});
}
message = json['message']; message = json['message'];
username = json['username']; username = json['username'];
userID = json['userID']; userID = json['userID'];

@ -1,3 +1,4 @@
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/pentry.dart'; import 'package:test_sa/models/pantry/pentry.dart';
@ -6,6 +7,7 @@ class Visit {
String serialNumber; String serialNumber;
String expectDate; String expectDate;
String actualDate; String actualDate;
String createdOn;
int hospitalId; int hospitalId;
String hospitalName; String hospitalName;
int deviceId; int deviceId;
@ -42,13 +44,16 @@ class Visit {
this.images, this.images,
this.assignTo, this.assignTo,
this.deviceNumber, this.deviceNumber,
this.createdOn,
}); });
factory Visit.fromJson(Map<String, dynamic> parsedJson) { factory Visit.fromJson(Map<String, dynamic> parsedJson) {
List<String> images = []; List<String> images = [];
if (parsedJson["vAttachments"] is List) { if (parsedJson["vAttachments"] is List) {
List list = parsedJson["vAttachments"]; List list = parsedJson["vAttachments"];
images = list.map((e) => e["attachmentURL"].toString()).toList(); images = list.map((e) {
return URLs.getFileUrl(e["attachmentURL"].toString());
}).toList();
} }
return Visit( return Visit(
id: parsedJson["id"], id: parsedJson["id"],
@ -73,6 +78,8 @@ class Visit {
name: parsedJson["visitStatusName"] // text value name: parsedJson["visitStatusName"] // text value
), ),
assignTo: parsedJson["assignedToName"], assignTo: parsedJson["assignedToName"],
pentry: Pentry.fromMap(parsedJson)); pentry: Pentry.fromMap(parsedJson),
createdOn: parsedJson['createdOn'],
);
} }
} }

@ -3,6 +3,8 @@ import 'package:test_sa/models/lookup.dart';
class VisitsSearch { class VisitsSearch {
String deviceSerialNumber; String deviceSerialNumber;
String deviceName;
String deviceNumber;
Hospital hospital; Hospital hospital;
String brand; String brand;
Lookup model; Lookup model;
@ -12,6 +14,7 @@ class VisitsSearch {
DateTime actualDateFrom; DateTime actualDateFrom;
DateTime actualDateTo; DateTime actualDateTo;
Lookup statusValue; Lookup statusValue;
bool mostRecent;
VisitsSearch({ VisitsSearch({
this.deviceSerialNumber, this.deviceSerialNumber,
@ -24,6 +27,9 @@ class VisitsSearch {
this.contactStatus, this.contactStatus,
this.expectedDateFrom, this.expectedDateFrom,
this.expectedDateTo, this.expectedDateTo,
this.deviceNumber,
this.deviceName,
this.mostRecent = true,
}); });
fromSearch(VisitsSearch newSearch) { fromSearch(VisitsSearch newSearch) {
@ -37,6 +43,9 @@ class VisitsSearch {
expectedDateFrom = newSearch.expectedDateFrom; expectedDateFrom = newSearch.expectedDateFrom;
expectedDateTo = newSearch.expectedDateTo; expectedDateTo = newSearch.expectedDateTo;
statusValue = newSearch.statusValue; statusValue = newSearch.statusValue;
mostRecent = newSearch.mostRecent;
deviceNumber = newSearch.deviceNumber;
deviceName = newSearch.deviceName;
} }
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
@ -49,6 +58,10 @@ class VisitsSearch {
_search["siteId"] = hospital.id; _search["siteId"] = hospital.id;
} }
if (mostRecent != null) {
_search["mostRecent"] = mostRecent;
}
if (brand != null && brand.isNotEmpty) { if (brand != null && brand.isNotEmpty) {
// todo get new key // todo get new key
_search[""] = brand; _search[""] = brand;

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
class AColors { class AColors {
AColors._(); AColors._();
static const Color white = Color(0xffffffff); static const Color white = Color(0xffffffff);
static const Color black = Color(0xff000000); static const Color black = Color(0xff000000);
static const Color grey3A = Color(0xff2e303a); static const Color grey3A = Color(0xff2e303a);

@ -3,9 +3,7 @@ import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/device/device_transfer.dart'; import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
@ -13,6 +11,7 @@ import 'package:test_sa/views/pages/device_transfer/update_device_transfer.dart'
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart'; import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_info_section.dart'; import 'package:test_sa/views/widgets/device_trancfer/device_transfer_info_section.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart';
@ -28,12 +27,10 @@ class DeviceTransferDetails extends StatefulWidget {
} }
class _DeviceTransferDetailsState extends State<DeviceTransferDetails> { class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
final DeviceTransferInfo _model = DeviceTransferInfo(); DeviceTransfer _model;
bool _isSender = false; bool _isSender = false;
bool _isReceiver = false; bool _isReceiver = false;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider;
DeviceTransferProvider _deviceTransferProvider;
bool _isLoading = false; bool _isLoading = false;
Subtitle _subtitle; Subtitle _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -41,21 +38,30 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
@override @override
void initState() { void initState() {
_model = widget.model;
super.initState(); super.initState();
} }
Future<void> _getDeviceTransfer() async {
_model = await Provider.of<DeviceTransferProvider>(context).getRequestById(assetTransferId: widget.model.id);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context);
_isSender = _userProvider.user.userID == widget.model.sender?.userId;
_isReceiver = _userProvider.user.userID == widget.model.receiver?.userId;
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: SafeArea(
child: Form( child: FutureBuilder(
future: _getDeviceTransfer(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const ALoading();
} else {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_isSender = _userProvider.user.userID == _model.sender?.userId;
_isReceiver = _userProvider.user.userID == _model.receiver?.userId;
return Form(
key: _formKey, key: _formKey,
child: LoadingManager( child: LoadingManager(
isLoading: _isLoading, isLoading: _isLoading,
@ -90,39 +96,39 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: "Transfer Id", title: "Transfer Id",
info: widget.model.title?.toString(), info: _model.title?.toString(),
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.assetName, title: _subtitle.assetName,
info: widget.model.device.assetName, info: _model.device.assetName,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.assetSN, title: _subtitle.assetSN,
info: widget.model.device.serialNumber, info: _model.device.serialNumber,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.assetNumber, title: _subtitle.assetNumber,
info: widget.model.device.number, info: _model.device.number,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.destinationSite, title: _subtitle.destinationSite,
info: widget.model.device.destSiteName, info: _model.device.destSiteName,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.building, title: _subtitle.building,
info: widget.model.device.destBuildingName, info: _model.device.destBuildingName,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.floor, title: _subtitle.floor,
info: widget.model.device.destFloor, info: _model.device.destFloor,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.department, title: _subtitle.department,
info: widget.model.device.destDepartmentName, info: _model.device.destDepartmentName,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.room, title: _subtitle.room,
info: widget.model.device.destRoom, info: _model.device.destRoom,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.actions, title: _subtitle.actions,
@ -137,21 +143,24 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
if (_userProvider.user?.type == UsersTypes.engineer) if (_userProvider.user?.type == UsersTypes.engineer)
ASmallButton( ASmallButton(
text: _subtitle.edit, text: _subtitle.edit,
onPressed: (_isSender || false) onPressed: (_isSender)
? () { ? (_model.sender.status?.name == "Closed"
? null
: () {
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer( builder: (_) => UpdateDeviceTransfer(
model: widget.model, model: _model,
isSender: true, isSender: true,
))); )));
} })
: null, : null,
), ),
], ],
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
DeviceTransferInfoSection( DeviceTransferInfoSection(
info: widget.model.sender, info: _model.sender,
isSender: true,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
@ -162,21 +171,24 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
if (_userProvider.user?.type == UsersTypes.engineer) if (_userProvider.user?.type == UsersTypes.engineer)
ASmallButton( ASmallButton(
text: _subtitle.edit, text: _subtitle.edit,
onPressed: (_isReceiver || false) onPressed: (_isReceiver)
? () { ? (_model.receiver.status?.name == "Closed"
? null
: () {
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer( builder: (_) => UpdateDeviceTransfer(
model: widget.model, model: _model,
isSender: false, isSender: false,
))); )));
} })
: null, : null,
), ),
], ],
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
DeviceTransferInfoSection( DeviceTransferInfoSection(
info: widget.model.receiver, info: _model.receiver,
isSender: false,
), ),
], ],
), ),
@ -185,6 +197,9 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
], ],
), ),
), ),
);
}
},
), ),
), ),
); );

@ -1,7 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
@ -12,14 +10,13 @@ import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/departments/department_button.dart';
import 'package:test_sa/views/widgets/equipment/device_button.dart'; import 'package:test_sa/views/widgets/equipment/device_button.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../controllers/validator/validator.dart'; import '../../../controllers/validator/validator.dart';
import '../../app_style/colors.dart';
import '../../widgets/app_text_form_field.dart'; import '../../widgets/app_text_form_field.dart';
import '../../widgets/gas_refill/building_type_menu.dart'; import '../../widgets/gas_refill/building_type_menu.dart';
import '../../widgets/gas_refill/department_type_menu.dart'; import '../../widgets/gas_refill/department_type_menu.dart';
@ -28,6 +25,7 @@ import '../../widgets/hospitals/hospital_auto_complete_field_new.dart';
class RequestDeviceTransfer extends StatefulWidget { class RequestDeviceTransfer extends StatefulWidget {
static const String id = "/request-device-transfer"; static const String id = "/request-device-transfer";
const RequestDeviceTransfer({Key key}) : super(key: key); const RequestDeviceTransfer({Key key}) : super(key: key);
@override @override
@ -66,7 +64,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_formModel.sender?.client?.id = _userProvider.user?.clientId; // _formModel.sender?.client?.id = _userProvider.user?.clientId;
int status = await _deviceTransferProvider.createRequest( int status = await _deviceTransferProvider.createRequest(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
@ -120,7 +118,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Transfer Device", "Transfer Asset",
style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold),
), ),
), ),
@ -140,7 +138,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
// }, // },
// ), // ),
12.height, 12.height,
const ASubTitle("Device"), const ASubTitle("Asset"),
if (_validate && _formModel.device == null) if (_validate && _formModel.device == null)
ASubTitle( ASubTitle(
_subtitle.requiredWord, _subtitle.requiredWord,
@ -151,9 +149,19 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
device: _formModel.device, device: _formModel.device,
onDevicePick: (device) { onDevicePick: (device) {
_formModel.device = device; _formModel.device = device;
_formModel.sender.client = device.hospital;
setState(() {}); setState(() {});
}, },
), ),
if (_formModel.device != null) 8.height,
if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Site", value: _formModel.device.hospital?.name),
if (_formModel.device != null) 4.height,
if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Department", value: _formModel.device.destDepartmentName),
if (_formModel.device != null) 4.height,
if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Floor", value: _formModel.device.destFloor),
if (_formModel.device != null) 4.height,
if (_formModel.device != null) AdditionalAssetInfo(title: "Asset Room", value: _formModel.device.destRoom),
if (_formModel.device != null) 8.height,
// const SizedBox(height: 8,), // const SizedBox(height: 8,),
// const ASubTitle("Sender Department"), // const ASubTitle("Sender Department"),
// if(_validate && _formModel.senderDepartment == null) // if(_validate && _formModel.senderDepartment == null)
@ -202,6 +210,8 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
Divider( Divider(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
const SizedBox(height: 8),
const ASubTitle("Destination"),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -250,8 +260,8 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
}, },
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
ASubTitle("Room"), const ASubTitle("Room"),
SizedBox( const SizedBox(
height: 4, height: 4,
), ),
ATextFormField( ATextFormField(
@ -281,3 +291,31 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
); );
} }
} }
class AdditionalAssetInfo extends StatelessWidget {
final String title, value;
const AdditionalAssetInfo({@required this.title, @required this.value, Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(title ?? ""),
Container(
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
decoration: BoxDecoration(
color: AColors.inputFieldBackgroundColor,
border: Border.all(
color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: ASubTitle(value ?? ""),
),
],
);
}
}

@ -1,14 +1,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/device/device_transfer_search.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_list.dart'; import 'package:test_sa/views/widgets/device_trancfer/device_transfer_list.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/search/asset_transfer_search_dialog.dart';
import '../../widgets/buttons/app_icon_button.dart';
class TrackDeviceTransferPage extends StatefulWidget { class TrackDeviceTransferPage extends StatefulWidget {
static const String id = "/track-device-transfer"; static const String id = "/track-device-transfer";
@ -23,12 +25,12 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage> with
DeviceTransferProvider _deviceTransferProvider; DeviceTransferProvider _deviceTransferProvider;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context); _deviceTransferProvider = Provider.of<DeviceTransferProvider>(context);
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
@ -54,18 +56,40 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage> with
children: [ children: [
Row( Row(
children: [ children: [
ABackButton(), const ABackButton(),
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
"Device Transfer", "Asset Transfer",
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
), ),
), ),
), ),
const SizedBox( AIconButton(
width: 48, iconData: Icons.search,
) color: AColors.secondaryColor,
buttonSize: 42,
backgroundColor: AColors.white,
onPressed: () async {
DeviceTransferSearch temp = await showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return AssetTransferSearchDialog(initialSearchValue: _deviceTransferProvider.deviceTransferSearch);
},
);
if (temp != null) {
_deviceTransferProvider.deviceTransferSearch = temp;
_deviceTransferProvider.reset();
setState(() {});
await _deviceTransferProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
);
}
},
),
const SizedBox(width: 16),
], ],
), ),
], ],

@ -14,8 +14,9 @@ import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart'; import 'package:test_sa/views/widgets/status/asset_status.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
@ -40,7 +41,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
Uint8List _signature; Uint8List _signature;
DeviceTransferProvider _deviceTransferProvider; DeviceTransferProvider _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController(); final TextEditingController _requestedQuantityController = TextEditingController();
final DeviceTransferInfo _formModel = DeviceTransferInfo(); final DeviceTransferInfo _formModel = DeviceTransferInfo(attachments: []);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@ -72,7 +73,6 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
); );
_validate = false; _validate = false;
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pop();
} }
} }
@ -118,7 +118,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Edit Transfer Device", "Edit Transfer Asset",
style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold),
), ),
), ),
@ -180,7 +180,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
GasStatusMenu( AssetStatusMenu(
initialValue: _formModel.status, initialValue: _formModel.status,
onSelect: (status) { onSelect: (status) {
if (status == null) return; if (status == null) return;
@ -189,7 +189,14 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
}, },
), ),
const SizedBox( const SizedBox(
height: 8, height: 16,
),
MultiFilesPicker(
label: "Attachments",
files: _formModel.attachments,
),
const SizedBox(
height: 16,
), ),
const ASubTitle("Signature"), const ASubTitle("Signature"),
// if(_validate && _formModel.signature == null) // if(_validate && _formModel.signature == null)
@ -198,12 +205,12 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
height: 4, height: 4,
), ),
ESignature( ESignature(
oldSignature: widget.isSender ? widget.model.sender.signature : widget.model.receiver.signature, oldSignature: widget.isSender ? widget.model.sender.engSignature : widget.model.receiver.engSignature,
newSignature: _signature, newSignature: _signature,
onSaved: (signature) { onSaved: (signature) {
_signature = signature; _signature = signature;
if (signature == null || signature.isEmpty) return; if (signature == null || signature.isEmpty) return;
_formModel.signature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; _formModel.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
// base64Encode(signature); // base64Encode(signature);
}, },
), ),

@ -6,14 +6,12 @@ import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart'; import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/departments/department_button.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_button.dart'; import 'package:test_sa/views/widgets/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
@ -131,15 +129,15 @@ class _RegisterState extends State<Register> {
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(height: 12), // const SizedBox(height: 12),
DepartmentButton( // DepartmentButton(
department: Department(id: _user.departmentId, name: _user.departmentName), // department: Department(id: _user.departmentId, name: _user.departmentName),
onDepartmentPick: (department) { // onDepartmentPick: (department) {
_user.departmentId = department.id; // _user.departmentId = department.id;
_user.departmentName = department.name; // _user.departmentName = department.name;
setState(() {}); // setState(() {});
}, // },
), // ),
const SizedBox(height: 12), const SizedBox(height: 12),
ATextFormField( ATextFormField(
initialValue: _user.phoneNumber, initialValue: _user.phoneNumber,

@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/models/service_request/search_work_order.dart';
import '../../../controllers/providers/api/status_drop_down/report/vendor_provider.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class AutoGeneratedVendorName extends StatefulWidget {
final String initialValue;
final Function(Supplier) onSearch;
const AutoGeneratedVendorName({Key key, this.initialValue, this.onSearch}) : super(key: key);
@override
State<AutoGeneratedVendorName> createState() => _AutoGeneratedVendorNameState();
}
class _AutoGeneratedVendorNameState extends State<AutoGeneratedVendorName> {
TextEditingController _controller;
@override
void initState() {
super.initState();
_controller = TextEditingController(text: widget.initialValue ?? "");
}
@override
void didUpdateWidget(covariant AutoGeneratedVendorName oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.initialValue != widget.initialValue) {
_controller = TextEditingController(text: widget.initialValue ?? "");
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final vendorProvider = Provider.of<VendorProvider>(context, listen: false);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: AColors.inputFieldBackgroundColor,
border: Border.all(
color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
// boxShadow: [
// AppStyle.boxShadow
// ]
),
child: TypeAheadField<Supplier>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.titleLarge,
controller: _controller,
textAlign: TextAlign.center,
decoration: const InputDecoration(
hintText: "Vendor Name",
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
),
suggestionsCallback: (vale) async {
await vendorProvider.getVendors(_controller.text.trim());
return vendorProvider.vendors;
},
itemBuilder: (context, vendor) {
return ListTile(title: Text(vendor.suppliername));
},
onSuggestionSelected: (hospital) {
widget.onSearch(hospital);
},
),
);
}
}

@ -16,6 +16,7 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart'; import 'package:test_sa/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart';
import 'package:test_sa/views/pages/sub_workorder/work_order_details_bottom_sheet.dart'; import 'package:test_sa/views/pages/sub_workorder/work_order_details_bottom_sheet.dart';
import 'package:test_sa/views/pages/sub_workorder/workorder_details.dart'; import 'package:test_sa/views/pages/sub_workorder/workorder_details.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
@ -27,7 +28,6 @@ import '../../widgets/app_text_form_field.dart';
import '../../widgets/buttons/app_back_button.dart'; import '../../widgets/buttons/app_back_button.dart';
import '../../widgets/buttons/app_button.dart'; import '../../widgets/buttons/app_button.dart';
import '../../widgets/date_and_time/date_picker.dart'; import '../../widgets/date_and_time/date_picker.dart';
import '../../widgets/images/mini_one_image_picker.dart';
import '../../widgets/status/report/service_report_fault_description.dart'; import '../../widgets/status/report/service_report_fault_description.dart';
import '../../widgets/status/report/service_report_reasons.dart'; import '../../widgets/status/report/service_report_reasons.dart';
import '../../widgets/titles/app_sub_title.dart'; import '../../widgets/titles/app_sub_title.dart';
@ -47,7 +47,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
SearchWorkOrder _subWorkOrders; SearchWorkOrder _subWorkOrders;
Lookup _serviceReportReason = const Lookup(); Lookup _serviceReportReason = const Lookup();
ServiceReport _serviceReport; ServiceReport _serviceReport;
File _image; final List<File> _files = [];
bool _isLoading = false; bool _isLoading = false;
bool _validate = false; bool _validate = false;
@ -58,6 +58,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
callRequest: CallRequest(id: widget?.workOrder?.callRequest?.id), callRequest: CallRequest(id: widget?.workOrder?.callRequest?.id),
currentSituation: null, currentSituation: null,
supplier: null, supplier: null,
parentWOId: widget.workOrder.id,
); );
_serviceReport = ServiceReport(id: widget.workOrder.id, type: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus); _serviceReport = ServiceReport(id: widget.workOrder.id, type: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus);
_isLoading = true; _isLoading = true;
@ -69,9 +70,19 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
Future getAssetType() async { Future getAssetType() async {
//if (assetTypesProvider == null) { //if (assetTypesProvider == null) {
final serviceRequestProvider = Provider.of<ServiceRequestsProvider>(context);
Provider.of<ServiceRequestFaultDescriptionProvider>(context, listen: false).reset(); Provider.of<ServiceRequestFaultDescriptionProvider>(context, listen: false).reset();
assetTypesProvider = Provider.of<ServiceStatusProvider>(context, listen: false); assetTypesProvider = Provider.of<ServiceStatusProvider>(context, listen: false);
_callRequestForWorkOrder = await Provider.of<ServiceRequestsProvider>(context).getCallRequestForWorkOrder(callId: widget.workOrder.callRequest.id.toString()); _callRequestForWorkOrder = await serviceRequestProvider.getCallRequestForWorkOrder(callId: widget.workOrder.callRequest.id.toString());
if (_subWorkOrders?.parentWOId != null) {
print(_subWorkOrders?.parentWOId.toString());
final subWoDetails = await serviceRequestProvider.getSubWorkOrderDetails(parentId: _subWorkOrders?.parentWOId.toString());
_subWorkOrders.copyDetails(subWoDetails);
_serviceReport.equipmentStatus = subWoDetails.equipmentStatus;
_serviceReport.reason = subWoDetails.reason;
_serviceReport.faultDescription = subWoDetails.faultDescription;
_serviceReportReason = _subWorkOrders.reason;
}
await assetTypesProvider.getTypes(); await assetTypesProvider.getTypes();
_subWorkOrders?.assetType = assetTypesProvider.statuses?.firstWhere( _subWorkOrders?.assetType = assetTypesProvider.statuses?.firstWhere(
(element) => element.value == _callRequestForWorkOrder?.assetType, (element) => element.value == _callRequestForWorkOrder?.assetType,
@ -112,7 +123,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
"New Work Order", "New Sub Work Order",
style: Theme.of(context).textTheme.titleLarge.copyWith(color: AColors.white, fontStyle: FontStyle.italic), style: Theme.of(context).textTheme.titleLarge.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
), ),
), ),
@ -158,11 +169,11 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const ASubTitle("Return to Service"), const ASubTitle("Return to Service"),
if (_validate && _subWorkOrders.visitDate == null) // if (_validate && _subWorkOrders.visitDate == null)
ASubTitle( // ASubTitle(
subtitle.requiredWord, // subtitle.requiredWord,
color: Colors.red, // color: Colors.red,
), // ),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -200,7 +211,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
onSelect: (status) { onSelect: (status) {
_serviceReportReason = status; _serviceReportReason = status;
_subWorkOrders.reason = status; _subWorkOrders.reason = status;
setState(() {}); // setState(() {});
}, },
), ),
], ],
@ -238,6 +249,8 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
MultiFilesPicker(label: "Attachments", files: _files),
const SizedBox(height: 8),
InkWell( InkWell(
onTap: () async { onTap: () async {
await showModalBottomSheet( await showModalBottomSheet(
@ -247,7 +260,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
builder: (context) => WorkOrderDetailsBottomSheet(subWorkOrder: _subWorkOrders), builder: (context) => WorkOrderDetailsBottomSheet(subWorkOrder: _subWorkOrders),
); );
log(_subWorkOrders?.toJson()?.toString()); //log(_subWorkOrders?.toJson()?.toString());
}, },
child: Card( child: Card(
child: ListTile( child: ListTile(
@ -272,7 +285,10 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
useSafeArea: true, useSafeArea: true,
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
builder: (context) => SparePartsBottomSheet(subWorkOrder: _subWorkOrders), builder: (context) => SparePartsBottomSheet(
subWorkOrder: _subWorkOrders,
assetId: widget.workOrder?.callRequest?.asset?.id,
),
); );
log(_subWorkOrders?.toJson()?.toString()); log(_subWorkOrders?.toJson()?.toString());
}, },
@ -291,15 +307,14 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
), ),
), ),
), ),
const SizedBox(height: 8), // AMiniOneFilePicker(
AMiniOneImagePicker( // file: _file,
image: _image, // onPick: (file) {
onPick: (image) { // _file = file;
_image = image; // _subWorkOrders.attachmentsWorkOrder ??= [];
_subWorkOrders.attachmentsWorkOrder ??= []; // _subWorkOrders.attachmentsWorkOrder.add(AttachmentsWorkOrder(name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"));
_subWorkOrders.attachmentsWorkOrder.add(AttachmentsWorkOrder(name: "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}")); // },
}, // ),
),
const SizedBox(height: 50), const SizedBox(height: 50),
], ],
), ),
@ -313,10 +328,17 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
child: AButton( child: AButton(
text: subtitle.create, text: subtitle.create,
onPressed: () async { onPressed: () async {
_subWorkOrders.parentWOId = widget.workOrder.id;
_validate = true; _validate = true;
setState(() {}); setState(() {});
if (validate()) { if (validate()) {
if (_subWorkOrders.calllastSituation.value == 12 && (_subWorkOrders.sparePartsWorkOrders == null || _subWorkOrders.sparePartsWorkOrders.isEmpty)) {
await Fluttertoast.showToast(msg: "You have to add parts");
return;
}
_subWorkOrders.attachmentsWorkOrder ??= [];
for (var file in _files) {
_subWorkOrders.attachmentsWorkOrder.add(AttachmentsWorkOrder(name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"));
}
if (_subWorkOrders.timer?.startAt == null || _subWorkOrders.timer?.endAt == null) { if (_subWorkOrders.timer?.startAt == null || _subWorkOrders.timer?.endAt == null) {
Fluttertoast.showToast(msg: "Working hours required"); Fluttertoast.showToast(msg: "Working hours required");
return; return;
@ -330,6 +352,11 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
if (_formKey.currentState?.validate() ?? false) {} if (_formKey.currentState?.validate() ?? false) {}
_formKey.currentState?.save(); _formKey.currentState?.save();
final serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false); final serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);
for (var element in (_subWorkOrders?.suppEngineerWorkOrders ?? [])) {
if (element != null) {
element.id = 0;
}
}
final status = await serviceRequestsProvider.createSubWorkOrder(workOrder: _subWorkOrders); final status = await serviceRequestsProvider.createSubWorkOrder(workOrder: _subWorkOrders);
_isLoading = false; _isLoading = false;
setState(() {}); setState(() {});
@ -354,7 +381,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
} }
bool validate() { bool validate() {
if (_subWorkOrders.faultDescription == null || _subWorkOrders.reason == null || _subWorkOrders.equipmentStatus == null || _subWorkOrders.visitDate == null) { if (_subWorkOrders.faultDescription == null || _subWorkOrders.reason == null || _subWorkOrders.equipmentStatus == null) {
return false; return false;
} else { } else {
return true; return true;

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/models/engineer.dart'; import 'package:test_sa/models/engineer.dart';
@ -24,6 +23,7 @@ import '../../widgets/titles/app_sub_title.dart';
class SearchSubWorkOrderPage extends StatefulWidget { class SearchSubWorkOrderPage extends StatefulWidget {
static String id = "/SubWorkOrderPage"; static String id = "/SubWorkOrderPage";
const SearchSubWorkOrderPage({Key key}) : super(key: key); const SearchSubWorkOrderPage({Key key}) : super(key: key);
@override @override

@ -6,6 +6,7 @@ import 'package:test_sa/views/app_style/colors.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart'; import '../../../models/subtitle.dart';
import '../../app_style/sizing.dart'; import '../../app_style/sizing.dart';
import '../../widgets/app_text_form_field.dart';
import '../../widgets/buttons/app_button.dart'; import '../../widgets/buttons/app_button.dart';
import '../../widgets/parts/auto_complete_parts_field.dart'; import '../../widgets/parts/auto_complete_parts_field.dart';
import '../../widgets/parts/part_item.dart'; import '../../widgets/parts/part_item.dart';
@ -13,7 +14,9 @@ import '../../widgets/titles/app_sub_title.dart';
class SparePartsBottomSheet extends StatefulWidget { class SparePartsBottomSheet extends StatefulWidget {
final SearchWorkOrder subWorkOrder; final SearchWorkOrder subWorkOrder;
const SparePartsBottomSheet({this.subWorkOrder, Key key}) : super(key: key); final num assetId;
const SparePartsBottomSheet({this.subWorkOrder, this.assetId, Key key}) : super(key: key);
@override @override
State<SparePartsBottomSheet> createState() => _SparePartsBottomSheetState(); State<SparePartsBottomSheet> createState() => _SparePartsBottomSheetState();
@ -86,7 +89,7 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(subtitle.partNumber), ASubTitle(subtitle.partNumberName),
_validate && _workOrder.sparePartsWorkOrders == null _validate && _workOrder.sparePartsWorkOrders == null
? ASubTitle( ? ASubTitle(
subtitle.requiredWord, subtitle.requiredWord,
@ -95,12 +98,15 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
: const SizedBox.shrink(), : const SizedBox.shrink(),
const SizedBox(height: 4), const SizedBox(height: 4),
AutoCompletePartsField( AutoCompletePartsField(
assetId: widget.assetId,
onPick: (part) { onPick: (part) {
_workOrder.sparePartsWorkOrders ??= []; _workOrder.sparePartsWorkOrders ??= [];
_workOrder.sparePartsWorkOrders.add(SparePartsWorkOrders( _workOrder.sparePartsWorkOrders.add(SparePartsWorkOrders(
id: part.reportPartID, id: part.reportPartID,
qty: part.quantity, qty: part.quantity,
sparePart: SparePart(id: part.id, partName: part.name, partNo: part.code), sparePart: SparePart(id: part.id, partName: part.partName, partNo: part.partNo),
installQty: part.installQty,
returnQty: part.returnQty,
)); ));
}, },
), ),
@ -128,11 +134,15 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
Part part = Part( Part part = Part(
id: spare.sparePart?.id, id: spare.sparePart?.id,
reportPartID: spare.id, reportPartID: spare.id,
code: spare.sparePart?.partNo, partNo: spare.sparePart?.partNo,
name: spare.sparePart?.partName, partName: spare.sparePart?.partName,
quantity: spare.qty, quantity: spare.qty?.toInt(),
installQty: spare.installQty,
returnQty: spare.returnQty,
); );
return PartItem( return Column(
children: [
PartItem(
part: part, part: part,
onEdit: (qty) { onEdit: (qty) {
spare.qty = qty; spare.qty = qty;
@ -141,6 +151,38 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
_workOrder.sparePartsWorkOrders.remove(spare); _workOrder.sparePartsWorkOrders.remove(spare);
setState(() {}); setState(() {});
}, },
),
if (_workOrder.calllastSituation?.name?.toLowerCase()?.contains("part installation") ?? false)
Row(
children: [
Expanded(
child: ATextFormField(
initialValue: part?.returnQty?.toString(),
labelText: "Return Quantity",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.number,
onSaved: (value) {
spare.returnQty = num.tryParse(value)?.toDouble();
},
),
),
const SizedBox(width: 8),
Expanded(
child: ATextFormField(
initialValue: part?.installQty?.toString(),
labelText: "Install Quantity",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.number,
onSaved: (value) {
spare.installQty = num.tryParse(value)?.toDouble();
},
),
),
],
),
],
); );
}, },
), ),

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_request/search_work_order.dart'; import 'package:test_sa/models/service_request/search_work_order.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
@ -8,11 +9,13 @@ import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart'; import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart';
import 'package:test_sa/views/widgets/status/report/service_report_maintenance_situation.dart'; import 'package:test_sa/views/widgets/status/report/service_report_maintenance_situation.dart';
import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart'; import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart';
import 'package:test_sa/views/widgets/status/service_request/supplier_engineers_menu.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart'; import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart';
import '../../widgets/timer/app_timer.dart'; import '../../widgets/timer/app_timer.dart';
import '../../widgets/titles/app_sub_title.dart'; import '../../widgets/titles/app_sub_title.dart';
import 'auto_generated_vendor_name.dart';
class WorkOrderDetailsBottomSheet extends StatefulWidget { class WorkOrderDetailsBottomSheet extends StatefulWidget {
final SearchWorkOrder subWorkOrder; final SearchWorkOrder subWorkOrder;
@ -25,17 +28,33 @@ class WorkOrderDetailsBottomSheet extends StatefulWidget {
class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomSheet> { class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomSheet> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final SearchWorkOrder _workOrder = SearchWorkOrder(); final SearchWorkOrder _workOrder = SearchWorkOrder();
bool _showVendorFields = false;
SuppEngineerWorkOrders engineer;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_workOrder.copyFrom(widget.subWorkOrder); _workOrder.copyFrom(widget.subWorkOrder);
if (checkVendorFieldsVisibility(_workOrder.calllastSituation)) {
if (_workOrder.suppEngineerWorkOrders?.isNotEmpty ?? false) {
engineer = _workOrder.suppEngineerWorkOrders?.last;
engineer?.id = engineer?.supplierContactId;
}
_workOrder.supplier ??= SupplierModel(id: _workOrder?.supplier?.id);
}
if (context.mounted) { if (context.mounted) {
Provider.of<ServiceReportMaintenanceSituationProvider>(context, listen: false).reset(); Provider.of<ServiceReportMaintenanceSituationProvider>(context, listen: false).reset();
} }
} }
bool checkVendorFieldsVisibility(Lookup callsLastSituation) {
bool result = (_workOrder.supplier?.suppliername?.isNotEmpty ?? false) ||
(callsLastSituation?.name?.toLowerCase()?.contains("under repair-vendor") ?? false) ||
(callsLastSituation?.name?.toLowerCase()?.contains("waiting for vendor") ?? false);
_showVendorFields = result;
return result;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = MediaQuery.of(context).size; final size = MediaQuery.of(context).size;
@ -118,14 +137,52 @@ class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomShee
ServiceReportMaintenanceSituation( ServiceReportMaintenanceSituation(
initialValue: _workOrder.calllastSituation, initialValue: _workOrder.calllastSituation,
onSelect: (status) { onSelect: (status) {
if (checkVendorFieldsVisibility(status)) {
_workOrder.supplier ??= SupplierModel(id: _workOrder?.supplier?.id);
engineer = null;
}
if (status?.value == 12 || _workOrder.calllastSituation?.value == 12) { if (status?.value == 12 || _workOrder.calllastSituation?.value == 12) {
_workOrder.calllastSituation = status; _workOrder.calllastSituation = status;
_workOrder.mrNumber = null;
setState(() {}); setState(() {});
} else { } else {
_workOrder.calllastSituation = status; _workOrder.calllastSituation = status;
} }
setState(() {});
},
woId: widget.subWorkOrder?.parentWOId?.toString(),
),
if (_workOrder.calllastSituation.value == 12) const ASubTitle(" You have to add parts", color: Colors.amber, padding: EdgeInsets.all(2), font: 11),
if (_workOrder.calllastSituation.value == 12) const SizedBox(height: 8),
if (_workOrder.calllastSituation.value == 12)
ATextFormField(
labelText: "MR number",
initialValue: _workOrder.mrNumber,
onSaved: (value) {
_workOrder.mrNumber = value;
},
),
if (_showVendorFields) const SizedBox(height: 8),
if (_showVendorFields)
AutoGeneratedVendorName(
initialValue: _workOrder.supplier?.suppliername,
onSearch: (supplier) {
_workOrder.supplier.id = supplier.id;
_workOrder.supplier.suppliername = supplier.suppliername;
_workOrder.supplier.suppPersons = supplier.suppPersons;
setState(() {});
},
),
if (_showVendorFields) const SizedBox(height: 8),
if (_showVendorFields)
SupplierEngineersMenu(
initialValue: engineer,
engineers: _workOrder?.supplier?.suppPersons,
onSelect: (engineer) {
if (engineer != null) {
this.engineer = engineer;
}
}, },
woId: widget.subWorkOrder?.callRequest?.id?.toString(),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
const ASubTitle("Repair Location"), const ASubTitle("Repair Location"),
@ -158,6 +215,20 @@ class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomShee
await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started"); await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started");
return; return;
} }
if (_showVendorFields && (_workOrder.supplier.suppliername == null || _workOrder.supplier.suppliername.isEmpty)) {
await Fluttertoast.showToast(msg: "Vendor Name Field is Required");
return;
}
if (_showVendorFields && _workOrder.suppEngineerWorkOrders == null) {
await Fluttertoast.showToast(msg: "Vendor Engineer Field is Required");
return;
}
_workOrder.suppEngineerWorkOrders ?? [];
if (engineer != null) _workOrder.suppEngineerWorkOrders.add(engineer..id = 0);
if (_workOrder.calllastSituation == null) {
await Fluttertoast.showToast(msg: "Call Last Situation Field is Required");
return;
}
_formKey.currentState.save(); _formKey.currentState.save();
widget.subWorkOrder.copyFrom(_workOrder); widget.subWorkOrder.copyFrom(_workOrder);
Navigator.pop(context); Navigator.pop(context);

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
@ -11,6 +13,7 @@ class WorkOrderItem extends StatelessWidget {
final int index; final int index;
final SearchWorkOrder item; final SearchWorkOrder item;
final Function(SearchWorkOrder) onPressed; final Function(SearchWorkOrder) onPressed;
const WorkOrderItem({Key key, this.item, this.onPressed, this.index}) : super(key: key); const WorkOrderItem({Key key, this.item, this.onPressed, this.index}) : super(key: key);
@override @override
@ -30,7 +33,13 @@ class WorkOrderItem extends StatelessWidget {
), ),
), ),
onPressed: () { onPressed: () {
onPressed(item); item.callRequest.status.value == 5 || item.callRequest.status.value == 3
? Fluttertoast.showToast(
msg: "Request is ${item.callRequest.status.name}. No more sub work orders will be create.",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
)
: onPressed(item);
}, },
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -45,17 +54,39 @@ class WorkOrderItem extends StatelessWidget {
item.callRequest.callNo ?? "-----", item.callRequest.callNo ?? "-----",
style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold),
), ),
// Text(
// item.callRequest.asset.id.toString(),
// style: Theme.of(context).textTheme.subtitle2.copyWith(
// color: onItemColor,
// ),
// ),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text( Text(
item.callRequest.asset.id.toString(), "Asset Name:",
style: Theme.of(context).textTheme.subtitle2.copyWith( style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor, color: onItemColor,
), ),
), ),
8.width,
Expanded(
child: Text(
//CallRequest.Asset.ModelDefinition.AssetND
// .AssetName
item.callRequest.asset.modelDefinition.assetName,
style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor,
),
),
),
],
),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
_subtitle.assetName, "Asset Number:",
style: Theme.of(context).textTheme.subtitle2.copyWith( style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor, color: onItemColor,
), ),
@ -70,8 +101,27 @@ class WorkOrderItem extends StatelessWidget {
), ),
], ],
), ),
Row(
children: [
Expanded(
child: Text(
"Asset SN:",
style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor,
),
),
),
//if (item.clientName != null)
Text(
item.callRequest.asset.assetSerialNo,
style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor,
),
),
],
),
Text( Text(
item.calllastSituation.name, item.currentSituation.name,
style: Theme.of(context).textTheme.subtitle2.copyWith( style: Theme.of(context).textTheme.subtitle2.copyWith(
color: onItemColor, color: onItemColor,
), ),

@ -17,6 +17,7 @@ import 'create_sub_workorder_page.dart';
class WorkOrderList extends StatefulWidget { class WorkOrderList extends StatefulWidget {
List<SearchWorkOrder> items; List<SearchWorkOrder> items;
final Future<List<SearchWorkOrder>> Function() onLazyLoading; final Future<List<SearchWorkOrder>> Function() onLazyLoading;
WorkOrderList({Key key, this.items, this.onLazyLoading}) : super(key: key); WorkOrderList({Key key, this.items, this.onLazyLoading}) : super(key: key);
@override @override
@ -25,6 +26,7 @@ class WorkOrderList extends StatefulWidget {
class _WorkOrderListState extends State<WorkOrderList> { class _WorkOrderListState extends State<WorkOrderList> {
List<SearchWorkOrder> _items; List<SearchWorkOrder> _items;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -81,7 +83,6 @@ class _WorkOrderListState extends State<WorkOrderList> {
onPressed: (model) { onPressed: (model) {
// Navigator.of(context).push(MaterialPageRoute( // Navigator.of(context).push(MaterialPageRoute(
// builder: (_) => WorkOrderUpdate(item: model,))); // builder: (_) => WorkOrderUpdate(item: model,)));
log(model?.toJson()?.toString());
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) => CreateSubWorkOrderPage(workOrder: model)), MaterialPageRoute(builder: (context) => CreateSubWorkOrderPage(workOrder: model)),

@ -25,15 +25,16 @@ import '../../../../models/enums/user_types.dart';
import '../../../app_style/colors.dart'; import '../../../app_style/colors.dart';
class GasRefillDetails extends StatefulWidget { class GasRefillDetails extends StatefulWidget {
final GasRefillModel model; GasRefillModel model;
const GasRefillDetails({Key key, this.model}) : super(key: key);
GasRefillDetails({Key key, this.model}) : super(key: key);
@override @override
State<GasRefillDetails> createState() => _GasRefillDetailsState(); State<GasRefillDetails> createState() => _GasRefillDetailsState();
} }
class _GasRefillDetailsState extends State<GasRefillDetails> { class _GasRefillDetailsState extends State<GasRefillDetails> {
final GasRefillModel _model = GasRefillModel(); GasRefillModel _model = GasRefillModel();
bool _enableEdit = false; bool _enableEdit = false;
bool _validate = false; bool _validate = false;
UserProvider _userProvider; UserProvider _userProvider;
@ -43,6 +44,7 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
Subtitle _subtitle; Subtitle _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
_update() async { _update() async {
_validate = true; _validate = true;
if (!_formKey.currentState.validate()) { if (!_formKey.currentState.validate()) {
@ -73,7 +75,7 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
@override @override
void initState() { void initState() {
_model.fromGasRefillModel(widget.model); _model?.fromGasRefillModel(widget.model);
super.initState(); super.initState();
} }
@ -100,11 +102,15 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Row( child: Row(
children: [ children: [
const ABackButton(), ABackButton(
onPressed: () {
Navigator.of(context).pop(_model);
},
),
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
_subtitle.details, "Gas Refill Request",
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
), ),
), ),
@ -115,11 +121,11 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
color: Theme.of(context).colorScheme.onPrimary, color: Theme.of(context).colorScheme.onPrimary,
buttonSize: 42, buttonSize: 42,
backgroundColor: AColors.green, backgroundColor: AColors.green,
onPressed: () async { onPressed: (widget.model.status?.value ?? 0) == 2
? null
: () async {
// _enableEdit = !_enableEdit; // _enableEdit = !_enableEdit;
print(widget.model.startDate); _model?.fromGasRefillModel(widget.model);
_model.fromGasRefillModel(widget.model);
print(widget.model.startDate);
// setState(() {}); // setState(() {});
Navigator.push( Navigator.push(
context, context,
@ -128,7 +134,12 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
gasRefillModel: widget.model, gasRefillModel: widget.model,
), ),
), ),
); ).then((value) {
if (value != null) {
_model = value;
}
});
setState(() {});
}, },
), ),
const SizedBox( const SizedBox(
@ -144,7 +155,7 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: _subtitle.title, title: "Gas Refill No",
info: _model.title, info: _model.title,
), ),
RequestInfoRow( RequestInfoRow(
@ -159,13 +170,17 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
title: "Floor", title: "Floor",
info: _model.floor?.name, info: _model.floor?.name,
), ),
RequestInfoRow(
title: "Department",
info: _model.department?.departmentName,
),
RequestInfoRow( RequestInfoRow(
title: _subtitle.startDate, title: _subtitle.startDate,
info: _model.startDate == null ? null : DateFormat.yMd().format(_model.startDate), info: _model.startDate == null ? null : "${DateFormat.yMd().format(_model.startDate)} ${DateFormat.Hms().format(_model.startDate)}",
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.endDate, title: _subtitle.endDate,
info: _model.endDate == null ? null : DateFormat.yMd().format(_model.endDate), info: _model.endDate == null ? null : "${DateFormat.yMd().format(_model.endDate)} ${DateFormat.Hms().format(_model.endDate)}",
), ),
_enableEdit _enableEdit
? Column( ? Column(

@ -12,10 +12,10 @@ import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart'; import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/time_picker.dart';
import 'package:test_sa/views/widgets/gas_refill/building_type_menu.dart'; import 'package:test_sa/views/widgets/gas_refill/building_type_menu.dart';
import 'package:test_sa/views/widgets/gas_refill/department_type_menu.dart'; import 'package:test_sa/views/widgets/gas_refill/department_type_menu.dart';
import 'package:test_sa/views/widgets/gas_refill/floor_type_menu.dart'; import 'package:test_sa/views/widgets/gas_refill/floor_type_menu.dart';
@ -30,12 +30,13 @@ import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/hospitals_provider.dart'; import '../../../../controllers/providers/api/hospitals_provider.dart';
import '../../../../models/enums/user_types.dart';
import '../../../widgets/e_signature/e_signature.dart'; import '../../../widgets/e_signature/e_signature.dart';
import '../../../widgets/timer/app_timer.dart';
class RequestGasRefill extends StatefulWidget { class RequestGasRefill extends StatefulWidget {
static const String id = "/request-gas-refill"; static const String id = "/request-gas-refill";
final GasRefillModel gasRefillModel; final GasRefillModel gasRefillModel;
const RequestGasRefill({this.gasRefillModel, Key key}) : super(key: key); const RequestGasRefill({this.gasRefillModel, Key key}) : super(key: key);
@override @override
@ -85,6 +86,12 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
return; return;
} }
} }
if (_gasRefillProvider.department?.name == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Select department")));
_isLoading = false;
setState(() {});
return;
}
int status = widget.gasRefillModel == null int status = widget.gasRefillModel == null
? await _gasRefillProvider.createModel( ? await _gasRefillProvider.createModel(
@ -104,7 +111,8 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully, msg: _subtitle.requestCompleteSuccessfully,
); );
Navigator.of(context).pop(); Navigator.of(context).pop(_formModel);
setState(() {});
} else { } else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle); String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
@ -149,20 +157,25 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
if (_gasRefillProvider == null) { if (_gasRefillProvider == null) {
_gasRefillProvider = Provider.of<GasRefillProvider>(context, listen: false); _gasRefillProvider = Provider.of<GasRefillProvider>(context, listen: false);
_gasRefillProvider.reset(); //_gasRefillProvider.reset();
} }
if (widget.gasRefillModel != null && _firstTime) { if (_firstTime) {
_formModel = widget.gasRefillModel; String _clientName;
_formModel.status = const Lookup(value: 0); if (widget.gasRefillModel != null) {
HospitalsProvider().getHospitalsListByVal(searchVal: widget.gasRefillModel.clientName).then((value) { _formModel.status = widget.gasRefillModel?.status ?? const Lookup(value: 0);
_gasRefillProvider.hospital = value?.firstWhere((element) => element.name == widget.gasRefillModel.clientName, orElse: () => null); _gasRefillProvider.expectedDateTime = _formModel.expectedDate;
print(_gasRefillProvider.hospital?.buildings?.length); _gasRefillProvider.timer = TimerModel(startAt: widget.gasRefillModel?.startDate, endAt: widget.gasRefillModel?.endDate);
print(widget.gasRefillModel?.building?.name); _clientName = _formModel.clientName;
} else {
_gasRefillProvider.timer = null;
_clientName = _userProvider.user?.clientName;
}
HospitalsProvider().getHospitalsListByVal(searchVal: _clientName).then((value) {
_gasRefillProvider.hospital = value?.firstWhere((element) => element.name == _clientName, orElse: () => null);
_gasRefillProvider.building = _gasRefillProvider.hospital?.buildings?.firstWhere((element) => element.name == widget.gasRefillModel?.building?.name, orElse: () => null); _gasRefillProvider.building = _gasRefillProvider.hospital?.buildings?.firstWhere((element) => element.name == widget.gasRefillModel?.building?.name, orElse: () => null);
_gasRefillProvider.floor = _gasRefillProvider.building?.floors?.firstWhere((element) => element.name == widget.gasRefillModel?.floor?.name, orElse: () => null); _gasRefillProvider.floor = _gasRefillProvider.building?.floors?.firstWhere((element) => element.name == widget.gasRefillModel?.floor?.name, orElse: () => null);
_gasRefillProvider.department = _gasRefillProvider.floor?.departments?.firstWhere((element) => element.name == widget.gasRefillModel?.department?.departmentName, orElse: () => null); _gasRefillProvider.department = _gasRefillProvider.floor?.departments?.firstWhere((element) => element.name == widget.gasRefillModel?.department?.departmentName, orElse: () => null);
_gasRefillProvider.startDate = widget.gasRefillModel?.startDate;
_gasRefillProvider.endDate = widget.gasRefillModel?.endDate;
_firstTime = false; _firstTime = false;
setState(() {}); setState(() {});
}); });
@ -217,7 +230,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
), ),
GasStatusMenu( GasStatusMenu(
initialValue: _formModel.status ?? const Lookup(value: 0), initialValue: _formModel.status ?? const Lookup(value: 0),
enabled: false, enabled: widget.gasRefillModel != null,
onSelect: (status) { onSelect: (status) {
_formModel.status = status; _formModel.status = status;
}, },
@ -232,6 +245,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
height: 4, height: 4,
), ),
HospitalAutoCompleteField( HospitalAutoCompleteField(
enabled: false,
initialValue: _gasRefillProvider.hospital?.name, initialValue: _gasRefillProvider.hospital?.name,
// onSave: (value){ // onSave: (value){
// _search.hospital = value; // _search.hospital = value;
@ -250,6 +264,8 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
BuildingTypeMenu( BuildingTypeMenu(
initialValue: _gasRefillProvider?.building, initialValue: _gasRefillProvider?.building,
building: _gasRefillProvider?.hospital?.buildings, building: _gasRefillProvider?.hospital?.buildings,
loading: _firstTime,
enabled: widget.gasRefillModel == null,
onSelect: (status) { onSelect: (status) {
_gasRefillProvider.building = status; _gasRefillProvider.building = status;
setState(() {}); setState(() {});
@ -259,6 +275,8 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
FloorTypeMenu( FloorTypeMenu(
initialValue: _gasRefillProvider?.floor, initialValue: _gasRefillProvider?.floor,
floors: _gasRefillProvider?.building?.floors, floors: _gasRefillProvider?.building?.floors,
enabled: widget.gasRefillModel == null,
loading: _firstTime,
onSelect: (status) { onSelect: (status) {
_gasRefillProvider.floor = status; _gasRefillProvider.floor = status;
setState(() {}); setState(() {});
@ -268,31 +286,54 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
DepartmentTypeMenu( DepartmentTypeMenu(
initialValue: _gasRefillProvider?.department, initialValue: _gasRefillProvider?.department,
departments: _gasRefillProvider?.floor?.departments, departments: _gasRefillProvider?.floor?.departments,
loading: _firstTime,
enabled: widget.gasRefillModel == null,
onSelect: (status) { onSelect: (status) {
_gasRefillProvider.department = status; _gasRefillProvider.department = status;
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
if (_userProvider.user?.type == UsersTypes.normal_user) if (widget.gasRefillModel != null) ASubTitle(_subtitle.workingHours),
Column( if (widget.gasRefillModel != null) const SizedBox(height: 8),
crossAxisAlignment: CrossAxisAlignment.stretch, if (widget.gasRefillModel != null)
Row(
children: [ children: [
const ASubTitle("Expected Date Time"), Expanded(
SizedBox( child: AppTimer(
height: 8 * AppStyle.getScaleFactor(context), timer: _gasRefillProvider.timer,
), onChange: (timer) async {
ADateTimePicker( _gasRefillProvider.timer = timer;
date: _gasRefillProvider.expectedDateTime, _formModel.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0");
from: DateTime.now().subtract(const Duration(days: 365)), _formModel.startDate = timer.startAt;
to: DateTime.now().add(const Duration(days: 365)), _formModel.endDate = timer.endAt;
onDateTimePicker: (date) { return true;
_gasRefillProvider.expectedDateTime = date;
setState(() {});
}, },
), ),
),
], ],
), ),
//const SizedBox(height: 8),
// if (_userProvider.user?.type == UsersTypes.normal_user || widget.gasRefillModel != null)
// Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: [
// const ASubTitle("Expected Date"),
// SizedBox(
// height: 8 * AppStyle.getScaleFactor(context),
// ),
// ADateTimePicker(
// date: _gasRefillProvider.expectedDateTime,
// from: DateTime.now().subtract(const Duration(days: 365)),
// to: DateTime.now().add(const Duration(days: 365)),
// onDateTimePicker: (date) {
// _gasRefillProvider.expectedDateTime = date;
// _formModel.expectedDate = _gasRefillProvider.expectedDateTime;
// setState(() {});
// },
// ),
// ],
// ),
// if (_userProvider.user?.type == UsersTypes.engineer) // if (_userProvider.user?.type == UsersTypes.engineer)
// Column( // Column(
// children: [ // children: [
@ -367,7 +408,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
const SizedBox(height: 8), const SizedBox(height: 8),
Divider(color: Theme.of(context).colorScheme.primary), Divider(color: Theme.of(context).colorScheme.primary),
const SizedBox(height: 4), const SizedBox(height: 4),
const ASubTitle("Type"), const ASubTitle("Gas Type"),
if (_validate && _currentDetails.type == null) ASubTitle(_subtitle.requiredWord, color: Colors.red), if (_validate && _currentDetails.type == null) ASubTitle(_subtitle.requiredWord, color: Colors.red),
const SizedBox(height: 4), const SizedBox(height: 4),
GasTypeMenu( GasTypeMenu(
@ -395,9 +436,6 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
const SizedBox(
height: 8,
),
const ASubTitle("Cylinder Type"), const ASubTitle("Cylinder Type"),
if (_validate && _currentDetails.cylinderSize == null) if (_validate && _currentDetails.cylinderSize == null)
ASubTitle( ASubTitle(
@ -508,12 +546,12 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
if (widget.gasRefillModel != null) if (widget.gasRefillModel != null)
ESignature( ESignature(
oldSignature: _formModel.signatureEngineer, oldSignature: _formModel.signatureEngineer,
newSignature: _formModel.localNurseSignature, newSignature: _formModel.localEngineerSignature,
onChange: (signature) { onChange: (signature) {
if (signature == null || signature.isEmpty) { if (signature == null || signature.isEmpty) {
return; return;
} }
_formModel.localNurseSignature = signature; _formModel.localEngineerSignature = signature;
_formModel.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; _formModel.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
}, },
), ),

@ -10,6 +10,8 @@ import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_list.dart'; import 'package:test_sa/views/widgets/gas_refill/gas_refill_list.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../widgets/switch_button.dart';
class TrackGasRefillPage extends StatefulWidget { class TrackGasRefillPage extends StatefulWidget {
static const String id = "/track-gas-refill"; static const String id = "/track-gas-refill";
@ -23,6 +25,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
GasRefillProvider _gasRefillProvider; GasRefillProvider _gasRefillProvider;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
bool mostRecent = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -46,6 +49,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
await _gasRefillProvider.getRequests( await _gasRefillProvider.getRequests(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
mostRecent: mostRecent,
); );
}, },
child: Stack( child: Stack(
@ -59,11 +63,11 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
children: [ children: [
Row( Row(
children: [ children: [
ABackButton(), const ABackButton(),
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
_subtitle.serviceRequests, "Gas Refill Requests",
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.grey3A, fontStyle: FontStyle.italic), style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.grey3A, fontStyle: FontStyle.italic),
), ),
), ),
@ -76,6 +80,22 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
], ],
), ),
), ),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ASwitchButton(
title: "Most Recent",
value: mostRecent,
onChange: (value) async {
mostRecent = value;
_gasRefillProvider.reset();
await _gasRefillProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
mostRecent: mostRecent,
);
},
),
),
Expanded( Expanded(
child: GasRefillList( child: GasRefillList(
nextPage: _gasRefillProvider.nextPage, nextPage: _gasRefillProvider.nextPage,
@ -83,6 +103,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProv
await _gasRefillProvider.getRequests( await _gasRefillProvider.getRequests(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
mostRecent: mostRecent,
); );
}, },
items: _gasRefillProvider.items, items: _gasRefillProvider.items,

@ -199,14 +199,14 @@ class _LandPageState extends State<LandPage> {
}, },
), ),
LandPageItem( LandPageItem(
text: "transfer Device", text: "Transfer Asset",
icon: FontAwesomeIcons.rightLeft, icon: FontAwesomeIcons.rightLeft,
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed(RequestDeviceTransfer.id); Navigator.of(context).pushNamed(RequestDeviceTransfer.id);
}, },
), ),
LandPageItem( LandPageItem(
text: "Track Device Transfer", text: "Track Asset Transfer",
icon: FontAwesomeIcons.peopleCarryBox, icon: FontAwesomeIcons.peopleCarryBox,
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed(TrackDeviceTransferPage.id); Navigator.of(context).pushNamed(TrackDeviceTransferPage.id);
@ -214,7 +214,7 @@ class _LandPageState extends State<LandPage> {
), ),
if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user) if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user)
LandPageItem( LandPageItem(
text: "Search Work Order", text: "Create Sub Work Order",
svgPath: "assets/images/sub_workorder_icon.svg", svgPath: "assets/images/sub_workorder_icon.svg",
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed(SearchSubWorkOrderPage.id); Navigator.of(context).pushNamed(SearchSubWorkOrderPage.id);
@ -392,12 +392,12 @@ class _LandPageState extends State<LandPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
"Powered By NewTrack", "Powered By Cloud Solutions",
style: Theme.of(context).textTheme.headline6.copyWith(fontWeight: FontWeight.w500, color: AColors.grey3A, fontSize: 12), style: Theme.of(context).textTheme.headline6.copyWith(fontWeight: FontWeight.w500, color: AColors.grey3A, fontSize: 12),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
6.width, 6.width,
Image.asset("assets/images/qr.jpeg", width: 32, height: 32, color: AColors.grey3A) Image.asset("assets/images/cloud_logo.png", width: 32, height: 32)
], ],
).paddingOnly(left: 20, right: 20, top: 8, bottom: 8), ).paddingOnly(left: 20, right: 20, top: 8, bottom: 8),
], ],

@ -12,6 +12,7 @@ import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
class NotificationsPage extends StatefulWidget { class NotificationsPage extends StatefulWidget {
static final String id = "/notifications"; static final String id = "/notifications";
@override @override
_NotificationsPageState createState() => _NotificationsPageState(); _NotificationsPageState createState() => _NotificationsPageState();
} }
@ -21,6 +22,7 @@ class _NotificationsPageState extends State<NotificationsPage> with TickerProvid
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
Subtitle _subtitle; Subtitle _subtitle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_notificationsProvider = Provider.of<NotificationsProvider>(context); _notificationsProvider = Provider.of<NotificationsProvider>(context);

@ -1,11 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart'; import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
@ -14,12 +12,12 @@ import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/departments/department_button.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_button.dart'; import 'package:test_sa/views/widgets/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
class ProfilePage extends StatefulWidget { class ProfilePage extends StatefulWidget {
static final String id = "/user/profile"; static final String id = "/user/profile";
@override @override
_ProfilePageState createState() => _ProfilePageState(); _ProfilePageState createState() => _ProfilePageState();
} }
@ -33,6 +31,7 @@ class _ProfilePageState extends State<ProfilePage> {
bool _firstTime = true; bool _firstTime = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
@ -119,14 +118,14 @@ class _ProfilePageState extends State<ProfilePage> {
SizedBox( SizedBox(
height: 8, height: 8,
), ),
DepartmentButton( // DepartmentButton(
department: Department(name: _user.departmentName, id: _user.departmentId), // department: Department(name: _user.departmentName, id: _user.departmentId),
onDepartmentPick: (department) { // onDepartmentPick: (department) {
_user.departmentName = department.name; // _user.departmentName = department.name;
_user.departmentId = department.id; // _user.departmentId = department.id;
setState(() {}); // setState(() {});
}, // },
), // ),
SizedBox( SizedBox(
height: 8, height: 8,
), ),
@ -170,29 +169,29 @@ class _ProfilePageState extends State<ProfilePage> {
child: AButton( child: AButton(
text: _subtitle.update, text: _subtitle.update,
onPressed: () async { onPressed: () async {
if (!_formKey.currentState.validate()) return; // if (!_formKey.currentState.validate()) return;
_formKey.currentState.save(); // _formKey.currentState.save();
if (_user.departmentId == null) { // if (_user.departmentId == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( // ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.unitRequired), // content: Text(_subtitle.unitRequired),
)); // ));
return; // return;
} // }
int status = await _userProvider.updateProfile( // int status = await _userProvider.updateProfile(
user: _user, // user: _user,
host: _settingProvider.host, // host: _settingProvider.host,
); // );
if (status >= 200 && status < 300) { // if (status >= 200 && status < 300) {
_settingProvider.setUser(_userProvider.user); // _settingProvider.setUser(_userProvider.user);
ScaffoldMessenger.of(context).showSnackBar(SnackBar( // ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.requestCompleteSuccessfully), // content: Text(_subtitle.requestCompleteSuccessfully),
)); // ));
} else { // } else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle); // String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar( // ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage), // content: Text(errorMessage),
)); // ));
} // }
}, },
), ),
), ),

@ -22,6 +22,7 @@ class ReportIssuesPage extends StatefulWidget {
final ServiceRequest serviceRequest; final ServiceRequest serviceRequest;
const ReportIssuesPage({Key key, this.serviceRequest}) : super(key: key); const ReportIssuesPage({Key key, this.serviceRequest}) : super(key: key);
@override @override
_ReportIssuesPageState createState() => _ReportIssuesPageState(); _ReportIssuesPageState createState() => _ReportIssuesPageState();
} }
@ -35,6 +36,7 @@ class _ReportIssuesPageState extends State<ReportIssuesPage> {
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context).subtitle;

@ -20,10 +20,12 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/time_picker.dart';
import 'package:test_sa/views/widgets/equipment/device_button.dart'; import 'package:test_sa/views/widgets/equipment/device_button.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/sound/record_sound.dart'; import 'package:test_sa/views/widgets/sound/record_sound.dart';
import 'package:test_sa/views/widgets/sound/sound_player.dart';
import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart'; import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_priority_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_priority_mune.dart';
@ -31,6 +33,9 @@ import 'package:test_sa/views/widgets/status/service_request/service_request_thr
import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_through_provider.dart';
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_type_provider.dart';
import '../../../app_style/sizing.dart';
import '../../../widgets/date_and_time/date_picker.dart'; import '../../../widgets/date_and_time/date_picker.dart';
import '../../../widgets/status/service_request/service_request_first_action.dart'; import '../../../widgets/status/service_request/service_request_first_action.dart';
import '../../../widgets/status/service_request/service_request_loan_availability.dart'; import '../../../widgets/status/service_request/service_request_loan_availability.dart';
@ -38,6 +43,7 @@ import '../../../widgets/status/service_request/service_request_loan_availabilit
class CreateRequestPage extends StatefulWidget { class CreateRequestPage extends StatefulWidget {
static const String id = "/create-request"; static const String id = "/create-request";
final ServiceRequest serviceRequest; final ServiceRequest serviceRequest;
const CreateRequestPage({this.serviceRequest, Key key}) : super(key: key); const CreateRequestPage({this.serviceRequest, Key key}) : super(key: key);
@override @override
@ -57,9 +63,11 @@ class CreateRequestPageState extends State<CreateRequestPage> {
Subtitle _subtitle; Subtitle _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TextEditingController _maintenanceController, _commentController; TextEditingController _maintenanceController, _commentController, _reviewCommentController;
DateTime _dateTime; DateTime _dateTime;
bool isFirstActionSubmitted = false;
@override @override
void initState() { void initState() {
_maintenanceController = TextEditingController(); _maintenanceController = TextEditingController();
@ -69,12 +77,36 @@ class CreateRequestPageState extends State<CreateRequestPage> {
_device = _serviceRequest.device; _device = _serviceRequest.device;
_deviceImages.addAll(_serviceRequest.devicePhotos.map((e) => File(e)).toList()); _deviceImages.addAll(_serviceRequest.devicePhotos.map((e) => File(e)).toList());
_showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit"; _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
if (_showDatePicker && _serviceRequest.visitDate != null) {
_dateTime = DateTime.tryParse(_serviceRequest.visitDate);
}
} else { } else {
_serviceRequest = ServiceRequest(); _serviceRequest = ServiceRequest();
} }
isFirstActionSubmitted = _serviceRequest?.firstAction != null;
super.initState(); super.initState();
} }
//
// getServiceRequestById(String id) async {
// try {
// ServiceRequest request = await _serviceRequestsProvider.getServiceRequestObjectById(requestId: id) ?? "";
// _serviceRequest = request;
// _device = _serviceRequest.device;
// _deviceImages.addAll(_serviceRequest.devicePhotos.map((e) {
// return File(e);
// }).toList());
// _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction.name == "Need a visit";
// if (_showDatePicker && _serviceRequest.visitDate != null) {
// _dateTime = DateTime.tryParse(_serviceRequest.visitDate);
// }
// _isLoading = false;
// } catch (ex) {
// _isLoading = false;
// }
// setState(() {});
// }
@override @override
void dispose() { void dispose() {
_maintenanceController.dispose(); _maintenanceController.dispose();
@ -82,13 +114,19 @@ class CreateRequestPageState extends State<CreateRequestPage> {
super.dispose(); super.dispose();
} }
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_height = MediaQuery.of(context).size.height; _height = MediaQuery.of(context).size.height;
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context).subtitle;
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: SafeArea(
@ -135,14 +173,39 @@ class CreateRequestPageState extends State<CreateRequestPage> {
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
), ),
12.height, 12.height,
_userProvider.user.departmentId == null _userProvider.user.departmentId == null || (_userProvider.user?.departmentId?.isEmpty ?? false)
? const SizedBox.shrink() ? const SizedBox.shrink()
: ATextFormField( : Container(
enable: false, padding: const EdgeInsets.all(12),
initialValue: _userProvider.user.departmentName ?? _subtitle.noUniteFound, decoration: BoxDecoration(
hintText: _subtitle.unite, color: const Color(0xfff5f5f5),
prefixIconData: FontAwesomeIcons.hospitalUser, border: Border.all(
style: Theme.of(context).textTheme.subtitle1, color: const Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _userProvider.user.departmentName
?.map(
(e) => Text(
e?.trim() ?? "",
style: Theme.of(context).textTheme.titleMedium.copyWith(color: AColors.black),
),
)
?.toList() ??
[],
),
Icon(
FontAwesomeIcons.hospitalUser,
size: 20 * AppStyle.getScaleFactor(context),
color: const Color(0xff2e303a),
),
],
),
), ),
12.height, 12.height,
DeviceButton( DeviceButton(
@ -160,15 +223,16 @@ class CreateRequestPageState extends State<CreateRequestPage> {
height: 4, height: 4,
), ),
ServiceRequestPriorityMenu( ServiceRequestPriorityMenu(
initialValue: _serviceRequest.priority, initialValue: widget.serviceRequest?.priority,
onSelect: (status) { onSelect: (status) {
_serviceRequest.priority = status; _serviceRequest.priority = status;
}, },
enabled: widget.serviceRequest == null ? true : false,
), ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
const ASubTitle("Defect Type"), const ASubTitle("Equipment Status"),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -177,12 +241,13 @@ class CreateRequestPageState extends State<CreateRequestPage> {
onSelect: (status) { onSelect: (status) {
_serviceRequest.defectType = status; _serviceRequest.defectType = status;
}, },
enabled: widget.serviceRequest == null ? true : false,
), ),
12.height, 12.height,
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
const ASubTitle("Type"), const ASubTitle("Type of Request"),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -191,6 +256,8 @@ class CreateRequestPageState extends State<CreateRequestPage> {
onSelect: (status) { onSelect: (status) {
_serviceRequest.type = status; _serviceRequest.type = status;
}, },
enabled: false,
withDefaultItem: widget.serviceRequest == null,
), ),
const SizedBox( const SizedBox(
height: 8, height: 8,
@ -201,9 +268,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
), ),
ServiceRequestedThroughMenu( ServiceRequestedThroughMenu(
initialValue: _serviceRequest.requestedThrough, initialValue: _serviceRequest.requestedThrough,
onSelect: (status) { enabled: false,
_serviceRequest.requestedThrough = status;
},
), ),
if (widget.serviceRequest != null) 12.height, if (widget.serviceRequest != null) 12.height,
if (widget.serviceRequest != null) const ASubTitle("First Action"), if (widget.serviceRequest != null) const ASubTitle("First Action"),
@ -213,6 +278,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
if (widget.serviceRequest != null) if (widget.serviceRequest != null)
ServiceRequestedFirstAction( ServiceRequestedFirstAction(
initialValue: _serviceRequest.firstAction, initialValue: _serviceRequest.firstAction,
enabled: !isFirstActionSubmitted,
onSelect: (status) { onSelect: (status) {
_dateTime = null; _dateTime = null;
_serviceRequest.firstAction = status; _serviceRequest.firstAction = status;
@ -222,10 +288,11 @@ class CreateRequestPageState extends State<CreateRequestPage> {
), ),
if (_showDatePicker) 12.height, if (_showDatePicker) 12.height,
if (_showDatePicker) if (_showDatePicker)
ADatePicker( ADateTimePicker(
date: _dateTime, date: _dateTime,
enable: !isFirstActionSubmitted,
from: DateTime.now(), from: DateTime.now(),
onDatePicker: (date) { onDateTimePicker: (date) {
_dateTime = date; _dateTime = date;
setState(() {}); setState(() {});
}, },
@ -249,7 +316,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
), ),
if (widget.serviceRequest != null) if (widget.serviceRequest != null)
ATextFormField( ATextFormField(
controller: _commentController, controller: _reviewCommentController,
initialValue: _serviceRequest.reviewComment, initialValue: _serviceRequest.reviewComment,
hintText: _subtitle.comment, hintText: _subtitle.comment,
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
@ -257,14 +324,19 @@ class CreateRequestPageState extends State<CreateRequestPage> {
onSaved: (value) { onSaved: (value) {
_serviceRequest.reviewComment = value; _serviceRequest.reviewComment = value;
}, },
enable: widget.serviceRequest != null ? false : true,
), ),
12.height, 12.height,
MultiImagesPicker( MultiFilesPicker(
label: _subtitle.deviceImages, label: _subtitle.deviceFiles,
images: _deviceImages, files: _deviceImages,
enabled: widget.serviceRequest == null ? true : false,
), ),
12.height, 12.height,
SpeechToTextButton(controller: _maintenanceController), SpeechToTextButton(
controller: _maintenanceController,
enabled: widget.serviceRequest == null ? true : false,
),
12.height, 12.height,
ATextFormField( ATextFormField(
controller: _maintenanceController, controller: _maintenanceController,
@ -273,15 +345,24 @@ class CreateRequestPageState extends State<CreateRequestPage> {
prefixIconData: FontAwesomeIcons.triangleExclamation, prefixIconData: FontAwesomeIcons.triangleExclamation,
style: Theme.of(context).textTheme.titleLarge, style: Theme.of(context).textTheme.titleLarge,
textInputType: TextInputType.multiline, textInputType: TextInputType.multiline,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.maintenanceIssueRequired, validator: (value) => widget.serviceRequest != null || Validator.hasValue(value) ? null : _subtitle.maintenanceIssueRequired,
onSaved: (value) { onSaved: (value) {
_serviceRequest.callComments = value; _serviceRequest.callComments = value;
}, },
enable: widget.serviceRequest == null ? true : false,
), ),
12.height, 12.height,
RecordSound(onRecord: (audio) { if (_serviceRequest.audio?.isNotEmpty == true)
ASoundPlayer(
audio: _serviceRequest.audio,
)
else
RecordSound(
onRecord: (audio) {
_serviceRequest.audio = audio; _serviceRequest.audio = audio;
}), },
enabled: widget.serviceRequest == null ? true : false,
),
12.height, 12.height,
if (widget.serviceRequest != null) if (widget.serviceRequest != null)
ATextFormField( ATextFormField(
@ -307,7 +388,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
return; return;
} }
if (_serviceRequest.firstAction?.name == "Need a visit" && _dateTime == null) { if (_serviceRequest.firstAction?.name == "Need a visit" && _dateTime == null) {
Fluttertoast.showToast(msg: _subtitle.noDateFound); Fluttertoast.showToast(msg: "first action is required");
return; return;
} }
if (widget.serviceRequest != null && (_serviceRequest?.engineerId == null || (_serviceRequest?.engineerId?.isEmpty ?? false))) { if (widget.serviceRequest != null && (_serviceRequest?.engineerId == null || (_serviceRequest?.engineerId?.isEmpty ?? false))) {
@ -316,13 +397,19 @@ class CreateRequestPageState extends State<CreateRequestPage> {
} }
_formKey.currentState.save(); _formKey.currentState.save();
_serviceRequest.deviceId = _device?.id; _serviceRequest.deviceId = _device?.id;
if (widget.serviceRequest == null) {
_serviceRequest.type = Provider.of<ServiceRequestTypeProvider>(context, listen: false).getDefaultItem();
}
_serviceRequest.requestedThrough = Provider.of<ServiceRequestedThroughProvider>(context, listen: false).getDefaultItem();
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_serviceRequest.devicePhotos = _deviceImages.map((e) => "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}").toList(); _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();
if (_serviceRequest.audio != null) { if (_serviceRequest.audio != null) {
final file = File(_serviceRequest.audio); if (_isLocalUrl(_serviceRequest.audio)) {
final File file = File(_serviceRequest.audio);
_serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
} }
}
int status = 0; int status = 0;
if (widget.serviceRequest == null) { if (widget.serviceRequest == null) {
status = await _serviceRequestsProvider.createRequest( status = await _serviceRequestsProvider.createRequest(

@ -20,6 +20,7 @@ class FutureRequestServiceDetails extends StatefulWidget {
class _FutureRequestServiceDetailsState extends State<FutureRequestServiceDetails> { class _FutureRequestServiceDetailsState extends State<FutureRequestServiceDetails> {
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);

@ -22,10 +22,8 @@ import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart'; import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart'; import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/parts/part_item.dart'; import 'package:test_sa/views/widgets/parts/part_item.dart';
@ -35,6 +33,8 @@ import 'package:test_sa/views/widgets/status/report/service_report_reasons.dart'
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart'; import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../widgets/date_and_time/date_picker.dart';
import '../../../../widgets/images/multi_image_picker.dart';
import '../../../../widgets/status/report/service_report_fault_description.dart'; import '../../../../widgets/status/report/service_report_fault_description.dart';
import '../../../../widgets/status/report/service_report_repair_location.dart'; import '../../../../widgets/status/report/service_report_repair_location.dart';
import '../../../../widgets/timer/app_timer.dart'; import '../../../../widgets/timer/app_timer.dart';
@ -60,7 +60,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
bool _showCommentField = false; bool _showCommentField = false;
Subtitle _subtitle; Subtitle _subtitle;
File _image; final List<File> _files = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final TextEditingController _faultController = TextEditingController(); final TextEditingController _faultController = TextEditingController();
@ -69,7 +69,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
@override @override
void initState() { void initState() {
_serviceReport = ServiceReport( _serviceReport = ServiceReport(
visitDate: DateTime.now(), returnToService: DateTime.now(),
//type: const Lookup(value: 2), //type: const Lookup(value: 2),
device: widget.request.device, device: widget.request.device,
parts: [], parts: [],
@ -155,12 +155,17 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
) )
]), ]),
child: Wrap( child: Wrap(
direction: Axis.vertical,
spacing: 10, spacing: 10,
children: [ children: [
ASubTitle( ASubTitle(
"${_subtitle.callId}: ${widget.request.requestCode}", "${_subtitle.callId}: ${widget.request.requestCode}",
font: 14, font: 14,
), ),
ASubTitle(
"${_subtitle.assetNumber}: ${widget.request.deviceNumber}",
font: 14,
),
widget.request.deviceSerialNumber == null widget.request.deviceSerialNumber == null
? const SizedBox() ? const SizedBox()
: ASubTitle( : ASubTitle(
@ -195,63 +200,6 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Report type and Reasons // Report type and Reasons
Row(
children: [
// Report Status
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// ASubTitle(_subtitle.reportType),
// _validate && _serviceReport.type == null ?
// ASubTitle(_subtitle.requiredWord,color: Colors.red,):
// const SizedBox.shrink(),
// const SizedBox(height: 4,),
// ServiceReportTypeMenu(
// initialValue: _serviceReport.type,
// onSelect: (status){
// _serviceReport.type = status;
// },
// ),
// ],
// ),
// ),
// const SizedBox(width: 8,),
// visit date
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.visitDate),
_validate && _serviceReport.visitDate == null
? ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
Row(
children: [
Expanded(
child: ADatePicker(
date: _serviceReport.visitDate,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDatePicker: (date) {
_serviceReport.visitDate = date;
setState(() {});
},
),
),
],
),
],
),
),
],
),
const SizedBox(
height: 8,
),
// device sn // device sn
Visibility( Visibility(
visible: widget.request.deviceSerialNumber == null, visible: widget.request.deviceSerialNumber == null,
@ -281,7 +229,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
ASubTitle(_subtitle.assetType ??""), ASubTitle(_subtitle.assetType ?? ""),
_validate && _serviceReport.assetType == null _validate && _serviceReport.assetType == null
? ASubTitle( ? ASubTitle(
_subtitle.requiredWord, _subtitle.requiredWord,
@ -415,6 +363,63 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
SizedBox( SizedBox(
height: 8 * AppStyle.getScaleFactor(context), height: 8 * AppStyle.getScaleFactor(context),
), ),
Row(
children: [
// Report Status
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// ASubTitle(_subtitle.reportType),
// _validate && _serviceReport.type == null ?
// ASubTitle(_subtitle.requiredWord,color: Colors.red,):
// const SizedBox.shrink(),
// const SizedBox(height: 4,),
// ServiceReportTypeMenu(
// initialValue: _serviceReport.type,
// onSelect: (status){
// _serviceReport.type = status;
// },
// ),
// ],
// ),
// ),
// const SizedBox(width: 8,),
// visit date
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ASubTitle("Return to Service"),
// _validate && _serviceReport.returnToService == null
// ? ASubTitle(
// _subtitle.requiredWord,
// color: Colors.red,
// )
// : const SizedBox.shrink(),
Row(
children: [
Expanded(
child: ADatePicker(
date: _serviceReport.returnToService,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDatePicker: (date) {
_serviceReport.returnToService = date;
setState(() {});
},
),
),
],
),
],
),
),
],
),
const SizedBox(
height: 8,
),
ASubTitle(_subtitle.workingHours), ASubTitle(_subtitle.workingHours),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
@ -541,8 +546,10 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
requestId: widget.request?.id, requestId: widget.request?.id,
initialValue: _serviceReport.faultDescription, initialValue: _serviceReport.faultDescription,
onSelect: (status) { onSelect: (status) {
if (status != null) {
_serviceReport.faultDescription = status; _serviceReport.faultDescription = status;
setState(() {}); setState(() {});
}
}, },
), ),
const SizedBox( const SizedBox(
@ -564,7 +571,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
), ),
Row( Row(
children: [ children: [
ASubTitle(_subtitle.workPreformed), const ASubTitle("Solutions"),
// Expanded( // Expanded(
// child: SizedBox( // child: SizedBox(
// height: 32 * AppStyle.getScaleFactor(context), // height: 32 * AppStyle.getScaleFactor(context),
@ -604,7 +611,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.reasons), const ASubTitle("Failure Reason"),
_validate && _serviceReport.reason?.id == null _validate && _serviceReport.reason?.id == null
? ASubTitle( ? ASubTitle(
_subtitle.requiredWord, _subtitle.requiredWord,
@ -622,25 +629,27 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( // Expanded(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
ASubTitle(_subtitle.attachImage), // const ASubTitle("Attachments"),
AMiniOneImagePicker( // AMiniOneFilePicker(
//error: _validate && _serviceReport.image == null, // //error: _validate && _serviceReport.image == null,
image: _image, // file: _file,
onPick: (image) { // onPick: (file) {
_image = image; // _file = file;
_serviceReport.image = "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}"; // _serviceReport.files[0] = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
}, // },
), // ),
], // ],
), // ),
), // ),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
MultiFilesPicker(label: "Attachments", files: _files),
const SizedBox(height: 8),
ASubTitle(_subtitle.repairLocation), ASubTitle(_subtitle.repairLocation),
const SizedBox(height: 4), const SizedBox(height: 4),
ServiceReportRepairLocation( ServiceReportRepairLocation(
@ -650,7 +659,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
ASubTitle(_subtitle.travelingExpense), const ASubTitle("Travel Expenses"),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -786,7 +795,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// ), // ),
const SizedBox(height: 8), const SizedBox(height: 8),
ASubTitle(_subtitle.comment), const ASubTitle("Technical comment"),
const SizedBox(height: 4), const SizedBox(height: 4),
ATextFormField( ATextFormField(
initialValue: _serviceReport?.comment, initialValue: _serviceReport?.comment,
@ -853,7 +862,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.partNumber), ASubTitle(_subtitle.partNumberName),
_validate && _serviceReport.parts == null _validate && _serviceReport.parts == null
? ASubTitle( ? ASubTitle(
_subtitle.requiredWord, _subtitle.requiredWord,
@ -864,6 +873,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
height: 4, height: 4,
), ),
AutoCompletePartsField( AutoCompletePartsField(
assetId: _serviceReport?.device?.id,
onPick: (part) { onPick: (part) {
_serviceReport.parts.add(part); _serviceReport.parts.add(part);
}, },
@ -918,15 +928,16 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_serviceReport.files ??= [];
for (var file in _files) {
_serviceReport.files.add("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}");
}
int status = await _serviceRequestsProvider.createServiceReport( int status = await _serviceRequestsProvider.createServiceReport(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
report: _serviceReport, report: _serviceReport,
request: widget.request, request: widget.request,
); );
print(6);
print(status);
_isLoading = false; _isLoading = false;
setState(() {}); setState(() {});
if (status >= 200 && status < 300) { if (status >= 200 && status < 300) {

@ -26,7 +26,6 @@ import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart'; import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart'; import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/parts/part_item.dart'; import 'package:test_sa/views/widgets/parts/part_item.dart';
@ -38,6 +37,8 @@ import 'package:test_sa/views/widgets/status/report/service_report_repair_locati
import 'package:test_sa/views/widgets/timer/app_timer.dart'; import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../widgets/images/multi_image_picker.dart';
class EditServiceReport extends StatefulWidget { class EditServiceReport extends StatefulWidget {
static final String id = "/edit-service-report"; static final String id = "/edit-service-report";
final ServiceRequest request; final ServiceRequest request;
@ -60,7 +61,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
bool _showCommentField = false; bool _showCommentField = false;
Subtitle _subtitle; Subtitle _subtitle;
File _image; List<File> _images = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TextEditingController _faultController = TextEditingController(); TextEditingController _faultController = TextEditingController();
@ -73,6 +74,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
@override @override
void initState() { void initState() {
_serviceReport = widget.report; _serviceReport = widget.report;
_images = widget.report?.files?.map((e) => File(e))?.toList();
super.initState(); super.initState();
} }
@ -149,12 +151,17 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
) )
]), ]),
child: Wrap( child: Wrap(
direction: Axis.vertical,
spacing: 10, spacing: 10,
children: [ children: [
ASubTitle( ASubTitle(
"${_subtitle.callId}: ${widget.request.requestCode}", "${_subtitle.callId}: ${widget.request.requestCode}",
font: 14, font: 14,
), ),
ASubTitle(
"${_subtitle.assetNumber}: ${widget.request.deviceNumber}",
font: 14,
),
widget.request.deviceSerialNumber == null widget.request.deviceSerialNumber == null
? const SizedBox() ? const SizedBox()
: ASubTitle( : ASubTitle(
@ -179,8 +186,8 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(vertical: 16), margin: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [
const BoxShadow( BoxShadow(
color: AColors.grey, color: AColors.grey,
offset: Offset(0, -1), offset: Offset(0, -1),
) )
@ -189,70 +196,70 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Report type and Reasons // Report type and Reasons
Row( // Row(
children: [ // children: [
// Report Status // // Report Status
// // Expanded(
// // child: Column(
// // crossAxisAlignment: CrossAxisAlignment.start,
// // children: [
// // ASubTitle(_subtitle.reportType),
// // _validate && _serviceReport.type == null
// // ? ASubTitle(
// // _subtitle.requiredWord,
// // color: Colors.red,
// // )
// // : const SizedBox.shrink(),
// // const SizedBox(
// // height: 4,
// // ),
// // ServiceReportTypeMenu(
// // initialValue: _serviceReport.type,
// // onSelect: (status) {
// // _serviceReport.type = status;
// // },
// // ),
// // ],
// // ),
// // ),
// // const SizedBox(
// // width: 8,
// // ),
// // visit date
// Expanded( // Expanded(
// child: Column( // child: Column(
// crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
// children: [ // children: [
// ASubTitle(_subtitle.reportType), // ASubTitle(_subtitle.visitDate),
// _validate && _serviceReport.type == null // _validate && _serviceReport.visitDate == null
// ? ASubTitle( // ? ASubTitle(
// _subtitle.requiredWord, // _subtitle.requiredWord,
// color: Colors.red, // color: Colors.red,
// ) // )
// : const SizedBox.shrink(), // : const SizedBox.shrink(),
// const SizedBox( // Row(
// height: 4, // children: [
// ), // Expanded(
// ServiceReportTypeMenu( // child: ADatePicker(
// initialValue: _serviceReport.type, // date: _serviceReport.visitDate,
// onSelect: (status) { // from: DateTime.now().subtract(const Duration(days: 365)),
// _serviceReport.type = status; // to: DateTime.now().add(const Duration(days: 365)),
// onDatePicker: (date) {
// _serviceReport.visitDate = date;
// setState(() {});
// }, // },
// ), // ),
// ),
// ], // ],
// ), // ),
// ],
// ),
// ),
// ],
// ), // ),
// const SizedBox( // const SizedBox(
// width: 8, // height: 8,
// ), // ),
// visit date
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.visitDate),
_validate && _serviceReport.visitDate == null
? ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
Row(
children: [
Expanded(
child: ADatePicker(
date: _serviceReport.visitDate,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDatePicker: (date) {
_serviceReport.visitDate = date;
setState(() {});
},
),
),
],
),
],
),
),
],
),
const SizedBox(
height: 8,
),
// device sn // device sn
Visibility( Visibility(
visible: widget.request.deviceSerialNumber == null, visible: widget.request.deviceSerialNumber == null,
@ -380,6 +387,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
setState(() {}); setState(() {});
} else { } else {
_serviceReport.callLastSituation = status; _serviceReport.callLastSituation = status;
setState(() {});
} }
}, },
), ),
@ -390,6 +398,56 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
), ),
], ],
), ),
const SizedBox(
height: 8,
),
const ASubTitle("Return to Service"),
Row(
children: [
Expanded(
child: ADatePicker(
date: _serviceReport.returnToService,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDatePicker: (date) {
_serviceReport.returnToService = date;
setState(() {});
},
),
),
],
),
if (_serviceReport?.callLastSituation?.value == 2)
Column(
children: [
const SizedBox(
height: 8,
),
ATextFormField(
initialValue: _serviceReport?.reviewComment,
hintText: "Vendor Name",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceReport.reviewComment = value;
},
),
const SizedBox(
height: 8,
),
ATextFormField(
initialValue: _serviceReport?.reviewComment,
hintText: "Vendor Engineer",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceReport.reviewComment = value;
},
),
],
),
if (_showCommentField) if (_showCommentField)
const SizedBox( const SizedBox(
height: 8, height: 8,
@ -658,13 +716,14 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
requestId: widget.request?.id, requestId: widget.request?.id,
initialValue: _serviceReport.faultDescription, initialValue: _serviceReport.faultDescription,
onSelect: (status) { onSelect: (status) {
print("faluttt:${status?.toJson()}");
_serviceReport.faultDescription = status; _serviceReport.faultDescription = status;
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if (mounted) setState(() {}); if (mounted) setState(() {});
});
}, },
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
ASubTitle(_subtitle.workPreformed), const ASubTitle("Solutions"),
const SizedBox(height: 4), const SizedBox(height: 4),
ATextFormField( ATextFormField(
initialValue: _serviceReport?.workPreformed, initialValue: _serviceReport?.workPreformed,
@ -680,14 +739,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
}, },
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Row( ASubTitle("Failure Reason"),
children: [
// reasons
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.reasons),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -697,30 +749,25 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
_serviceReport.reason = status; _serviceReport.reason = status;
}, },
), ),
],
),
),
const SizedBox( const SizedBox(
width: 8, height: 8,
), ),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.attachImage), ASubTitle(_subtitle.attachImage),
AMiniOneImagePicker( const SizedBox(
//error: _validate && _serviceReport.image == null, height: 4,
image: _image,
onPick: (image) {
_image = image;
_serviceReport.image = base64Encode(image.readAsBytesSync());
},
),
],
),
), ),
], MultiFilesPicker(
label: "",
files: _images,
), ),
// AMiniOneImagePicker(
// //error: _validate && _serviceReport.image == null,
// image: _image,
// onPick: (image) {
// _image = image;
// _serviceReport.image = base64Encode(image.readAsBytesSync());
// },
// ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
@ -734,7 +781,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
ASubTitle(_subtitle.travelingExpense), ASubTitle("Travel Expenses"),
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
@ -746,9 +793,9 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
textInputType: TextInputType.number, textInputType: TextInputType.number,
onSaved: (value) { onSaved: (value) {
if (value != null && value.isEmpty) { if (value != null && value.isEmpty) {
_serviceReport.travelingExpense = int.tryParse(_serviceReport?.travelingExpense?.toString() ?? "") ?? 0; _serviceReport.travelingExpense = num.tryParse(_serviceReport?.travelingExpense?.toString() ?? "") ?? 0;
} else } else
_serviceReport.travelingExpense = int.tryParse(value) ?? 0; _serviceReport.travelingExpense = num.tryParse(value) ?? 0;
}, },
), ),
@ -885,7 +932,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
//const SizedBox(height: 8,), //const SizedBox(height: 8,),
const SizedBox(height: 8), const SizedBox(height: 8),
ASubTitle(_subtitle.comment), const ASubTitle("Technical comment"),
const SizedBox(height: 4), const SizedBox(height: 4),
ATextFormField( ATextFormField(
initialValue: _serviceReport?.comment, initialValue: _serviceReport?.comment,
@ -955,7 +1002,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.partNumber), ASubTitle(_subtitle.partNumberName),
_validate && _serviceReport.parts == null _validate && _serviceReport.parts == null
? ASubTitle( ? ASubTitle(
_subtitle.requiredWord, _subtitle.requiredWord,
@ -966,6 +1013,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
height: 4, height: 4,
), ),
AutoCompletePartsField( AutoCompletePartsField(
assetId: _serviceReport?.device?.id,
onPick: (part) { onPick: (part) {
_serviceReport.parts.add(part); _serviceReport.parts.add(part);
setState(() {}); setState(() {});
@ -1011,7 +1059,6 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
return; return;
} }
_validate = true; _validate = true;
print("jere1245");
// if (!_formKey.currentState.validate()) { // if (!_formKey.currentState.validate()) {
// setState(() {}); // setState(() {});
// return; // return;
@ -1026,7 +1073,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_serviceReport.files = _images.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();
int status = await _serviceRequestsProvider.updateServiceReport(user: _userProvider.user, host: _settingProvider.host, report: _serviceReport, request: widget.request); int status = await _serviceRequestsProvider.updateServiceReport(user: _userProvider.user, host: _settingProvider.host, report: _serviceReport, request: widget.request);
_isLoading = false; _isLoading = false;
setState(() {}); setState(() {});
@ -1054,4 +1101,9 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
), ),
); );
} }
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
} }

@ -26,30 +26,32 @@ class FutureServiceReport extends StatefulWidget {
class _FutureServiceReportState extends State<FutureServiceReport> { class _FutureServiceReportState extends State<FutureServiceReport> {
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle subtitle = AppLocalization.of(context).subtitle;
ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle); ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: subtitle);
return Scaffold( return Scaffold(
body: FutureBuilder<ServiceReport>( body: FutureBuilder<ServiceReport>(
future: ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle), future: ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: subtitle),
builder: (BuildContext context, AsyncSnapshot<ServiceReport> snapshot) { builder: (BuildContext context, AsyncSnapshot<ServiceReport> snapshot) {
if (snapshot.hasError) if (snapshot.hasError) {
return FailedLoading( return FailedLoading(
message: snapshot.error.toString(), message: snapshot.error.toString(),
onReload: () { onReload: () {
setState(() {}); setState(() {});
}, },
); );
if (snapshot.hasData) { }
if (snapshot.connectionState == ConnectionState.done) {
return EditServiceReport( return EditServiceReport(
report: snapshot.data, report: snapshot.data,
request: widget.request, request: widget.request,
); );
} }
return Center(child: ALoading()); return const Center(child: ALoading());
}, },
), ),
); );

@ -6,6 +6,7 @@ import 'package:test_sa/controllers/providers/api/service_requests_provider.dart
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
@ -16,7 +17,9 @@ import 'package:test_sa/views/pages/user/requests/report/create_service_report.d
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart'; import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/images/images_list.dart'; import 'package:test_sa/views/widgets/images/images_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart';
@ -27,10 +30,10 @@ import '../../../../models/service_request/search_work_order.dart';
import 'report/future_service_report.dart'; import 'report/future_service_report.dart';
class RequestDetailsPage extends StatelessWidget { class RequestDetailsPage extends StatelessWidget {
static final String id = "/call-details"; static const String id = "/call-details";
final ServiceRequest serviceRequest; ServiceRequest serviceRequest;
const RequestDetailsPage({Key key, this.serviceRequest}) : super(key: key); RequestDetailsPage({Key key, this.serviceRequest}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -39,11 +42,20 @@ class RequestDetailsPage extends StatelessWidget {
SettingProvider _settingProvider = Provider.of<SettingProvider>(context); SettingProvider _settingProvider = Provider.of<SettingProvider>(context);
List<SearchWorkOrder> workOrders = []; List<SearchWorkOrder> workOrders = [];
ServiceRequestsProvider _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); ServiceRequestsProvider _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_serviceRequestsProvider.getServiceRequestObjectById(requestId: serviceRequest.id);
return DefaultTabController( return DefaultTabController(
length: 2, length: 2,
child: Scaffold( child: Scaffold(
body: SafeArea( body: SafeArea(
child: Column( child: FutureBuilder(
future: _serviceRequestsProvider.getServiceRequestObjectById(requestId: serviceRequest.id),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) {
return const ALoading();
} else if (snap.hasData) {
serviceRequest = snap.data;
return Column(
children: [ children: [
Container( Container(
color: AColors.primaryColor, color: AColors.primaryColor,
@ -82,7 +94,9 @@ class RequestDetailsPage extends StatelessWidget {
color: AColors.white, color: AColors.white,
buttonSize: 42, buttonSize: 42,
backgroundColor: AColors.green, backgroundColor: AColors.green,
onPressed: () async { onPressed: (serviceRequest.statusValue == 5 || serviceRequest.statusValue == 3)
? null
: () async {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)), MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)),
); );
@ -129,45 +143,52 @@ class RequestDetailsPage extends StatelessWidget {
), ),
), ),
serviceRequest.devicePhotos.isEmpty serviceRequest.devicePhotos.isEmpty
? SizedBox.shrink() ? const SizedBox.shrink()
: Column( : SizedBox(
children: [
SizedBox(
height: 8,
),
MaterialButton(
padding: EdgeInsets.zero,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => Scaffold(
body: InteractiveViewer(
child: Center(
child: ImageLoader(
url: serviceRequest.devicePhotos.first,
boxFit: BoxFit.contain,
),
),
),
)));
},
child: SizedBox(
height: 140 * AppStyle.getScaleFactor(context),
width: MediaQuery.of(context).size.width,
child: ImageLoader(
url: serviceRequest.devicePhotos.first,
boxFit: BoxFit.cover,
),
),
),
SizedBox(height: 8),
SizedBox(
height: 60 * AppStyle.getScaleFactor(context), height: 60 * AppStyle.getScaleFactor(context),
child: ImagesList( child: FilesList(
images: serviceRequest.devicePhotos, images: serviceRequest.devicePhotos,
), ),
), ).paddingOnly(top: 4, bottom: 4),
],
), // Column(
// children: [
// SizedBox(
// height: 8,
// ),
// MaterialButton(
// padding: EdgeInsets.zero,
// onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (_) => Scaffold(
// body: InteractiveViewer(
// child: Center(
// child: ImageLoader(
// url: serviceRequest.devicePhotos.first,
// boxFit: BoxFit.contain,
// ),
// ),
// ),
// )));
// },
// child: SizedBox(
// height: 140 * AppStyle.getScaleFactor(context),
// width: MediaQuery.of(context).size.width,
// child: ImageLoader(
// url: serviceRequest.devicePhotos.first,
// boxFit: BoxFit.cover,
// ),
// ),
// ),
// SizedBox(height: 8),
// SizedBox(
// height: 60 * AppStyle.getScaleFactor(context),
// child: FilesList(
// images: serviceRequest.devicePhotos,
// ),
// ),
// ],
// ),
TabBar(labelColor: AColors.primaryColor, tabs: [ TabBar(labelColor: AColors.primaryColor, tabs: [
Tab( Tab(
text: _subtitle.general, text: _subtitle.general,
@ -186,7 +207,7 @@ class RequestDetailsPage extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 16), padding: EdgeInsets.symmetric(horizontal: 16),
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: _subtitle.code, title: _subtitle.callId,
info: serviceRequest.requestCode, info: serviceRequest.requestCode,
), ),
RequestInfoRow( RequestInfoRow(
@ -246,10 +267,10 @@ class RequestDetailsPage extends StatelessWidget {
// title: _subtitle.deviceArName, // title: _subtitle.deviceArName,
// content: serviceRequest.deviceArName, // content: serviceRequest.deviceArName,
// ), // ),
RequestInfoRow( // RequestInfoRow(
title: _subtitle.deviceName, // title: _subtitle.deviceName,
content: serviceRequest.deviceEnName, // content: serviceRequest.deviceEnName,
), // ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.maintenanceIssue, title: _subtitle.maintenanceIssue,
content: serviceRequest.callComments, content: serviceRequest.callComments,
@ -354,6 +375,10 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.assetName, title: _subtitle.assetName,
info: workOrders[index].callRequest.asset.modelDefinition.assetName, info: workOrders[index].callRequest.asset.modelDefinition.assetName,
), ),
RequestInfoRow(
title: _subtitle.assetNumber,
info: workOrders[index].callRequest.asset.assetNumber,
),
RequestInfoRow( RequestInfoRow(
title: _subtitle.model, title: _subtitle.model,
info: workOrders[index].callRequest.asset.modelDefinition.modelName, info: workOrders[index].callRequest.asset.modelDefinition.modelName,
@ -363,11 +388,7 @@ class RequestDetailsPage extends StatelessWidget {
info: workOrders[index].callRequest.asset.site.custName, info: workOrders[index].callRequest.asset.site.custName,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.maintenanceSituation, title: "Call last Situation",
info: workOrders[index].calllastSituation.name ?? '',
),
RequestInfoRow(
title: _subtitle.currentSituation,
info: workOrders[index].currentSituation.name ?? '', info: workOrders[index].currentSituation.name ?? '',
), ),
_userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null _userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null
@ -375,7 +396,9 @@ class RequestDetailsPage extends StatelessWidget {
padding: EdgeInsets.all(32), padding: EdgeInsets.all(32),
child: AButton( child: AButton(
text: _subtitle.editServiceReport, text: _subtitle.editServiceReport,
onPressed: () { onPressed: serviceRequest.statusValue == 5 || serviceRequest.statusValue == 3
? null
: () {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (_) => FutureServiceReport( builder: (_) => FutureServiceReport(
@ -398,7 +421,9 @@ class RequestDetailsPage extends StatelessWidget {
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: AButton( child: AButton(
text: "Create Work Order", text: "Create Work Order",
onPressed: () { onPressed: serviceRequest.statusValue == 5 || serviceRequest.statusValue == 3
? null
: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest)));
}, },
), ),
@ -421,7 +446,9 @@ class RequestDetailsPage extends StatelessWidget {
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: AButton( child: AButton(
text: "Create Work Order", text: "Create Work Order",
onPressed: () { onPressed: serviceRequest.statusValue == 5 || serviceRequest.statusValue == 3
? null
: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest)));
}, },
), ),
@ -436,7 +463,10 @@ class RequestDetailsPage extends StatelessWidget {
), ),
), ),
], ],
), );
}
return const SizedBox();
}),
), ),
), ),
); );

@ -15,6 +15,7 @@ import 'package:test_sa/views/widgets/search/service_request_search_bar.dart';
class ServiceRequestsPage extends StatefulWidget { class ServiceRequestsPage extends StatefulWidget {
static final String id = "/service-requests"; static final String id = "/service-requests";
@override @override
_ServiceRequestsPageState createState() => _ServiceRequestsPageState(); _ServiceRequestsPageState createState() => _ServiceRequestsPageState();
} }
@ -25,6 +26,7 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerPr
SettingProvider _settingProvider; SettingProvider _settingProvider;
bool _expandedSearch = false; bool _expandedSearch = false;
bool _firstTime = true; bool _firstTime = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);

@ -22,6 +22,7 @@ import '../../../../widgets/pentry/pentry_info_form.dart';
class EditPentry extends StatefulWidget { class EditPentry extends StatefulWidget {
final Pentry pentry; final Pentry pentry;
final Visit visit; final Visit visit;
const EditPentry({Key key, this.pentry, this.visit}) : super(key: key); const EditPentry({Key key, this.pentry, this.visit}) : super(key: key);
@override @override
@ -39,6 +40,7 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _tabController; TabController _tabController;
_onSubmit() async { _onSubmit() async {
_validate = true; _validate = true;
@ -46,10 +48,9 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
setState(() {}); setState(() {});
return; return;
} }
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_pentry.clearEmptyObjects();
int status = await _regularVisitsProvider.updatePentry(user: _userProvider.user, host: _settingProvider.host, pentry: _pentry, visit: widget.visit); int status = await _regularVisitsProvider.updatePentry(user: _userProvider.user, host: _settingProvider.host, pentry: _pentry, visit: widget.visit);
_isLoading = false; _isLoading = false;
setState(() {}); setState(() {});
@ -145,6 +146,7 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
PentryPMKitForm( PentryPMKitForm(
models: _pentry.pmKits, models: _pentry.pmKits,
enableValidate: _validate, enableValidate: _validate,
assetId: widget.visit?.deviceId,
), ),
PentryInfoForm( PentryInfoForm(
model: _pentry, model: _pentry,

@ -21,6 +21,7 @@ import 'package:test_sa/views/widgets/visits/visits_list.dart';
class PreventiveMaintenanceVisitsPage extends StatefulWidget { class PreventiveMaintenanceVisitsPage extends StatefulWidget {
static final String id = "/preventive-maintenance-visits"; static final String id = "/preventive-maintenance-visits";
@override @override
_PreventiveMaintenanceVisitsPageState createState() => _PreventiveMaintenanceVisitsPageState(); _PreventiveMaintenanceVisitsPageState createState() => _PreventiveMaintenanceVisitsPageState();
} }

@ -21,6 +21,7 @@ import 'package:test_sa/views/widgets/visits/visits_list.dart';
class RegularVisitsPage extends StatefulWidget { class RegularVisitsPage extends StatefulWidget {
static final String id = "/Regular-visits"; static final String id = "/Regular-visits";
@override @override
_RegularVisitsPageState createState() => _RegularVisitsPageState(); _RegularVisitsPageState createState() => _RegularVisitsPageState();
} }
@ -31,6 +32,7 @@ class _RegularVisitsPageState extends State<RegularVisitsPage> with TickerProvid
SettingProvider _settingProvider; SettingProvider _settingProvider;
bool _expandedSearch = false; bool _expandedSearch = false;
Subtitle _subtitle; Subtitle _subtitle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_visitsProvider = Provider.of<RegularVisitsProvider>(context); _visitsProvider = Provider.of<RegularVisitsProvider>(context);
@ -105,7 +107,7 @@ class _RegularVisitsPageState extends State<RegularVisitsPage> with TickerProvid
), ),
), ),
Visibility( Visibility(
visible: _visitsProvider.visitsSearch.toMap().isNotEmpty, visible: (_visitsProvider.visitsSearch.toMap()..remove("mostRecent")).isNotEmpty,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: AButton( child: AButton(

@ -1,10 +1,5 @@
import 'package:flutter/material.dart';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart'; import 'package:test_sa/models/visits/visits_group.dart';
@ -18,6 +13,7 @@ import 'package:test_sa/views/widgets/visits/visit_status.dart';
class UpdateVisitsGroupSheet extends StatefulWidget { class UpdateVisitsGroupSheet extends StatefulWidget {
final List<Visit> visits; final List<Visit> visits;
final String title; final String title;
const UpdateVisitsGroupSheet({Key key, this.visits, this.title}) : super(key: key); const UpdateVisitsGroupSheet({Key key, this.visits, this.title}) : super(key: key);
@override @override
@ -36,6 +32,7 @@ class _UpdateVisitsGroupSheetState extends State<UpdateVisitsGroupSheet> {
// Lookup(name: "Failed", id: 1), // Lookup(name: "Failed", id: 1),
// ]; // ];
VisitsGroup _group = VisitsGroup(); VisitsGroup _group = VisitsGroup();
// File _image; // File _image;
Subtitle _subtitle; Subtitle _subtitle;

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
@ -8,25 +9,25 @@ import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/user/visits/pantry/edit_pentry.dart'; import 'package:test_sa/views/pages/user/visits/pantry/edit_pentry.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart'; import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/images/images_list.dart'; import 'package:test_sa/views/widgets/images/images_list.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/visits/visit_status.dart'; import 'package:test_sa/views/widgets/visits/visit_status.dart';
import '../../../../controllers/providers/api/regular_visits_provider.dart';
import '../../../../controllers/providers/api/user_provider.dart'; import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../models/enums/user_types.dart'; import '../../../../models/enums/user_types.dart';
import '../../../widgets/loaders/image_loader.dart';
class VisitDetailsPage extends StatelessWidget { class VisitDetailsPage extends StatelessWidget {
static final String id = "/visit-details"; static const String id = "/visit-details";
final Visit visit; final Visit visit;
const VisitDetailsPage({Key key, this.visit}) : super(key: key); const VisitDetailsPage({Key key, this.visit}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle subtitle = AppLocalization.of(context).subtitle;
final regularVisitsProvider = Provider.of<RegularVisitsProvider>(context); UserProvider userProvider = Provider.of<UserProvider>(context);
UserProvider _userProvider = Provider.of<UserProvider>(context);
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
@ -37,80 +38,87 @@ class VisitDetailsPage extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Row( child: Row(
children: [ children: [
ABackButton(), const ABackButton(),
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
_subtitle.visitInformation, subtitle.visitInformation,
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), style: Theme.of(context).textTheme.titleLarge.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
), ),
), ),
), ),
if (_userProvider?.user?.type == UsersTypes.engineer) if (userProvider?.user?.type == UsersTypes.engineer)
AIconButton( AIconButton(
iconData: Icons.edit, iconData: Icons.edit,
color: AColors.white, color: AColors.white,
buttonSize: 42, buttonSize: 42,
backgroundColor: AColors.green, backgroundColor: AColors.green,
onPressed: () async { onPressed: visit?.status?.name == "Closed" || visit?.status?.name == "Complete"
Navigator.of(context).push(MaterialPageRoute( ? null
: () async {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => EditPentry( builder: (_) => EditPentry(
visit: visit, visit: visit,
pentry: visit.pentry, pentry: visit.pentry,
))); ),
),
);
}, },
), ),
SizedBox(width: 42) const SizedBox(width: 42)
], ],
), ),
), ),
Expanded( Expanded(
child: ListView( child: ListView(
padding: EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
children: [ children: [
SizedBox( const SizedBox(height: 8),
height: 8, // MaterialButton(
), // padding: EdgeInsets.zero,
MaterialButton( // onPressed: () {
padding: EdgeInsets.zero, // if ((visit.images?.isNotEmpty ?? false) && (visit.images?.first?.isNotEmpty ?? false)) {
onPressed: visit.images.isEmpty || (visit.images?.first?.isEmpty ?? false) // Navigator.of(context).push(
? () {} // MaterialPageRoute(
: () { // builder: (_) => Scaffold(
Navigator.of(context).push(MaterialPageRoute( // body: InteractiveViewer(
builder: (_) => Scaffold( // child: Center(
body: InteractiveViewer( // child: ImageLoader(
child: Center( // url: visit.images.first,
child: ImageLoader( // boxFit: BoxFit.contain,
url: visit.images.first, // ),
boxFit: BoxFit.contain, // ),
), // ),
), // ),
), // ),
))); // );
}, // }
child: SizedBox( // },
height: 140 * AppStyle.getScaleFactor(context), // child: SizedBox(
width: MediaQuery.of(context).size.width, // height: 140 * AppStyle.getScaleFactor(context),
child: ImageLoader( // width: MediaQuery.of(context).size.width,
url: visit.images.isEmpty ? " " : visit.images.first, // child: ImageLoader(
boxFit: BoxFit.cover, // url: visit.images.isEmpty ? " " : visit.images.first,
), // boxFit: BoxFit.cover,
), // ),
), // ),
SizedBox( // ),
height: 8, // const SizedBox(
), // height: 8,
// ),
if (visit?.images?.isNotEmpty ?? false)
SizedBox( SizedBox(
height: 60 * AppStyle.getScaleFactor(context), height: 60 * AppStyle.getScaleFactor(context),
child: ImagesList( child: FilesList(
images: visit.images, images: visit.images,
), ),
), ).paddingOnly(top: 4, bottom: 4),
SizedBox( const SizedBox(
height: 8, height: 8,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.code, title: subtitle.code,
info: visit.serialNumber, info: visit.serialNumber,
), ),
RequestInfoRow( RequestInfoRow(
@ -118,23 +126,27 @@ class VisitDetailsPage extends StatelessWidget {
info: visit.deviceNumber, info: visit.deviceNumber,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.deviceSN, title: subtitle.deviceName,
content: visit.deviceEnglishName,
),
RequestInfoRow(
title: subtitle.deviceSN,
info: visit.deviceSerialNumber, info: visit.deviceSerialNumber,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.expectDate, title: subtitle.expectDate,
info: visit.expectDate, info: visit.expectDate,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.actualDate, title: subtitle.actualDate,
info: visit.actualDate, info: visit.actualDate,
), ),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"${_subtitle.status} : ", "${subtitle.status} : ",
style: Theme.of(context).textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.titleMedium.copyWith(fontWeight: FontWeight.bold),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
), ),
@ -147,21 +159,17 @@ class VisitDetailsPage extends StatelessWidget {
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.contactStatus, title: subtitle.contactStatus,
info: visit.assignTo, info: visit.assignTo,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.engineerName, title: subtitle.engineerName,
info: visit.employName, info: visit.employName,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.hospital, title: subtitle.hospital,
content: visit.hospitalName, content: visit.hospitalName,
), ),
RequestInfoRow(
title: _subtitle.deviceName,
content: visit.deviceEnglishName,
),
], ],
), ),
), ),

@ -9,6 +9,7 @@ class AFlatButton extends StatelessWidget {
final VoidCallback onPressed; final VoidCallback onPressed;
const AFlatButton({Key key, this.text, this.textColor, this.style, this.onPressed, this.padding}) : super(key: key); const AFlatButton({Key key, this.text, this.textColor, this.style, this.onPressed, this.padding}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextButton( return TextButton(

@ -9,6 +9,7 @@ class ASmallButton extends StatelessWidget {
final VoidCallback onPressed; final VoidCallback onPressed;
const ASmallButton({Key key, this.text, this.style, this.onPressed, this.padding, this.color}) : super(key: key); const ASmallButton({Key key, this.text, this.style, this.onPressed, this.padding, this.color}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ElevatedButton( return ElevatedButton(

@ -6,8 +6,9 @@ class ADatePicker extends StatelessWidget {
final DateTime from; final DateTime from;
final DateTime to; final DateTime to;
final Function(DateTime) onDatePicker; final Function(DateTime) onDatePicker;
final bool enable;
const ADatePicker({Key key, this.date, this.onDatePicker, this.from, this.to}) : super(key: key); const ADatePicker({Key key, this.date, this.onDatePicker, this.from, this.to, this.enable = true}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -19,14 +20,16 @@ class ADatePicker extends StatelessWidget {
borderRadius: BorderRadius.circular(12 * AppStyle.getScaleFactor(context)), borderRadius: BorderRadius.circular(12 * AppStyle.getScaleFactor(context)),
), ),
), ),
onPressed: enable
? () async {
DateTime picked = await showDatePicker(context: context, initialDate: DateTime.now(), firstDate: from ?? DateTime.now(), lastDate: to ?? DateTime.now().add(Duration(days: 365)));
onDatePicker(picked);
}
: null,
child: Text( child: Text(
date == null ? "Pick Date" : date.toString().split(" ").first, date == null ? "Pick Date" : date.toString().split(" ").first,
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
onPressed: () async {
DateTime picked = await showDatePicker(context: context, initialDate: DateTime.now(), firstDate: from ?? DateTime.now(), lastDate: to ?? DateTime.now().add(Duration(days: 365)));
onDatePicker(picked);
},
); );
} }
} }

@ -12,6 +12,7 @@ class FromToDateBar extends StatefulWidget {
final Function(DateTime) onPickTo; final Function(DateTime) onPickTo;
const FromToDateBar({Key key, this.from, this.to, this.onPickFrom, this.onPickTo}) : super(key: key); const FromToDateBar({Key key, this.from, this.to, this.onPickFrom, this.onPickTo}) : super(key: key);
@override @override
_FromToDateBarState createState() => _FromToDateBarState(); _FromToDateBarState createState() => _FromToDateBarState();
} }

@ -6,8 +6,10 @@ class ADateTimePicker extends StatelessWidget {
final DateTime from; final DateTime from;
final DateTime to; final DateTime to;
final Function(DateTime) onDateTimePicker; final Function(DateTime) onDateTimePicker;
final bool enable;
const ADateTimePicker({Key key, this.date, this.onDateTimePicker, this.from, this.to}) : super(key: key);
const ADateTimePicker({Key key, this.date, this.onDateTimePicker, this.from, this.to, this.enable}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -23,10 +25,10 @@ class ADateTimePicker extends StatelessWidget {
date == null ? "Pick Time" : date.toString().substring(0, date.toString().lastIndexOf(":")), date == null ? "Pick Time" : date.toString().substring(0, date.toString().lastIndexOf(":")),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
onPressed: () async { onPressed: enable? () async {
// TimeOfDay picked = await showTimePicker(context: context, initialTime: TimeOfDay.now()); // TimeOfDay picked = await showTimePicker(context: context, initialTime: TimeOfDay.now());
onDateTimePicker(await showDateTimePicker(context: context, initialDate: date, firstDate: from, lastDate: to)); onDateTimePicker(await showDateTimePicker(context: context, initialDate: date, firstDate: from, lastDate: to));
}, }: null,
); );
} }
} }

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/department.dart'; import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';

@ -8,6 +8,7 @@ class DepartmentItem extends StatelessWidget {
final Function(Department) onPressed; final Function(Department) onPressed;
const DepartmentItem({Key key, this.department, this.onPressed}) : super(key: key); const DepartmentItem({Key key, this.department, this.onPressed}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(

@ -13,6 +13,7 @@ import '../app_text_form_field.dart';
class SingleDepartmentPicker extends StatefulWidget { class SingleDepartmentPicker extends StatefulWidget {
static final String id = "/single-Department-Picker"; static final String id = "/single-Department-Picker";
@override @override
_SingleDepartmentPickerState createState() => _SingleDepartmentPickerState(); _SingleDepartmentPickerState createState() => _SingleDepartmentPickerState();
} }
@ -22,6 +23,7 @@ class _SingleDepartmentPickerState extends State<SingleDepartmentPicker> {
SettingProvider _settingProvider; SettingProvider _settingProvider;
List<Department> _searchableList = []; List<Department> _searchableList = [];
bool _firstTime = true; bool _firstTime = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_departmentsProvider = Provider.of<DepartmentsProvider>(context); _departmentsProvider = Provider.of<DepartmentsProvider>(context);

@ -8,17 +8,19 @@ import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart';
import '../../../controllers/providers/api/user_provider.dart'; import '../../../controllers/providers/api/user_provider.dart';
import '../images/multi_image_picker.dart';
class DeviceTransferInfoSection extends StatelessWidget { class DeviceTransferInfoSection extends StatelessWidget {
final DeviceTransferInfo info; final DeviceTransferInfo info;
final bool isSender;
final VoidCallback onEdit; final VoidCallback onEdit;
const DeviceTransferInfoSection({Key key, this.info, this.onEdit}) : super(key: key); const DeviceTransferInfoSection({Key key, this.info, this.onEdit, this.isSender}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
info.userName = Provider.of<UserProvider>(context).user.username; info.userName = Provider.of<UserProvider>(context).user.username;
final subtitle = AppLocalization.of(context).subtitle; final subtitle = AppLocalization.of(context).subtitle;
print("url:${info.signature}"); info.attachments ??= [];
return Column( return Column(
children: [ children: [
RequestInfoRow( RequestInfoRow(
@ -29,10 +31,10 @@ class DeviceTransferInfoSection extends StatelessWidget {
title: subtitle.department, title: subtitle.department,
info: info.department.name, info: info.department.name,
), ),
RequestInfoRow( // RequestInfoRow(
title: subtitle.engineerName, // title: isSender ? "Sender Name " : "Receiver Name",
info: info.userName, // info: info.userName,
), // ),
RequestInfoRow( RequestInfoRow(
title: subtitle.workingHours, title: subtitle.workingHours,
info: info.workingHours, info: info.workingHours,
@ -46,16 +48,20 @@ class DeviceTransferInfoSection extends StatelessWidget {
info: info.comment, info: info.comment,
), ),
RequestInfoRow( RequestInfoRow(
title: "Assigned FE", title: "Assigned Engineer",
info: info.assignedEmployeeName, info: info.assignedEmployeeName,
), ),
RequestInfoRow( RequestInfoRow(
title: "Signature", title: "Signature",
info: info.signature?.isEmpty != false ? subtitle.noDateFound : null, info: info.engSignature?.isEmpty != false ? subtitle.noDateFound : null,
contentWidget: info.signature?.isEmpty != false contentWidget: info.engSignature?.isEmpty != false ? null : ImageLoader(url: info.engSignature),
? null ),
: ImageLoader( Padding(
url: info.signature, padding: const EdgeInsets.symmetric(vertical: 16),
child: MultiFilesPicker(
label: "Attachments",
files: info.attachments,
enabled: false,
), ),
), ),
RequestInfoRow( RequestInfoRow(

@ -16,7 +16,7 @@ class DeviceTransferList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (items.length == 0) { if (items.isEmpty) {
Subtitle subtitle = AppLocalization.of(context).subtitle; Subtitle subtitle = AppLocalization.of(context).subtitle;
return NoItemFound( return NoItemFound(
message: subtitle.noServiceRequestFound, message: subtitle.noServiceRequestFound,
@ -33,11 +33,8 @@ class DeviceTransferList extends StatelessWidget {
return DeviceTransferItem( return DeviceTransferItem(
index: itemIndex, index: itemIndex,
item: items[itemIndex], item: items[itemIndex],
onPressed: (model) { onPressed: (model) async {
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: model)));
builder: (_) => DeviceTransferDetails(
model: model,
)));
}, },
); );
}), }),

@ -56,6 +56,20 @@ class DeviceButton extends StatelessWidget {
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),
Text(
"${_subtitle.assetNumber} : ${device.number}",
style: Theme.of(context).textTheme.subtitle2,
),
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),
Text(
"${_subtitle.assetName} : ${device.modelDefinition.assetName}",
style: Theme.of(context).textTheme.subtitle2,
),
Divider( Divider(
color: Theme.of(context).textTheme.subtitle1.color, color: Theme.of(context).textTheme.subtitle1.color,
), ),

@ -10,6 +10,7 @@ class DeviceItem extends StatelessWidget {
final Function(Device) onPressed; final Function(Device) onPressed;
const DeviceItem({Key key, this.device, this.onPressed}) : super(key: key); const DeviceItem({Key key, this.device, this.onPressed}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context).subtitle;

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart'; import 'package:test_sa/controllers/providers/api/devices_provider.dart';
@ -18,6 +17,7 @@ import '../qr/scan_qr.dart';
class SingleDevicePicker extends StatefulWidget { class SingleDevicePicker extends StatefulWidget {
static final String id = "/single-device-Picker"; static final String id = "/single-device-Picker";
final bool sandraChoice = true; final bool sandraChoice = true;
@override @override
_SingleDevicePickerState createState() => _SingleDevicePickerState(); _SingleDevicePickerState createState() => _SingleDevicePickerState();
} }
@ -33,12 +33,19 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
TextEditingController numberController = TextEditingController(); TextEditingController numberController = TextEditingController();
TextEditingController snController = TextEditingController(); TextEditingController snController = TextEditingController();
_getDevice(String result) async {
print(result); _getDevice(String result, {bool isQr = false}) async {
if (result == null) return; if (result == null) return;
// List<Device> devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result); // List<Device> devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result);
_devicesProvider.reset(); _devicesProvider.reset();
await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: "", number: result); await _devicesProvider.getEquipment(
user: _userProvider.user,
host: _settingProvider.host,
hospitalId: _userProvider.user.clientId,
serialNumber: "",
number: result,
isQr: isQr,
);
_searchableList.clear(); _searchableList.clear();
_searchableList.addAll(_devicesProvider.devices); _searchableList.addAll(_devicesProvider.devices);
// Navigator.of(context).pop(); // Navigator.of(context).pop();
@ -163,7 +170,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
String result = await Navigator.of(context).push( String result = await Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const ScanQr()), MaterialPageRoute(builder: (_) => const ScanQr()),
) as String; ) as String;
_getDevice(result); _getDevice(result, isQr: true);
}, },
), ),
); );

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save