diff --git a/assets/images/sub_workorder_icon.svg b/assets/images/sub_workorder_icon.svg new file mode 100644 index 00000000..4400caae --- /dev/null +++ b/assets/images/sub_workorder_icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 4dc9dc73..86794228 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -36,6 +36,9 @@ class URLs { static get getRepairLocation => "$_baseUrl/Lookups/GetLookup?lookupEnum=504"; static get equipmentStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; + static get getDateOperators => "$_baseUrl/Lookups/GetLookup?lookupEnum=200"; + static get getMaintenanceSituation => "$_baseUrl/Lookups/GetLookup?lookupEnum=502"; + static get getAllUsers => "http://109.123.243.118:5000/api/Account/GetAllUsers"; static get getPreventiveMaintenanceVisits => "$_baseUrl/return/user/calibrations"; // get static get updatePreventiveMaintenanceVisits => "$_baseUrl/Visit/UpdateVisits"; // get diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index a044543d..3334332b 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -7,6 +7,7 @@ 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/call_request_for_work_order_model.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'; @@ -557,4 +558,48 @@ class ServiceRequestsProvider extends ChangeNotifier { return {}; } } + + Future> searchForWorkOrders( + SearchWorkOrders search, + String callerId, + Lookup dateOperator, + String site, + ) async { + Response response; + try { + var body = { + "pageSize": pageItemNumber, + "pageNumber": ((workOrders?.length ?? 0) ~/ pageItemNumber) + 1, + if (callerId?.isNotEmpty ?? false) "callId": callerId, + if (search.assetType != null) "assetSerialNo": search.assetType, + if (search.id != null) "workOrderNo": search.id?.toString(), + if (search.calllastSituation != null) "callslastSituationWO": search.calllastSituation.toMap(), + if (search.assignedEmployee != null) + "assignedEmployees": [ + search.assignedEmployee.id, + ], + // "statusWO": [], + if (site?.isNotEmpty ?? false) "site": site, + if (search.visitDate != null && dateOperator != null) "visitDateSymbol": dateOperator?.toMap(), + if (search.visitDate != null && dateOperator != null) "visitDateFrom": search.visitDate, + }; + print(body); + response = await ApiManager.instance.post(URLs.searchWorkOrders, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List workOrdersJson = json.decode(response.body)["data"]; + print(workOrdersJson); + workOrders = workOrdersJson.map((request) => SearchWorkOrders.fromJson(request)).toList(); + if (workOrders.length == pageItemNumber) { + nextPage = true; + } else { + nextPage = false; + } + } + return workOrders; + } catch (e) { + return []; + } + } } diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart new file mode 100644 index 00000000..1041a2a2 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart @@ -0,0 +1,75 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/lookup.dart'; + +class ServiceReportMaintenanceSituationProvider extends ChangeNotifier { + //reset provider data + void reset() { + _calls = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _calls; + List get operators => _calls; + + // 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 getOperators() async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + "${URLs.getMaintenanceSituation}", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + _calls = categoriesListJson.map((type) => Lookup.fromJson(type)).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/report/service_report_users_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart new file mode 100644 index 00000000..42132b29 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart @@ -0,0 +1,75 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/engineer.dart'; + +class ServiceReportUsersProvider extends ChangeNotifier { + //reset provider data + void reset() { + _calls = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _calls; + List get users => _calls; + + // 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 getAllUsers() async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + "${URLs.getAllUsers}", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List usersListJson = json.decode(response.body); + _calls = usersListJson.map((type) => Engineer.fromJson(type)).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/report/service_report_visit_date_operator_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart new file mode 100644 index 00000000..dc8d7855 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart @@ -0,0 +1,75 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/lookup.dart'; + +class ServiceReportVisitOperatorProvider extends ChangeNotifier { + //reset provider data + void reset() { + _calls = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _calls; + List get operators => _calls; + + // 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 getOperators() async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + "${URLs.getDateOperators}", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + _calls = categoriesListJson.map((type) => Lookup.fromJson(type)).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 3d85f355..c6ffff50 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -23,7 +23,10 @@ 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_equipment_status_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_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_users_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_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'; @@ -33,6 +36,7 @@ import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/pages/login.dart'; import 'package:test_sa/views/pages/register.dart'; import 'package:test_sa/views/pages/splash_screen.dart'; +import 'package:test_sa/views/pages/sub_workorder/sub_workorder_page.dart'; import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/land_page.dart'; @@ -121,6 +125,9 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()), ChangeNotifierProvider(create: (_) => ServiceReportRepairLocationProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestFaultDescriptionProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportVisitOperatorProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportMaintenanceSituationProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportUsersProvider()), ], child: GestureDetector( onTap: () { @@ -172,6 +179,7 @@ class MyApp extends StatelessWidget { TrackGasRefillPage.id: (_) => const TrackGasRefillPage(), RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(), TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(), + SubWorkOrderPage.id: (_) => const SubWorkOrderPage(), }, ), ), diff --git a/lib/views/pages/sub_workorder/sub_workorder_page.dart b/lib/views/pages/sub_workorder/sub_workorder_page.dart new file mode 100644 index 00000000..4aeaa1be --- /dev/null +++ b/lib/views/pages/sub_workorder/sub_workorder_page.dart @@ -0,0 +1,207 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; +import 'package:test_sa/models/engineer.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; +import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/views/widgets/app_text_form_field.dart'; +import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; + +import '../../../controllers/api_routes/http_status_manger.dart'; +import '../../../controllers/localization/localization.dart'; +import '../../app_style/colors.dart'; +import '../../widgets/buttons/app_back_button.dart'; +import '../../widgets/buttons/app_button.dart'; +import '../../widgets/loaders/app_loading.dart'; +import '../../widgets/status/report/service_report_all_users.dart'; +import '../../widgets/status/report/service_report_maintenance_situation.dart'; +import '../../widgets/status/report/service_report_visit_date_operator.dart'; +import '../../widgets/titles/app_sub_title.dart'; + +class SubWorkOrderPage extends StatefulWidget { + static String id = "/SubWorkOrderPage"; + const SubWorkOrderPage({Key key}) : super(key: key); + + @override + State createState() => _SubWorkOrderPageState(); +} + +class _SubWorkOrderPageState extends State { + final GlobalKey _formKey = GlobalKey(); + final SearchWorkOrders _searchWorkOrders = SearchWorkOrders(); + Subtitle _subtitle; + bool _isLoading = false; + String _callerId = "", _site = ""; + Lookup _dateOperator; + @override + Widget build(BuildContext context) { + _subtitle = AppLocalization.of(context).subtitle; + return Scaffold( + body: SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + Container( + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Column( + children: [ + Row( + children: [ + const ABackButton(), + Expanded( + child: Center( + child: Text( + "Search Work Order", + style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), + ), + ), + ), + const SizedBox( + width: 48, + ) + ], + ), + ], + ), + ), + const SizedBox(height: 8), + Form( + key: _formKey, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ATextFormField( + labelText: "Caller ID", + onSaved: (value) { + _callerId = value; + }, + ), + const SizedBox(height: 16), + ATextFormField( + labelText: "Asset S.N.", + textInputType: TextInputType.number, + onSaved: (value) { + _searchWorkOrders.assetType = value; + }, + ), + const SizedBox(height: 16), + ATextFormField( + labelText: "Work Order No.", + onSaved: (value) { + _searchWorkOrders.workOrderNo = value; + }, + ), + const SizedBox(height: 16), + ASubTitle(_subtitle.assignedEmployee), + const SizedBox(height: 4), + ServiceReportAllUsers( + initialValue: _searchWorkOrders.assignedEmployee == null ? null : Engineer(id: _searchWorkOrders.assignedEmployee.id, name: _searchWorkOrders.assignedEmployee.name), + onSelect: (engineer) { + _searchWorkOrders.assignedEmployee = AssignedEmployee(id: engineer.id, name: engineer.name); + }, + ), + const SizedBox(height: 16), + const ASubTitle("Maintenance Situation"), + const SizedBox(height: 4), + ServiceReportMaintenanceSituation( + initialValue: _searchWorkOrders.calllastSituation, + onSelect: (status) { + if (status?.value == 12 || _searchWorkOrders.calllastSituation?.value == 12) { + _searchWorkOrders.calllastSituation = status; + setState(() {}); + } else { + _searchWorkOrders.calllastSituation = status; + } + }, + ), + const SizedBox(height: 16), + ATextFormField( + labelText: "Site", + onSaved: (value) { + _site = value; + }, + ), + const SizedBox(height: 16), + ASubTitle(_subtitle.visitDate), + const SizedBox(height: 4), + ServiceReportVisitDateOperator( + initialValue: _dateOperator, + onSelect: (status) { + _dateOperator = status; + }, + ), + Row( + children: [ + Expanded( + child: ADatePicker( + date: DateTime.tryParse(_searchWorkOrders.visitDate ?? ""), + from: DateTime(1950), + onDatePicker: (date) { + _searchWorkOrders.visitDate = date?.toIso8601String(); + setState(() {}); + }, + ), + ), + ], + ), + ], + ), + ), + ), + const SizedBox(height: 100), + ], + ), + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: _isLoading + ? const ALoading() + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: AButton( + text: _subtitle.search, + onPressed: () async { + _isLoading = true; + setState(() {}); + if (_formKey.currentState?.validate() ?? false) {} + _formKey.currentState?.save(); + final serviceRequestsProvider = Provider.of(context, listen: false); + final List woList = await serviceRequestsProvider.searchForWorkOrders( + _searchWorkOrders, + _callerId, + _dateOperator, + _site, + ); + _isLoading = false; + setState(() {}); + if (serviceRequestsProvider.stateCode >= 200 && serviceRequestsProvider.stateCode < 300) { + Fluttertoast.showToast(msg: _subtitle.requestCompleteSuccessfully); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => Scaffold( + body: ListView.builder( + itemCount: woList.length, + shrinkWrap: true, + itemBuilder: (context, index) => Text( + woList[index].id?.toString(), + ), + ), + ), + ), + ); + } else { + String errorMessage = HttpStatusManger.getStatusMessage(status: serviceRequestsProvider.stateCode, subtitle: _subtitle); + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage))); + } + }, + ), + ), + ); + } +} diff --git a/lib/views/pages/user/land_page.dart b/lib/views/pages/user/land_page.dart index ba49b91b..d4a56737 100644 --- a/lib/views/pages/user/land_page.dart +++ b/lib/views/pages/user/land_page.dart @@ -23,6 +23,7 @@ import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/pages/device_transfer/request_device_transfer.dart'; import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart'; +import 'package:test_sa/views/pages/sub_workorder/sub_workorder_page.dart'; import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/requests/create_request.dart'; @@ -211,6 +212,14 @@ class _LandPageState extends State { Navigator.of(context).pushNamed(TrackDeviceTransferPage.id); }, ), + // if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.engineer) + LandPageItem( + text: "Search Work Order", + svgPath: "assets/images/sub_workorder_icon.svg", + onPressed: () { + Navigator.of(context).pushNamed(SubWorkOrderPage.id); + }, + ), ], ), ], diff --git a/lib/views/pages/user/requests/request_details.dart b/lib/views/pages/user/requests/request_details.dart index 36f3f948..03a71d01 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'; @@ -21,7 +20,6 @@ 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'; @@ -308,111 +306,114 @@ class RequestDetailsPage extends StatelessWidget { workOrders = snap.data as List; if (snap.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator()); if (snap.connectionState == ConnectionState.done && (snap.data?.length ?? 0) != 0) { - return ListView.separated( - padding: EdgeInsets.all(21), - itemCount: workOrders.length, - separatorBuilder: (czt, index) => 21.height, - itemBuilder: (context, index) { - Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; - Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; + return SingleChildScrollView( + child: Column( + children: [ + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.all(21), + itemCount: workOrders.length, + separatorBuilder: (czt, index) => 21.height, + itemBuilder: (context, index) { + Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; + Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; - return ElevatedButton( - style: ElevatedButton.styleFrom( - padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), - primary: itemColor.withOpacity(.7), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), - ), - ), - //padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8), - onPressed: () { - // onPressed(request); - }, - child: Column( - children: [ - RequestInfoRow( - title: _subtitle.callId, - content: serviceRequest.requestCode, - ), - RequestInfoRow( - title: _subtitle.orderWorkNumber, - info: workOrders[index].workOrderNo.toString(), - ), - RequestInfoRow( - title: _subtitle.visitDate, - info: workOrders[index].visitDate, - ), - RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee.name), - RequestInfoRow( - title: _subtitle.assetSN, - info: workOrders[index].callRequest.asset.assetSerialNo, - ), - RequestInfoRow( - title: _subtitle.assetName, - info: workOrders[index].callRequest.asset.modelDefinition.assetName, - ), - RequestInfoRow( - title: _subtitle.model, - info: workOrders[index].callRequest.asset.modelDefinition.modelName, - ), - RequestInfoRow( - title: _subtitle.site, - info: workOrders[index].callRequest.asset.site.custName, - ), - RequestInfoRow( - title: _subtitle.maintenanceSituation, - info: workOrders[index].calllastSituation.name ?? '', - ), - RequestInfoRow( - title: _subtitle.currentSituation, - info: workOrders[index].currentSituation.name ?? '', - ), - _userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null - ? Padding( - padding: EdgeInsets.all(32), - child: AButton( - text: _subtitle.editServiceReport, - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => FutureServiceReport( - request: serviceRequest, - workOrder: workOrders[index], - )), - ); - }, - ), - ) - : SizedBox.shrink(), - ], - ), - ); - }, - ); - } else { - return _userProvider.user.type == UsersTypes.engineer - ? Center( - child: Padding( - padding: EdgeInsets.all(32), - child: AButton( - text: "Create Report", + return ElevatedButton( + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), + primary: itemColor.withOpacity(.7), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + ), + ), + //padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8), onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => CreateServiceReport( - request: serviceRequest, - )), - ); + // onPressed(request); }, + child: Column( + children: [ + RequestInfoRow( + title: _subtitle.callId, + content: serviceRequest.requestCode, + ), + RequestInfoRow( + title: _subtitle.orderWorkNumber, + info: workOrders[index].workOrderNo.toString(), + ), + RequestInfoRow( + title: _subtitle.visitDate, + info: workOrders[index].visitDate, + ), + RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee.name), + RequestInfoRow( + title: _subtitle.assetSN, + info: workOrders[index].callRequest.asset.assetSerialNo, + ), + RequestInfoRow( + title: _subtitle.assetName, + info: workOrders[index].callRequest.asset.modelDefinition.assetName, + ), + RequestInfoRow( + title: _subtitle.model, + info: workOrders[index].callRequest.asset.modelDefinition.modelName, + ), + RequestInfoRow( + title: _subtitle.site, + info: workOrders[index].callRequest.asset.site.custName, + ), + RequestInfoRow( + title: _subtitle.maintenanceSituation, + info: workOrders[index].calllastSituation.name ?? '', + ), + RequestInfoRow( + title: _subtitle.currentSituation, + info: workOrders[index].currentSituation.name ?? '', + ), + _userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null + ? Padding( + padding: EdgeInsets.all(32), + child: AButton( + text: _subtitle.editServiceReport, + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => FutureServiceReport( + request: serviceRequest, + workOrder: workOrders[index], + )), + ); + }, + ), + ) + : SizedBox.shrink(), + ], + ), + ); + }, + ), + if (_userProvider.user.type == UsersTypes.engineer) + Center( + child: Padding( + padding: const EdgeInsets.all(32), + child: AButton( + text: "Create Report", + onPressed: () { + Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); + }, + ), ), ), - ) - : Center( - child: ASubTitle(_subtitle.noDateFound), - ); + ], + ), + ); + } else { + return Center( + child: ASubTitle(_subtitle.noDateFound), + ); } }, - ) + ), ], ), ), diff --git a/lib/views/widgets/land_page/land_page_item.dart b/lib/views/widgets/land_page/land_page_item.dart index a3085e65..10b7ff05 100644 --- a/lib/views/widgets/land_page/land_page_item.dart +++ b/lib/views/widgets/land_page/land_page_item.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; @@ -6,8 +7,8 @@ class LandPageItem extends StatelessWidget { final String text; final IconData icon; final VoidCallback onPressed; - - const LandPageItem({Key key, this.text, this.icon, this.onPressed}) : super(key: key); + final String svgPath; + const LandPageItem({Key key, this.svgPath, this.text, this.icon, this.onPressed}) : super(key: key); @override Widget build(BuildContext context) { @@ -30,12 +31,20 @@ class LandPageItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Icon( - icon, - color: AColors.primaryColor, - size: 42 * AppStyle.getScaleFactor(context), - ), - Text(text, style: TextStyle(color: AColors.grey3A)), + if (icon != null) + Icon( + icon, + color: AColors.primaryColor, + size: 42 * AppStyle.getScaleFactor(context), + ), + if (svgPath != null) + SvgPicture.asset( + svgPath, + width: 42 * AppStyle.getScaleFactor(context), + height: 42 * AppStyle.getScaleFactor(context), + color: AColors.primaryColor, + ), + Text(text, style: const TextStyle(color: AColors.grey3A)), ], ), ), diff --git a/lib/views/widgets/status/report/service_report_all_users.dart b/lib/views/widgets/status/report/service_report_all_users.dart new file mode 100644 index 00000000..981806f8 --- /dev/null +++ b/lib/views/widgets/status/report/service_report_all_users.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart'; +import 'package:test_sa/models/engineer.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import 'package:test_sa/views/widgets/status/users_menu.dart'; + +class ServiceReportAllUsers extends StatelessWidget { + final Function(Engineer) onSelect; + final Engineer initialValue; + const ServiceReportAllUsers({Key key, @required this.onSelect, this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportUsersProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.users == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + menuProvider.getAllUsers(); + }, + child: UsersMenu( + initialStatus: initialValue, + statuses: menuProvider.users, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/report/service_report_maintenance_situation.dart b/lib/views/widgets/status/report/service_report_maintenance_situation.dart new file mode 100644 index 00000000..936a2284 --- /dev/null +++ b/lib/views/widgets/status/report/service_report_maintenance_situation.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_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'; + +class ServiceReportMaintenanceSituation extends StatelessWidget { + final Function(Lookup) onSelect; + final Lookup initialValue; + + const ServiceReportMaintenanceSituation({Key key, @required this.onSelect, @required this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportMaintenanceSituationProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.operators == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + menuProvider.getOperators(); + }, + child: SingleStatusMenu( + initialStatus: initialValue, + statuses: menuProvider.operators, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/report/service_report_visit_date_operator.dart b/lib/views/widgets/status/report/service_report_visit_date_operator.dart new file mode 100644 index 00000000..5148ffaa --- /dev/null +++ b/lib/views/widgets/status/report/service_report_visit_date_operator.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_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'; + +class ServiceReportVisitDateOperator extends StatelessWidget { + final Function(Lookup) onSelect; + final Lookup initialValue; + + const ServiceReportVisitDateOperator({Key key, @required this.onSelect, @required this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportVisitOperatorProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.operators == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + menuProvider.getOperators(); + }, + child: SingleStatusMenu( + initialStatus: initialValue, + statuses: menuProvider.operators, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/users_menu.dart b/lib/views/widgets/status/users_menu.dart new file mode 100644 index 00000000..8ffad745 --- /dev/null +++ b/lib/views/widgets/status/users_menu.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; + +import '../../../models/engineer.dart'; + +class UsersMenu extends StatefulWidget { + final List statuses; + final Engineer initialStatus; + final Function(Engineer) onSelect; + + const UsersMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); + + @override + _SingleUsersMenuState createState() => _SingleUsersMenuState(); +} + +class _SingleUsersMenuState extends State { + Engineer _selectedStatus; + + @override + void setState(VoidCallback fn) { + if (mounted) super.setState(fn); + } + + @override + void didUpdateWidget(covariant UsersMenu oldWidget) { + if (widget.initialStatus != null) { + final result = widget.statuses?.where((element) { + return element == widget.initialStatus; + }); + if (result.isNotEmpty) { + _selectedStatus = result.first; + } else { + _selectedStatus = null; + } + if ((widget.initialStatus?.id ?? "") != (_selectedStatus?.id ?? "")) { + widget.onSelect(_selectedStatus); + } + } else { + _selectedStatus = null; + } + super.didUpdateWidget(oldWidget); + } + + @override + void initState() { + if (widget.initialStatus != null) { + final result = widget.statuses?.where((element) { + return element == widget.initialStatus; + }); + if (result.isNotEmpty) _selectedStatus = result.first; + if (widget.initialStatus.id != _selectedStatus?.id) { + widget.onSelect(_selectedStatus); + } + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: const [ + // AppStyle.boxShadow + // ] + ), + child: DropdownButton( + value: _selectedStatus, + iconSize: 24, + icon: const Icon(Icons.keyboard_arrow_down_rounded), + elevation: 0, + isExpanded: true, + hint: Text( + "Select", + style: Theme.of(context).textTheme.subtitle1, + ), + style: TextStyle(color: Theme.of(context).primaryColor), + underline: SizedBox.shrink(), + onChanged: (Engineer newValue) { + setState(() { + _selectedStatus = newValue; + }); + widget.onSelect(newValue); + }, + items: widget.statuses.map>((Engineer value) { + return DropdownMenuItem( + value: value, + child: Text( + value.name, + style: Theme.of(context).textTheme.subtitle1.copyWith( + color: Theme.of(context).primaryColor, + fontSize: 11, + //fontWeight: FontWeight.bold + ), + ), + ); + }).toList(), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 99885208..4f82161b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,7 @@ dependencies: audioplayers: ^1.1.1 flare_flutter: ^3.0.2 signature: ^5.3.0 + flutter_svg: ^1.1.6 dev_dependencies: