Merge branch 'zaid_development_new' into 'main_latest_merged'

version 0.7.4 - update pentry

See merge request haroon6138/cloudsolutions-atoms!27
merge-requests/27/merge
zaid daoud 3 years ago
commit 54bc8436c0

@ -188,5 +188,7 @@
"alert": "تنبيه", "alert": "تنبيه",
"duplicateAlert": "تنبيه التكرار", "duplicateAlert": "تنبيه التكرار",
"duplicateAlertMessage": "هل أنت متأكد أنك تريد تكرار الطلب؟", "duplicateAlertMessage": "هل أنت متأكد أنك تريد تكرار الطلب؟",
"duplicateRequest": "تكرار الطلب" "duplicateRequest": "تكرار الطلب",
"comment" : "تعليق",
"updateServiceRequest" : "تعديل طلب الخدمة"
} }

@ -188,5 +188,7 @@
"alert": "Alert", "alert": "Alert",
"duplicateAlert": "Duplicate Alert", "duplicateAlert": "Duplicate Alert",
"duplicateAlertMessage": "Are you sure you want to duplicate request?", "duplicateAlertMessage": "Are you sure you want to duplicate request?",
"duplicateRequest": "Duplicate Request" "duplicateRequest": "Duplicate Request",
"comment" : "Comment",
"updateServiceRequest" : "Update Service Request"
} }

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

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

@ -14,7 +14,7 @@ class URLs {
static String getFileUrl(String file) => file == null || file.isEmpty ? null : "$_host/attachment/$file"; static String getFileUrl(String file) => file == null || file.isEmpty ? null : "$_host/attachment/$file";
// API Routes // API Routes
static get login => "$_baseUrl/MobileAuth/Login"; // post static get login => "$_baseUrl/MobileAuth/LoginIntegration"; // post
static get register => "$_baseUrl/handle/create/user"; // post static get register => "$_baseUrl/handle/create/user"; // post
static get updateProfile => "$_baseUrl/update/user/profile"; // post static get updateProfile => "$_baseUrl/update/user/profile"; // post
static get getHospitals => "$_baseUrl/Customer/GetCustomers"; // get static get getHospitals => "$_baseUrl/Customer/GetCustomers"; // get
@ -23,7 +23,10 @@ class URLs {
static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2
// 08051 // 08051
static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // get static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // get
static get getServiceRequestById => "$_baseUrl/CallRequest/GetCallRequestById"; // get
static get getServiceRequestThrough => "$_baseUrl/Lookups/GetLookup?lookupEnum=603"; // get static get getServiceRequestThrough => "$_baseUrl/Lookups/GetLookup?lookupEnum=603"; // get
static get getServiceLoanAvailability => "$_baseUrl/Lookups/GetLookup?lookupEnum=4"; // get
static get getServiceFirstAction => "$_baseUrl/Lookups/GetLookup?lookupEnum=700"; // get
static get getServiceRequestTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=604"; // get static get getServiceRequestTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=604"; // get
static get getServiceRequestStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=503"; static get getServiceRequestStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=503";

@ -6,7 +6,6 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/issue.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_report.dart';
import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/service_request/service_request_search.dart'; import 'package:test_sa/models/service_request/service_request_search.dart';
@ -133,17 +132,42 @@ class ServiceRequestsProvider extends ChangeNotifier {
@required ServiceRequest serviceRequest, @required ServiceRequest serviceRequest,
}) async { }) async {
var body = { var body = {
"callCreatedBy": {"id": user.id, "name": user.userName}, "id": 0,
"calNo": "",
"callCreatedBy": {"id": user.id, "name": user.userName ?? ""},
"assets": serviceRequest.deviceId == null ? [] : [serviceRequest.deviceId], "assets": serviceRequest.deviceId == null ? [] : [serviceRequest.deviceId],
"requestedDate": DateTime.now().toIso8601String(), "requestedDate": DateTime.now().toIso8601String(),
"requestedTime": DateTime.now().toIso8601String(), "requestedTime": DateTime.now().toIso8601String(),
"client": user.hospital?.id ?? '', "client": user.clientId,
"callComments": serviceRequest.maintenanceIssue, "callComments": serviceRequest.maintenanceIssue,
"attachmentsCallRequest": serviceRequest.devicePhotos.map((e) => {"name": e}).toList(), if (serviceRequest.devicePhotos.isNotEmpty) "attachmentsCallRequest": serviceRequest.devicePhotos.map((e) => {"name": e}).toList(),
"priority": serviceRequest.priority.toMap(), "priority": serviceRequest.priority.toMap(),
"defectType": serviceRequest.defectType.toMap(), "defectType": serviceRequest.defectType.toMap(),
"typeofRequest": serviceRequest.type.toMap(), "typeofRequest": serviceRequest.type.toMap(),
"requestedThrough": serviceRequest.type.toMap(), "requestedThrough": serviceRequest.type.toMap(),
"reviewComment": null,
if (serviceRequest.audio != null) "voiceNote": serviceRequest.audio,
"callSiteContactPerson": [
{
"id": 0,
// "employeeCode": user.email,
"name": user.userName,
"telephone": user.phoneNumber,
// "job": "",
"email": user.email,
// "land": "",
"contactUserId": user.id,
},
],
"noofFollowup": 0,
"status": null,
"callLastSituation": null,
"firstAction": null,
"loanAvailablity": null,
"comments": null,
"firstActionDate": null,
"visitDate": null,
"callReview": null,
}; };
if (serviceRequest.audio != null) { if (serviceRequest.audio != null) {
body["voiceNote"] = serviceRequest.audio; body["voiceNote"] = serviceRequest.audio;
@ -188,16 +212,50 @@ class ServiceRequestsProvider extends ChangeNotifier {
Future<int> updateDate({ Future<int> updateDate({
@required String host, @required String host,
@required User user, @required User user,
@required String newDate,
@required Lookup employee,
@required ServiceRequest request, @required ServiceRequest request,
DateTime date,
}) async { }) async {
Map<String, dynamic> serviceRequest = await getServiceRequestById(requestId: request.id) ?? "";
final List callSiteContacts = (serviceRequest['callSiteContactPerson'] as List);
final Map<String, dynamic> callSiteContactPerson = callSiteContacts.isEmpty ? {} : callSiteContacts[0];
print(callSiteContactPerson);
Response response; Response response;
var body = { var body = {
"callCreatedBy": {"id": user.id, "name": user.userName}, "id": request.id,
"callNo": serviceRequest['callNo'],
"callCreatedBy": serviceRequest['callCreatedBy'],
"requestedDate": date?.toIso8601String() ?? "",
"requestedTime": date?.toIso8601String() ?? "",
"priority": request.priority?.toMap(),
"defectType": request.defectType?.toMap(),
"typeofRequest": request.type?.toMap(),
"requestedThrough": request.requestedThrough?.toMap(),
"voiceNote": request.audio,
"assets": request.deviceId == null ? [] : [request.deviceId], "assets": request.deviceId == null ? [] : [request.deviceId],
"requestedDate": newDate, "attachmentsCallRequest": request.devicePhotos?.map((e) => {"name": e})?.toList(),
"requestedTime": newDate, "callSiteContactPerson": [
{
"id": callSiteContactPerson['id'] ?? 0,
"employeeCode": callSiteContactPerson['employeeCode'],
"name": callSiteContactPerson['name'] ?? user.userName,
"telephone": callSiteContactPerson['telephone'] ?? user.phoneNumber,
"job": callSiteContactPerson['job'],
"email": callSiteContactPerson['email'] ?? user.email,
"land": callSiteContactPerson['land'],
"contactUserId": user.id,
},
],
"callComments": request.maintenanceIssue,
"noofFollowup": 0,
// "status": null,
"callLastSituation": null,
"firstAction": request.firstAction?.toMap(),
"loanAvailablity": request.loanAvailability?.toMap(),
"comments": request.comment,
"firstActionDate": serviceRequest['firstActionDate'],
"visitDate": date?.toIso8601String() ?? "",
"callReview": null,
"reviewComment": null,
}; };
try { try {
response = await ApiManager.instance.put( response = await ApiManager.instance.put(
@ -206,7 +264,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
); );
stateCode = response.statusCode; stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
request.engineerName = employee.name; // request.engineerName = employee.name;
notifyListeners(); notifyListeners();
} }
return response.statusCode; return response.statusCode;
@ -363,4 +421,29 @@ class ServiceRequestsProvider extends ChangeNotifier {
throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle)); throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle));
} }
} }
Future<Map<String, dynamic>> getServiceRequestById({@required String requestId}) async {
Response response;
try {
response = await ApiManager.instance.get(
URLs.getServiceRequestById + "?callRequestId=$requestId",
);
} catch (error) {
print(error);
return {};
}
// 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 {
"callNo": json.decode(response.body)["data"]["callNo"],
"callCreatedBy": json.decode(response.body)["data"]["callCreatedBy"],
"callSiteContactPerson": json.decode(response.body)["data"]["callSiteContactPerson"],
"firstActionDate": json.decode(response.body)["data"]["firstActionDate"],
};
} else {
return {};
}
}
} }

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

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

@ -98,7 +98,8 @@ class UserProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
_user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
_user.hospital = user.hospital; _user.clientId = user.clientId;
_user.clientName = user.clientName;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} }
@ -123,8 +124,8 @@ class UserProvider extends ChangeNotifier {
Map<String, dynamic> jsonObject = {}; Map<String, dynamic> jsonObject = {};
jsonObject["uid"] = user.id; jsonObject["uid"] = user.id;
jsonObject["token"] = user.token; jsonObject["token"] = user.token;
if (user.department.id != _user.department.id) jsonObject["department"] = user.department.id; if (user.departmentId != _user.departmentId) jsonObject["department"] = user.departmentId;
if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp; // if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp;
if (user.phoneNumber != _user.phoneNumber) jsonObject["phone"] = user.phoneNumber; if (user.phoneNumber != _user.phoneNumber) jsonObject["phone"] = user.phoneNumber;
try { try {
response = response = await ApiManager.instance.post( response = response = await ApiManager.instance.post(
@ -143,8 +144,10 @@ class UserProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
_user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
_user.hospital = user.hospital; _user.clientId = user.clientId;
_user.department = user.department; _user.clientName = user.clientName;
_user.departmentName = user.departmentName;
_user.departmentId = user.departmentId;
notifyListeners(); notifyListeners();
return response.statusCode; return response.statusCode;
} }

@ -1,6 +1,3 @@
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
import 'dart:io'; import 'dart:io';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
@ -26,6 +23,8 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry
import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_visit_status_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_visit_status_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_defect_types_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_defect_types_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_status_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_status_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_through_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_through_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_type_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_type_provider.dart';
@ -65,17 +64,16 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
if (Platform.isIOS) { if (Platform.isIOS) {
await Firebase.initializeApp( await Firebase.initializeApp(
options: const FirebaseOptions(apiKey: "AIzaSyACQkSleNwU1jzEKR5ho1uSfZERokwwAbc", appId: "1:973582662416:ios:bc4a8061444c6a08fbc395", messagingSenderId: "973582662416", projectId: "atoms-fb912"), options:
const FirebaseOptions(apiKey: "AIzaSyACQkSleNwU1jzEKR5ho1uSfZERokwwAbc", appId: "1:973582662416:ios:bc4a8061444c6a08fbc395", messagingSenderId: "973582662416", projectId: "atoms-fb912"),
); );
} else { } else {
await Firebase.initializeApp(); await Firebase.initializeApp();
} }
runApp( runApp(ChangeNotifierProvider(
ChangeNotifierProvider( create: (_) => SettingProvider(),
create: (_) => SettingProvider(), child: MyApp(),
child: MyApp(), ));
)
);
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
@ -115,6 +113,8 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => ServiceRequestedThroughProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestedThroughProvider()),
ChangeNotifierProvider(create: (_) => ServiceRequestStatusProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestStatusProvider()),
ChangeNotifierProvider(create: (_) => EngineersProvider()), ChangeNotifierProvider(create: (_) => EngineersProvider()),
ChangeNotifierProvider(create: (_) => ServiceLoanAvailabilityProvider()),
ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()),
], ],
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
@ -127,18 +127,12 @@ class MyApp extends StatelessWidget {
title: 'ATOMS', title: 'ATOMS',
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: ThemeData( theme: ThemeData(
fontFamily: "Poppins", fontFamily: "Poppins",
//canvasColor: AColors.primaryColor, //canvasColor: AColors.primaryColor,
scaffoldBackgroundColor: AColors.scaffoldBackgroundColor, scaffoldBackgroundColor: AColors.scaffoldBackgroundColor,
primaryColor: AColors.primaryColor, primaryColor: AColors.primaryColor,
indicatorColor: AColors.primaryColor, indicatorColor: AColors.primaryColor,
colorScheme: const ColorScheme.light( colorScheme: const ColorScheme.light(primary: AColors.primaryColor, onPrimary: Colors.white, secondary: AColors.secondaryColor, onSecondary: Colors.white)),
primary: AColors.primaryColor,
onPrimary: Colors.white,
secondary: AColors.secondaryColor,
onSecondary: Colors.white
)
),
localizationsDelegates: const [ localizationsDelegates: const [
// ... app-specific localization delegate[s] here // ... app-specific localization delegate[s] here
AppLocalization.delegate, AppLocalization.delegate,
@ -153,31 +147,28 @@ class MyApp extends StatelessWidget {
locale: Locale(_settingProvider.language ?? 'en'), locale: Locale(_settingProvider.language ?? 'en'),
initialRoute: SplashScreen.id, initialRoute: SplashScreen.id,
routes: { routes: {
SplashScreen.id: (_)=> const SplashScreen(), SplashScreen.id: (_) => const SplashScreen(),
LandPage.id: (_)=> const LandPage(), LandPage.id: (_) => const LandPage(),
Login.id: (_)=> Login(), Login.id: (_) => Login(),
Register.id: (_)=> Register(), Register.id: (_) => Register(),
ProfilePage.id: (_)=> ProfilePage(), ProfilePage.id: (_) => ProfilePage(),
ReportIssuesPage.id: (_)=> const ReportIssuesPage(), ReportIssuesPage.id: (_) => const ReportIssuesPage(),
RequestGasRefill.id: (_)=> const RequestGasRefill(), RequestGasRefill.id: (_) => const RequestGasRefill(),
CreateRequestPage.id: (_)=> CreateRequestPage(), CreateRequestPage.id: (_) => const CreateRequestPage(),
SingleHospitalPicker.id: (_)=> SingleHospitalPicker(), SingleHospitalPicker.id: (_) => SingleHospitalPicker(),
SingleDevicePicker.id: (_)=> SingleDevicePicker(), SingleDevicePicker.id: (_) => SingleDevicePicker(),
SingleDepartmentPicker.id: (_)=> SingleDepartmentPicker(), SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(),
ServiceRequestsPage.id: (_)=> ServiceRequestsPage(), ServiceRequestsPage.id: (_) => ServiceRequestsPage(),
NotificationsPage.id: (_)=> NotificationsPage(), NotificationsPage.id: (_) => NotificationsPage(),
FutureRequestServiceDetails.id: (_)=> FutureRequestServiceDetails(), FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(),
PreventiveMaintenanceVisitsPage.id: (_)=> PreventiveMaintenanceVisitsPage(), PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
RegularVisitsPage.id: (_)=> RegularVisitsPage(), RegularVisitsPage.id: (_) => RegularVisitsPage(),
TrackGasRefillPage.id: (_)=> const TrackGasRefillPage(), TrackGasRefillPage.id: (_) => const TrackGasRefillPage(),
RequestDeviceTransfer.id: (_)=> const RequestDeviceTransfer(), RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(),
TrackDeviceTransferPage.id: (_)=> const TrackDeviceTransferPage(), TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(),
}, },
), ),
), ),
); );
} }
} }

@ -2,7 +2,7 @@ import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
class ServiceRequest{ class ServiceRequest {
String id; String id;
String requestCode; String requestCode;
String deviceSerialNumber; String deviceSerialNumber;
@ -19,6 +19,7 @@ class ServiceRequest{
String audio; String audio;
int statusValue; int statusValue;
String statusLabel; String statusLabel;
String comment;
bool viewReport; bool viewReport;
String engineerMobile; String engineerMobile;
@ -34,6 +35,8 @@ class ServiceRequest{
Lookup defectType; Lookup defectType;
Lookup type; Lookup type;
Lookup requestedThrough; Lookup requestedThrough;
Lookup firstAction;
Lookup loanAvailability;
Device device; Device device;
ServiceRequest({ ServiceRequest({
@ -53,7 +56,6 @@ class ServiceRequest{
this.deviceId, this.deviceId,
this.audio, this.audio,
this.engineerName, this.engineerName,
this.viewReport = false, this.viewReport = false,
this.deviceModel, this.deviceModel,
this.engineerMobile, this.engineerMobile,
@ -69,11 +71,14 @@ class ServiceRequest{
this.type, this.type,
this.requestedThrough, this.requestedThrough,
this.device, this.device,
this.comment,
this.loanAvailability,
this.firstAction,
}); });
factory ServiceRequest.fromJson(Map<String,dynamic> parsedJson){ factory ServiceRequest.fromJson(Map<String, dynamic> parsedJson) {
List<String> images = []; List<String> images = [];
if(parsedJson["attachmentsCallRequest"] is List){ if (parsedJson["attachmentsCallRequest"] is List) {
List list = parsedJson["attachmentsCallRequest"]; List list = parsedJson["attachmentsCallRequest"];
images = list.map((e) => URLs.getFileUrl(e["attachmentsCallRequest"])).toList(); images = list.map((e) => URLs.getFileUrl(e["attachmentsCallRequest"])).toList();
} }
@ -85,35 +90,33 @@ class ServiceRequest{
deviceId: parsedJson["asset"]["id"], deviceId: parsedJson["asset"]["id"],
audio: URLs.getFileUrl(parsedJson["voiceNote"] ?? ""), audio: URLs.getFileUrl(parsedJson["voiceNote"] ?? ""),
deviceArName: parsedJson["asset"]["modelDefinition"]["assetName"] ?? "", deviceArName: parsedJson["asset"]["modelDefinition"]["assetName"] ?? "",
deviceEnName: parsedJson["asset"]["modelDefinition"]["assetName"] ?? "", deviceEnName: parsedJson["asset"]["modelDefinition"]["assetName"] ?? "",
devicePhotos: images, devicePhotos: images,
deviceSerialNumber: parsedJson["asset"]["assetSerialNo"], deviceSerialNumber: parsedJson["asset"]["assetSerialNo"],
date: DateTime.tryParse(parsedJson["requestedDate"] ?? "").toString().split(" ").first, date: DateTime.tryParse(parsedJson["requestedDate"] ?? "").toString().split(" ").first,
maintenanceIssue: parsedJson["comments"], maintenanceIssue: parsedJson["comments"],
statusLabel: parsedJson["status"] == null ? null : statusLabel: parsedJson["status"] == null ? null : parsedJson["status"]["name"],
parsedJson["status"]["name"], statusValue: parsedJson["status"] == null ? null : parsedJson["status"]["value"],
statusValue: parsedJson["status"] == null ? null : departmentName: parsedJson["asset"]["department"] != null ? parsedJson["asset"]["department"]["name"] : "",
parsedJson["status"]["value"], engineerName: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["name"],
departmentName: parsedJson["asset"]["department"] != null ?
parsedJson["asset"]["department"]["name"] : "",
engineerName: parsedJson["assignedEmployee"] == null ? null :
parsedJson["assignedEmployee"]["name"],
hospitalId: parsedJson["asset"]["site"]["id"], hospitalId: parsedJson["asset"]["site"]["id"],
reportID: parsedJson["workOrder"] != null ? reportID: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workOrderId"] : null,
parsedJson["workOrder"]["workOrderId"] : null,
viewReport: parsedJson["workOrder"] != null, viewReport: parsedJson["workOrder"] != null,
deviceModel: parsedJson["asset"]["modelDefinition"]["modelName"], deviceModel: parsedJson["asset"]["modelDefinition"]["modelName"],
engineerMobile: parsedJson["assignedEmployee"] == null ? null : engineerMobile: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["phone"],
parsedJson["assignedEmployee"]["phone"], faultDescription: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["faultDescription"] : null,
faultDescription: parsedJson["workOrder"] != null ? jobSheetNumber: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["jobSheetNumber"] : null,
parsedJson["workOrder"]["faultDescription"] : null,
jobSheetNumber: parsedJson["workOrder"] != null ?
parsedJson["workOrder"]["jobSheetNumber"] :null,
visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? "").toString().split(" ").first, visitDate: DateTime.tryParse(parsedJson["visitDate"] ?? "").toString().split(" ").first,
nextVisitDate: DateTime.tryParse(parsedJson["nextVisitDate"] ?? ""), nextVisitDate: DateTime.tryParse(parsedJson["nextVisitDate"] ?? ""),
workPerformed: parsedJson["workOrder"] != null ? workPerformed: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workPerformed"] : null,
parsedJson["workOrder"]["workPerformed"] : null, device: Device.fromJson(parsedJson["asset"]),
device: Device.fromJson(parsedJson["asset"]) comment: parsedJson["reviewComment"],
type: Lookup.fromJson(parsedJson['typeofRequest']),
defectType: Lookup.fromJson(parsedJson['defectType']),
loanAvailability: Lookup.fromJson(parsedJson['loanAvailability']),
firstAction: Lookup.fromJson(parsedJson['firstAction']),
requestedThrough: Lookup.fromJson(parsedJson['requestedThrough']),
priority: Lookup.fromJson(parsedJson['priority']),
); );
} }
} }

@ -1,6 +1,6 @@
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
class Subtitle{ class Subtitle {
// http requests status messages // http requests status messages
String currentlyServiceNotAvailable; String currentlyServiceNotAvailable;
String waitUntilYourRequestComplete; String waitUntilYourRequestComplete;
@ -215,8 +215,10 @@ class Subtitle{
String duplicateAlert; String duplicateAlert;
String duplicateAlertMessage; String duplicateAlertMessage;
String alert; String alert;
String comment;
String updateServiceRequest;
void setIssues(List<String> issues){ void setIssues(List<String> issues) {
issues.clear(); issues.clear();
issues.add(reason1); issues.add(reason1);
issues.add(reason2); issues.add(reason2);
@ -226,6 +228,8 @@ class Subtitle{
} }
Subtitle({ Subtitle({
@required this.updateServiceRequest,
@required this.comment,
@required this.currentlyServiceNotAvailable, @required this.currentlyServiceNotAvailable,
@required this.waitUntilYourRequestComplete, @required this.waitUntilYourRequestComplete,
@required this.requestCompleteSuccessfully, @required this.requestCompleteSuccessfully,
@ -278,7 +282,6 @@ class Subtitle{
@required this.titleValidateMessage, @required this.titleValidateMessage,
@required this.to, @required this.to,
@required this.urlNotFound, @required this.urlNotFound,
@required this.nameExist, @required this.nameExist,
@required this.unitRequired, @required this.unitRequired,
@required this.unite, @required this.unite,
@ -384,7 +387,6 @@ class Subtitle{
@required this.pickImage, @required this.pickImage,
@required this.requiredImage, @required this.requiredImage,
@required this.activationAlert, @required this.activationAlert,
@required this.callId, @required this.callId,
@required this.requiredWord, @required this.requiredWord,
@required this.quantity, @required this.quantity,
@ -409,8 +411,10 @@ class Subtitle{
@required this.duplicateRequest, @required this.duplicateRequest,
}); });
factory Subtitle.fromJson(Map<String,dynamic> parsedJson){ factory Subtitle.fromJson(Map<String, dynamic> parsedJson) {
return Subtitle( return Subtitle(
updateServiceRequest: parsedJson["updateServiceRequest"],
comment: parsedJson["comment"],
currentlyServiceNotAvailable: parsedJson["server_error_message"], currentlyServiceNotAvailable: parsedJson["server_error_message"],
failedToCompleteRequest: parsedJson["failed_request_message"], failedToCompleteRequest: parsedJson["failed_request_message"],
requestCompleteSuccessfully: parsedJson["successful_request_message"], requestCompleteSuccessfully: parsedJson["successful_request_message"],
@ -423,7 +427,6 @@ class Subtitle{
signOut: parsedJson["sign_out"], signOut: parsedJson["sign_out"],
signOutAlert: parsedJson["logout_alert"], signOutAlert: parsedJson["logout_alert"],
language: parsedJson["language"], language: parsedJson["language"],
name: parsedJson["name"], name: parsedJson["name"],
email: parsedJson["email"], email: parsedJson["email"],
phoneNumber: parsedJson["phone_number"], phoneNumber: parsedJson["phone_number"],
@ -437,7 +440,6 @@ class Subtitle{
passwordValidateMessage: parsedJson["password_validate_message"], passwordValidateMessage: parsedJson["password_validate_message"],
confirmPasswordValidateMessage: parsedJson["confirm_password_validate_message"], confirmPasswordValidateMessage: parsedJson["confirm_password_validate_message"],
phoneNumberValidateMessage: parsedJson["phone_number_validate_message"], phoneNumberValidateMessage: parsedJson["phone_number_validate_message"],
forgetPasswordWithMark: parsedJson["forget_password_with_mark"], forgetPasswordWithMark: parsedJson["forget_password_with_mark"],
showPassword: parsedJson["show_password"], showPassword: parsedJson["show_password"],
wrongEmailOrPassword: parsedJson["wrong_email_or_password"], wrongEmailOrPassword: parsedJson["wrong_email_or_password"],
@ -447,7 +449,6 @@ class Subtitle{
back: parsedJson["back"], back: parsedJson["back"],
search: parsedJson["search"], search: parsedJson["search"],
searchByName: parsedJson["search_by_name"], searchByName: parsedJson["search_by_name"],
address: parsedJson["address"], address: parsedJson["address"],
addressNotFound: parsedJson["address_not_found"], addressNotFound: parsedJson["address_not_found"],
addressValidateMessage: parsedJson["address_validate_message"], addressValidateMessage: parsedJson["address_validate_message"],
@ -466,7 +467,6 @@ class Subtitle{
titleNotFound: parsedJson["title_not_found"], titleNotFound: parsedJson["title_not_found"],
titleValidateMessage: parsedJson["title_validate_message"], titleValidateMessage: parsedJson["title_validate_message"],
urlNotFound: parsedJson["url_not_found"], urlNotFound: parsedJson["url_not_found"],
date: parsedJson["date"], date: parsedJson["date"],
status: parsedJson["status"], status: parsedJson["status"],
code: parsedJson["code"], code: parsedJson["code"],
@ -542,7 +542,6 @@ class Subtitle{
visitDate: parsedJson["visitDate"], visitDate: parsedJson["visitDate"],
whatsApp: parsedJson["whatsApp"], whatsApp: parsedJson["whatsApp"],
workPerformed: parsedJson["workPerformed"], workPerformed: parsedJson["workPerformed"],
actualDate: parsedJson["actualDate"], actualDate: parsedJson["actualDate"],
done: parsedJson["done"], done: parsedJson["done"],
expectDate: parsedJson["expectDate"], expectDate: parsedJson["expectDate"],
@ -573,7 +572,6 @@ class Subtitle{
requiredImage: parsedJson["requiredImage"], requiredImage: parsedJson["requiredImage"],
taskStatus: parsedJson["taskStatus"], taskStatus: parsedJson["taskStatus"],
activationAlert: parsedJson["activationAlert"], activationAlert: parsedJson["activationAlert"],
attachImage: parsedJson["attachImage"], attachImage: parsedJson["attachImage"],
callLastSituation: parsedJson["callLastSituation"], callLastSituation: parsedJson["callLastSituation"],
customer: parsedJson["customer"], customer: parsedJson["customer"],
@ -592,12 +590,10 @@ class Subtitle{
requiredWord: parsedJson["requiredWord"], requiredWord: parsedJson["requiredWord"],
serviceType: parsedJson["serviceType"], serviceType: parsedJson["serviceType"],
workPreformed: parsedJson["workPreformed"], workPreformed: parsedJson["workPreformed"],
alert: parsedJson["alert"], alert: parsedJson["alert"],
duplicateAlert: parsedJson["duplicateAlert"], duplicateAlert: parsedJson["duplicateAlert"],
duplicateAlertMessage: parsedJson["duplicateAlertMessage"], duplicateAlertMessage: parsedJson["duplicateAlertMessage"],
duplicateRequest: parsedJson["duplicateRequest"], duplicateRequest: parsedJson["duplicateRequest"],
); );
} }
}
}

@ -1,108 +1,219 @@
import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; 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/enums/user_types.dart';
import 'package:test_sa/models/hospital.dart';
class User { class User {
int clientId;
String clientName;
int departmentId;
String departmentName;
String message;
String username;
String userID;
String email;
String password;
String token;
dynamic roles;
List<UserRoles> userRoles;
String tokenlife;
bool isAuthenticated;
bool hasError;
String profilePhotoName;
String id; String id;
String userName; String userName;
String password; String normalizedUserName;
String email; String normalizedEmail;
Hospital hospital; bool emailConfirmed;
Department department; dynamic passwordHash;
UsersTypes type; String securityStamp;
String concurrencyStamp;
String phoneNumber; String phoneNumber;
String whatsApp; bool phoneNumberConfirmed;
String token; bool twoFactorEnabled;
bool isActive; dynamic lockoutEnd;
DateTime tokenLife; bool lockoutEnabled;
int accessFailedCount;
User( User({
{this.id, this.clientId,
this.userName = "", this.clientName,
this.email = "", this.departmentId,
this.password = "", this.departmentName,
this.phoneNumber = "", this.message,
this.hospital, this.username,
this.department, this.userID,
this.type, this.email,
this.whatsApp, this.password,
this.token, this.token,
this.tokenLife, this.roles,
this.isActive = false}); 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,
});
Future<Map<String, dynamic>> toLoginJson() async { Future<Map<String, dynamic>> toLoginJson() async {
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
return { return {
"username": userName, "username": userName,
"password": password, "password": password,
"firebase_token": FirebaseNotificationManger?.token ?? "", "fireBaseToken": FirebaseNotificationManger?.token ?? "",
}; };
} }
UsersTypes get type {
switch (userRoles.first.name) {
case "Engineer":
return UsersTypes.engineer;
case "Hospital":
return UsersTypes.normal_user;
default:
return null;
}
}
Map<String, dynamic> toUpdateProfileJson() { Map<String, dynamic> toUpdateProfileJson() {
Map<String, dynamic> jsonObject = {}; Map<String, dynamic> jsonObject = {};
if (department?.id != null) jsonObject["department"] = department.id; // if (departmentId != null) jsonObject["department"] = departmentId;
if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp; // if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp;
if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber; // if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber;
return jsonObject; return jsonObject;
} }
Future<Map<String, dynamic>> toRegisterJson() async { Future<Map<String, dynamic>> toRegisterJson() async {
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); // if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
return { return {
"username": userName, // "username": userName,
"email": email, // "email": email,
"whatsapp": whatsApp, // "whatsapp": whatsApp,
"client": hospital.id, // "client": hospital.id,
"department": department?.id, // "department": department?.id,
"phone": phoneNumber, // "phone": phoneNumber,
"pass": password, // "pass": password,
"firebase_token": FirebaseNotificationManger?.token ?? "", // "firebase_token": FirebaseNotificationManger?.token ?? "",
}; };
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { final map = <String, dynamic>{};
"userID": id, map['client_id'] = clientId;
"username": userName, map['client_name'] = clientName;
"email": email, map['department_id'] = departmentId;
"token": token, map['department_name'] = departmentName;
"phoneNumber": phoneNumber, map['message'] = message;
"whatsapp": whatsApp, map['username'] = username;
"client_id": hospital?.id, map['userID'] = userID;
"client_name": hospital?.name, map['email'] = email;
"department_id": department?.id, map['password'] = password;
"department_name": department?.name, map['token'] = token;
//"password":password, map['roles'] = roles;
"tokenlife": tokenLife.toIso8601String(), if (userRoles != null) {
"active": isActive, map['userRoles'] = userRoles.map((v) => v.toJson()).toList();
"userRoles": type == UsersTypes.engineer ? "value: R-6" : "value: R-5", }
// "token":token, pass is token map['tokenlife'] = tokenlife;
}; map['isAuthenticated'] = isAuthenticated;
map['hasError'] = hasError;
map['profilePhotoName'] = profilePhotoName;
map['id'] = id;
map['userName'] = userName;
map['normalizedUserName'] = normalizedUserName;
map['normalizedEmail'] = normalizedEmail;
map['emailConfirmed'] = emailConfirmed;
map['passwordHash'] = passwordHash;
map['securityStamp'] = securityStamp;
map['concurrencyStamp'] = concurrencyStamp;
map['phoneNumber'] = phoneNumber;
map['phoneNumberConfirmed'] = phoneNumberConfirmed;
map['twoFactorEnabled'] = twoFactorEnabled;
map['lockoutEnd'] = lockoutEnd;
map['lockoutEnabled'] = lockoutEnabled;
map['accessFailedCount'] = accessFailedCount;
return map;
} }
factory User.fromJson(Map<String, dynamic> parsedJson) { User.fromJson(dynamic json) {
UsersTypes type; clientId = json['client_id'];
if (parsedJson["userRoles"].toString().contains("value: R-4") || parsedJson["userRoles"].toString().contains("value: R-5") || parsedJson["userRoles"].toString().contains("value: R-7")) { clientName = json['client_name'];
type = UsersTypes.normal_user; departmentId = json['department_id'];
} else { departmentName = json['department_name'];
type = UsersTypes.engineer; 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 = [];
json['userRoles'].forEach((v) {
userRoles.add(UserRoles.fromJson(v));
});
} }
return User( tokenlife = json['tokenlife'];
id: parsedJson["userID"], isAuthenticated = json['isAuthenticated'];
userName: parsedJson["username"], hasError = json['hasError'];
email: parsedJson["email"], profilePhotoName = json['profilePhotoName'];
hospital: Hospital(id: parsedJson["client_id"], name: parsedJson["client_name"]), id = json['id'];
department: Department( userName = json['userName'];
id: parsedJson["department_id"], normalizedUserName = json['normalizedUserName'];
name: parsedJson["department_name"], normalizedEmail = json['normalizedEmail'];
), emailConfirmed = json['emailConfirmed'];
phoneNumber: parsedJson["phoneNumber"], passwordHash = json['passwordHash'];
whatsApp: parsedJson["phoneNumber"], securityStamp = json['securityStamp'];
token: parsedJson["token"], concurrencyStamp = json['concurrencyStamp'];
isActive: parsedJson["isAuthenticated"], phoneNumber = json['phoneNumber'];
tokenLife: DateTime.tryParse(parsedJson["tokenlife"] ?? ""), phoneNumberConfirmed = json['phoneNumberConfirmed'];
type: type); twoFactorEnabled = json['twoFactorEnabled'];
lockoutEnd = json['lockoutEnd'];
lockoutEnabled = json['lockoutEnabled'];
accessFailedCount = json['accessFailedCount'];
}
}
class UserRoles {
UserRoles({
this.id,
this.name,
this.value,
});
UserRoles.fromJson(dynamic json) {
id = json['id'];
name = json['name'];
value = json['value'];
}
String id;
String name;
String value;
UserRoles copyWith({
String id,
String name,
String value,
}) =>
UserRoles(
id: id ?? this.id,
name: name ?? this.name,
value: value ?? this.value,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
map['value'] = value;
return map;
} }
} }

@ -35,7 +35,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
SettingProvider _settingProvider; SettingProvider _settingProvider;
DeviceTransferProvider _deviceTransferProvider; DeviceTransferProvider _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController(); final TextEditingController _requestedQuantityController = TextEditingController();
final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo(),sender: DeviceTransferInfo()); final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo(), sender: DeviceTransferInfo());
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@ -59,7 +59,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_formModel.sender?.client?.id = _userProvider.user?.hospital?.id; _formModel.sender?.client?.id = _userProvider.user?.clientId;
int status = await _deviceTransferProvider.createRequest( int status = await _deviceTransferProvider.createRequest(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,

@ -113,7 +113,7 @@ class _LoginState extends State<Login> {
user: _user, user: _user,
host: _settingProvider.host, host: _settingProvider.host,
); );
if (status >= 200 && status < 300 && _userProvider.user?.userName != null) { if (status >= 200 && status < 300) {
_settingProvider.setUser(_userProvider.user); _settingProvider.setUser(_userProvider.user);
// if (_userProvider.user.isActive) // if (_userProvider.user.isActive)
Navigator.of(context).pushNamed(LandPage.id); Navigator.of(context).pushNamed(LandPage.id);

@ -1,12 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart'; import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
@ -123,17 +124,19 @@ class _RegisterState extends State<Register> {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
HospitalButton( HospitalButton(
hospital: _user.hospital, hospital: Hospital(id: _user.clientId, name: _user.clientName),
onHospitalPick: (hospital) { onHospitalPick: (hospital) {
_user.hospital = hospital; _user.clientId = hospital.id;
_user.clientName = hospital.name;
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
DepartmentButton( DepartmentButton(
department: _user.department, department: Department(id: _user.departmentId, name: _user.departmentName),
onDepartmentPick: (department) { onDepartmentPick: (department) {
_user.department = department; _user.departmentId = department.id;
_user.departmentName = department.name;
setState(() {}); setState(() {});
}, },
), ),
@ -150,31 +153,31 @@ class _RegisterState extends State<Register> {
}, },
), ),
SizedBox(height: 8), SizedBox(height: 8),
ATextFormField( // ATextFormField(
initialValue: _user.whatsApp, // initialValue: _user.whatsApp,
hintText: _subtitle.whatsApp, // hintText: _subtitle.whatsApp,
style: Theme.of(context).textTheme.headline6, // style: Theme.of(context).textTheme.headline6,
prefixIconData: FontAwesomeIcons.whatsapp, // prefixIconData: FontAwesomeIcons.whatsapp,
prefixIconSize: 36, // prefixIconSize: 36,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, // validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage,
textInputType: TextInputType.phone, // textInputType: TextInputType.phone,
onSaved: (value) { // onSaved: (value) {
_user.whatsApp = value; // _user.whatsApp = value;
}, // },
), // ),
const SizedBox(height: 12), const SizedBox(height: 12),
AButton( AButton(
text: _subtitle.signUp, text: _subtitle.signUp,
onPressed: () async { onPressed: () async {
if (!_formKey.currentState.validate()) return; if (!_formKey.currentState.validate()) return;
_formKey.currentState.save(); _formKey.currentState.save();
if (_user.hospital == null) { if (_user.clientId == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.hospitalRequired), content: Text(_subtitle.hospitalRequired),
)); ));
return; return;
} }
if (_user.department == null) { if (_user.departmentId == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.unitRequired), content: Text(_subtitle.unitRequired),
)); ));

@ -22,12 +22,11 @@ class SplashScreen extends StatefulWidget {
} }
class _SplashScreenState extends State<SplashScreen> { class _SplashScreenState extends State<SplashScreen> {
SettingProvider _settingProvider; SettingProvider _settingProvider;
UserProvider _userProvider; UserProvider _userProvider;
_goToUserScreen(User user){ _goToUserScreen(User user) {
if(user.tokenLife != null && user.tokenLife.isAfter(DateTime.now())){ if (user.tokenlife != null && (DateTime.tryParse(user.tokenlife)?.isAfter(DateTime.now()) ?? false)) {
_userProvider.user = user; _userProvider.user = user;
// Navigator.of(context).pushNamed(Login.id); // Navigator.of(context).pushNamed(Login.id);
Navigator.of(context).pushNamed(LandPage.id); Navigator.of(context).pushNamed(LandPage.id);
@ -38,38 +37,30 @@ class _SplashScreenState extends State<SplashScreen> {
void initState() { void initState() {
Firebase.initializeApp(); Firebase.initializeApp();
NotificationManger.initialisation( NotificationManger.initialisation((notificationDetails) {
(notificationDetails) { AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload));
AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload)); if (notification.path == null || notification.path.isEmpty) return;
if(notification.path == null || notification.path.isEmpty) Navigator.pushNamed(context, notification.path, arguments: notification.requestId);
return; }, (id, title, body, payload) async {});
Navigator.pushNamed(
context,
notification.path,
arguments: notification.requestId
);
}
, (id, title, body, payload) async {
});
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context,listen: false); _settingProvider = Provider.of<SettingProvider>(context, listen: false);
_userProvider = Provider.of<UserProvider>(context,listen: false); _userProvider = Provider.of<UserProvider>(context, listen: false);
return Scaffold( return Scaffold(
backgroundColor: Colors.white, backgroundColor: Colors.white,
body: Center( body: Center(
child: SizedBox( child: SizedBox(
width: MediaQuery.of(context).size.width/1.1, width: MediaQuery.of(context).size.width / 1.1,
child: FlareActor( child: FlareActor(
"assets/rives/atoms_splash.flr", "assets/rives/atoms_splash.flr",
fit: BoxFit.contain, fit: BoxFit.contain,
animation: "splash", animation: "splash",
callback: (animation) async { callback: (animation) async {
Navigator.of(context).pushNamed(Login.id); Navigator.of(context).pushNamed(Login.id);
if(_settingProvider.isLoaded && _settingProvider.user != null){ if (_settingProvider.isLoaded && _settingProvider.user != null) {
_goToUserScreen(_settingProvider.user); _goToUserScreen(_settingProvider.user);
} }
}, },

@ -9,14 +9,14 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/pages/user/notifications/notifications_list.dart'; import 'package:test_sa/views/pages/user/notifications/notifications_list.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
class NotificationsPage extends StatefulWidget { class NotificationsPage extends StatefulWidget {
static final String id = "/notifications"; static final String id = "/notifications";
@override @override
_NotificationsPageState createState() => _NotificationsPageState(); _NotificationsPageState createState() => _NotificationsPageState();
} }
class _NotificationsPageState extends State<NotificationsPage> class _NotificationsPageState extends State<NotificationsPage> with TickerProviderStateMixin {
with TickerProviderStateMixin{
NotificationsProvider _notificationsProvider; NotificationsProvider _notificationsProvider;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
@ -36,9 +36,9 @@ class _NotificationsPageState extends State<NotificationsPage>
onRefresh: () async { onRefresh: () async {
_notificationsProvider.reset(); _notificationsProvider.reset();
await _notificationsProvider.getNotifications( await _notificationsProvider.getNotifications(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
hospitalId: _userProvider.user.hospital.id, hospitalId: _userProvider.user.clientId,
); );
}, },
child: Stack( child: Stack(
@ -46,8 +46,8 @@ class _NotificationsPageState extends State<NotificationsPage>
Column( Column(
children: [ children: [
Container( Container(
color:AColors.primaryColor, color: AColors.primaryColor,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Column( child: Column(
children: [ children: [
Row( Row(
@ -57,17 +57,15 @@ class _NotificationsPageState extends State<NotificationsPage>
child: Center( child: Center(
child: Text( child: Text(
_subtitle.notifications, _subtitle.notifications,
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
color: AColors.white,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
SizedBox(width: 48,) SizedBox(
width: 48,
)
], ],
), ),
], ],
), ),
), ),
@ -78,7 +76,7 @@ class _NotificationsPageState extends State<NotificationsPage>
await _notificationsProvider.getNotifications( await _notificationsProvider.getNotifications(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
hospitalId: _userProvider.user.hospital.id, hospitalId: _userProvider.user.clientId,
); );
}, },
notifications: _notificationsProvider.notifications, notifications: _notificationsProvider.notifications,
@ -86,7 +84,6 @@ class _NotificationsPageState extends State<NotificationsPage>
), ),
], ],
), ),
], ],
), ),
), ),

@ -1,11 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart'; import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
@ -16,6 +17,7 @@ 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/departments/department_button.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_button.dart'; import 'package:test_sa/views/widgets/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
class ProfilePage extends StatefulWidget { class ProfilePage extends StatefulWidget {
static final String id = "/user/profile"; static final String id = "/user/profile";
@override @override
@ -38,13 +40,13 @@ class _ProfilePageState extends State<ProfilePage> {
_width = MediaQuery.of(context).size.width; _width = MediaQuery.of(context).size.width;
_height = MediaQuery.of(context).size.height; _height = MediaQuery.of(context).size.height;
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(_firstTime){ if (_firstTime) {
_user = User.fromJson(_userProvider.user.toJson()); _user = User.fromJson(_userProvider.user.toJson());
_firstTime = false; _firstTime = false;
} }
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body:LoadingManager( body: LoadingManager(
isLoading: _userProvider.isLoading, isLoading: _userProvider.isLoading,
isFailedLoading: false, isFailedLoading: false,
stateCode: 200, stateCode: 200,
@ -60,23 +62,19 @@ class _ProfilePageState extends State<ProfilePage> {
Hero( Hero(
tag: "logo", tag: "logo",
child: Image( child: Image(
height: _height/4, height: _height / 4,
image: AssetImage("assets/images/logo.png"), image: AssetImage("assets/images/logo.png"),
), ),
), ),
Container( Container(
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 16), padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
margin: EdgeInsets.symmetric(horizontal: 16), margin: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(color: AColors.primaryColor, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [
color: AColors.primaryColor, BoxShadow(
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), color: AColors.grey,
boxShadow: [ offset: Offset(0, -1),
BoxShadow( )
color: AColors.grey, ]),
offset: Offset(0,-1),
)
]
),
child: Column( child: Column(
children: [ children: [
ATextFormField( ATextFormField(
@ -85,13 +83,14 @@ class _ProfilePageState extends State<ProfilePage> {
enable: false, enable: false,
prefixIconData: Icons.account_circle, prefixIconData: Icons.account_circle,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.hasValue(value) validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage,
? null : _subtitle.nameValidateMessage, onSaved: (value) {
onSaved: (value){
_user.userName = value; _user.userName = value;
}, },
), ),
SizedBox(height: 8,), SizedBox(
height: 8,
),
ATextFormField( ATextFormField(
initialValue: _user.email, initialValue: _user.email,
hintText: _subtitle.email, hintText: _subtitle.email,
@ -99,110 +98,108 @@ class _ProfilePageState extends State<ProfilePage> {
prefixIconData: Icons.email, prefixIconData: Icons.email,
textInputType: TextInputType.emailAddress, textInputType: TextInputType.emailAddress,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.isEmail(value) validator: (value) => Validator.isEmail(value) ? null : _subtitle.emailValidateMessage,
? null : _subtitle.emailValidateMessage, onSaved: (value) {
onSaved: (value){
_user.email = value; _user.email = value;
}, },
), ),
SizedBox(height: 8,), SizedBox(
height: 8,
),
AbsorbPointer( AbsorbPointer(
child: HospitalButton( child: HospitalButton(
hospital: _user.hospital, hospital: Hospital(name: _user.clientName, id: _user.clientId),
onHospitalPick: (hospital){ onHospitalPick: (hospital) {
_user.hospital = hospital; _user.clientName = hospital.name;
_user.clientId = hospital.id;
setState(() {}); setState(() {});
}, },
), ),
), ),
SizedBox(height: 8,), SizedBox(
height: 8,
),
DepartmentButton( DepartmentButton(
department: _user.department, department: Department(name: _user.departmentName, id: _user.departmentId),
onDepartmentPick: (department){ onDepartmentPick: (department) {
_user.department = department; _user.departmentName = department.name;
_user.departmentId = department.id;
setState(() {}); setState(() {});
}, },
), ),
SizedBox(height: 8,), SizedBox(
height: 8,
),
ATextFormField( ATextFormField(
initialValue: _user.phoneNumber, initialValue: _user.phoneNumber,
hintText: _subtitle.phoneNumber, hintText: _subtitle.phoneNumber,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.headline6,
prefixIconData: Icons.phone_android, prefixIconData: Icons.phone_android,
validator: (value) => validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage,
Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage,
textInputType: TextInputType.phone, textInputType: TextInputType.phone,
onSaved: (value){ onSaved: (value) {
_user.phoneNumber = value; _user.phoneNumber = value;
}, },
), ),
SizedBox(height: 8,), SizedBox(
ATextFormField( height: 8,
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;
},
), ),
// 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;
// },
// ),
], ],
), ),
), ),
SizedBox(height: 16,), SizedBox(
height: 16,
),
Center( Center(
child: SizedBox( child: SizedBox(
height: _width / 8, height: _width / 8,
width: _width/1.2, width: _width / 1.2,
child: AButton( child: AButton(
text: _subtitle.update, text: _subtitle.update,
onPressed: () async { onPressed: () async {
if(!_formKey.currentState.validate()) if (!_formKey.currentState.validate()) return;
return;
_formKey.currentState.save(); _formKey.currentState.save();
if(_user.department?.id == null){ if (_user.departmentId == null) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
SnackBar( content: Text(_subtitle.unitRequired),
content: Text( ));
_subtitle.unitRequired
),
)
);
return; return;
} }
int status = await _userProvider.updateProfile( int status = await _userProvider.updateProfile(
user: _user, user: _user,
host: _settingProvider.host, host: _settingProvider.host,
); );
if(status >= 200 && status < 300){ if (status >= 200 && status < 300) {
_settingProvider.setUser(_userProvider.user); _settingProvider.setUser(_userProvider.user);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
SnackBar( content: Text(_subtitle.requestCompleteSuccessfully),
content: Text( ));
_subtitle.requestCompleteSuccessfully } 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
),
)
);
} }
}, },
), ),
), ),
), ),
SizedBox(height: 32,), SizedBox(
height: 32,
),
], ],
), ),
), ),

@ -31,36 +31,53 @@ import 'package:test_sa/views/widgets/status/service_request/service_request_pri
import 'package:test_sa/views/widgets/status/service_request/service_request_through_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_through_mune.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart'; import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../widgets/date_and_time/date_picker.dart';
import '../../../widgets/status/service_request/service_request_first_action.dart';
import '../../../widgets/status/service_request/service_request_loan_availability.dart';
class CreateRequestPage extends StatefulWidget { class CreateRequestPage extends StatefulWidget {
static final String id = "/create-request"; static const String id = "/create-request";
final ServiceRequest serviceRequest;
const CreateRequestPage({this.serviceRequest, Key key}) : super(key: key);
@override @override
_CreateRequestPageState createState() => _CreateRequestPageState(); CreateRequestPageState createState() => CreateRequestPageState();
} }
class _CreateRequestPageState extends State<CreateRequestPage> { class CreateRequestPageState extends State<CreateRequestPage> {
double _height; double _height;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
ServiceRequestsProvider _serviceRequestsProvider; ServiceRequestsProvider _serviceRequestsProvider;
ServiceRequest _serviceRequest = ServiceRequest(); ServiceRequest _serviceRequest;
List<File> _deviceImages = []; final List<File> _deviceImages = [];
bool _isLoading = false; bool _isLoading = false;
Device _device; Device _device;
Subtitle _subtitle; Subtitle _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TextEditingController _controller; TextEditingController _maintenanceController, _commentController;
DateTime _dateTime;
@override @override
void initState() { void initState() {
_controller = TextEditingController(); _maintenanceController = TextEditingController();
_commentController = TextEditingController();
if (widget.serviceRequest != null) {
_serviceRequest = widget.serviceRequest;
_device = _serviceRequest.device;
_deviceImages.addAll(_serviceRequest.devicePhotos.map((e) => File(e)).toList());
} else {
_serviceRequest = ServiceRequest();
}
super.initState(); super.initState();
} }
@override @override
void dispose() { void dispose() {
_controller.dispose(); _maintenanceController.dispose();
_commentController.dispose();
super.dispose(); super.dispose();
} }
@ -86,21 +103,19 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
ListView( ListView(
children: [ children: [
//AppNameBar(), //AppNameBar(),
SizedBox( const SizedBox(height: 16),
height: 16,
),
Hero( Hero(
tag: "logo", tag: "logo",
child: Image( child: Image(
height: _height / 6, height: _height / 6,
image: AssetImage("assets/images/logo.png"), image: const AssetImage("assets/images/logo.png"),
), ),
), ),
Center( Center(
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
_subtitle.newServiceRequest, widget.serviceRequest == null ? _subtitle.newServiceRequest : _subtitle.updateServiceRequest,
style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600), style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600),
), ),
), ),
@ -109,21 +124,21 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
12.height, 12.height,
_userProvider.user.hospital == null _userProvider.user.clientId == null
? SizedBox.shrink() ? const SizedBox.shrink()
: ATextFormField( : ATextFormField(
enable: false, enable: false,
initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound, initialValue: _userProvider.user.clientName ?? _subtitle.noHospitalFound,
hintText: _subtitle.hospital, hintText: _subtitle.hospital,
prefixIconData: FontAwesomeIcons.hospital, prefixIconData: FontAwesomeIcons.hospital,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
), ),
12.height, 12.height,
_userProvider.user.department == null _userProvider.user.departmentId == null
? SizedBox.shrink() ? const SizedBox.shrink()
: ATextFormField( : ATextFormField(
enable: false, enable: false,
initialValue: _userProvider.user.department?.name ?? _subtitle.noUniteFound, initialValue: _userProvider.user.departmentName ?? _subtitle.noUniteFound,
hintText: _subtitle.unite, hintText: _subtitle.unite,
prefixIconData: FontAwesomeIcons.hospitalUser, prefixIconData: FontAwesomeIcons.hospitalUser,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
@ -136,53 +151,105 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
setState(() {}); setState(() {});
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
const ASubTitle("Priority"), const ASubTitle("Priority"),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ServiceRequestPriorityMenu( ServiceRequestPriorityMenu(
initialValue: _serviceRequest.priority, initialValue: _serviceRequest.priority,
onSelect: (status){ onSelect: (status) {
_serviceRequest.priority = status; _serviceRequest.priority = status;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
const ASubTitle("Defect Type"), const ASubTitle("Defect Type"),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ServiceRequestDefectTypesMenu( ServiceRequestDefectTypesMenu(
initialValue: _serviceRequest.defectType, initialValue: _serviceRequest.defectType,
onSelect: (status){ onSelect: (status) {
_serviceRequest.defectType = status; _serviceRequest.defectType = status;
}, },
), ),
12.height, 12.height,
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
const ASubTitle("Type"), const ASubTitle("Type"),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ServiceRequestTypesMenu( ServiceRequestTypesMenu(
initialValue: _serviceRequest.type, initialValue: _serviceRequest.type,
onSelect: (status){ onSelect: (status) {
_serviceRequest.type = status; _serviceRequest.type = status;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
const ASubTitle("Through"), const ASubTitle("Through"),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ServiceRequestedThroughMenu( ServiceRequestedThroughMenu(
initialValue: const Lookup(name: "App",value: 3), initialValue: const Lookup(name: "App", value: 375),
onSelect: (status){ onSelect: (status) {
_serviceRequest.requestedThrough = status; _serviceRequest.requestedThrough = status;
}, },
), ),
if (widget.serviceRequest != null) 12.height,
if (widget.serviceRequest != null) const ASubTitle("First Action"),
const SizedBox(
height: 4,
),
if (widget.serviceRequest != null)
ServiceRequestedFirstAction(
initialValue: _serviceRequest.firstAction,
onSelect: (status) {
_dateTime = null;
_serviceRequest.firstAction = status;
_serviceRequestsProvider.notifyListeners();
},
),
if (_serviceRequest.firstAction != null) 12.height,
if (_serviceRequest.firstAction != null)
ADatePicker(
date: _dateTime,
from: DateTime.now(),
onDatePicker: (date) {
_dateTime = date;
setState(() {});
},
),
if (widget.serviceRequest != null) 12.height,
if (widget.serviceRequest != null) const ASubTitle("Loan Availability"),
const SizedBox(
height: 4,
),
if (widget.serviceRequest != null)
ServiceRequestedLoanAvailability(
initialValue: _serviceRequest.loanAvailability,
onSelect: (status) {
_serviceRequest.loanAvailability = status;
},
),
12.height, 12.height,
MultiImagesPicker( MultiImagesPicker(
label: _subtitle.deviceImages, label: _subtitle.deviceImages,
images: _deviceImages, images: _deviceImages,
), ),
12.height, 12.height,
SpeechToTextButton(controller: _controller), SpeechToTextButton(controller: _maintenanceController),
12.height, 12.height,
ATextFormField( ATextFormField(
controller: _controller, controller: _maintenanceController,
initialValue: _serviceRequest.maintenanceIssue, initialValue: _serviceRequest.maintenanceIssue,
hintText: _subtitle.maintenanceIssue, hintText: _subtitle.maintenanceIssue,
prefixIconData: FontAwesomeIcons.triangleExclamation, prefixIconData: FontAwesomeIcons.triangleExclamation,
@ -198,29 +265,57 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
_serviceRequest.audio = audio; _serviceRequest.audio = audio;
}), }),
12.height, 12.height,
if (widget.serviceRequest != null)
ATextFormField(
controller: _commentController,
initialValue: _serviceRequest.comment,
hintText: _subtitle.comment,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceRequest.comment = value;
},
),
], ],
).paddingOnly(left: 20, right: 20), ).paddingOnly(left: 20, right: 20),
Padding( Padding(
padding: const EdgeInsets.all(20.0), padding: const EdgeInsets.all(20.0),
child: AButton( child: AButton(
text: _subtitle.submit, text: widget.serviceRequest == null ? _subtitle.submit : _subtitle.update,
onPressed: () async { onPressed: () async {
if (!_formKey.currentState.validate()) return; if (!_formKey.currentState.validate()) return;
if (_device?.id == null) {
Fluttertoast.showToast(msg: _subtitle.pickDevice);
return;
}
if (_serviceRequest.firstAction != null && _dateTime == null) {
Fluttertoast.showToast(msg: _subtitle.noDateFound);
return;
}
_formKey.currentState.save(); _formKey.currentState.save();
_serviceRequest.deviceId = _device?.id ?? ""; _serviceRequest.deviceId = _device?.id;
_isLoading = true; _isLoading = true;
setState(() {}); setState(() {});
_serviceRequest.devicePhotos = _deviceImages.map( _serviceRequest.devicePhotos = _deviceImages.map((e) => "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}").toList();
(e) => "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}").toList(); if (_serviceRequest.audio != null) {
if(_serviceRequest.audio != null){
final file = File(_serviceRequest.audio); final file = File(_serviceRequest.audio);
_serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}";
} }
int status = await _serviceRequestsProvider.createRequest( int status = 0;
user: _userProvider.user, if (widget.serviceRequest == null) {
host: _settingProvider.host, status = await _serviceRequestsProvider.createRequest(
serviceRequest: _serviceRequest, user: _userProvider.user,
); host: _settingProvider.host,
serviceRequest: _serviceRequest,
);
} else {
status = await _serviceRequestsProvider.updateDate(
user: _userProvider.user,
host: _settingProvider.host,
request: _serviceRequest,
date: _dateTime,
);
}
_isLoading = false; _isLoading = false;
setState(() {}); setState(() {});
if (status >= 200 && status < 300) { if (status >= 200 && status < 300) {
@ -239,7 +334,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
), ),
], ],
), ),
ABackButton(), const ABackButton(),
], ],
), ),
), ),

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -11,6 +10,7 @@ import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/user/requests/create_request.dart';
import 'package:test_sa/views/pages/user/requests/report/create_service_report.dart'; import 'package:test_sa/views/pages/user/requests/report/create_service_report.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
@ -19,11 +19,11 @@ import 'package:test_sa/views/widgets/images/images_list.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:test_sa/views/widgets/requests/service_request_update_dialog.dart';
import 'package:test_sa/views/widgets/sound/sound_player.dart'; import 'package:test_sa/views/widgets/sound/sound_player.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import 'report/future_service_report.dart'; import 'report/future_service_report.dart';
class RequestDetailsPage extends StatelessWidget { class RequestDetailsPage extends StatelessWidget {
static final String id = "/call-details"; static final String id = "/call-details";
final ServiceRequest serviceRequest; final ServiceRequest serviceRequest;
@ -42,8 +42,8 @@ class RequestDetailsPage extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
Container( Container(
color:AColors.primaryColor, color: AColors.primaryColor,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Row( child: Row(
children: [ children: [
ABackButton(), ABackButton(),
@ -51,124 +51,133 @@ class RequestDetailsPage extends StatelessWidget {
child: Center( child: Center(
child: Text( child: Text(
_subtitle.details, _subtitle.details,
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
color: AColors.white,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
_userProvider.user.type == UsersTypes.normal_user ? _userProvider.user.type == UsersTypes.normal_user
// AIconButton( ?
// iconData: Icons.warning_amber_rounded, // AIconButton(
// color: AColors.white, // iconData: Icons.warning_amber_rounded,
// buttonSize: 42, // color: AColors.white,
// backgroundColor: AColors.deepOrange, // buttonSize: 42,
// onPressed: (){ // backgroundColor: AColors.deepOrange,
// Navigator.of(context).push( // onPressed: (){
// MaterialPageRoute( // Navigator.of(context).push(
// builder: (_) => ReportIssuesPage(serviceRequest: serviceRequest,) // MaterialPageRoute(
// ) // builder: (_) => ReportIssuesPage(serviceRequest: serviceRequest,)
// ); // )
// },
// )
const SizedBox(width: 48,)
: AIconButton(
iconData: Icons.edit,
color: AColors.white,
buttonSize: 42,
backgroundColor: AColors.green,
onPressed: () async {
showModalBottomSheet(
context: context,
builder: (context){
return ServiceRequestsUpdateDialog(request: serviceRequest,);
});
// DateTime picked = await showDatePicker(
// context: context,
// initialDate: DateTime.now(),
// firstDate: DateTime.now(),
// lastDate: DateTime.now().add(Duration(days: 182))
// );
// if(picked == null){return;}
// showDialog<void>(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context) {
// return CupertinoAlertDialog(
// title: Text(_subtitle.updatingDots),
// content: Center(child: CircularProgressIndicator()),
// ); // );
// }, // },
// ); // )
// int status = await _serviceRequestsProvider.updateDate( const SizedBox(
// user: _userProvider.user, width: 48,
// host: _settingProvider.host, )
// request: serviceRequest, : AIconButton(
// newDate: picked.toString().split(" ").first iconData: Icons.edit,
// ); color: AColors.white,
// Navigator.of(context).pop(); buttonSize: 42,
// Fluttertoast.showToast( backgroundColor: AColors.green,
// msg: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle), onPressed: () async {
// ); Navigator.of(context).push(
}, MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)),
), );
SizedBox(width: 16,) // showModalBottomSheet(
// context: context,
// builder: (context) {
//
// // return ServiceRequestsUpdateDialog(request: serviceRequest,);
// });
// DateTime picked = await showDatePicker(
// context: context,
// initialDate: DateTime.now(),
// firstDate: DateTime.now(),
// lastDate: DateTime.now().add(Duration(days: 182))
// );
// if(picked == null){return;}
// showDialog<void>(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context) {
// return CupertinoAlertDialog(
// title: Text(_subtitle.updatingDots),
// content: Center(child: CircularProgressIndicator()),
// );
// },
// );
// int status = await _serviceRequestsProvider.updateDate(
// user: _userProvider.user,
// host: _settingProvider.host,
// request: serviceRequest,
// newDate: picked.toString().split(" ").first
// );
// Navigator.of(context).pop();
// Fluttertoast.showToast(
// msg: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle),
// );
},
),
SizedBox(
width: 16,
)
], ],
), ),
), ),
serviceRequest.devicePhotos.isEmpty
serviceRequest.devicePhotos.isEmpty ? SizedBox.shrink(): ? SizedBox.shrink()
Column( : Column(
children: [ children: [
SizedBox(height: 8,), SizedBox(
MaterialButton( height: 8,
padding: EdgeInsets.zero, ),
onPressed: (){ MaterialButton(
Navigator.of(context).push( padding: EdgeInsets.zero,
MaterialPageRoute( onPressed: () {
builder: (_) => Scaffold( Navigator.of(context).push(MaterialPageRoute(
body: InteractiveViewer( builder: (_) => Scaffold(
child: Center( body: InteractiveViewer(
child: ImageLoader( child: Center(
url: serviceRequest.devicePhotos.first, child: ImageLoader(
boxFit: BoxFit.contain, url: serviceRequest.devicePhotos.first,
), boxFit: BoxFit.contain,
), ),
), ),
) ),
) )));
); },
}, child: SizedBox(
child: SizedBox( height: 140 * AppStyle.getScaleFactor(context),
height: 140 * AppStyle.getScaleFactor(context), width: MediaQuery.of(context).size.width,
width: MediaQuery.of(context).size.width, child: ImageLoader(
child: ImageLoader( url: serviceRequest.devicePhotos.first,
url: serviceRequest.devicePhotos.first, boxFit: BoxFit.cover,
boxFit: BoxFit.cover, ),
), ),
), ),
), SizedBox(
SizedBox(height: 8,), height: 8,
SizedBox( ),
height: 60* AppStyle.getScaleFactor(context), SizedBox(
child: ImagesList( height: 60 * AppStyle.getScaleFactor(context),
images: serviceRequest.devicePhotos, child: ImagesList(
images: serviceRequest.devicePhotos,
),
),
],
), ),
), TabBar(labelColor: AColors.primaryColor, tabs: [
], Tab(
), text: _subtitle.general,
),
TabBar( Tab(
labelColor: AColors.primaryColor, text: _subtitle.serviceRequestInformation,
tabs: [ ),
Tab(text: _subtitle.general,),
Tab(text: _subtitle.serviceRequestInformation,),
]), ]),
SizedBox(height: 8,), SizedBox(
height: 8,
),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
children: [ children: [
ListView( ListView(
padding: EdgeInsets.symmetric(horizontal: 16), padding: EdgeInsets.symmetric(horizontal: 16),
@ -187,7 +196,7 @@ class RequestDetailsPage extends StatelessWidget {
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.deviceModel, title: _subtitle.deviceModel,
info : serviceRequest.deviceModel, info: serviceRequest.deviceModel,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.engineerName, title: _subtitle.engineerName,
@ -201,11 +210,12 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.date, title: _subtitle.date,
info: serviceRequest.date, info: serviceRequest.date,
), ),
serviceRequest.nextVisitDate == null ? SizedBox.shrink() : serviceRequest.nextVisitDate == null
RequestInfoRow( ? SizedBox.shrink()
title: _subtitle.nextVisitDate, : RequestInfoRow(
info: DateFormat('EE dd/MM/yyyy').format(serviceRequest.nextVisitDate), title: _subtitle.nextVisitDate,
), info: DateFormat('EE dd/MM/yyyy').format(serviceRequest.nextVisitDate),
),
Row( Row(
children: [ children: [
Expanded( Expanded(
@ -215,12 +225,12 @@ class RequestDetailsPage extends StatelessWidget {
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
), ),
), ),
StatusLabel(label: serviceRequest.statusLabel, StatusLabel(label: serviceRequest.statusLabel, color: AColors.getRequestStatusColor(serviceRequest.statusValue)),
color: AColors.getRequestStatusColor(serviceRequest.statusValue)
),
], ],
), ),
Divider(color: Theme.of(context).primaryColor,), Divider(
color: Theme.of(context).primaryColor,
),
RequestInfoRow( RequestInfoRow(
title: _subtitle.hospital, title: _subtitle.hospital,
info: serviceRequest.hospitalName, info: serviceRequest.hospitalName,
@ -241,10 +251,10 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.maintenanceIssue, title: _subtitle.maintenanceIssue,
content: serviceRequest.maintenanceIssue, content: serviceRequest.maintenanceIssue,
), ),
if(serviceRequest.audio?.isNotEmpty == true) if (serviceRequest.audio?.isNotEmpty == true)
ASoundPlayer( ASoundPlayer(
audio: serviceRequest.audio, audio: serviceRequest.audio,
), ),
// //
// Center( // Center(
// child: Padding( // child: Padding(
@ -286,65 +296,64 @@ class RequestDetailsPage extends StatelessWidget {
// ) // )
], ],
), ),
serviceRequest.viewReport ? serviceRequest.viewReport
ListView( ? ListView(
padding: EdgeInsets.symmetric(horizontal: 16), padding: EdgeInsets.symmetric(horizontal: 16),
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: _subtitle.faultDescription, title: _subtitle.faultDescription,
content: serviceRequest.faultDescription, content: serviceRequest.faultDescription,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.workPerformed, title: _subtitle.workPerformed,
content: serviceRequest.workPerformed, content: serviceRequest.workPerformed,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.visitDate, title: _subtitle.visitDate,
info: serviceRequest.visitDate, info: serviceRequest.visitDate,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.jobSheetNumber, title: _subtitle.jobSheetNumber,
info: serviceRequest.jobSheetNumber, info: serviceRequest.jobSheetNumber,
), ),
_userProvider.user.type == UsersTypes.engineer _userProvider.user.type == UsersTypes.engineer && serviceRequest.reportID != null
&& serviceRequest.reportID != null? ? Padding(
Padding( padding: EdgeInsets.all(32),
padding: EdgeInsets.all(32), child: AButton(
child: AButton( text: _subtitle.editServiceReport,
text: _subtitle.editServiceReport, onPressed: () {
onPressed: (){ Navigator.of(context).push(
Navigator.of(context).push( MaterialPageRoute(
MaterialPageRoute( builder: (_) => FutureServiceReport(
builder: (_) => FutureServiceReport( request: serviceRequest,
request: serviceRequest, )),
);
},
),
) )
: SizedBox.shrink(),
],
)
: _userProvider.user.type == UsersTypes.engineer
? Center(
child: Padding(
padding: EdgeInsets.all(32),
child: AButton(
text: "Create Report",
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => CreateServiceReport(
request: serviceRequest,
)),
);
},
),
), ),
); )
}, : Center(
), child: ASubTitle(_subtitle.noDateFound),
): SizedBox.shrink(),
],
):
_userProvider.user.type == UsersTypes.engineer ?
Center(
child: Padding(
padding: EdgeInsets.all(32),
child: AButton(
text: "Create Report",
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => CreateServiceReport(
request: serviceRequest,
)
), ),
);
},
),
),
): Center(child: ASubTitle(_subtitle.noDateFound),),
], ],
), ),
), ),

@ -12,14 +12,14 @@ import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/requests/service_request_list.dart'; import 'package:test_sa/views/widgets/requests/service_request_list.dart';
import 'package:test_sa/views/widgets/search/service_request_search_bar.dart'; import 'package:test_sa/views/widgets/search/service_request_search_bar.dart';
class ServiceRequestsPage extends StatefulWidget { class ServiceRequestsPage extends StatefulWidget {
static final String id = "/service-requests"; static final String id = "/service-requests";
@override @override
_ServiceRequestsPageState createState() => _ServiceRequestsPageState(); _ServiceRequestsPageState createState() => _ServiceRequestsPageState();
} }
class _ServiceRequestsPageState extends State<ServiceRequestsPage> class _ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerProviderStateMixin {
with TickerProviderStateMixin{
ServiceRequestsProvider _serviceRequestsProvider; ServiceRequestsProvider _serviceRequestsProvider;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
@ -31,7 +31,7 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(_firstTime){ if (_firstTime) {
_serviceRequestsProvider.reset(); _serviceRequestsProvider.reset();
_firstTime = false; _firstTime = false;
} }
@ -45,9 +45,9 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
onRefresh: () async { onRefresh: () async {
_serviceRequestsProvider.reset(); _serviceRequestsProvider.reset();
await _serviceRequestsProvider.getRequests( await _serviceRequestsProvider.getRequests(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
hospitalId: _userProvider.user.hospital?.id, hospitalId: _userProvider.user.clientId,
); );
}, },
child: Stack( child: Stack(
@ -55,8 +55,8 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
Column( Column(
children: [ children: [
Container( Container(
color:AColors.primaryColor, color: AColors.primaryColor,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Column( child: Column(
children: [ children: [
Row( Row(
@ -66,10 +66,7 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
child: Center( child: Center(
child: Text( child: Text(
_subtitle.serviceRequests, _subtitle.serviceRequests,
style: Theme.of(context).textTheme.headline6.copyWith( style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
color: AColors.white,
fontStyle: FontStyle.italic
),
), ),
), ),
), ),
@ -83,22 +80,23 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
ServiceRequestSearch _temp = await showModalBottomSheet( ServiceRequestSearch _temp = await showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
builder: (context){ builder: (context) {
return ServiceRequestsSearchDialog( return ServiceRequestsSearchDialog(
initialSearchValue: _serviceRequestsProvider.search, initialSearchValue: _serviceRequestsProvider.search,
); );
}); });
if(_temp != null){ if (_temp != null) {
_serviceRequestsProvider.search = _temp; _serviceRequestsProvider.search = _temp;
_serviceRequestsProvider.reset(); _serviceRequestsProvider.reset();
setState(() {}); setState(() {});
} }
}, },
), ),
SizedBox(width: 16,) SizedBox(
width: 16,
)
], ],
), ),
], ],
), ),
), ),
@ -107,9 +105,9 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
nextPage: _serviceRequestsProvider.nextPage, nextPage: _serviceRequestsProvider.nextPage,
onLazyLoad: () async { onLazyLoad: () async {
await _serviceRequestsProvider.getRequests( await _serviceRequestsProvider.getRequests(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
hospitalId: _userProvider.user.hospital.id, hospitalId: _userProvider.user.clientId,
); );
}, },
requests: _serviceRequestsProvider.serviceRequests, requests: _serviceRequestsProvider.serviceRequests,
@ -117,7 +115,6 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
), ),
], ],
), ),
], ],
), ),
), ),

@ -8,6 +8,7 @@ import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
class AutoCompleteDeviceField extends StatefulWidget { class AutoCompleteDeviceField extends StatefulWidget {
final Device initialValue; final Device initialValue;
final int hospitalId; final int hospitalId;
@ -20,7 +21,6 @@ class AutoCompleteDeviceField extends StatefulWidget {
} }
class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> { class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
SettingProvider _settingProvider; SettingProvider _settingProvider;
DevicesProvider _devicesProvider; DevicesProvider _devicesProvider;
UserProvider _userProvider; UserProvider _userProvider;
@ -37,6 +37,7 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_controller.dispose(); _controller.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
@ -44,64 +45,53 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_devicesProvider = Provider.of<DevicesProvider>(context); _devicesProvider = Provider.of<DevicesProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle; //Subtitle _subtitle = AppLocalization.of(context).subtitle;
return LoadingManager( return LoadingManager(
isLoading: _devicesProvider.isLoading, isLoading: _devicesProvider.isLoading,
isFailedLoading: _devicesProvider.devices == null, isFailedLoading: _devicesProvider.devices == null,
stateCode: _devicesProvider.stateCode, stateCode: _devicesProvider.stateCode,
onRefresh: () async { onRefresh: () async {
_devicesProvider.reset(); _devicesProvider.reset();
await _devicesProvider.getEquipment( await _devicesProvider.getEquipment(host: _settingProvider.host, user: _userProvider.user, hospitalId: widget.hospitalId);
host: _settingProvider.host, },
user: _userProvider.user, child: Container(
hospitalId: widget.hospitalId padding: const EdgeInsets.symmetric(horizontal: 16),
); decoration: BoxDecoration(
}, color: Colors.white,
child: Container( border: Border.all(color: AColors.black),
padding: const EdgeInsets.symmetric( borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
horizontal: 16 boxShadow: [AppStyle.boxShadow]),
), child: TypeAheadField<Device>(
decoration: BoxDecoration( textFieldConfiguration: TextFieldConfiguration(
color: Colors.white, style: Theme.of(context).textTheme.headline6,
border: Border.all(color:AColors.black), controller: _controller,
borderRadius: BorderRadius.circular( textAlign: TextAlign.center,
AppStyle.borderRadius * AppStyle.getScaleFactor(context) decoration: const InputDecoration(
), border: InputBorder.none,
boxShadow: [ disabledBorder: InputBorder.none,
AppStyle.boxShadow focusedBorder: InputBorder.none,
] enabledBorder: InputBorder.none,
),
child: TypeAheadField<Device>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
controller: _controller,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
), ),
suggestionsCallback: (value) async { textInputAction: TextInputAction.search,
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId ?? _userProvider.user.hospital.id,
serialNumber: value,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.serialNumber),
subtitle: Text("${device.modelDefinition.modelName}/${device.modelDefinition.manufacturerName}"),
);
},
onSuggestionSelected: (device) {
_controller.text = device.serialNumber;
widget.onPick(device.id);
},
), ),
suggestionsCallback: (value) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId ?? _userProvider.user.clientId,
serialNumber: value,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.serialNumber),
subtitle: Text("${device.modelDefinition.modelName}/${device.modelDefinition.manufacturerName}"),
);
},
onSuggestionSelected: (device) {
_controller.text = device.serialNumber;
widget.onPick(device.id);
},
), ),
),
); );
} }
} }

@ -11,9 +11,9 @@ import 'package:test_sa/views/widgets/equipment/device_item.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart'; import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart'; import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import 'package:test_sa/views/widgets/qr/scan_qr.dart';
import '../app_text_form_field.dart'; import '../app_text_form_field.dart';
class SingleDevicePicker extends StatefulWidget { class SingleDevicePicker extends StatefulWidget {
static final String id = "/single-device-Picker"; static final String id = "/single-device-Picker";
final bool sandraChoice = true; final bool sandraChoice = true;
@ -32,22 +32,16 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
TextEditingController numberController = TextEditingController(); TextEditingController numberController = TextEditingController();
TextEditingController snController = TextEditingController(); TextEditingController snController = TextEditingController();
_getDevice(String result) async { _getDevice(String result) async {
if(result == null) return; if (result == null) return;
showDialog( showDialog(
barrierDismissible: false, barrierDismissible: false,
context: context, context: context,
builder: (dialogContext){ builder: (dialogContext) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} });
); List<Device> devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result);
List<Device> devices = await _devicesProvider.getDevicesListBySN(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: _userProvider.user.hospital.id,
sn: result
);
Navigator.of(context).pop(); Navigator.of(context).pop();
if(devices.isEmpty){ if (devices.isEmpty) {
Fluttertoast.showToast(msg: _subtitle.noDeviceFound); Fluttertoast.showToast(msg: _subtitle.noDeviceFound);
return; return;
} }
@ -72,7 +66,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
if(_firstTime && _devicesProvider.devices != null){ if (_firstTime && _devicesProvider.devices != null) {
_searchableList.clear(); _searchableList.clear();
_searchableList.addAll(_devicesProvider.devices); _searchableList.addAll(_devicesProvider.devices);
} }
@ -85,54 +79,42 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
isFailedLoading: _devicesProvider.devices == null, isFailedLoading: _devicesProvider.devices == null,
onRefresh: () async { onRefresh: () async {
_devicesProvider.reset(); _devicesProvider.reset();
await _devicesProvider.getEquipment( await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId);
user: _userProvider.user,
host: _settingProvider.host,
hospitalId: _userProvider.user.hospital?.id
);
}, },
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 48), const SizedBox(height: 48),
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Column( child: Column(
children: [ children: [
ATextFormField( ATextFormField(
hintText: _subtitle.searchBySn, hintText: _subtitle.searchBySn,
controller: snController, controller: snController,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
suffixIcon: const Icon(Icons.search_rounded), suffixIcon: const Icon(Icons.search_rounded),
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
onAction: () async { onAction: () async {
_devicesProvider.reset(); _devicesProvider.reset();
await _devicesProvider.getEquipment( await _devicesProvider.getEquipment(
user: _userProvider.user, user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text);
host: _settingProvider.host,
hospitalId: _userProvider.user.hospital?.id,
serialNumber: snController.text,
number: numberController.text
);
_searchableList.clear(); _searchableList.clear();
_searchableList.addAll(_devicesProvider.devices); _searchableList.addAll(_devicesProvider.devices);
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
ATextFormField( ATextFormField(
hintText: "Search by Number", hintText: "Search by Number",
controller: numberController, controller: numberController,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
suffixIcon: const Icon(Icons.search_rounded), suffixIcon: const Icon(Icons.search_rounded),
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
onAction: () async { onAction: () async {
_devicesProvider.reset(); _devicesProvider.reset();
await _devicesProvider.getEquipment( await _devicesProvider.getEquipment(
user: _userProvider.user, user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text);
host: _settingProvider.host,
hospitalId: _userProvider.user.hospital?.id,
serialNumber: snController.text,
number: numberController.text
);
_searchableList.clear(); _searchableList.clear();
_searchableList.addAll(_devicesProvider.devices); _searchableList.addAll(_devicesProvider.devices);
}, },
@ -141,34 +123,30 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
), ),
), ),
Expanded( Expanded(
child: _searchableList.isEmpty ? child: _searchableList.isEmpty
NoItemFound(message: _subtitle.noDeviceFound,): ? NoItemFound(
LazyLoading( message: _subtitle.noDeviceFound,
nextPage: _devicesProvider.nextPage, )
onLazyLoad: () async { : LazyLoading(
await _devicesProvider.getDevicesList( nextPage: _devicesProvider.nextPage,
user: _userProvider.user, onLazyLoad: () async {
host: _settingProvider.host, await _devicesProvider.getDevicesList(
hospitalId: _userProvider.user.hospital?.id, user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text);
serialNumber: snController.text, },
number: numberController.text child: ListView.builder(
); padding: EdgeInsets.zero,
}, shrinkWrap: true,
child:ListView.builder( itemCount: _searchableList.length,
padding: EdgeInsets.zero, itemBuilder: (listContext, itemIndex) {
shrinkWrap: true, return DeviceItem(
itemCount: _searchableList.length, device: _searchableList[itemIndex],
itemBuilder: (listContext,itemIndex){ onPressed: (device) {
return DeviceItem( Navigator.of(context).pop(device);
device: _searchableList[itemIndex], },
onPressed: (device){ );
Navigator.of(context).pop(device); },
}, ),
); )),
},
),
)
),
], ],
), ),
), ),

@ -71,7 +71,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
), ),
AutoCompleteDeviceNumberField( AutoCompleteDeviceNumberField(
initialValue: model.assetsNumber, initialValue: model.assetsNumber,
hospitalId: userProvider.user.hospital?.id, hospitalId: userProvider.user.clientId,
onPick: (number) { onPick: (number) {
model.assetsNumber = number; model.assetsNumber = number;
}, },

@ -54,8 +54,7 @@ class _ServiceRequestsUpdateDialogState extends State<ServiceRequestsUpdateDialo
); );
}, },
); );
int status = await _serviceRequestsProvider.updateDate( int status = await _serviceRequestsProvider.updateDate(user: _userProvider.user, host: _settingProvider.host, request: widget.request);
user: _userProvider.user, host: _settingProvider.host, request: widget.request, newDate: _dateTime?.toString()?.split(" ")?.first, employee: _employee);
if (status == 200) Navigator.of(context).pop(); if (status == 200) Navigator.of(context).pop();
Navigator.of(context).pop(); Navigator.of(context).pop();
Fluttertoast.showToast( Fluttertoast.showToast(

@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import 'package:provider/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/lookup.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart';
class ServiceRequestedFirstAction extends StatelessWidget {
final Function(Lookup) onSelect;
final Lookup initialValue;
const ServiceRequestedFirstAction({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override
Widget build(BuildContext context) {
final settingProvider = Provider.of<SettingProvider>(context);
final userProvider = Provider.of<UserProvider>(context);
final menuProvider = Provider.of<ServiceFirstActionProvider>(context);
return LoadingManager(
isLoading: menuProvider.isLoading,
isFailedLoading: menuProvider.items == null,
stateCode: menuProvider.stateCode,
onRefresh: () async {
menuProvider.reset();
await menuProvider.getData(user: userProvider.user, host: settingProvider.host);
},
child: SingleStatusMenu(
initialStatus: initialValue,
statuses: menuProvider.items,
onSelect: onSelect,
),
);
}
}

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:provider/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/lookup.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart';
class ServiceRequestedLoanAvailability extends StatelessWidget {
final Function(Lookup) onSelect;
final Lookup initialValue;
const ServiceRequestedLoanAvailability({Key key, this.onSelect, this.initialValue}) : super(key: key);
@override
Widget build(BuildContext context) {
final settingProvider = Provider.of<SettingProvider>(context);
final userProvider = Provider.of<UserProvider>(context);
final menuProvider = Provider.of<ServiceLoanAvailabilityProvider>(context);
return LoadingManager(
isLoading: menuProvider.isLoading,
isFailedLoading: menuProvider.items == null,
stateCode: menuProvider.stateCode,
onRefresh: () async {
menuProvider.reset();
await menuProvider.getData(user: userProvider.user, host: settingProvider.host);
},
child: SingleStatusMenu(
initialStatus: initialValue,
statuses: menuProvider.items,
onSelect: onSelect,
));
}
}
Loading…
Cancel
Save