Compare commits

...

79 Commits

Author SHA1 Message Date
Sikander Saleem 7350184656 Merge branch 'zaid-development' into 'master'
Zaid development

See merge request haroon6138/cloudsolutions-atoms!21
3 years ago
zaid_daoud af99b1cc44 Merge branch 'master' into zaid-development 3 years ago
Sikander Saleem bb1613d744 Merge branch 'majd_development' into 'master'
changed to new apis

See merge request haroon6138/cloudsolutions-atoms!20
3 years ago
nextwo bcf5ece25f changed to new apis 3 years ago
zaid_daoud fe9b8215d3 Enhancements 3 years ago
nextwo 4c3caf9340 changed to new apis 3 years ago
zaid_daoud f90df43023 Merge master into my work 3 years ago
Sikander Saleem c79ac5e5b3 Merge branch 'majd_development' into 'master'
Majd development

See merge request haroon6138/cloudsolutions-atoms!18
3 years ago
nextwo 1fd3488b3d Merge branch 'master' into majd_development 3 years ago
nextwo 6c792cbced changed to new apis 3 years ago
Sikander Saleem 7289cfb05d put & delete method added. 3 years ago
nextwo d2cf147acd changed to new apis 3 years ago
nextwo a3439c3192 Merge branch 'main' into majd_development
# Conflicts:
#	lib/controllers/api_routes/urls.dart
#	pubspec.lock
3 years ago
nextwo 5201f5789e changed to new apis 3 years ago
nextwo 42028f14fd changed to new apis 3 years ago
Sikander Saleem e589c7a181 Merge remote-tracking branch 'origin/master' 3 years ago
Sikander Saleem 88a16c3175 Merge branch 'zaid-development' into 'master'
Changing Login API & user model

See merge request haroon6138/cloudsolutions-atoms!17
3 years ago
zaid_daoud c96d401630 Fixing parsing issue in User model 3 years ago
zaid_daoud 1a3232dbe1 Changing User Model 3 years ago
Sikander Saleem 04c1624f18 temp changes 3 years ago
zaid_daoud b8e253e685 Changing The API's 3 years ago
Sikander Saleem fe468aa254 Merge branch 'majd_development' into 'master'
Majd development

See merge request haroon6138/cloudsolutions-atoms!16
3 years ago
nextwo 6ad1f909bf format code 3 years ago
nextwo 55245403d3 Merge branch 'master' into majd_development 3 years ago
nextwo b3eeefd1e5 Merge remote-tracking branch 'origin/majd_development' into majd_development 3 years ago
Sikander Saleem 4d5944cbdd Merge branch 'majd_development' into 'master'
Majd development

See merge request haroon6138/cloudsolutions-atoms!15
3 years ago
nextwo 32acdb8537 Merge branch 'master' into majd_development 3 years ago
Sikander Saleem b2e721a8c5 Merge branch 'zaid-development' into 'master'
Track Service Request DONE

See merge request haroon6138/cloudsolutions-atoms!14
3 years ago
nextwo 7e808e5bf4 Merge branch 'master' into majd_development
# Conflicts:
#	lib/controllers/providers/api/devices_provider.dart
#	lib/views/widgets/equipment/auto_complete_devices_field.dart
3 years ago
majd alattari 53185976da Merge branch 'master' into 'majd_development'
# Conflicts:
#   lib/controllers/providers/api/devices_provider.dart
#   lib/views/widgets/equipment/auto_complete_devices_field.dart
3 years ago
nextwo 9b7c8827e3 change structure of Track device transfer page 3 years ago
nextwo fd160ca0b7 solve the problem of missing some data in track gas refill screen 3 years ago
nextwo 198dc95814 change the structure of Track Gas Refill and Transfer Device (point 2 & 3) 3 years ago
zaid_daoud 3a20bf0017 Track Service Filter DONE && Preventive Maintenance DONE 3 years ago
zaid_daoud 802ec7bb01 Track Service Request DONE 4 years ago
Sikander Saleem 408eb92063 Merge branch 'majd_development' into 'master'
change Api structure for request gas refill page + solve null safety bugs...

See merge request haroon6138/cloudsolutions-atoms!13
4 years ago
Sikander Saleem d8a1a982bf Merge branch 'zaid-development' into 'master'
New Service Request is DONE

See merge request haroon6138/cloudsolutions-atoms!12
4 years ago
nextwo 1e06449d8d change Api structure for request gas refill page + solve null safety bugs faced it during restructure the code 4 years ago
zaid_daoud 5f78d7e164 get device list & get device list by serial number 4 years ago
zaid_daoud b65158322c New Service Request is DONE
and The Major Changes happened in these files :
 - devices_api_client.dart
 - service_request_api_client.dart
 - devices_provider.dart
4 years ago
zaid_daoud 03379393b5 New Service Request is DONE
and The Major Changes happened in these files :
 - devices_api_client.dart
 - devices_provider.dart
4 years ago
Sikander Saleem 7b31efc2ab Merge branch 'zaid-development' into 'master'
Recoding Login Task & Upgrade Flutter Version

See merge request haroon6138/cloudsolutions-atoms!11
4 years ago
zaid_daoud 1a2b53d8bb Change login_api_client.dart name 4 years ago
zaid_daoud 5b193b1c86 - Change a comment 4 years ago
zaid_daoud 05faf47913 - Change a comment 4 years ago
zaid_daoud 1ef45711af - Creating Api Client Class and Loading Notifier Class [Fully Documented].
- Recoding Login & Register & Update Profile.
- Reformat the lib folder on Dart Format (200 char on each line).
4 years ago
Sikander Saleem 942fa0f0ba Merge branch 'majd_development' into 'master'
null safety

See merge request haroon6138/cloudsolutions-atoms!10
4 years ago
nextwo 9afe7e7ec6 null safety 4 years ago
Sikander Saleem 0ee51298e3 Merge branch 'majd_development' into 'master'
Majd development

See merge request haroon6138/cloudsolutions-atoms!9
4 years ago
nextwo 0a79df11db null safety 4 years ago
nextwo 0e12265f84 null safety 4 years ago
Sikander Saleem af5726fe38 Merge branch 'zaid-development' into 'master'
Preventive Maintenance Screen

See merge request haroon6138/cloudsolutions-atoms!8
4 years ago
zaid_daoud 76969ea01b EditPentry Screen & It's Pages 4 years ago
zaid_daoud 0e87b0fbf9 Preventive Maintenance Screen 4 years ago
Sikander Saleem 095dbc86ad Merge branch 'majd_development' into 'master'
null safety

See merge request haroon6138/cloudsolutions-atoms!7
4 years ago
Sikander Saleem 4100950a42 Merge branch 'master' into 'majd_development'
# Conflicts:
#   lib/views/widgets/loaders/loading_manager.dart
4 years ago
Sikander Saleem 4eef9775c5 Merge branch 'zaid-development' into 'master'
Fixing New Service Screen

See merge request haroon6138/cloudsolutions-atoms!6
4 years ago
nextwo 157761c361 null safety 4 years ago
zaid_daoud ca3c93ad6e New Service Screen 4 years ago
Sikander Saleem 6a63025ee9 Merge branch 'majd_development' into 'master'
Majd development

See merge request haroon6138/cloudsolutions-atoms!5
4 years ago
Sikander Saleem 4484a63955 Merge branch 'zaid-development' into 'master'
Zaid development - Retrieve The Previous Structure and Applying Null-Safety

See merge request haroon6138/cloudsolutions-atoms!4
4 years ago
nextwo 4a79708a9f null safety 4 years ago
zaid_daoud 8d54c44118 Create Request Screen 4 years ago
zaid_daoud d8252529ce Engineer : Track Service Screen & Preventive Maintenance Screen & Notifications Screen 4 years ago
zaid_daoud e88c88ef4e Arguments datatype -> null safety 4 years ago
zaid_daoud c1a3eedbf6 Revert the project to the previous structure with applying null safety 4 years ago
zaid_daoud d9d26a0fe0 Revert the project to the previous structure with applying null safety 4 years ago
zaid_daoud cd4ff9e3a0 Revert the project to the previous structure with applying null safety 4 years ago
Sikander Saleem f4aef79fa7 Merge branch 'zaid-development' into 'master'
Restructuring Project Files & Supporting Null Safety

See merge request haroon6138/cloudsolutions-atoms!3
4 years ago
nextwo 82e3005e85 support null safety 4 4 years ago
nextwo f926951125 Merge remote-tracking branch 'origin/restructuring' into support_null_safety
# Conflicts:
#	old_lib/controllers/http_status_manger/http_status_manger.dart
#	old_lib/controllers/providers/api/service_requests_provider.dart
#	old_lib/models/visits/visits_search.dart
#	old_lib/views/widgets/app_text_form_field.dart
#	old_lib/views/widgets/buttons/app_small_button.dart
#	old_lib/views/widgets/date_and_time/from_to_date_bar.dart
#	old_lib/views/widgets/loaders/loading_manager.dart
#	old_lib/views/widgets/loaders/no_item_found.dart
#	old_lib/views/widgets/sound/record_sound.dart
#	old_lib/views/widgets/status/report/service_report_last_call.dart
#	old_lib/views/widgets/titles/app_sub_title.dart
4 years ago
omar alqaseer 429c8136ee Null Safety - Widgets Folder 4 years ago
nextwo 33a2e2127d support null safety 3 4 years ago
nextwo 5644ccad7c support null safety 2 4 years ago
nextwo 7fb78685ac Merge remote-tracking branch 'origin/restructuring' into support_null_safety 4 years ago
nextwo bb6dd618fc support null safety 1 4 years ago
Zaid-daoud b906ca60e6 - Null Safety 4 years ago
Zaid-daoud 216aabaf8a - Restructuring Project Files
- Creating ApiClient class
4 years ago
Zaid-daoud a2ce99fbae - Restructuring Project Files
- Creating ApiClient class
4 years ago

@ -38,8 +38,8 @@ android {
ndkVersion flutter.ndkVersion ndkVersion flutter.ndkVersion
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_11
} }
defaultConfig { defaultConfig {
@ -71,6 +71,7 @@ android {
signingConfig signingConfigs.release signingConfig signingConfigs.release
} }
} }
namespace 'com.example.test_sa'
} }
flutter { flutter {

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.example.test_sa">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.example.test_sa">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.

@ -1,12 +1,12 @@
buildscript { buildscript {
ext.kotlin_version = '1.6.10' ext.kotlin_version = '1.6.21'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.1.2' classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'com.google.gms:google-services:4.3.13' classpath 'com.google.gms:google-services:4.3.13'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

@ -6,10 +6,10 @@ PODS:
- Firebase/Messaging (10.3.0): - Firebase/Messaging (10.3.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseMessaging (~> 10.3.0) - FirebaseMessaging (~> 10.3.0)
- firebase_core (2.4.1): - firebase_core (2.6.1):
- Firebase/CoreOnly (= 10.3.0) - Firebase/CoreOnly (= 10.3.0)
- Flutter - Flutter
- firebase_messaging (14.2.1): - firebase_messaging (14.2.4):
- Firebase/Messaging (= 10.3.0) - Firebase/Messaging (= 10.3.0)
- firebase_core - firebase_core
- Flutter - Flutter
@ -79,8 +79,9 @@ PODS:
- nanopb/encode (2.30909.0) - nanopb/encode (2.30909.0)
- package_info (0.0.1): - package_info (0.0.1):
- Flutter - Flutter
- path_provider_ios (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS
- permission_handler_apple (9.0.4): - permission_handler_apple (9.0.4):
- Flutter - Flutter
- PromisesObjC (2.1.1) - PromisesObjC (2.1.1)
@ -89,8 +90,9 @@ PODS:
- MTBBarcodeScanner - MTBBarcodeScanner
- share (0.0.1): - share (0.0.1):
- Flutter - Flutter
- shared_preferences_ios (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS
- speech_to_text (0.0.1): - speech_to_text (0.0.1):
- Flutter - Flutter
- Try - Try
@ -113,11 +115,11 @@ DEPENDENCIES:
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`) - qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
- share (from `.symlinks/plugins/share/ios`) - share (from `.symlinks/plugins/share/ios`)
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
- speech_to_text (from `.symlinks/plugins/speech_to_text/ios`) - speech_to_text (from `.symlinks/plugins/speech_to_text/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@ -160,16 +162,16 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/image_picker_ios/ios" :path: ".symlinks/plugins/image_picker_ios/ios"
package_info: package_info:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info/ios"
path_provider_ios: path_provider_foundation:
:path: ".symlinks/plugins/path_provider_ios/ios" :path: ".symlinks/plugins/path_provider_foundation/ios"
permission_handler_apple: permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios" :path: ".symlinks/plugins/permission_handler_apple/ios"
qr_code_scanner: qr_code_scanner:
:path: ".symlinks/plugins/qr_code_scanner/ios" :path: ".symlinks/plugins/qr_code_scanner/ios"
share: share:
:path: ".symlinks/plugins/share/ios" :path: ".symlinks/plugins/share/ios"
shared_preferences_ios: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_ios/ios" :path: ".symlinks/plugins/shared_preferences_foundation/ios"
speech_to_text: speech_to_text:
:path: ".symlinks/plugins/speech_to_text/ios" :path: ".symlinks/plugins/speech_to_text/ios"
sqflite: sqflite:
@ -180,8 +182,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40
Firebase: f92fc551ead69c94168d36c2b26188263860acd9 Firebase: f92fc551ead69c94168d36c2b26188263860acd9
firebase_core: bf59c32d2e53814f558efa20840c1902fa2fe461 firebase_core: 6242f038aefa4582e028536e71312f7e3a41e6bb
firebase_messaging: ee597229fc260f8fa491fa8f2d4a32dfbfa406fa firebase_messaging: ee61b8065c395a117864224e3031729e656232af
FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b
FirebaseInstallations: e2f26126089dcf41e215f7b8925af8d953c7d602 FirebaseInstallations: e2f26126089dcf41e215f7b8925af8d953c7d602
@ -199,17 +201,17 @@ SPEC CHECKSUMS:
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
share: 0b2c3e82132f5888bccca3351c504d0003b3b410 share: 0b2c3e82132f5888bccca3351c504d0003b3b410
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca
speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96 Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de url_launcher_ios: fb12c43172927bb5cf75aeebd073f883801f1993
PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 51; objectVersion = 54;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -227,6 +227,7 @@
}; };
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -258,6 +259,7 @@
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );

@ -60,5 +60,7 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict> </dict>
</plist> </plist>

@ -0,0 +1,404 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import '../exceptions/api_exception.dart';
typedef FactoryConstructor<U> = U Function(dynamic);
class APIError {
int? errorCode;
String? errorMessage;
APIError(this.errorCode, this.errorMessage);
Map<String, dynamic> toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage};
@override
String toString() {
return jsonEncode(this);
}
}
APIException _throwAPIException(Response response) {
print(response.statusCode);
switch (response.statusCode) {
case 200:
APIError? apiError;
if (response.body.isNotEmpty) {
var jsonError = jsonDecode(response.body);
debugPrint(jsonError);
apiError = APIError(response.statusCode, jsonError[0]);
}
return APIException(APIException.BAD_REQUEST, error: apiError);
case 400:
APIError? apiError;
if (response.body.isNotEmpty) {
var jsonError = jsonDecode(response.body);
debugPrint("json error : $jsonError");
apiError = APIError(response.statusCode, jsonError[0]);
}
return APIException(APIException.BAD_REQUEST, error: apiError);
case 401:
return const APIException(APIException.UNAUTHORIZED);
case 403:
return const APIException(APIException.FORBIDDEN);
case 404:
return const APIException(APIException.NOT_FOUND);
case 500:
return const APIException(APIException.INTERNAL_SERVER_ERROR);
case 444:
var downloadUrl = response.headers["location"];
return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl);
default:
return const APIException(APIException.OTHER);
}
}
class ApiClient {
static final ApiClient _instance = ApiClient._internal();
ApiClient._internal();
factory ApiClient() => _instance;
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false}) async {
var defaultHeaders = {'Accept': 'application/json'};
if (headers != null && headers.isNotEmpty) {
defaultHeaders.addAll(headers);
}
if (!kReleaseMode) {
debugPrint("Url:$url");
var bodyJson = json.encode(jsonObject);
debugPrint("body:$bodyJson");
}
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes, isFormData: isFormData);
try {
var jsonData = jsonDecode(response.body);
if (jsonData != null) {
debugPrint(jsonData.runtimeType.toString());
return factoryConstructor(jsonData);
} else {
APIError? apiError;
apiError = APIError(response.statusCode, jsonData[0]);
throw APIException(APIException.BAD_REQUEST, error: apiError);
}
} catch (ex) {
if (ex is APIException) {
rethrow;
} else {
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
}
}
}
Future<U> putJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false}) async {
var defaultHeaders = {'Accept': 'application/json'};
if (headers != null && headers.isNotEmpty) {
defaultHeaders.addAll(headers);
}
if (!kReleaseMode) {
debugPrint("Url:$url");
var bodyJson = json.encode(jsonObject);
debugPrint("body:$bodyJson");
}
var response = await putJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes, isFormData: isFormData);
try {
var jsonData = jsonDecode(response.body);
if (jsonData != null) {
debugPrint(jsonData.runtimeType.toString());
return factoryConstructor(jsonData);
} else {
APIError? apiError;
apiError = APIError(response.statusCode, jsonData[0]);
throw APIException(APIException.BAD_REQUEST, error: apiError);
}
} catch (ex) {
if (ex is APIException) {
rethrow;
} else {
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
}
}
}
Future<Response> postJsonForResponse<T>(String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false}) async {
int currentRetryTime = retryTimes;
String? requestBody;
late Map<String, String> stringObj;
if (jsonObject != null) {
requestBody = jsonEncode(jsonObject);
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
}
if (!kReleaseMode) {
print("url:$url");
print("requestBody:$requestBody");
}
if (isFormData) {
headers = {'Content-Type': 'application/x-www-form-urlencoded'};
stringObj = ((jsonObject ?? {}) as Map<String, dynamic>).map((key, value) => MapEntry(key, value?.toString() ?? ""));
}
if (!kReleaseMode) {
print("url:$url");
print("requestBody:$requestBody");
}
Future<Response> retry(APIException exception) async {
if (currentRetryTime > 0) {
currentRetryTime -= 1;
debugPrint('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers);
} else {
throw exception;
}
}
try {
return await _postForResponse(url, isFormData ? stringObj : requestBody, token: token, queryParameters: queryParameters, headers: headers);
} on SocketException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on HttpException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on TimeoutException catch (e) {
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
}
}
Future<Response> putJsonForResponse<T>(String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = true}) async {
int currentRetryTime = retryTimes;
String? requestBody;
late Map<String, String> stringObj;
if (jsonObject != null) {
requestBody = jsonEncode(jsonObject);
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
}
if (!kReleaseMode) {
print(jsonObject);
}
if (isFormData) {
headers = {'Content-Type': 'application/x-www-form-urlencoded'};
stringObj = ((jsonObject ?? {}) as Map<String, dynamic>).map((key, value) => MapEntry(key, value?.toString() ?? ""));
}
if (!kReleaseMode) {
print("url:$url");
print("requestBody:$requestBody");
}
Future<Response> retry(APIException exception) async {
if (currentRetryTime > 0) {
currentRetryTime -= 1;
debugPrint('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3));
return await _putForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers);
} else {
throw exception;
}
}
try {
return await _postForResponse(url, isFormData ? stringObj : requestBody, token: token, queryParameters: queryParameters, headers: headers);
} on SocketException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on HttpException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on TimeoutException catch (e) {
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
}
}
Future<Response> _postForResponse(String url, requestBody, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers}) async {
var defaultHeaders = <String, String>{};
if (token != null) {
defaultHeaders['Authorization'] = 'Bearer $token';
}
if (headers != null && headers.isNotEmpty) {
defaultHeaders.addAll(headers);
}
if (queryParameters != null) {
var queryString = Uri(queryParameters: queryParameters).query;
url = '$url?$queryString';
}
var response = await _post(Uri.parse(url), body: requestBody, headers: defaultHeaders).timeout(const Duration(seconds: 120));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
} else {
throw _throwAPIException(response);
}
}
Future<Response> _putForResponse(String url, requestBody, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers}) async {
var defaultHeaders = <String, String>{};
if (token != null) {
defaultHeaders['Authorization'] = 'Bearer $token';
}
if (headers != null && headers.isNotEmpty) {
defaultHeaders.addAll(headers);
}
if (queryParameters != null) {
var queryString = Uri(queryParameters: queryParameters).query;
url = '$url?$queryString';
}
var response = await _put(Uri.parse(url), body: requestBody, headers: defaultHeaders).timeout(const Duration(seconds: 120));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
} else {
throw _throwAPIException(response);
}
}
Future<Response> _deleteForResponse(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers}) async {
var defaultHeaders = <String, String>{};
if (token != null) {
defaultHeaders['Authorization'] = 'Bearer $token';
}
if (headers != null && headers.isNotEmpty) {
defaultHeaders.addAll(headers);
}
if (queryParameters != null) {
var queryString = Uri(queryParameters: queryParameters).query;
url = '$url?$queryString';
}
var response = await _delete(Uri.parse(url), headers: defaultHeaders).timeout(const Duration(seconds: 60));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
} else {
throw _throwAPIException(response);
}
}
Future<Response> getJsonForResponse<T>(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
int currentRetryTime = retryTimes;
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
Future<Response> retry(APIException exception) async {
if (currentRetryTime > 0) {
currentRetryTime -= 1;
debugPrint('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3));
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers);
} else {
throw exception;
}
}
try {
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers);
} on SocketException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on HttpException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on TimeoutException catch (e) {
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
}
}
Future<Response> deleteJsonForResponse<T>(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
int currentRetryTime = retryTimes;
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
Future<Response> retry(APIException exception) async {
if (currentRetryTime > 0) {
currentRetryTime -= 1;
debugPrint('will retry after 3 seconds...');
await Future.delayed(const Duration(seconds: 3));
return await _deleteForResponse(url, token: token, queryParameters: queryParameters, headers: headers);
} else {
throw exception;
}
}
try {
return await _deleteForResponse(url, token: token, queryParameters: queryParameters, headers: headers);
} on SocketException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on HttpException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
} on TimeoutException catch (e) {
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
return await retry(APIException(APIException.OTHER, arguments: e));
}
}
Future<Response> _getForResponse(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers}) async {
var defaultHeaders = <String, String>{};
if (token != null) {
defaultHeaders['Authorization'] = 'Bearer $token';
}
if (headers != null && headers.isNotEmpty) {
defaultHeaders.addAll(headers);
}
if (queryParameters != null) {
var queryString = Uri(queryParameters: queryParameters).query;
url = '$url?$queryString';
}
var response = await _get(Uri.parse(url), headers: defaultHeaders).timeout(const Duration(seconds: 60));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
} else {
throw _throwAPIException(response);
}
}
Future<Response> _get(url, {Map<String, String>? headers}) => _withClient((client) => client.get(url, headers: headers));
bool _certificateCheck(X509Certificate cert, String host, int port) => true;
Future<T> _withClient<T>(Future<T> Function(Client) fn) async {
var httpClient = HttpClient()..badCertificateCallback = _certificateCheck;
var client = IOClient(httpClient);
try {
return await fn(client);
} finally {
client.close();
}
}
Future<Response> _post(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
Future<Response> _put(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.put(url, headers: headers, body: body, encoding: encoding));
Future<Response> _delete(url, {Map<String, String>? headers}) => _withClient((client) => client.delete(url, headers: headers));
}

@ -0,0 +1,27 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import '../models/department.dart';
class DepartmentsApiClient{
static final DepartmentsApiClient _instance = DepartmentsApiClient._internal();
DepartmentsApiClient._internal();
factory DepartmentsApiClient() => _instance;
Future getDepartment() async {
Response response;
response = await ApiClient().postJsonForResponse(
URLs.host1 + URLs.getDepartments,
{},
isFormData: false
);
Map listJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
return listJson['data'].map<Department>((department) => Department.fromJson(department)).toList();
}
}

@ -0,0 +1,71 @@
import 'dart:convert';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/api/user_api_client.dart';
import '../controllers/api_routes/urls.dart';
import '../models/device/device_transfer.dart';
import '../models/device/device_transfer_info.dart';
class DeviceTransferApiClient {
static final DeviceTransferApiClient _instance = DeviceTransferApiClient._internal();
DeviceTransferApiClient._internal();
factory DeviceTransferApiClient() => _instance;
Future<List<DeviceTransfer>> getRequests({required List items, required int pageItemNumber}) async {
Map<String, dynamic> body= {
"pageSize": "${(items.length) ~/ pageItemNumber}",
};
final response = await ApiClient().postJsonForResponse(
"${URLs.host1}${URLs.getDeviceTransfer}",
body,
isFormData: false
);
Map listJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
print(listJson);
return listJson['data'].map<DeviceTransfer>((request) => DeviceTransfer.fromJson(request)).toList();
}
Future<DeviceTransfer> createRequest({
required DeviceTransfer model,
}) async {
Map<String, dynamic> body = {
"id": model.id??0,
"assetId": model.device?.id,
"destSiteId":model.receiver?.client?.id,
"senderSiteId":model.sender?.userId,
"receiverAssignedEmployeeId": model.receiver?.userId
};
print(body);
final response = await ApiClient().postJsonForResponse("${URLs.host1}${URLs.requestDeviceTransfer}", body, isFormData: false);
return DeviceTransfer.fromJson(json.decode(utf8.decode(response.bodyBytes))[0]);
}
Future<DeviceTransfer> updateRequest({
required bool isSender,
required String requestId,
required DeviceTransfer oldModel,
required DeviceTransferInfo newModel,
}) async {
Map<String, dynamic> body = {
"id": oldModel.id??0,
"assetId": oldModel.device?.id,
"destSiteId":oldModel.receiver?.client?.id,
"senderSiteId":oldModel.sender?.userId,
"receiverAssignedEmployeeId": oldModel.receiver?.userId
};
body.addAll(newModel.toJson(isSender));
final response = await ApiClient().putJsonForResponse("${URLs.host1}${URLs.updateDeviceTransfer}", body);
return DeviceTransfer.fromJson(json.decode(utf8.decode(response.bodyBytes))[0]);
}
}

@ -0,0 +1,62 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:test_sa/models/device/device.dart';
import '../controllers/api_routes/urls.dart';
import 'api_client.dart';
class DevicesApiClient {
static final DevicesApiClient _instance = DevicesApiClient._internal();
final List<Device> devices = [];
DevicesApiClient._internal();
factory DevicesApiClient() => _instance;
/// Fetch devices by [hospitalId] and insert the result into [devices] list
Future getEquipment(String hospitalId) async {
final response = await ApiClient().postJsonForResponse(
URLs.host1 + URLs.getEquipment,
{'client': hospitalId},
isFormData: false
);
Map equipmentListJson = json.decode(utf8.decode(response.bodyBytes));
print(equipmentListJson);
devices.clear();
devices.addAll(equipmentListJson['data'] != null ? equipmentListJson['data'].map<Device>((device) => Device.fromJson(device)).toList(): []);
debugPrint("devices : ${devices.length}");
}
/// Returns a list of devices by [hospitalId] and [serialNumber] (or | and) [number]
Future<List<Device>> getDevicesList({required String hospitalId, String? serialNumber, String? number}) async {
final response = await ApiClient().postJsonForResponse(
URLs.host1 + URLs.getEquipment,
{
'client': hospitalId,
if (serialNumber?.isEmpty == false) 'name': serialNumber,
if (number?.isEmpty == false) 'number': number,
},
isFormData: false
);
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
return categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
/// Returns a list of devices by [hospitalId] (and optionally) [serialNumber]
Future<List<Device>> getDevicesListBySN({required String hospitalId, required String serialNumber}) async {
final response = await ApiClient().postJsonForResponse(
URLs.host1 + URLs.getEquipment,
{
'client': hospitalId,
if (serialNumber.isNotEmpty) 'serial_qr': serialNumber,
},
isFormData: false
);
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
return categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
}

@ -0,0 +1,149 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/api/user_api_client.dart';
import '../controllers/api_routes/urls.dart';
import '../models/gas_refill/gas_refill_model.dart';
import 'api_client.dart';
class GasRefillApiClient {
static final GasRefillApiClient _instance = GasRefillApiClient._internal();
GasRefillApiClient._internal();
factory GasRefillApiClient() => _instance;
// todo @majd there is a method postJsonForObject, use this, rather then postJsonForResponse
Future<List<GasRefillModel>> getRequestPages({required List items, required int pageItemNumber}) async {
Map<String, dynamic> body = {
"uid": "${UserApiClient().user?.id}",
"token": "${UserApiClient().user?.token}",
"pageSize": "${(items.length) ~/ pageItemNumber}",
};
final response = await ApiClient().postJsonForResponse(
"${URLs.host1}${URLs.getGasRefill}",
body,
isFormData: false,
);
// client's request was successfully received
var requestsListJson = json.decode(utf8.decode(response.bodyBytes));
print(requestsListJson);
return requestsListJson['data'].map<GasRefillModel>((request) => GasRefillModel.fromJson(request)).toList();
}
Future<GasRefillModel> createModel({
required GasRefillModel model,
}) async {
Map<String, dynamic> body = {
"gazRefillNo": await generateGazRefillNo(),
"assignedEmployee": {
"id": UserApiClient().user?.id.toString(),
"name": UserApiClient().user?.username.toString()
},
"status": {
"id": 0,
"name": "",
"value": 0
},
};
body["gazRefillDetails"] = model.details
?.map((model) => {
"gasType": {
"id": model.type?.id,
"name": model.type?.label.toString(),
"value": model.type?.id
},
"cylinderType": {
"id": 0,
"name": "",
"value": 0
},
"cylinderSize": {
"id": model.cylinderSize?.id,
"name": model.cylinderSize?.label.toString(),
"value": model.cylinderSize?.id,
},
"requestedQty": model.requestedQuantity,
"deliverdQty": 0
})
.toList();
print(body);
final response = await ApiClient().postJsonForResponse(
"${URLs.host1}${URLs.requestGasRefill}",
body,
isFormData: false
);
return GasRefillModel.fromJson(json.decode(utf8.decode(response.bodyBytes))[0]);
}
Future updateModel({
required GasRefillModel? oldModel,
required GasRefillModel newModel,
}) async {
Map<String, dynamic> body = {
"id": oldModel?.id,
"gazRefillNo": await generateGazRefillNo(),
"assignedEmployee": {
"id": UserApiClient().user?.id.toString(),
"name": UserApiClient().user?.username.toString()
},
"status": {
"id": 0,
"name": "",
"value": 0
},
};
body["gazRefillDetails"] = newModel.details
?.map((model) => {
"gasType": {
"id": model.type?.id,
"name": model.type?.label.toString(),
"value": model.type?.id
},
"cylinderType": {
"id": 0,
"name": "",
"value": 0
},
"cylinderSize": {
"id": model.cylinderSize?.id,
"name": model.cylinderSize?.label.toString(),
"value": model.cylinderSize?.id,
},
"requestedQty": model.requestedQuantity,
"deliverdQty": 0
})
.toList();
final reponse = await ApiClient().putJsonForResponse("${URLs.host1}${URLs.updateGasRefill}/${newModel.id}", body);
oldModel?.fromGasRefillModel(newModel);
}
Future<String> generateGazRefillNo() async {
final reponse = await ApiClient().getJsonForResponse("${URLs.host1}${URLs.generateGazRefillNo}");
var data = json.decode(reponse.body);
return data['data'];
}
}

@ -0,0 +1,25 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import '../models/lookup.dart';
class GasTypesApiClient{
static final GasTypesApiClient _instance = GasTypesApiClient._internal();
GasTypesApiClient._internal();
factory GasTypesApiClient() => _instance;
Future <List<Lookup>> getData() async {
Response response;
response = await ApiClient().getJsonForResponse("${URLs.host1}${URLs.getGasTypes}");
Map categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
return categoriesListJson["data"].map<Lookup>((item) => Lookup.fromJson(item)).toList();
}
}

@ -0,0 +1,22 @@
import 'dart:convert';
import 'package:http/http.dart';
import '../controllers/api_routes/urls.dart';
import '../models/lookup.dart';
import 'api_client.dart';
class GazCylinderSizeApiClient{
static final GazCylinderSizeApiClient _instance = GazCylinderSizeApiClient._internal();
GazCylinderSizeApiClient._internal();
factory GazCylinderSizeApiClient() => _instance;
Future getData() async {
Response response= await ApiClient().getJsonForResponse("${URLs.host1}${URLs.getGasCylinderSize}");
var categoriesListJson = json.decode(response.body);
return categoriesListJson['data'].map<Lookup>((item) => Lookup.fromJson(item)).toList();
}
}

@ -0,0 +1,53 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import '../models/hospital.dart';
import 'api_client.dart';
class HospitalsApiClient{
static final HospitalsApiClient _instance = HospitalsApiClient._internal();
HospitalsApiClient._internal();
factory HospitalsApiClient() => _instance;
Future getHospitals({
required String title,
required int pageSize
}) async {
Response response = await ApiClient().postJsonForResponse(
URLs.host1 + URLs.getHospitals,
{
"pageSize": pageSize.toString(),
"name": title,
},
isFormData: false
);
Map categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
print(categoriesListJson);
return categoriesListJson['data'].map<Hospital>((category) => Hospital.fromJson(category)).toList();
}
Future<List<Hospital>> getHospitalsList({
required String title,
}) async {
Response response;
response = await ApiClient().postJsonForResponse(
URLs.host1 + URLs.getHospitals,
{"name" : title},
isFormData: false
);
List<Hospital> page = [];
Map categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
page = categoriesListJson['data'].map<Hospital>((category) => Hospital.fromJson(category)).toList();
return page;
}
}

@ -0,0 +1,56 @@
import 'dart:convert';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/api/user_api_client.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/visits/visits_group.dart';
import 'package:test_sa/models/visits/visits_search.dart';
import '../models/visits/visit.dart';
class PreventiveMaintenanceApiClient {
static final PreventiveMaintenanceApiClient _instance = PreventiveMaintenanceApiClient._internal();
/// ## list of user requests
final List<Visit> visits = [];
PreventiveMaintenanceApiClient._internal();
factory PreventiveMaintenanceApiClient() => _instance;
Future getVisits({required int pageItemNumber, VisitsSearch? visitsSearch}) async {
print('get visits');
final response = await ApiClient().getJsonForResponse(
'${URLs.host1}${URLs.getPreventiveMaintenanceVisits}',
headers: {"Content-Type": "application/json; charset=utf-8"},
queryParameters: {
'uid': UserApiClient().user?.id,
'token': UserApiClient().user?.token,
'page': '${(visits.length) ~/ pageItemNumber}',
if (visitsSearch != null) ...visitsSearch.queryParameters(),
},
);
List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<Visit> visitsList = requestsListJson.map((request) => Visit.fromJson(request)).toList();
visits.addAll(visitsList);
}
Future updateGroupOfVisits({required VisitsGroup group}) async {
print('update group of visits');
final user = UserApiClient().user;
Map<String, String> body = group.toJson();
body["token"] = user?.token ?? "";
body["uid"] = user?.id ?? "";
//userId = 397.toString(); // testing id to view data
await ApiClient().postJsonForResponse(
'${URLs.host1}${URLs.updatePreventiveMaintenanceVisits}',
body,
);
// client's request was successfully received
for (var visit in (group.visits ?? [])) {
visit.status = group.status;
visit.actualDate = group.date.toString().split(" ").first;
}
group.visits?.clear();
}
}

@ -0,0 +1,250 @@
import 'dart:convert';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/api/user_api_client.dart';
import 'package:test_sa/models/issue.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/service_request/service_request_search.dart';
import 'package:test_sa/models/timer_model.dart';
import '../controllers/api_routes/urls.dart';
class ServiceRequestApiClient {
static final ServiceRequestApiClient _instance = ServiceRequestApiClient._internal();
final List<ServiceRequest> serviceRequests = [];
ServiceRequestApiClient._internal();
factory ServiceRequestApiClient() => _instance;
// 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
/// ### The result will be added to [serviceRequests]
Future createRequest(ServiceRequest serviceRequest) async {
print("create request");
final user = UserApiClient().user;
await ApiClient().postJsonForObject(
(json) {
// ServiceRequest.fromJson(json.decode(utf8.decode(response.bodyBytes))[0])
serviceRequests.insert(0, ServiceRequest.fromJson(json[0]));
},
'${URLs.host1}${URLs.createRequest}',
{
"callNo": serviceRequest.id,
"callCreatedBy": {"name": serviceRequest.engineerName},
"requestedDate": DateTime.now().millisecondsSinceEpoch.toString(),
"requestedTime": DateTime.now().millisecondsSinceEpoch.toString(),
"defectType": {"id": serviceRequest.defectType?.id, "name": serviceRequest.defectType?.label, "value": serviceRequest.defectType?.id},
// "assets": [0],
"assignedEmployee": {"id": user?.id.toString(), "name": user?.username},
"voiceNote": serviceRequest.audio,
// "callSiteContactPerson": [
// {"id": 0, "employeeCode": "string", "name": "string", "telephone": "string", "job": "string", "email": "string", "land": "string", "contactUserId": "string"}
// ],
"priority": {"id": serviceRequest.priority?.id, "name": serviceRequest.priority?.label, "value": serviceRequest.priority?.id},
// "requestedThrough": {"id": 0, "name": "string", "value": 0},
// "typeofRequest": {"id": 0, "name": "string", "value": 0},
// "callComments": "string",
// "noofFollowup": 0,
// "attachmentsCallRequest": [
// {"id": "", "name": ""}
// ],
"status": {"name": serviceRequest.statusLabel, "value": serviceRequest.statusValue},
// "callLastSituation": {"id": 0, "name": "string", "value": 0},
// "firstAction": {"id": 0, "name": "string", "value": 0},
// "loanAvailablity": {"id": 0, "name": "string", "value": 0},
// "comments": "string",
// "firstActionDate": "2023-04-17T10:39:59.599Z",
"visitDate": serviceRequest.visitDate,
// "callReview": {"id": 0, "name": "string", "value": serviceRequest.}
},
// {
// "uid": user?.id,
// "token": user?.token ?? "",
// "sn_id": serviceRequest.deviceId ?? "",
// "date": (DateTime.now().millisecondsSinceEpoch).toString(),
// "client": user?.hospital?.id ?? '',
// "complaint": serviceRequest.maintenanceIssue,
// "image": json.encode(serviceRequest.devicePhotos),
// "priority": (serviceRequest.priority?.id).toString(),
// "defect_types": (serviceRequest.defectType?.id).toString(),
// "audio": serviceRequest.audio,
// },
);
}
// 222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
/// Get Service Requests and Fill [serviceRequests]
Future<List<ServiceRequest>> getRequests({pageItemNumber, ServiceRequestSearch? search}) async {
print("get requests xx");
final user = UserApiClient().user;
print("user name : ${user?.username}");
print("user id : ${user?.id}");
final response = await ApiClient().postJsonForResponse(
'${URLs.host1}${URLs.getCallRequests}',
{
// "pageSize": (serviceRequests.length) ~/ pageItemNumber,
"pageNumber": pageItemNumber,
// "callId": "string",
// "requestedDateSymbol": {
// "id": 0,
// "name": "string",
// "value": 0
// },
// "requestedDateFrom": "2023-04-18T08:29:50.708Z",
// "requestedDateTo": "2023-04-18T08:29:50.708Z",
// "firstActionSymbol": {
// "id": 0,
// "name": "string",
// "value": 0
// },
// "firstActionFrom": "2023-04-18T08:29:50.708Z",
// "firstActionTo": "2023-04-18T08:29:50.708Z",
if (search?.hospital != null && (search?.hospital?.isNotEmpty ?? false)) "site": search?.hospital,
// "assetNo": "string",
if (search?.deviceSerialNumber != null && (search?.deviceSerialNumber?.isNotEmpty ?? false)) "assetSerialNumber": search?.deviceSerialNumber,
// "maintenanceSituation": {
// "id": 0,
// "name": "string",
// "value": 0
// },
// "status": {
// "id": 0,
// "name": "string",
// "value": 0
// },
"assignedEmployee": {
"id": user?.id,
"name": user?.username,
},
// "firstActionStatus": {
// "id": 0,
// "name": "string",
// "value": 0
// },
if (search?.deviceName != null && (search?.deviceName?.isNotEmpty ?? false)) "assetName": search?.deviceName,
// "manufacturer": "string",
if (search?.model != null && (search?.model?.isNotEmpty ?? false)) "modelDefinition": search?.model,
// "typeOfrequest": {
// "id": 0,
// "name": "string",
// "value": 0
// },
// "priority": {
// "id": 0,
// "name": "string",
// "value": 0
// }
},
// queryParameters: {
// // 'uid': user?.id,
// if (user?.hospital?.id != null) 'client_nid': user?.hospital?.id,
// 'token': user?.token,
// 'page': '${(serviceRequests.length) ~/ pageItemNumber}',
// // if (deviceSerialNumber != null && (deviceSerialNumber?.isNotEmpty ?? false)) 'sn_id': deviceSerialNumber,
// if (statusValue != null) 'status': statusValue?.toString(),
// // if (deviceName != null && (deviceName?.isNotEmpty ?? false)) 'equipment_en_name': deviceName,
// // if (hospital != null && (hospital?.isNotEmpty ?? false)) 'client': hospital,
// // if (model != null && (model?.isNotEmpty ?? false)) 'model': model,
// // if (search != null) ...search.queryParameters(),
// },
);
print(response.body);
List requestsListJson = json.decode(response.body)['data'];
List<ServiceRequest> serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList();
serviceRequests.addAll(serviceRequestsPage);
return serviceRequestsPage;
}
Future<ServiceRequest> getServiceById(String? requestId) async {
print("get service by id");
final user = UserApiClient().user;
final response = await ApiClient().getJsonForResponse(
'${URLs.host1}${URLs.getSingleServiceRequest}',
queryParameters: {'call_nid': requestId, 'uid': user?.id, 'token': user?.token},
);
// If the call to the server was successful, parse the JSON.
List jsonList = json.decode(utf8.decode(response.bodyBytes));
List<ServiceRequest> requests = jsonList.map((i) => ServiceRequest.fromJson(i)).toList();
return requests[0];
}
Future createIssueReport(Issue issue) async {
print("Create Issue Report");
final user = UserApiClient().user;
Map<String, String> body = issue.toMap();
body["uid"] = user?.id ?? "";
body["token"] = user?.token ?? "";
await ApiClient().postJsonForResponse('${URLs.host1}${URLs.createReport}', body);
}
Future updateDate({String? newDate, Lookup? employee, ServiceRequest? request}) async {
print("Update Date");
final user = UserApiClient().user;
Map<String, String> body = {};
body["uid"] = user?.id ?? '';
body["token"] = user?.token ?? '';
body["nid"] = request?.id ?? '';
body["date"] = newDate ?? '';
body["ass_emp"] = employee?.id?.toString() ?? '';
await ApiClient().postJsonForResponse('${URLs.host1}${URLs.updateRequestDate}', body);
request?.engineerName = employee?.label.toString();
}
Future createServiceReport({required ServiceReport? report, required ServiceRequest? request}) async {
print("Create Service Report");
final user = UserApiClient().user;
Map<String, String>? body = report?.toMap();
body?["uid"] = user?.id ?? "";
body?["token"] = user?.token ?? "";
body?["job_id"] = request?.id ?? '';
await ApiClient().postJsonForResponse('${URLs.host1}${URLs.createServiceReport}', body);
}
Future createDuplicatedReport({required ServiceRequest request}) async {
print("Create Duplicated Report");
final user = UserApiClient().user;
await ApiClient().getJsonForResponse(
'${URLs.host1}${URLs.createDuplicatedReport}',
queryParameters: {'nid': request.id, 'uid': user?.id, 'token': user?.token},
);
}
Future updateServiceReport({required ServiceReport report, required ServiceRequest request}) async {
print("Update Service Report");
final user = UserApiClient().user;
Map<String, String> body = report.toMap();
body["uid"] = user?.id ?? "";
body["token"] = user?.token ?? "";
body["job_id"] = request.id ?? '';
body["report_id"] = request.reportID ?? '';
await ApiClient().postJsonForResponse('${URLs.host1}${URLs.updateServiceReport}', body);
}
Future updateServiceReportTimer({required TimerModel timer, required ServiceRequest request}) async {
print("Update Service Report Timer");
final user = UserApiClient().user;
Map<String, String> body = {};
body["uid"] = user?.id ?? "";
body["token"] = user?.token ?? "";
body["job_id"] = request.id ?? '';
body["start_time"] = ((timer.startAt?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
body["end_time"] = ((timer.endAt?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
body["working_hours"] = ((timer.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5);
body["report_id"] = request.reportID ?? '';
await ApiClient().postJsonForResponse('${URLs.host1}${URLs.updateServiceReport}', body);
}
Future<ServiceReport> getSingleServiceReport({required String reportId}) async {
print("Get Single Service Report");
final user = UserApiClient().user;
final response = await ApiClient().getJsonForResponse(
'${URLs.host1}${URLs.getServiceReport}',
queryParameters: {'report_id': reportId, 'uid': user?.id, 'token': user?.token},
);
return ServiceReport.fromJson(json.decode(utf8.decode(response.bodyBytes)), reportId);
}
}

@ -0,0 +1,81 @@
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.dart';
import 'api_client.dart';
class UserApiClient {
static final UserApiClient _instance = UserApiClient._internal();
/// ### This instance will be [NULL] until the login or registration process completed successfully by calling [login] or [register] functions
User? user;
UserApiClient._internal();
factory UserApiClient() => _instance;
/// - [user] object have to contains username & password
/// - If the request completed successfully the [UserApiClient.user] object inside [UserApiClient] class won't be null and will contains the data comes from the response.
/// - Returns exception of type [APIException] if any error happened.
///
///#### lib\client\user_api_client.dart
Future login({required User user}) async {
return await ApiClient().postJsonForObject(
(json) {
this.user = User.fromJson(json);
},
"${URLs.host1}${URLs.login}",
await user.toLoginJson(), //body
isFormData: false,
);
}
/// - [newUser] object have to contains the new user data [email, phone, ...]
/// - If the request completed successfully the [user] object inside [UserApiClient] class won't be null and will contains the data comes from the response.
/// - Returns exception of type [APIException] if any error happened.
///
///#### lib\client\user_api_client.dart
Future register({required User newUser}) async {
return await ApiClient().postJsonForObject(
(json) {
user = User.fromJson(json);
},
"${URLs.host1}${URLs.register}",
await newUser.toRegisterJson(), //body
);
}
/// [updatedUser] have to contains the new data for the current user
/// - If the request completed successfully the [user] object inside [UserApiClient] class won't be null and will contains the data comes from the response.
/// - Returns exception of type [APIException] if any error happened.
///
///#### lib\client\user_api_client.dart
Future updateProfile({required User updatedUser}) async {
return await ApiClient().postJsonForObject(
(json) {
user = User.fromJson(json);
},
"${URLs.host1}${URLs.updateProfile}",
updatedUser.toUpdateProfileJson(), //body
);
// Map<String, dynamic> jsonObject = {};
// jsonObject["uid"] = user.id;
// jsonObject["token"] = user.token;
// if (user.department?.id != user.department?.id) {
// jsonObject["department"] = user.department?.id;
// }
// if (user.whatsApp != user.whatsApp) {
// jsonObject["whatsapp"] = user.whatsApp;
// }
// if (user.phoneNumber != user.phoneNumber) {
// jsonObject["phone"] = user.phoneNumber;
// }
// final response = await ApiClient().postJsonForResponse(URLs.updateProfile, jsonObject);
//
// if (response.statusCode >= 200 && response.statusCode < 300) {
// // client's request was successfully received
// this.user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
// this.user?.hospital = user.hospital;
// this.user?.department = user.department;
// }
}
}

@ -0,0 +1,91 @@
import 'dart:convert';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/api/user_api_client.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/models/visits/visits_group.dart';
import 'package:test_sa/models/visits/visits_search.dart';
import '../models/visits/visit.dart';
class VisitsApiClient {
static final VisitsApiClient _instance = VisitsApiClient._internal();
/// ## list of user requests
final List<Visit> visits = [];
VisitsApiClient._internal();
factory VisitsApiClient() => _instance;
// 333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
Future getVisits({required int pageItemNumber, VisitsSearch? visitsSearch}) async {
print("get visits");
final response = await ApiClient().postJsonForResponse(
'${URLs.host1}${URLs.getRegularVisits}',
// headers: {"Content-Type": "application/json; charset=utf-8"},
{
// "pageSize": 0,
"pageNumber": pageItemNumber,
// "id": 0,
// "assetId": 0,
"modelId": visitsSearch?.model,
// "ppmId": 0,
// "ppmScheduleId": 0,
// "classification": 0,
// "visitStatusId": 0,
// "deviceStatusId": 0,
// "groupLeaderReviewId": 0,
// "assignedEmployeeId": "string",
"assignedToId": visitsSearch?.contactStatus,
"expectedDateFrom": visitsSearch?.expectedDateFrom,
"expectedDateTo": visitsSearch?.expectedDateTo,
"actualDateFrom": visitsSearch?.actualDateFrom,
"actualDateTo": visitsSearch?.actualDateTo,
// "siteId": 0,
// "jobSheetNo": "string",
// "typeOfServiceId": 0,
// "planNumber": 0
}
// queryParameters: {
// 'uid': UserApiClient().user?.id,
// 'token': UserApiClient().user?.token,
// 'page': '${(visits.length) ~/ pageItemNumber}',
// if (visitsSearch != null) ...visitsSearch.queryParameters(),
// },
);
// print(json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", "")));
List requestsListJson = json.decode(response.body)['data'];
List<Visit> visitsList = requestsListJson.map((request) => Visit.fromJson(request)).toList();
visits.addAll(visitsList);
}
// 4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
Future updateGroupOfVisits({required VisitsGroup group}) async {
final user = UserApiClient().user;
Map<String, dynamic> body = {};
// body["token"] = user?.token ?? "";
body['ids'] = [...(group.visits?.map((e) => e.id).toList() ?? [])];
body["assignedEmployeeId"] = user?.id ?? "";
//userId = 397.toString(); // testing id to view data
await ApiClient().putJsonForResponse('${URLs.host1}${URLs.updateRegularVisits}', body);
}
Future<Pentry> getPentry(String id) async {
final response = await ApiClient().getJsonForResponse(
'${URLs.host1}${URLs.getPentry}/$id',
headers: {"Content-Type": "application/json; charset=utf-8"},
);
return Pentry.fromMap(json.decode(utf8.decode(response.bodyBytes)));
}
Future updatePentry({Pentry? pentry, Visit? visit}) async {
final user = UserApiClient().user;
Map<String, String>? body = pentry?.toMap();
body?["uid"] = user?.id ?? "";
body?["token"] = user?.token ?? "";
await ApiClient().postJsonForResponse('${URLs.host1}${URLs.updatePentry}/${visit?.id}', body);
// visit?.status = pentry?.ppmVisitStatus;
}
}

@ -1,23 +1,22 @@
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";
// static const host1 = "https://atoms.hmg.com/api"; // production url static const host1 = "https://atomsuat.hmg.com";
static const host1 = "https://atomsdev.hmg.com/api"; // uat url
// API Routes // API Routes
static const login = "/handle/user/login"; // post static const login = "/mobile/MobileAuth/Login"; // post
static const register = "/handle/create/user"; // post static const register = "/handle/create/user"; // post
static const updateProfile = "/update/user/profile"; // post static const updateProfile = "/update/user/profile"; // post
static const getHospitals = "/handle/return/all/clients"; // get static const getHospitals = "/mobile/Customer/GetCustomers"; // get
static const getDepartments = "/handle/return/all/departments"; // get static const getDepartments = "/mobile/Department/search"; // get
static const getEquipment = "/handle/return/all/client/equipments"; // get ?client=208051 static const getEquipment = "/mobile/Asset/GetAssets"; // get ?client=208051
static const getServiceRequests = "/return/user/calls"; // get static const getCallRequests = "/mobile/CallRequest/GetCallRequests"; // get
static const getPreventiveMaintenanceVisits = "/return/user/calibrations"; // get static const getPreventiveMaintenanceVisits = "/return/user/calibrations"; // get
static const updatePreventiveMaintenanceVisits = "/update/user/calibrations"; // get static const updatePreventiveMaintenanceVisits = "/update/user/calibrations"; // get
static const getRegularVisits = "/return/user/ppm"; // get static const getRegularVisits = "/mobile/Visit/GetVisits"; // get
static const updateRegularVisits = "/update/user/ppm"; // get static const updateRegularVisits = "/mobile/Visit/UpdateVisits"; // get
static const getSingleServiceRequest = "/return/call/information"; // get static const getSingleServiceRequest = "/return/call/information"; // get
static const getNotifications = "/return/user/notification"; // get static const getNotifications = "/return/user/notification"; // get
@ -32,7 +31,7 @@ class URLs{
static const getServiceReport = "/handle/view/service/report"; // get static const getServiceReport = "/handle/view/service/report"; // get
static const createDuplicatedReport = "/handle/duplicate/request"; // get static const createDuplicatedReport = "/handle/duplicate/request"; // get
static const getServiceReportReasons = "/return/service/report/reasons"; // get static const getServiceReportReasons = "/return/service/report/reasons"; // get
static const getServiceReportTypes = "/return/service/report/type"; // get static const getServiceReportTypes = "/return/service/report/type"; // get
static const getServiceReportStatus = "/return/service/report/status"; // get static const getServiceReportStatus = "/return/service/report/status"; // get
static const getServiceReportLastCalls = "/return/call/last/situation"; // get static const getServiceReportLastCalls = "/return/call/last/situation"; // get
@ -42,17 +41,18 @@ class URLs{
static const getServiceReportDefectTypes = "/return/call/defect/type/list"; // get static const getServiceReportDefectTypes = "/return/call/defect/type/list"; // get
//gas refill //gas refill
static const getGasTypes = "/return/gas/refill/types"; // get static const getGasTypes = "/mobile/Lookups/GetLookup?lookupEnum=606"; // get
static const getGasCylinderSize = "/return/gas/refill/size/cylinder"; // get static const getGasCylinderSize = "/mobile/Lookups/GetLookup?lookupEnum=608"; // get
static const getGasStatus = "/return/gas/refill/status"; // get static const getGasStatus = "/mobile/Lookups/GetLookup?lookupEnum=609"; // get
static const requestGasRefill = "/create/gas/refill"; // get static const requestGasRefill = "/mobile/GazRefill/AddGazRefill"; // get
static const updateGasRefill = "/update/gas/refill/"; // get static const updateGasRefill = "/mobile/GazRefill/UpdateGazRefill"; // get
static const getGasRefill = "/search/gas/refill"; // get static const getGasRefill = "/mobile/GazRefill/GetGazRefills"; // get
static const generateGazRefillNo = "/mobile/GazRefill/GenerateGazRefillNumber";
//device transfer //device transfer
static const requestDeviceTransfer = "/create/transfer/asset"; // get static const requestDeviceTransfer = "/mobile/AssetTransfer/AddAssetTransfer"; // get
static const updateDeviceTransfer = "/update/transfer/asset"; // get static const updateDeviceTransfer = "/mobile/AssetTransfer/UpdateAssetTransfer"; // get
static const getDeviceTransfer = "/search/transfer/asset"; // get static const getDeviceTransfer = "/mobile/AssetTransfer/GetAssetTransfers"; // get
// employee // employee
static const getEmployees = "/return/assigned/employee"; // get static const getEmployees = "/return/assigned/employee"; // get
@ -64,5 +64,4 @@ class URLs{
static const getPentryStatus = "/return/pentry/status/list"; // get static const getPentryStatus = "/return/pentry/status/list"; // get
// contacts // contacts
static const getPentryContacts = "/handle/return/all/contacts"; // get static const getPentryContacts = "/handle/return/all/contacts"; // get
}
}

@ -1,40 +1,38 @@
import 'package:test_sa/models/subtitle.dart'; import '../../models/subtitle.dart';
import 'package:meta/meta.dart';
class HttpStatusManger{ class HttpStatusManger {
static String getStatusMessage({ static String getStatusMessage({
@required int status, required int? status,
@required Subtitle subtitle, required Subtitle? subtitle,
String messageFor400, String? messageFor400,
String messageFor200, String? messageFor200,
}){ }) {
if(status == null) if (status == null) {
// no status code - code error no need for subtitle
return "careful null status"; return "careful null status";
if(status == -1) }
// client's request in process if (status == -1) {
return subtitle.currentlyServiceNotAvailable; return subtitle?.currentlyServiceNotAvailable ?? "";
if(status == -2){ }
if (status == -2) {
// client's request in process // client's request in process
return subtitle.waitUntilYourRequestComplete; return subtitle?.waitUntilYourRequestComplete ?? "";
}else if(status >= 200 && status < 300){ } else if (status >= 200 && status < 300) {
// client's request was successfully received // client's request was successfully received
return messageFor200 ?? subtitle.requestCompleteSuccessfully; return messageFor200 ?? subtitle?.requestCompleteSuccessfully ?? "";
} else if(status >= 400 && status < 500){ } else if (status >= 400 && status < 500) {
// client's request have error // client's request have error
switch(status){ switch (status) {
case 400: case 400:
return messageFor400 ?? subtitle.failedToCompleteRequest; return messageFor400 ?? subtitle?.failedToCompleteRequest ?? "";
default: default:
return subtitle.failedToCompleteRequest; return subtitle?.failedToCompleteRequest ?? "";
} }
} else if(status >= 500){ } else if (status >= 500) {
// server error // server error
return subtitle.currentlyServiceNotAvailable; return subtitle?.currentlyServiceNotAvailable ?? "";
} else { } else {
// no error match so return default error // no error match so return default error
return subtitle.failedToCompleteRequest; return subtitle?.failedToCompleteRequest ?? "";
} }
} }
} }

@ -2,47 +2,46 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:test_sa/models/subtitle.dart';
import '../../models/subtitle.dart';
class AppLocalization { class AppLocalization {
AppLocalization(this.locale); AppLocalization(this.locale);
final Locale locale; final Locale locale;
static AppLocalization of(BuildContext context) {
static AppLocalization? of(BuildContext context) {
return Localizations.of<AppLocalization>(context, AppLocalization); return Localizations.of<AppLocalization>(context, AppLocalization);
} }
Subtitle _subtitle; Subtitle? _subtitle;
Subtitle get subtitle => _subtitle;
Subtitle? get subtitle => _subtitle;
Future<void> load() async { Future<void> load() async {
String jsonStringValues = String jsonStringValues = await rootBundle.loadString('assets/subtitles/${locale.languageCode}_subtitle.json');
await rootBundle.loadString('assets/subtitles/${locale.languageCode}_subtitle.json');
_subtitle = Subtitle.fromJson(json.decode(jsonStringValues)); _subtitle = Subtitle.fromJson(json.decode(jsonStringValues));
} }
// static member to have simple access to the delegate from Material App // static member to have simple access to the delegate from Material App
static const LocalizationsDelegate<AppLocalization> delegate = static const LocalizationsDelegate<AppLocalization> delegate = _DemoLocalizationsDelegate();
_DemoLocalizationsDelegate();
} }
class _DemoLocalizationsDelegate class _DemoLocalizationsDelegate extends LocalizationsDelegate<AppLocalization> {
extends LocalizationsDelegate<AppLocalization> {
const _DemoLocalizationsDelegate(); const _DemoLocalizationsDelegate();
@override @override
bool isSupported(Locale locale) { bool isSupported(Locale locale) {
return ['en','ar'].contains(locale.languageCode); return ['en', 'ar'].contains(locale.languageCode);
} }
@override @override
Future<AppLocalization> load(Locale locale) async { Future<AppLocalization> load(Locale locale) async {
AppLocalization localization = new AppLocalization(locale); AppLocalization localization = AppLocalization(locale);
await localization.load(); await localization.load();
return localization; return localization;
} }
@override @override
bool shouldReload(LocalizationsDelegate<AppLocalization> old) => false; bool shouldReload(LocalizationsDelegate<AppLocalization> old) => false;
} }

@ -3,16 +3,15 @@ import 'dart:convert';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/models/app_notification.dart';
import '../../models/app_notification.dart';
import 'notification_manger.dart'; import 'notification_manger.dart';
class FirebaseNotificationManger{ class FirebaseNotificationManger {
static FirebaseMessaging messaging = FirebaseMessaging.instance; static FirebaseMessaging messaging = FirebaseMessaging.instance;
static String token; static String? token;
static Future<String> getToken() async { static Future<String?> getToken() async {
NotificationSettings settings = await messaging.requestPermission( NotificationSettings settings = await messaging.requestPermission(
alert: true, alert: true,
announcement: false, announcement: false,
@ -23,7 +22,7 @@ class FirebaseNotificationManger{
sound: true, sound: true,
); );
if(settings.authorizationStatus == AuthorizationStatus.authorized){ if (settings.authorizationStatus == AuthorizationStatus.authorized) {
token = await messaging.getToken(); token = await messaging.getToken();
} }
return token; return token;
@ -32,7 +31,7 @@ class FirebaseNotificationManger{
static initialized(BuildContext context) async { static initialized(BuildContext context) async {
await Firebase.initializeApp(); await Firebase.initializeApp();
NotificationSettings settings; NotificationSettings settings;
try{ try {
settings = await messaging.requestPermission( settings = await messaging.requestPermission(
alert: true, alert: true,
announcement: false, announcement: false,
@ -42,11 +41,11 @@ class FirebaseNotificationManger{
provisional: false, provisional: false,
sound: true, sound: true,
); );
}catch(error){ } catch (error) {
return; return;
} }
if(settings.authorizationStatus != AuthorizationStatus.authorized){ if (settings.authorizationStatus != AuthorizationStatus.authorized) {
return; return;
} }
@ -56,28 +55,24 @@ class FirebaseNotificationManger{
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
AppNotification notification = AppNotification.fromJson(message.data); AppNotification notification = AppNotification.fromJson(message.data);
if(notification.path == null
|| notification.path.isEmpty)
return;
Navigator.pushNamed( Navigator.pushNamed(
context, context,
notification.path, notification.path ?? "",
arguments: notification.requestId arguments: notification.requestId,
); );
}); });
FirebaseMessaging.onMessage.listen((RemoteMessage message) { FirebaseMessaging.onMessage.listen((RemoteMessage message) {
AppNotification notification = AppNotification.fromJson(message.data); AppNotification notification = AppNotification.fromJson(message.data);
NotificationManger.showNotification( NotificationManger.showNotification(
title: message.notification.title, title: message.notification?.title,
subtext: message.notification.body, subtext: message.notification?.body,
hashcode: int.tryParse(notification.requestId ?? "") ?? 1, hashcode: int.tryParse(notification.requestId ?? "0") ?? 1,
payload: json.encode(message.data) payload: json.encode(message.data),
); );
return; return;
}); });
} }
} }
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {}
}

@ -1,8 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:test_sa/views/app_style/colors.dart';
class NotificationManger{ import '../../views/app_style/colors.dart';
class NotificationManger {
// private constructor to avoid create object // private constructor to avoid create object
NotificationManger._(); NotificationManger._();
@ -12,43 +12,31 @@ class NotificationManger{
/// onNotificationPressed action when notification pressed to open tap /// onNotificationPressed action when notification pressed to open tap
/// onIOSNotificationPressed action when notification pressed /// onIOSNotificationPressed action when notification pressed
/// to open tap in iOS versions older than 10 /// to open tap in iOS versions older than 10
static initialisation( static initialisation(Function(NotificationResponse) onNotificationPressed, DidReceiveLocalNotificationCallback onIOSNotificationPressed) async {
Function(NotificationResponse) onNotificationPressed, FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
DidReceiveLocalNotificationCallback onIOSNotificationPressed
) async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project // initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
const AndroidInitializationSettings initializationSettingsAndroid = const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings(
AndroidInitializationSettings('app_icon',); 'app_icon',
);
final DarwinInitializationSettings initializationSettingsDarwin = final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings(onDidReceiveLocalNotification: onIOSNotificationPressed);
DarwinInitializationSettings(
onDidReceiveLocalNotification: onIOSNotificationPressed);
final InitializationSettings initializationSettings = InitializationSettings( final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, macOS: initializationSettingsDarwin);
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
macOS: initializationSettingsDarwin);
await flutterLocalNotificationsPlugin.initialize( await flutterLocalNotificationsPlugin.initialize(initializationSettings, onDidReceiveNotificationResponse: onNotificationPressed);
initializationSettings,
onDidReceiveNotificationResponse: onNotificationPressed);
} }
// push new notification // push new notification
static Future showNotification( static Future showNotification({
{ required String? title,
@required String title, required String? subtext,
@required String subtext, required int hashcode,
@required int hashcode, String? payload,
String payload }) async {
}) async {
const AndroidNotificationDetails androidChannel = AndroidNotificationDetails( const AndroidNotificationDetails androidChannel = AndroidNotificationDetails(
'com.newtrack.testsa', 'com.newtrack.testsa',
'Test SA', 'Test SA',
channelDescription:'Push notification service for Test SA', channelDescription: 'Push notification service for Test SA',
importance: Importance.max, importance: Importance.max,
priority: Priority.max, priority: Priority.max,
playSound: true, playSound: true,
@ -62,8 +50,7 @@ class NotificationManger{
groupKey: 'com.newtrack.testsa', groupKey: 'com.newtrack.testsa',
); );
const DarwinNotificationDetails iosNotificationDetails = const DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails(
DarwinNotificationDetails(
categoryIdentifier: "testSA", categoryIdentifier: "testSA",
); );
@ -81,5 +68,4 @@ class NotificationManger{
payload: payload, payload: payload,
); );
} }
}
}

@ -2,66 +2,37 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/api/departments_api_client.dart';
import 'package:test_sa/models/department.dart';
class DepartmentsProvider extends ChangeNotifier{ import '../../../models/department.dart';
import '../../api_routes/urls.dart';
import '../loading_notifier.dart';
class DepartmentsProvider extends LoadingNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
departments = null; departments.clear();
stateCode = null; stateCode = null;
} }
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Department> departments; List<Department> departments=[];
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
Future getDepartment() async {
/// return -2 if request in progress waitApiRequest(() async {
/// return -1 if error happen when sending request departments.addAll(await DepartmentsApiClient().getDepartment());
/// 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> getDepartment (String host) async {
if(isLoading == true)
return -2;
isLoading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(host + URLs.getDepartments),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
} catch(error) {
isLoading = false;
stateCode = -1;
notifyListeners(); notifyListeners();
return -1; },
onSuccess: (){
stateCode=200;
} }
stateCode = response.statusCode; );
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
departments = listJson.map((department) => Department.fromJson(department)).toList();
}
isLoading = false;
notifyListeners();
return response.statusCode;
} }
}
}

@ -1,20 +1,21 @@
import 'dart:convert'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter/cupertino.dart'; import 'package:test_sa/api/device_transfer_api_client.dart';
import 'package:http/http.dart'; import 'package:test_sa/controllers/providers/loading_notifier.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device_transfer.dart'; import '../../../models/device/device_transfer.dart';
import 'package:test_sa/models/device/device_transfer_info.dart'; import '../../../models/device/device_transfer_info.dart';
import 'package:test_sa/models/user.dart'; import '../../../models/user.dart';
import '../../http_status_manger/http_status_manger.dart';
class DeviceTransferProvider extends ChangeNotifier{ import '../../localization/localization.dart';
class DeviceTransferProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset(){ void reset() {
items = null; items.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -22,162 +23,59 @@ class DeviceTransferProvider extends ChangeNotifier{
// 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;
// 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;
// list of user requests // list of user requests
List<DeviceTransfer> items; List<DeviceTransfer> items = [];
// when requests in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
/// 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> getRequests ({
@required String host,
@required User user,
}) async {
if(isLoading == true)
return -2;
isLoading = true;
// isLoading = false; Future getRequests() async {
// stateCode = 200; waitApiRequest(() async {
// items = []; items.clear();
// items.addAll(List.generate(20, (index) => DeviceTransfer( items.addAll(await DeviceTransferApiClient().getRequests(items: items, pageItemNumber: pageItemNumber));
// title: "ddddd", print(items);
// id: "5",
// device: Device(id: "1",brand: "brand",model: "model"),
// destinationClient: Hospital(name: "hospital name",id: "1"),
// destinationDepartment: Department(id: "5",name: "destination Department"),
// senderDepartment: Department(id: "5",name: "sender Department"),
// userId: "5"
// )));
// notifyListeners();
// return 200;
Response response;
try{
response = await get(
Uri.parse(
"$host${URLs.getDeviceTransfer}?uid=${user.id}"
"&token=${user.token}&page=${(items?.length ?? 0) ~/pageItemNumber}"
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
stateCode = response.statusCode;
if(stateCode >= 200 && stateCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<DeviceTransfer> itemsPage = listJson.map(
(request) => DeviceTransfer.fromJson(request)).toList();
items ??= [];
items.addAll(itemsPage);
if(itemsPage.length == pageItemNumber){
nextPage = true;
}else{
nextPage = false;
}
}
isLoading = false;
notifyListeners(); notifyListeners();
return response.statusCode; if (items.length == pageItemNumber) {
nextPage = true;
} catch(error) { } else {
isLoading = false; nextPage = false;
stateCode = -1; }
}, onSuccess: () {
stateCode = 200;
notifyListeners(); notifyListeners();
return -1; });
}
} }
Future<int> createRequest ({ Future createRequest({required DeviceTransfer model, required BuildContext context}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user, waitApiRequest(() async {
@required DeviceTransfer model, items.insert(0, await DeviceTransferApiClient().createRequest(model: model));
}) async { notifyListeners();
Map<String,dynamic> body = { }, onSuccess: () {
"uid": user.id.toString(), Fluttertoast.showToast(
"token": user.token ?? "", msg: subtitle?.requestCompleteSuccessfully ?? "",
"serial_id": model.device.id ?? "",
"destination_client": model.receiver.client.id ?? "",
"destination_department": model.receiver.department.id ?? "",
};
Response response;
try{
response = await post(
Uri.parse(
host+URLs.requestDeviceTransfer),
body: body,
); );
stateCode = response.statusCode; Navigator.of(context).pop();
if(response.statusCode >= 200 && response.statusCode < 300) { }, onError: (error) {
if(items != null) { String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
items.insert( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
0, content: Text(errorMessage),
DeviceTransfer.fromJson( ));
json.decode(utf8.decode(response.bodyBytes))[0] });
)
);
notifyListeners();
}
}
return response.statusCode;
} catch(error) {
return -1;
}
} }
Future<int> updateRequest ({ Future updateRequest({
@required String host, required String host,
@required User user, required User user,
@required bool isSender, required bool isSender,
@required String requestId, required String requestId,
@required DeviceTransfer oldModel, required DeviceTransfer oldModel,
@required DeviceTransferInfo newModel, required DeviceTransferInfo newModel,
}) async { }) async {
reset();
Map<String,dynamic> body = { oldModel = await DeviceTransferApiClient().updateRequest(isSender: isSender, requestId: requestId, oldModel: oldModel, newModel: newModel);
"uid": user.id.toString(), notifyListeners();
"token": user.token ?? "",
"current_user": user.id ?? "",
};
body.addAll(newModel.toJson(isSender));
Response response;
try{
response = await post(
Uri.parse("$host${URLs.updateDeviceTransfer}/$requestId"),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
reset();
// oldModel.fromDeviceTransfer(
// DeviceTransfer.fromJson(
// json.decode(utf8.decode(response.bodyBytes))[0]
// )
// );
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
} }
} }

@ -1,142 +1,65 @@
import 'dart:convert'; import 'package:test_sa/api/devices_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
import 'package:flutter/cupertino.dart'; import '../../../models/device/device.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/user.dart';
class DevicesProvider extends ChangeNotifier{ class DevicesProvider extends LoadingNotifier {
final List<Device> _searchableList = [];
List<Device> get searchableList => _searchableList;
//reset provider data //reset provider data
void reset(){ void reset() {
_devices = null; DevicesApiClient().devices.clear();
_stateCode = null; _stateCode = null;
} }
// 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;
List<Device> _devices;
List<Device> get devices => _devices;
// when categories in-process _loading = true int? get stateCode => _stateCode;
// 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 /// - Fetching Devices From The Server and Inserting them into [DevicesApiClient.devices] List.
/// return -1 if error happen when sending request /// - [_searchableList] will be filled after the request succeed.
/// return state code if request complete may be 200, 404 or 403 ///
/// for more details check http state manager /// ### NOTE : if [hospitalId] is [NULL] nothing will happen
/// lib\controllers\http_status_manger\http_status_manger.dart Future getEquipment() async {
Future<int> getEquipment ({ final hospitalId = /*UserApiClient().user?.hospital?.id ??*/ '';
@required String host, if (hospitalId != null) {
@required User user, _searchableList.clear();
@required String hospitalId await waitApiRequest(
}) async { () async {
if(_loading == true) await DevicesApiClient().getEquipment(hospitalId);
return -2; _searchableList.addAll(DevicesApiClient().devices);
_loading = true; },
notifyListeners(); onSuccess: () {
Response response; /// TODO : this is temporary
try{ _stateCode = 200;
response = await get( },
Uri.parse(host + URLs.getEquipment+"?client=$hospitalId"), onError: (error) {
headers: { /// TODO : this is temporary
"Content-Type":"application/json; charset=utf-8" _stateCode = error.error?.errorCode;
} },
); );
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
} }
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List equipmentListJson = json.decode(utf8.decode(response.bodyBytes));
_devices = equipmentListJson.map((device) => Device.fromJson(device)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} }
/// return -2 if request in progress /// Returns a list of devices by [hospitalId] and [serialNumber] (or | and) [number]
/// return -1 if error happen when sending request ///
/// return state code if request complete may be 200, 404 or 403 /// ### NOTE : if [hospitalId] is [NULL] empty list will be returned
/// for more details check http state manager Future<List<Device>> getDevicesList({required String? hospitalId, String? serialNumber, String? number}) {
/// lib\controllers\http_status_manger\http_status_manger.dart if (hospitalId == null) return Future.value(const []);
Future<List<Device>> getDevicesList ({ return DevicesApiClient().getDevicesList(hospitalId: hospitalId, serialNumber: serialNumber, number: number);
@required String host,
@required User user,
@required String hospitalId,
String serialNumber,
String number,
}) async {
Response response;
try{
response = await get(
Uri.parse("$host${URLs.getEquipment}?client=$hospitalId"
"${serialNumber?.isEmpty == false ? "&name=$serialNumber" :""}"
"${number?.isEmpty == false ? "&number=$number" : ""}"
),
);
List<Device> page = [];
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
return page;
} catch(error) {
return [];
}
} }
/// return -2 if request in progress /// Returns a list of devices by [hospitalId] (and optionally) [serialNumber]
/// return -1 if error happen when sending request ///
/// return state code if request complete may be 200, 404 or 403 /// ### NOTE : if [hospitalId] is [NULL] empty list will be returned
/// for more details check http state manager Future<List<Device>> getDevicesListBySN({required String serialNumber}) {
/// lib\controllers\http_status_manger\http_status_manger.dart final hospitalId = /*UserApiClient().user?.hospital?.id ??*/ "";
Future<List<Device>> getDevicesListBySN ({ if (hospitalId == null) return Future.value(const []);
@required String host, return DevicesApiClient().getDevicesListBySN(hospitalId: hospitalId, serialNumber: serialNumber);
@required User user,
@required String hospitalId,
@required String sn
}) async {
Response response;
try{
response = await get(
Uri.parse(host + URLs.getEquipment+"?client=$hospitalId"
+ ( sn == null || sn.isEmpty ? "" : "&serial_qr=$sn" )),
);
_stateCode = response.statusCode;
List<Device> _page = [];
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
return _page;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return [];
}
} }
} }

@ -1,19 +1,25 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/api/gas_refill_api_client.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/user.dart';
class GasRefillProvider extends ChangeNotifier{ import '../../../models/gas_refill/gas_refill_model.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
import '../loading_notifier.dart';
class GasRefillProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset(){ void reset() {
items = null; items.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -21,152 +27,53 @@ class GasRefillProvider extends ChangeNotifier{
// 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;
// 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;
// list of user requests // list of user requests
List<GasRefillModel> items; List<GasRefillModel> items = [];
// when requests in-process _loading = true Future getRequests() async {
// done _loading = true waitApiRequest(() async {
// failed _loading = false items.clear();
bool isLoading; items.addAll(await GasRefillApiClient().getRequestPages(items: items, pageItemNumber: pageItemNumber));
/// 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> getRequests ({
@required String host,
@required User user,
}) async {
if(isLoading == true)
return -2;
isLoading = true;
Response response;
try{
response = await get(
Uri.parse(
"$host${URLs.getGasRefill}?uid=${user.id}"
"&token=${user.token}&page=${(items?.length ?? 0) ~/pageItemNumber}"
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
stateCode = response.statusCode;
if(stateCode >= 200 && stateCode < 300) {
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<GasRefillModel> itemsPage = requestsListJson.map(
(request) => GasRefillModel.fromJson(request)).toList();
items ??= [];
items.addAll(itemsPage);
if(itemsPage.length == pageItemNumber){
nextPage = true;
}else{
nextPage = false;
}
}
isLoading = false;
notifyListeners(); notifyListeners();
return response.statusCode; if (items.length == pageItemNumber) {
nextPage = true;
} catch(error) { } else {
isLoading = false; nextPage = false;
stateCode = -1; }
}, onSuccess: () {
stateCode = 200;
notifyListeners(); notifyListeners();
return -1; });
}
} }
Future<int> createModel ({ Future createModel({required GasRefillModel model, required BuildContext context}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user,
@required GasRefillModel model,
}) async {
Map<String,dynamic> body = {
"uid": user.id.toString(),
"token": user.token ?? "",
"title": model.title ?? "",
"status": "0",//model.status.value.toString(),
};
body["details"] = jsonEncode(model.details.map((model) => {
"type": model.type.id?.toString(),
"size": model.cylinderSize?.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
}).toList());
Response response; waitApiRequest(() async {
try{ items.insert(0, await GasRefillApiClient().createModel(model: model));
response = await post( notifyListeners();
Uri.parse( }, onError: (error) {
host+URLs.requestGasRefill), String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
body: body, ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}, onSuccess: () {
Fluttertoast.showToast(
msg: subtitle?.requestCompleteSuccessfully ?? "",
); );
Navigator.of(context).pop();
stateCode = response.statusCode; });
if(response.statusCode >= 200 && response.statusCode < 300) {
if(items != null) {
items.insert(
0,
GasRefillModel.fromJson(
json.decode(utf8.decode(response.bodyBytes))[0]
)
);
notifyListeners();
}
}
return response.statusCode;
} catch(error) {
return -1;
}
} }
Future<int> updateModel ({ Future updateModel({
@required String host, required GasRefillModel? oldModel,
@required User user, required GasRefillModel newModel,
@required GasRefillModel oldModel,
@required GasRefillModel newModel,
}) async { }) async {
Map<String,dynamic> body = { await GasRefillApiClient().updateModel(oldModel: oldModel, newModel: newModel);
"uid": user.id.toString(),
"token": user.token ?? "",
"title": newModel.title ?? "",
"status": newModel.status.id.toString(),
};
body["details"] = jsonEncode(newModel.details.map((model) => {
"type": model.type.id.toString(),
"size": model.cylinderSize.id.toString(),
"requsted_qty": model.requestedQuantity.toString(),
"deliverd_qty": model.deliveredQuantity.toString(),
}).toList());
Response response;
try{
response = await post(
Uri.parse("$host${URLs.updateGasRefill}/${newModel.id}"),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
oldModel.fromGasRefillModel(newModel);
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
} }
} }

@ -3,122 +3,61 @@ import 'dart:convert';
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/urls.dart'; import 'package:test_sa/api/hospitals_api_client.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/controllers/providers/loading_notifier.dart';
import 'package:test_sa/models/user.dart';
class HospitalsProvider extends ChangeNotifier{ import '../../../models/hospital.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
class HospitalsProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset(){ void reset() {
_hospitals = null;
_stateCode = null; _stateCode = null;
} }
// state code of current request to defied error message int? _stateCode;
// like 400 customer request failed
// 500 service not available int? get stateCode => _stateCode;
int _stateCode;
int get stateCode => _stateCode;
// true if there is next page in product list and false if not
bool _nextPage = true;
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;
// when categories in-process _loading = true List<Hospital> get hospitals => _hospitals;
// 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> getHospitals ({String host,User user,String title}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getHospitals
+ "?page=${(_hospitals?.length ?? 0) ~/pageItemNumber}"
+ ( title == null || title.isEmpty ? "" : "&name=$title" )
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
List<Hospital> _page = categoriesListJson.map((category) => Hospital.fromJson(category)).toList();
if(hospitals == null)
_hospitals = [];
_hospitals.addAll(_page);
if(_page.length >= pageItemNumber){
_nextPage = true;
}else{
_nextPage = false;
}
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
Future getHospitals({
required String? title,
}) async {
waitApiRequest(() async {
_hospitals.clear();
_hospitals.addAll(await HospitalsApiClient().getHospitals(title: title ?? "", pageSize: _hospitals.length ~/ pageItemNumber));
notifyListeners();
},
onSuccess: (){
_stateCode = 200;
},
onError: (error) {
_stateCode = error.error?.errorCode;
},
);
} }
Future<List<Hospital>> getHospitalsList ({String host,User user,String title}) async { Future<List<Hospital>> getHospitalsList({
Response response; required String title,
try{ }) async {
waitApiRequest((){
response = await get( return HospitalsApiClient().getHospitalsList(title: title);
Uri.parse(host + URLs.getHospitals },
+ ( title == null || title.isEmpty ? "" : "?name=$title" )), onSuccess: (){
headers: { _stateCode=200;
"Content-Type":"application/json; charset=utf-8"
}
);
_stateCode = response.statusCode;
List<Hospital> _page = [];
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_page = categoriesListJson.map((category) => Hospital.fromJson(category)).toList();
}
return _page;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return [];
} }
);
return [];
} }
}
}

@ -2,18 +2,18 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/app_notification.dart';
import 'package:test_sa/models/user.dart';
class NotificationsProvider extends ChangeNotifier{ import '../../../models/app_notification.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
class NotificationsProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 20; final pageItemNumber = 20;
//reset provider data //reset provider data
void reset(){ void reset() {
notifications = null; notifications.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -21,71 +21,63 @@ class NotificationsProvider extends ChangeNotifier{
// 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;
// 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;
// list of user requests // list of user requests
List<AppNotification> notifications; List<AppNotification> notifications = [];
// when requests in-process _loading = true // when requests in-process _loading = true
// done _loading = true // done _loading = true
// failed _loading = false // failed _loading = false
bool isLoading; bool? isLoading;
/// 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<int> getNotifications ({ Future<int> getNotifications({
@required String host, required String host,
@required User user, required User user,
@required String hospitalId, required String hospitalId,
}) async { }) async {
if(isLoading == true) if (isLoading == true) {
return -2; return -2;
}
isLoading = true; isLoading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
// userId = 397.toString(); // testing id to view data // userId = 397.toString(); // testing id to view data
try{ try {
response = await get( response = await get(
Uri.parse(host+URLs.getNotifications Uri.parse(
+"?uid=${user.id}" "${host + URLs.getNotifications}?uid=${user.id}&token=${user.token}&page=${(notifications?.length ?? 0) ~/ pageItemNumber}",
"&token=${user.token}" ),
"&page=${(notifications?.length ?? 0) ~/pageItemNumber}"), headers: {"Content-Type": "application/json; charset=utf-8"});
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
stateCode = response.statusCode; stateCode = response.statusCode;
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 requestsListJson = json.decode(utf8.decode(response.bodyBytes)); List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<AppNotification> _serviceRequestsPage = requestsListJson.map( List<AppNotification> serviceRequestsPage = requestsListJson.map((request) => AppNotification.fromJson(request)).toList();
(request) => AppNotification.fromJson(request)).toList(); notifications.addAll(serviceRequestsPage);
if(notifications == null) if (serviceRequestsPage.length == pageItemNumber) {
notifications = [];
notifications.addAll(_serviceRequestsPage);
if(_serviceRequestsPage.length == pageItemNumber){
nextPage = true; nextPage = true;
}else{ } else {
nextPage = false; nextPage = false;
} }
} }
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
isLoading = false; isLoading = false;
stateCode = -1; stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
/// return -2 if request in progress /// return -2 if request in progress
@ -93,35 +85,26 @@ class NotificationsProvider 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<AppNotification>> getRecentNotifications ({ Future<List<AppNotification>?> getRecentNotifications({
@required String host, required String host,
@required User user, required User user,
}) async { }) async {
Response response; Response response;
//userId = 397.toString(); // testing id to view data //userId = 397.toString(); // testing id to view data
try{ try {
response = await get( response = await get(Uri.parse("$host${URLs.getNotifications}?uid=${user.id}&token=${user.token}"), headers: {"Content-Type": "application/json; charset=utf-8"});
Uri.parse(host+URLs.getNotifications
+"?uid=${user.id}&token=${user.token}"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
stateCode = response.statusCode; stateCode = response.statusCode;
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 requestsListJson = json.decode(utf8.decode(response.bodyBytes)); List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<AppNotification> _recentNotifications = requestsListJson.map( List<AppNotification> recentNotifications = requestsListJson.map((request) => AppNotification.fromJson(request)).toList();
(request) => AppNotification.fromJson(request)).toList(); return recentNotifications;
return _recentNotifications;
} }
return null; return null;
} catch (error) {
} catch(error) {
return null; return null;
} }
} }
} }

@ -1,19 +1,19 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/part.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';
class PartsProvider extends ChangeNotifier{ import '../../../models/part.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
class PartsProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset(){ void reset() {
_parts = null; _parts = null;
_stateCode = null; _stateCode = null;
} }
@ -21,24 +21,29 @@ class PartsProvider extends ChangeNotifier{
// 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;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -48,48 +53,45 @@ 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<int> getParts ({String host,User user,String title}) async { Future<int> getParts({
if(_loading == true) required String host,
return -2; required User user,
required String? title,
}) async {
if (_loading == true) return -2;
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(
Uri.parse( Uri.parse(
host + URLs.getPartNumber "$host${URLs.getPartNumber}?page=${(_parts?.length ?? 0) ~/ pageItemNumber}${title == null || title.isEmpty ? "" : "&name=$title"}",
+ "?page=${(_parts?.length ?? 0) ~/pageItemNumber}" ),
+ ( title == null || title.isEmpty ? "" : "&name=$title" ) headers: {"Content-Type": "application/json; charset=utf-8"},
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
); );
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
List<Part> _page = categoriesListJson.map((part) => Part.fromJson(part)).toList(); List<Part> page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
if(parts == null) if (parts == null) _parts = [];
_parts = [];
_parts.addAll(_page); _parts?.addAll(page);
if(_page.length >= pageItemNumber){ if (page.length >= pageItemNumber) {
_nextPage = true; _nextPage = true;
}else{ } else {
_nextPage = false; _nextPage = false;
} }
} }
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
/// return -2 if request in progress /// return -2 if request in progress
@ -97,30 +99,23 @@ 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({
required String host,
required User user,
required String? title,
}) async {
Response response; Response response;
try{ try {
response = await get(Uri.parse(host + URLs.getPartNumber + (title == null || title.isEmpty ? "" : "?name=$title")), headers: {"Content-Type": "application/json; charset=utf-8"});
response = await get( List<Part> page = [];
Uri.parse( if (response.statusCode >= 200 && response.statusCode < 300) {
host + URLs.getPartNumber
+ ( title == null || title.isEmpty ? "" : "?name=$title" )
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
List<Part> _page = [];
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((part) => Part.fromJson(part)).toList(); page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
} }
return _page; return page;
} catch(error) { } catch (error) {
return []; return [];
} }
} }
}
}

@ -1,21 +1,22 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.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_search.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/api/preventive_maintenance_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
class PreventiveMaintenanceVisitsProvider extends ChangeNotifier{ import '../../../models/visits/visits_group.dart';
import '../../../models/visits/visits_search.dart';
import '../../../views/pages/user/visits/update_visits_group_sheet.dart';
import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
class PreventiveMaintenanceVisitsProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset(){ void reset() {
visits = null; PreventiveMaintenanceApiClient().visits.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -23,115 +24,81 @@ class PreventiveMaintenanceVisitsProvider extends ChangeNotifier{
// 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;
// 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;
// list of user requests
List<Visit> visits;
// when requests in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
VisitsSearch visitsSearch = VisitsSearch(); VisitsSearch? visitsSearch = VisitsSearch();
/// return -2 if request in progress Future getVisits() async {
/// return -1 if error happen when sending request await waitApiRequest(
/// return state code if request complete may be 200, 404 or 403 () async {
/// for more details check http state manager await PreventiveMaintenanceApiClient().getVisits(pageItemNumber: pageItemNumber, visitsSearch: visitsSearch);
/// lib\controllers\http_status_manger\http_status_manger.dart },
Future<int> getVisits ({ onSuccess: () {
@required String host, /// TODO : this is temporary
@required User user, stateCode = 200;
// VisitsSearch visitsSearch, if (PreventiveMaintenanceApiClient().visits.length == pageItemNumber) {
}) async { nextPage = true;
if(isLoading == true) } else {
return -2; nextPage = false;
isLoading = true;
Response response;
//userId = 397.toString(); // testing id to view data
try{
response = await get(
Uri.parse(
host + URLs.getPreventiveMaintenanceVisits
+"?uid=${user.id}"
"&token=${user.token}"
"&page=${(visits?.length ?? 0) ~/pageItemNumber}"
+visitsSearch?.toSearchString() ?? ""
),
headers: {
"Content-Type":"application/json; charset=utf-8"
} }
); },
} catch(error) { onError: (error) {
isLoading = false; /// TODO : this is temporary
stateCode = -1; stateCode = error.error?.errorCode;
notifyListeners(); },
return -1; );
}
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<Visit> _visits = requestsListJson.map(
(request) => Visit.fromJson(request)).toList();
if(visits == null)
visits = [];
visits.addAll(_visits);
if(_visits.length == pageItemNumber){
nextPage = true;
}else{
nextPage = false;
}
}
isLoading = false;
notifyListeners();
return response.statusCode;
} }
/// return -2 if request in progress Future updateGroupOfVisits(BuildContext context) async {
/// return -1 if error happen when sending request final subtitle = AppLocalization.of(context)?.subtitle;
/// return state code if request complete may be 200, 404 or 403 VisitsGroup? group = await showModalBottomSheet(
/// for more details check http state manager isScrollControlled: true,
/// lib\controllers\http_status_manger\http_status_manger.dart context: context,
Future<int> updateGroupOfVisits ({ builder: (context) {
@required String host, return UpdateVisitsGroupSheet(visits: PreventiveMaintenanceApiClient().visits, title: subtitle?.updatePreventiveMaintenance);
@required User user, },
VisitsGroup group, ) as VisitsGroup?;
}) async { if (context.mounted && group != null) {
Response response; showDialog<void>(
Map<String,String> body = group.toJson(); context: context,
body["token"] = user.token ?? ""; barrierDismissible: false,
body["uid"] = user.id; builder: (BuildContext context) {
//userId = 397.toString(); // testing id to view data return CupertinoAlertDialog(
try{ title: Text(subtitle?.updatingDots ?? ''),
response = await post( content: const Center(child: CircularProgressIndicator()),
Uri.parse( );
host+URLs.updatePreventiveMaintenanceVisits },
), );
body: body, await waitApiRequest(
() async {
await PreventiveMaintenanceApiClient().updateGroupOfVisits(group: group);
if (context.mounted) {
Navigator.of(context).pop();
}
},
onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
Navigator.of(context).pop();
Fluttertoast.showToast(
msg: subtitle?.regularVisitsUpdatedSuccessfully ?? '',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
Fluttertoast.showToast(
msg: HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle),
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
},
); );
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
group.visits.forEach((visit) {
visit.status = group.status;
visit.actualDate = group.date.toString().split(" ").first;
});
group.visits.clear();
notifyListeners();
}
return response.statusCode;
} catch(error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
} }
} }
} }

@ -1,22 +1,24 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/models/user.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_search.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class RegularVisitsProvider extends ChangeNotifier{ import 'package:test_sa/api/visits_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
import '../../../models/pantry/pentry.dart';
import '../../../models/visits/visit.dart';
import '../../../models/visits/visits_group.dart';
import '../../../models/visits/visits_search.dart';
import '../../../views/pages/user/visits/update_visits_group_sheet.dart';
import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
class RegularVisitsProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data // reset provider data
void reset(){ void reset() {
visits = null; VisitsApiClient().visits.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -24,160 +26,105 @@ class RegularVisitsProvider extends ChangeNotifier{
// 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;
// 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;
// list of user requests VisitsSearch? visitsSearch = VisitsSearch();
List<Visit> visits;
Future getVisits() async {
// when requests in-process _loading = true await waitApiRequest(
// done _loading = true () async {
// failed _loading = false await VisitsApiClient().getVisits(pageItemNumber: pageItemNumber, visitsSearch: visitsSearch);
bool isLoading; },
onSuccess: () {
VisitsSearch visitsSearch = VisitsSearch(); /// TODO : this is temporary
stateCode = 200;
/// return -2 if request in progress if (VisitsApiClient().visits.length == pageItemNumber) {
/// 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> getVisits ({
@required String host,
@required User user,
// VisitsSearch visitsSearch,
}) async {
if(isLoading == true)
return -2;
isLoading = true;
Response response;
//userId = 397.toString(); // testing id to view data
try{
response = await get(
Uri.parse(
host+URLs.getRegularVisits
+"?uid=${user.id}"
"&token=${user.token}"
"&page=${(visits?.length ?? 0) ~/pageItemNumber}"
+visitsSearch?.toSearchString() ?? ""
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
} catch(error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
try{
List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<Visit> _visits = requestsListJson.map(
(request) => Visit.fromJson(request)
).toList();
if(visits == null)
visits = [];
visits.addAll(_visits);
if(_visits.length == pageItemNumber){
nextPage = true; nextPage = true;
}else{ } else {
nextPage = false; nextPage = false;
} }
}catch(error){ },
isLoading = false; onError: (error) {
stateCode = -1; /// TODO : this is temporary
notifyListeners(); stateCode = error.error?.errorCode;
return -1; },
} );
}
isLoading = false;
notifyListeners();
return response.statusCode;
} }
/// return -2 if request in progress Future updateGroupOfVisits(BuildContext context) async {
/// return -1 if error happen when sending request final subtitle = AppLocalization.of(context)?.subtitle;
/// return state code if request complete may be 200, 404 or 403 VisitsGroup? group = await showModalBottomSheet(
/// for more details check http state manager isScrollControlled: true,
/// lib\controllers\http_status_manger\http_status_manger.dart context: context,
Future<int> updateGroupOfVisits ({ builder: (context) {
@required String host, return UpdateVisitsGroupSheet(visits: VisitsApiClient().visits, title: subtitle?.updateRegularVisits);
@required User user, },
VisitsGroup group, ) as VisitsGroup?;
}) async { if (context.mounted && group != null) {
Response response; showDialog<void>(
Map<String,String> body = group.toJson(); context: context,
body["token"] = user.token ?? ""; barrierDismissible: false,
body["uid"] = user.id; builder: (BuildContext context) {
//userId = 397.toString(); // testing id to view data return CupertinoAlertDialog(
try{ title: Text(subtitle?.updatingDots ?? ''),
response = await post( content: const Center(child: CircularProgressIndicator()),
Uri.parse(host+URLs.updateRegularVisits), );
body: body, },
);
await waitApiRequest(
() async {
await VisitsApiClient().updateGroupOfVisits(group: group);
reset();
},
onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
Navigator.of(context).pop();
Fluttertoast.showToast(
msg: subtitle?.regularVisitsUpdatedSuccessfully ?? '',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
Fluttertoast.showToast(
msg: HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle),
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
},
); );
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
reset();
notifyListeners();
}
return response.statusCode;
} catch(error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
} }
} }
Future<Pentry> getPently({String host,User user,String id}) async { Future<Pentry?> getPently({required String? id}) async {
Response response; return id == null ? null : await VisitsApiClient().getPentry(id);
response = await get(
Uri.parse("$host${URLs.getPentry}/$id"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
Pentry pantry;
if(response.statusCode >= 200 && response.statusCode < 300) {
pantry = Pentry.fromMap(json.decode(utf8.decode(response.bodyBytes)));
}
return pantry;
} }
Future<int> updatePentry ({ void updatePentry(BuildContext context, {required Pentry? pentry, required Visit? visit}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user, await waitApiRequest(
@required Pentry pentry, () async {
@required Visit visit, await VisitsApiClient().updatePentry(pentry: pentry, visit: visit);
}) async { },
try{ onSuccess: () {
Response response; /// TODO : this is temporary
Map<String,String> body = pentry.toMap(); stateCode = 200;
body["uid"] = user.id; if (subtitle != null) {
body["token"] = user.token; Fluttertoast.showToast(msg: subtitle.requestCompleteSuccessfully);
response = await post( }
Uri.parse(host+URLs.updatePentry + "/${visit.id}"), },
body: body, onError: (error) {
); /// TODO : this is temporary
if(response.statusCode >= 200 && response.statusCode < 300) { stateCode = error.error?.errorCode;
visit.status = pentry.ppmVisitStatus; String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
notifyListeners(); Fluttertoast.showToast(msg: errorMessage);
} },
return response.statusCode; );
} catch(error) {
return -1;
}
} }
} }

@ -1,26 +1,30 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart'; import 'package:test_sa/api/service_request_api_client.dart';
import 'package:test_sa/models/issue.dart'; import 'package:test_sa/controllers/providers/loading_notifier.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/exceptions/api_exception.dart';
import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import '../../../models/issue.dart';
import 'package:test_sa/models/service_request/service_request_search.dart'; import '../../../models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import '../../../models/service_report.dart';
import 'package:test_sa/models/timer_model.dart'; import '../../../models/service_request/service_request.dart';
import 'package:test_sa/models/user.dart'; import '../../../models/service_request/service_request_search.dart';
import '../../../models/timer_model.dart';
class ServiceRequestsProvider extends ChangeNotifier{ import '../../../views/widgets/dialogs/dialog.dart';
import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
class ServiceRequestsProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset(){ void reset() {
serviceRequests = null; ServiceRequestApiClient().serviceRequests.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -28,395 +32,190 @@ class ServiceRequestsProvider extends ChangeNotifier{
// 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;
// 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;
// list of user requests ServiceRequestSearch? search = ServiceRequestSearch();
List<ServiceRequest> serviceRequests;
/// Get Service Requests and Fill [ServiceRequestApiClient.serviceRequests]
// when requests in-process _loading = true Future getRequests() async {
// done _loading = true await waitApiRequest(() async {
// failed _loading = false final serviceRequestsPage = await ServiceRequestApiClient().getRequests(pageItemNumber: pageItemNumber, search: search);
bool isLoading; if (serviceRequestsPage.length == pageItemNumber) {
nextPage = true;
ServiceRequestSearch search = ServiceRequestSearch(); } else {
nextPage = false;
/// 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> getRequests ({
@required String host,
@required User user,
@required String hospitalId,
}) async {
if(isLoading == true)
return -2;
isLoading = true;
Response response;
try{
response = await get(
Uri.parse(
host+URLs.getServiceRequests
+"?uid=${user.id}"
+(hospitalId == null? "" :"&client_nid=$hospitalId")
+"&token=${user.token}"
"&page=${(serviceRequests?.length ?? 0) ~/pageItemNumber}"
+search?.toSearchString() ?? ""
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<ServiceRequest> _serviceRequestsPage = requestsListJson.map(
(request) => ServiceRequest.fromJson(request)).toList();
if(serviceRequests == null)
serviceRequests = [];
serviceRequests.addAll(_serviceRequestsPage);
if(_serviceRequestsPage.length == pageItemNumber){
nextPage = true;
}else{
nextPage = false;
}
} }
isLoading = false; }, onSuccess: () {
notifyListeners(); /// TODO : this is temporary
return response.statusCode; stateCode = 200;
}, onError: (error) {
} catch(error) { /// TODO : this is temporary
isLoading = false; stateCode = error.error?.errorCode;
stateCode = -1; });
notifyListeners();
return -1;
}
} }
Future<ServiceRequest> getSingleServiceRequest({ Future<ServiceRequest> getSingleServiceRequest({required String? requestId}) async {
@required String requestId, return await ServiceRequestApiClient().getServiceById(requestId);
@required String host,
@required User user,
@required Subtitle subtitle,
}) async {
String userData = '';
if(user != null){
userData += "&uid="+user.id;
userData += "&token="+user.token;
}
Response response;
try{
response = await get(
Uri.parse(
host+URLs.getSingleServiceRequest
+'?call_nid=$requestId'
'$userData',)
);
}catch(error){
throw(HttpStatusManger.getStatusMessage(
status: -1, subtitle: subtitle));
}
// If the call to the server was successful, parse the JSON.
if (response.statusCode >= 200 && response.statusCode < 300){
// If the call to the server was successful, parse the JSON.
List jsonList = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<ServiceRequest> _requests = jsonList.map((i) => ServiceRequest.fromJson(i)).toList();
return _requests[0];
}else{
throw(HttpStatusManger.getStatusMessage(
status: response.statusCode, subtitle: subtitle));
}
} }
Future<int> createRequest ({ /// ### Create service request and add the response to [ServiceRequestApiClient.serviceRequests]
@required String host, Future createRequest(BuildContext context, {required ServiceRequest serviceRequest, required List<File> deviceImages}) async {
@required User user, final subtitle = AppLocalization.of(context)?.subtitle;
@required ServiceRequest serviceRequest, serviceRequest.devicePhotos = deviceImages.map((e) => base64Encode(e.readAsBytesSync())).toList();
}) async { if (serviceRequest.audio != null) {
final file = File(serviceRequest.audio!);
var body = { serviceRequest.audio = base64Encode(file.readAsBytesSync());
"uid": user.id, }
"token": user.token ?? "", waitApiRequest(() async {
"sn_id": serviceRequest.deviceId ?? "", await ServiceRequestApiClient().createRequest(serviceRequest);
"date": (DateTime.now().millisecondsSinceEpoch).toString(), }, onSuccess: () {
"client": user.hospital.id ?? '', /// TODO : this is temporary
"complaint": serviceRequest.maintenanceIssue, stateCode = 200;
"image": json.encode(serviceRequest.devicePhotos),
"priority": (serviceRequest.priority?.id).toString(), Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
"defect_types": (serviceRequest.defectType?.id).toString(), Navigator.of(context).pop();
}; }, onError: (error) {
if(serviceRequest.audio != null){ /// TODO : this is temporary
body["audio"] = serviceRequest.audio; stateCode = error.error?.errorCode;
}
Response response; String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
try{ ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
response = await post( });
Uri.parse(
host+URLs.createRequest),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if(serviceRequests != null)
serviceRequests.insert(
0,
ServiceRequest.fromJson(
json.decode(utf8.decode(response.bodyBytes))[0]
)
);
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
} }
Future<int> createIssueReport ({ Future createIssueReport(BuildContext context, {required Issue issue}) async {
@required String host, await waitApiRequest(() async {
@required User user, await ServiceRequestApiClient().createIssueReport(issue);
@required Issue issue, }, onSuccess: () {
}) async { final subtitle = AppLocalization.of(context)?.subtitle;
Response response; Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
Map<String,String> body = issue.toMap();
body["uid"] = user.id; /// TODO : this is temporary
body["token"] = user.token; stateCode = 200;
try{ }, onError: (error) {
response = await post( /// TODO : this is temporary
Uri.parse(host+URLs.createReport), stateCode = error.error?.errorCode;
body: body, });
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
}
return response.statusCode;
} catch(error) {
return -1;
}
} }
Future<int> updateDate ({ Future updateDate(BuildContext context, {required String? newDate, required Lookup? employee, required ServiceRequest? request}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user, showDialog<void>(
@required String newDate, context: context,
@required Lookup employee, barrierDismissible: false,
@required ServiceRequest request, builder: (BuildContext context) {
}) async { return CupertinoAlertDialog(title: Text(subtitle?.updatingDots ?? ''), content: const Center(child: CircularProgressIndicator()));
Response response; },
Map<String,String> body = {}; );
body["uid"] = user.id; await waitApiRequest(
body["token"] = user.token; () async {
body["nid"] = request.id; await ServiceRequestApiClient().updateDate(newDate: newDate, employee: employee, request: request);
if(newDate != null) body["date"] = newDate; },
if(employee != null) body["ass_emp"] = employee.id.toString(); onSuccess: () {
try{ Navigator.of(context).pop();
response = await post( Fluttertoast.showToast(msg: HttpStatusManger.getStatusMessage(status: 200, subtitle: subtitle));
Uri.parse(
host+URLs.updateRequestDate), /// TODO : this is temporary
body: body, stateCode = 200;
); },
stateCode = response.statusCode; onError: (error) {
if(response.statusCode >= 200 && response.statusCode < 300) { /// TODO : this is temporary
request.engineerName = employee.label; stateCode = error.error?.errorCode;
notifyListeners(); },
} );
return response.statusCode;
} catch(error) {
return -1;
}
} }
Future<int> createServiceReport ({ Future createServiceReport(BuildContext context, {required ServiceReport? report, required ServiceRequest? request}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user, await waitApiRequest(
@required ServiceReport report, () async {
@required ServiceRequest request, await ServiceRequestApiClient().createServiceReport(report: report, request: request);
}) async {
Response response;
Map<String,String> body = report.toMap();
body["uid"] = user.id;
body["token"] = user.token;
body["job_id"] = request.id;
try{
response = await post(
Uri.parse(
host+URLs.createServiceReport),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
reset(); reset();
notifyListeners(); },
} onSuccess: () {
return response.statusCode; /// TODO : this is temporary
stateCode = 200;
} catch(error) { Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? "");
Navigator.of(context).pop();
return -1; Navigator.of(context).pop();
} },
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
},
);
} }
Future<int> createDuplicatedReport ({ Future createDuplicatedReport(BuildContext context, {required ServiceRequest request}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user, bool result = await showDialog(context: context, builder: (_) => AAlertDialog(title: subtitle?.duplicateAlert, content: subtitle?.duplicateAlertMessage));
@required ServiceRequest request, if (result == true && context.mounted) {
}) async { showDialog(
Response response; context: context,
String userData = ''; builder: (context) {
if(user != null){ return const Center(child: CircularProgressIndicator());
userData += "&uid="+user.id; },
userData += "&token="+user.token; );
} await waitApiRequest(
() async {
try{ await ServiceRequestApiClient().createDuplicatedReport(request: request);
response = await get( reset();
Uri.parse( },
host+URLs.createDuplicatedReport onSuccess: () {
+"?nid=${request.id}" Navigator.of(context).pop();
+userData), },
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle))));
Navigator.of(context).pop();
},
); );
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
reset();
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
} }
} }
Future<int> updateServiceReport ({ Future updateServiceReport(BuildContext context, {required ServiceReport report, required ServiceRequest request}) async {
@required String host, final subtitle = AppLocalization.of(context)?.subtitle;
@required User user, await waitApiRequest(
@required ServiceReport report, () async {
@required ServiceRequest request, await ServiceRequestApiClient().updateServiceReport(report: report, request: request);
}) async {
Response response;
Map<String,String> body = report.toMap();
body["uid"] = user.id;
body["token"] = user.token;
body["job_id"] = request.id;
body["report_id"] = request.reportID;
try{
response = await post(
Uri.parse(
host+URLs.updateServiceReport),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
reset(); reset();
notifyListeners(); },
} onSuccess: () {
return response.statusCode; Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
Navigator.of(context).pop();
} catch(error) { Navigator.of(context).pop();
return -1; /// TODO : this is temporary
} stateCode = 200;
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
},
);
} }
Future<int> updateServiceReportTimer ({ Future updateServiceReportTimer({required TimerModel timer, required ServiceRequest request}) async {
@required String host, try {
@required User user, await ServiceRequestApiClient().updateServiceReportTimer(timer: timer, request: request);
@required TimerModel timer,
@required ServiceRequest request,
}) async {
Response response;
Map<String,String> body = {};
body["uid"] = user.id;
body["token"] = user.token;
body["job_id"] = request.id;
body["start_time"] = (timer.startAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0);
body["end_time"] = (timer.endAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0);
body["working_hours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
body["report_id"] = request.reportID;
try{
response = await post(
Uri.parse(
host+URLs.updateServiceReport),
body: body,
);
//stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// reset();
// notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1; /// TODO : this is temporary
stateCode = 200;
} on APIException catch (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
} }
} }
Future<ServiceReport> getSingleServiceReport({ Future<ServiceReport?> getSingleServiceReport({required String reportId}) async {
@required String reportId, return await ServiceRequestApiClient().getSingleServiceReport(reportId: reportId);
@required String host,
@required User user,
@required Subtitle subtitle,
}) async {
String userData = '';
if(user != null){
userData += "&uid="+user.id;
userData += "&token="+user.token;
}
Response response;
try{
response = await get(
Uri.parse(
host+URLs.getServiceReport
+'?report_id=$reportId'
'$userData',)
);
}catch(error){
throw(HttpStatusManger.getStatusMessage(
status: -1, subtitle: subtitle));
}
// If the call to the server was successful, parse the JSON.
if (response.statusCode >= 200 && response.statusCode < 300){
// If the call to the server was successful, parse the JSON.
return ServiceReport.fromJson(
json.decode(utf8.decode(response.bodyBytes)),reportId);
}else{
throw(HttpStatusManger.getStatusMessage(
status: response.statusCode, subtitle: subtitle));
}
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class EmployeesProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class EmployeesProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class EmployeesProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,19 +45,17 @@ class EmployeesProvider 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<int> getData ({String host,User user}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) return -2;
return -2;
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(
Uri.parse( Uri.parse((host ?? '') + URLs.getEmployees),
host + URLs.getEmployees),
); );
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_items = categoriesListJson.map((type) => Lookup.fromJson(type)).toList(); _items = categoriesListJson.map((type) => Lookup.fromJson(type)).toList();
@ -61,14 +63,11 @@ class EmployeesProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,71 +3,43 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class GasCylinderSizesProvider extends ChangeNotifier{ import '../../../../../api/gaz_cylinder_size_api_client.dart';
import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
import '../../../loading_notifier.dart';
class GasCylinderSizesProvider extends LoadingNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items.clear();
_loading = null;
_stateCode = null; _stateCode = null;
} }
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup> _items=[];
List<Lookup> get items => _items;
// when categories in-process _loading = true List<Lookup> get items => _items;
// 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 Future getData() async {
/// return -1 if error happen when sending request waitApiRequest(() async {
/// return state code if request complete may be 200, 404 or 403 _items = await GazCylinderSizeApiClient().getData();
/// 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 get(
Uri.parse(host + URLs.getGasCylinderSize),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
_loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; },
} catch(error) { onSuccess: (){
_loading = false; _stateCode = 200;
_stateCode = -1;
notifyListeners(); notifyListeners();
return -1;
} }
);
} }
}
}

@ -1,16 +1,16 @@
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';
class GasStatusProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class GasStatusProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_loading = null; _loading = null;
_stateCode = null; _stateCode = null;
@ -19,20 +19,24 @@ class GasStatusProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -42,17 +46,15 @@ class GasStatusProvider 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<int> getData ({String host,User user,}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) return -2; if (_loading == true) return -2;
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getGasStatus));
Uri.parse(host + URLs.getGasStatus),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); _items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
@ -60,13 +62,11 @@ class GasStatusProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -1,72 +1,44 @@
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';
class GasTypesProvider extends ChangeNotifier{ import '../../../../../api/gas_types_api_client.dart';
import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
import '../../../loading_notifier.dart';
class GasTypesProvider extends LoadingNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items?.clear();
_loading = null;
_stateCode = null; _stateCode = null;
stopLoading();
} }
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
// when categories in-process _loading = true List<Lookup>? get items => _items;
// 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 Future getData() async {
/// return -1 if error happen when sending request waitApiRequest(() async {
/// return state code if request complete may be 200, 404 or 403 _items = await GasTypesApiClient().getData();
/// 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 get(
Uri.parse(host + URLs.getGasTypes),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
notifyListeners(); notifyListeners();
return -1; },
} onSuccess: () {
_stateCode = 200;
notifyListeners();
});
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class PentryStatusProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class PentryStatusProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class PentryStatusProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,20 +45,18 @@ class PentryStatusProvider 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<int> getData ({String host,User user}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getPentryStatus));
Uri.parse(
host + URLs.getPentryStatus),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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 listJson = json.decode(utf8.decode(response.bodyBytes)); List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,14 +64,11 @@ class PentryStatusProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class PentryTaskStatusProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class PentryTaskStatusProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class PentryTaskStatusProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,20 +45,18 @@ class PentryTaskStatusProvider 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<int> getData ({String host,User user}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getPentryTaskStatus));
Uri.parse(
host + URLs.getPentryTaskStatus),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_items = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _items = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,14 +64,11 @@ class PentryTaskStatusProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class PentryVisitStatusProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class PentryVisitStatusProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class PentryVisitStatusProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,20 +45,18 @@ class PentryVisitStatusProvider 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<int> getData ({String host,User user}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getPentryVisitStatus));
Uri.parse(
host + URLs.getPentryVisitStatus),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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 listJson = json.decode(utf8.decode(response.bodyBytes)); List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,13 +64,11 @@ class PentryVisitStatusProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceRequestDefectTypesProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceRequestDefectTypesProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class ServiceRequestDefectTypesProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,20 +45,18 @@ class ServiceRequestDefectTypesProvider 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<int> getData ({String host,User user}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getServiceReportDefectTypes));
Uri.parse(
host + URLs.getServiceReportDefectTypes),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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 listJson = json.decode(utf8.decode(response.bodyBytes)); List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,14 +64,11 @@ class ServiceRequestDefectTypesProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceReportLastCallsProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceReportLastCallsProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_calls = null; _calls = null;
_loading = null; _loading = null;
_stateCode = null; _stateCode = null;
@ -19,20 +19,24 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _calls; List<Lookup>? _calls;
List<Lookup> get calls => _calls;
List<Lookup>? get calls => _calls;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -42,21 +46,23 @@ class ServiceReportLastCallsProvider 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<int> getCalls ({String host,User user,String serviceStatus}) async { Future<int> getCalls({
if(_loading == true) required String? host,
return -2; required User? user,
String? serviceStatus,
}) async {
if (_loading == true) return -2;
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(
Uri.parse( Uri.parse(
host + URLs.getServiceReportLastCalls (host ?? '') + URLs.getServiceReportLastCalls + (serviceStatus == null ? "" : "?service_status=$serviceStatus"),
+(serviceStatus == null ? "" : "?service_status=$serviceStatus") ),
),
); );
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_calls = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _calls = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -64,13 +70,11 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceRequestPriorityProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceRequestPriorityProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_items = null; _items = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class ServiceRequestPriorityProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _items; List<Lookup>? _items;
List<Lookup> get items => _items;
List<Lookup>? get items => _items;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,20 +45,18 @@ class ServiceRequestPriorityProvider 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<int> getData ({String host,User user}) async { Future<int> getData({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getServiceReportPriority));
Uri.parse(
host + URLs.getServiceReportPriority),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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 listJson = json.decode(utf8.decode(response.bodyBytes)); List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,13 +64,11 @@ class ServiceRequestPriorityProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceReportReasonsProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceReportReasonsProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_reasons = null; _reasons = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _reasons; List<Lookup>? _reasons;
List<Lookup> get reasons => _reasons;
List<Lookup>? get reasons => _reasons;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,19 +45,17 @@ class ServiceReportReasonsProvider 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<int> getTypes ({String host,User user}) async { Future<int> getTypes({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getServiceReportReasons));
Uri.parse(
host + URLs.getServiceReportReasons),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_reasons = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _reasons = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -61,13 +63,11 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceReportStatusProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceReportStatusProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_status = null; _status = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class ServiceReportStatusProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _status; List<Lookup>? _status;
List<Lookup> get statuses => _status;
List<Lookup>? get statuses => _status;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,19 +45,17 @@ class ServiceReportStatusProvider 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<int> getTypes ({String host,User user}) async { Future<int> getTypes({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get( response = await get(Uri.parse((host ?? '') + URLs.getServiceReportStatus));
Uri.parse(
host + URLs.getServiceReportStatus),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_status = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _status = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -61,14 +63,11 @@ class ServiceReportStatusProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceReportTypesProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceReportTypesProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_types = null; _types = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class ServiceReportTypesProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _types; List<Lookup>? _types;
List<Lookup> get types => _types;
List<Lookup>? get types => _types;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,20 +45,17 @@ class ServiceReportTypesProvider 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<int> getTypes ({String host,User user}) async { Future<int> getTypes({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceReportTypes));
response = await get(
Uri.parse(
host + URLs.getServiceReportTypes),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_types = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList(); _types = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,13 +63,11 @@ class ServiceReportTypesProvider extends ChangeNotifier{
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
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/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart';
class ServiceStatusProvider extends ChangeNotifier{ import '../../../../../models/lookup.dart';
import '../../../../../models/user.dart';
import '../../../../api_routes/urls.dart';
class ServiceStatusProvider extends ChangeNotifier {
//reset provider data //reset provider data
void reset(){ void reset() {
_statuses = null; _statuses = null;
_stateCode = null; _stateCode = null;
} }
@ -18,20 +18,24 @@ class ServiceStatusProvider extends ChangeNotifier{
// 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;
// contain user data // contain user data
// when user not login or register _user = null // when user not login or register _user = null
List<Lookup> _statuses; List<Lookup>? _statuses;
List<Lookup> get statuses => _statuses;
List<Lookup>? get statuses => _statuses;
// 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;
set isLoading(bool isLoading){ bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading; _loading = isLoading;
notifyListeners(); notifyListeners();
} }
@ -41,35 +45,29 @@ class ServiceStatusProvider 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<int> getTypes ({String host,User user}) async { Future<int> getTypes({required String? host, required User? user}) async {
if(_loading == true) if (_loading == true) {
return -2; return -2;
}
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try{ try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceTypes));
response = await get(
Uri.parse(
host + URLs.getServiceTypes),
);
_stateCode = response.statusCode; _stateCode = response.statusCode;
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));
_statuses = categoriesListJson.map((e) => Lookup.fromIntIdJson(e)).toList(); _statuses = categoriesListJson.map((e) => Lookup.fromIntIdJson(e)).toList();
} }
_loading = false; _loading = false;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} catch(error) { } catch (error) {
_loading = false; _loading = false;
_stateCode = -1; _stateCode = -1;
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} }
}
}

@ -1,162 +0,0 @@
import 'dart:convert';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class UserProvider extends ChangeNotifier{
//reset provider data
void reset(){
_user = null;
_loading = false;
}
// contain user data
// when user not login or register _user = null
User _user;
User get user => _user;
set user(User user) {
_user = user;
notifyListeners();
}
// when login or register in-process _login = true
// when login or register is done or not start = false
bool _loading = false;
bool get isLoading => _loading;
set isLoading(bool isLoading) {
_loading = isLoading;
notifyListeners();
}
/// sign in with user - need (email or phone) and password;
/// 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> login ({
@required String host,
@required User user,
}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await post(
Uri.parse(
host+URLs.login),
body: await user.toLoginJson(),
);
_loading = false;
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
_user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
return response.statusCode;
}
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
notifyListeners();
return -1;
}
}
/// sign up with User object;
/// 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 about state codes check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> register ({
@required String host,
@required User user,
}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await post(
Uri.parse(
host+URLs.register),
body: await user.toRegisterJson()
);
} catch(error) {
_loading = false;
notifyListeners();
return -1;
}
_loading = false;
notifyListeners();
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
_user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
_user.hospital = user.hospital;
notifyListeners();
return response.statusCode;
}
return response.statusCode;
}
/// sign up with User object;
/// 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 about state codes check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> updateProfile ({
@required String host,
@required User user,
}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
Map<String,dynamic> jsonObject ={};
jsonObject["uid"] = user.id;
jsonObject["token"] = user.token;
if(user.department.id != _user.department.id)
jsonObject["department"] = user.department.id;
if(user.whatsApp != _user.whatsApp)
jsonObject["whatsapp"] = user.whatsApp;
if(user.phoneNumber != _user.phoneNumber)
jsonObject["phone"] = user.phoneNumber;
try{
response = await post(
Uri.parse(
host+URLs.updateProfile),
body: jsonObject
);
} catch(error) {
_loading = false;
notifyListeners();
return -1;
}
_loading = false;
notifyListeners();
if(response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
_user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
_user.hospital = user.hospital;
_user.department = user.department;
notifyListeners();
return response.statusCode;
}
return response.statusCode;
}
}

@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import '../../exceptions/api_exception.dart';
/// ## Change Notifier Class To Handle The State While Waiting The Futures Value
class LoadingNotifier with ChangeNotifier {
bool _loading = false;
/// - Returns [TRUE] if [waitApiRequest] function called
/// - Returns [FALSE] if [waitApiRequest] function completed in both states (failed, succeed)
bool get loading => _loading;
/// - [fun] : Callback function that contains the API request.
/// - [onError] : Optional callback function to handle the request on failure with [APIException] parameter.
/// - [onSuccess] : Optional callback function to handle the request on succeed.
Future waitApiRequest(Function fun, {Function(APIException)? onError, Function? onSuccess}) async {
if (_loading == true) {
debugPrint('loading_notifier.dart : another action already started');
return;
}
_loading = true;
debugPrint('loading_notifier.dart : start loading');
notifyListeners();
try {
await fun();
if (onSuccess != null) {
await onSuccess();
}
} on APIException catch (error) {
debugPrint("loading_notifier.dart : [_waitResult] returns this message ${error.message} : ${error.arguments} ${error.error?.errorCode} ");
if (onError != null) {
await onError(error);
}
} finally {
stopLoading();
debugPrint('loading_notifier.dart : stop loading');
}
}
/// ## Stop loading and Notify listeners
void stopLoading() {
_loading = false;
notifyListeners();
}
}

@ -3,4 +3,4 @@ class ASettings {
static final String host = "host"; static final String host = "host";
static final String language = "language"; static final String language = "language";
static final String speechToText = "speech_to_text"; static final String speechToText = "speech_to_text";
} }

@ -1,15 +1,14 @@
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 '../settings/app_settings.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
import 'app_settings.dart';
class SettingProvider extends ChangeNotifier{ class SettingProvider extends ChangeNotifier {
resetSettings() async { resetSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
user = null; user = null;
@ -21,7 +20,7 @@ class SettingProvider extends ChangeNotifier{
bool isLoaded = false; bool isLoaded = false;
// contain saved user data // contain saved user data
User user; User? user;
Future<void> setUser(User user) async { Future<void> setUser(User user) async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
@ -30,8 +29,10 @@ class SettingProvider extends ChangeNotifier{
notifyListeners(); notifyListeners();
} }
String _host; String? _host;
String get host => _host;
String? get host => _host;
Future<void> setHost(String host) async { Future<void> setHost(String host) async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(ASettings.host, host); prefs.setString(ASettings.host, host);
@ -39,8 +40,10 @@ class SettingProvider extends ChangeNotifier{
notifyListeners(); notifyListeners();
} }
String _language; String? _language;
String get language => _language;
String? get language => _language;
Future<void> setLanguage(String currentLanguage) async { Future<void> setLanguage(String currentLanguage) async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(ASettings.language, currentLanguage); prefs.setString(ASettings.language, currentLanguage);
@ -48,8 +51,10 @@ class SettingProvider extends ChangeNotifier{
notifyListeners(); notifyListeners();
} }
String _speechToText; String? _speechToText;
String get speechToText => _speechToText;
String? get speechToText => _speechToText;
Future<void> setSpeechToText(String currentLanguage) async { Future<void> setSpeechToText(String currentLanguage) async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(ASettings.speechToText, currentLanguage); prefs.setString(ASettings.speechToText, currentLanguage);
@ -58,40 +63,38 @@ class SettingProvider extends ChangeNotifier{
} }
// call loadSharedPreferences when provider initialise // call loadSharedPreferences when provider initialise
SettingProvider(){ SettingProvider() {
loadSharedPreferences(); loadSharedPreferences();
} }
// get app setting // get app setting
Future<void> loadSharedPreferences() async { Future<void> loadSharedPreferences() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
if(prefs.containsKey(ASettings.language)){ if (prefs.containsKey(ASettings.language)) {
_language = prefs.getString(ASettings.language); _language = prefs.getString(ASettings.language);
}else{ } else {
_language = 'en'; _language = 'en';
} }
if(prefs.containsKey(ASettings.speechToText)){ if (prefs.containsKey(ASettings.speechToText)) {
_speechToText = prefs.getString(ASettings.speechToText); _speechToText = prefs.getString(ASettings.speechToText);
}else{ } else {
_speechToText = 'ar'; _speechToText = 'ar';
} }
if(prefs.containsKey(ASettings.user)){ if (prefs.containsKey(ASettings.user)) {
String userJson = prefs.getString(ASettings.user); String? userJson = prefs.getString(ASettings.user);
user = User.fromJson(json.decode(userJson)); user = User.fromJson(json.decode(userJson ?? ''));
} }
if(prefs.containsKey(ASettings.host)){ if (prefs.containsKey(ASettings.host)) {
_host = prefs.getString(ASettings.host); _host = prefs.getString(ASettings.host);
} else{ } else {
_host = URLs.host1; _host = URLs.host1;
} }
isLoaded = true; isLoaded = true;
notifyListeners(); notifyListeners();
} }
}
}

@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/api/user_api_client.dart';
import '../../models/user.dart';
import '../../views/pages/user/land_page.dart';
import '../http_status_manger/http_status_manger.dart';
import '../localization/localization.dart';
import 'loading_notifier.dart';
import 'settings/setting_provider.dart';
class UserProvider extends LoadingNotifier {
/// - [UserApiClient.user] will be null
/// - loading process will stop
void reset() {
UserApiClient().user = null;
stopLoading();
}
/// ## Login & Fill [UserApiClient.user] data
/// - onSuccess and user is Active : push to [LandPage]
/// - onSuccess and user isn't Active : toast message will appears
/// - onError : SnackBar will appears
Future login(BuildContext context, {required User user}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
waitApiRequest(
() async {
await UserApiClient().login(user: user);
},
onSuccess: () {
if (context.mounted) {
Provider.of<SettingProvider>(context, listen: false).setUser(UserApiClient().user ?? User());
if (UserApiClient().user?.isAuthenticated ?? false) {
Navigator.of(context).pushNamed(LandPage.id);
} else {
Fluttertoast.showToast(msg: subtitle?.activationAlert ?? "");
}
}
},
onError: (error) {
String errorMessage = error.error?.errorCode == 400 ? subtitle?.wrongEmailOrPassword ?? "" : HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
},
);
}
/// ## Register & Fill [UserApiClient.user] data
/// - onSuccess : toast message will appears
/// - onError : SnackBar will appears
Future register(BuildContext context, {required User newUser}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
// if (newUser.hospital == null) {
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(subtitle?.hospitalRequired ?? "")));
// return;
// }
// if (newUser.department == null) {
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(subtitle?.unitRequired ?? "")));
// return;
// }
waitApiRequest(
() async {
await UserApiClient().register(newUser: newUser);
},
onSuccess: () {
Fluttertoast.showToast(msg: subtitle?.activationAlert ?? "");
Navigator.of(context).pop();
},
onError: (error) {
String? errorMessage = error.error?.errorCode == 402
? subtitle?.nameExist
: error.error?.errorCode == 401
? subtitle?.emailExist
: HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage ?? "")));
},
);
}
/// ## Update current user profile
/// - onSuccess : SnackBar will appears
/// - onError : SnackBar will appears
Future updateProfile(BuildContext context, {required User updatedUser}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
// if (updatedUser.department?.id == null) {
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(subtitle?.unitRequired ?? "")));
// return;
// }
waitApiRequest(
() async {
await UserApiClient().updateProfile(updatedUser: updatedUser);
},
onSuccess: () {
Provider.of<SettingProvider>(context, listen: false).setUser(UserApiClient().user!);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(subtitle?.requestCompleteSuccessfully ?? '')));
},
onError: (error) {
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
},
);
}
}

@ -1,24 +1,22 @@
class Validator{ class Validator {
// private constructor to avoid create class object // private constructor to avoid create class object
Validator._(); Validator._();
// check if string not empty and has value // check if string not empty and has value
static bool hasValue(String string){ static bool hasValue(String? string) {
if (string == null || string.isEmpty) if (string == null || string.isEmpty) return false;
return false;
return true; return true;
} }
// Return true if email is valid. Otherwise, return false // Return true if email is valid. Otherwise, return false
static bool isEmail(String email){ static bool isEmail(String email) {
RegExp exp = new RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); RegExp exp = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
if(exp.hasMatch(email)) if (exp.hasMatch(email)) return true;
return true;
return false; return false;
} }
// Return true if phone number is valid. Otherwise, return false // Return true if phone number is valid. Otherwise, return false
static bool isPhoneNumber(String phoneNumber){ static bool isPhoneNumber(String phoneNumber) {
if (phoneNumber == null || phoneNumber.isEmpty) { if (phoneNumber == null || phoneNumber.isEmpty) {
return false; return false;
} }
@ -26,22 +24,19 @@ class Validator{
final pattern = r'^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$'; final pattern = r'^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$';
final regExp = RegExp(pattern); final regExp = RegExp(pattern);
if (regExp.hasMatch(phoneNumber)) if (regExp.hasMatch(phoneNumber)) return true;
return true;
return false; return false;
} }
// Return true if password is valid. Otherwise, return false // Return true if password is valid. Otherwise, return false
static bool isValidPassword(String password){ static bool isValidPassword(String password) {
if(password == null) if (password == null) return false;
return false; if (password.length < 6) return false;
if(password.length <6)
return false;
return true; return true;
} }
// Return true if String is valid Numeric. Otherwise, return false // Return true if String is valid Numeric. Otherwise, return false
static bool isNumeric(String s) { static bool isNumeric(String? s) {
if (s == null) { if (s == null) {
return false; return false;
} }
@ -55,4 +50,4 @@ class Validator{
} }
return int.tryParse(value) != null; return int.tryParse(value) != null;
} }
} }

@ -0,0 +1,29 @@
import 'dart:convert';
import '../api/api_client.dart';
class APIException implements Exception {
static const String BAD_REQUEST = 'api_common_bad_request';
static const String UNAUTHORIZED = 'api_common_unauthorized';
static const String FORBIDDEN = 'api_common_forbidden';
static const String NOT_FOUND = 'api_common_not_found';
static const String INTERNAL_SERVER_ERROR = 'api_common_internal_server_error';
static const String UPGRADE_REQUIRED = 'api_common_upgrade_required';
static const String BAD_RESPONSE_FORMAT = 'api_common_bad_response_format';
static const String OTHER = 'api_common_http_error';
static const String TIMEOUT = 'api_common_http_timeout';
static const String UNKNOWN = 'unexpected_error';
final String message;
final APIError? error;
final arguments;
const APIException(this.message, {this.arguments, this.error});
Map<String, dynamic> toJson() => {'message': message, 'error': error, 'arguments': '$arguments'};
@override
String toString() {
return jsonEncode(this);
}
}

@ -1,6 +1,6 @@
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 '../views/app_style/colors.dart';
extension IntExtensions on int { extension IntExtensions on int {
Widget get height => SizedBox(height: toDouble()); Widget get height => SizedBox(height: toDouble());

@ -47,8 +47,8 @@ import 'controllers/providers/api/status_drop_down/report/service_report_reasons
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/user_provider.dart';
import 'controllers/providers/settings/setting_provider.dart'; import 'controllers/providers/settings/setting_provider.dart';
import 'controllers/providers/user_provider.dart';
import 'views/pages/device_transfer/request_device_transfer.dart'; import 'views/pages/device_transfer/request_device_transfer.dart';
import 'views/pages/device_transfer/track_device_transfer.dart'; import 'views/pages/device_transfer/track_device_transfer.dart';
import 'views/widgets/hospitals/single_hospital_picker.dart'; import 'views/widgets/hospitals/single_hospital_picker.dart';
@ -57,24 +57,25 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
if (Platform.isIOS) { if (Platform.isIOS) {
await Firebase.initializeApp( await Firebase.initializeApp(
options: const FirebaseOptions(apiKey: "AIzaSyACQkSleNwU1jzEKR5ho1uSfZERokwwAbc", appId: "1:973582662416:ios:bc4a8061444c6a08fbc395", messagingSenderId: "973582662416", projectId: "atoms-fb912"), options:
const FirebaseOptions(apiKey: "AIzaSyACQkSleNwU1jzEKR5ho1uSfZERokwwAbc", appId: "1:973582662416:ios:bc4a8061444c6a08fbc395", messagingSenderId: "973582662416", projectId: "atoms-fb912"),
); );
} else { } else {
await Firebase.initializeApp(); await Firebase.initializeApp();
} }
runApp( runApp(ChangeNotifierProvider(
ChangeNotifierProvider( create: (_) => SettingProvider(),
create: (_) => SettingProvider(), child: MyApp(),
child: MyApp(), ));
)
);
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({super.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()),
@ -107,25 +108,19 @@ class MyApp extends StatelessWidget {
onTap: () { onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context); FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) { if (!currentFocus.hasPrimaryFocus) {
FocusManager.instance.primaryFocus.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
} }
}, },
child: MaterialApp( child: MaterialApp(
title: 'ATOMS', title: 'ATOMS',
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: ThemeData( theme: ThemeData(
fontFamily: "Poppins", fontFamily: "Poppins",
//canvasColor: AColors.primaryColor, //canvasColor: AColors.primaryColor,
scaffoldBackgroundColor: AColors.scaffoldBackgroundColor, scaffoldBackgroundColor: AColors.scaffoldBackgroundColor,
primaryColor: AColors.primaryColor, primaryColor: AColors.primaryColor,
indicatorColor: AColors.primaryColor, indicatorColor: AColors.primaryColor,
colorScheme: const ColorScheme.light( colorScheme: const ColorScheme.light(primary: AColors.primaryColor, onPrimary: Colors.white, secondary: AColors.secondaryColor, onSecondary: Colors.white)),
primary: AColors.primaryColor,
onPrimary: Colors.white,
secondary: AColors.secondaryColor,
onSecondary: Colors.white
)
),
localizationsDelegates: const [ localizationsDelegates: const [
// ... app-specific localization delegate[s] here // ... app-specific localization delegate[s] here
AppLocalization.delegate, AppLocalization.delegate,
@ -137,34 +132,31 @@ 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(),
LandPage.id: (_)=> const LandPage(), LandPage.id: (_) => const LandPage(),
Login.id: (_)=> Login(), Login.id: (_) => const Login(),
Register.id: (_)=> Register(), Register.id: (_) => Register(),
ProfilePage.id: (_)=> ProfilePage(), ProfilePage.id: (_) => ProfilePage(),
ReportIssuesPage.id: (_)=> const ReportIssuesPage(), ReportIssuesPage.id: (_) => const ReportIssuesPage(),
RequestGasRefill.id: (_)=> const RequestGasRefill(), RequestGasRefill.id: (_) => const RequestGasRefill(),
CreateRequestPage.id: (_)=> CreateRequestPage(), CreateRequestPage.id: (_) => CreateRequestPage(),
SingleHospitalPicker.id: (_)=> SingleHospitalPicker(), SingleHospitalPicker.id: (_) => SingleHospitalPicker(),
SingleDevicePicker.id: (_)=> SingleDevicePicker(), SingleDevicePicker.id: (_) => SingleDevicePicker(),
SingleDepartmentPicker.id: (_)=> SingleDepartmentPicker(), SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(),
ServiceRequestsPage.id: (_)=> ServiceRequestsPage(), ServiceRequestsPage.id: (_) => ServiceRequestsPage(),
NotificationsPage.id: (_)=> NotificationsPage(), NotificationsPage.id: (_) => NotificationsPage(),
FutureRequestServiceDetails.id: (_)=> FutureRequestServiceDetails(), FutureRequestServiceDetails.id: (_) => const FutureRequestServiceDetails(),
PreventiveMaintenanceVisitsPage.id: (_)=> PreventiveMaintenanceVisitsPage(), PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
RegularVisitsPage.id: (_)=> RegularVisitsPage(), RegularVisitsPage.id: (_) => const RegularVisitsPage(),
TrackGasRefillPage.id: (_)=> const TrackGasRefillPage(), TrackGasRefillPage.id: (_) => const TrackGasRefillPage(),
RequestDeviceTransfer.id: (_)=> const RequestDeviceTransfer(), RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(),
TrackDeviceTransferPage.id: (_)=> const TrackDeviceTransferPage(), TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(),
}, },
), ),
), ),
); );
} }
} }

@ -1,11 +1,11 @@
import 'package:test_sa/views/pages/user/requests/future_request_service_details.dart'; import '../views/pages/user/requests/future_request_service_details.dart';
class AppNotification{ class AppNotification {
String requestId; String? requestId;
String title; String? title;
String description; String? description;
String date; String? date;
String path; String? path;
AppNotification({ AppNotification({
this.requestId, this.requestId,
@ -15,13 +15,12 @@ class AppNotification{
this.path, this.path,
}); });
factory AppNotification.fromJson(Map<String,dynamic> parsedJson){ factory AppNotification.fromJson(Map<String, dynamic> parsedJson) {
return AppNotification( return AppNotification(
requestId: parsedJson["nid"], requestId: parsedJson["nid"],
title: parsedJson["call_client"] ?? parsedJson["title"], title: parsedJson["call_client"] ?? parsedJson["title"],
description: parsedJson["task_description"], description: parsedJson["task_description"],
date: parsedJson["creation_date"], date: parsedJson["creation_date"],
path: FutureRequestServiceDetails.id path: FutureRequestServiceDetails.id);
);
} }
} }

@ -1,22 +1,22 @@
class Department{ class Department {
String id; int? id;
String name; String? name;
Department({ Department({
this.id, this.id,
this.name, this.name,
}); });
factory Department.fromJson(Map<String,dynamic> parsedJson){ factory Department.fromJson(Map<String, dynamic> parsedJson) {
return Department( return Department(
id: parsedJson["nid"] ?? parsedJson["id"], id: parsedJson["nid"] ?? parsedJson["id"],
name: parsedJson["dept_name"] ?? parsedJson["value"], name: parsedJson["dept_name"] ?? parsedJson["value"],
); );
} }
factory Department.fromDepartment(Department department){ factory Department.fromDepartment(Department? department) {
return Department( return Department(
id: department?.id, id: department?.id,
name: department?.name, name: department?.name,
); );
} }
} }

@ -1,15 +1,15 @@
class Device{ class Device {
String id; String? id;
String serialNumber; String? serialNumber;
String number; String? number;
String brand; String? brand;
String model; String? model;
DateTime productionDate; DateTime? productionDate;
DateTime supplyDate; DateTime? supplyDate;
DateTime installDate; DateTime? installDate;
DateTime receivingDate; DateTime? receivingDate;
DateTime operationDate; DateTime? operationDate;
DateTime warrantyDate; DateTime? warrantyDate;
Device({ Device({
this.id, this.id,
@ -25,23 +25,23 @@ class Device{
this.warrantyDate, this.warrantyDate,
}); });
factory Device.fromJson(Map<String,dynamic> parsedJson){ factory Device.fromJson(Map<String, dynamic>? parsedJson) {
return Device( return Device(
id: parsedJson["nid"] ?? parsedJson["id"], id: parsedJson?["nid"] ?? parsedJson?["id"]?.toString(),
serialNumber: parsedJson["sn"] ?? parsedJson["value"], serialNumber: parsedJson?["sn"] ?? parsedJson?["assetSerialNo"],
number: parsedJson["asset_no"], number: parsedJson?["asset_no"],
brand: parsedJson["brand"].toString(), brand: parsedJson?["modelDefinition"]["manufacturerName"] as String?,
model: parsedJson["model"].toString(), model: parsedJson?["modelDefinition"]["modelName"] as String?,
productionDate: getDateFromString(parsedJson["production_date"]), productionDate: getDateFromString(parsedJson?["production_date"]),
supplyDate: getDateFromString(parsedJson["supply_date "]), supplyDate: getDateFromString(parsedJson?["supply_date "]),
installDate: getDateFromString(parsedJson["install_date "]), installDate: getDateFromString(parsedJson?["install_date "]),
receivingDate: getDateFromString(parsedJson["receving_date "]), receivingDate: getDateFromString(parsedJson?["receving_date "]),
operationDate: getDateFromString(parsedJson["operation_date "]), operationDate: getDateFromString(parsedJson?["operation_date "]),
warrantyDate: getDateFromString(parsedJson["warranty_date "]), warrantyDate: getDateFromString(parsedJson?["warranty_date "]),
); );
} }
factory Device.fromDevice(Device device){ factory Device.fromDevice(Device device) {
return Device( return Device(
id: device.id, id: device.id,
serialNumber: device.serialNumber, serialNumber: device.serialNumber,
@ -58,9 +58,9 @@ class Device{
} }
} }
DateTime getDateFromString(String unixDate){ DateTime? getDateFromString(String? unixDate) {
if(unixDate == null) if (unixDate == null) {
return null; return null;
return DateTime.fromMillisecondsSinceEpoch( }
int.parse(unixDate)); return DateTime.fromMillisecondsSinceEpoch(int.parse(unixDate));
} }

@ -1,13 +1,13 @@
import 'package:test_sa/models/device/device.dart'; import 'device.dart';
import 'package:test_sa/models/device/device_transfer_info.dart'; import 'device_transfer_info.dart';
class DeviceTransfer{ class DeviceTransfer {
String id; int? id;
String userId; String? userId;
String title; String? title;
Device device; Device? device;
DeviceTransferInfo sender; DeviceTransferInfo? sender;
DeviceTransferInfo receiver; DeviceTransferInfo? receiver;
DeviceTransfer({ DeviceTransfer({
this.id, this.id,
@ -18,33 +18,36 @@ class DeviceTransfer{
this.receiver, this.receiver,
}); });
bool validate(){ bool validate() {
if(device == null) return false; if (device == null) return false;
return receiver.validate(); return receiver?.validate() ?? false;
} }
fromDeviceTransfer(DeviceTransfer old){ fromDeviceTransfer(DeviceTransfer old) {
id = old.id; id = old.id;
title = old.title; title = old.title;
userId = old.userId; userId = old.userId;
device = Device.fromDevice(old.device); device = old.device != null ? Device.fromDevice(old.device!) : null;
final sender = DeviceTransferInfo(); final sender = DeviceTransferInfo();
sender.fromDetails(old.sender); if (old.sender != null) {
sender.fromDetails(old.sender!);
}
this.sender = sender; this.sender = sender;
final receiver = DeviceTransferInfo(); final receiver = DeviceTransferInfo();
receiver.fromDetails(old.receiver); if (old.receiver != null) {
receiver.fromDetails(old.receiver!);
}
this.receiver = receiver; this.receiver = receiver;
} }
factory DeviceTransfer.fromJson(Map<String,dynamic> parsedJson){ factory DeviceTransfer.fromJson(Map<String, dynamic> parsedJson) {
return DeviceTransfer( return DeviceTransfer(
id: parsedJson["id"], id: parsedJson["id"],
title: parsedJson["title"], title: parsedJson["title"],
userId: parsedJson["uid"], userId: parsedJson["uid"],
device: Device.fromJson(parsedJson["eq_sn"]), device: Device.fromJson(parsedJson["eq_sn"]),
sender: DeviceTransferInfo.fromJson(parsedJson,"sender_"), sender: DeviceTransferInfo.fromJson(parsedJson, "sender"),
receiver: DeviceTransferInfo.fromJson(parsedJson,"receiver_"), receiver: DeviceTransferInfo.fromJson(parsedJson, "receiver"),
); );
} }
} }

@ -1,17 +1,17 @@
import 'package:test_sa/models/department.dart'; import '../department.dart';
import 'package:test_sa/models/hospital.dart'; import '../hospital.dart';
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class DeviceTransferInfo{ class DeviceTransferInfo {
String userId; int? userId;
String comment; String? comment;
Hospital client; Hospital? client;
Department department; Department? department;
String workingHours; String? workingHours;
String travelingHours; String? travelingHours;
String name; String? name;
String signature; String? signature;
Lookup status; Lookup? status;
DeviceTransferInfo({ DeviceTransferInfo({
this.userId, this.userId,
@ -25,48 +25,52 @@ class DeviceTransferInfo{
this.status, this.status,
}); });
Map<String,String>toJson(bool isSender){ Map<String, String> toJson(bool isSender) {
Map<String,String> body = {}; Map<String, String> body = {};
final baseKey = isSender ? "sender_" : "receiver_"; final baseKey = isSender ? "sender" : "receiver";
if(comment != null && comment.isNotEmpty) body["${baseKey}comment"] = comment; if (comment?.isNotEmpty ?? false) body["${baseKey}Comment"] = comment!;
if(workingHours != null && workingHours.isNotEmpty) body["${baseKey}working_hours"] = workingHours; if (workingHours?.isNotEmpty ?? false) {
if(travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = comment; body["${baseKey}WorkingHours"] = workingHours!;
if(status != null) body["${baseKey}status"] = status.id.toString(); }
if(signature != null && signature.isNotEmpty) body["${baseKey}image"] = signature; if (travelingHours?.isNotEmpty ?? false) {
body["${baseKey}TravelingHours"] = travelingHours!;
}
final status = this.status;
if (status != null) body["${baseKey}MachineStatusId"] = status.id.toString();
if (signature?.isNotEmpty ?? false) body["${baseKey}AttachmentUrl"] = signature!;
return body; return body;
} }
bool validate(){ bool validate() {
if(client == null) return false; if (client == null) return false;
if(department == null) return false; if (department == null) return false;
return true; return true;
} }
fromDetails(DeviceTransferInfo old,{bool withSignature = true}){ fromDetails(DeviceTransferInfo? old, {bool withSignature = true}) {
userId = old.userId; userId = old?.userId;
name = old.name; name = old?.name;
client = Hospital.fromHospital(old.client); client = old?.client != null ? Hospital.fromHospital(old?.client) : null;
department = Department.fromDepartment(old.department); department = department != null ? Department.fromDepartment(old?.department!) : null;
workingHours = old.workingHours; workingHours = old?.workingHours;
travelingHours = old.travelingHours; travelingHours = old?.travelingHours;
comment = old.comment; comment = old?.comment;
if(withSignature) signature = old.signature; if (withSignature) signature = old?.signature;
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}WorkingHours"],
travelingHours: parsedJson["${key}travel_hours"], travelingHours: parsedJson["${key}TravelingHours"],
name: parsedJson["${key}name"], name: parsedJson["${key}SiteName"],
signature: parsedJson["${key}image"], signature: parsedJson["${key}AttachmentUrl"],
userId: parsedJson["${key}id"], userId: parsedJson["${key}SiteId"],
comment: parsedJson["${key}comment"], comment: parsedJson["${key}Comment"],
client: Hospital.fromJson(parsedJson["${key}client"]), client: Hospital(id: parsedJson["${key}senderAssignedEmployeeId"], name: parsedJson["${key}senderAssignedEmployeeName"]),
department: Department.fromJson(parsedJson["${key}department"]), department: Department(id: parsedJson["${key}DepartmentId"], name: parsedJson["${key}DepartmentName"]),
status: Lookup.fromJson(parsedJson["${key}status"]), status: Lookup(id: parsedJson["${key}senderMachineStatusId"], label: parsedJson["${key}senderMachineStatusName"]),
); );
} }
} }

@ -1,4 +1,4 @@
enum UsersTypes{ enum UsersTypes {
engineer, // 0 engineer, // 0
normal_user, // 1 normal_user, // 1
} }

@ -1,43 +1,43 @@
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class GasRefillDetails{ class GasRefillDetails {
Lookup type; Lookup? type;
Lookup cylinderSize; Lookup? cylinderSize;
int requestedQuantity; int? requestedQuantity;
int deliveredQuantity; int? deliveredQuantity;
GasRefillDetails({ GasRefillDetails({
this.type, this.type,
this.cylinderSize, this.cylinderSize,
this.requestedQuantity, this.requestedQuantity,
this.deliveredQuantity, this.deliveredQuantity,
required model,
}); });
bool validate(){ bool validate() {
//if(cylinderSize == null) return false; //if(cylinderSize == null) return false;
if(type == null) return false; if (type == null) return false;
if(requestedQuantity == null) return false; if (requestedQuantity == null) return false;
return true; return true;
} }
factory GasRefillDetails.fromJson(Map<String,dynamic> parsedJson){
return GasRefillDetails(
type: Lookup.fromJson(parsedJson["type"]),
cylinderSize: Lookup.fromJson(parsedJson["size"]), factory GasRefillDetails.fromJson(Map<String, dynamic> parsedJson) {
requestedQuantity: parsedJson["requsted_qty"] == null return GasRefillDetails(
? 0 : int.tryParse(parsedJson["requsted_qty"].toString()) ?? 0, type: Lookup.fromJson(parsedJson["gasType"]),
deliveredQuantity: parsedJson["deliverd_qty"] == null cylinderSize: Lookup.fromJson(parsedJson["cylinderSize"]),
? 0 : int.tryParse(parsedJson["deliverd_qty"].toString()) ?? 0, requestedQuantity: parsedJson["requestedQty"] == null ? 0 : int.tryParse(parsedJson["requestedQty"].toString()) ?? 0,
deliveredQuantity: parsedJson["deliverdQty"] == null ? 0 : int.tryParse(parsedJson["deliverdQty"].toString()) ?? 0,
model: null,
); );
} }
factory GasRefillDetails.fromDetails(GasRefillDetails details){ factory GasRefillDetails.fromDetails(GasRefillDetails details) {
return GasRefillDetails( return GasRefillDetails(
type: Lookup.fromStatus(details.type), type: details.type != null ? Lookup.fromStatus(details.type!) : null,
cylinderSize:Lookup.fromStatus(details.cylinderSize), cylinderSize: details.cylinderSize != null ? Lookup.fromStatus(details.cylinderSize!) : null,
requestedQuantity: details.requestedQuantity, requestedQuantity: details.requestedQuantity,
deliveredQuantity: details.deliveredQuantity, deliveredQuantity: details.deliveredQuantity,
model: null,
); );
} }
} }

@ -1,13 +1,13 @@
import 'package:test_sa/models/gas_refill/gas_refill_details.dart'; import '../lookup.dart';
import 'package:test_sa/models/lookup.dart'; import 'gas_refill_details.dart';
class GasRefillModel{ class GasRefillModel {
String id; int? id;
String userId; String? userId;
String clientName; String? clientName;
String title; String? title;
Lookup status; Lookup? status;
List<GasRefillDetails> details; List<GasRefillDetails>? details;
GasRefillModel({ GasRefillModel({
this.id, this.id,
@ -18,36 +18,35 @@ class GasRefillModel{
this.details, this.details,
}); });
bool validate(){ bool validate() {
if(title == null) return false; if (title == null) return false;
if(status == null) return false; if (status == null) return false;
if(details == null && details.isEmpty) return false; if (details == null && (details?.isEmpty ?? true)) return false;
return true; return true;
} }
fromGasRefillModel(GasRefillModel model){ fromGasRefillModel(GasRefillModel model) {
id = model.id; id = model.id;
userId = model.userId; userId = model.userId;
clientName = model.clientName; clientName = model.clientName;
title = model.title; title = model.title;
status = Lookup.fromStatus(model.status); status = model.status != null ? Lookup.fromStatus(model.status!) : null;
details = model.details.map((e) => GasRefillDetails.fromDetails(e)).toList(); details = model.details?.map<GasRefillDetails>((e) => GasRefillDetails.fromDetails(e)).toList();
} }
factory GasRefillModel.fromJson(Map<String,dynamic> parsedJson){ factory GasRefillModel.fromJson(Map<String, dynamic> parsedJson) {
List<GasRefillDetails> details = []; List<GasRefillDetails> details = [];
if(parsedJson["details"] != null){ if (parsedJson["gazRefillDetails"] != null) {
List list = parsedJson["details"]; List list = parsedJson["gazRefillDetails"];
details = list.map((e) => GasRefillDetails.fromJson(e)).toList(); details = list.map((e) => GasRefillDetails.fromJson(e)).toList();
} }
return GasRefillModel( return GasRefillModel(
id: parsedJson["id"], id: parsedJson["id"],
userId: parsedJson["uid"], userId: parsedJson["uid"],
title: parsedJson["title"], title: parsedJson["title"],
clientName: parsedJson["client"], clientName: parsedJson["site"]['custName'],
status: Lookup.fromJson(parsedJson["status"]), status: Lookup.fromJson(parsedJson["status"]),
details: details, details: details,
); );
} }
} }

@ -1,23 +1,23 @@
class Hospital{ class Hospital {
String id; int? id;
String name; String? name;
Hospital({ Hospital({
this.id, this.id,
this.name, this.name,
}); });
factory Hospital.fromJson(Map<String,dynamic> parsedJson){ factory Hospital.fromJson(Map<String, dynamic> parsedJson) {
return Hospital( return Hospital(
id: parsedJson["nid"] ?? parsedJson["id"], id: parsedJson["id"],
name: parsedJson["client_name"] ?? parsedJson["value"], name:parsedJson["custName"],
); );
} }
factory Hospital.fromHospital(Hospital hospital){ factory Hospital.fromHospital(Hospital? hospital) {
return Hospital( return Hospital(
id: hospital?.id, id: hospital?.id,
name: hospital?.name, name: hospital?.name,
); );
} }
} }

@ -1,10 +1,10 @@
class Issue{ class Issue {
String title; String? title;
String userId; String? userId;
List<int> reports; List<int>? reports;
String serviceRequestId; String? serviceRequestId;
String description; String? description;
bool isSelected; bool? isSelected;
Issue({ Issue({
this.description, this.description,
@ -15,13 +15,13 @@ class Issue{
this.serviceRequestId, this.serviceRequestId,
}); });
Map<String,String> toMap(){ Map<String, String> toMap() {
Map<String,String> map ={}; Map<String, String> map = {};
if(title != null) map["title"] = title; if (title != null) map["title"] = title ?? "";
if(reports != null) map["issue_report"] = reports.toString(); if (reports != null) map["issue_report"] = reports.toString();
if(userId != null) map["uid"] = userId; if (userId != null) map["uid"] = userId ?? "";
if(description != null) map["desc"] = description; if (description != null) map["desc"] = description ?? "";
if(serviceRequestId != null) map["call_id"] = serviceRequestId; if (serviceRequestId != null) map["call_id"] = serviceRequestId ?? "";
return map; return map;
} }
} }

@ -1,8 +1,7 @@
class Lookup{ class Lookup {
final String? label;
final String label; final String? key;
final String key; final int? id;
final int id;
const Lookup({ const Lookup({
this.label, this.label,
@ -11,16 +10,12 @@ class Lookup{
}); });
@override @override
bool operator == (Object other) => bool operator ==(Object other) => identical(this, other) || other is Lookup && key == other.key && id == other.id;
identical(this, other) || other is Lookup &&
key == other.key &&
id == other.id;
@override @override
int get hashCode => id.hashCode; int get hashCode => id.hashCode;
factory Lookup.fromStatus(Lookup old){ factory Lookup.fromStatus(Lookup old) {
return Lookup( return Lookup(
label: old.label, label: old.label,
id: old.id, id: old.id,
@ -28,20 +23,17 @@ class Lookup{
); );
} }
factory Lookup.fromJson(Map<String,dynamic> parsedJson){ factory Lookup.fromJson(Map<String, dynamic> parsedJson) {
if(parsedJson["id"] == null && parsedJson["uid"] == null) return null;
return Lookup( return Lookup(
label: parsedJson["value"], label: parsedJson["name"],
id: parsedJson["id"] is int id: parsedJson["id"] is int? ? parsedJson["id"] : int.tryParse(parsedJson["id"] ?? parsedJson["uid"]),
? parsedJson["id"]
: int.tryParse(parsedJson["id"] ?? parsedJson["uid"]),
); );
} }
factory Lookup.fromIntIdJson(Map<String,dynamic> parsedJson){ factory Lookup.fromIntIdJson(Map<String, dynamic> parsedJson) {
return Lookup( return Lookup(
label: parsedJson["value"], label: parsedJson["name"],
id: parsedJson["id"], id: parsedJson["id"],
); );
} }
} }

@ -1,8 +1,8 @@
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class CalibrationTool{ class CalibrationTool {
Lookup assetsNumber; Lookup? assetsNumber;
DateTime dataOfTesting; DateTime? dataOfTesting;
CalibrationTool({ CalibrationTool({
this.assetsNumber, this.assetsNumber,
@ -11,16 +11,19 @@ class CalibrationTool{
Map<String, String> toMap() { Map<String, String> toMap() {
return { return {
if(assetsNumber != null) 'assetsSN': (assetsNumber?.id).toString(), if (assetsNumber != null) 'assetsSN': (assetsNumber?.id).toString(),
if(dataOfTesting != null) 'dataOfTesting': (dataOfTesting.millisecondsSinceEpoch ~/ 1000).toString(), if (dataOfTesting != null) 'dataOfTesting': ((dataOfTesting?.millisecondsSinceEpoch ?? 0) ~/ 1000).toString(),
}; };
} }
factory CalibrationTool.fromMap(Map<String, dynamic> map) { factory CalibrationTool.fromMap(Map<String, dynamic> map) {
return CalibrationTool( return CalibrationTool(
assetsNumber: Lookup.fromJson(map['assetsSN']), assetsNumber: Lookup.fromJson(map['assetsSN']),
dataOfTesting: map['dataOfTesting'] == null || map['dataOfTesting'] == "" ? null : dataOfTesting: map['dataOfTesting'] == null || map['dataOfTesting'] == ""
DateTime.fromMillisecondsSinceEpoch(int.tryParse(map['dataOfTesting']) * 1000), ? null
: DateTime.fromMillisecondsSinceEpoch(
(int.tryParse(map['dataOfTesting']) ?? 0) * 1000,
),
); );
} }
} }

@ -1,30 +1,23 @@
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class Contact{ class Contact {
Lookup title; Lookup? title;
Lookup contactPerson; Lookup? contactPerson;
String job; String? job;
String email; String? email;
String telephone; String? telephone;
String landLine; String? landLine;
Contact({ Contact({this.title, this.contactPerson, this.job, this.email, this.telephone, this.landLine});
this.title,
this.contactPerson,
this.job,
this.email,
this.telephone,
this.landLine
});
Map<String, String> toMap() { Map<String, String> toMap() {
return { return {
if (title != null) 'title': title.id.toString(), if (title != null) 'title': title!.id.toString(),
if (contactPerson != null) 'contactPerson': contactPerson.id.toString(), if (contactPerson != null) 'contactPerson': contactPerson!.id.toString(),
if (job != null) 'job': job, if (job != null) 'job': job!,
if (email != null) 'email': email, if (email != null) 'email': email!,
if (telephone != null) 'telephone': telephone, if (telephone != null) 'telephone': telephone!,
if (landLine != null) 'landLine': landLine, if (landLine != null) 'landLine': landLine!,
}; };
} }
@ -38,4 +31,4 @@ class Contact{
landLine: map['landLine'] as String, landLine: map['landLine'] as String,
); );
} }
} }

@ -1,15 +1,12 @@
import 'package:test_sa/models/lookup.dart'; import '../../lookup.dart';
class ContactTitle extends Lookup { class ContactTitle extends Lookup {
ContactTitle({ ContactTitle({required int id, required String label}) : super(id: id, label: label);
int id,
String label
}):super(id: id,label: label);
factory ContactTitle.fromMap(Map<String,dynamic> parsedJson){ factory ContactTitle.fromMap(Map<String, dynamic> parsedJson) {
return ContactTitle( return ContactTitle(
label: parsedJson["value"], label: parsedJson["value"],
id: parsedJson["id"], id: parsedJson["id"],
); );
} }
} }

@ -1,15 +1,12 @@
import 'package:test_sa/models/lookup.dart'; import '../../lookup.dart';
class ContactTitle extends Lookup { class ContactTitle extends Lookup {
ContactTitle({ ContactTitle({required int id, required String label}) : super(id: id, label: label);
int id,
String label
}):super(id: id,label: label);
factory ContactTitle.fromMap(Map<String,dynamic> parsedJson){ factory ContactTitle.fromMap(Map<String, dynamic> parsedJson) {
return ContactTitle( return ContactTitle(
label: parsedJson["value"], label: parsedJson["value"],
id: parsedJson["id"], id: parsedJson["id"],
); );
} }
} }

@ -1,24 +1,23 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart'; import '../timer_model.dart';
import 'package:test_sa/models/pantry/pm_kit.dart'; import 'calibration_tools.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart'; import 'pm_kit.dart';
import 'package:test_sa/models/timer_model.dart'; import 'ppm_check_list.dart';
class Pentry{ class Pentry {
Lookup ppmVisitStatus; Lookup? ppmVisitStatus;
Lookup status; Lookup? status;
TimerModel timer; TimerModel? timer;
DateTime actualVisitDate; DateTime? actualVisitDate;
String travelingHours; String? travelingHours;
String image; String? image;
File imageFile; File? imageFile;
// List<Contact> contacts; List<PPMCheckList>? ppmCheckLists;
List<PPMCheckList> ppmCheckLists; List<CalibrationTool>? calibrationTools;
List<CalibrationTool> calibrationTools; List<PMKit>? pmKits;
List<PMKit> pmKits;
Pentry({ Pentry({
this.travelingHours, this.travelingHours,
@ -34,10 +33,10 @@ class Pentry{
this.pmKits, this.pmKits,
}); });
bool validate(){ bool validate() {
if(actualVisitDate == null) return false; if (actualVisitDate == null) return false;
if(timer == null && timer.endAt != null) return false; if (timer == null && timer?.endAt != null) return false;
if(ppmVisitStatus == null) return false; if (ppmVisitStatus == null) return false;
//if(status == null) return false; //if(status == null) return false;
return true; return true;
@ -45,15 +44,15 @@ class Pentry{
Map<String, String> toMap() { Map<String, String> toMap() {
Map<String, String> map = {}; Map<String, String> map = {};
map["visit_status"] = ppmVisitStatus?.id.toString(); if (ppmVisitStatus != null) map["visit_status"] = ppmVisitStatus!.id.toString();
if(status != null) map["pentry_status"] = status?.id.toString(); if (status != null) map["pentry_status"] = status!.id.toString();
if(travelingHours != null) map["traveling_hours"] = travelingHours; if (travelingHours != null) map["traveling_hours"] = travelingHours!;
if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync()); if (imageFile != null) map["file_attachement"] = base64Encode(imageFile!.readAsBytesSync());
map["actual_date"] = (actualVisitDate.millisecondsSinceEpoch / 1000).toStringAsFixed(0); map["actual_date"] = ((actualVisitDate?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
if(timer != null){ if (timer != null) {
map["start_date"] = (timer.startAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0); map["start_date"] = ((timer!.startAt?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
map["end_date"] = ((timer.endAt ?? DateTime.now()).millisecondsSinceEpoch / 1000).toStringAsFixed(0); map["end_date"] = (((timer!.endAt)?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
map["working_hours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5); map["working_hours"] = ((timer!.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5);
} }
// if(contacts?.isNotEmpty == true) { // if(contacts?.isNotEmpty == true) {
// for(int i = 0;i<contacts.length;i++){ // for(int i = 0;i<contacts.length;i++){
@ -62,9 +61,9 @@ class Pentry{
// }); // });
// } // }
// } // }
map["ppmCheckLists"] = jsonEncode(ppmCheckLists.map((e) => e.toMap()).toList()); map["ppmCheckLists"] = jsonEncode(ppmCheckLists?.map((e) => e.toMap()).toList());
map["calibrationTools"] = jsonEncode(calibrationTools.map((e) => e.toMap()).toList()); map["calibrationTools"] = jsonEncode(calibrationTools?.map((e) => e.toMap()).toList());
map["pmKits"] = jsonEncode(pmKits.map((e) => e.toMap()).toList()); map["pmKits"] = jsonEncode(pmKits?.map((e) => e.toMap()).toList());
return map; return map;
} }
@ -77,35 +76,25 @@ class Pentry{
// } // }
List<PMKit> pmKits = []; List<PMKit> pmKits = [];
if(map['pmKits'] != null){ if (map['pmKits'] != null) {
pmKits =(map['pmKits'] as List<dynamic>) pmKits = (map['pmKits'] as List<dynamic>).map((e) => PMKit.fromMap(e as Map<String, dynamic>)).toList();
.map((e) => PMKit.fromMap(e as Map<String, dynamic>))
.toList();
} }
List<PPMCheckList> ppmCheckLists = []; List<PPMCheckList> ppmCheckLists = [];
if(map['ppmCheckLists'] != null){ if (map['ppmCheckLists'] != null) {
ppmCheckLists =(map['ppmCheckLists'] as List<dynamic>) ppmCheckLists = (map['ppmCheckLists'] as List<dynamic>).map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>)).toList();
.map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>))
.toList();
} }
List<CalibrationTool> calibrationTools = []; List<CalibrationTool> calibrationTools = [];
if(map['calibrationTools'] != null){ if (map['calibrationTools'] != null) {
calibrationTools =(map['calibrationTools'] as List<dynamic>) calibrationTools = (map['calibrationTools'] as List<dynamic>).map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>)).toList();
.map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>))
.toList();
} }
return Pentry( return Pentry(
status: Lookup.fromJson(map["pentry_status"]), status: Lookup.fromJson(map["pentry_status"]),
ppmVisitStatus: Lookup.fromJson(map["visit_status"]), ppmVisitStatus: Lookup.fromJson(map["visit_status"]),
actualVisitDate: getDate(map["actual_date"]), actualVisitDate: getDate(map["actual_date"]),
travelingHours: map["traveling_hours"], travelingHours: map["traveling_hours"],
timer: TimerModel( timer: TimerModel(startAt: getDate(map["start_date"]), endAt: getDate(map["end_date"]), durationInSecond: (int.tryParse(map["working_hours"] ?? "") ?? 0) * 60 * 60),
startAt: getDate(map["start_date"]),
endAt: getDate(map["end_date"]),
durationInSecond: (int.tryParse(map["working_hours"] ?? "") ?? 0) * 60 *60
),
// contacts: contacts, // contacts: contacts,
ppmCheckLists: ppmCheckLists, ppmCheckLists: ppmCheckLists,
calibrationTools: calibrationTools, calibrationTools: calibrationTools,
@ -113,8 +102,7 @@ class Pentry{
); );
} }
static getDate(String date){ static getDate(String? date) {
return date == null || date.isEmpty return date == null || date.isEmpty ? null : DateTime.fromMillisecondsSinceEpoch((int.tryParse(date) ?? 0) * 1000);
? null : DateTime.fromMillisecondsSinceEpoch(int.tryParse(date) * 1000);
} }
} }

@ -1,45 +1,37 @@
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class PMKit{ class PMKit {
Lookup itemCode; Lookup? itemCode;
String itemName; String? itemName;
String preparationTimeFrame; String? preparationTimeFrame;
String kitFrequencyDemand; String? kitFrequencyDemand;
String availability; String? availability;
String quantityNeeded; String? quantityNeeded;
String quantityReserved; String? quantityReserved;
PMKit({ PMKit({this.itemCode, this.itemName, this.preparationTimeFrame, this.kitFrequencyDemand, this.availability, this.quantityNeeded, this.quantityReserved});
this.itemCode,
this.itemName,
this.preparationTimeFrame,
this.kitFrequencyDemand,
this.availability,
this.quantityNeeded,
this.quantityReserved
});
Map<String, String> toMap() { Map<String, String> toMap() {
return { return {
if(itemCode != null) 'itemCode': (itemCode?.id).toString(), if (itemCode != null) 'itemCode': (itemCode?.id).toString(),
if(itemName != null) 'itemName': itemName, if (itemName != null) 'itemName': itemName!,
if(preparationTimeFrame != null) 'preparationTimeFrame': preparationTimeFrame, if (preparationTimeFrame != null) 'preparationTimeFrame': preparationTimeFrame!,
if(kitFrequencyDemand != null) 'kitFrequencyDemand': kitFrequencyDemand, if (kitFrequencyDemand != null) 'kitFrequencyDemand': kitFrequencyDemand!,
if(availability != null) 'availability': availability, if (availability != null) 'availability': availability!,
if(quantityNeeded != null) 'quantityNeeded': quantityNeeded, if (quantityNeeded != null) 'quantityNeeded': quantityNeeded!,
if(quantityReserved != null) 'quantityReserved': quantityReserved, if (quantityReserved != null) 'quantityReserved': quantityReserved!,
}; };
} }
factory PMKit.fromMap(Map<String, dynamic> map) { factory PMKit.fromMap(Map<String, dynamic> map) {
return PMKit( return PMKit(
itemCode: Lookup.fromJson(map['itemCode']), itemCode: Lookup.fromJson(map['itemCode']),
itemName: map['itemName'] as String, itemName: map['itemName'] as String?,
preparationTimeFrame: map['preparationTimeFrame'] as String, preparationTimeFrame: map['preparationTimeFrame'] as String?,
kitFrequencyDemand: map['kitFrequencyDemand'] as String, kitFrequencyDemand: map['kitFrequencyDemand'] as String?,
availability: map['availability'] as String, availability: map['availability'] as String?,
quantityNeeded: map['quantityNeeded'] as String, quantityNeeded: map['quantityNeeded'] as String?,
quantityReserved: map['quantityReserved'] as String, quantityReserved: map['quantityReserved'] as String?,
); );
} }
} }

@ -1,10 +1,10 @@
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class PPMCheckList{ class PPMCheckList {
Lookup status; Lookup? status;
String title; String? title;
String comment; String? comment;
String measuredValue; String? measuredValue;
PPMCheckList({ PPMCheckList({
this.title, this.title,
@ -15,19 +15,19 @@ class PPMCheckList{
Map<String, String> toMap() { Map<String, String> toMap() {
return { return {
if(status != null) 'status': status?.id.toString(), if (status != null) 'status': status!.id.toString(),
if(title != null) 'title': title, if (title != null) 'title': title!,
if(comment != null) 'comment': comment, if (comment != null) 'comment': comment!,
if(measuredValue != null) 'measuredValue': measuredValue, if (measuredValue != null) 'measuredValue': measuredValue!,
}; };
} }
factory PPMCheckList.fromMap(Map<String, dynamic> map) { factory PPMCheckList.fromMap(Map<String, dynamic> map) {
return PPMCheckList( return PPMCheckList(
status: Lookup.fromJson(map['status']), status: Lookup.fromJson(map['status']),
title: map['title'] as String, title: map['title'] as String?,
comment: map['comment'] as String, comment: map['comment'] as String?,
measuredValue: map['measuredValue'] as String, measuredValue: map['measuredValue'] as String?,
); );
} }
} }

@ -1,7 +1,7 @@
class Part{ class Part {
String id; String? id;
String code; String? code;
String name; String? name;
int quantity; int quantity;
Part({ Part({
@ -11,13 +11,12 @@ class Part{
this.quantity = 1, this.quantity = 1,
}); });
factory Part.fromJson(Map<String,dynamic> parsedJson){ factory Part.fromJson(Map<String, dynamic> parsedJson) {
return Part( return Part(
id: parsedJson["nid"] ?? parsedJson["id"], id: parsedJson["nid"] ?? parsedJson["id"],
code: parsedJson["part_code"] ?? parsedJson["name"], code: parsedJson["part_code"] ?? parsedJson["name"],
name: parsedJson["part_name"], name: parsedJson["part_name"],
quantity: parsedJson["qty"] == null quantity: parsedJson["qty"] == null ? 1 : int.tryParse(parsedJson["qty"].toString()) ?? 1,
? 1 : int.tryParse(parsedJson["qty"].toString()) ?? 1,
); );
} }
} }

@ -1,32 +1,31 @@
import 'dart:convert'; import 'dart:convert';
import 'package:test_sa/models/device/device.dart'; import 'device/device.dart';
import 'package:test_sa/models/lookup.dart'; import 'lookup.dart';
import 'package:test_sa/models/part.dart'; import 'part.dart';
import 'package:test_sa/models/timer_model.dart'; import 'timer_model.dart';
class ServiceReport { class ServiceReport {
String id; String? id;
String operatingHours; String? operatingHours;
DateTime visitDate; DateTime? visitDate;
DateTime endDate; DateTime? endDate;
Lookup serviceType; Lookup? serviceType;
Lookup callLastSituation; Lookup? callLastSituation;
Lookup status; Lookup? status;
Lookup type; Lookup? type;
Lookup reason; Lookup? reason;
String faultDescription; String? faultDescription;
String workPreformed; String? workPreformed;
//String workHours; String? travelingHours;
String travelingHours; String? invoiceNumber;
String invoiceNumber; String? invoiceCode;
String invoiceCode; List<Part>? parts;
List<Part> parts; String? image;
String image; Device? device;
Device device; String? quantity;
String quantity; String? jobSheetNumber;
String jobSheetNumber; TimerModel? timer;
TimerModel timer;
ServiceReport({ ServiceReport({
this.id, this.id,
@ -36,7 +35,6 @@ class ServiceReport {
this.status, this.status,
this.type, this.type,
this.faultDescription, this.faultDescription,
//this.workHours,
this.travelingHours, this.travelingHours,
this.parts, this.parts,
this.workPreformed, this.workPreformed,
@ -52,98 +50,95 @@ class ServiceReport {
this.timer, this.timer,
}); });
Map<String,String> toMap(){ Map<String, String> toMap() {
Map<String,String> _map = {}; Map<String, String> _map = {};
if(id != null) _map["id"] = id; if (id != null) _map["id"] = id ?? "";
if(visitDate != null) _map["visit_date"] = (visitDate.millisecondsSinceEpoch ~/ 1000).toString(); if (visitDate != null) _map["visit_date"] = ((visitDate?.millisecondsSinceEpoch ?? 0) ~/ 1000).toString();
if(serviceType != null) _map["service_type"] = serviceType.id.toString(); if (serviceType != null) _map["service_type"] = serviceType?.id.toString() ?? "";
if(status != null) _map["status"] = status.id.toString(); if (status != null) _map["status"] = status?.id.toString() ?? "";
if(type != null) _map["service_report_type"] = type.id.toString(); if (type != null) _map["service_report_type"] = type?.id.toString() ?? "";
if(faultDescription != null && faultDescription.isNotEmpty) _map["fault_description"] = faultDescription; if (faultDescription != null && (faultDescription?.isNotEmpty ?? false)) _map["fault_description"] = faultDescription ?? "";
//if(workHours != null && workHours.isNotEmpty) _map["working_hours"] = workHours; //if(workHours != null && workHours.isNotEmpty) _map["working_hours"] = workHours;
if(timer != null){ if (timer != null) {
_map["start_time"] = (timer.startAt.millisecondsSinceEpoch / 1000).toStringAsFixed(0); _map["start_time"] = ((timer?.startAt?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
_map["end_time"] = ((timer.endAt ?? DateTime.now()).millisecondsSinceEpoch / 1000).toStringAsFixed(0); _map["end_time"] = ((timer?.endAt ?? DateTime.now()).millisecondsSinceEpoch / 1000).toStringAsFixed(0);
_map["working_hours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5); _map["working_hours"] = ((timer?.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5);
} }
if(travelingHours != null && travelingHours.isNotEmpty) _map["traveling_hours"] = travelingHours; if (travelingHours != null && (travelingHours?.isNotEmpty ?? false)) _map["traveling_hours"] = travelingHours ?? "";
if(workPreformed != null && workPreformed.isNotEmpty) _map["work_performed"] = workPreformed; if (workPreformed != null && (workPreformed?.isNotEmpty ?? false)) _map["work_performed"] = workPreformed ?? "";
if(jobSheetNumber != null && jobSheetNumber.isNotEmpty) _map["job_sheet_no"] = jobSheetNumber; if (jobSheetNumber != null && (jobSheetNumber?.isNotEmpty ?? false)) _map["job_sheet_no"] = jobSheetNumber ?? "";
if(parts != null && parts.isNotEmpty){ if (parts != null && (parts?.isNotEmpty ?? false)) {
Map<String,int> _partsMap = {}; Map<String, int> _partsMap = {};
parts.forEach((part) { parts?.forEach((part) {
if(part.id.isNotEmpty) if ((part.id?.isNotEmpty ?? false)) {
_partsMap[part.id] = part.quantity; _partsMap[part?.id ?? ""] = part.quantity;
}
}); });
_map["parts"] = json.encode(_partsMap); _map["parts"] = json.encode(_partsMap);
} }
if(device?.id != null && device.id != null) _map["eq_id"] = device.id; if (device?.id != null && device?.id != null) _map["eq_id"] = device?.id ?? "";
if(quantity != null && quantity.isNotEmpty) _map["qty"] = quantity; if (quantity != null && (quantity?.isNotEmpty ?? false)) _map["qty"] = quantity ?? "";
if(endDate != null) _map["end_date"] = (endDate.millisecondsSinceEpoch ~/ 1000).toString(); if (endDate != null) _map["end_date"] = ((endDate?.millisecondsSinceEpoch ?? 0) ~/ 1000).toString();
if(reason != null) _map["reasons"] = reason.id.toString(); if (reason != null) _map["reasons"] = reason?.id.toString() ?? "";
if(operatingHours != null && operatingHours.isNotEmpty) _map["operation_hours"] = operatingHours; if (operatingHours != null && (operatingHours?.isNotEmpty ?? false)) _map["operation_hours"] = operatingHours ?? "";
if(callLastSituation != null) _map["call_last_situtation"] = callLastSituation.id.toString(); if (callLastSituation != null) _map["call_last_situtation"] = callLastSituation?.id.toString() ?? "";
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 ?? "";
return _map; return _map;
} }
bool validate(){ bool validate() {
if(visitDate == null) return false; if (visitDate == null) return false;
if(serviceType == null) return false; if (serviceType == null) return false;
if(status == null) return false; if (status == null) return false;
if(type == null) return false; if (type == null) return false;
if(callLastSituation == null) return false; if (callLastSituation == null) return false;
if(callLastSituation?.id == 12){ if (callLastSituation?.id == 12) {
if(invoiceCode != null || invoiceCode?.isEmpty == true) return false; if (invoiceCode != null || invoiceCode?.isEmpty == true) return false;
if(invoiceNumber != null || invoiceNumber?.isEmpty== true ) return false; if (invoiceNumber != null || invoiceNumber?.isEmpty == true) return false;
} }
if(parts == null) return false; if (parts == null) return false;
//if(endDate == null) return false; //if(endDate == null) return false;
//if(reason == null) return false; //if(reason == null) return false;
if((device?.id == null || device.id.isEmpty) && type?.id != 1) return false; if ((device?.id == null || (device?.id?.isEmpty ?? false)) && type?.id != 1) return false;
//if(quantity == null || quantity.isEmpty) return false; //if(quantity == null || quantity.isEmpty) return false;
//if(image == null) return false; //if(image == null) return false;
return true; return true;
} }
factory ServiceReport.fromJson(Map<String,dynamic> parsedJson,String id){ factory ServiceReport.fromJson(Map<String, dynamic> parsedJson, String id) {
List<Part> _parts = []; List<Part> _parts = [];
if(parsedJson["parts"] != null){ if (parsedJson["parts"] != null) {
if(parsedJson["parts"][0]["id"] != null){ if (parsedJson["parts"][0]["id"] != null) {
List partsList = parsedJson["parts"]; List partsList = parsedJson["parts"];
_parts = partsList.map((e) => Part.fromJson(e)).toList(); _parts = partsList.map((e) => Part.fromJson(e)).toList();
}
} }
}
return ServiceReport( return ServiceReport(
id: id, id: id,
serviceType: Lookup.fromJson(parsedJson["service_type"]), serviceType: Lookup.fromJson(parsedJson["service_type"]),
callLastSituation: Lookup.fromJson(parsedJson["call_last_situtation"]), callLastSituation: Lookup.fromJson(parsedJson["call_last_situtation"]),
reason: Lookup.fromJson(parsedJson["reasons"]), reason: Lookup.fromJson(parsedJson["reasons"]),
status: Lookup.fromJson(parsedJson["service_report_status"]), status: Lookup.fromJson(parsedJson["service_report_status"]),
type: Lookup.fromJson(parsedJson["service_report_type"]), type: Lookup.fromJson(parsedJson["service_report_type"]),
faultDescription: parsedJson["fault_description"], faultDescription: parsedJson["fault_description"],
endDate:getDate(parsedJson["end_date"]), endDate: getDate(parsedJson["end_date"]),
invoiceCode: parsedJson["invoice_code"], invoiceCode: parsedJson["invoice_code"],
invoiceNumber: parsedJson["invoice_no"], invoiceNumber: parsedJson["invoice_no"],
jobSheetNumber: parsedJson["job_sheet_no"], jobSheetNumber: parsedJson["job_sheet_no"],
operatingHours: parsedJson["operation_hours"], operatingHours: parsedJson["operation_hours"],
parts: _parts, parts: _parts,
quantity: parsedJson["nid"], quantity: parsedJson["nid"],
travelingHours: parsedJson["traveling_hours"], travelingHours: parsedJson["traveling_hours"],
visitDate: getDate(parsedJson["visit_date"]), visitDate: getDate(parsedJson["visit_date"]),
//workHours: parsedJson["working_hours"], //workHours: parsedJson["working_hours"],
timer: TimerModel( timer: TimerModel(durationInSecond: (int.tryParse(parsedJson["working_hours"] ?? "") ?? 0) * 60 * 60),
durationInSecond: (int.tryParse(parsedJson["working_hours"] ?? "") ?? 0) * 60 *60), workPreformed: parsedJson["work_performed"],
workPreformed: parsedJson["work_performed"], device: parsedJson["eq_nid"] == null ? null : Device(id: parsedJson["eq_nid"], serialNumber: parsedJson["eq_serial"]));
device: parsedJson["eq_nid"] == null ? null : Device(id: parsedJson["eq_nid"],serialNumber: parsedJson["eq_serial"])
);
} }
static getDate(String date){ static getDate(String date) {
return date == null || date.isEmpty return date == null || date.isEmpty ? null : DateTime.fromMillisecondsSinceEpoch((int.tryParse(date) ?? 0) * 1000);
? null : DateTime.fromMillisecondsSinceEpoch(int.tryParse(date) * 1000);
} }
} }

@ -1,35 +1,35 @@
import 'package:test_sa/models/lookup.dart'; import '../lookup.dart';
class ServiceRequest{ class ServiceRequest {
String id; String? id;
String requestCode; String? requestCode;
String deviceSerialNumber; String? deviceSerialNumber;
String deviceId; String? deviceId;
String deviceArName; String? deviceArName;
String deviceEnName; String? deviceEnName;
List<String> devicePhotos; List<String>? devicePhotos;
String maintenanceIssue; String? maintenanceIssue;
String hospitalName; String? hospitalName;
String hospitalId; String? hospitalId;
String departmentName; String? departmentName;
String engineerName; String? engineerName;
String date; String? date;
String audio; String? audio;
int statusValue; int? statusValue;
String statusLabel; String? statusLabel;
bool viewReport; bool? viewReport;
String engineerMobile; String? engineerMobile;
String deviceModel; String? deviceModel;
String faultDescription; String? faultDescription;
String workPerformed; String? workPerformed;
String visitDate; String? visitDate;
DateTime nextVisitDate; DateTime? nextVisitDate;
String jobSheetNumber; String? jobSheetNumber;
String reportID; String? reportID;
String deviceNumber; String? deviceNumber;
Lookup priority; Lookup? priority;
Lookup defectType; Lookup? defectType;
ServiceRequest({ ServiceRequest({
this.id, this.id,
@ -48,7 +48,6 @@ class ServiceRequest{
this.deviceId, this.deviceId,
this.audio, this.audio,
this.engineerName, this.engineerName,
this.viewReport = false, this.viewReport = false,
this.deviceModel, this.deviceModel,
this.engineerMobile, this.engineerMobile,
@ -61,42 +60,40 @@ class ServiceRequest{
this.defectType, this.defectType,
this.priority, this.priority,
this.deviceNumber, this.deviceNumber,
}); });
factory ServiceRequest.fromJson(Map<String,dynamic> parsedJson){ factory ServiceRequest.fromJson(Map<String, dynamic> parsedJson) {
return ServiceRequest( return ServiceRequest(
id: parsedJson["nid"], id: parsedJson["nid"],
requestCode: parsedJson["call_id"] ?? parsedJson["jobcode"] , requestCode: parsedJson["call_id"] ?? parsedJson["jobcode"],
hospitalName: parsedJson["call_client"], hospitalName: parsedJson["call_client"],
deviceNumber: parsedJson["device_no"], deviceNumber: parsedJson["device_no"],
deviceId: parsedJson["deviceid"], deviceId: parsedJson["deviceid"],
audio: parsedJson["audio"] ?? "", audio: parsedJson["audio"] ?? "",
deviceArName: parsedJson["equipment_arabic_name"] == false deviceArName: parsedJson["equipment_arabic_name"] == false ? "No Name found" : parsedJson["equipment_arabic_name"],
? "No Name found" : parsedJson["equipment_arabic_name"], deviceEnName: parsedJson["equipment_english_name"] == false ? "No Name found" : parsedJson["equipment_english_name"],
deviceEnName: parsedJson["equipment_english_name"] == false
? "No Name found" : parsedJson["equipment_english_name"],
devicePhotos: List<String>.from(parsedJson["image"]), devicePhotos: List<String>.from(parsedJson["image"]),
deviceSerialNumber: parsedJson["call_sn"], deviceSerialNumber: parsedJson["call_sn"],
date: parsedJson["call_data"], date: parsedJson["call_data"],
maintenanceIssue: parsedJson["call_complaint"] ?? parsedJson["complaint"], maintenanceIssue: parsedJson["call_complaint"] ?? parsedJson["complaint"],
statusLabel: parsedJson["status_value"], statusLabel: parsedJson["status_value"],
statusValue: int.tryParse(parsedJson["status"]??"-1"), statusValue: int.tryParse(parsedJson["status"] ?? "-1"),
departmentName: parsedJson["department_name"], departmentName: parsedJson["department_name"],
engineerName: parsedJson["employee_name"], engineerName: parsedJson["employee_name"],
hospitalId: parsedJson["client"], hospitalId: parsedJson["client"],
reportID: parsedJson["service_report_nid"] is String reportID: parsedJson["service_report_nid"] is String ? parsedJson["service_report_nid"] : null,
? parsedJson["service_report_nid"]
: null ,
viewReport: parsedJson["service_report_nid"] is bool ? false : true, viewReport: parsedJson["service_report_nid"] is bool ? false : true,
deviceModel: parsedJson["device_model"], deviceModel: parsedJson["device_model"],
engineerMobile: parsedJson["engineer_mobile"], engineerMobile: parsedJson["engineer_mobile"],
faultDescription: parsedJson["fault_desc"], faultDescription: parsedJson["fault_desc"],
jobSheetNumber: parsedJson["job_sheet_number"], jobSheetNumber: parsedJson["job_sheet_number"],
visitDate: parsedJson["visit_date"], visitDate: parsedJson["visit_date"],
nextVisitDate:parsedJson["next_visit_date"] == null nextVisitDate: parsedJson["next_visit_date"] == null
? null : DateTime.fromMillisecondsSinceEpoch(int.tryParse(parsedJson["next_visit_date"]) * 1000), ? null
: DateTime.fromMillisecondsSinceEpoch(
(int.tryParse(parsedJson["next_visit_date"]) ?? 0) * 1000,
),
workPerformed: parsedJson["work_performed"], workPerformed: parsedJson["work_performed"],
); );
} }
} }

@ -1,10 +1,9 @@
class ServiceRequestSearch{ class ServiceRequestSearch {
String deviceSerialNumber; String? deviceSerialNumber;
String deviceName; String? deviceName;
String hospital; String? hospital;
String model; String? model;
int statusValue; int? statusValue;
ServiceRequestSearch({ ServiceRequestSearch({
this.deviceSerialNumber, this.deviceSerialNumber,
@ -14,33 +13,20 @@ class ServiceRequestSearch{
this.hospital, this.hospital,
}); });
fromSearch(ServiceRequestSearch newSearch){ fromSearch(ServiceRequestSearch newSearch) {
deviceSerialNumber = newSearch.deviceSerialNumber; deviceSerialNumber = newSearch.deviceSerialNumber;
statusValue = newSearch.statusValue; statusValue = newSearch.statusValue;
hospital = newSearch.hospital; hospital = newSearch.hospital;
model = newSearch.model; model = newSearch.model;
} }
String toSearchString(){ Map<String, dynamic> queryParameters() {
String _search = ""; return <String, dynamic>{
if(deviceSerialNumber != null && deviceSerialNumber.isNotEmpty){ if (deviceSerialNumber != null && (deviceSerialNumber?.isNotEmpty ?? false)) 'sn_id': deviceSerialNumber,
_search += "&sn_id=$deviceSerialNumber"; if (statusValue != null) 'status': statusValue?.toString(),
} if (deviceName != null && (deviceName?.isNotEmpty ?? false)) 'equipment_en_name': deviceName,
if (hospital != null && (hospital?.isNotEmpty ?? false)) 'client': hospital,
if(statusValue != null){ if (model != null && (model?.isNotEmpty ?? false)) 'model': model,
_search += "&status=$statusValue"; };
}
if(deviceName != null && deviceName.isNotEmpty){
_search += "&equipment_en_name=$deviceName";
}
if(hospital != null && hospital.isNotEmpty){
_search += "&client=$hospital";
}
if(model != null && model.isNotEmpty){
_search += "&model=$model";
}
return _search;
} }
} }

@ -1,6 +1,4 @@
import 'package:meta/meta.dart'; class Subtitle {
class Subtitle{
// http requests status messages // http requests status messages
String currentlyServiceNotAvailable; String currentlyServiceNotAvailable;
String waitUntilYourRequestComplete; String waitUntilYourRequestComplete;
@ -179,7 +177,7 @@ class Subtitle{
String requiredStatus; String requiredStatus;
String visitInformation; String visitInformation;
String expectDate; String expectDate;
String actualDate; String? actualDate;
String noVisitsFound; String noVisitsFound;
String contactStatus; String contactStatus;
String workingHours; String workingHours;
@ -216,7 +214,7 @@ class Subtitle{
String duplicateAlertMessage; String duplicateAlertMessage;
String alert; String alert;
void setIssues(List<String> issues){ void setIssues(List<String> issues) {
issues.clear(); issues.clear();
issues.add(reason1); issues.add(reason1);
issues.add(reason2); issues.add(reason2);
@ -226,190 +224,188 @@ class Subtitle{
} }
Subtitle({ Subtitle({
@required this.currentlyServiceNotAvailable, required this.currentlyServiceNotAvailable,
@required this.waitUntilYourRequestComplete, required this.waitUntilYourRequestComplete,
@required this.requestCompleteSuccessfully, required this.requestCompleteSuccessfully,
@required this.failedToCompleteRequest, required this.failedToCompleteRequest,
@required this.update, required this.update,
@required this.cancel, required this.cancel,
@required this.confirm, required this.confirm,
@required this.exit, required this.exit,
@required this.exitAlert, required this.exitAlert,
@required this.signOutAlert, required this.signOutAlert,
@required this.language, required this.language,
@required this.name, required this.name,
@required this.email, required this.email,
@required this.phoneNumber, required this.phoneNumber,
@required this.password, required this.password,
@required this.forgetPassword, required this.forgetPassword,
@required this.confirmPassword, required this.confirmPassword,
@required this.signIn, required this.signIn,
@required this.signUp, required this.signUp,
@required this.nameValidateMessage, required this.nameValidateMessage,
@required this.emailValidateMessage, required this.emailValidateMessage,
@required this.phoneNumberValidateMessage, required this.phoneNumberValidateMessage,
@required this.passwordValidateMessage, required this.passwordValidateMessage,
@required this.confirmPasswordValidateMessage, required this.confirmPasswordValidateMessage,
@required this.emailExist, required this.emailExist,
@required this.forgetPasswordWithMark, required this.forgetPasswordWithMark,
@required this.phoneNumberExist, required this.phoneNumberExist,
@required this.showPassword, required this.showPassword,
@required this.signOut, required this.signOut,
@required this.wrongEmailOrPassword, required this.wrongEmailOrPassword,
@required this.next, required this.next,
@required this.back, required this.back,
@required this.search, required this.search,
@required this.searchByName, required this.searchByName,
@required this.address, required this.address,
@required this.description, required this.description,
@required this.title, required this.title,
@required this.addressNotFound, required this.addressNotFound,
@required this.addressValidateMessage, required this.addressValidateMessage,
@required this.dataNotFound, required this.dataNotFound,
@required this.descriptionNotFound, required this.descriptionNotFound,
@required this.descriptionValidateMessage, required this.descriptionValidateMessage,
@required this.edit, required this.edit,
@required this.emailNotFound, required this.emailNotFound,
@required this.from, required this.from,
@required this.linkNotFound, required this.linkNotFound,
@required this.nameNotFound, required this.nameNotFound,
@required this.phoneNumberNotFound, required this.phoneNumberNotFound,
@required this.titleNotFound, required this.titleNotFound,
@required this.titleValidateMessage, required this.titleValidateMessage,
@required this.to, required this.to,
@required this.urlNotFound, required this.urlNotFound,
required this.nameExist,
@required this.nameExist, required this.unitRequired,
@required this.unitRequired, required this.unite,
@required this.unite, required this.hospitalRequired,
@required this.hospitalRequired, required this.whatsApp,
@required this.whatsApp, required this.submit,
@required this.submit, required this.shareAntherIssue,
@required this.shareAntherIssue, required this.reportIssue,
@required this.reportIssue, required this.noUniteFound,
@required this.noUniteFound, required this.pickUnite,
@required this.pickUnite, required this.noHospitalFound,
@required this.noHospitalFound, required this.pickHospital,
@required this.pickHospital, required this.shareApp,
@required this.shareApp, required this.ourWebsite,
@required this.ourWebsite, required this.linkedIn,
@required this.linkedIn, required this.facebook,
@required this.facebook, required this.hotLine,
@required this.hotLine, required this.trackServiceRequest,
@required this.trackServiceRequest, required this.newServiceRequest,
@required this.newServiceRequest, required this.deviceModel,
@required this.deviceModel, required this.noServiceRequestFound,
@required this.noServiceRequestFound, required this.engineerName,
@required this.engineerName, required this.serviceRequests,
@required this.serviceRequests, required this.jobSheetNumber,
@required this.jobSheetNumber, required this.visitDate,
@required this.visitDate, required this.workPerformed,
@required this.workPerformed, required this.faultDescription,
@required this.faultDescription, required this.serviceRequestInformation,
@required this.serviceRequestInformation, required this.maintenanceIssue,
@required this.maintenanceIssue, required this.deviceArName,
@required this.deviceArName, required this.hospital,
@required this.hospital, required this.status,
@required this.status, required this.date,
@required this.date, required this.engineerPhone,
@required this.engineerPhone, required this.device,
@required this.device, required this.deviceSN,
@required this.deviceSN, required this.details,
@required this.details, required this.requestInformation,
@required this.requestInformation, required this.model,
@required this.model, required this.brand,
@required this.brand, required this.noDeviceFound,
@required this.noDeviceFound, required this.noDateFound,
@required this.noDateFound, required this.searchBySn,
@required this.searchBySn, required this.pickDevice,
@required this.pickDevice, required this.notifications,
@required this.notifications, required this.notificationsNotFound,
@required this.notificationsNotFound, required this.twitter,
@required this.twitter, required this.add,
@required this.add, required this.code,
@required this.code, required this.deviceEnName,
@required this.deviceEnName, required this.deviceName,
@required this.deviceName, required this.serialNumber,
@required this.serialNumber, required this.policy,
@required this.policy, required this.clearSearch,
@required this.clearSearch, required this.closed,
@required this.closed, required this.create,
@required this.create, required this.createServiceRequest,
@required this.createServiceRequest, required this.delete,
@required this.delete, required this.deviceImages,
@required this.deviceImages, required this.deviceRequired,
@required this.deviceRequired, required this.general,
@required this.general, required this.maintenanceIssueRequired,
@required this.maintenanceIssueRequired, required this.maxImagesNumberIs5,
@required this.maxImagesNumberIs5, required this.newWord,
@required this.newWord, required this.noModelFound,
@required this.noModelFound, required this.noSnFound,
@required this.noSnFound, required this.reason1,
@required this.reason1, required this.reason2,
@required this.reason2, required this.reason3,
@required this.reason3, required this.reason4,
@required this.reason4, required this.reason5,
@required this.reason5, required this.repaired,
@required this.repaired, required this.repeated,
@required this.repeated, required this.sn,
@required this.sn, required this.underRepair,
@required this.underRepair, required this.actualDate,
@required this.actualDate, required this.expectDate,
@required this.expectDate, required this.visitInformation,
@required this.visitInformation, required this.regularVisitsUpdatedSuccessfully,
@required this.regularVisitsUpdatedSuccessfully, required this.regularVisits,
@required this.regularVisits, required this.updateRegularVisits,
@required this.updateRegularVisits, required this.updatingDots,
@required this.updatingDots, required this.preventiveMaintenanceUpdatedSuccessfully,
@required this.preventiveMaintenanceUpdatedSuccessfully, required this.updatePreventiveMaintenance,
@required this.updatePreventiveMaintenance, required this.preventiveMaintenance,
@required this.preventiveMaintenance, required this.requiredStatus,
@required this.requiredStatus, required this.noSerialNumberFound,
@required this.noSerialNumberFound, required this.updateVisitsGroup,
@required this.updateVisitsGroup, required this.pickFromGallery,
@required this.pickFromGallery, required this.pickFromCamera,
@required this.pickFromCamera, required this.images,
@required this.images, required this.done,
@required this.done, required this.imagesRequired,
@required this.imagesRequired, required this.notYet,
@required this.notYet, required this.noVisitsFound,
@required this.noVisitsFound, required this.onHold,
@required this.onHold, required this.nextVisitDate,
@required this.nextVisitDate, required this.contactStatus,
@required this.contactStatus, required this.travelingHours,
@required this.travelingHours, required this.workingHours,
@required this.workingHours, required this.taskStatus,
@required this.taskStatus, required this.image,
@required this.image, required this.pickImage,
@required this.pickImage, required this.requiredImage,
@required this.requiredImage, required this.activationAlert,
@required this.activationAlert, required this.callId,
required this.requiredWord,
@required this.callId, required this.quantity,
@required this.requiredWord, required this.callLastSituation,
@required this.quantity, required this.invoiceNumber,
@required this.callLastSituation, required this.invoiceCode,
@required this.invoiceNumber, required this.attachImage,
@required this.invoiceCode, required this.customer,
@required this.attachImage, required this.editServiceReport,
@required this.customer, required this.newServiceReport,
@required this.editServiceReport, required this.number,
@required this.newServiceReport, required this.operatingHours,
@required this.number, required this.partNumber,
@required this.operatingHours, required this.reasons,
@required this.partNumber, required this.reportStatus,
@required this.reasons, required this.reportType,
@required this.reportStatus, required this.serviceType,
@required this.reportType, required this.workPreformed,
@required this.serviceType, required this.alert,
@required this.workPreformed, required this.duplicateAlert,
@required this.alert, required this.duplicateAlertMessage,
@required this.duplicateAlert, required this.duplicateRequest,
@required this.duplicateAlertMessage,
@required this.duplicateRequest,
}); });
factory Subtitle.fromJson(Map<String,dynamic> parsedJson){ factory Subtitle.fromJson(Map<String, dynamic> parsedJson) {
return Subtitle( return Subtitle(
currentlyServiceNotAvailable: parsedJson["server_error_message"], currentlyServiceNotAvailable: parsedJson["server_error_message"],
failedToCompleteRequest: parsedJson["failed_request_message"], failedToCompleteRequest: parsedJson["failed_request_message"],
@ -423,7 +419,6 @@ class Subtitle{
signOut: parsedJson["sign_out"], signOut: parsedJson["sign_out"],
signOutAlert: parsedJson["logout_alert"], signOutAlert: parsedJson["logout_alert"],
language: parsedJson["language"], language: parsedJson["language"],
name: parsedJson["name"], name: parsedJson["name"],
email: parsedJson["email"], email: parsedJson["email"],
phoneNumber: parsedJson["phone_number"], phoneNumber: parsedJson["phone_number"],
@ -437,7 +432,6 @@ class Subtitle{
passwordValidateMessage: parsedJson["password_validate_message"], passwordValidateMessage: parsedJson["password_validate_message"],
confirmPasswordValidateMessage: parsedJson["confirm_password_validate_message"], confirmPasswordValidateMessage: parsedJson["confirm_password_validate_message"],
phoneNumberValidateMessage: parsedJson["phone_number_validate_message"], phoneNumberValidateMessage: parsedJson["phone_number_validate_message"],
forgetPasswordWithMark: parsedJson["forget_password_with_mark"], forgetPasswordWithMark: parsedJson["forget_password_with_mark"],
showPassword: parsedJson["show_password"], showPassword: parsedJson["show_password"],
wrongEmailOrPassword: parsedJson["wrong_email_or_password"], wrongEmailOrPassword: parsedJson["wrong_email_or_password"],
@ -447,7 +441,6 @@ class Subtitle{
back: parsedJson["back"], back: parsedJson["back"],
search: parsedJson["search"], search: parsedJson["search"],
searchByName: parsedJson["search_by_name"], searchByName: parsedJson["search_by_name"],
address: parsedJson["address"], address: parsedJson["address"],
addressNotFound: parsedJson["address_not_found"], addressNotFound: parsedJson["address_not_found"],
addressValidateMessage: parsedJson["address_validate_message"], addressValidateMessage: parsedJson["address_validate_message"],
@ -466,7 +459,6 @@ class Subtitle{
titleNotFound: parsedJson["title_not_found"], titleNotFound: parsedJson["title_not_found"],
titleValidateMessage: parsedJson["title_validate_message"], titleValidateMessage: parsedJson["title_validate_message"],
urlNotFound: parsedJson["url_not_found"], urlNotFound: parsedJson["url_not_found"],
date: parsedJson["date"], date: parsedJson["date"],
status: parsedJson["status"], status: parsedJson["status"],
code: parsedJson["code"], code: parsedJson["code"],
@ -542,7 +534,6 @@ class Subtitle{
visitDate: parsedJson["visitDate"], visitDate: parsedJson["visitDate"],
whatsApp: parsedJson["whatsApp"], whatsApp: parsedJson["whatsApp"],
workPerformed: parsedJson["workPerformed"], workPerformed: parsedJson["workPerformed"],
actualDate: parsedJson["actualDate"], actualDate: parsedJson["actualDate"],
done: parsedJson["done"], done: parsedJson["done"],
expectDate: parsedJson["expectDate"], expectDate: parsedJson["expectDate"],
@ -573,7 +564,6 @@ class Subtitle{
requiredImage: parsedJson["requiredImage"], requiredImage: parsedJson["requiredImage"],
taskStatus: parsedJson["taskStatus"], taskStatus: parsedJson["taskStatus"],
activationAlert: parsedJson["activationAlert"], activationAlert: parsedJson["activationAlert"],
attachImage: parsedJson["attachImage"], attachImage: parsedJson["attachImage"],
callLastSituation: parsedJson["callLastSituation"], callLastSituation: parsedJson["callLastSituation"],
customer: parsedJson["customer"], customer: parsedJson["customer"],
@ -592,12 +582,10 @@ class Subtitle{
requiredWord: parsedJson["requiredWord"], requiredWord: parsedJson["requiredWord"],
serviceType: parsedJson["serviceType"], serviceType: parsedJson["serviceType"],
workPreformed: parsedJson["workPreformed"], workPreformed: parsedJson["workPreformed"],
alert: parsedJson["alert"], alert: parsedJson["alert"],
duplicateAlert: parsedJson["duplicateAlert"], duplicateAlert: parsedJson["duplicateAlert"],
duplicateAlertMessage: parsedJson["duplicateAlertMessage"], duplicateAlertMessage: parsedJson["duplicateAlertMessage"],
duplicateRequest: parsedJson["duplicateRequest"], duplicateRequest: parsedJson["duplicateRequest"],
); );
} }
}
}

@ -1,7 +1,7 @@
class TimerModel { class TimerModel {
DateTime startAt; DateTime? startAt;
DateTime endAt; DateTime? endAt;
int durationInSecond; int? durationInSecond;
TimerModel({this.startAt,this.endAt,this.durationInSecond}); TimerModel({this.startAt, this.endAt, this.durationInSecond});
} }

@ -1,50 +1,161 @@
import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; import '../controllers/notification/firebase_notification_manger.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/hospital.dart';
class User { class User {
String id; String? clientId;
String userName; String? clientName;
String password; int? departmentId;
String email; String? departmentName;
String image; String? message;
Hospital hospital; String? username;
Department department; String? userID;
UsersTypes type; String? email;
String phoneNumber; String? password;
String whatsApp; String? token;
String token; String? roles;
bool isActive; List<String>? userRoles;
String? tokenlife;
bool? isAuthenticated;
bool? hasError;
String? profilePhotoName;
String? id;
String? userName;
String? normalizedUserName;
String? normalizedEmail;
bool? emailConfirmed;
String? passwordHash;
String? securityStamp;
String? concurrencyStamp;
User( ///I'm not sure from the datatype
{this.id, String? phoneNumber;
this.userName = "", bool? phoneNumberConfirmed;
this.email = "", bool? twoFactorEnabled;
this.password = "",
this.phoneNumber = "", ///I'm not sure from the datatype
this.hospital, String? lockoutEnd;
this.image, bool? lockoutEnabled;
this.department, int? accessFailedCount;
this.type,
this.whatsApp, User({
this.token, this.clientId,
this.isActive = false}); this.clientName,
this.departmentId,
this.departmentName,
this.message,
this.username,
this.userID,
this.email,
this.password,
this.token,
this.roles,
this.userRoles,
this.tokenlife,
this.isAuthenticated,
this.hasError,
this.profilePhotoName,
this.id,
this.userName,
this.normalizedUserName,
this.normalizedEmail,
this.emailConfirmed,
this.passwordHash,
this.securityStamp,
this.concurrencyStamp,
this.phoneNumber,
this.phoneNumberConfirmed,
this.twoFactorEnabled,
this.lockoutEnd,
this.lockoutEnabled,
this.accessFailedCount,
});
User.fromJson(Map<String, dynamic> json) {
clientId = json['client_id'];
clientName = json['client_name'];
departmentId = json['department_id'];
departmentName = json['department_name'];
message = json['message'];
username = json['username'];
userID = json['userID'];
email = json['email'];
password = json['password'];
token = json['token'];
roles = json['roles'];
if (json['userRoles'] != null) {
userRoles = <String>[];
json['userRoles'].forEach((v) {
userRoles!.add(v);
});
}
tokenlife = json['tokenlife'];
isAuthenticated = json['isAuthenticated'];
hasError = json['hasError'];
profilePhotoName = json['profilePhotoName'];
id = json['id'];
userName = json['userName'];
normalizedUserName = json['normalizedUserName'];
normalizedEmail = json['normalizedEmail'];
emailConfirmed = json['emailConfirmed'];
passwordHash = json['passwordHash'];
securityStamp = json['securityStamp'];
concurrencyStamp = json['concurrencyStamp'];
phoneNumber = json['phoneNumber'];
phoneNumberConfirmed = json['phoneNumberConfirmed'];
twoFactorEnabled = json['twoFactorEnabled'];
lockoutEnd = json['lockoutEnd'];
lockoutEnabled = json['lockoutEnabled'];
accessFailedCount = json['accessFailedCount'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['client_id'] = clientId;
data['client_name'] = clientName;
data['department_id'] = departmentId;
data['department_name'] = departmentName;
data['message'] = message;
data['username'] = username;
data['userID'] = userID;
data['email'] = email;
data['password'] = password;
data['token'] = token;
data['roles'] = roles;
data['userRoles'] = userRoles;
data['tokenlife'] = tokenlife;
data['isAuthenticated'] = isAuthenticated;
data['hasError'] = hasError;
data['profilePhotoName'] = profilePhotoName;
data['id'] = id;
data['userName'] = userName;
data['normalizedUserName'] = normalizedUserName;
data['normalizedEmail'] = normalizedEmail;
data['emailConfirmed'] = emailConfirmed;
data['passwordHash'] = passwordHash;
data['securityStamp'] = securityStamp;
data['concurrencyStamp'] = concurrencyStamp;
data['phoneNumber'] = phoneNumber;
data['phoneNumberConfirmed'] = phoneNumberConfirmed;
data['twoFactorEnabled'] = twoFactorEnabled;
data['lockoutEnd'] = lockoutEnd;
data['lockoutEnabled'] = lockoutEnabled;
data['accessFailedCount'] = accessFailedCount;
return data;
}
Future<Map<String, dynamic>> toLoginJson() async { Future<Map<String, dynamic>> toLoginJson() async {
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
return { return {
"username": userName, "username": userName,
"pass": password, "password": password,
"firebase_token": FirebaseNotificationManger?.token ?? "", "fireBaseToken": FirebaseNotificationManger.token ?? "",
}; };
} }
Map<String, dynamic> toUpdateProfileJson() { Map<String, dynamic> toUpdateProfileJson() {
Map<String, dynamic> jsonObject = {}; Map<String, dynamic> jsonObject = {};
if (department?.id != null && department.id.isNotEmpty) jsonObject["department"] = department.id; // if (department?.id != null && (department?.id?.isNotEmpty ?? false)) jsonObject["department"] = department?.id ?? "";
if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp; // if (whatsApp != null && (whatsApp?.isNotEmpty ?? false)) jsonObject["whatsapp"] = whatsApp;
if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber; // if (phoneNumber != null && (phoneNumber?.isNotEmpty ?? false)) jsonObject["phoneNumber"] = phoneNumber;
return jsonObject; return jsonObject;
} }
@ -53,59 +164,12 @@ class User {
return { return {
"username": userName, "username": userName,
"email": email, "email": email,
"whatsapp": whatsApp, // "whatsapp": whatsApp,
"client": hospital.id, // "client": hospital?.id,
"department": department?.id, // "department": department?.id,
"phone": phoneNumber, "phoneNumber": phoneNumber,
"pass": password,
"firebase_token": FirebaseNotificationManger?.token ?? "",
};
}
Map<String, dynamic> toJson() {
return {
"uid": id,
"name": userName,
"email": email,
"token": token,
"phone": phoneNumber,
"whatsapp": whatsApp,
"client": hospital?.id,
"client_name": hospital?.name,
"department": department?.id,
"department_name": department?.name,
"password": password, "password": password,
"picture": image, "fireBaseToken": FirebaseNotificationManger.token ?? "",
"active": isActive ? 1 : 0,
"role": type == UsersTypes.engineer ? "field_engineer" : "normal_user",
// "token":token, pass is token
}; };
} }
factory User.fromJson(Map<String, dynamic> parsedJson) {
UsersTypes type;
switch (parsedJson["role"]) {
case "field_engineer":
type = UsersTypes.engineer;
break;
default:
type = UsersTypes.normal_user;
break;
}
return User(
id: parsedJson["uid"],
userName: parsedJson["name"] ?? parsedJson["title"],
email: parsedJson["mail"] ?? parsedJson["email"],
hospital: Hospital(id: parsedJson["client"], name: parsedJson["client_name"]),
department: Department(
id: parsedJson["department"],
name: parsedJson["department_name"],
),
image: parsedJson["picture"],
phoneNumber: parsedJson["phone"],
whatsApp: parsedJson["whatsapp"],
token: parsedJson["token"],
isActive: parsedJson["active"] == "1",
type: type);
}
} }

@ -1,69 +1,433 @@
import 'package:test_sa/models/lookup.dart'; class Visit {
int? id;
class Visit{ int? visitNo;
String id; String? visitCode;
String serialNumber; int? ppmId;
String expectDate; int? planNo;
String actualDate; String? planCode;
String hospitalId; int? ppmScheduleId;
String hospitalName; int? ppmScheduleNo;
String deviceId; String? ppmScheduleCode;
String deviceSerialNumber; int? assetId;
String deviceArabicName; String? assetName;
String deviceEnglishName; String? assetSerialNo;
String employId; String? assetNumber;
String employName; String? warrantyEndDate;
String modelAndBrand; int? modelId;
String contactStatus; String? modelName;
Lookup status; int? manufacturerId;
String assignTo; String? manufacturerName;
String deviceNumber; int? siteId;
List<String> images; String? siteName;
int? assignedToId;
Visit({ String? assignedToName;
this.id, String? jobSheetNo;
this.serialNumber, String? assignedEmployeeId;
this.hospitalId, String? assignedEmployeeName;
this.hospitalName, String? expectedDate;
this.deviceId, String? actualDate;
this.deviceSerialNumber, String? nextDate;
this.deviceArabicName, String? forwardToId;
this.deviceEnglishName, String? forwardToName;
this.employId, int? maintenanceContractId;
this.employName, String? contractNumber;
this.expectDate, int? typeOfServiceId;
this.actualDate, String? typeOfServiceName;
this.status, int? executionTimeFrameId;
this.modelAndBrand, String? executionTimeFrameName;
this.contactStatus, String? externalEngineer;
this.images, String? telephone;
this.assignTo, int? groupLeaderReviewId;
this.deviceNumber, String? groupLeaderReviewName;
}); int? timePeriodId;
String? timePeriodName;
factory Visit.fromJson(Map<String,dynamic> parsedJson){ List<VCalibrationTools>? vCalibrationTools;
return Visit( List<VKits>? vKits;
id: parsedJson["nid"], List<VContacts>? vContacts;
serialNumber: parsedJson["title"], List<VChecklists>? vChecklists;
hospitalId: parsedJson["client"], List<String>? vAttachments;
deviceNumber: parsedJson["device_no"], int? visitStatusId;
hospitalName: parsedJson["client_name"], String? visitStatusName;
deviceId: parsedJson["medical_equipment_nid"], String? startDate;
deviceSerialNumber: parsedJson["medical_equipment"], String? endDate;
deviceEnglishName: parsedJson["equipment_english_name"], String? workingHours;
deviceArabicName: parsedJson["equipment_arabic_name"], String? travelingHours;
employId: parsedJson["assigned_employee"], int? deviceStatusId;
employName: parsedJson["assigned_employee_name"], String? deviceStatusName;
expectDate: parsedJson["expected_date"], String? comments;
actualDate: parsedJson["actual_date"], String? workPerformed;
modelAndBrand: parsedJson["mode_brand"], int? supplierId;
contactStatus: parsedJson["contactStatus"], String? supplierName;
images: List<String>.from(parsedJson["images"] ?? []), int? ppmSupplierId;
status: Lookup( String? ppmSupplierName;
id: int.tryParse(parsedJson["status"] ?? "-1"), // actual value (0,1,2) String? createdOn;
label: parsedJson["status_value"] // text value String? modifiedOn;
), int? taskStatusId;
assignTo: parsedJson["assigned_to"], String? taskStatusName;
);
Visit(
{this.id,
this.visitNo,
this.visitCode,
this.ppmId,
this.planNo,
this.planCode,
this.ppmScheduleId,
this.ppmScheduleNo,
this.ppmScheduleCode,
this.assetId,
this.assetName,
this.assetSerialNo,
this.assetNumber,
this.warrantyEndDate,
this.modelId,
this.modelName,
this.manufacturerId,
this.manufacturerName,
this.siteId,
this.siteName,
this.assignedToId,
this.assignedToName,
this.jobSheetNo,
this.assignedEmployeeId,
this.assignedEmployeeName,
this.expectedDate,
this.actualDate,
this.nextDate,
this.forwardToId,
this.forwardToName,
this.maintenanceContractId,
this.contractNumber,
this.typeOfServiceId,
this.typeOfServiceName,
this.executionTimeFrameId,
this.executionTimeFrameName,
this.externalEngineer,
this.telephone,
this.groupLeaderReviewId,
this.groupLeaderReviewName,
this.timePeriodId,
this.timePeriodName,
this.vCalibrationTools,
this.vKits,
this.vContacts,
this.vChecklists,
this.vAttachments,
this.visitStatusId,
this.visitStatusName,
this.startDate,
this.endDate,
this.workingHours,
this.travelingHours,
this.deviceStatusId,
this.deviceStatusName,
this.comments,
this.workPerformed,
this.supplierId,
this.supplierName,
this.ppmSupplierId,
this.ppmSupplierName,
this.createdOn,
this.modifiedOn,
this.taskStatusId,
this.taskStatusName});
Visit.fromJson(Map<String, dynamic> json) {
id = json['id'];
visitNo = json['visitNo'];
visitCode = json['visitCode'];
ppmId = json['ppmId'];
planNo = json['planNo'];
planCode = json['planCode'];
ppmScheduleId = json['ppmScheduleId'];
ppmScheduleNo = json['ppmScheduleNo'];
ppmScheduleCode = json['ppmScheduleCode'];
assetId = json['assetId'];
assetName = json['assetName'];
assetSerialNo = json['assetSerialNo'];
assetNumber = json['assetNumber'];
warrantyEndDate = json['warrantyEndDate'];
modelId = json['modelId'];
modelName = json['modelName'];
manufacturerId = json['manufacturerId'];
manufacturerName = json['manufacturerName'];
siteId = json['siteId'];
siteName = json['siteName'];
assignedToId = json['assignedToId'];
assignedToName = json['assignedToName'];
jobSheetNo = json['jobSheetNo'];
assignedEmployeeId = json['assignedEmployeeId'];
assignedEmployeeName = json['assignedEmployeeName'];
expectedDate = json['expectedDate'];
actualDate = json['actualDate'];
nextDate = json['nextDate'];
forwardToId = json['forwardToId'];
forwardToName = json['forwardToName'];
maintenanceContractId = json['maintenanceContractId'];
contractNumber = json['contractNumber'];
typeOfServiceId = json['typeOfServiceId'];
typeOfServiceName = json['typeOfServiceName'];
executionTimeFrameId = json['executionTimeFrameId'];
executionTimeFrameName = json['executionTimeFrameName'];
externalEngineer = json['externalEngineer'];
telephone = json['telephone'];
groupLeaderReviewId = json['groupLeaderReviewId'];
groupLeaderReviewName = json['groupLeaderReviewName'];
timePeriodId = json['timePeriodId'];
timePeriodName = json['timePeriodName'];
if (json['vCalibrationTools'] != null) {
vCalibrationTools = <VCalibrationTools>[];
json['vCalibrationTools'].forEach((v) {
vCalibrationTools!.add(VCalibrationTools.fromJson(v));
});
}
if (json['vKits'] != null) {
vKits = <VKits>[];
json['vKits'].forEach((v) {
vKits!.add(VKits.fromJson(v));
});
}
if (json['vContacts'] != null) {
vContacts = <VContacts>[];
json['vContacts'].forEach((v) {
vContacts!.add(VContacts.fromJson(v));
});
}
if (json['vChecklists'] != null) {
vChecklists = <VChecklists>[];
json['vChecklists'].forEach((v) {
vChecklists!.add(VChecklists.fromJson(v));
});
}
vAttachments = json['vAttachments'].cast<String>();
visitStatusId = json['visitStatusId'];
visitStatusName = json['visitStatusName'];
startDate = json['startDate'];
endDate = json['endDate'];
workingHours = json['workingHours'];
travelingHours = json['travelingHours'];
deviceStatusId = json['deviceStatusId'];
deviceStatusName = json['deviceStatusName'];
comments = json['comments'];
workPerformed = json['workPerformed'];
supplierId = json['supplierId'];
supplierName = json['supplierName'];
ppmSupplierId = json['ppmSupplierId'];
ppmSupplierName = json['ppmSupplierName'];
createdOn = json['createdOn'];
modifiedOn = json['modifiedOn'];
taskStatusId = json['taskStatusId'];
taskStatusName = json['taskStatusName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['visitNo'] = visitNo;
data['visitCode'] = visitCode;
data['ppmId'] = ppmId;
data['planNo'] = planNo;
data['planCode'] = planCode;
data['ppmScheduleId'] = ppmScheduleId;
data['ppmScheduleNo'] = ppmScheduleNo;
data['ppmScheduleCode'] = ppmScheduleCode;
data['assetId'] = assetId;
data['assetName'] = assetName;
data['assetSerialNo'] = assetSerialNo;
data['assetNumber'] = assetNumber;
data['warrantyEndDate'] = warrantyEndDate;
data['modelId'] = modelId;
data['modelName'] = modelName;
data['manufacturerId'] = manufacturerId;
data['manufacturerName'] = manufacturerName;
data['siteId'] = siteId;
data['siteName'] = siteName;
data['assignedToId'] = assignedToId;
data['assignedToName'] = assignedToName;
data['jobSheetNo'] = jobSheetNo;
data['assignedEmployeeId'] = assignedEmployeeId;
data['assignedEmployeeName'] = assignedEmployeeName;
data['expectedDate'] = expectedDate;
data['actualDate'] = actualDate;
data['nextDate'] = nextDate;
data['forwardToId'] = forwardToId;
data['forwardToName'] = forwardToName;
data['maintenanceContractId'] = maintenanceContractId;
data['contractNumber'] = contractNumber;
data['typeOfServiceId'] = typeOfServiceId;
data['typeOfServiceName'] = typeOfServiceName;
data['executionTimeFrameId'] = executionTimeFrameId;
data['executionTimeFrameName'] = executionTimeFrameName;
data['externalEngineer'] = externalEngineer;
data['telephone'] = telephone;
data['groupLeaderReviewId'] = groupLeaderReviewId;
data['groupLeaderReviewName'] = groupLeaderReviewName;
data['timePeriodId'] = timePeriodId;
data['timePeriodName'] = timePeriodName;
if (vCalibrationTools != null) {
data['vCalibrationTools'] = vCalibrationTools!.map((v) => v.toJson()).toList();
}
if (vKits != null) {
data['vKits'] = vKits!.map((v) => v.toJson()).toList();
}
if (vContacts != null) {
data['vContacts'] = vContacts!.map((v) => v.toJson()).toList();
}
if (vChecklists != null) {
data['vChecklists'] = vChecklists!.map((v) => v.toJson()).toList();
}
data['vAttachments'] = vAttachments;
data['visitStatusId'] = visitStatusId;
data['visitStatusName'] = visitStatusName;
data['startDate'] = startDate;
data['endDate'] = endDate;
data['workingHours'] = workingHours;
data['travelingHours'] = travelingHours;
data['deviceStatusId'] = deviceStatusId;
data['deviceStatusName'] = deviceStatusName;
data['comments'] = comments;
data['workPerformed'] = workPerformed;
data['supplierId'] = supplierId;
data['supplierName'] = supplierName;
data['ppmSupplierId'] = ppmSupplierId;
data['ppmSupplierName'] = ppmSupplierName;
data['createdOn'] = createdOn;
data['modifiedOn'] = modifiedOn;
data['taskStatusId'] = taskStatusId;
data['taskStatusName'] = taskStatusName;
return data;
}
}
class VCalibrationTools {
int? id;
int? visitId;
int? assetId;
String? assetSerialNo;
String? calibrationDateOfTesters;
VCalibrationTools({this.id, this.visitId, this.assetId, this.assetSerialNo, this.calibrationDateOfTesters});
VCalibrationTools.fromJson(Map<String, dynamic> json) {
id = json['id'];
visitId = json['visitId'];
assetId = json['assetId'];
assetSerialNo = json['assetSerialNo'];
calibrationDateOfTesters = json['calibrationDateOfTesters'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['visitId'] = visitId;
data['assetId'] = assetId;
data['assetSerialNo'] = assetSerialNo;
data['calibrationDateOfTesters'] = calibrationDateOfTesters;
return data;
}
}
class VKits {
int? id;
int? visitId;
int? partCatalogItemId;
String? partNumber;
String? oracleCode;
String? partName;
String? partName2;
VKits({this.id, this.visitId, this.partCatalogItemId, this.partNumber, this.oracleCode, this.partName, this.partName2});
VKits.fromJson(Map<String, dynamic> json) {
id = json['id'];
visitId = json['visitId'];
partCatalogItemId = json['partCatalogItemId'];
partNumber = json['partNumber'];
oracleCode = json['oracleCode'];
partName = json['partName'];
partName2 = json['partName2'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['visitId'] = visitId;
data['partCatalogItemId'] = partCatalogItemId;
data['partNumber'] = partNumber;
data['oracleCode'] = oracleCode;
data['partName'] = partName;
data['partName2'] = partName2;
return data;
}
}
class VContacts {
int? id;
int? visitId;
String? title;
String? person;
String? job;
String? email;
String? telephone;
String? landLine;
VContacts({this.id, this.visitId, this.title, this.person, this.job, this.email, this.telephone, this.landLine});
VContacts.fromJson(Map<String, dynamic> json) {
id = json['id'];
visitId = json['visitId'];
title = json['title'];
person = json['person'];
job = json['job'];
email = json['email'];
telephone = json['telephone'];
landLine = json['landLine'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['visitId'] = visitId;
data['title'] = title;
data['person'] = person;
data['job'] = job;
data['email'] = email;
data['telephone'] = telephone;
data['landLine'] = landLine;
return data;
}
}
class VChecklists {
int? id;
int? visitId;
String? task;
int? taskStatusId;
String? taskStatusName;
String? taskComment;
String? measuredValue;
VChecklists({this.id, this.visitId, this.task, this.taskStatusId, this.taskStatusName, this.taskComment, this.measuredValue});
VChecklists.fromJson(Map<String, dynamic> json) {
id = json['id'];
visitId = json['visitId'];
task = json['task'];
taskStatusId = json['taskStatusId'];
taskStatusName = json['taskStatusName'];
taskComment = json['taskComment'];
measuredValue = json['measuredValue'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['visitId'] = visitId;
data['task'] = task;
data['taskStatusId'] = taskStatusId;
data['taskStatusName'] = taskStatusName;
data['taskComment'] = taskComment;
data['measuredValue'] = measuredValue;
return data;
} }
} }

@ -1,17 +1,16 @@
import '../lookup.dart';
import 'visit.dart';
import 'package:test_sa/models/lookup.dart'; class VisitsGroup {
import 'package:test_sa/models/visits/visit.dart'; String? userId;
String? workingHours;
class VisitsGroup{ String? travelingHours;
String userId; String? jobSheetNumber;
String workingHours; String? image;
String travelingHours; Lookup? status;
String jobSheetNumber; Lookup? taskStatus;
String image; DateTime? date;
Lookup status; List<Visit>? visits;
Lookup taskStatus;
DateTime date;
List<Visit> visits;
VisitsGroup({ VisitsGroup({
this.userId, this.userId,
@ -25,21 +24,22 @@ class VisitsGroup{
this.taskStatus, this.taskStatus,
}); });
Map<String,String> toJson(){ Map<String, String> toJson() {
Map<String,String> jsonObject = {}; Map<String, String> jsonObject = {};
jsonObject["nids"] = visits.map((e) => e.id).toList().join(','); jsonObject["nids"] = visits!.map((e) => e.id).toList().join(',');
if(status != null) jsonObject["status"] = status.id.toString(); if (status != null) jsonObject["status"] = status?.id.toString() ?? "";
if(date != null) jsonObject["date"] = date.toString().split(" ").first; if (date != null) jsonObject["date"] = date.toString().split(" ").first;
if(jobSheetNumber != null && jobSheetNumber.isNotEmpty) if (jobSheetNumber != null && (jobSheetNumber?.isNotEmpty ?? false)) {
jsonObject["job_sheet_no"] = jobSheetNumber; jsonObject["job_sheet_no"] = jobSheetNumber!;
if(travelingHours != null && travelingHours.isNotEmpty) }
jsonObject["traveling_hours"] = travelingHours; if (travelingHours != null && (travelingHours?.isNotEmpty ?? false)) {
if(workingHours != null && workingHours.isNotEmpty) jsonObject["traveling_hours"] = travelingHours ?? "";
jsonObject["working_hours"] = workingHours; }
if(image != null) jsonObject["image"] = image; if (workingHours != null && (workingHours?.isNotEmpty ?? false)) {
if(taskStatus != null) jsonObject["task_status"] = taskStatus.id.toString(); jsonObject["working_hours"] = workingHours ?? "";
}
if (image != null) jsonObject["image"] = image ?? "";
if (taskStatus != null) jsonObject["task_status"] = taskStatus?.id.toString() ?? "";
return jsonObject; return jsonObject;
} }
}
}

@ -1,14 +1,14 @@
class VisitsSearch{ class VisitsSearch {
String deviceSerialNumber; String? deviceSerialNumber;
String hospitalName; String? hospitalName;
String brand; String? brand;
String model; String? model;
String contactStatus; String? contactStatus;
DateTime expectedDateFrom; DateTime? expectedDateFrom;
DateTime expectedDateTo; DateTime? expectedDateTo;
DateTime actualDateFrom; DateTime? actualDateFrom;
DateTime actualDateTo; DateTime? actualDateTo;
int statusValue; int? statusValue;
VisitsSearch({ VisitsSearch({
this.deviceSerialNumber, this.deviceSerialNumber,
@ -23,7 +23,7 @@ class VisitsSearch{
this.expectedDateTo, this.expectedDateTo,
}); });
fromSearch(VisitsSearch newSearch){ fromSearch(VisitsSearch newSearch) {
deviceSerialNumber = newSearch.deviceSerialNumber; deviceSerialNumber = newSearch.deviceSerialNumber;
brand = newSearch.brand; brand = newSearch.brand;
hospitalName = newSearch.hospitalName; hospitalName = newSearch.hospitalName;
@ -36,48 +36,18 @@ class VisitsSearch{
statusValue = newSearch.statusValue; statusValue = newSearch.statusValue;
} }
String toSearchString(){ Map<String, dynamic> queryParameters() {
String _search = ""; return <String, dynamic>{
if(deviceSerialNumber != null && deviceSerialNumber.isNotEmpty){ if (deviceSerialNumber != null && (deviceSerialNumber?.isNotEmpty ?? false)) 'sn_id': deviceSerialNumber,
_search += "&sn_id=$deviceSerialNumber"; if (statusValue != null) 'status': statusValue?.toString(),
} if (hospitalName != null && (hospitalName?.isNotEmpty ?? false)) 'client': hospitalName,
if (brand != null && (brand?.isNotEmpty ?? false)) 'brand': brand,
if(hospitalName != null && hospitalName.isNotEmpty){ if (model != null && (model?.isNotEmpty ?? false)) 'model': model,
_search += "&client=$hospitalName"; if (expectedDateFrom != null) 'expected_date_from': (expectedDateFrom?.millisecondsSinceEpoch ?? 0) ~/ 1000,
} if (expectedDateTo != null) 'expected_date_to': (expectedDateTo?.millisecondsSinceEpoch ?? 0) ~/ 1000,
if (actualDateFrom != null) 'actual_date_from': (actualDateFrom?.millisecondsSinceEpoch ?? 0) ~/ 1000,
if(brand != null && brand.isNotEmpty){ if (actualDateTo != null) 'actual_date_to': (actualDateTo?.millisecondsSinceEpoch ?? 0) ~/ 1000,
_search += "&brand=$brand"; if (contactStatus != null) 'assigned_to': contactStatus,
} };
if(model != null && model.isNotEmpty){
_search += "&model=$model";
}
if(expectedDateFrom != null){
_search += "&expected_date_from=${expectedDateFrom.millisecondsSinceEpoch ~/ 1000}";
}
if(expectedDateTo != null){
_search += "&expected_date_to=${expectedDateTo.millisecondsSinceEpoch~/1000}";
}
if(actualDateFrom != null){
_search += "&actual_date_from=${actualDateFrom.millisecondsSinceEpoch ~/ 1000}";
}
if(actualDateTo != null){
_search += "&actual_date_to=${actualDateTo.millisecondsSinceEpoch~/1000}";
}
if(statusValue != null){
_search += "&status=$statusValue";
}
if(contactStatus != null){
_search += "&assigned_to=$contactStatus";
}
return _search;
} }
} }

@ -1,41 +1,50 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/models/lookup.dart'; //import 'package:test_sa/models/lookup.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);
static const Color grey = Color(0xffe1e7e7); static const Color grey = Color(0xffe1e7e7);
static const green = Colors.green; static const green = Colors.green;
static const Color orange = Colors.orange; static const Color orange = Colors.orange;
static const Color deepOrange = Colors.deepOrangeAccent; static const Color deepOrange = Colors.deepOrangeAccent;
static const Color red = Colors.red; static const Color red = Colors.red;
static const Color deepRed = Color(0xFFD32F2F); static const Color deepRed = Color(0xFFD32F2F);
static const Color scaffoldBackgroundColor = Color(0xffffffff); static const Color scaffoldBackgroundColor = Color(0xffffffff);
static const Color secondaryColor = Color(0xff111427); static const Color secondaryColor = Color(0xff111427);
static const Color primaryColor = Color(0xff5bb0da); static const Color primaryColor = Color(0xff5bb0da);
static const Color cyan = Color(0xff4A8DB7); static const Color cyan = Color(0xff4A8DB7);
static const Color onPrimaryColor = Color(0xffffffff); static const Color onPrimaryColor = Color(0xffffffff);
static Color inputFieldBackgroundColor = Color(0xfff5f5f5); static Color inputFieldBackgroundColor = Color(0xfff5f5f5);
static Color greyEF = Color(0xffEFEFEF); static Color greyEF = Color(0xffEFEFEF);
static Color getRequestStatusColor(int id){ static Color getRequestStatusColor(int id) {
switch(id){ switch (id) {
case 4: return AColors.deepRed; case 4:
case 6: return AColors.green; return AColors.deepRed;
case 5: return AColors.orange; case 6:
case 8: return AColors.green; return AColors.green;
case 9: return AColors.orange; case 5:
default : return AColors.grey; return AColors.orange;
case 8:
return AColors.green;
case 9:
return AColors.orange;
default:
return AColors.grey;
} }
} }
static Color getGasStatusColor(int id){ static Color getGasStatusColor(int id) {
switch(id){ switch (id) {
case 0: return AColors.orange; case 0:
case 1: return AColors.green; return AColors.orange;
default : return AColors.grey; case 1:
return AColors.green;
default:
return AColors.grey;
} }
} }
} }

@ -1,39 +1,31 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppStyle { class AppStyle {
AppStyle._(); AppStyle._();
static const double borderRadius = 10; static const double borderRadius = 10;
static const BoxShadow boxShadow = BoxShadow( static const BoxShadow boxShadow = BoxShadow(color: Colors.black26, blurRadius: 3, offset: Offset(0, 2));
color: Colors.black26,
blurRadius: 3,
offset: Offset(0,2)
);
static double getBorderRadius(BuildContext context){ static double getBorderRadius(BuildContext context) {
return borderRadius * getScaleFactor(context); return borderRadius * getScaleFactor(context);
} }
static double getScaleFactor(BuildContext context){ static double getScaleFactor(BuildContext context) {
return MediaQuery.of(context).orientation == Orientation.portrait return MediaQuery.of(context).orientation == Orientation.portrait
? MediaQuery.of(context).size.width/(360) > 1.5 ? MediaQuery.of(context).size.width / (360) > 1.5
? 1.5 : MediaQuery.of(context).size.width/(360) ? 1.5
: MediaQuery.of(context).size.height/(360) > 1.5 : MediaQuery.of(context).size.width / (360)
? 1.5 : MediaQuery.of(context).size.height/(360); : MediaQuery.of(context).size.height / (360) > 1.5
? 1.5
: MediaQuery.of(context).size.height / (360);
} }
static BorderRadius getCardBorder(BuildContext context){ static BorderRadius getCardBorder(BuildContext context) {
return BorderRadius.only( return BorderRadius.only(
topRight: Radius.circular( topRight: Radius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
AppStyle.borderRadius * AppStyle.getScaleFactor(context) topLeft: Radius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
), bottomRight: Radius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
topLeft: Radius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
bottomRight: Radius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
); );
} }
}
}

@ -1,57 +1,56 @@
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 '../../../api/user_api_client.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import '../../../controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import '../../../controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/models/device/device_transfer.dart'; import '../../../controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/device/device_transfer_info.dart'; import '../../../controllers/providers/user_provider.dart';
import 'package:test_sa/models/subtitle.dart'; import '../../../models/device/device_transfer.dart';
import 'package:test_sa/views/app_style/colors.dart'; import '../../../models/device/device_transfer_info.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import '../../../models/subtitle.dart';
import 'package:test_sa/views/pages/device_transfer/update_device_transfer.dart'; import '../../app_style/colors.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import '../../app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart'; import '../../widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_info_section.dart'; import '../../widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import '../../widgets/device_trancfer/device_transfer_info_section.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import '../../widgets/loaders/loading_manager.dart';
import '../../widgets/requests/info_row.dart';
import 'update_device_transfer.dart';
class DeviceTransferDetails extends StatefulWidget { class DeviceTransferDetails extends StatefulWidget {
final DeviceTransfer model; final DeviceTransfer model;
const DeviceTransferDetails({Key key, this.model}) : super(key: key); const DeviceTransferDetails({Key? key, required this.model}) : super(key: key);
@override @override
State<DeviceTransferDetails> createState() => _DeviceTransferDetailsState(); State<DeviceTransferDetails> createState() => _DeviceTransferDetailsState();
} }
class _DeviceTransferDetailsState extends State<DeviceTransferDetails> { class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
final DeviceTransferInfo _model = DeviceTransferInfo(); final DeviceTransferInfo _model = DeviceTransferInfo();
bool _isSender = false; bool _isSender = false;
bool _isReceiver = false; bool _isReceiver = false;
UserProvider _userProvider; UserProvider? _userProvider;
SettingProvider _settingProvider; SettingProvider? _settingProvider;
DeviceTransferProvider _deviceTransferProvider; DeviceTransferProvider? _deviceTransferProvider;
bool _isLoading = false; bool _isLoading = false;
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>();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context); _deviceTransferProvider = Provider.of<DeviceTransferProvider>(context);
_isSender = _userProvider.user.id == widget.model.sender?.userId; _isSender = UserApiClient().user?.id == widget.model.sender?.userId;
_isReceiver = _userProvider.user.id == widget.model.receiver?.userId; _isReceiver = UserApiClient().user?.id == widget.model.receiver?.userId;
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: SafeArea(
@ -66,18 +65,15 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
children: [ children: [
Container( Container(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
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(),
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
_subtitle.details, _subtitle?.details ?? "",
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6?.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
color: AColors.white,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
@ -87,71 +83,64 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
), ),
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: EdgeInsets.all(16*AppStyle.getScaleFactor(context)), padding: EdgeInsets.all(16 * AppStyle.getScaleFactor(context)),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: _subtitle.title, title: _subtitle!.title,
info: widget.model.title, info: widget.model.title,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.device, title: _subtitle?.device,
info: widget.model.device.serialNumber, info: widget.model.device?.serialNumber,
), ),
const SizedBox(height:8), const SizedBox(height: 8),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Text( child: Text("Sender", style: Theme.of(context).textTheme.headline6),
"Sender",
style: Theme.of(context).textTheme.headline6
),
), ),
if(_isSender) if (_isSender)
ASmallButton( ASmallButton(
text: _subtitle.edit, text: _subtitle?.edit ?? "",
onPressed: (){ onPressed: () {
Navigator.of(context).push( Navigator.of(context).push(MaterialPageRoute(
MaterialPageRoute( builder: (_) => UpdateDeviceTransfer(
builder: (_)=> UpdateDeviceTransfer(model: widget.model,isSender: _isSender,) model: widget.model,
) isSender: _isSender,
); )));
}, },
), ),
], ],
), ),
const SizedBox(height:12), const SizedBox(height: 12),
DeviceTransferInfoSection( DeviceTransferInfoSection(
info: widget.model.sender, info: widget.model.sender!,
), ),
const SizedBox(height:8), const SizedBox(height: 8),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Text( child: Text("Receiver", style: Theme.of(context).textTheme.headline6),
"Receiver",
style: Theme.of(context).textTheme.headline6
),
),
if(_isReceiver)
ASmallButton(
text: _subtitle.edit,
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_)=> UpdateDeviceTransfer(model: widget.model,isSender: _isSender,)
)
);
},
), ),
if (_isReceiver)
ASmallButton(
text: _subtitle?.edit ?? "",
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => UpdateDeviceTransfer(
model: widget.model,
isSender: _isSender,
)));
},
),
], ],
), ),
const SizedBox(height:12), const SizedBox(height: 12),
DeviceTransferInfoSection( DeviceTransferInfoSection(
info: widget.model.receiver, info: widget.model.receiver!,
), ),
], ],
), ),
), ),

@ -1,27 +1,29 @@
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/controllers/http_status_manger/http_status_manger.dart'; import 'package:test_sa/models/hospital.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/settings/setting_provider.dart';
import 'package:test_sa/extensions/int_extensions.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/views/app_style/sizing.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/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../api/user_api_client.dart';
import '../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/device_transfer_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../controllers/providers/user_provider.dart';
import '../../../extensions/int_extensions.dart';
import '../../../models/device/device_transfer.dart';
import '../../../models/device/device_transfer_info.dart';
import '../../../models/subtitle.dart';
import '../../app_style/sizing.dart';
import '../../widgets/buttons/app_button.dart';
import '../../widgets/departments/department_button.dart';
import '../../widgets/equipment/device_button.dart';
import '../../widgets/hospitals/hospital_button.dart';
import '../../widgets/loaders/loading_manager.dart';
import '../../widgets/titles/app_sub_title.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
State<RequestDeviceTransfer> createState() => _RequestDeviceTransferState(); State<RequestDeviceTransfer> createState() => _RequestDeviceTransferState();
@ -30,10 +32,8 @@ class RequestDeviceTransfer extends StatefulWidget {
class _RequestDeviceTransferState extends State<RequestDeviceTransfer> { class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
bool _isLoading = false; bool _isLoading = false;
bool _validate = false; bool _validate = false;
Subtitle _subtitle; Subtitle? _subtitle;
UserProvider _userProvider; DeviceTransferProvider? _deviceTransferProvider;
SettingProvider _settingProvider;
DeviceTransferProvider _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController(); final TextEditingController _requestedQuantityController = TextEditingController();
final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo()); final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo());
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -44,42 +44,6 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
if (mounted) super.setState(() {}); if (mounted) super.setState(() {});
} }
_onSubmit() async {
_validate = true;
if (!_formKey.currentState.validate()) {
setState(() {});
return false;
}
_formKey.currentState.save();
if (!_formModel.validate()) {
setState(() {});
return false;
}
_isLoading = true;
setState(() {});
int status = await _deviceTransferProvider.createRequest(
user: _userProvider.user,
host: _settingProvider.host,
model: _formModel,
);
_isLoading = false;
setState(() {});
if (status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
);
Navigator.of(context).pop();
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
}
@override @override
void dispose() { void dispose() {
_requestedQuantityController.dispose(); _requestedQuantityController.dispose();
@ -88,9 +52,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context, listen: false); _deviceTransferProvider = Provider.of<DeviceTransferProvider>(context, listen: false);
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
@ -112,7 +74,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Transfer Device", "Transfer Device",
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),
), ),
), ),
), ),
@ -134,7 +96,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
const ASubTitle("Device"), const ASubTitle("Device"),
if (_validate && _formModel.device == null) if (_validate && _formModel.device == null)
ASubTitle( ASubTitle(
_subtitle.requiredWord, _subtitle?.requiredWord ?? "",
color: Colors.red, color: Colors.red,
), ),
6.height, 6.height,
@ -159,38 +121,55 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
// ), // ),
12.height, 12.height,
const ASubTitle("Destination Client"), const ASubTitle("Destination Client"),
if (_validate && _formModel.receiver.client == null) if (_validate && _formModel.receiver?.client == null)
ASubTitle( ASubTitle(
_subtitle.requiredWord, _subtitle?.requiredWord ?? "",
color: Colors.red, color: Colors.red,
), ),
6.height, 6.height,
HospitalButton( HospitalButton(
hospital: _formModel.receiver.client, hospital: _formModel.receiver?.client ?? Hospital(),
onHospitalPick: (hospital) { onHospitalPick: (hospital) {
_formModel.receiver.client = hospital; _formModel.receiver?.client = hospital;
setState(() {}); setState(() {});
}, },
), ),
12.height, 12.height,
const ASubTitle("Destination Department"), const ASubTitle("Destination Department"),
if (_validate && _formModel.receiver.department == null) if (_validate && _formModel.receiver?.department == null)
ASubTitle( ASubTitle(
_subtitle.requiredWord, _subtitle?.requiredWord ?? "",
color: Colors.red, color: Colors.red,
), ),
6.height, 6.height,
DepartmentButton( DepartmentButton(
department: _formModel.receiver.department, department: _formModel.receiver?.department,
onDepartmentPick: (department) { onDepartmentPick: (department) {
_formModel.receiver.department = department; _formModel.receiver?.department = department;
setState(() {}); setState(() {});
}, },
), ),
12.height, 12.height,
AButton( AButton(
text: _subtitle.submit, text: _subtitle?.submit ?? "",
onPressed: _onSubmit, onPressed: () async {
_validate = true;
if (!(_formKey.currentState?.validate() ?? false)) {
setState(() {});
return;
}
_formKey.currentState?.save();
if (!_formModel.validate()) {
setState(() {});
return;
}
await _deviceTransferProvider?.createRequest(
model: _formModel,
context: context,
);
},
), ),
const SizedBox( const SizedBox(
height: 100, height: 100,

@ -1,55 +1,52 @@
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 '../../../api/user_api_client.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import '../../../controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import '../../../controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/models/subtitle.dart'; import '../../../controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/views/app_style/colors.dart'; import '../../../controllers/providers/user_provider.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import '../../../models/subtitle.dart';
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_list.dart'; import '../../../models/user.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import '../../app_style/colors.dart';
import '../../widgets/buttons/app_back_button.dart';
import '../../widgets/device_trancfer/device_transfer_list.dart';
import '../../widgets/loaders/loading_manager.dart';
class TrackDeviceTransferPage extends StatefulWidget { class TrackDeviceTransferPage extends StatefulWidget {
static const String id = "/track-device-transfer"; static const String id = "/track-device-transfer";
const TrackDeviceTransferPage({Key key}) : super(key: key); const TrackDeviceTransferPage({Key? key}) : super(key: key);
@override @override
State<TrackDeviceTransferPage> createState() => _TrackDeviceTransferPageState(); State<TrackDeviceTransferPage> createState() => _TrackDeviceTransferPageState();
} }
class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage> class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage> with TickerProviderStateMixin {
with TickerProviderStateMixin{ late DeviceTransferProvider _deviceTransferProvider;
DeviceTransferProvider _deviceTransferProvider;
UserProvider _userProvider;
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); Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
//print(_deviceTransferProvider.items.length);
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
child: LoadingManager( child: LoadingManager(
isLoading: _deviceTransferProvider.isLoading, isLoading: _deviceTransferProvider.loading,
isFailedLoading: _deviceTransferProvider.items == null, //isFailedLoading: _deviceTransferProvider.items == null,
stateCode: _deviceTransferProvider.stateCode, stateCode: _deviceTransferProvider.stateCode,
onRefresh: () async { onRefresh: () async {
_deviceTransferProvider.reset(); _deviceTransferProvider.reset();
await _deviceTransferProvider.getRequests( await _deviceTransferProvider.getRequests();
user: _userProvider.user,
host: _settingProvider.host,
);
}, },
child: Stack( child: Stack(
children: [ children: [
Column( Column(
children: [ children: [
Container( Container(
color:AColors.primaryColor, color: AColors.primaryColor,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Column( child: Column(
children: [ children: [
Row( Row(
@ -59,17 +56,15 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage>
child: Center( child: Center(
child: Text( child: Text(
"Device Transfer", "Device Transfer",
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6?.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
color: AColors.white,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
const SizedBox(width: 48,) const SizedBox(
width: 48,
)
], ],
), ),
], ],
), ),
), ),
@ -77,10 +72,7 @@ class _TrackDeviceTransferPageState extends State<TrackDeviceTransferPage>
child: DeviceTransferList( child: DeviceTransferList(
nextPage: _deviceTransferProvider.nextPage, nextPage: _deviceTransferProvider.nextPage,
onLazyLoad: () async { onLazyLoad: () async {
await _deviceTransferProvider.getRequests( await _deviceTransferProvider.getRequests();
user: _userProvider.user,
host: _settingProvider.host,
);
}, },
items: _deviceTransferProvider.items, items: _deviceTransferProvider.items,
), ),

@ -4,26 +4,29 @@ import 'package:flutter/foundation.dart';
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/controllers/http_status_manger/http_status_manger.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/settings/setting_provider.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/views/app_style/sizing.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/e_signature/e_signature.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/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../api/user_api_client.dart';
import '../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/device_transfer_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../controllers/providers/user_provider.dart';
import '../../../models/device/device_transfer.dart';
import '../../../models/device/device_transfer_info.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../../app_style/sizing.dart';
import '../../widgets/app_text_form_field.dart';
import '../../widgets/buttons/app_button.dart';
import '../../widgets/e_signature/e_signature.dart';
import '../../widgets/loaders/loading_manager.dart';
import '../../widgets/status/gas_refill/gas_status.dart';
import '../../widgets/titles/app_sub_title.dart';
class UpdateDeviceTransfer extends StatefulWidget { class UpdateDeviceTransfer extends StatefulWidget {
final DeviceTransfer model; final DeviceTransfer model;
final bool isSender; final bool? isSender;
const UpdateDeviceTransfer({Key key, this.model, this.isSender}) : super(key: key); const UpdateDeviceTransfer({Key? key, required this.model, this.isSender}) : super(key: key);
@override @override
State<UpdateDeviceTransfer> createState() => _UpdateDeviceTransferState(); State<UpdateDeviceTransfer> createState() => _UpdateDeviceTransferState();
@ -32,11 +35,11 @@ class UpdateDeviceTransfer extends StatefulWidget {
class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> { class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
bool _isLoading = false; bool _isLoading = false;
bool _validate = false; bool _validate = false;
Subtitle _subtitle; Subtitle? _subtitle;
UserProvider _userProvider; UserProvider? _userProvider;
SettingProvider _settingProvider; SettingProvider? _settingProvider;
Uint8List _signature; Uint8List? _signature;
DeviceTransferProvider _deviceTransferProvider; DeviceTransferProvider? _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController(); final TextEditingController _requestedQuantityController = TextEditingController();
final DeviceTransferInfo _formModel = DeviceTransferInfo(); final DeviceTransferInfo _formModel = DeviceTransferInfo();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -44,55 +47,41 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
_update() async { _update() async {
_validate = true; _validate = true;
if(!_formKey.currentState.validate()){ if ((_formKey.currentState?.validate() ?? false)) {
setState(() {}); setState(() {});
return false; return false;
} }
_formKey.currentState.save(); _formKey.currentState?.save();
_isLoading =true; _isLoading = true;
setState(() {}); setState(() {});
int status = await _deviceTransferProvider.updateRequest( int? status = await _deviceTransferProvider?.updateRequest(
user: _userProvider.user, user: UserApiClient().user ?? User(), host: _settingProvider?.host ?? "", requestId: widget.model?.id.toString() ?? "", isSender: widget.isSender ?? false, newModel: _formModel, oldModel: widget.model);
host: _settingProvider.host, _isLoading = false;
requestId: widget.model.id,
isSender: widget.isSender,
newModel: _formModel,
oldModel: widget.model
);
_isLoading =false;
setState(() {}); setState(() {});
if(status >= 200 && status < 300){ if (status != null && status >= 200 && status < 300) {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully, msg: _subtitle?.requestCompleteSuccessfully ?? "",
); );
_validate = false; _validate = false;
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pop(); Navigator.of(context).pop();
}else{ } else {
String errorMessage = HttpStatusManger.getStatusMessage( String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
status: status, subtitle: _subtitle); ScaffoldMessenger.of(context).showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar( content: Text(errorMessage),
SnackBar( ));
content: Text(
errorMessage
),
)
);
} }
} }
@override @override
void setState(VoidCallback fn){ void setState(VoidCallback fn) {
if(mounted) super.setState(() {}); if (mounted) super.setState(() {});
} }
@override @override
void initState() { void initState() {
_formModel.fromDetails(widget.isSender _formModel.fromDetails((widget.isSender ?? false) ? widget.model?.sender : widget.model?.receiver, withSignature: false);
? widget.model.sender : widget.model.receiver,
withSignature: false
);
super.initState(); super.initState();
} }
@ -104,10 +93,10 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context,listen: false); _deviceTransferProvider = Provider.of<DeviceTransferProvider>(context, listen: false);
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: Form( body: Form(
@ -128,96 +117,100 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Edit Transfer Device", "Edit Transfer Device",
style: Theme.of(context).textTheme.headline5.copyWith( style: Theme.of(context).textTheme.headline5?.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold),
color: Theme.of(context).primaryColor,
fontSize: 28,
fontWeight: FontWeight.bold
),
), ),
), ),
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
ASubTitle("Comment"), ASubTitle("Comment"),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ATextFormField( ATextFormField(
initialValue: _formModel?.comment, initialValue: _formModel.comment ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text, textInputType: TextInputType.text,
onSaved: (value){ onSaved: (value) {
_formModel.comment = value; _formModel.comment = value;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
ASubTitle(_subtitle.travelingHours), height: 8,
const SizedBox(height: 4,), ),
ASubTitle(_subtitle?.travelingHours ?? ""),
const SizedBox(
height: 4,
),
ATextFormField( ATextFormField(
initialValue: _formModel?.travelingHours, initialValue: _formModel.travelingHours ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number, textInputType: TextInputType.number,
onSaved: (value){ onSaved: (value) {
_formModel.travelingHours = value; _formModel.travelingHours = value;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
ASubTitle(_subtitle.workingHours), height: 8,
const SizedBox(height: 4,), ),
ASubTitle(_subtitle?.workingHours ?? ""),
const SizedBox(
height: 4,
),
ATextFormField( ATextFormField(
initialValue: _formModel?.workingHours, initialValue: _formModel.workingHours ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number, textInputType: TextInputType.number,
onSaved: (value){ onSaved: (value) {
_formModel.workingHours = value; _formModel.workingHours = value;
}, },
), ),
// const SizedBox(height: 8,), const SizedBox(
// const ASubTitle("Sender Department"), height: 8,
// if(_validate && _formModel.senderDepartment == null) ),
// ASubTitle(_subtitle.requiredWord,color: Colors.red,), ASubTitle(_subtitle?.status ?? ""),
// const SizedBox(height: 4,), const SizedBox(
// DepartmentButton( height: 4,
// department: _formModel.senderDepartment, ),
// onDepartmentPick: (department){
// _formModel.senderDepartment = department;
// setState(() {});
// },
// ),
const SizedBox(height: 8,),
ASubTitle(_subtitle.status),
const SizedBox(height: 4,),
GasStatusMenu( GasStatusMenu(
initialValue: _formModel.status, initialValue: _formModel.status,
onSelect: (status){ onSelect: (status) {
_formModel.status = status; _formModel.status = status;
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
const ASubTitle("Signature"), const ASubTitle("Signature"),
// if(_validate && _formModel.signature == null) // if(_validate && _formModel.signature == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,), // ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ESignature( ESignature(
oldSignature: widget.isSender oldSignature: (widget.isSender ?? false) ? widget.model?.sender?.signature : widget.model?.receiver?.signature,
? widget.model.sender.signature newSignature: _signature,
: widget.model.receiver.signature, onSaved: (signature) {
newSignature: _signature, _signature = signature;
onSaved: (signature){ _formModel.signature = base64Encode(signature);
_signature = signature; },
_formModel.signature = base64Encode(signature);
},
), ),
Padding( Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: AButton( child: AButton(
text: _subtitle.update, text: _subtitle?.update ?? "",
onPressed: _update, onPressed: _update,
), ),
), ),
const SizedBox(height: 100,) const SizedBox(
height: 100,
)
], ],
), ),
), ),
@ -227,4 +220,3 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
); );
} }
} }

@ -1,38 +1,33 @@
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/http_status_manger/http_status_manger.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/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/register.dart';
import 'package:test_sa/views/pages/user/land_page.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/loaders/loading_manager.dart';
import '../widgets/buttons/app_outlined_button.dart'; import '../../controllers/localization/localization.dart';
import '../../controllers/providers/settings/setting_provider.dart';
import '../../controllers/providers/user_provider.dart';
import '../../controllers/validator/validator.dart';
import '../../models/subtitle.dart';
import '../../models/user.dart';
import '../app_style/sizing.dart';
import '../widgets/app_text_form_field.dart';
import '../widgets/buttons/app_button.dart';
import '../widgets/loaders/loading_manager.dart';
class Login extends StatefulWidget { class Login extends StatefulWidget {
static final String id = "/login"; static const String id = "/login";
const Login({super.key});
@override @override
_LoginState createState() => _LoginState(); LoginState createState() => LoginState();
} }
class _LoginState extends State<Login> { class LoginState extends State<Login> {
UserProvider _userProvider; late UserProvider _userProvider;
SettingProvider _settingProvider; late SettingProvider _settingProvider;
User _user = User();
bool _obscurePassword = true; bool _obscurePassword = true;
bool _firstTime = true; late double _height;
double _height; final User _user = User();
double _width;
String _payload;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@ -41,13 +36,12 @@ class _LoginState extends State<Login> {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_height = MediaQuery.of(context).size.height; _height = MediaQuery.of(context).size.height;
_width = MediaQuery.of(context).size.width; Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: SafeArea(
child: LoadingManager( child: LoadingManager(
isLoading: _userProvider.isLoading || !_settingProvider.isLoaded, isLoading: (_userProvider.loading) || !(_settingProvider.isLoaded),
isFailedLoading: false, isFailedLoading: false,
stateCode: 200, stateCode: 200,
onRefresh: () async {}, onRefresh: () async {},
@ -66,7 +60,7 @@ class _LoginState extends State<Login> {
child: Image( child: Image(
height: _height / 6, height: _height / 6,
fit: BoxFit.contain, fit: BoxFit.contain,
image: AssetImage("assets/images/logo.png"), image: const AssetImage("assets/images/logo.png"),
), ),
), ),
Padding( Padding(
@ -77,57 +71,45 @@ class _LoginState extends State<Login> {
height: 24 * AppStyle.getScaleFactor(context), height: 24 * AppStyle.getScaleFactor(context),
), ),
ATextFormField( ATextFormField(
initialValue: _user?.userName, initialValue: _user.userName ?? "",
hintText: _subtitle.name, hintText: subtitle?.name ?? "",
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: Theme.of(context).textTheme.bodyText1, style: Theme.of(context).textTheme.bodyLarge,
prefixIconData: Icons.account_circle, prefixIconData: Icons.account_circle,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage, validator: (value) => Validator.hasValue(value ?? '') ? null : subtitle?.nameValidateMessage,
textInputType: TextInputType.name, textInputType: TextInputType.name,
onSaved: (value) { onSaved: (value) {
_user.userName = value; if (value != null) {
_user.userName = value;
}
}, },
), ),
SizedBox(height: 12), const SizedBox(height: 12),
ATextFormField( ATextFormField(
initialValue: _user?.password, initialValue: _user.password,
hintText: _subtitle.password, hintText: subtitle?.password ?? "",
obscureText: _obscurePassword, obscureText: _obscurePassword,
style: Theme.of(context).textTheme.bodyText1, style: Theme.of(context).textTheme.bodyLarge,
prefixIconData: Icons.vpn_key_sharp, prefixIconData: Icons.vpn_key_sharp,
textAlign: TextAlign.left, textAlign: TextAlign.left,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle.passwordValidateMessage, validator: (value) => Validator.isValidPassword(value ?? '') ? null : subtitle?.passwordValidateMessage,
showPassword: () { showPassword: () {
_obscurePassword = !_obscurePassword; _obscurePassword = !_obscurePassword;
setState(() {}); setState(() {});
}, },
onSaved: (value) { onSaved: (value) {
_user.password = value; _user.password = value!;
}, },
), ),
SizedBox( SizedBox(
height: 32 * AppStyle.getScaleFactor(context), height: 32 * AppStyle.getScaleFactor(context),
), ),
AButton( AButton(
text: _subtitle.signIn, text: subtitle?.signIn ?? "",
onPressed: () async { onPressed: () async {
if (!_formKey.currentState.validate()) return; if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState.save(); _formKey.currentState?.save();
int status = await _userProvider.login( await _userProvider.login(context, user: _user);
user: _user,
host: _settingProvider.host,
);
if (status >= 200 && status < 300) {
_settingProvider.setUser(_userProvider.user);
if (_userProvider.user.isActive)
Navigator.of(context).pushNamed(LandPage.id);
else
Fluttertoast.showToast(msg: _subtitle.activationAlert);
} else {
String errorMessage = status == 400 ? _subtitle.wrongEmailOrPassword : HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
} }
}, },
), ),

@ -1,34 +1,29 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import '../../controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import '../../controllers/providers/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import '../../controllers/validator/validator.dart';
import 'package:test_sa/controllers/validator/validator.dart'; import '../../models/subtitle.dart';
import 'package:test_sa/models/subtitle.dart'; import '../../models/user.dart';
import 'package:test_sa/models/user.dart'; import '../widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import '../widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import '../widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import '../widgets/loaders/loading_manager.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/loaders/loading_manager.dart';
class Register extends StatefulWidget { class Register extends StatefulWidget {
static final String id = "/register"; static const String id = "/register";
const Register({super.key});
@override @override
_RegisterState createState() => _RegisterState(); RegisterState createState() => RegisterState();
} }
class _RegisterState extends State<Register> { class RegisterState extends State<Register> {
UserProvider _userProvider; late UserProvider _userProvider;
SettingProvider _settingProvider; late double _height;
double _width; final User _user = User();
double _height;
User _user = User();
bool _obscurePassword = true; bool _obscurePassword = 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>();
@ -36,14 +31,12 @@ class _RegisterState extends State<Register> {
@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);
_width = MediaQuery.of(context).size.width;
_height = MediaQuery.of(context).size.height; _height = MediaQuery.of(context).size.height;
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: LoadingManager( body: LoadingManager(
isLoading: _userProvider.isLoading, isLoading: _userProvider.loading,
isFailedLoading: false, isFailedLoading: false,
stateCode: 200, stateCode: 200,
onRefresh: () async {}, onRefresh: () async {},
@ -63,46 +56,46 @@ class _RegisterState extends State<Register> {
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Image( child: Image(
height: _height / 6, height: _height / 6,
image: AssetImage("assets/images/logo.png"), image: const AssetImage("assets/images/logo.png"),
), ),
), ),
), ),
ATextFormField( ATextFormField(
initialValue: _user.userName, initialValue: _user.userName,
hintText: _subtitle.name, hintText: subtitle?.name ?? "",
prefixIconData: Icons.account_circle, prefixIconData: Icons.account_circle,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage, validator: (value) => Validator.hasValue(value!) ? '' : subtitle?.nameValidateMessage ?? "",
onSaved: (value) { onSaved: (value) {
_user.userName = value; _user.userName = value!;
}, },
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
ATextFormField( ATextFormField(
initialValue: _user.email, initialValue: _user.email,
hintText: _subtitle.email, hintText: subtitle?.email ?? "",
prefixIconData: Icons.email, prefixIconData: Icons.email,
textInputType: TextInputType.emailAddress, textInputType: TextInputType.emailAddress,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
validator: (value) => Validator.isEmail(value) ? null : _subtitle.emailValidateMessage, validator: (value) => Validator.isEmail(value!) ? '' : subtitle?.emailValidateMessage ?? "",
onSaved: (value) { onSaved: (value) {
_user.email = value; _user.email = value!;
}, },
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
ATextFormField( ATextFormField(
initialValue: _user.password, initialValue: _user.password,
hintText: _subtitle.password, hintText: subtitle?.password ?? "",
prefixIconData: Icons.vpn_key_sharp, prefixIconData: Icons.vpn_key_sharp,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
obscureText: _obscurePassword, obscureText: _obscurePassword,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle.passwordValidateMessage, validator: (value) => Validator.isValidPassword(value!) ? '' : subtitle?.passwordValidateMessage ?? '',
showPassword: () { showPassword: () {
_obscurePassword = !_obscurePassword; _obscurePassword = !_obscurePassword;
setState(() {}); setState(() {});
}, },
onSaved: (value) { onSaved: (value) {
_user.password = value; _user.password = value!;
}, },
onChange: (value) { onChange: (value) {
_user.password = value; _user.password = value;
@ -112,97 +105,70 @@ class _RegisterState extends State<Register> {
ATextFormField( ATextFormField(
initialValue: _user.password, initialValue: _user.password,
prefixIconData: Icons.vpn_key_sharp, prefixIconData: Icons.vpn_key_sharp,
hintText: _subtitle.confirmPassword, hintText: subtitle?.confirmPassword ?? "",
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
obscureText: _obscurePassword, obscureText: _obscurePassword,
validator: (value) => _user.password == value ? null : _subtitle.confirmPasswordValidateMessage, validator: (value) => _user.password == value ? '' : subtitle?.confirmPasswordValidateMessage ?? "",
showPassword: () { showPassword: () {
_obscurePassword = !_obscurePassword; _obscurePassword = !_obscurePassword;
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
HospitalButton( // HospitalButton(
hospital: _user.hospital, // hospital: _user.hospital ?? Hospital(),
onHospitalPick: (hospital) { // onHospitalPick: (hospital) {
_user.hospital = hospital; // _user.hospital = hospital;
setState(() {}); // setState(() {});
}, // },
), // ),
const SizedBox(height: 12), const SizedBox(height: 12),
DepartmentButton( // DepartmentButton(
department: _user.department, // department: _user.department,
onDepartmentPick: (department) { // onDepartmentPick: (department) {
_user.department = department; // _user.department = department;
setState(() {}); // setState(() {});
}, // },
), // ),
const SizedBox(height: 12), const SizedBox(height: 12),
ATextFormField( ATextFormField(
initialValue: _user.phoneNumber, initialValue: _user.phoneNumber ?? "",
hintText: _subtitle.phoneNumber, hintText: subtitle?.phoneNumber ?? "",
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
prefixIconData: Icons.phone_android, prefixIconData: Icons.phone_android,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, validator: (value) => Validator.isPhoneNumber(value!) ? '' : subtitle?.phoneNumberValidateMessage ?? "",
textInputType: TextInputType.phone, textInputType: TextInputType.phone,
onSaved: (value) { onSaved: (value) {
_user.phoneNumber = value; _user.phoneNumber = value;
}, },
), ),
SizedBox(height: 8), const SizedBox(height: 8),
ATextFormField( // ATextFormField(
initialValue: _user.whatsApp, // initialValue: _user.whatsApp ?? "",
hintText: _subtitle.whatsApp, // hintText: subtitle?.whatsApp ?? "",
style: Theme.of(context).textTheme.headline6, // style: Theme.of(context).textTheme.titleLarge,
prefixIconData: FontAwesomeIcons.whatsapp, // prefixIconData: FontAwesomeIcons.whatsapp,
prefixIconSize: 36, // prefixIconSize: 36,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, // validator: (value) => (Validator.isPhoneNumber(value!)) ? "" : subtitle?.phoneNumberValidateMessage ?? "",
textInputType: TextInputType.phone, // textInputType: TextInputType.phone,
onSaved: (value) { // onSaved: (value) {
_user.whatsApp = value; // _user.whatsApp = value;
}, // },
), // ),
const SizedBox(height: 12), const SizedBox(height: 12),
AButton( AButton(
text: _subtitle.signUp, text: subtitle?.signUp ?? "",
onPressed: () async { onPressed: () async {
if (!_formKey.currentState.validate()) return; if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState.save(); _formKey.currentState?.save();
if (_user.hospital == null) { await _userProvider.register(context, newUser: _user);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.hospitalRequired),
));
return;
}
if (_user.department == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.unitRequired),
));
return;
}
int status = await _userProvider.register(
user: _user,
host: _settingProvider.host,
);
if (status >= 200 && status < 300) {
Fluttertoast.showToast(msg: _subtitle.activationAlert);
Navigator.of(context).pop();
} else {
String errorMessage = status == 402
? _subtitle.nameExist
: status == 401
? _subtitle.emailExist
: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
} }
}, },
), ),
], ],
), ),
), ),
ABackButton(), const ABackButton(),
], ],
), ),
), ),

@ -5,72 +5,65 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flare_flutter/flare_actor.dart'; import 'package:flare_flutter/flare_actor.dart';
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/notification/notification_manger.dart'; import 'package:test_sa/api/user_api_client.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/app_notification.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/pages/user/land_page.dart';
import '../../controllers/notification/notification_manger.dart';
import '../../controllers/providers/settings/setting_provider.dart';
import '../../models/app_notification.dart';
import '../../models/user.dart';
import 'login.dart'; import 'login.dart';
import 'user/land_page.dart';
class SplashScreen extends StatefulWidget { class SplashScreen extends StatefulWidget {
static const String id = '/splash'; static const String id = '/splashScreen';
const SplashScreen({Key key}) : super(key: key);
const SplashScreen({Key? key}) : super(key: key);
@override @override
State<SplashScreen> createState() => _SplashScreenState(); State<SplashScreen> createState() => _SplashScreenState();
} }
class _SplashScreenState extends State<SplashScreen> { class _SplashScreenState extends State<SplashScreen> {
late SettingProvider _settingProvider;
SettingProvider _settingProvider; _goToUserScreen(User? user) {
UserProvider _userProvider; UserApiClient().user = user;
// Navigator.of(context).pushNamed(Login.id);
_goToUserScreen(User user){
_userProvider.user = user;
// Navigator.of(context).pushNamed(Login.id);
Navigator.of(context).pushNamed(LandPage.id); Navigator.of(context).pushNamed(LandPage.id);
} }
@override @override
void initState() { void initState() {
Firebase.initializeApp(); Firebase.initializeApp();
NotificationManger.initialisation((notificationDetails) {
NotificationManger.initialisation( AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload ?? ""));
(notificationDetails) { if (notification.path == null || (notification.path?.isEmpty ?? false)) {
AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload)); return;
if(notification.path == null || notification.path.isEmpty) }
return; Navigator.pushNamed(context, notification.path ?? "", arguments: notification.requestId);
Navigator.pushNamed( }, (id, title, body, payload) async {});
context,
notification.path,
arguments: notification.requestId
);
}
, (id, title, body, payload) async {
});
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context,listen: false); _settingProvider = Provider.of<SettingProvider>(context, listen: false);
_userProvider = Provider.of<UserProvider>(context,listen: false);
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: Center( body: Center(
child: SizedBox( child: SizedBox(
width: MediaQuery.of(context).size.width/1.1, width: MediaQuery.of(context).size.width / 1.1,
child: FlareActor( child: FlareActor(
"assets/rives/atoms_splash.flr", "assets/rives/atoms_splash.flr",
fit: BoxFit.contain, fit: BoxFit.contain,
animation: "splash", animation: "splash",
callback: (animation) async { callback: (animation) async {
print(await FirebaseMessaging.instance.getToken()); debugPrint(await FirebaseMessaging.instance.getToken());
Navigator.of(context).pushNamed(Login.id); if (context.mounted) {
if(_settingProvider.isLoaded && _settingProvider.user != null){ Navigator.of(context).pushNamed(Login.id);
_goToUserScreen(_settingProvider.user); if (_settingProvider.isLoaded && _settingProvider.user != null) {
_goToUserScreen(_settingProvider.user);
}
} }
}, },
), ),

@ -1,95 +1,80 @@
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/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/gas_refill_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/enums/user_types.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.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_icon_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_update_details_item.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/request_status.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../api/user_api_client.dart';
import '../../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/gas_refill_provider.dart';
import '../../../../models/enums/user_types.dart';
import '../../../../models/gas_refill/gas_refill_model.dart';
import '../../../../models/subtitle.dart';
import '../../../app_style/colors.dart'; import '../../../app_style/colors.dart';
import '../../../app_style/sizing.dart';
import '../../../widgets/buttons/app_back_button.dart';
import '../../../widgets/buttons/app_button.dart';
import '../../../widgets/buttons/app_icon_button.dart';
import '../../../widgets/gas_refill/gas_refill_update_details_item.dart';
import '../../../widgets/loaders/loading_manager.dart';
import '../../../widgets/requests/info_row.dart';
import '../../../widgets/requests/request_status.dart';
import '../../../widgets/status/gas_refill/gas_status.dart';
import '../../../widgets/titles/app_sub_title.dart';
class GasRefillDetails extends StatefulWidget { class GasRefillDetails extends StatefulWidget {
final GasRefillModel model; final GasRefillModel? model;
const GasRefillDetails({Key key, this.model}) : super(key: key); const 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(); final GasRefillModel _model = GasRefillModel();
bool _enableEdit = false; bool _enableEdit = false;
bool _validate = false; bool _validate = false;
UserProvider _userProvider; GasRefillProvider? _gasRefillProvider;
SettingProvider _settingProvider;
GasRefillProvider _gasRefillProvider;
bool _isLoading = false; bool _isLoading = false;
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() ?? false)) {
setState(() {}); setState(() {});
return false; return false;
} }
_formKey.currentState.save(); _formKey.currentState?.save();
_isLoading =true; _isLoading = true;
setState(() {}); setState(() {});
int status = await _gasRefillProvider.updateModel( int? status = await _gasRefillProvider?.updateModel(newModel: _model, oldModel: widget.model);
user: _userProvider.user, _isLoading = false;
host: _settingProvider.host,
newModel: _model,
oldModel: widget.model
);
_isLoading =false;
setState(() {}); setState(() {});
if(status >= 200 && status < 300){ if (status != null && status >= 200 && status < 300) {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully, msg: _subtitle?.requestCompleteSuccessfully ?? "",
); );
_enableEdit = false; _enableEdit = false;
_validate = false; _validate = false;
//Navigator.of(context).pop(); //Navigator.of(context).pop();
}else{ } else {
String errorMessage = HttpStatusManger.getStatusMessage( String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
status: status, subtitle: _subtitle); ScaffoldMessenger.of(context).showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar( content: Text(errorMessage),
SnackBar( ));
content: Text(
errorMessage
),
)
);
} }
} }
@override @override
void initState() { void initState() {
_model.fromGasRefillModel(widget.model); _model.fromGasRefillModel(widget.model ?? GasRefillModel());
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context); _gasRefillProvider = Provider.of<GasRefillProvider>(context);
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
@ -105,108 +90,117 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
children: [ children: [
Container( Container(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
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(),
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
_subtitle.details, _subtitle?.details ?? "",
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6?.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
color: AColors.white,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
if(_userProvider.user.type == UsersTypes.engineer) if (UserApiClient().user?.roles == UsersTypes.engineer.name)
AIconButton( AIconButton(
iconData: _enableEdit ? Icons.cancel : Icons.edit, iconData: _enableEdit ? Icons.cancel : Icons.edit,
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: () async {
_enableEdit = !_enableEdit; _enableEdit = !_enableEdit;
_model.fromGasRefillModel(widget.model); _model.fromGasRefillModel(widget.model ?? GasRefillModel());
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(width: 16,) const SizedBox(
width: 16,
)
], ],
), ),
), ),
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: EdgeInsets.all(16*AppStyle.getScaleFactor(context)), padding: EdgeInsets.all(16 * AppStyle.getScaleFactor(context)),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: _subtitle.title, title: _subtitle?.title ?? "",
info: _model.title, info: _model.title ?? "",
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.hospital, title: _subtitle?.hospital ?? "",
info: _model.clientName, info: _model.clientName ?? "",
), ),
_enableEdit ? _enableEdit
Column( ? Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(height: 8,), const SizedBox(
ASubTitle(_subtitle.status), height: 8,
if(_validate && _model.status == null) ),
ASubTitle(_subtitle.requiredWord,color: Colors.red,), ASubTitle(_subtitle?.status ?? ""),
const SizedBox(height: 4,), if (_validate && _model.status == null)
GasStatusMenu( ASubTitle(
initialValue: _model.status, _subtitle?.requiredWord ?? "",
onSelect: (status){ color: Colors.red,
_model.status = status; ),
}, const SizedBox(
) height: 4,
], ),
): GasStatusMenu(
Row( initialValue: _model.status,
children: [ onSelect: (status) {
Expanded( _model.status = status;
child: Text( },
"${_subtitle.status} : ", )
style: Theme.of(context).textTheme.subtitle2, ],
textScaleFactor: AppStyle.getScaleFactor(context), )
: Row(
children: [
Expanded(
child: Text(
"${_subtitle?.status} : ",
style: Theme.of(context).textTheme.subtitle2,
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
StatusLabel(label: _model.status?.label.toString() ?? "", color: AColors.getGasStatusColor(_model.status?.id ?? 0)),
],
), ),
), const SizedBox(
StatusLabel(label: _model.status.label, height: 8,
color: AColors.getGasStatusColor(_model.status.id)
),
],
), ),
const SizedBox(height: 8,),
const ASubTitle("Gas Requests"), const ASubTitle("Gas Requests"),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
ListView.builder( ListView.builder(
shrinkWrap: true, shrinkWrap: true,
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
itemCount: _model.details.length, itemCount: _model.details?.length,
itemBuilder: (context,index){ itemBuilder: (context, index) {
final details = _model.details[index]; final details = _model.details![index];
return GasRefillUpdateDetailsItem( return GasRefillUpdateDetailsItem(
details: details, details: details,
validate: _validate, validate: _validate,
enableEdit: _enableEdit, enableEdit: _enableEdit,
); );
} }),
), if (_enableEdit)
if(_enableEdit) Column(
Column( children: [
children: [ const SizedBox(
const SizedBox(height: 16,), height: 16,
AButton( ),
text: _subtitle.update, AButton(
onPressed: _update, text: _subtitle?.update ?? "",
), onPressed: _update,
], ),
), ],
),
], ],
), ),
), ),

@ -1,28 +1,30 @@
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/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/gas_refill_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/validator/validator.dart';
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/subtitle.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/buttons/app_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_create_details_item.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_cylinder_size.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_type.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../api/user_api_client.dart';
import '../../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/gas_refill_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../controllers/providers/user_provider.dart';
import '../../../../controllers/validator/validator.dart';
import '../../../../models/gas_refill/gas_refill_details.dart';
import '../../../../models/gas_refill/gas_refill_model.dart';
import '../../../../models/subtitle.dart';
import '../../../../models/user.dart';
import '../../../app_style/sizing.dart';
import '../../../widgets/app_text_form_field.dart';
import '../../../widgets/buttons/app_button.dart';
import '../../../widgets/gas_refill/gas_refill_create_details_item.dart';
import '../../../widgets/loaders/loading_manager.dart';
import '../../../widgets/status/gas_refill/gas_cylinder_size.dart';
import '../../../widgets/status/gas_refill/gas_type.dart';
import '../../../widgets/titles/app_sub_title.dart';
class RequestGasRefill extends StatefulWidget { class RequestGasRefill extends StatefulWidget {
static const String id = "/request-gas-refill"; static const String id = "/request-gas-refill";
const RequestGasRefill({Key key}) : super(key: key); const RequestGasRefill({Key? key}) : super(key: key);
@override @override
State<RequestGasRefill> createState() => _RequestGasRefillState(); State<RequestGasRefill> createState() => _RequestGasRefillState();
@ -31,11 +33,9 @@ class RequestGasRefill extends StatefulWidget {
class _RequestGasRefillState extends State<RequestGasRefill> { class _RequestGasRefillState extends State<RequestGasRefill> {
bool _isLoading = false; bool _isLoading = false;
bool _validate = false; bool _validate = false;
Subtitle _subtitle; Subtitle? _subtitle;
UserProvider _userProvider; GasRefillProvider? _gasRefillProvider;
SettingProvider _settingProvider; GasRefillDetails _currentDetails = GasRefillDetails(model: null);
GasRefillProvider _gasRefillProvider;
GasRefillDetails _currentDetails = GasRefillDetails();
final TextEditingController _requestedQuantityController = TextEditingController(); final TextEditingController _requestedQuantityController = TextEditingController();
final GasRefillModel _formModel = GasRefillModel(details: []); final GasRefillModel _formModel = GasRefillModel(details: []);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -43,61 +43,27 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
void setState(VoidCallback fn){ void setState(VoidCallback fn) {
if(mounted) super.setState(() {}); if (mounted) super.setState(() {});
} }
_onSubmit() async { bool _addNewModel() {
if(_formModel.details.isEmpty){
if(!_addNewModel()) return;
}
_isLoading =true;
setState(() {});
int status = await _gasRefillProvider.createModel(
user: _userProvider.user,
host: _settingProvider.host,
model: _formModel,
);
_isLoading =false;
setState(() {});
if(status >= 200 && status < 300){
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
);
Navigator.of(context).pop();
}else{
String errorMessage = HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
}
}
bool _addNewModel(){
_validate = true; _validate = true;
if(!_formKey.currentState.validate()){ if (!(_formKey.currentState?.validate() ?? false)) {
setState(() {}); setState(() {});
return false; return false;
} }
_formKey.currentState.save(); _formKey.currentState?.save();
if(!_currentDetails.validate()) { if (!_currentDetails.validate()) {
setState(() { }); setState(() {});
return false; return false;
} }
_formModel.details?.insert(0, _currentDetails);
_formModel.details.insert(0,_currentDetails);
_validate = false; _validate = false;
Scrollable.ensureVisible(_DetailsKey.currentContext); Scrollable.ensureVisible(_DetailsKey.currentContext!);
_requestedQuantityController.clear(); _requestedQuantityController.clear();
_currentDetails = GasRefillDetails(); _currentDetails = GasRefillDetails(model: null);
setState(() {}); setState(() {});
return true; return true;
} }
@ -107,12 +73,11 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
_requestedQuantityController.dispose(); _requestedQuantityController.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context); _gasRefillProvider = Provider.of<GasRefillProvider>(context, listen: false);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context,listen: false);
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: Form( body: Form(
@ -133,11 +98,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"Request Gas Refill", "Request Gas Refill",
style: Theme.of(context).textTheme.headline5.copyWith( style: Theme.of(context).textTheme.headline5?.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold),
color: Theme.of(context).primaryColor,
fontSize: 28,
fontWeight: FontWeight.bold
),
), ),
), ),
), ),
@ -168,76 +129,94 @@ 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("Type"),
if(_validate && _currentDetails.type == null) if (_validate && _currentDetails.type == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,), ASubTitle(
const SizedBox(height: 4,), _subtitle?.requiredWord ?? "",
color: Colors.red,
),
const SizedBox(
height: 4,
),
GasTypeMenu( GasTypeMenu(
initialValue: _currentDetails.type, initialValue: _currentDetails.type,
onSelect: (status){ onSelect: (status) {
_currentDetails.type = status; _currentDetails.type = status;
}, },
), ),
// const SizedBox(height: 8,),
// const ASubTitle("Cylinder Size"),
// if(_validate && _currentDetails.cylinderSize == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
// const SizedBox(height: 4,),
// GasCylinderSizeMenu(
// initialValue: _currentDetails.cylinderSize,
// onSelect: (status){
// _currentDetails.cylinderSize = status;
// },
// ),
const SizedBox(height: 8,), const SizedBox(height: 8,),
ASubTitle(_subtitle.quantity), const ASubTitle("Cylinder Size"),
if(_validate && _currentDetails.requestedQuantity == null) if(_validate && _currentDetails.cylinderSize == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,), ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,),
SizedBox(height: 4,), const SizedBox(height: 4,),
GasCylinderSizeMenu(
initialValue: _currentDetails.cylinderSize,
onSelect: (status){
_currentDetails.cylinderSize = status;
},
),
const SizedBox(
height: 8,
),
ASubTitle(_subtitle?.quantity ?? ""),
if (_validate && _currentDetails.requestedQuantity == null)
ASubTitle(
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
SizedBox(
height: 4,
),
ATextFormField( ATextFormField(
initialValue: (_currentDetails?.requestedQuantity ?? "").toString(), initialValue: (_currentDetails.requestedQuantity ?? "").toString(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
controller: _requestedQuantityController, controller: _requestedQuantityController,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
validator: (value) => validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only",
Validator.isNumeric(value)
? null : "allow numbers only",
textInputType: TextInputType.number, textInputType: TextInputType.number,
onSaved: (value){ onSaved: (value) {
_currentDetails.requestedQuantity = int.tryParse(value); _currentDetails.requestedQuantity = int.tryParse(value!);
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
AButton( AButton(
text: _subtitle.add, text: _subtitle?.add ?? "",
onPressed: _addNewModel, onPressed: _addNewModel,
), ),
if(_formModel.details.isNotEmpty) if ((_formModel.details?.isNotEmpty ?? false)) const ASubTitle("Gas Requests"),
const ASubTitle("Gas Requests"),
ListView.builder( ListView.builder(
key: _DetailsKey, key: _DetailsKey,
shrinkWrap: true, shrinkWrap: true,
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
itemCount: _formModel.details.length, itemCount: _formModel.details?.length,
itemBuilder: (context,index){ itemBuilder: (context, index) {
final model = _formModel.details[index]; final model = _formModel.details![index];
return GasRefillCreateDetailsItem( return GasRefillCreateDetailsItem(
model: model, model: model,
onDelete: (){ onDelete: () {
_formModel.details.remove(model); _formModel.details?.remove(model);
setState(() {}); setState(() {});
}, },
); );
} }),
),
const SizedBox(height: 16), const SizedBox(height: 16),
AButton( AButton(
text: _subtitle.submit, text: _subtitle?.submit ?? "",
onPressed: _onSubmit, onPressed: () async {
if ((_formModel.details?.isEmpty ?? false)) {
if (!_addNewModel()) return;
}
await _gasRefillProvider?.createModel(model: _formModel, context: context);
},
), ),
const SizedBox(height: 100,) const SizedBox(
height: 100,
)
], ],
), ),
), ),
@ -247,4 +226,3 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
); );
} }
} }

@ -1,55 +1,51 @@
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/gas_refill_provider.dart'; import '../../../../api/user_api_client.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import '../../../../controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import '../../../../controllers/providers/api/gas_refill_provider.dart';
import 'package:test_sa/models/subtitle.dart'; import '../../../../controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/views/app_style/colors.dart'; import '../../../../controllers/providers/user_provider.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import '../../../../models/subtitle.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_list.dart'; import '../../../../models/user.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import '../../../app_style/colors.dart';
import '../../../widgets/buttons/app_back_button.dart';
import '../../../widgets/gas_refill/gas_refill_list.dart';
import '../../../widgets/loaders/loading_manager.dart';
class TrackGasRefillPage extends StatefulWidget { class TrackGasRefillPage extends StatefulWidget {
static const String id = "/track-gas-refill"; static const String id = "/track-gas-refill";
const TrackGasRefillPage({Key key}) : super(key: key); const TrackGasRefillPage({Key? key}) : super(key: key);
@override @override
State<TrackGasRefillPage> createState() => _TrackGasRefillPageState(); State<TrackGasRefillPage> createState() => _TrackGasRefillPageState();
} }
class _TrackGasRefillPageState extends State<TrackGasRefillPage> class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProviderStateMixin {
with TickerProviderStateMixin{ late GasRefillProvider _gasRefillProvider;
GasRefillProvider _gasRefillProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_gasRefillProvider = Provider.of<GasRefillProvider>(context); _gasRefillProvider = Provider.of<GasRefillProvider>(context);
_userProvider = Provider.of<UserProvider>(context); Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
child: LoadingManager( child: LoadingManager(
isLoading: _gasRefillProvider.isLoading, isLoading: _gasRefillProvider.loading,
isFailedLoading: _gasRefillProvider.items == null, isFailedLoading: _gasRefillProvider.items == null,
stateCode: _gasRefillProvider.stateCode, stateCode: _gasRefillProvider.stateCode,
onRefresh: () async { onRefresh: () async {
_gasRefillProvider.reset(); _gasRefillProvider.reset();
await _gasRefillProvider.getRequests( await _gasRefillProvider.getRequests();
user: _userProvider.user,
host: _settingProvider.host,
);
}, },
child: Stack( child: Stack(
children: [ children: [
Column( Column(
children: [ children: [
Container( Container(
color:AColors.white, color: AColors.white,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Column( child: Column(
children: [ children: [
Row( Row(
@ -58,18 +54,16 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
_subtitle.serviceRequests, _subtitle?.serviceRequests ?? "",
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6?.copyWith(color: AColors.grey3A, fontStyle: FontStyle.italic),
color: AColors.grey3A,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
const SizedBox(width: 48,) const SizedBox(
width: 48,
)
], ],
), ),
], ],
), ),
), ),
@ -77,17 +71,13 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
child: GasRefillList( child: GasRefillList(
nextPage: _gasRefillProvider.nextPage, nextPage: _gasRefillProvider.nextPage,
onLazyLoad: () async { onLazyLoad: () async {
await _gasRefillProvider.getRequests( await _gasRefillProvider.getRequests();
user: _userProvider.user,
host: _settingProvider.host,
);
}, },
items: _gasRefillProvider.items, items: _gasRefillProvider.items,
), ),
), ),
], ],
), ),
], ],
), ),
), ),

@ -1,64 +1,64 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:package_info/package_info.dart'; import 'package:package_info/package_info.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:share/share.dart'; import 'package:share/share.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/notification/firebase_notification_manger.dart';
import 'package:test_sa/controllers/providers/api/departments_provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/controllers/providers/api/preventive_maintenance_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/user_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/widget_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/device_transfer/request_device_transfer.dart';
import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart';
import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart';
import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart';
import 'package:test_sa/views/pages/user/notifications/notifications_page.dart';
import 'package:test_sa/views/pages/user/requests/create_request.dart';
import 'package:test_sa/views/pages/user/visits/regular_visits_page.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/dialogs/dialog.dart';
import 'package:test_sa/views/widgets/drawer/drawer_item.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../api/user_api_client.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/notification/firebase_notification_manger.dart';
import '../../../controllers/providers/api/departments_provider.dart';
import '../../../controllers/providers/api/devices_provider.dart';
import '../../../controllers/providers/api/preventive_maintenance_visits_provider.dart';
import '../../../controllers/providers/api/regular_visits_provider.dart';
import '../../../controllers/providers/api/service_requests_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../controllers/providers/user_provider.dart';
import '../../../extensions/int_extensions.dart';
import '../../../extensions/widget_extensions.dart';
import '../../../models/enums/user_types.dart';
import '../../../models/subtitle.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../../widgets/buttons/app_back_button.dart';
import '../../widgets/buttons/app_icon_button.dart';
import '../../widgets/dialogs/dialog.dart';
import '../../widgets/drawer/drawer_item.dart';
import '../../widgets/land_page/land_page_item.dart'; import '../../widgets/land_page/land_page_item.dart';
import '../device_transfer/request_device_transfer.dart';
import '../device_transfer/track_device_transfer.dart';
import 'gas_refill/request_gas_refill.dart';
import 'gas_refill/track_gas_refill.dart';
import 'notifications/notifications_page.dart';
import 'requests/create_request.dart';
import 'requests/requests_page.dart'; import 'requests/requests_page.dart';
import 'visits/regular_visits_page.dart';
class LandPage extends StatefulWidget { class LandPage extends StatefulWidget {
static const String id = "/land-page"; static const String id = "/land-page";
const LandPage({Key key}) : super(key: key); const LandPage({Key? key}) : super(key: key);
@override @override
State<LandPage> createState() => _LandPageState(); State<LandPage> createState() => _LandPageState();
} }
class _LandPageState extends State<LandPage> { class _LandPageState extends State<LandPage> {
double _height; late double _height;
double _width; late double _width;
UserProvider _userProvider; late UserProvider _userProvider;
SettingProvider _settingProvider; late SettingProvider _settingProvider;
DepartmentsProvider _departmentsProvider; late DepartmentsProvider _departmentsProvider;
DevicesProvider _devicesProvider; late DevicesProvider _devicesProvider;
double _buttonHeight; late double _buttonHeight;
bool firstTime = true; late bool firstTime = true;
ServiceRequestsProvider _serviceRequestsProvider; late ServiceRequestsProvider _serviceRequestsProvider;
PreventiveMaintenanceVisitsProvider _preventiveMaintenanceVisitsProvider; late PreventiveMaintenanceVisitsProvider _preventiveMaintenanceVisitsProvider;
RegularVisitsProvider _regularVisitsProvider; late RegularVisitsProvider _regularVisitsProvider;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
@ -73,7 +73,7 @@ class _LandPageState extends State<LandPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String path = ModalRoute.of(context).settings.arguments; String? path = ModalRoute.of(context)?.settings.arguments as String?;
_height = MediaQuery.of(context).size.height; _height = MediaQuery.of(context).size.height;
_width = MediaQuery.of(context).size.width; _width = MediaQuery.of(context).size.width;
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
@ -83,7 +83,7 @@ class _LandPageState extends State<LandPage> {
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_preventiveMaintenanceVisitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context); _preventiveMaintenanceVisitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context);
_regularVisitsProvider = Provider.of<RegularVisitsProvider>(context); _regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context)!.subtitle!;
if (firstTime) { if (firstTime) {
if (path != null) { if (path != null) {
Navigator.of(context).pushNamed("/" + path.split("/").first, arguments: path.split("/").last); Navigator.of(context).pushNamed("/" + path.split("/").first, arguments: path.split("/").last);
@ -153,7 +153,7 @@ class _LandPageState extends State<LandPage> {
mainAxisSpacing: 12, mainAxisSpacing: 12,
childAspectRatio: 1, childAspectRatio: 1,
children: [ children: [
if (_userProvider.user.type == UsersTypes.normal_user) if (UserApiClient().user!.roles == UsersTypes.normal_user.name)
LandPageItem( LandPageItem(
text: _subtitle.newServiceRequest, text: _subtitle.newServiceRequest,
icon: FontAwesomeIcons.tools, icon: FontAwesomeIcons.tools,
@ -184,7 +184,7 @@ class _LandPageState extends State<LandPage> {
// Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id); // Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id);
// }, // },
// ), // ),
if (_userProvider.user.type != UsersTypes.engineer) if (UserApiClient().user?.roles != UsersTypes.engineer.name)
LandPageItem( LandPageItem(
text: "Request Gas Refill", text: "Request Gas Refill",
icon: FontAwesomeIcons.truckFast, icon: FontAwesomeIcons.truckFast,
@ -250,7 +250,7 @@ class _LandPageState extends State<LandPage> {
buttonSize: 42, buttonSize: 42,
backgroundColor: AColors.white, backgroundColor: AColors.white,
onPressed: () { onPressed: () {
_scaffoldKey.currentState.openEndDrawer(); _scaffoldKey.currentState?.openEndDrawer();
}, },
), ),
), ),
@ -278,14 +278,18 @@ class _LandPageState extends State<LandPage> {
decoration: BoxDecoration(border: Border.all(color: Theme.of(context).primaryColor, width: 2), shape: BoxShape.circle), decoration: BoxDecoration(border: Border.all(color: Theme.of(context).primaryColor, width: 2), shape: BoxShape.circle),
child: ClipOval( child: ClipOval(
child: ClipOval( child: ClipOval(
child: Icon(Icons.person,size: 36,color: Theme.of(context).colorScheme.primary,), child: Icon(
Icons.person,
size: 36,
color: Theme.of(context).colorScheme.primary,
),
), ),
), ),
), ),
12.width, 12.width,
Text( Text(
_userProvider.user.userName, UserApiClient().user?.userName ?? "",
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6?.copyWith(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
@ -307,11 +311,11 @@ class _LandPageState extends State<LandPage> {
focusColor: AColors.grey3A, focusColor: AColors.grey3A,
groupValue: _settingProvider.language, groupValue: _settingProvider.language,
onChanged: (value) { onChanged: (value) {
_settingProvider.setLanguage(value); _settingProvider.setLanguage(value!);
}), }),
Text( Text(
"English", "English",
style: Theme.of(context).textTheme.bodyText1.copyWith(color: AColors.grey3A), style: Theme.of(context).textTheme.bodyText1?.copyWith(color: AColors.grey3A),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
Radio( Radio(
@ -320,11 +324,11 @@ class _LandPageState extends State<LandPage> {
focusColor: AColors.grey3A, focusColor: AColors.grey3A,
groupValue: _settingProvider.language, groupValue: _settingProvider.language,
onChanged: (value) { onChanged: (value) {
_settingProvider.setLanguage(value); _settingProvider.setLanguage(value!);
}), }),
Text( Text(
"عربي", "عربي",
style: Theme.of(context).textTheme.bodyText1.copyWith(color: AColors.grey3A), style: Theme.of(context).textTheme.bodyText1?.copyWith(color: AColors.grey3A),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
], ],
@ -381,7 +385,7 @@ class _LandPageState extends State<LandPage> {
children: [ children: [
Text( Text(
"Powered By NewTrack", "Powered By NewTrack",
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,

@ -1,43 +1,44 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/app_notification.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/pages/user/requests/future_request_service_details.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import 'package:test_sa/views/widgets/notifications/notification_item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../models/app_notification.dart';
import '../../../../models/subtitle.dart';
import '../../../widgets/loaders/lazy_loading.dart';
import '../../../widgets/loaders/no_item_found.dart';
import '../../../widgets/notifications/notification_item.dart';
import '../requests/future_request_service_details.dart';
class NotificationsList extends StatelessWidget { class NotificationsList extends StatelessWidget {
final List<AppNotification> notifications; final List<AppNotification>? notifications;
final bool nextPage; final bool? nextPage;
final Future<void> Function() onLazyLoad; final Future<void> Function()? onLazyLoad;
const NotificationsList({Key key, this.notifications, this.nextPage, this.onLazyLoad}) : super(key: key); const NotificationsList({Key? key, this.notifications, this.nextPage, this.onLazyLoad}) : 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;
if(notifications.length == 0){ if ((notifications?.isEmpty ?? false)) {
return NoItemFound(message: _subtitle.notificationsNotFound,); return NoItemFound(
message: _subtitle?.notificationsNotFound ?? "",
);
} }
return LazyLoading( return LazyLoading(
nextPage: nextPage, nextPage: nextPage ?? false,
onLazyLoad: onLazyLoad, onLazyLoad: onLazyLoad ?? () async {},
onLoadingEnd: () {},
child: ListView.builder( child: ListView.builder(
physics: BouncingScrollPhysics(), physics: BouncingScrollPhysics(),
itemCount: notifications.length, itemCount: notifications?.length,
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 8), padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
itemBuilder: (context,itemIndex){ itemBuilder: (context, itemIndex) {
return NotificationItem( return NotificationItem(
notification: notifications[itemIndex], notification: notifications![itemIndex],
onPressed: (notification){ onPressed: (notification) {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(FutureRequestServiceDetails.id, arguments: notification.requestId);
FutureRequestServiceDetails.id,
arguments: notification.requestId
);
}, },
); );
} }),
),
); );
} }
} }

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

Loading…
Cancel
Save