From e32de37209acd9c492a330cae7060d326f6c2a13 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Mon, 21 Aug 2023 09:51:41 +0300 Subject: [PATCH 1/3] Improve most recent filter --- .../providers/api/device_transfer_provider.dart | 8 ++------ .../providers/api/gas_refill_provider.dart | 1 + .../providers/api/regular_visits_provider.dart | 15 ++++++++------- .../providers/api/service_requests_provider.dart | 5 +++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/controllers/providers/api/device_transfer_provider.dart b/lib/controllers/providers/api/device_transfer_provider.dart index cdd685b..289fd41 100644 --- a/lib/controllers/providers/api/device_transfer_provider.dart +++ b/lib/controllers/providers/api/device_transfer_provider.dart @@ -74,10 +74,7 @@ class DeviceTransferProvider extends ChangeNotifier { body["pageSize"] = pageItemNumber; body.addAll(deviceTransferSearch.toMap()); - response = await ApiManager.instance.post( - URLs.getDeviceTransfer, - body: body, - ); + response = await ApiManager.instance.post(URLs.getDeviceTransfer, body: body); stateCode = response.statusCode; if (stateCode >= 200 && stateCode < 300) { @@ -87,8 +84,7 @@ class DeviceTransferProvider extends ChangeNotifier { items ??= []; items.addAll(itemsPage.toSet().toList()); sortMostRecent(items, deviceTransferSearch.mostRecent); - - print(listJson); + notifyListeners(); if (itemsPage.length == pageItemNumber) { nextPage = true; } else { diff --git a/lib/controllers/providers/api/gas_refill_provider.dart b/lib/controllers/providers/api/gas_refill_provider.dart index 40a9620..5237998 100644 --- a/lib/controllers/providers/api/gas_refill_provider.dart +++ b/lib/controllers/providers/api/gas_refill_provider.dart @@ -77,6 +77,7 @@ class GasRefillProvider extends ChangeNotifier { } items.addAll(itemsPage); sortMostRecent(items, mostRecent); + notifyListeners(); if (itemsPage.length == pageItemNumber) { nextPage = true; } else { diff --git a/lib/controllers/providers/api/regular_visits_provider.dart b/lib/controllers/providers/api/regular_visits_provider.dart index 25e330f..6688347 100644 --- a/lib/controllers/providers/api/regular_visits_provider.dart +++ b/lib/controllers/providers/api/regular_visits_provider.dart @@ -13,7 +13,7 @@ import 'package:test_sa/models/visits/visits_search.dart'; class RegularVisitsProvider extends ChangeNotifier { // number of items call in each request - final pageItemNumber = 20; + final pageItemNumber = 12; //reset provider data void reset() { @@ -52,7 +52,7 @@ class RegularVisitsProvider extends ChangeNotifier { }) async { if (isLoading == true) return -2; isLoading = true; - if (visits == null) notifyListeners(); + if (visits?.isEmpty ?? true) notifyListeners(); Response response; //userId = 397.toString(); // testing id to view data @@ -77,11 +77,12 @@ class RegularVisitsProvider extends ChangeNotifier { // client's request was successfully received try { List requestsListJson = json.decode(response.body)["data"]; - List _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); - visits ??= []; - sortMostRecent(_visits); - visits.addAll(_visits); - if (_visits.length == pageItemNumber) { + List visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); + this.visits ??= []; + this.visits.addAll(visits); + sortMostRecent(this.visits); + notifyListeners(); + if (visits.length == pageItemNumber) { nextPage = true; } else { nextPage = false; diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index ea03c7e..54dbee7 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -57,7 +57,7 @@ class ServiceRequestsProvider extends ChangeNotifier { Future getRequests({@required int hospitalId}) async { if (isLoading == true) return -2; isLoading = true; - if (serviceRequests == null) notifyListeners(); + if (serviceRequests?.isEmpty ?? false) notifyListeners(); Response response; try { Map body = {}; @@ -76,8 +76,9 @@ class ServiceRequestsProvider extends ChangeNotifier { List requestsListJson = json.decode(response.body)["data"]; List serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList(); serviceRequests ??= []; - sortMostRecent(serviceRequestsPage); serviceRequests.addAll(serviceRequestsPage); + sortMostRecent(serviceRequests); + notifyListeners(); if (serviceRequestsPage.length == pageItemNumber) { nextPage = true; } else { From 5aedb12004fd6a2631b749b88a915176b6419ad9 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Mon, 21 Aug 2023 15:32:29 +0300 Subject: [PATCH 2/3] Vendor Fields Have Been Added --- lib/controllers/api_routes/urls.dart | 1 + .../report/vendor_provider.dart | 53 ++++++++ lib/main.dart | 10 +- .../service_request/search_work_order.dart | 17 ++- .../auto_generated_vendor_name.dart | 85 +++++++++++++ .../create_sub_workorder_page.dart | 2 +- .../work_order_details_bottom_sheet.dart | 50 +++++++- .../supplier_engineers_menu.dart | 118 ++++++++++++++++++ 8 files changed, 329 insertions(+), 7 deletions(-) create mode 100644 lib/controllers/providers/api/status_drop_down/report/vendor_provider.dart create mode 100644 lib/views/pages/sub_workorder/auto_generated_vendor_name.dart create mode 100644 lib/views/widgets/status/service_request/supplier_engineers_menu.dart diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index a587fb7..33eef04 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -51,6 +51,7 @@ class URLs { static get updateRegularVisits => "$_baseUrl/Visit/UpdateVisits"; // get static get getSingleServiceRequest => "$_baseUrl/return/call/information"; // get + static get getSuppliersAutoComplete => "$_baseUrl/Supplier/GetSuppliersAutoComplete"; static get getNotifications => "$_baseUrl/return/user/notification"; // get static get getRecentNotifications => "$_baseUrl/return/user/recent/notification"; // get static get createRequest => "$_baseUrl/CallRequest/AddCallRequest"; // get diff --git a/lib/controllers/providers/api/status_drop_down/report/vendor_provider.dart b/lib/controllers/providers/api/status_drop_down/report/vendor_provider.dart new file mode 100644 index 0000000..4271e00 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/vendor_provider.dart @@ -0,0 +1,53 @@ +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/service_request/search_work_order.dart'; + +class VendorProvider extends ChangeNotifier { + void reset() { + _vendors = null; + _loading = null; + _stateCode = null; + } + + int _stateCode; + int get stateCode => _stateCode; + + List _vendors; + List get vendors => _vendors; + + bool _loading; + bool get isLoading => _loading; + set isLoading(bool isLoading) { + _loading = isLoading; + notifyListeners(); + } + + Future getVendors(String text) async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get("${URLs.getSuppliersAutoComplete}?searchText=$text"); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List suppliersJson = json.decode(response.body)["data"]; + _vendors = suppliersJson.map((type) => Supplier.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 466e052..03427e4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -63,6 +63,7 @@ import 'controllers/providers/api/status_drop_down/report/service_report_repair_ import 'controllers/providers/api/status_drop_down/report/service_report_status_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_types_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_types_provider.dart'; +import 'controllers/providers/api/status_drop_down/report/vendor_provider.dart'; import 'controllers/providers/api/user_provider.dart'; import 'controllers/providers/settings/setting_provider.dart'; import 'views/pages/device_transfer/request_device_transfer.dart'; @@ -81,15 +82,17 @@ void main() async { } runApp(ChangeNotifierProvider( create: (_) => SettingProvider(), - child: MyApp(), + child: const MyApp(), )); } class MyApp extends StatelessWidget { + const MyApp({Key key}) : super(key: key); + // This widget is the root of your application. @override Widget build(BuildContext context) { - final _settingProvider = Provider.of(context); + final settingProvider = Provider.of(context); return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => UserProvider()), @@ -131,6 +134,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => ServiceReportMaintenanceSituationProvider()), ChangeNotifierProvider(create: (_) => ServiceReportUsersProvider()), ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()), + ChangeNotifierProvider(create: (_) => VendorProvider()), ], child: GestureDetector( onTap: () { @@ -160,7 +164,7 @@ class MyApp extends StatelessWidget { Locale('en'), Locale('ar'), ], - locale: Locale(_settingProvider.language ?? 'en'), + locale: Locale(settingProvider.language ?? 'en'), initialRoute: SplashScreen.id, routes: { SplashScreen.id: (_) => const SplashScreen(), diff --git a/lib/models/service_request/search_work_order.dart b/lib/models/service_request/search_work_order.dart index 7f4efa5..564b7dd 100644 --- a/lib/models/service_request/search_work_order.dart +++ b/lib/models/service_request/search_work_order.dart @@ -286,7 +286,7 @@ class SearchWorkOrder { if (repairLocation?.id != null) { map['repairLocation'] = repairLocation.toMap(); } - if (reason != null) { + if (reason != null && reason.id != null) { map['reason'] = reason.toMap(); } // map['startofWorkTime'] = startofWorkTime; @@ -308,7 +308,7 @@ class SearchWorkOrder { if (attachmentsWorkOrder != null) { map['attachmentsWorkOrder'] = attachmentsWorkOrder.map((v) => v.toJson()).toList(); } - if (equipmentStatus != null) { + if (equipmentStatus != null && equipmentStatus.id != null) { map['equipmentStatus'] = equipmentStatus.toMap(); } if (suppEngineerWorkOrders != null) { @@ -2719,29 +2719,42 @@ class Supplier { Supplier({ this.id, this.suppliername, + this.suppPersons, }); Supplier.fromJson(dynamic json) { id = json['id']; suppliername = json['suppliername']; + if (json['suppPersons'] != null) { + suppPersons = []; + json['suppPersons'].forEach((v) { + suppPersons.add(SuppPersons.fromJson(v)); + }); + } } num id; String suppliername; + List suppPersons; SupplierModel copyWith({ num id, String suppliername, + List suppPersons, }) => SupplierModel( id: id ?? this.id, suppliername: suppliername ?? this.suppliername, + suppPersons: suppPersons ?? this.suppPersons, ); Map toJson() { final map = {}; map['id'] = id ?? 0; map['suppliername'] = suppliername; + if (suppPersons != null) { + map['suppPersons'] = suppPersons.map((v) => v.toJson()).toList(); + } return map; } } diff --git a/lib/views/pages/sub_workorder/auto_generated_vendor_name.dart b/lib/views/pages/sub_workorder/auto_generated_vendor_name.dart new file mode 100644 index 0000000..41244de --- /dev/null +++ b/lib/views/pages/sub_workorder/auto_generated_vendor_name.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_typeahead/flutter_typeahead.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; + +import '../../../controllers/providers/api/status_drop_down/report/vendor_provider.dart'; +import '../../app_style/colors.dart'; +import '../../app_style/sizing.dart'; + +class AutoGeneratedVendorName extends StatefulWidget { + final String initialValue; + final Function(Supplier) onSearch; + const AutoGeneratedVendorName({Key key, this.initialValue, this.onSearch}) : super(key: key); + + @override + State createState() => _AutoGeneratedVendorNameState(); +} + +class _AutoGeneratedVendorNameState extends State { + TextEditingController _controller; + + @override + void initState() { + super.initState(); + _controller = TextEditingController(text: widget.initialValue ?? ""); + } + + @override + void didUpdateWidget(covariant AutoGeneratedVendorName oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.initialValue != widget.initialValue) { + _controller = TextEditingController(text: widget.initialValue ?? ""); + } + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final vendorProvider = Provider.of(context, listen: false); + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: const Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: [ + // AppStyle.boxShadow + // ] + ), + child: TypeAheadField( + textFieldConfiguration: TextFieldConfiguration( + style: Theme.of(context).textTheme.titleLarge, + controller: _controller, + textAlign: TextAlign.center, + decoration: const InputDecoration( + hintText: "Vendor Name", + border: InputBorder.none, + disabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + textInputAction: TextInputAction.search, + ), + suggestionsCallback: (vale) async { + await vendorProvider.getVendors(_controller.text.trim()); + return vendorProvider.vendors; + }, + itemBuilder: (context, vendor) { + return ListTile(title: Text(vendor.suppliername)); + }, + onSuggestionSelected: (hospital) { + widget.onSearch(hospital); + }, + ), + ); + } +} diff --git a/lib/views/pages/sub_workorder/create_sub_workorder_page.dart b/lib/views/pages/sub_workorder/create_sub_workorder_page.dart index fdfd67e..f022539 100644 --- a/lib/views/pages/sub_workorder/create_sub_workorder_page.dart +++ b/lib/views/pages/sub_workorder/create_sub_workorder_page.dart @@ -58,6 +58,7 @@ class _CreateSubWorkOrderPageState extends State { callRequest: CallRequest(id: widget?.workOrder?.callRequest?.id), currentSituation: null, supplier: null, + parentWOId: widget.workOrder.id, ); _serviceReport = ServiceReport(id: widget.workOrder.id, type: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus); _isLoading = true; @@ -313,7 +314,6 @@ class _CreateSubWorkOrderPageState extends State { child: AButton( text: subtitle.create, onPressed: () async { - _subWorkOrders.parentWOId = widget.workOrder.id; _validate = true; setState(() {}); if (validate()) { diff --git a/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart b/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart index e91de02..ab6ff1b 100644 --- a/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart +++ b/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart @@ -8,11 +8,13 @@ import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart'; import 'package:test_sa/views/widgets/status/report/service_report_maintenance_situation.dart'; import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart'; +import 'package:test_sa/views/widgets/status/service_request/supplier_engineers_menu.dart'; import '../../../controllers/localization/localization.dart'; import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart'; import '../../widgets/timer/app_timer.dart'; import '../../widgets/titles/app_sub_title.dart'; +import 'auto_generated_vendor_name.dart'; class WorkOrderDetailsBottomSheet extends StatefulWidget { final SearchWorkOrder subWorkOrder; @@ -25,12 +27,18 @@ class WorkOrderDetailsBottomSheet extends StatefulWidget { class _WorkOrderDetailsBottomSheetState extends State { final GlobalKey _formKey = GlobalKey(); final SearchWorkOrder _workOrder = SearchWorkOrder(); + bool _showVendorFields = false; + SuppEngineerWorkOrders engineer; @override void initState() { super.initState(); _workOrder.copyFrom(widget.subWorkOrder); + if (_workOrder.calllastSituation?.name?.toLowerCase()?.contains("under repair-vendor") ?? false) { + _showVendorFields = true; + _workOrder.supplier ??= SupplierModel(id: _workOrder?.supplier?.id); + } if (context.mounted) { Provider.of(context, listen: false).reset(); } @@ -118,6 +126,14 @@ class _WorkOrderDetailsBottomSheetState extends State engineers; + final SuppEngineerWorkOrders initialValue; + final Function(SuppEngineerWorkOrders) onSelect; + + const SupplierEngineersMenu({Key key, this.engineers, this.onSelect, this.initialValue}) : super(key: key); + + @override + SingleAssistantEmployeeMenuState createState() => SingleAssistantEmployeeMenuState(); +} + +class SingleAssistantEmployeeMenuState extends State { + SuppPersons _selectedEngineer; + + @override + void setState(VoidCallback fn) { + if (mounted) super.setState(fn); + } + + @override + void didUpdateWidget(covariant SupplierEngineersMenu oldWidget) { + if (widget.initialValue != null) { + final result = widget.engineers?.where((element) { + return element?.id == widget.initialValue?.supplierContactId; + }); + if (result.isNotEmpty) { + _selectedEngineer = result.first; + } else { + _selectedEngineer = null; + } + if ((widget.initialValue?.supplierContactId ?? "") != (_selectedEngineer?.id ?? "")) { + onSelect(_selectedEngineer); + } + } else { + _selectedEngineer = null; + } + super.didUpdateWidget(oldWidget); + } + + @override + void initState() { + if (widget.initialValue != null) { + final result = widget.engineers?.where((element) { + return element?.id == widget.initialValue?.supplierContactId; + }); + if (result.isNotEmpty) _selectedEngineer = result.first; + if (widget.initialValue?.supplierContactId != _selectedEngineer?.id) { + onSelect(_selectedEngineer); + } + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: const Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: const [ + // AppStyle.boxShadow + // ] + ), + child: DropdownButton( + value: _selectedEngineer, + iconSize: 24, + icon: const Icon(Icons.keyboard_arrow_down_rounded), + elevation: 0, + isExpanded: true, + hint: Text("Vendor Engineer", style: Theme.of(context).textTheme.titleMedium), + style: TextStyle(color: Theme.of(context).primaryColor), + underline: const SizedBox.shrink(), + onChanged: (SuppPersons newValue) { + setState(() { + _selectedEngineer = newValue; + }); + onSelect(newValue); + }, + items: widget.engineers?.map>((SuppPersons value) { + return DropdownMenuItem( + value: value, + child: Text( + value?.personName ?? "NULL", + style: Theme.of(context).textTheme.titleMedium.copyWith( + color: Theme.of(context).primaryColor, + fontSize: 11, + //fontWeight: FontWeight.bold + ), + ), + ); + })?.toList(), + ), + ); + } + + void onSelect(SuppPersons engineer) { + widget.onSelect( + SuppEngineerWorkOrders( + id: engineer?.supplierId, + supplierContactId: engineer?.id, + personName: engineer?.personName, + contact: engineer?.contact, + externalEngCode: engineer?.externalEngCode, + email: engineer?.email, + ), + ); + } +} From 90fe4e76b75c64b2325ae449dd666c195b5b37ab Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Tue, 22 Aug 2023 12:58:47 +0300 Subject: [PATCH 3/3] Asset Transfer Search Dialog Done --- lib/models/device/device_transfer_search.dart | 69 ++-- .../track_device_transfer.dart | 11 +- .../gas_refill/department_type_menu.dart | 2 +- .../search/asset_transfer_search_dialog.dart | 296 +++++++++--------- 4 files changed, 197 insertions(+), 181 deletions(-) diff --git a/lib/models/device/device_transfer_search.dart b/lib/models/device/device_transfer_search.dart index 14cf695..8a7a24f 100644 --- a/lib/models/device/device_transfer_search.dart +++ b/lib/models/device/device_transfer_search.dart @@ -1,49 +1,64 @@ -import '../lookup.dart'; +import 'package:test_sa/models/device/device.dart'; + +import '../hospital.dart'; class DeviceTransferSearch { - String assetName, assetNumber, site; + Device device; + String title, room; bool mostRecent; - Lookup dateOperator; - String from, to; + Hospital hospital; + Buildings building; + List buildingsList; + Floors floor; + List floorsList; + Departments department; + List departmentsList; DeviceTransferSearch({ - this.assetName, - this.assetNumber, - this.site, + this.device, + this.hospital, + this.building, + this.floor, + this.department, + this.room, + this.title, this.mostRecent, - this.dateOperator, - this.from, - this.to, }); Map toMap() { Map search = {}; - if (assetName != null && assetName.isNotEmpty) { - search["assetName"] = assetName; + if (title != null && title.isNotEmpty) { + search["transferCode"] = title; + } + if (device != null) { + search["assetId"] = device.id; + } + if (hospital?.id != null) { + search["destSiteId"] = hospital.id; } - if (assetNumber != null && assetNumber.isNotEmpty) { - search["assetNumber"] = assetNumber; + if (building?.id != null) { + search["destBuildingId"] = building.id; } - if (site != null && site.isNotEmpty) { - search["site"] = site; + if (floor?.id != null) { + search["destFloorId"] = floor.id; } - if (dateOperator != null && from != null) { - search["requestedDateSymbol"] = dateOperator.toMap(); - search["requestedDateFrom"] = from; + if (department?.id != null) { + search["destDepartmentId"] = department.id; } - if (dateOperator != null && to != null) { - search["requestedDateTo"] = to; + if (room != null && room.isNotEmpty) { + search["destRoom"] = department.id; } return search; } void fromSearch(DeviceTransferSearch newSearch) { - assetName = newSearch.assetName; - assetNumber = newSearch.assetNumber; - site = newSearch.site; + title = newSearch.title; + room = newSearch.room; mostRecent = newSearch.mostRecent; - from = newSearch.from; - to = newSearch.to; - dateOperator = newSearch.dateOperator; + device = newSearch.device; + hospital = newSearch.hospital; + building = newSearch.building; + floor = newSearch.floor; + department = newSearch.department; } } diff --git a/lib/views/pages/device_transfer/track_device_transfer.dart b/lib/views/pages/device_transfer/track_device_transfer.dart index 1610640..34e8168 100644 --- a/lib/views/pages/device_transfer/track_device_transfer.dart +++ b/lib/views/pages/device_transfer/track_device_transfer.dart @@ -72,11 +72,12 @@ class _TrackDeviceTransferPageState extends State with backgroundColor: AColors.white, onPressed: () async { DeviceTransferSearch temp = await showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (context) { - return AssetTransferSearchDialog(initialSearchValue: _deviceTransferProvider.deviceTransferSearch); - }); + context: context, + isScrollControlled: true, + builder: (context) { + return AssetTransferSearchDialog(initialSearchValue: _deviceTransferProvider.deviceTransferSearch); + }, + ); if (temp != null) { _deviceTransferProvider.deviceTransferSearch = temp; _deviceTransferProvider.reset(); diff --git a/lib/views/widgets/gas_refill/department_type_menu.dart b/lib/views/widgets/gas_refill/department_type_menu.dart index bd887c7..3ea429b 100644 --- a/lib/views/widgets/gas_refill/department_type_menu.dart +++ b/lib/views/widgets/gas_refill/department_type_menu.dart @@ -90,7 +90,7 @@ class _DepartmentTypeMenuState extends State { return DropdownMenuItem( value: value, child: Text( - value.name, + value?.name ?? "", style: Theme.of(context).textTheme.subtitle1.copyWith( color: Theme.of(context).primaryColor, fontSize: 11, diff --git a/lib/views/widgets/search/asset_transfer_search_dialog.dart b/lib/views/widgets/search/asset_transfer_search_dialog.dart index 5953923..20a88ec 100644 --- a/lib/views/widgets/search/asset_transfer_search_dialog.dart +++ b/lib/views/widgets/search/asset_transfer_search_dialog.dart @@ -5,12 +5,15 @@ import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_small_button.dart'; +import 'package:test_sa/views/widgets/equipment/device_button.dart'; +import '../../../controllers/providers/api/hospitals_provider.dart'; import '../app_text_form_field.dart'; -import '../date_and_time/date_picker.dart'; -import '../status/report/service_report_visit_date_operator.dart'; +import '../gas_refill/building_type_menu.dart'; +import '../gas_refill/department_type_menu.dart'; +import '../gas_refill/floor_type_menu.dart'; +import '../hospitals/hospital_auto_complete_field.dart'; import '../switch_button.dart'; -import '../titles/app_sub_title.dart'; class AssetTransferSearchDialog extends StatefulWidget { final DeviceTransferSearch initialSearchValue; @@ -25,6 +28,7 @@ class AssetTransferSearchDialog extends StatefulWidget { class AssetTransferSearchDialogState extends State with TickerProviderStateMixin { DeviceTransferSearch _search; final GlobalKey _formKey = GlobalKey(); + bool _isLoading = false; @override void initState() { @@ -36,165 +40,161 @@ class AssetTransferSearchDialogState extends State wi @override Widget build(BuildContext context) { Subtitle subtitle = AppLocalization.of(context).subtitle; - return SizedBox( - height: MediaQuery.of(context).size.height / 1.3, - child: Form( - key: _formKey, - child: ListView( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + return Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: ClipRRect( + borderRadius: const BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15)), + clipBehavior: Clip.antiAliasWithSaveLayer, + child: Container( + color: Colors.white, + height: MediaQuery.of(context).size.height / 1.3, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 20), + child: Form( + key: _formKey, + child: ListView( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), children: [ - ASmallButton( - text: subtitle.cancel, - onPressed: () { - Navigator.of(context).pop(); + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ASmallButton( + text: subtitle.cancel, + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ASmallButton( + text: subtitle.search, + onPressed: () { + if (!_formKey.currentState.validate()) { + return; + } + _formKey.currentState.save(); + Navigator.of(context).pop(_search); + }, + ) + ], + ), + ASwitchButton( + title: "Most Recent", + value: _search.mostRecent ?? false, + onChange: (value) { + _search.mostRecent = value; + setState(() {}); }, ), - ASmallButton( - text: subtitle.search, - onPressed: () { + SizedBox(height: 8.0 * AppStyle.getScaleFactor(context)), + DeviceButton( + device: _search.device, + onDevicePick: (device) { + _search.device = device; + setState(() {}); + }, + ), + SizedBox(height: 8.0 * AppStyle.getScaleFactor(context)), + ATextFormField( + initialValue: _search.title, + hintText: subtitle.title, + style: Theme.of(context).textTheme.titleLarge, + textInputAction: TextInputAction.search, + onAction: () { if (!_formKey.currentState.validate()) { return; } _formKey.currentState.save(); Navigator.of(context).pop(_search); }, - ) - ], - ), - ASwitchButton( - title: "Most Recent", - value: _search.mostRecent ?? false, - onChange: (value) { - _search.mostRecent = value; - setState(() {}); - }, - ), - SizedBox( - height: 8.0 * AppStyle.getScaleFactor(context), - ), - ATextFormField( - initialValue: _search.assetNumber, - hintText: subtitle.assetNumber, - style: Theme.of(context).textTheme.headline6, - textInputAction: TextInputAction.search, - onAction: () { - if (!_formKey.currentState.validate()) { - return; - } - _formKey.currentState.save(); - Navigator.of(context).pop(_search); - }, - onSaved: (value) { - _search.assetNumber = value; - }, - ), - SizedBox( - height: 8.0 * AppStyle.getScaleFactor(context), - ), - ATextFormField( - initialValue: _search.assetName, - hintText: subtitle.assetName, - style: Theme.of(context).textTheme.headline6, - textInputAction: TextInputAction.search, - onAction: () { - if (!_formKey.currentState.validate()) { - return; - } - _formKey.currentState.save(); - Navigator.of(context).pop(_search); - }, - onSaved: (value) { - _search.site = value; - }, - ), - SizedBox( - height: 8.0 * AppStyle.getScaleFactor(context), - ), - ATextFormField( - initialValue: _search.site, - hintText: subtitle.site, - style: Theme.of(context).textTheme.headline6, - textInputAction: TextInputAction.search, - onAction: () { - if (!_formKey.currentState.validate()) { - return; - } - _formKey.currentState.save(); - Navigator.of(context).pop(_search); - }, - onSaved: (value) { - _search.assetName = value; - }, - ), - SizedBox( - height: 8.0 * AppStyle.getScaleFactor(context), - ), - const ASubTitle("Request Date"), - const SizedBox(height: 4), - ServiceReportVisitDateOperator( - initialValue: _search.dateOperator, - onSelect: (status) { - _search.dateOperator = status; - setState(() {}); - }, - ), - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (_search?.dateOperator?.name?.toLowerCase()?.contains("between") ?? false) const ASubTitle("From"), - ADatePicker( - date: DateTime.tryParse(_search.from ?? ""), - from: DateTime(1950), - onDatePicker: (date) { - _search.from = date?.toIso8601String(); - setState(() {}); - }, - ), - ], - ), + onSaved: (value) { + _search.title = value; + }, ), - if (_search?.dateOperator?.name?.toLowerCase()?.contains("between") ?? false) const SizedBox(width: 16), - if (_search?.dateOperator?.name?.toLowerCase()?.contains("between") ?? false) - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("To"), - ADatePicker( - date: DateTime.tryParse(_search.to ?? ""), - from: DateTime(1950), - onDatePicker: (date) { - _search.to = date?.toIso8601String(); - setState(() {}); - }, - ), - ], - ), - ), - ], - ), - const SizedBox(width: 16), - Visibility( - visible: _search.toMap().isNotEmpty, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - child: AButton( - padding: EdgeInsets.zero, - text: subtitle.clearSearch, - onPressed: () { - _search = DeviceTransferSearch(); + SizedBox(height: 8.0 * AppStyle.getScaleFactor(context)), + HospitalAutoCompleteField( + initialValue: _search?.hospital?.name, + onSearch: (selected) async { + _search.building = null; + _search.floor = null; + _search.department = null; + _search.buildingsList = null; + _search.floorsList = null; + _search.departmentsList = null; + _isLoading = true; + setState(() {}); + await HospitalsProvider().getHospitalsListByVal(searchVal: selected?.name ?? "").then((value) { + _search.hospital = value?.firstWhere((element) => element.name == selected.name, orElse: () => null); + _search.buildingsList = _search.hospital?.buildings; + }); + _isLoading = false; + setState(() {}); + }, + ), + const SizedBox(height: 8), + BuildingTypeMenu( + initialValue: _search?.building, + building: _search.buildingsList, + enabled: !_isLoading, + onSelect: (status) { + _search.building = status; + _search.floorsList = status?.floors; + setState(() {}); + }, + ), + const SizedBox(height: 8), + FloorTypeMenu( + initialValue: _search?.floor, + floors: _search.floorsList, + enabled: !_isLoading, + onSelect: (status) { + _search.floor = status; + _search.departmentsList = _search.floor?.departments; + setState(() {}); + }, + ), + const SizedBox(height: 8), + DepartmentTypeMenu( + initialValue: _search?.department, + departments: _search.departmentsList, + enabled: !_isLoading, + onSelect: (status) { + _search.department = status; + setState(() {}); + }, + ), + SizedBox(height: 8.0 * AppStyle.getScaleFactor(context)), + ATextFormField( + initialValue: _search.room, + hintText: subtitle.room, + style: Theme.of(context).textTheme.titleLarge, + textInputAction: TextInputAction.search, + onAction: () { + if (!_formKey.currentState.validate()) { + return; + } + _formKey.currentState.save(); Navigator.of(context).pop(_search); }, + onSaved: (value) { + _search.room = value; + }, ), - ), + SizedBox(height: 16.0 * AppStyle.getScaleFactor(context)), + Visibility( + visible: _search.toMap().isNotEmpty, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + child: AButton( + padding: EdgeInsets.zero, + text: subtitle.clearSearch, + onPressed: () { + _search = DeviceTransferSearch(); + Navigator.of(context).pop(_search); + }, + ), + ), + ), + ], ), - ], + ), ), ), );