diff --git a/assets/subtitles/ar_subtitle.json b/assets/subtitles/ar_subtitle.json index 5a57fc1d..b4294845 100644 --- a/assets/subtitles/ar_subtitle.json +++ b/assets/subtitles/ar_subtitle.json @@ -189,5 +189,6 @@ "duplicateAlert": "تنبيه التكرار", "duplicateAlertMessage": "هل أنت متأكد أنك تريد تكرار الطلب؟", "duplicateRequest": "تكرار الطلب", - "comment" : "تعليق" + "comment" : "تعليق", + "updateServiceRequest" : "تعديل طلب الخدمة" } \ No newline at end of file diff --git a/assets/subtitles/en_subtitle.json b/assets/subtitles/en_subtitle.json index a86013b2..3045e66e 100644 --- a/assets/subtitles/en_subtitle.json +++ b/assets/subtitles/en_subtitle.json @@ -189,5 +189,6 @@ "duplicateAlert": "Duplicate Alert", "duplicateAlertMessage": "Are you sure you want to duplicate request?", "duplicateRequest": "Duplicate Request", - "comment" : "Comment" + "comment" : "Comment", + "updateServiceRequest" : "Update Service Request" } \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a5559bc2..5116f0d6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -227,6 +227,7 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -258,6 +259,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 347cd5f4..86b0405c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -60,5 +60,7 @@ UIViewControllerBasedStatusBarAppearance + UIApplicationSupportsIndirectInputEvents + diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 65c8935d..44645f76 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -24,6 +24,8 @@ class URLs { // 08051 static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // 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 getServiceRequestStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=503"; diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index 6c72fbb9..e989a85d 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -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/urls.dart'; import 'package:test_sa/models/issue.dart'; -import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request_search.dart'; @@ -146,7 +145,7 @@ class ServiceRequestsProvider extends ChangeNotifier { "defectType": serviceRequest.defectType.toMap(), "typeofRequest": serviceRequest.type.toMap(), "requestedThrough": serviceRequest.type.toMap(), - "reviewComment": serviceRequest.comment, + "reviewComment": null, if (serviceRequest.audio != null) "voiceNote": serviceRequest.audio, "callSiteContactPerson": [ { @@ -213,30 +212,46 @@ class ServiceRequestsProvider extends ChangeNotifier { Future updateDate({ @required String host, @required User user, - @required String newDate, - @required Lookup employee, @required ServiceRequest request, + DateTime date, }) async { Response response; var body = { + "id": request.id, + "callNo": "", "callCreatedBy": {"id": user.id, "name": user.userName}, - "assets": request.deviceId == null ? [] : [request.deviceId], - "requestedDate": newDate, - "requestedTime": newDate, + "requestedDate": date?.toIso8601String(), + "requestedTime": date?.toIso8601String(), "priority": request.priority?.toMap(), "defectType": request.defectType?.toMap(), "typeofRequest": request.type?.toMap(), - "requestedThrough": request.type?.toMap(), - "assignedEmployee": { - "id": request.requestedThrough?.id ?? "", - "name": request.requestedThrough?.name ?? '', - }, + "requestedThrough": request.requestedThrough?.toMap(), "voiceNote": request.audio, + "assets": request.deviceId == null ? [] : [request.deviceId], + "attachmentsCallRequest": request.devicePhotos?.map((e) => {"name": e})?.toList(), + "callSiteContactPerson": [ + { + "id": 0, + "employeeCode": user.email, + "name": user.userName, + "telephone": user.phoneNumber, + // "job": "", + "email": user.email, + // "land": "", + "contactUserId": user.id, + }, + ], "callComments": request.maintenanceIssue, "noofFollowup": 0, - "attachmentsCallRequest": request.devicePhotos?.map((e) => {"name": e})?.toList(), - // "status": request.statusLabel, + // "status": null, "callLastSituation": null, + "firstAction": request.firstAction.toMap(), + "loanAvailablity": request.loanAvailability.toMap(), + "comments": request.comment, + "firstActionDate": null, + "visitDate": null, + "callReview": null, + "reviewComment": null, }; try { response = await ApiManager.instance.put( @@ -245,7 +260,7 @@ class ServiceRequestsProvider extends ChangeNotifier { ); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - request.engineerName = employee.name; + // request.engineerName = employee.name; notifyListeners(); } return response.statusCode; diff --git a/lib/controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart b/lib/controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart new file mode 100644 index 00000000..6c1beb9d --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart @@ -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 _statuses; + List 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 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; + } + } +} diff --git a/lib/controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart b/lib/controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart new file mode 100644 index 00000000..a4f1594a --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart @@ -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 _statuses; + List 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 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; + } + } +} diff --git a/lib/main.dart b/lib/main.dart index 26805518..60cea674 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -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 '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/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/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_through_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(); if (Platform.isIOS) { await Firebase.initializeApp( - options: const FirebaseOptions(apiKey: "AIzaSyACQkSleNwU1jzEKR5ho1uSfZERokwwAbc", appId: "1:973582662416:ios:bc4a8061444c6a08fbc395", messagingSenderId: "973582662416", projectId: "atoms-fb912"), + options: + const FirebaseOptions(apiKey: "AIzaSyACQkSleNwU1jzEKR5ho1uSfZERokwwAbc", appId: "1:973582662416:ios:bc4a8061444c6a08fbc395", messagingSenderId: "973582662416", projectId: "atoms-fb912"), ); } else { await Firebase.initializeApp(); } - runApp( - ChangeNotifierProvider( - create: (_) => SettingProvider(), - child: MyApp(), - ) - ); + runApp(ChangeNotifierProvider( + create: (_) => SettingProvider(), + child: MyApp(), + )); } class MyApp extends StatelessWidget { @@ -115,6 +113,8 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => ServiceRequestedThroughProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestStatusProvider()), ChangeNotifierProvider(create: (_) => EngineersProvider()), + ChangeNotifierProvider(create: (_) => ServiceLoanAvailabilityProvider()), + ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()), ], child: GestureDetector( onTap: () { @@ -127,18 +127,12 @@ class MyApp extends StatelessWidget { title: 'ATOMS', debugShowCheckedModeBanner: false, theme: ThemeData( - fontFamily: "Poppins", - //canvasColor: AColors.primaryColor, - scaffoldBackgroundColor: AColors.scaffoldBackgroundColor, - primaryColor: AColors.primaryColor, - indicatorColor: AColors.primaryColor, - colorScheme: const ColorScheme.light( - primary: AColors.primaryColor, - onPrimary: Colors.white, - secondary: AColors.secondaryColor, - onSecondary: Colors.white - ) - ), + fontFamily: "Poppins", + //canvasColor: AColors.primaryColor, + scaffoldBackgroundColor: AColors.scaffoldBackgroundColor, + primaryColor: AColors.primaryColor, + indicatorColor: AColors.primaryColor, + colorScheme: const ColorScheme.light(primary: AColors.primaryColor, onPrimary: Colors.white, secondary: AColors.secondaryColor, onSecondary: Colors.white)), localizationsDelegates: const [ // ... app-specific localization delegate[s] here AppLocalization.delegate, @@ -153,31 +147,28 @@ class MyApp extends StatelessWidget { locale: Locale(_settingProvider.language ?? 'en'), initialRoute: SplashScreen.id, routes: { - SplashScreen.id: (_)=> const SplashScreen(), - LandPage.id: (_)=> const LandPage(), - Login.id: (_)=> Login(), - Register.id: (_)=> Register(), - ProfilePage.id: (_)=> ProfilePage(), - ReportIssuesPage.id: (_)=> const ReportIssuesPage(), - RequestGasRefill.id: (_)=> const RequestGasRefill(), - CreateRequestPage.id: (_)=> CreateRequestPage(), - SingleHospitalPicker.id: (_)=> SingleHospitalPicker(), - SingleDevicePicker.id: (_)=> SingleDevicePicker(), - SingleDepartmentPicker.id: (_)=> SingleDepartmentPicker(), - ServiceRequestsPage.id: (_)=> ServiceRequestsPage(), - NotificationsPage.id: (_)=> NotificationsPage(), - FutureRequestServiceDetails.id: (_)=> FutureRequestServiceDetails(), - PreventiveMaintenanceVisitsPage.id: (_)=> PreventiveMaintenanceVisitsPage(), - RegularVisitsPage.id: (_)=> RegularVisitsPage(), - TrackGasRefillPage.id: (_)=> const TrackGasRefillPage(), - RequestDeviceTransfer.id: (_)=> const RequestDeviceTransfer(), - TrackDeviceTransferPage.id: (_)=> const TrackDeviceTransferPage(), + SplashScreen.id: (_) => const SplashScreen(), + LandPage.id: (_) => const LandPage(), + Login.id: (_) => Login(), + Register.id: (_) => Register(), + ProfilePage.id: (_) => ProfilePage(), + ReportIssuesPage.id: (_) => const ReportIssuesPage(), + RequestGasRefill.id: (_) => const RequestGasRefill(), + CreateRequestPage.id: (_) => const CreateRequestPage(), + SingleHospitalPicker.id: (_) => SingleHospitalPicker(), + SingleDevicePicker.id: (_) => SingleDevicePicker(), + SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(), + ServiceRequestsPage.id: (_) => ServiceRequestsPage(), + NotificationsPage.id: (_) => NotificationsPage(), + FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(), + PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(), + RegularVisitsPage.id: (_) => RegularVisitsPage(), + TrackGasRefillPage.id: (_) => const TrackGasRefillPage(), + RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(), + TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(), }, ), ), ); } } - - - diff --git a/lib/models/service_request/service_request.dart b/lib/models/service_request/service_request.dart index bf957294..6ebc748b 100644 --- a/lib/models/service_request/service_request.dart +++ b/lib/models/service_request/service_request.dart @@ -35,6 +35,8 @@ class ServiceRequest { Lookup defectType; Lookup type; Lookup requestedThrough; + Lookup firstAction; + Lookup loanAvailability; Device device; ServiceRequest({ @@ -70,6 +72,8 @@ class ServiceRequest { this.requestedThrough, this.device, this.comment, + this.loanAvailability, + this.firstAction, }); factory ServiceRequest.fromJson(Map parsedJson) { @@ -107,6 +111,12 @@ class ServiceRequest { workPerformed: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workPerformed"] : null, 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']), ); } } diff --git a/lib/models/subtitle.dart b/lib/models/subtitle.dart index 30b8efc9..1a05ab65 100644 --- a/lib/models/subtitle.dart +++ b/lib/models/subtitle.dart @@ -216,6 +216,7 @@ class Subtitle { String duplicateAlertMessage; String alert; String comment; + String updateServiceRequest; void setIssues(List issues) { issues.clear(); @@ -227,6 +228,7 @@ class Subtitle { } Subtitle({ + @required this.updateServiceRequest, @required this.comment, @required this.currentlyServiceNotAvailable, @required this.waitUntilYourRequestComplete, @@ -411,6 +413,7 @@ class Subtitle { factory Subtitle.fromJson(Map parsedJson) { return Subtitle( + updateServiceRequest: parsedJson["updateServiceRequest"], comment: parsedJson["comment"], currentlyServiceNotAvailable: parsedJson["server_error_message"], failedToCompleteRequest: parsedJson["failed_request_message"], diff --git a/lib/views/pages/user/requests/create_request.dart b/lib/views/pages/user/requests/create_request.dart index 695a4075..5e6701f5 100644 --- a/lib/views/pages/user/requests/create_request.dart +++ b/lib/views/pages/user/requests/create_request.dart @@ -32,31 +32,43 @@ import 'package:test_sa/views/widgets/status/service_request/service_request_thr import 'package:test_sa/views/widgets/status/service_request/service_request_types_mune.dart'; import 'package:test_sa/views/widgets/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 { - 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 - _CreateRequestPageState createState() => _CreateRequestPageState(); + CreateRequestPageState createState() => CreateRequestPageState(); } -class _CreateRequestPageState extends State { +class CreateRequestPageState extends State { double _height; UserProvider _userProvider; SettingProvider _settingProvider; ServiceRequestsProvider _serviceRequestsProvider; - ServiceRequest _serviceRequest = ServiceRequest(); - List _deviceImages = []; + ServiceRequest _serviceRequest; + final List _deviceImages = []; bool _isLoading = false; Device _device; Subtitle _subtitle; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); TextEditingController _maintenanceController, _commentController; + DateTime _dateTime; @override void initState() { _maintenanceController = TextEditingController(); _commentController = TextEditingController(); + if (widget.serviceRequest != null) { + _serviceRequest = widget.serviceRequest; + _device = _serviceRequest.device; + _deviceImages.addAll(_serviceRequest.devicePhotos.map((e) => File(e)).toList()); + } super.initState(); } @@ -89,21 +101,19 @@ class _CreateRequestPageState extends State { ListView( children: [ //AppNameBar(), - SizedBox( - height: 16, - ), + const SizedBox(height: 16), Hero( tag: "logo", child: Image( height: _height / 6, - image: AssetImage("assets/images/logo.png"), + image: const AssetImage("assets/images/logo.png"), ), ), Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( - _subtitle.newServiceRequest, + widget.serviceRequest == null ? _subtitle.newServiceRequest : _subtitle.updateServiceRequest, style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600), ), ), @@ -113,7 +123,7 @@ class _CreateRequestPageState extends State { children: [ 12.height, _userProvider.user.hospital == null - ? SizedBox.shrink() + ? const SizedBox.shrink() : ATextFormField( enable: false, initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound, @@ -123,7 +133,7 @@ class _CreateRequestPageState extends State { ), 12.height, _userProvider.user.department == null - ? SizedBox.shrink() + ? const SizedBox.shrink() : ATextFormField( enable: false, initialValue: _userProvider.user.department?.name ?? _subtitle.noUniteFound, @@ -192,12 +202,45 @@ class _CreateRequestPageState extends State { _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) { + _serviceRequest.firstAction = status; + }, + ), + 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, MultiImagesPicker( label: _subtitle.deviceImages, images: _deviceImages, ), 12.height, + ADatePicker( + date: _dateTime, + from: DateTime.now(), + onDatePicker: (date) { + _dateTime = date; + setState(() {}); + }, + ), + 12.height, SpeechToTextButton(controller: _maintenanceController), 12.height, ATextFormField( @@ -217,22 +260,23 @@ class _CreateRequestPageState extends State { _serviceRequest.audio = audio; }), 12.height, - ATextFormField( - controller: _commentController, - initialValue: _serviceRequest.comment, - hintText: _subtitle.comment, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.multiline, - onSaved: (value) { - _serviceRequest.comment = value; - }, - ), + 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), Padding( padding: const EdgeInsets.all(20.0), child: AButton( - text: _subtitle.submit, + text: widget.serviceRequest == null ? _subtitle.submit : _subtitle.update, onPressed: () async { if (!_formKey.currentState.validate()) return; if (_device?.id == null) { @@ -248,11 +292,21 @@ class _CreateRequestPageState extends State { final file = File(_serviceRequest.audio); _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; } - int status = await _serviceRequestsProvider.createRequest( - user: _userProvider.user, - host: _settingProvider.host, - serviceRequest: _serviceRequest, - ); + int status = 0; + if (widget.serviceRequest == null) { + status = await _serviceRequestsProvider.createRequest( + 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; setState(() {}); if (status >= 200 && status < 300) { @@ -271,7 +325,7 @@ class _CreateRequestPageState extends State { ), ], ), - ABackButton(), + const ABackButton(), ], ), ), diff --git a/lib/views/pages/user/requests/request_details.dart b/lib/views/pages/user/requests/request_details.dart index d45692d8..598e8f2b 100644 --- a/lib/views/pages/user/requests/request_details.dart +++ b/lib/views/pages/user/requests/request_details.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.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/views/app_style/colors.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/widgets/buttons/app_back_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/requests/info_row.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/titles/app_sub_title.dart'; import 'report/future_service_report.dart'; + class RequestDetailsPage extends StatelessWidget { static final String id = "/call-details"; final ServiceRequest serviceRequest; @@ -42,8 +42,8 @@ class RequestDetailsPage extends StatelessWidget { child: Column( children: [ Container( - color:AColors.primaryColor, - padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), child: Row( children: [ ABackButton(), @@ -51,124 +51,133 @@ class RequestDetailsPage extends StatelessWidget { child: Center( child: Text( _subtitle.details, - style: Theme.of(context).textTheme.headline6.copyWith( - color: AColors.white, - fontStyle: FontStyle.italic - ), + style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), ), ), ), - _userProvider.user.type == UsersTypes.normal_user ? - // AIconButton( - // iconData: Icons.warning_amber_rounded, - // color: AColors.white, - // buttonSize: 42, - // backgroundColor: AColors.deepOrange, - // onPressed: (){ - // Navigator.of(context).push( - // 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( - // context: context, - // barrierDismissible: false, - // builder: (BuildContext context) { - // return CupertinoAlertDialog( - // title: Text(_subtitle.updatingDots), - // content: Center(child: CircularProgressIndicator()), + _userProvider.user.type == UsersTypes.normal_user + ? + // AIconButton( + // iconData: Icons.warning_amber_rounded, + // color: AColors.white, + // buttonSize: 42, + // backgroundColor: AColors.deepOrange, + // onPressed: (){ + // Navigator.of(context).push( + // MaterialPageRoute( + // builder: (_) => ReportIssuesPage(serviceRequest: serviceRequest,) + // ) // ); // }, - // ); - // 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,) + // ) + const SizedBox( + width: 48, + ) + : AIconButton( + iconData: Icons.edit, + color: AColors.white, + buttonSize: 42, + backgroundColor: AColors.green, + onPressed: () async { + Navigator.of(context).push( + MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)), + ); + // 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( + // 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 ? SizedBox.shrink(): - Column( - children: [ - SizedBox(height: 8,), - MaterialButton( - padding: EdgeInsets.zero, - onPressed: (){ - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => Scaffold( - body: InteractiveViewer( - child: Center( - child: ImageLoader( - url: serviceRequest.devicePhotos.first, - boxFit: BoxFit.contain, - ), - ), - ), - ) - ) - ); - }, - child: SizedBox( - height: 140 * AppStyle.getScaleFactor(context), - width: MediaQuery.of(context).size.width, - child: ImageLoader( - url: serviceRequest.devicePhotos.first, - boxFit: BoxFit.cover, - ), - ), - ), - SizedBox(height: 8,), - SizedBox( - height: 60* AppStyle.getScaleFactor(context), - child: ImagesList( - images: serviceRequest.devicePhotos, + serviceRequest.devicePhotos.isEmpty + ? SizedBox.shrink() + : Column( + children: [ + SizedBox( + height: 8, + ), + MaterialButton( + padding: EdgeInsets.zero, + onPressed: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => Scaffold( + body: InteractiveViewer( + child: Center( + child: ImageLoader( + url: serviceRequest.devicePhotos.first, + boxFit: BoxFit.contain, + ), + ), + ), + ))); + }, + child: SizedBox( + height: 140 * AppStyle.getScaleFactor(context), + width: MediaQuery.of(context).size.width, + child: ImageLoader( + url: serviceRequest.devicePhotos.first, + boxFit: BoxFit.cover, + ), + ), + ), + SizedBox( + height: 8, + ), + SizedBox( + height: 60 * AppStyle.getScaleFactor(context), + child: ImagesList( + images: serviceRequest.devicePhotos, + ), + ), + ], ), - ), - ], - ), - - TabBar( - labelColor: AColors.primaryColor, - tabs: [ - Tab(text: _subtitle.general,), - Tab(text: _subtitle.serviceRequestInformation,), + TabBar(labelColor: AColors.primaryColor, tabs: [ + Tab( + text: _subtitle.general, + ), + Tab( + text: _subtitle.serviceRequestInformation, + ), ]), - SizedBox(height: 8,), + SizedBox( + height: 8, + ), Expanded( child: TabBarView( - children: [ ListView( padding: EdgeInsets.symmetric(horizontal: 16), @@ -187,7 +196,7 @@ class RequestDetailsPage extends StatelessWidget { ), RequestInfoRow( title: _subtitle.deviceModel, - info : serviceRequest.deviceModel, + info: serviceRequest.deviceModel, ), RequestInfoRow( title: _subtitle.engineerName, @@ -201,11 +210,12 @@ class RequestDetailsPage extends StatelessWidget { title: _subtitle.date, info: serviceRequest.date, ), - serviceRequest.nextVisitDate == null ? SizedBox.shrink() : - RequestInfoRow( - title: _subtitle.nextVisitDate, - info: DateFormat('EE dd/MM/yyyy').format(serviceRequest.nextVisitDate), - ), + serviceRequest.nextVisitDate == null + ? SizedBox.shrink() + : RequestInfoRow( + title: _subtitle.nextVisitDate, + info: DateFormat('EE dd/MM/yyyy').format(serviceRequest.nextVisitDate), + ), Row( children: [ Expanded( @@ -215,12 +225,12 @@ class RequestDetailsPage extends StatelessWidget { textScaleFactor: AppStyle.getScaleFactor(context), ), ), - StatusLabel(label: serviceRequest.statusLabel, - color: AColors.getRequestStatusColor(serviceRequest.statusValue) - ), + StatusLabel(label: serviceRequest.statusLabel, color: AColors.getRequestStatusColor(serviceRequest.statusValue)), ], ), - Divider(color: Theme.of(context).primaryColor,), + Divider( + color: Theme.of(context).primaryColor, + ), RequestInfoRow( title: _subtitle.hospital, info: serviceRequest.hospitalName, @@ -241,10 +251,10 @@ class RequestDetailsPage extends StatelessWidget { title: _subtitle.maintenanceIssue, content: serviceRequest.maintenanceIssue, ), - if(serviceRequest.audio?.isNotEmpty == true) - ASoundPlayer( - audio: serviceRequest.audio, - ), + if (serviceRequest.audio?.isNotEmpty == true) + ASoundPlayer( + audio: serviceRequest.audio, + ), // // Center( // child: Padding( @@ -286,65 +296,64 @@ class RequestDetailsPage extends StatelessWidget { // ) ], ), - serviceRequest.viewReport ? - ListView( - padding: EdgeInsets.symmetric(horizontal: 16), - children: [ - RequestInfoRow( - title: _subtitle.faultDescription, - content: serviceRequest.faultDescription, - ), - RequestInfoRow( - title: _subtitle.workPerformed, - content: serviceRequest.workPerformed, - ), - RequestInfoRow( - title: _subtitle.visitDate, - info: serviceRequest.visitDate, - ), - RequestInfoRow( - title: _subtitle.jobSheetNumber, - info: serviceRequest.jobSheetNumber, - ), - _userProvider.user.type == UsersTypes.engineer - && serviceRequest.reportID != null? - Padding( - padding: EdgeInsets.all(32), - child: AButton( - text: _subtitle.editServiceReport, - onPressed: (){ - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => FutureServiceReport( - request: serviceRequest, + serviceRequest.viewReport + ? ListView( + padding: EdgeInsets.symmetric(horizontal: 16), + children: [ + RequestInfoRow( + title: _subtitle.faultDescription, + content: serviceRequest.faultDescription, + ), + RequestInfoRow( + title: _subtitle.workPerformed, + content: serviceRequest.workPerformed, + ), + RequestInfoRow( + title: _subtitle.visitDate, + info: serviceRequest.visitDate, + ), + RequestInfoRow( + title: _subtitle.jobSheetNumber, + info: serviceRequest.jobSheetNumber, + ), + _userProvider.user.type == UsersTypes.engineer && serviceRequest.reportID != null + ? Padding( + padding: EdgeInsets.all(32), + child: AButton( + text: _subtitle.editServiceReport, + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => FutureServiceReport( + 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, + )), + ); + }, + ), ), - ); - }, - ), - ): 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), ), - ); - }, - ), - ), - ): Center(child: ASubTitle(_subtitle.noDateFound),), - - ], ), ), diff --git a/lib/views/widgets/requests/service_request_update_dialog.dart b/lib/views/widgets/requests/service_request_update_dialog.dart index e2680384..ce8cae93 100644 --- a/lib/views/widgets/requests/service_request_update_dialog.dart +++ b/lib/views/widgets/requests/service_request_update_dialog.dart @@ -54,8 +54,7 @@ class _ServiceRequestsUpdateDialogState extends State(context); + final userProvider = Provider.of(context); + final menuProvider = Provider.of(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, + ), + ); + } +} diff --git a/lib/views/widgets/status/service_request/service_request_loan_availability.dart b/lib/views/widgets/status/service_request/service_request_loan_availability.dart new file mode 100644 index 00000000..31cb3f33 --- /dev/null +++ b/lib/views/widgets/status/service_request/service_request_loan_availability.dart @@ -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(context); + final userProvider = Provider.of(context); + final menuProvider = Provider.of(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, + )); + } +}