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 3 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
3 years ago
Sikander Saleem d8a1a982bf Merge branch 'zaid-development' into 'master'
New Service Request is DONE

See merge request haroon6138/cloudsolutions-atoms!12
3 years ago
nextwo 1e06449d8d change Api structure for request gas refill page + solve null safety bugs faced it during restructure the code 3 years ago
zaid_daoud 5f78d7e164 get device list & get device list by serial number 3 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
3 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
3 years ago
Sikander Saleem 7b31efc2ab Merge branch 'zaid-development' into 'master'
Recoding Login Task & Upgrade Flutter Version

See merge request haroon6138/cloudsolutions-atoms!11
3 years ago
zaid_daoud 1a2b53d8bb Change login_api_client.dart name 3 years ago
zaid_daoud 5b193b1c86 - Change a comment 3 years ago
zaid_daoud 05faf47913 - Change a comment 3 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).
3 years ago
Sikander Saleem 942fa0f0ba Merge branch 'majd_development' into 'master'
null safety

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

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

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

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

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

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

See merge request haroon6138/cloudsolutions-atoms!3
3 years ago
nextwo 82e3005e85 support null safety 4 3 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
3 years ago
omar alqaseer 429c8136ee Null Safety - Widgets Folder 3 years ago
nextwo 33a2e2127d support null safety 3 3 years ago
nextwo 5644ccad7c support null safety 2 3 years ago
nextwo 7fb78685ac Merge remote-tracking branch 'origin/restructuring' into support_null_safety 3 years ago
nextwo bb6dd618fc support null safety 1 3 years ago
Zaid-daoud b906ca60e6 - Null Safety 3 years ago
Zaid-daoud 216aabaf8a - Restructuring Project Files
- Creating ApiClient class
3 years ago
Zaid-daoud a2ce99fbae - Restructuring Project Files
- Creating ApiClient class
3 years ago

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

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

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

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.6.21'
repositories {
google()
mavenCentral()
}
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 "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

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

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

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

@ -1,40 +1,38 @@
import 'package:test_sa/models/subtitle.dart';
import 'package:meta/meta.dart';
import '../../models/subtitle.dart';
class HttpStatusManger{
class HttpStatusManger {
static String getStatusMessage({
@required int status,
@required Subtitle subtitle,
String messageFor400,
String messageFor200,
}){
if(status == null)
// no status code - code error no need for subtitle
required int? status,
required Subtitle? subtitle,
String? messageFor400,
String? messageFor200,
}) {
if (status == null) {
return "careful null status";
if(status == -1)
// client's request in process
return subtitle.currentlyServiceNotAvailable;
if(status == -2){
}
if (status == -1) {
return subtitle?.currentlyServiceNotAvailable ?? "";
}
if (status == -2) {
// client's request in process
return subtitle.waitUntilYourRequestComplete;
}else if(status >= 200 && status < 300){
return subtitle?.waitUntilYourRequestComplete ?? "";
} else if (status >= 200 && status < 300) {
// client's request was successfully received
return messageFor200 ?? subtitle.requestCompleteSuccessfully;
} else if(status >= 400 && status < 500){
return messageFor200 ?? subtitle?.requestCompleteSuccessfully ?? "";
} else if (status >= 400 && status < 500) {
// client's request have error
switch(status){
switch (status) {
case 400:
return messageFor400 ?? subtitle.failedToCompleteRequest;
return messageFor400 ?? subtitle?.failedToCompleteRequest ?? "";
default:
return subtitle.failedToCompleteRequest;
return subtitle?.failedToCompleteRequest ?? "";
}
} else if(status >= 500){
} else if (status >= 500) {
// server error
return subtitle.currentlyServiceNotAvailable;
return subtitle?.currentlyServiceNotAvailable ?? "";
} else {
// 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/services.dart';
import 'package:test_sa/models/subtitle.dart';
import '../../models/subtitle.dart';
class AppLocalization {
AppLocalization(this.locale);
final Locale locale;
static AppLocalization of(BuildContext context) {
static AppLocalization? of(BuildContext context) {
return Localizations.of<AppLocalization>(context, AppLocalization);
}
Subtitle _subtitle;
Subtitle get subtitle => _subtitle;
Subtitle? _subtitle;
Subtitle? get subtitle => _subtitle;
Future<void> load() async {
String jsonStringValues =
await rootBundle.loadString('assets/subtitles/${locale.languageCode}_subtitle.json');
String jsonStringValues = await rootBundle.loadString('assets/subtitles/${locale.languageCode}_subtitle.json');
_subtitle = Subtitle.fromJson(json.decode(jsonStringValues));
}
// static member to have simple access to the delegate from Material App
static const LocalizationsDelegate<AppLocalization> delegate =
_DemoLocalizationsDelegate();
static const LocalizationsDelegate<AppLocalization> delegate = _DemoLocalizationsDelegate();
}
class _DemoLocalizationsDelegate
extends LocalizationsDelegate<AppLocalization> {
class _DemoLocalizationsDelegate extends LocalizationsDelegate<AppLocalization> {
const _DemoLocalizationsDelegate();
@override
bool isSupported(Locale locale) {
return ['en','ar'].contains(locale.languageCode);
return ['en', 'ar'].contains(locale.languageCode);
}
@override
Future<AppLocalization> load(Locale locale) async {
AppLocalization localization = new AppLocalization(locale);
AppLocalization localization = AppLocalization(locale);
await localization.load();
return localization;
}
@override
bool shouldReload(LocalizationsDelegate<AppLocalization> old) => false;
}
}

@ -3,16 +3,15 @@ import 'dart:convert';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:test_sa/models/app_notification.dart';
import '../../models/app_notification.dart';
import 'notification_manger.dart';
class FirebaseNotificationManger{
class FirebaseNotificationManger {
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(
alert: true,
announcement: false,
@ -23,7 +22,7 @@ class FirebaseNotificationManger{
sound: true,
);
if(settings.authorizationStatus == AuthorizationStatus.authorized){
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
token = await messaging.getToken();
}
return token;
@ -32,7 +31,7 @@ class FirebaseNotificationManger{
static initialized(BuildContext context) async {
await Firebase.initializeApp();
NotificationSettings settings;
try{
try {
settings = await messaging.requestPermission(
alert: true,
announcement: false,
@ -42,11 +41,11 @@ class FirebaseNotificationManger{
provisional: false,
sound: true,
);
}catch(error){
} catch (error) {
return;
}
if(settings.authorizationStatus != AuthorizationStatus.authorized){
if (settings.authorizationStatus != AuthorizationStatus.authorized) {
return;
}
@ -56,28 +55,24 @@ class FirebaseNotificationManger{
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
AppNotification notification = AppNotification.fromJson(message.data);
if(notification.path == null
|| notification.path.isEmpty)
return;
Navigator.pushNamed(
context,
notification.path,
arguments: notification.requestId
context,
notification.path ?? "",
arguments: notification.requestId,
);
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
AppNotification notification = AppNotification.fromJson(message.data);
NotificationManger.showNotification(
title: message.notification.title,
subtext: message.notification.body,
hashcode: int.tryParse(notification.requestId ?? "") ?? 1,
payload: json.encode(message.data)
title: message.notification?.title,
subtext: message.notification?.body,
hashcode: int.tryParse(notification.requestId ?? "0") ?? 1,
payload: json.encode(message.data),
);
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:test_sa/views/app_style/colors.dart';
class NotificationManger{
import '../../views/app_style/colors.dart';
class NotificationManger {
// private constructor to avoid create object
NotificationManger._();
@ -12,43 +12,31 @@ class NotificationManger{
/// onNotificationPressed action when notification pressed to open tap
/// onIOSNotificationPressed action when notification pressed
/// to open tap in iOS versions older than 10
static initialisation(
Function(NotificationResponse) onNotificationPressed,
DidReceiveLocalNotificationCallback onIOSNotificationPressed
) async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
static initialisation(Function(NotificationResponse) onNotificationPressed, 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
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('app_icon',);
const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings(
'app_icon',
);
final DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings(
onDidReceiveLocalNotification: onIOSNotificationPressed);
final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings(onDidReceiveLocalNotification: onIOSNotificationPressed);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
macOS: initializationSettingsDarwin);
final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, macOS: initializationSettingsDarwin);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: onNotificationPressed);
await flutterLocalNotificationsPlugin.initialize(initializationSettings, onDidReceiveNotificationResponse: onNotificationPressed);
}
// push new notification
static Future showNotification(
{
@required String title,
@required String subtext,
@required int hashcode,
String payload
}) async {
static Future showNotification({
required String? title,
required String? subtext,
required int hashcode,
String? payload,
}) async {
const AndroidNotificationDetails androidChannel = AndroidNotificationDetails(
'com.newtrack.testsa',
'Test SA',
channelDescription:'Push notification service for Test SA',
channelDescription: 'Push notification service for Test SA',
importance: Importance.max,
priority: Priority.max,
playSound: true,
@ -62,8 +50,7 @@ class NotificationManger{
groupKey: 'com.newtrack.testsa',
);
const DarwinNotificationDetails iosNotificationDetails =
DarwinNotificationDetails(
const DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails(
categoryIdentifier: "testSA",
);
@ -81,5 +68,4 @@ class NotificationManger{
payload: payload,
);
}
}
}

@ -2,66 +2,37 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/api/departments_api_client.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
void reset(){
departments = null;
void reset() {
departments.clear();
stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// contain user data
// when user not login or register _user = null
List<Department> departments;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
List<Department> departments=[];
Future getDepartment() async {
/// 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> 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;
waitApiRequest(() async {
departments.addAll(await DepartmentsApiClient().getDepartment());
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/cupertino.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/user.dart';
class DeviceTransferProvider extends ChangeNotifier{
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/api/device_transfer_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
import '../../../models/device/device_transfer.dart';
import '../../../models/device/device_transfer_info.dart';
import '../../../models/user.dart';
import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
class DeviceTransferProvider extends LoadingNotifier {
// number of items call in each request
final pageItemNumber = 50;
//reset provider data
void reset(){
items = null;
void reset() {
items.clear();
nextPage = true;
stateCode = null;
}
@ -22,162 +23,59 @@ class DeviceTransferProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// true if there is next page in product list and false if not
bool nextPage = true;
bool? nextPage = true;
// list of user requests
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;
List<DeviceTransfer> items = [];
// isLoading = false;
// stateCode = 200;
// items = [];
// items.addAll(List.generate(20, (index) => DeviceTransfer(
// title: "ddddd",
// 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;
Future getRequests() async {
waitApiRequest(() async {
items.clear();
items.addAll(await DeviceTransferApiClient().getRequests(items: items, pageItemNumber: pageItemNumber));
print(items);
notifyListeners();
return response.statusCode;
} catch(error) {
isLoading = false;
stateCode = -1;
if (items.length == pageItemNumber) {
nextPage = true;
} else {
nextPage = false;
}
}, onSuccess: () {
stateCode = 200;
notifyListeners();
return -1;
}
});
}
Future<int> createRequest ({
@required String host,
@required User user,
@required DeviceTransfer model,
}) async {
Map<String,dynamic> body = {
"uid": user.id.toString(),
"token": user.token ?? "",
"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,
Future createRequest({required DeviceTransfer model, required BuildContext context}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
waitApiRequest(() async {
items.insert(0, await DeviceTransferApiClient().createRequest(model: model));
notifyListeners();
}, onSuccess: () {
Fluttertoast.showToast(
msg: subtitle?.requestCompleteSuccessfully ?? "",
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if(items != null) {
items.insert(
0,
DeviceTransfer.fromJson(
json.decode(utf8.decode(response.bodyBytes))[0]
)
);
notifyListeners();
}
}
return response.statusCode;
} catch(error) {
return -1;
}
Navigator.of(context).pop();
}, onError: (error) {
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
});
}
Future<int> updateRequest ({
@required String host,
@required User user,
@required bool isSender,
@required String requestId,
@required DeviceTransfer oldModel,
@required DeviceTransferInfo newModel,
Future updateRequest({
required String host,
required User user,
required bool isSender,
required String requestId,
required DeviceTransfer oldModel,
required DeviceTransferInfo newModel,
}) async {
Map<String,dynamic> body = {
"uid": user.id.toString(),
"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;
}
reset();
oldModel = await DeviceTransferApiClient().updateRequest(isSender: isSender, requestId: requestId, oldModel: oldModel, newModel: newModel);
notifyListeners();
}
}
}

@ -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 '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';
import '../../../models/device/device.dart';
class DevicesProvider extends ChangeNotifier{
class DevicesProvider extends LoadingNotifier {
final List<Device> _searchableList = [];
List<Device> get searchableList => _searchableList;
//reset provider data
void reset(){
_devices = null;
void reset() {
DevicesApiClient().devices.clear();
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
List<Device> _devices;
List<Device> get devices => _devices;
int? _stateCode;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
int? get stateCode => _stateCode;
/// 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> getEquipment ({
@required String host,
@required User user,
@required String hospitalId
}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(host + URLs.getEquipment+"?client=$hospitalId"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
/// - Fetching Devices From The Server and Inserting them into [DevicesApiClient.devices] List.
/// - [_searchableList] will be filled after the request succeed.
///
/// ### NOTE : if [hospitalId] is [NULL] nothing will happen
Future getEquipment() async {
final hospitalId = /*UserApiClient().user?.hospital?.id ??*/ '';
if (hospitalId != null) {
_searchableList.clear();
await waitApiRequest(
() async {
await DevicesApiClient().getEquipment(hospitalId);
_searchableList.addAll(DevicesApiClient().devices);
},
onSuccess: () {
/// TODO : this is temporary
_stateCode = 200;
},
onError: (error) {
/// TODO : this is temporary
_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
/// 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<List<Device>> getDevicesList ({
@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 [];
}
/// Returns a list of devices by [hospitalId] and [serialNumber] (or | and) [number]
///
/// ### NOTE : if [hospitalId] is [NULL] empty list will be returned
Future<List<Device>> getDevicesList({required String? hospitalId, String? serialNumber, String? number}) {
if (hospitalId == null) return Future.value(const []);
return DevicesApiClient().getDevicesList(hospitalId: hospitalId, serialNumber: serialNumber, number: number);
}
/// 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<List<Device>> getDevicesListBySN ({
@required String host,
@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 [];
}
/// Returns a list of devices by [hospitalId] (and optionally) [serialNumber]
///
/// ### NOTE : if [hospitalId] is [NULL] empty list will be returned
Future<List<Device>> getDevicesListBySN({required String serialNumber}) {
final hospitalId = /*UserApiClient().user?.hospital?.id ??*/ "";
if (hospitalId == null) return Future.value(const []);
return DevicesApiClient().getDevicesListBySN(hospitalId: hospitalId, serialNumber: serialNumber);
}
}
}

@ -1,19 +1,25 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/api/gas_refill_api_client.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
final pageItemNumber = 50;
//reset provider data
void reset(){
items = null;
void reset() {
items.clear();
nextPage = true;
stateCode = null;
}
@ -21,152 +27,53 @@ class GasRefillProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// true if there is next page in product list and false if not
bool nextPage = true;
// list of user requests
List<GasRefillModel> items;
List<GasRefillModel> 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;
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;
Future getRequests() async {
waitApiRequest(() async {
items.clear();
items.addAll(await GasRefillApiClient().getRequestPages(items: items, pageItemNumber: pageItemNumber));
notifyListeners();
return response.statusCode;
} catch(error) {
isLoading = false;
stateCode = -1;
if (items.length == pageItemNumber) {
nextPage = true;
} else {
nextPage = false;
}
}, onSuccess: () {
stateCode = 200;
notifyListeners();
return -1;
}
});
}
Future<int> createModel ({
@required String host,
@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());
Future createModel({required GasRefillModel model, required BuildContext context}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
Response response;
try{
response = await post(
Uri.parse(
host+URLs.requestGasRefill),
body: body,
waitApiRequest(() async {
items.insert(0, await GasRefillApiClient().createModel(model: model));
notifyListeners();
}, onError: (error) {
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}, onSuccess: () {
Fluttertoast.showToast(
msg: subtitle?.requestCompleteSuccessfully ?? "",
);
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;
}
Navigator.of(context).pop();
});
}
Future<int> updateModel ({
@required String host,
@required User user,
@required GasRefillModel oldModel,
@required GasRefillModel newModel,
Future updateModel({
required GasRefillModel? oldModel,
required GasRefillModel newModel,
}) async {
Map<String,dynamic> body = {
"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;
}
await GasRefillApiClient().updateModel(oldModel: oldModel, newModel: newModel);
}
}
}

@ -3,122 +3,61 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/api/hospitals_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.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
final pageItemNumber = 50;
//reset provider data
void reset(){
_hospitals = null;
void reset() {
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
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
// when user not login or register _user = null
List<Hospital> _hospitals;
List<Hospital> get hospitals => _hospitals;
List<Hospital> _hospitals=[];
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
/// return -2 if request in progress
/// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> 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 = [];
List<Hospital> get hospitals => _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 {
Response response;
try{
response = await get(
Uri.parse(host + URLs.getHospitals
+ ( title == null || title.isEmpty ? "" : "?name=$title" )),
headers: {
"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 [];
Future<List<Hospital>> getHospitalsList({
required String title,
}) async {
waitApiRequest((){
return HospitalsApiClient().getHospitalsList(title: title);
},
onSuccess: (){
_stateCode=200;
}
);
return [];
}
}
}

@ -2,18 +2,18 @@ import 'dart:convert';
import 'package:flutter/cupertino.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
final pageItemNumber = 20;
//reset provider data
void reset(){
notifications = null;
void reset() {
notifications.clear();
nextPage = true;
stateCode = null;
}
@ -21,71 +21,63 @@ class NotificationsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// true if there is next page in product list and false if not
bool nextPage = true;
bool? nextPage = true;
// list of user requests
List<AppNotification> notifications;
List<AppNotification> notifications = [];
// when requests in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
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> getNotifications ({
@required String host,
@required User user,
@required String hospitalId,
Future<int> getNotifications({
required String host,
required User user,
required String hospitalId,
}) async {
if(isLoading == true)
if (isLoading == true) {
return -2;
}
isLoading = true;
notifyListeners();
Response response;
// userId = 397.toString(); // testing id to view data
try{
// userId = 397.toString(); // testing id to view data
try {
response = await get(
Uri.parse(host+URLs.getNotifications
+"?uid=${user.id}"
"&token=${user.token}"
"&page=${(notifications?.length ?? 0) ~/pageItemNumber}"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
Uri.parse(
"${host + URLs.getNotifications}?uid=${user.id}&token=${user.token}&page=${(notifications?.length ?? 0) ~/ pageItemNumber}",
),
headers: {"Content-Type": "application/json; charset=utf-8"});
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<AppNotification> _serviceRequestsPage = requestsListJson.map(
(request) => AppNotification.fromJson(request)).toList();
if(notifications == null)
notifications = [];
notifications.addAll(_serviceRequestsPage);
if(_serviceRequestsPage.length == pageItemNumber){
List<AppNotification> serviceRequestsPage = requestsListJson.map((request) => AppNotification.fromJson(request)).toList();
notifications.addAll(serviceRequestsPage);
if (serviceRequestsPage.length == pageItemNumber) {
nextPage = true;
}else{
} else {
nextPage = false;
}
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
/// 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
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<List<AppNotification>> getRecentNotifications ({
@required String host,
@required User user,
Future<List<AppNotification>?> getRecentNotifications({
required String host,
required User user,
}) async {
Response response;
//userId = 397.toString(); // testing id to view data
try{
response = await get(
Uri.parse(host+URLs.getNotifications
+"?uid=${user.id}&token=${user.token}"),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
);
try {
response = await get(Uri.parse("$host${URLs.getNotifications}?uid=${user.id}&token=${user.token}"), headers: {"Content-Type": "application/json; charset=utf-8"});
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<AppNotification> _recentNotifications = requestsListJson.map(
(request) => AppNotification.fromJson(request)).toList();
return _recentNotifications;
List<AppNotification> recentNotifications = requestsListJson.map((request) => AppNotification.fromJson(request)).toList();
return recentNotifications;
}
return null;
} catch(error) {
} catch (error) {
return null;
}
}
}
}

@ -1,19 +1,19 @@
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/material.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
final pageItemNumber = 50;
//reset provider data
void reset(){
void reset() {
_parts = null;
_stateCode = null;
}
@ -21,24 +21,29 @@ class PartsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
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
// when user not login or register _user = null
List<Part> _parts;
List<Part> get parts => _parts;
List<Part>? _parts;
List<Part>? get parts => _parts;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -48,48 +53,45 @@ class PartsProvider extends ChangeNotifier{
/// 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> getParts ({String host,User user,String title}) async {
if(_loading == true)
return -2;
Future<int> getParts({
required String host,
required User user,
required String? title,
}) async {
if (_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try{
try {
response = await get(
Uri.parse(
host + URLs.getPartNumber
+ "?page=${(_parts?.length ?? 0) ~/pageItemNumber}"
+ ( title == null || title.isEmpty ? "" : "&name=$title" )
),
headers: {
"Content-Type":"application/json; charset=utf-8"
}
Uri.parse(
"$host${URLs.getPartNumber}?page=${(_parts?.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) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
List<Part> _page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
if(parts == null)
_parts = [];
List<Part> page = categoriesListJson.map((part) => Part.fromJson(part)).toList();
if (parts == null) _parts = [];
_parts.addAll(_page);
if(_page.length >= pageItemNumber){
_parts?.addAll(page);
if (page.length >= pageItemNumber) {
_nextPage = true;
}else{
} else {
_nextPage = false;
}
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
/// 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
/// for more details check http state manager
/// 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;
try{
response = await get(
Uri.parse(
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) {
try {
response = await get(Uri.parse(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
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;
} catch(error) {
return page;
} catch (error) {
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: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
final pageItemNumber = 50;
//reset provider data
void reset(){
visits = null;
void reset() {
PreventiveMaintenanceApiClient().visits.clear();
nextPage = true;
stateCode = null;
}
@ -23,115 +24,81 @@ class PreventiveMaintenanceVisitsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// true if there is next page in product list and false if not
bool nextPage = true;
// list of user requests
List<Visit> visits;
// when requests in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
bool? nextPage = true;
VisitsSearch visitsSearch = VisitsSearch();
VisitsSearch? visitsSearch = VisitsSearch();
/// 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> 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.getPreventiveMaintenanceVisits
+"?uid=${user.id}"
"&token=${user.token}"
"&page=${(visits?.length ?? 0) ~/pageItemNumber}"
+visitsSearch?.toSearchString() ?? ""
),
headers: {
"Content-Type":"application/json; charset=utf-8"
Future getVisits() async {
await waitApiRequest(
() async {
await PreventiveMaintenanceApiClient().getVisits(pageItemNumber: pageItemNumber, visitsSearch: visitsSearch);
},
onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
if (PreventiveMaintenanceApiClient().visits.length == pageItemNumber) {
nextPage = true;
} else {
nextPage = false;
}
);
} 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
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;
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
},
);
}
/// 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> updateGroupOfVisits ({
@required String host,
@required User user,
VisitsGroup group,
}) async {
Response response;
Map<String,String> body = group.toJson();
body["token"] = user.token ?? "";
body["uid"] = user.id;
//userId = 397.toString(); // testing id to view data
try{
response = await post(
Uri.parse(
host+URLs.updatePreventiveMaintenanceVisits
),
body: body,
Future updateGroupOfVisits(BuildContext context) async {
final subtitle = AppLocalization.of(context)?.subtitle;
VisitsGroup? group = await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return UpdateVisitsGroupSheet(visits: PreventiveMaintenanceApiClient().visits, title: subtitle?.updatePreventiveMaintenance);
},
) as VisitsGroup?;
if (context.mounted && group != null) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text(subtitle?.updatingDots ?? ''),
content: const Center(child: CircularProgressIndicator()),
);
},
);
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:http/http.dart';
class RegularVisitsProvider extends ChangeNotifier{
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
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
final pageItemNumber = 50;
//reset provider data
void reset(){
visits = null;
// reset provider data
void reset() {
VisitsApiClient().visits.clear();
nextPage = true;
stateCode = null;
}
@ -24,160 +26,105 @@ class RegularVisitsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// true if there is next page in product list and false if not
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();
/// 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> 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){
VisitsSearch? visitsSearch = VisitsSearch();
Future getVisits() async {
await waitApiRequest(
() async {
await VisitsApiClient().getVisits(pageItemNumber: pageItemNumber, visitsSearch: visitsSearch);
},
onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
if (VisitsApiClient().visits.length == pageItemNumber) {
nextPage = true;
}else{
} else {
nextPage = false;
}
}catch(error){
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
isLoading = false;
notifyListeners();
return response.statusCode;
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
},
);
}
/// 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> updateGroupOfVisits ({
@required String host,
@required User user,
VisitsGroup group,
}) async {
Response response;
Map<String,String> body = group.toJson();
body["token"] = user.token ?? "";
body["uid"] = user.id;
//userId = 397.toString(); // testing id to view data
try{
response = await post(
Uri.parse(host+URLs.updateRegularVisits),
body: body,
Future updateGroupOfVisits(BuildContext context) async {
final subtitle = AppLocalization.of(context)?.subtitle;
VisitsGroup? group = await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return UpdateVisitsGroupSheet(visits: VisitsApiClient().visits, title: subtitle?.updateRegularVisits);
},
) as VisitsGroup?;
if (context.mounted && group != null) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text(subtitle?.updatingDots ?? ''),
content: const Center(child: CircularProgressIndicator()),
);
},
);
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 {
Response response;
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<Pentry?> getPently({required String? id}) async {
return id == null ? null : await VisitsApiClient().getPentry(id);
}
Future<int> updatePentry ({
@required String host,
@required User user,
@required Pentry pentry,
@required Visit visit,
}) async {
try{
Response response;
Map<String,String> body = pentry.toMap();
body["uid"] = user.id;
body["token"] = user.token;
response = await post(
Uri.parse(host+URLs.updatePentry + "/${visit.id}"),
body: body,
);
if(response.statusCode >= 200 && response.statusCode < 300) {
visit.status = pentry.ppmVisitStatus;
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
void updatePentry(BuildContext context, {required Pentry? pentry, required Visit? visit}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
await waitApiRequest(
() async {
await VisitsApiClient().updatePentry(pentry: pentry, visit: visit);
},
onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
if (subtitle != null) {
Fluttertoast.showToast(msg: subtitle.requestCompleteSuccessfully);
}
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
Fluttertoast.showToast(msg: errorMessage);
},
);
}
}
}

@ -1,26 +1,30 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.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/subtitle.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/models/user.dart';
class ServiceRequestsProvider extends ChangeNotifier{
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/api/service_request_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
import 'package:test_sa/exceptions/api_exception.dart';
import '../../../models/issue.dart';
import '../../../models/lookup.dart';
import '../../../models/service_report.dart';
import '../../../models/service_request/service_request.dart';
import '../../../models/service_request/service_request_search.dart';
import '../../../models/timer_model.dart';
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
final pageItemNumber = 50;
//reset provider data
void reset(){
serviceRequests = null;
void reset() {
ServiceRequestApiClient().serviceRequests.clear();
nextPage = true;
stateCode = null;
}
@ -28,395 +32,190 @@ class ServiceRequestsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int stateCode;
int? stateCode;
// true if there is next page in product list and false if not
bool nextPage = true;
// list of user requests
List<ServiceRequest> serviceRequests;
// when requests in-process _loading = true
// done _loading = true
// failed _loading = false
bool isLoading;
ServiceRequestSearch search = ServiceRequestSearch();
/// 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;
}
bool? nextPage = true;
ServiceRequestSearch? search = ServiceRequestSearch();
/// Get Service Requests and Fill [ServiceRequestApiClient.serviceRequests]
Future getRequests() async {
await waitApiRequest(() async {
final serviceRequestsPage = await ServiceRequestApiClient().getRequests(pageItemNumber: pageItemNumber, search: search);
if (serviceRequestsPage.length == pageItemNumber) {
nextPage = true;
} else {
nextPage = false;
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}, onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
}, onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
});
}
Future<ServiceRequest> getSingleServiceRequest({
@required String 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<ServiceRequest> getSingleServiceRequest({required String? requestId}) async {
return await ServiceRequestApiClient().getServiceById(requestId);
}
Future<int> createRequest ({
@required String host,
@required User user,
@required ServiceRequest serviceRequest,
}) async {
var body = {
"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(),
};
if(serviceRequest.audio != null){
body["audio"] = serviceRequest.audio;
}
Response response;
try{
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;
}
/// ### Create service request and add the response to [ServiceRequestApiClient.serviceRequests]
Future createRequest(BuildContext context, {required ServiceRequest serviceRequest, required List<File> deviceImages}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
serviceRequest.devicePhotos = deviceImages.map((e) => base64Encode(e.readAsBytesSync())).toList();
if (serviceRequest.audio != null) {
final file = File(serviceRequest.audio!);
serviceRequest.audio = base64Encode(file.readAsBytesSync());
}
waitApiRequest(() async {
await ServiceRequestApiClient().createRequest(serviceRequest);
}, onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
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> createIssueReport ({
@required String host,
@required User user,
@required Issue issue,
}) async {
Response response;
Map<String,String> body = issue.toMap();
body["uid"] = user.id;
body["token"] = user.token;
try{
response = await post(
Uri.parse(host+URLs.createReport),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
}
return response.statusCode;
} catch(error) {
return -1;
}
Future createIssueReport(BuildContext context, {required Issue issue}) async {
await waitApiRequest(() async {
await ServiceRequestApiClient().createIssueReport(issue);
}, onSuccess: () {
final subtitle = AppLocalization.of(context)?.subtitle;
Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
/// TODO : this is temporary
stateCode = 200;
}, onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
});
}
Future<int> updateDate ({
@required String host,
@required User user,
@required String newDate,
@required Lookup employee,
@required ServiceRequest request,
}) async {
Response response;
Map<String,String> body = {};
body["uid"] = user.id;
body["token"] = user.token;
body["nid"] = request.id;
if(newDate != null) body["date"] = newDate;
if(employee != null) body["ass_emp"] = employee.id.toString();
try{
response = await post(
Uri.parse(
host+URLs.updateRequestDate),
body: body,
);
stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
request.engineerName = employee.label;
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
Future updateDate(BuildContext context, {required String? newDate, required Lookup? employee, required ServiceRequest? request}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CupertinoAlertDialog(title: Text(subtitle?.updatingDots ?? ''), content: const Center(child: CircularProgressIndicator()));
},
);
await waitApiRequest(
() async {
await ServiceRequestApiClient().updateDate(newDate: newDate, employee: employee, request: request);
},
onSuccess: () {
Navigator.of(context).pop();
Fluttertoast.showToast(msg: HttpStatusManger.getStatusMessage(status: 200, subtitle: subtitle));
/// TODO : this is temporary
stateCode = 200;
},
onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
},
);
}
Future<int> createServiceReport ({
@required String host,
@required User user,
@required ServiceReport report,
@required ServiceRequest 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) {
Future createServiceReport(BuildContext context, {required ServiceReport? report, required ServiceRequest? request}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
await waitApiRequest(
() async {
await ServiceRequestApiClient().createServiceReport(report: report, request: request);
reset();
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
},
onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? "");
Navigator.of(context).pop();
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 ({
@required String host,
@required User user,
@required ServiceRequest request,
}) async {
Response response;
String userData = '';
if(user != null){
userData += "&uid="+user.id;
userData += "&token="+user.token;
}
try{
response = await get(
Uri.parse(
host+URLs.createDuplicatedReport
+"?nid=${request.id}"
+userData),
Future createDuplicatedReport(BuildContext context, {required ServiceRequest request}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
bool result = await showDialog(context: context, builder: (_) => AAlertDialog(title: subtitle?.duplicateAlert, content: subtitle?.duplicateAlertMessage));
if (result == true && context.mounted) {
showDialog(
context: context,
builder: (context) {
return const Center(child: CircularProgressIndicator());
},
);
await waitApiRequest(
() async {
await ServiceRequestApiClient().createDuplicatedReport(request: request);
reset();
},
onSuccess: () {
Navigator.of(context).pop();
},
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 ({
@required String host,
@required User user,
@required ServiceReport report,
@required ServiceRequest 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) {
Future updateServiceReport(BuildContext context, {required ServiceReport report, required ServiceRequest request}) async {
final subtitle = AppLocalization.of(context)?.subtitle;
await waitApiRequest(
() async {
await ServiceRequestApiClient().updateServiceReport(report: report, request: request);
reset();
notifyListeners();
}
return response.statusCode;
} catch(error) {
return -1;
}
},
onSuccess: () {
Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
Navigator.of(context).pop();
Navigator.of(context).pop();
/// 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 ({
@required String host,
@required User user,
@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) {
Future updateServiceReportTimer({required TimerModel timer, required ServiceRequest request}) async {
try {
await ServiceRequestApiClient().updateServiceReportTimer(timer: timer, request: request);
return -1;
/// TODO : this is temporary
stateCode = 200;
} on APIException catch (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
}
}
Future<ServiceReport> getSingleServiceReport({
@required String 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));
}
Future<ServiceReport?> getSingleServiceReport({required String reportId}) async {
return await ServiceRequestApiClient().getSingleServiceReport(reportId: reportId);
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_items = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class EmployeesProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,19 +45,17 @@ class EmployeesProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user}) async {
if(_loading == true)
return -2;
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try{
try {
response = await get(
Uri.parse(
host + URLs.getEmployees),
Uri.parse((host ?? '') + URLs.getEmployees),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((type) => Lookup.fromJson(type)).toList();
@ -61,14 +63,11 @@ class EmployeesProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,71 +3,43 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
_items = null;
_loading = null;
void reset() {
_items.clear();
_stateCode = null;
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup> _items=[];
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
List<Lookup> get items => _items;
/// return -2 if request in progress
/// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user,}) async {
if(_loading == true)
return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await 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;
Future getData() async {
waitApiRequest(() async {
_items = await GazCylinderSizeApiClient().getData();
notifyListeners();
return response.statusCode;
} catch(error) {
_loading = false;
_stateCode = -1;
},
onSuccess: (){
_stateCode = 200;
notifyListeners();
return -1;
}
);
}
}
}

@ -1,16 +1,16 @@
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/material.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
void reset(){
void reset() {
_items = null;
_loading = null;
_stateCode = null;
@ -19,20 +19,24 @@ class GasStatusProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -42,17 +46,15 @@ class GasStatusProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user,}) async {
if(_loading == true) return -2;
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(host + URLs.getGasStatus),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getGasStatus));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
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();
@ -60,13 +62,11 @@ class GasStatusProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -1,72 +1,44 @@
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/material.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
void reset(){
_items = null;
_loading = null;
void reset() {
_items?.clear();
_stateCode = null;
stopLoading();
}
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
_loading = isLoading;
notifyListeners();
}
List<Lookup>? get items => _items;
/// return -2 if request in progress
/// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user,}) async {
if(_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try{
response = await 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;
Future getData() async {
waitApiRequest(() async {
_items = await GasTypesApiClient().getData();
notifyListeners();
return -1;
}
},
onSuccess: () {
_stateCode = 200;
notifyListeners();
});
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_items = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class PentryStatusProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,20 +45,18 @@ class PentryStatusProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user}) async {
if(_loading == true)
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getPentryStatus),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getPentryStatus));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,14 +64,11 @@ class PentryStatusProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_items = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class PentryTaskStatusProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,20 +45,18 @@ class PentryTaskStatusProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user}) async {
if(_loading == true)
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getPentryTaskStatus),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getPentryTaskStatus));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_items = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,14 +64,11 @@ class PentryTaskStatusProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_items = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class PentryVisitStatusProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,20 +45,18 @@ class PentryVisitStatusProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user}) async {
if(_loading == true)
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getPentryVisitStatus),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getPentryVisitStatus));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,13 +64,11 @@ class PentryVisitStatusProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_items = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class ServiceRequestDefectTypesProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,20 +45,18 @@ class ServiceRequestDefectTypesProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user}) async {
if(_loading == true)
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportDefectTypes),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceReportDefectTypes));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,14 +64,11 @@ class ServiceRequestDefectTypesProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_calls = null;
_loading = null;
_stateCode = null;
@ -19,20 +19,24 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _calls;
List<Lookup> get calls => _calls;
List<Lookup>? _calls;
List<Lookup>? get calls => _calls;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -42,21 +46,23 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
/// 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> getCalls ({String host,User user,String serviceStatus}) async {
if(_loading == true)
return -2;
Future<int> getCalls({
required String? host,
required User? user,
String? serviceStatus,
}) async {
if (_loading == true) return -2;
_loading = true;
notifyListeners();
Response response;
try{
try {
response = await get(
Uri.parse(
host + URLs.getServiceReportLastCalls
+(serviceStatus == null ? "" : "?service_status=$serviceStatus")
),
Uri.parse(
(host ?? '') + URLs.getServiceReportLastCalls + (serviceStatus == null ? "" : "?service_status=$serviceStatus"),
),
);
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_calls = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -64,13 +70,11 @@ class ServiceReportLastCallsProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_items = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class ServiceRequestPriorityProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _items;
List<Lookup> get items => _items;
List<Lookup>? _items;
List<Lookup>? get items => _items;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,20 +45,18 @@ class ServiceRequestPriorityProvider extends ChangeNotifier{
/// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getData ({String host,User user}) async {
if(_loading == true)
Future<int> getData({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportPriority),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceReportPriority));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(utf8.decode(response.bodyBytes));
_items = listJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,13 +64,11 @@ class ServiceRequestPriorityProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_reasons = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _reasons;
List<Lookup> get reasons => _reasons;
List<Lookup>? _reasons;
List<Lookup>? get reasons => _reasons;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,19 +45,17 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
/// 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> getTypes ({String host,User user}) async {
if(_loading == true)
Future<int> getTypes({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportReasons),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceReportReasons));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_reasons = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -61,13 +63,11 @@ class ServiceReportReasonsProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_status = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class ServiceReportStatusProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _status;
List<Lookup> get statuses => _status;
List<Lookup>? _status;
List<Lookup>? get statuses => _status;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,19 +45,17 @@ class ServiceReportStatusProvider extends ChangeNotifier{
/// 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> getTypes ({String host,User user}) async {
if(_loading == true)
Future<int> getTypes({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportStatus),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceReportStatus));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_status = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -61,14 +63,11 @@ class ServiceReportStatusProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_types = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class ServiceReportTypesProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _types;
List<Lookup> get types => _types;
List<Lookup>? _types;
List<Lookup>? get types => _types;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,20 +45,17 @@ class ServiceReportTypesProvider extends ChangeNotifier{
/// 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> getTypes ({String host,User user}) async {
if(_loading == true)
Future<int> getTypes({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceReportTypes),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceReportTypes));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_types = categoriesListJson.map((type) => Lookup.fromIntIdJson(type)).toList();
@ -62,13 +63,11 @@ class ServiceReportTypesProvider extends ChangeNotifier{
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
}
}
}
}

@ -3,14 +3,14 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/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
void reset(){
void reset() {
_statuses = null;
_stateCode = null;
}
@ -18,20 +18,24 @@ class ServiceStatusProvider extends ChangeNotifier{
// state code of current request to defied error message
// like 400 customer request failed
// 500 service not available
int _stateCode;
int get stateCode => _stateCode;
int? _stateCode;
int? get stateCode => _stateCode;
// contain user data
// when user not login or register _user = null
List<Lookup> _statuses;
List<Lookup> get statuses => _statuses;
List<Lookup>? _statuses;
List<Lookup>? get statuses => _statuses;
// when categories in-process _loading = true
// done _loading = true
// failed _loading = false
bool _loading;
bool get isLoading => _loading;
set isLoading(bool isLoading){
bool? _loading;
bool? get isLoading => _loading;
set isLoading(bool? isLoading) {
_loading = isLoading;
notifyListeners();
}
@ -41,35 +45,29 @@ class ServiceStatusProvider extends ChangeNotifier{
/// 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> getTypes ({String host,User user}) async {
if(_loading == true)
Future<int> getTypes({required String? host, required User? user}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try{
response = await get(
Uri.parse(
host + URLs.getServiceTypes),
);
try {
response = await get(Uri.parse((host ?? '') + URLs.getServiceTypes));
_stateCode = response.statusCode;
if(response.statusCode >= 200 && response.statusCode < 300) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_statuses = categoriesListJson.map((e) => Lookup.fromIntIdJson(e)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} catch(error) {
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
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 language = "language";
static final String speechToText = "speech_to_text";
}
}

@ -1,15 +1,14 @@
import 'dart:async';
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: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 {
SharedPreferences prefs = await SharedPreferences.getInstance();
user = null;
@ -21,7 +20,7 @@ class SettingProvider extends ChangeNotifier{
bool isLoaded = false;
// contain saved user data
User user;
User? user;
Future<void> setUser(User user) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
@ -30,8 +29,10 @@ class SettingProvider extends ChangeNotifier{
notifyListeners();
}
String _host;
String get host => _host;
String? _host;
String? get host => _host;
Future<void> setHost(String host) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(ASettings.host, host);
@ -39,8 +40,10 @@ class SettingProvider extends ChangeNotifier{
notifyListeners();
}
String _language;
String get language => _language;
String? _language;
String? get language => _language;
Future<void> setLanguage(String currentLanguage) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(ASettings.language, currentLanguage);
@ -48,8 +51,10 @@ class SettingProvider extends ChangeNotifier{
notifyListeners();
}
String _speechToText;
String get speechToText => _speechToText;
String? _speechToText;
String? get speechToText => _speechToText;
Future<void> setSpeechToText(String currentLanguage) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(ASettings.speechToText, currentLanguage);
@ -58,40 +63,38 @@ class SettingProvider extends ChangeNotifier{
}
// call loadSharedPreferences when provider initialise
SettingProvider(){
SettingProvider() {
loadSharedPreferences();
}
// get app setting
Future<void> loadSharedPreferences() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if(prefs.containsKey(ASettings.language)){
if (prefs.containsKey(ASettings.language)) {
_language = prefs.getString(ASettings.language);
}else{
_language = 'en';
} else {
_language = 'en';
}
if(prefs.containsKey(ASettings.speechToText)){
if (prefs.containsKey(ASettings.speechToText)) {
_speechToText = prefs.getString(ASettings.speechToText);
}else{
_speechToText = 'ar';
} else {
_speechToText = 'ar';
}
if(prefs.containsKey(ASettings.user)){
String userJson = prefs.getString(ASettings.user);
user = User.fromJson(json.decode(userJson));
if (prefs.containsKey(ASettings.user)) {
String? userJson = prefs.getString(ASettings.user);
user = User.fromJson(json.decode(userJson ?? ''));
}
if(prefs.containsKey(ASettings.host)){
if (prefs.containsKey(ASettings.host)) {
_host = prefs.getString(ASettings.host);
} else{
} else {
_host = URLs.host1;
}
isLoaded = true;
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
Validator._();
// check if string not empty and has value
static bool hasValue(String string){
if (string == null || string.isEmpty)
return false;
static bool hasValue(String? string) {
if (string == null || string.isEmpty) return false;
return true;
}
// Return true if email is valid. Otherwise, return false
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]+");
if(exp.hasMatch(email))
return true;
static bool isEmail(String email) {
RegExp exp = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
if (exp.hasMatch(email)) return true;
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) {
return false;
}
@ -26,22 +24,19 @@ class Validator{
final pattern = r'^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$';
final regExp = RegExp(pattern);
if (regExp.hasMatch(phoneNumber))
return true;
if (regExp.hasMatch(phoneNumber)) return true;
return false;
}
// Return true if password is valid. Otherwise, return false
static bool isValidPassword(String password){
if(password == null)
return false;
if(password.length <6)
return false;
static bool isValidPassword(String password) {
if (password == null) return false;
if (password.length < 6) return false;
return true;
}
// Return true if String is valid Numeric. Otherwise, return false
static bool isNumeric(String s) {
static bool isNumeric(String? s) {
if (s == null) {
return false;
}
@ -55,4 +50,4 @@ class Validator{
}
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:test_sa/views/app_style/colors.dart';
import '../views/app_style/colors.dart';
extension IntExtensions on int {
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_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/user_provider.dart';
import 'views/pages/device_transfer/request_device_transfer.dart';
import 'views/pages/device_transfer/track_device_transfer.dart';
import 'views/widgets/hospitals/single_hospital_picker.dart';
@ -57,24 +57,25 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (Platform.isIOS) {
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 {
await Firebase.initializeApp();
}
runApp(
ChangeNotifierProvider(
create: (_) => SettingProvider(),
child: MyApp(),
)
);
runApp(ChangeNotifierProvider(
create: (_) => SettingProvider(),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final _settingProvider = Provider.of<SettingProvider>(context);
final settingProvider = Provider.of<SettingProvider>(context);
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserProvider()),
@ -107,25 +108,19 @@ class MyApp extends StatelessWidget {
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
FocusManager.instance.primaryFocus.unfocus();
FocusManager.instance.primaryFocus?.unfocus();
}
},
child: MaterialApp(
title: 'ATOMS',
debugShowCheckedModeBanner: false,
theme: ThemeData(
fontFamily: "Poppins",
//canvasColor: AColors.primaryColor,
scaffoldBackgroundColor: AColors.scaffoldBackgroundColor,
primaryColor: AColors.primaryColor,
indicatorColor: AColors.primaryColor,
colorScheme: const ColorScheme.light(
primary: AColors.primaryColor,
onPrimary: Colors.white,
secondary: AColors.secondaryColor,
onSecondary: Colors.white
)
),
fontFamily: "Poppins",
//canvasColor: AColors.primaryColor,
scaffoldBackgroundColor: AColors.scaffoldBackgroundColor,
primaryColor: AColors.primaryColor,
indicatorColor: AColors.primaryColor,
colorScheme: const ColorScheme.light(primary: AColors.primaryColor, onPrimary: Colors.white, secondary: AColors.secondaryColor, onSecondary: Colors.white)),
localizationsDelegates: const [
// ... app-specific localization delegate[s] here
AppLocalization.delegate,
@ -137,34 +132,31 @@ class MyApp extends StatelessWidget {
Locale('en'),
Locale('ar'),
],
locale: Locale(_settingProvider.language ?? 'en'),
locale: Locale(settingProvider.language ?? 'en'),
initialRoute: SplashScreen.id,
routes: {
SplashScreen.id: (_)=> const SplashScreen(),
LandPage.id: (_)=> const LandPage(),
Login.id: (_)=> Login(),
Register.id: (_)=> Register(),
ProfilePage.id: (_)=> ProfilePage(),
ReportIssuesPage.id: (_)=> const ReportIssuesPage(),
RequestGasRefill.id: (_)=> const RequestGasRefill(),
CreateRequestPage.id: (_)=> CreateRequestPage(),
SingleHospitalPicker.id: (_)=> SingleHospitalPicker(),
SingleDevicePicker.id: (_)=> SingleDevicePicker(),
SingleDepartmentPicker.id: (_)=> SingleDepartmentPicker(),
ServiceRequestsPage.id: (_)=> ServiceRequestsPage(),
NotificationsPage.id: (_)=> NotificationsPage(),
FutureRequestServiceDetails.id: (_)=> FutureRequestServiceDetails(),
PreventiveMaintenanceVisitsPage.id: (_)=> PreventiveMaintenanceVisitsPage(),
RegularVisitsPage.id: (_)=> RegularVisitsPage(),
TrackGasRefillPage.id: (_)=> const TrackGasRefillPage(),
RequestDeviceTransfer.id: (_)=> const RequestDeviceTransfer(),
TrackDeviceTransferPage.id: (_)=> const TrackDeviceTransferPage(),
SplashScreen.id: (_) => const SplashScreen(),
LandPage.id: (_) => const LandPage(),
Login.id: (_) => const Login(),
Register.id: (_) => Register(),
ProfilePage.id: (_) => ProfilePage(),
ReportIssuesPage.id: (_) => const ReportIssuesPage(),
RequestGasRefill.id: (_) => const RequestGasRefill(),
CreateRequestPage.id: (_) => CreateRequestPage(),
SingleHospitalPicker.id: (_) => SingleHospitalPicker(),
SingleDevicePicker.id: (_) => SingleDevicePicker(),
SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(),
ServiceRequestsPage.id: (_) => ServiceRequestsPage(),
NotificationsPage.id: (_) => NotificationsPage(),
FutureRequestServiceDetails.id: (_) => const FutureRequestServiceDetails(),
PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
RegularVisitsPage.id: (_) => const RegularVisitsPage(),
TrackGasRefillPage.id: (_) => const TrackGasRefillPage(),
RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(),
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{
String requestId;
String title;
String description;
String date;
String path;
class AppNotification {
String? requestId;
String? title;
String? description;
String? date;
String? path;
AppNotification({
this.requestId,
@ -15,13 +15,12 @@ class AppNotification{
this.path,
});
factory AppNotification.fromJson(Map<String,dynamic> parsedJson){
factory AppNotification.fromJson(Map<String, dynamic> parsedJson) {
return AppNotification(
requestId: parsedJson["nid"],
title: parsedJson["call_client"] ?? parsedJson["title"],
description: parsedJson["task_description"],
date: parsedJson["creation_date"],
path: FutureRequestServiceDetails.id
);
requestId: parsedJson["nid"],
title: parsedJson["call_client"] ?? parsedJson["title"],
description: parsedJson["task_description"],
date: parsedJson["creation_date"],
path: FutureRequestServiceDetails.id);
}
}
}

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

@ -1,15 +1,15 @@
class Device{
String id;
String serialNumber;
String number;
String brand;
String model;
DateTime productionDate;
DateTime supplyDate;
DateTime installDate;
DateTime receivingDate;
DateTime operationDate;
DateTime warrantyDate;
class Device {
String? id;
String? serialNumber;
String? number;
String? brand;
String? model;
DateTime? productionDate;
DateTime? supplyDate;
DateTime? installDate;
DateTime? receivingDate;
DateTime? operationDate;
DateTime? warrantyDate;
Device({
this.id,
@ -25,23 +25,23 @@ class Device{
this.warrantyDate,
});
factory Device.fromJson(Map<String,dynamic> parsedJson){
factory Device.fromJson(Map<String, dynamic>? parsedJson) {
return Device(
id: parsedJson["nid"] ?? parsedJson["id"],
serialNumber: parsedJson["sn"] ?? parsedJson["value"],
number: parsedJson["asset_no"],
brand: parsedJson["brand"].toString(),
model: parsedJson["model"].toString(),
productionDate: getDateFromString(parsedJson["production_date"]),
supplyDate: getDateFromString(parsedJson["supply_date "]),
installDate: getDateFromString(parsedJson["install_date "]),
receivingDate: getDateFromString(parsedJson["receving_date "]),
operationDate: getDateFromString(parsedJson["operation_date "]),
warrantyDate: getDateFromString(parsedJson["warranty_date "]),
id: parsedJson?["nid"] ?? parsedJson?["id"]?.toString(),
serialNumber: parsedJson?["sn"] ?? parsedJson?["assetSerialNo"],
number: parsedJson?["asset_no"],
brand: parsedJson?["modelDefinition"]["manufacturerName"] as String?,
model: parsedJson?["modelDefinition"]["modelName"] as String?,
productionDate: getDateFromString(parsedJson?["production_date"]),
supplyDate: getDateFromString(parsedJson?["supply_date "]),
installDate: getDateFromString(parsedJson?["install_date "]),
receivingDate: getDateFromString(parsedJson?["receving_date "]),
operationDate: getDateFromString(parsedJson?["operation_date "]),
warrantyDate: getDateFromString(parsedJson?["warranty_date "]),
);
}
factory Device.fromDevice(Device device){
factory Device.fromDevice(Device device) {
return Device(
id: device.id,
serialNumber: device.serialNumber,
@ -58,9 +58,9 @@ class Device{
}
}
DateTime getDateFromString(String unixDate){
if(unixDate == null)
DateTime? getDateFromString(String? unixDate) {
if (unixDate == 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 'package:test_sa/models/device/device_transfer_info.dart';
import 'device.dart';
import 'device_transfer_info.dart';
class DeviceTransfer{
String id;
String userId;
String title;
Device device;
DeviceTransferInfo sender;
DeviceTransferInfo receiver;
class DeviceTransfer {
int? id;
String? userId;
String? title;
Device? device;
DeviceTransferInfo? sender;
DeviceTransferInfo? receiver;
DeviceTransfer({
this.id,
@ -18,33 +18,36 @@ class DeviceTransfer{
this.receiver,
});
bool validate(){
if(device == null) return false;
return receiver.validate();
bool validate() {
if (device == null) return false;
return receiver?.validate() ?? false;
}
fromDeviceTransfer(DeviceTransfer old){
fromDeviceTransfer(DeviceTransfer old) {
id = old.id;
title = old.title;
userId = old.userId;
device = Device.fromDevice(old.device);
device = old.device != null ? Device.fromDevice(old.device!) : null;
final sender = DeviceTransferInfo();
sender.fromDetails(old.sender);
if (old.sender != null) {
sender.fromDetails(old.sender!);
}
this.sender = sender;
final receiver = DeviceTransferInfo();
receiver.fromDetails(old.receiver);
if (old.receiver != null) {
receiver.fromDetails(old.receiver!);
}
this.receiver = receiver;
}
factory DeviceTransfer.fromJson(Map<String,dynamic> parsedJson){
factory DeviceTransfer.fromJson(Map<String, dynamic> parsedJson) {
return DeviceTransfer(
id: parsedJson["id"],
title: parsedJson["title"],
userId: parsedJson["uid"],
device: Device.fromJson(parsedJson["eq_sn"]),
sender: DeviceTransferInfo.fromJson(parsedJson,"sender_"),
receiver: DeviceTransferInfo.fromJson(parsedJson,"receiver_"),
sender: DeviceTransferInfo.fromJson(parsedJson, "sender"),
receiver: DeviceTransferInfo.fromJson(parsedJson, "receiver"),
);
}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,10 +1,9 @@
class ServiceRequestSearch{
String deviceSerialNumber;
String deviceName;
String hospital;
String model;
int statusValue;
class ServiceRequestSearch {
String? deviceSerialNumber;
String? deviceName;
String? hospital;
String? model;
int? statusValue;
ServiceRequestSearch({
this.deviceSerialNumber,
@ -14,33 +13,20 @@ class ServiceRequestSearch{
this.hospital,
});
fromSearch(ServiceRequestSearch newSearch){
fromSearch(ServiceRequestSearch newSearch) {
deviceSerialNumber = newSearch.deviceSerialNumber;
statusValue = newSearch.statusValue;
hospital = newSearch.hospital;
model = newSearch.model;
}
String toSearchString(){
String _search = "";
if(deviceSerialNumber != null && deviceSerialNumber.isNotEmpty){
_search += "&sn_id=$deviceSerialNumber";
}
if(statusValue != null){
_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;
Map<String, dynamic> queryParameters() {
return <String, dynamic>{
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,
};
}
}
}

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

@ -1,7 +1,7 @@
class TimerModel {
DateTime startAt;
DateTime endAt;
int durationInSecond;
DateTime? startAt;
DateTime? endAt;
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 'package:test_sa/models/department.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/hospital.dart';
import '../controllers/notification/firebase_notification_manger.dart';
class User {
String id;
String userName;
String password;
String email;
String image;
Hospital hospital;
Department department;
UsersTypes type;
String phoneNumber;
String whatsApp;
String token;
bool isActive;
String? clientId;
String? clientName;
int? departmentId;
String? departmentName;
String? message;
String? username;
String? userID;
String? email;
String? password;
String? token;
String? roles;
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(
{this.id,
this.userName = "",
this.email = "",
this.password = "",
this.phoneNumber = "",
this.hospital,
this.image,
this.department,
this.type,
this.whatsApp,
this.token,
this.isActive = false});
///I'm not sure from the datatype
String? phoneNumber;
bool? phoneNumberConfirmed;
bool? twoFactorEnabled;
///I'm not sure from the datatype
String? lockoutEnd;
bool? lockoutEnabled;
int? accessFailedCount;
User({
this.clientId,
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 {
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
return {
"username": userName,
"pass": password,
"firebase_token": FirebaseNotificationManger?.token ?? "",
"password": password,
"fireBaseToken": FirebaseNotificationManger.token ?? "",
};
}
Map<String, dynamic> toUpdateProfileJson() {
Map<String, dynamic> jsonObject = {};
if (department?.id != null && department.id.isNotEmpty) jsonObject["department"] = department.id;
if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp;
if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber;
// if (department?.id != null && (department?.id?.isNotEmpty ?? false)) jsonObject["department"] = department?.id ?? "";
// if (whatsApp != null && (whatsApp?.isNotEmpty ?? false)) jsonObject["whatsapp"] = whatsApp;
// if (phoneNumber != null && (phoneNumber?.isNotEmpty ?? false)) jsonObject["phoneNumber"] = phoneNumber;
return jsonObject;
}
@ -53,59 +164,12 @@ class User {
return {
"username": userName,
"email": email,
"whatsapp": whatsApp,
"client": hospital.id,
"department": department?.id,
"phone": 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,
// "whatsapp": whatsApp,
// "client": hospital?.id,
// "department": department?.id,
"phoneNumber": phoneNumber,
"password": password,
"picture": image,
"active": isActive ? 1 : 0,
"role": type == UsersTypes.engineer ? "field_engineer" : "normal_user",
// "token":token, pass is token
"fireBaseToken": FirebaseNotificationManger.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{
String id;
String serialNumber;
String expectDate;
String actualDate;
String hospitalId;
String hospitalName;
String deviceId;
String deviceSerialNumber;
String deviceArabicName;
String deviceEnglishName;
String employId;
String employName;
String modelAndBrand;
String contactStatus;
Lookup status;
String assignTo;
String deviceNumber;
List<String> images;
Visit({
this.id,
this.serialNumber,
this.hospitalId,
this.hospitalName,
this.deviceId,
this.deviceSerialNumber,
this.deviceArabicName,
this.deviceEnglishName,
this.employId,
this.employName,
this.expectDate,
this.actualDate,
this.status,
this.modelAndBrand,
this.contactStatus,
this.images,
this.assignTo,
this.deviceNumber,
});
factory Visit.fromJson(Map<String,dynamic> parsedJson){
return Visit(
id: parsedJson["nid"],
serialNumber: parsedJson["title"],
hospitalId: parsedJson["client"],
deviceNumber: parsedJson["device_no"],
hospitalName: parsedJson["client_name"],
deviceId: parsedJson["medical_equipment_nid"],
deviceSerialNumber: parsedJson["medical_equipment"],
deviceEnglishName: parsedJson["equipment_english_name"],
deviceArabicName: parsedJson["equipment_arabic_name"],
employId: parsedJson["assigned_employee"],
employName: parsedJson["assigned_employee_name"],
expectDate: parsedJson["expected_date"],
actualDate: parsedJson["actual_date"],
modelAndBrand: parsedJson["mode_brand"],
contactStatus: parsedJson["contactStatus"],
images: List<String>.from(parsedJson["images"] ?? []),
status: Lookup(
id: int.tryParse(parsedJson["status"] ?? "-1"), // actual value (0,1,2)
label: parsedJson["status_value"] // text value
),
assignTo: parsedJson["assigned_to"],
);
class Visit {
int? id;
int? visitNo;
String? visitCode;
int? ppmId;
int? planNo;
String? planCode;
int? ppmScheduleId;
int? ppmScheduleNo;
String? ppmScheduleCode;
int? assetId;
String? assetName;
String? assetSerialNo;
String? assetNumber;
String? warrantyEndDate;
int? modelId;
String? modelName;
int? manufacturerId;
String? manufacturerName;
int? siteId;
String? siteName;
int? assignedToId;
String? assignedToName;
String? jobSheetNo;
String? assignedEmployeeId;
String? assignedEmployeeName;
String? expectedDate;
String? actualDate;
String? nextDate;
String? forwardToId;
String? forwardToName;
int? maintenanceContractId;
String? contractNumber;
int? typeOfServiceId;
String? typeOfServiceName;
int? executionTimeFrameId;
String? executionTimeFrameName;
String? externalEngineer;
String? telephone;
int? groupLeaderReviewId;
String? groupLeaderReviewName;
int? timePeriodId;
String? timePeriodName;
List<VCalibrationTools>? vCalibrationTools;
List<VKits>? vKits;
List<VContacts>? vContacts;
List<VChecklists>? vChecklists;
List<String>? vAttachments;
int? visitStatusId;
String? visitStatusName;
String? startDate;
String? endDate;
String? workingHours;
String? travelingHours;
int? deviceStatusId;
String? deviceStatusName;
String? comments;
String? workPerformed;
int? supplierId;
String? supplierName;
int? ppmSupplierId;
String? ppmSupplierName;
String? createdOn;
String? modifiedOn;
int? taskStatusId;
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';
import 'package:test_sa/models/visits/visit.dart';
class VisitsGroup{
String userId;
String workingHours;
String travelingHours;
String jobSheetNumber;
String image;
Lookup status;
Lookup taskStatus;
DateTime date;
List<Visit> visits;
class VisitsGroup {
String? userId;
String? workingHours;
String? travelingHours;
String? jobSheetNumber;
String? image;
Lookup? status;
Lookup? taskStatus;
DateTime? date;
List<Visit>? visits;
VisitsGroup({
this.userId,
@ -25,21 +24,22 @@ class VisitsGroup{
this.taskStatus,
});
Map<String,String> toJson(){
Map<String,String> jsonObject = {};
jsonObject["nids"] = visits.map((e) => e.id).toList().join(',');
if(status != null) jsonObject["status"] = status.id.toString();
if(date != null) jsonObject["date"] = date.toString().split(" ").first;
if(jobSheetNumber != null && jobSheetNumber.isNotEmpty)
jsonObject["job_sheet_no"] = jobSheetNumber;
if(travelingHours != null && travelingHours.isNotEmpty)
jsonObject["traveling_hours"] = travelingHours;
if(workingHours != null && workingHours.isNotEmpty)
jsonObject["working_hours"] = workingHours;
if(image != null) jsonObject["image"] = image;
if(taskStatus != null) jsonObject["task_status"] = taskStatus.id.toString();
Map<String, String> toJson() {
Map<String, String> jsonObject = {};
jsonObject["nids"] = visits!.map((e) => e.id).toList().join(',');
if (status != null) jsonObject["status"] = status?.id.toString() ?? "";
if (date != null) jsonObject["date"] = date.toString().split(" ").first;
if (jobSheetNumber != null && (jobSheetNumber?.isNotEmpty ?? false)) {
jsonObject["job_sheet_no"] = jobSheetNumber!;
}
if (travelingHours != null && (travelingHours?.isNotEmpty ?? false)) {
jsonObject["traveling_hours"] = travelingHours ?? "";
}
if (workingHours != null && (workingHours?.isNotEmpty ?? false)) {
jsonObject["working_hours"] = workingHours ?? "";
}
if (image != null) jsonObject["image"] = image ?? "";
if (taskStatus != null) jsonObject["task_status"] = taskStatus?.id.toString() ?? "";
return jsonObject;
}
}
}

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

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

@ -1,39 +1,31 @@
import 'package:flutter/material.dart';
class AppStyle {
AppStyle._();
static const double borderRadius = 10;
static const BoxShadow boxShadow = BoxShadow(
color: Colors.black26,
blurRadius: 3,
offset: Offset(0,2)
);
static const BoxShadow boxShadow = BoxShadow(color: Colors.black26, blurRadius: 3, offset: Offset(0, 2));
static double getBorderRadius(BuildContext context){
static double getBorderRadius(BuildContext context) {
return borderRadius * getScaleFactor(context);
}
static double getScaleFactor(BuildContext context){
static double getScaleFactor(BuildContext context) {
return MediaQuery.of(context).orientation == Orientation.portrait
? MediaQuery.of(context).size.width/(360) > 1.5
? 1.5 : MediaQuery.of(context).size.width/(360)
: MediaQuery.of(context).size.height/(360) > 1.5
? 1.5 : MediaQuery.of(context).size.height/(360);
? MediaQuery.of(context).size.width / (360) > 1.5
? 1.5
: MediaQuery.of(context).size.width / (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(
topRight: Radius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
topLeft: Radius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
bottomRight: Radius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
topRight: 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:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/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/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/device_transfer/update_device_transfer.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/device_trancfer/device_transfer_info_section.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart';
import '../../../api/user_api_client.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 '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../../widgets/buttons/app_back_button.dart';
import '../../widgets/buttons/app_small_button.dart';
import '../../widgets/device_trancfer/device_transfer_info_section.dart';
import '../../widgets/loaders/loading_manager.dart';
import '../../widgets/requests/info_row.dart';
import 'update_device_transfer.dart';
class DeviceTransferDetails extends StatefulWidget {
final DeviceTransfer model;
const DeviceTransferDetails({Key key, this.model}) : super(key: key);
const DeviceTransferDetails({Key? key, required this.model}) : super(key: key);
@override
State<DeviceTransferDetails> createState() => _DeviceTransferDetailsState();
}
class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
final DeviceTransferInfo _model = DeviceTransferInfo();
bool _isSender = false;
bool _isReceiver = false;
UserProvider _userProvider;
SettingProvider _settingProvider;
DeviceTransferProvider _deviceTransferProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
DeviceTransferProvider? _deviceTransferProvider;
bool _isLoading = false;
Subtitle _subtitle;
Subtitle? _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
}
@override
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);
_isSender = _userProvider.user.id == widget.model.sender?.userId;
_isReceiver = _userProvider.user.id == widget.model.receiver?.userId;
_isSender = UserApiClient().user?.id == widget.model.sender?.userId;
_isReceiver = UserApiClient().user?.id == widget.model.receiver?.userId;
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
@ -66,18 +65,15 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
children: [
Container(
color: Theme.of(context).colorScheme.primary,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Row(
children: [
const ABackButton(),
ABackButton(),
Expanded(
child: Center(
child: Text(
_subtitle.details,
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.white,
fontStyle: FontStyle.italic
),
_subtitle?.details ?? "",
style: Theme.of(context).textTheme.headline6?.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
),
),
),
@ -87,71 +83,64 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
),
Expanded(
child: SingleChildScrollView(
padding: EdgeInsets.all(16*AppStyle.getScaleFactor(context)),
padding: EdgeInsets.all(16 * AppStyle.getScaleFactor(context)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RequestInfoRow(
title: _subtitle.title,
title: _subtitle!.title,
info: widget.model.title,
),
RequestInfoRow(
title: _subtitle.device,
info: widget.model.device.serialNumber,
title: _subtitle?.device,
info: widget.model.device?.serialNumber,
),
const SizedBox(height:8),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: Text(
"Sender",
style: Theme.of(context).textTheme.headline6
),
child: Text("Sender", style: Theme.of(context).textTheme.headline6),
),
if(_isSender)
if (_isSender)
ASmallButton(
text: _subtitle.edit,
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_)=> UpdateDeviceTransfer(model: widget.model,isSender: _isSender,)
)
);
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(
info: widget.model.sender,
info: widget.model.sender!,
),
const SizedBox(height:8),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: Text(
"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,)
)
);
},
child: Text("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,
)));
},
),
],
),
const SizedBox(height:12),
const SizedBox(height: 12),
DeviceTransferInfoSection(
info: widget.model.receiver,
info: widget.model.receiver!,
),
],
),
),

@ -1,27 +1,29 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.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/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 'package:test_sa/models/hospital.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 {
static const String id = "/request-device-transfer";
const RequestDeviceTransfer({Key key}) : super(key: key);
const RequestDeviceTransfer({Key? key}) : super(key: key);
@override
State<RequestDeviceTransfer> createState() => _RequestDeviceTransferState();
@ -30,10 +32,8 @@ class RequestDeviceTransfer extends StatefulWidget {
class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
bool _isLoading = false;
bool _validate = false;
Subtitle _subtitle;
UserProvider _userProvider;
SettingProvider _settingProvider;
DeviceTransferProvider _deviceTransferProvider;
Subtitle? _subtitle;
DeviceTransferProvider? _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController();
final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo());
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -44,42 +44,6 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
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
void dispose() {
_requestedQuantityController.dispose();
@ -88,9 +52,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_subtitle = AppLocalization.of(context)?.subtitle;
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
@ -112,7 +74,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
padding: const EdgeInsets.all(8.0),
child: Text(
"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"),
if (_validate && _formModel.device == null)
ASubTitle(
_subtitle.requiredWord,
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
6.height,
@ -159,38 +121,55 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
// ),
12.height,
const ASubTitle("Destination Client"),
if (_validate && _formModel.receiver.client == null)
if (_validate && _formModel.receiver?.client == null)
ASubTitle(
_subtitle.requiredWord,
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
6.height,
HospitalButton(
hospital: _formModel.receiver.client,
hospital: _formModel.receiver?.client ?? Hospital(),
onHospitalPick: (hospital) {
_formModel.receiver.client = hospital;
_formModel.receiver?.client = hospital;
setState(() {});
},
),
12.height,
const ASubTitle("Destination Department"),
if (_validate && _formModel.receiver.department == null)
if (_validate && _formModel.receiver?.department == null)
ASubTitle(
_subtitle.requiredWord,
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
6.height,
DepartmentButton(
department: _formModel.receiver.department,
department: _formModel.receiver?.department,
onDepartmentPick: (department) {
_formModel.receiver.department = department;
_formModel.receiver?.department = department;
setState(() {});
},
),
12.height,
AButton(
text: _subtitle.submit,
onPressed: _onSubmit,
text: _subtitle?.submit ?? "",
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(
height: 100,

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

@ -4,26 +4,29 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.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 {
final DeviceTransfer model;
final bool isSender;
const UpdateDeviceTransfer({Key key, this.model, this.isSender}) : super(key: key);
final bool? isSender;
const UpdateDeviceTransfer({Key? key, required this.model, this.isSender}) : super(key: key);
@override
State<UpdateDeviceTransfer> createState() => _UpdateDeviceTransferState();
@ -32,11 +35,11 @@ class UpdateDeviceTransfer extends StatefulWidget {
class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
bool _isLoading = false;
bool _validate = false;
Subtitle _subtitle;
UserProvider _userProvider;
SettingProvider _settingProvider;
Uint8List _signature;
DeviceTransferProvider _deviceTransferProvider;
Subtitle? _subtitle;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
Uint8List? _signature;
DeviceTransferProvider? _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController();
final DeviceTransferInfo _formModel = DeviceTransferInfo();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -44,55 +47,41 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
_update() async {
_validate = true;
if(!_formKey.currentState.validate()){
if ((_formKey.currentState?.validate() ?? false)) {
setState(() {});
return false;
}
_formKey.currentState.save();
_formKey.currentState?.save();
_isLoading =true;
_isLoading = true;
setState(() {});
int status = await _deviceTransferProvider.updateRequest(
user: _userProvider.user,
host: _settingProvider.host,
requestId: widget.model.id,
isSender: widget.isSender,
newModel: _formModel,
oldModel: widget.model
);
_isLoading =false;
int? status = await _deviceTransferProvider?.updateRequest(
user: UserApiClient().user ?? User(), host: _settingProvider?.host ?? "", requestId: widget.model?.id.toString() ?? "", isSender: widget.isSender ?? false, newModel: _formModel, oldModel: widget.model);
_isLoading = false;
setState(() {});
if(status >= 200 && status < 300){
if (status != null && status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
msg: _subtitle?.requestCompleteSuccessfully ?? "",
);
_validate = false;
Navigator.of(context).pop();
Navigator.of(context).pop();
}else{
String errorMessage = HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
}
@override
void setState(VoidCallback fn){
if(mounted) super.setState(() {});
void setState(VoidCallback fn) {
if (mounted) super.setState(() {});
}
@override
void initState() {
_formModel.fromDetails(widget.isSender
? widget.model.sender : widget.model.receiver,
withSignature: false
);
_formModel.fromDetails((widget.isSender ?? false) ? widget.model?.sender : widget.model?.receiver, withSignature: false);
super.initState();
}
@ -104,10 +93,10 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
@override
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(
key: _scaffoldKey,
body: Form(
@ -128,96 +117,100 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
padding: const EdgeInsets.all(8.0),
child: Text(
"Edit 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),
),
),
),
const SizedBox(height: 8,),
const SizedBox(
height: 8,
),
ASubTitle("Comment"),
const SizedBox(height: 4,),
const SizedBox(
height: 4,
),
ATextFormField(
initialValue: _formModel?.comment,
initialValue: _formModel.comment ?? "",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
onSaved: (value){
onSaved: (value) {
_formModel.comment = value;
},
),
const SizedBox(height: 8,),
ASubTitle(_subtitle.travelingHours),
const SizedBox(height: 4,),
const SizedBox(
height: 8,
),
ASubTitle(_subtitle?.travelingHours ?? ""),
const SizedBox(
height: 4,
),
ATextFormField(
initialValue: _formModel?.travelingHours,
initialValue: _formModel.travelingHours ?? "",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
onSaved: (value){
onSaved: (value) {
_formModel.travelingHours = value;
},
),
const SizedBox(height: 8,),
ASubTitle(_subtitle.workingHours),
const SizedBox(height: 4,),
const SizedBox(
height: 8,
),
ASubTitle(_subtitle?.workingHours ?? ""),
const SizedBox(
height: 4,
),
ATextFormField(
initialValue: _formModel?.workingHours,
initialValue: _formModel.workingHours ?? "",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
onSaved: (value){
onSaved: (value) {
_formModel.workingHours = value;
},
),
// const SizedBox(height: 8,),
// const ASubTitle("Sender Department"),
// if(_validate && _formModel.senderDepartment == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
// const SizedBox(height: 4,),
// DepartmentButton(
// department: _formModel.senderDepartment,
// onDepartmentPick: (department){
// _formModel.senderDepartment = department;
// setState(() {});
// },
// ),
const SizedBox(height: 8,),
ASubTitle(_subtitle.status),
const SizedBox(height: 4,),
const SizedBox(
height: 8,
),
ASubTitle(_subtitle?.status ?? ""),
const SizedBox(
height: 4,
),
GasStatusMenu(
initialValue: _formModel.status,
onSelect: (status){
onSelect: (status) {
_formModel.status = status;
setState(() {});
},
),
const SizedBox(height: 8,),
const SizedBox(
height: 8,
),
const ASubTitle("Signature"),
// if(_validate && _formModel.signature == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
const SizedBox(
height: 4,
),
ESignature(
oldSignature: widget.isSender
? widget.model.sender.signature
: widget.model.receiver.signature,
newSignature: _signature,
onSaved: (signature){
_signature = signature;
_formModel.signature = base64Encode(signature);
},
oldSignature: (widget.isSender ?? false) ? widget.model?.sender?.signature : widget.model?.receiver?.signature,
newSignature: _signature,
onSaved: (signature) {
_signature = signature;
_formModel.signature = base64Encode(signature);
},
),
Padding(
padding: const EdgeInsets.all(16.0),
child: AButton(
text: _subtitle.update,
text: _subtitle?.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:fluttertoast/fluttertoast.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 {
static final String id = "/login";
static const String id = "/login";
const Login({super.key});
@override
_LoginState createState() => _LoginState();
LoginState createState() => LoginState();
}
class _LoginState extends State<Login> {
UserProvider _userProvider;
SettingProvider _settingProvider;
User _user = User();
class LoginState extends State<Login> {
late UserProvider _userProvider;
late SettingProvider _settingProvider;
bool _obscurePassword = true;
bool _firstTime = true;
double _height;
double _width;
String _payload;
late double _height;
final User _user = User();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@ -41,13 +36,12 @@ class _LoginState extends State<Login> {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_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(
key: _scaffoldKey,
body: SafeArea(
child: LoadingManager(
isLoading: _userProvider.isLoading || !_settingProvider.isLoaded,
isLoading: (_userProvider.loading) || !(_settingProvider.isLoaded),
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
@ -66,7 +60,7 @@ class _LoginState extends State<Login> {
child: Image(
height: _height / 6,
fit: BoxFit.contain,
image: AssetImage("assets/images/logo.png"),
image: const AssetImage("assets/images/logo.png"),
),
),
Padding(
@ -77,57 +71,45 @@ class _LoginState extends State<Login> {
height: 24 * AppStyle.getScaleFactor(context),
),
ATextFormField(
initialValue: _user?.userName,
hintText: _subtitle.name,
initialValue: _user.userName ?? "",
hintText: subtitle?.name ?? "",
textAlign: TextAlign.left,
style: Theme.of(context).textTheme.bodyText1,
style: Theme.of(context).textTheme.bodyLarge,
prefixIconData: Icons.account_circle,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage,
validator: (value) => Validator.hasValue(value ?? '') ? null : subtitle?.nameValidateMessage,
textInputType: TextInputType.name,
onSaved: (value) {
_user.userName = value;
if (value != null) {
_user.userName = value;
}
},
),
SizedBox(height: 12),
const SizedBox(height: 12),
ATextFormField(
initialValue: _user?.password,
hintText: _subtitle.password,
initialValue: _user.password,
hintText: subtitle?.password ?? "",
obscureText: _obscurePassword,
style: Theme.of(context).textTheme.bodyText1,
style: Theme.of(context).textTheme.bodyLarge,
prefixIconData: Icons.vpn_key_sharp,
textAlign: TextAlign.left,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle.passwordValidateMessage,
validator: (value) => Validator.isValidPassword(value ?? '') ? null : subtitle?.passwordValidateMessage,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
},
onSaved: (value) {
_user.password = value;
_user.password = value!;
},
),
SizedBox(
height: 32 * AppStyle.getScaleFactor(context),
),
AButton(
text: _subtitle.signIn,
text: subtitle?.signIn ?? "",
onPressed: () async {
if (!_formKey.currentState.validate()) return;
_formKey.currentState.save();
int status = await _userProvider.login(
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),
));
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState?.save();
await _userProvider.login(context, user: _user);
}
},
),

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

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

@ -1,95 +1,80 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.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/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 {
final GasRefillModel model;
const GasRefillDetails({Key key, this.model}) : super(key: key);
final GasRefillModel? model;
const GasRefillDetails({Key? key, this.model}) : super(key: key);
@override
State<GasRefillDetails> createState() => _GasRefillDetailsState();
}
class _GasRefillDetailsState extends State<GasRefillDetails> {
final GasRefillModel _model = GasRefillModel();
bool _enableEdit = false;
bool _validate = false;
UserProvider _userProvider;
SettingProvider _settingProvider;
GasRefillProvider _gasRefillProvider;
GasRefillProvider? _gasRefillProvider;
bool _isLoading = false;
Subtitle _subtitle;
Subtitle? _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
_update() async {
_validate = true;
if(!_formKey.currentState.validate()){
if (!(_formKey.currentState?.validate() ?? false)) {
setState(() {});
return false;
}
_formKey.currentState.save();
_formKey.currentState?.save();
_isLoading =true;
_isLoading = true;
setState(() {});
int status = await _gasRefillProvider.updateModel(
user: _userProvider.user,
host: _settingProvider.host,
newModel: _model,
oldModel: widget.model
);
_isLoading =false;
int? status = await _gasRefillProvider?.updateModel(newModel: _model, oldModel: widget.model);
_isLoading = false;
setState(() {});
if(status >= 200 && status < 300){
if (status != null && status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
msg: _subtitle?.requestCompleteSuccessfully ?? "",
);
_enableEdit = false;
_validate = false;
//Navigator.of(context).pop();
}else{
String errorMessage = HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
}
@override
void initState() {
_model.fromGasRefillModel(widget.model);
_model.fromGasRefillModel(widget.model ?? GasRefillModel());
super.initState();
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_subtitle = AppLocalization.of(context)?.subtitle;
_gasRefillProvider = Provider.of<GasRefillProvider>(context);
return Scaffold(
key: _scaffoldKey,
@ -105,108 +90,117 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
children: [
Container(
color: Theme.of(context).colorScheme.primary,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Row(
children: [
const ABackButton(),
ABackButton(),
Expanded(
child: Center(
child: Text(
_subtitle.details,
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.white,
fontStyle: FontStyle.italic
),
_subtitle?.details ?? "",
style: Theme.of(context).textTheme.headline6?.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
),
),
),
if(_userProvider.user.type == UsersTypes.engineer)
AIconButton(
iconData: _enableEdit ? Icons.cancel : Icons.edit,
color: Theme.of(context).colorScheme.onPrimary,
buttonSize: 42,
backgroundColor: AColors.green,
onPressed: () async {
_enableEdit = !_enableEdit;
_model.fromGasRefillModel(widget.model);
setState(() {});
},
),
const SizedBox(width: 16,)
if (UserApiClient().user?.roles == UsersTypes.engineer.name)
AIconButton(
iconData: _enableEdit ? Icons.cancel : Icons.edit,
color: Theme.of(context).colorScheme.onPrimary,
buttonSize: 42,
backgroundColor: AColors.green,
onPressed: () async {
_enableEdit = !_enableEdit;
_model.fromGasRefillModel(widget.model ?? GasRefillModel());
setState(() {});
},
),
const SizedBox(
width: 16,
)
],
),
),
Expanded(
child: SingleChildScrollView(
padding: EdgeInsets.all(16*AppStyle.getScaleFactor(context)),
padding: EdgeInsets.all(16 * AppStyle.getScaleFactor(context)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RequestInfoRow(
title: _subtitle.title,
info: _model.title,
title: _subtitle?.title ?? "",
info: _model.title ?? "",
),
RequestInfoRow(
title: _subtitle.hospital,
info: _model.clientName,
title: _subtitle?.hospital ?? "",
info: _model.clientName ?? "",
),
_enableEdit ?
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8,),
ASubTitle(_subtitle.status),
if(_validate && _model.status == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
GasStatusMenu(
initialValue: _model.status,
onSelect: (status){
_model.status = status;
},
)
],
):
Row(
children: [
Expanded(
child: Text(
"${_subtitle.status} : ",
style: Theme.of(context).textTheme.subtitle2,
textScaleFactor: AppStyle.getScaleFactor(context),
_enableEdit
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 8,
),
ASubTitle(_subtitle?.status ?? ""),
if (_validate && _model.status == null)
ASubTitle(
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
const SizedBox(
height: 4,
),
GasStatusMenu(
initialValue: _model.status,
onSelect: (status) {
_model.status = status;
},
)
],
)
: 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)),
],
),
),
StatusLabel(label: _model.status.label,
color: AColors.getGasStatusColor(_model.status.id)
),
],
const SizedBox(
height: 8,
),
const SizedBox(height: 8,),
const ASubTitle("Gas Requests"),
const SizedBox(height: 8,),
const SizedBox(
height: 8,
),
ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: _model.details.length,
itemBuilder: (context,index){
final details = _model.details[index];
itemCount: _model.details?.length,
itemBuilder: (context, index) {
final details = _model.details![index];
return GasRefillUpdateDetailsItem(
details: details,
validate: _validate,
enableEdit: _enableEdit,
);
}
),
if(_enableEdit)
Column(
children: [
const SizedBox(height: 16,),
AButton(
text: _subtitle.update,
onPressed: _update,
),
],
),
}),
if (_enableEdit)
Column(
children: [
const SizedBox(
height: 16,
),
AButton(
text: _subtitle?.update ?? "",
onPressed: _update,
),
],
),
],
),
),

@ -1,28 +1,30 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.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/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 {
static const String id = "/request-gas-refill";
const RequestGasRefill({Key key}) : super(key: key);
const RequestGasRefill({Key? key}) : super(key: key);
@override
State<RequestGasRefill> createState() => _RequestGasRefillState();
@ -31,11 +33,9 @@ class RequestGasRefill extends StatefulWidget {
class _RequestGasRefillState extends State<RequestGasRefill> {
bool _isLoading = false;
bool _validate = false;
Subtitle _subtitle;
UserProvider _userProvider;
SettingProvider _settingProvider;
GasRefillProvider _gasRefillProvider;
GasRefillDetails _currentDetails = GasRefillDetails();
Subtitle? _subtitle;
GasRefillProvider? _gasRefillProvider;
GasRefillDetails _currentDetails = GasRefillDetails(model: null);
final TextEditingController _requestedQuantityController = TextEditingController();
final GasRefillModel _formModel = GasRefillModel(details: []);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -43,61 +43,27 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void setState(VoidCallback fn){
if(mounted) super.setState(() {});
void setState(VoidCallback fn) {
if (mounted) super.setState(() {});
}
_onSubmit() async {
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(){
bool _addNewModel() {
_validate = true;
if(!_formKey.currentState.validate()){
if (!(_formKey.currentState?.validate() ?? false)) {
setState(() {});
return false;
}
_formKey.currentState.save();
if(!_currentDetails.validate()) {
setState(() { });
_formKey.currentState?.save();
if (!_currentDetails.validate()) {
setState(() {});
return false;
}
_formModel.details.insert(0,_currentDetails);
_formModel.details?.insert(0, _currentDetails);
_validate = false;
Scrollable.ensureVisible(_DetailsKey.currentContext);
Scrollable.ensureVisible(_DetailsKey.currentContext!);
_requestedQuantityController.clear();
_currentDetails = GasRefillDetails();
_currentDetails = GasRefillDetails(model: null);
setState(() {});
return true;
}
@ -107,12 +73,11 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
_requestedQuantityController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context,listen: false);
_subtitle = AppLocalization.of(context)?.subtitle;
_gasRefillProvider = Provider.of<GasRefillProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
body: Form(
@ -133,11 +98,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
padding: const EdgeInsets.all(8.0),
child: Text(
"Request Gas Refill",
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),
),
),
),
@ -168,76 +129,94 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
// ),
// const SizedBox(height: 8,),
// Divider(color: Theme.of(context).colorScheme.primary,),
const SizedBox(height: 4,),
const SizedBox(
height: 4,
),
const ASubTitle("Type"),
if(_validate && _currentDetails.type == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
if (_validate && _currentDetails.type == null)
ASubTitle(
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
const SizedBox(
height: 4,
),
GasTypeMenu(
initialValue: _currentDetails.type,
onSelect: (status){
onSelect: (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,),
ASubTitle(_subtitle.quantity),
if(_validate && _currentDetails.requestedQuantity == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
SizedBox(height: 4,),
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,
),
ASubTitle(_subtitle?.quantity ?? ""),
if (_validate && _currentDetails.requestedQuantity == null)
ASubTitle(
_subtitle?.requiredWord ?? "",
color: Colors.red,
),
SizedBox(
height: 4,
),
ATextFormField(
initialValue: (_currentDetails?.requestedQuantity ?? "").toString(),
initialValue: (_currentDetails.requestedQuantity ?? "").toString(),
textAlign: TextAlign.center,
controller: _requestedQuantityController,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.isNumeric(value)
? null : "allow numbers only",
validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only",
textInputType: TextInputType.number,
onSaved: (value){
_currentDetails.requestedQuantity = int.tryParse(value);
onSaved: (value) {
_currentDetails.requestedQuantity = int.tryParse(value!);
},
),
const SizedBox(height: 16),
AButton(
text: _subtitle.add,
text: _subtitle?.add ?? "",
onPressed: _addNewModel,
),
if(_formModel.details.isNotEmpty)
const ASubTitle("Gas Requests"),
if ((_formModel.details?.isNotEmpty ?? false)) const ASubTitle("Gas Requests"),
ListView.builder(
key: _DetailsKey,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: _formModel.details.length,
itemBuilder: (context,index){
final model = _formModel.details[index];
return GasRefillCreateDetailsItem(
model: model,
onDelete: (){
_formModel.details.remove(model);
setState(() {});
},
);
}
),
key: _DetailsKey,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: _formModel.details?.length,
itemBuilder: (context, index) {
final model = _formModel.details![index];
return GasRefillCreateDetailsItem(
model: model,
onDelete: () {
_formModel.details?.remove(model);
setState(() {});
},
);
}),
const SizedBox(height: 16),
AButton(
text: _subtitle.submit,
onPressed: _onSubmit,
text: _subtitle?.submit ?? "",
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:provider/provider.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/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_list.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../api/user_api_client.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 '../../../../models/subtitle.dart';
import '../../../../models/user.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 {
static const String id = "/track-gas-refill";
const TrackGasRefillPage({Key key}) : super(key: key);
const TrackGasRefillPage({Key? key}) : super(key: key);
@override
State<TrackGasRefillPage> createState() => _TrackGasRefillPageState();
}
class _TrackGasRefillPageState extends State<TrackGasRefillPage>
with TickerProviderStateMixin{
GasRefillProvider _gasRefillProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
class _TrackGasRefillPageState extends State<TrackGasRefillPage> with TickerProviderStateMixin {
late GasRefillProvider _gasRefillProvider;
@override
Widget build(BuildContext context) {
_gasRefillProvider = Provider.of<GasRefillProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
body: SafeArea(
child: LoadingManager(
isLoading: _gasRefillProvider.isLoading,
isLoading: _gasRefillProvider.loading,
isFailedLoading: _gasRefillProvider.items == null,
stateCode: _gasRefillProvider.stateCode,
onRefresh: () async {
_gasRefillProvider.reset();
await _gasRefillProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
);
await _gasRefillProvider.getRequests();
},
child: Stack(
children: [
Column(
children: [
Container(
color:AColors.white,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4),
color: AColors.white,
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Column(
children: [
Row(
@ -58,18 +54,16 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
Expanded(
child: Center(
child: Text(
_subtitle.serviceRequests,
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.grey3A,
fontStyle: FontStyle.italic
),
_subtitle?.serviceRequests ?? "",
style: Theme.of(context).textTheme.headline6?.copyWith(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(
nextPage: _gasRefillProvider.nextPage,
onLazyLoad: () async {
await _gasRefillProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
);
await _gasRefillProvider.getRequests();
},
items: _gasRefillProvider.items,
),
),
],
),
],
),
),

@ -1,64 +1,64 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:package_info/package_info.dart';
import 'package:provider/provider.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 '../../../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 '../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 'visits/regular_visits_page.dart';
class LandPage extends StatefulWidget {
static const String id = "/land-page";
const LandPage({Key key}) : super(key: key);
const LandPage({Key? key}) : super(key: key);
@override
State<LandPage> createState() => _LandPageState();
}
class _LandPageState extends State<LandPage> {
double _height;
double _width;
UserProvider _userProvider;
SettingProvider _settingProvider;
DepartmentsProvider _departmentsProvider;
DevicesProvider _devicesProvider;
double _buttonHeight;
bool firstTime = true;
ServiceRequestsProvider _serviceRequestsProvider;
PreventiveMaintenanceVisitsProvider _preventiveMaintenanceVisitsProvider;
RegularVisitsProvider _regularVisitsProvider;
late double _height;
late double _width;
late UserProvider _userProvider;
late SettingProvider _settingProvider;
late DepartmentsProvider _departmentsProvider;
late DevicesProvider _devicesProvider;
late double _buttonHeight;
late bool firstTime = true;
late ServiceRequestsProvider _serviceRequestsProvider;
late PreventiveMaintenanceVisitsProvider _preventiveMaintenanceVisitsProvider;
late RegularVisitsProvider _regularVisitsProvider;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
@ -73,7 +73,7 @@ class _LandPageState extends State<LandPage> {
@override
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;
_width = MediaQuery.of(context).size.width;
_settingProvider = Provider.of<SettingProvider>(context);
@ -83,7 +83,7 @@ class _LandPageState extends State<LandPage> {
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_preventiveMaintenanceVisitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context);
_regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle _subtitle = AppLocalization.of(context)!.subtitle!;
if (firstTime) {
if (path != null) {
Navigator.of(context).pushNamed("/" + path.split("/").first, arguments: path.split("/").last);
@ -153,7 +153,7 @@ class _LandPageState extends State<LandPage> {
mainAxisSpacing: 12,
childAspectRatio: 1,
children: [
if (_userProvider.user.type == UsersTypes.normal_user)
if (UserApiClient().user!.roles == UsersTypes.normal_user.name)
LandPageItem(
text: _subtitle.newServiceRequest,
icon: FontAwesomeIcons.tools,
@ -184,7 +184,7 @@ class _LandPageState extends State<LandPage> {
// Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id);
// },
// ),
if (_userProvider.user.type != UsersTypes.engineer)
if (UserApiClient().user?.roles != UsersTypes.engineer.name)
LandPageItem(
text: "Request Gas Refill",
icon: FontAwesomeIcons.truckFast,
@ -250,7 +250,7 @@ class _LandPageState extends State<LandPage> {
buttonSize: 42,
backgroundColor: AColors.white,
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),
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,
Text(
_userProvider.user.userName,
style: Theme.of(context).textTheme.headline6.copyWith(
UserApiClient().user?.userName ?? "",
style: Theme.of(context).textTheme.headline6?.copyWith(
fontWeight: FontWeight.w600,
),
textScaleFactor: AppStyle.getScaleFactor(context),
@ -307,11 +311,11 @@ class _LandPageState extends State<LandPage> {
focusColor: AColors.grey3A,
groupValue: _settingProvider.language,
onChanged: (value) {
_settingProvider.setLanguage(value);
_settingProvider.setLanguage(value!);
}),
Text(
"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),
),
Radio(
@ -320,11 +324,11 @@ class _LandPageState extends State<LandPage> {
focusColor: AColors.grey3A,
groupValue: _settingProvider.language,
onChanged: (value) {
_settingProvider.setLanguage(value);
_settingProvider.setLanguage(value!);
}),
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),
),
],
@ -381,7 +385,7 @@ class _LandPageState extends State<LandPage> {
children: [
Text(
"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),
),
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 '../../../../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 {
final List<AppNotification> notifications;
final bool nextPage;
final Future<void> Function() onLazyLoad;
final List<AppNotification>? notifications;
final bool? nextPage;
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
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(notifications.length == 0){
return NoItemFound(message: _subtitle.notificationsNotFound,);
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
if ((notifications?.isEmpty ?? false)) {
return NoItemFound(
message: _subtitle?.notificationsNotFound ?? "",
);
}
return LazyLoading(
nextPage: nextPage,
onLazyLoad: onLazyLoad,
nextPage: nextPage ?? false,
onLazyLoad: onLazyLoad ?? () async {},
onLoadingEnd: () {},
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: notifications.length,
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 8),
itemBuilder: (context,itemIndex){
physics: BouncingScrollPhysics(),
itemCount: notifications?.length,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
itemBuilder: (context, itemIndex) {
return NotificationItem(
notification: notifications[itemIndex],
onPressed: (notification){
Navigator.of(context).pushNamed(
FutureRequestServiceDetails.id,
arguments: notification.requestId
);
notification: notifications![itemIndex],
onPressed: (notification) {
Navigator.of(context).pushNamed(FutureRequestServiceDetails.id, arguments: notification.requestId);
},
);
}
),
}),
);
}
}

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

Loading…
Cancel
Save