From 74cfd942c87b6000291256f2c53646ad59df0c23 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 <50428976+WaseemAbbasi22@users.noreply.github.com> Date: Thu, 24 Sep 2026 11:25:01 +0300 Subject: [PATCH] pagination and filters added --- lib/controllers/api_routes/urls.dart | 4 + lib/main.dart | 7 + .../asset_tracking/asset_tracking_page.dart | 229 +++++++++++++++- .../asset_tracking_provider.dart | 22 +- .../asset_tracking_search_screen.dart | 253 ++++++++++++++++++ .../asset_tracking/filter_provider.dart | 182 +++++++++++++ .../models/asset_tracking_search_model.dart | 64 +++++ 7 files changed, 745 insertions(+), 16 deletions(-) create mode 100644 lib/modules/asset_tracking/asset_tracking_search_screen.dart create mode 100644 lib/modules/asset_tracking/filter_provider.dart create mode 100644 lib/modules/asset_tracking/models/asset_tracking_search_model.dart diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 645db97d..d2b95192 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -637,5 +637,9 @@ class URLs { static get getPenguinDepartments => "$_baseUrl/PenguinIN/departments"; static get getPenguinBuildings => "$_baseUrl/PenguinIN/buildings"; static get getPenguinFloors => "$_baseUrl/PenguinIN/floors"; + static get getPenguinStatus => "$_baseUrl/PenguinIN/statuses"; + static get getPenguinAssetTypes => "$_baseUrl/PenguinIN/assetTypes"; + static get getPenguinTagStatusLookup => "$_baseUrl/Lookups/GetLookup?lookupEnum=3037"; + static get getPenguinTagAssignmentLookup => "$_baseUrl/Lookups/GetLookup?lookupEnum=3033"; } diff --git a/lib/main.dart b/lib/main.dart index 9a50b7ae..091514cd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -137,6 +137,7 @@ import 'controllers/providers/settings/setting_provider.dart'; import 'dashboard_latest/dashboard_provider.dart'; import 'l10n/app_localizations.dart'; import 'modules/asset_tracking/asset_tracking_provider.dart'; +import 'modules/asset_tracking/filter_provider.dart'; import 'modules/demo_module/demo_document_lookup_provider.dart'; import 'modules/incident_module/create_incident_request_page.dart'; import 'modules/incident_module/incident_lookup_provider.dart'; @@ -405,6 +406,12 @@ class MyApp extends StatelessWidget { // UTILITY PROVIDERS (1) ChangeNotifierProvider(create: (_) => OracleCodeProvider(), lazy: true), ChangeNotifierProvider(create: (_) => AssetTrackingProvider(), lazy: true), + ChangeNotifierProvider(create: (_) => TypeProvider(), lazy: true), + ChangeNotifierProvider(create: (_) => TagAssignmentProvider(), lazy: true), + ChangeNotifierProvider(create: (_) => TagStatusProvider(), lazy: true), + ChangeNotifierProvider(create: (_) => LastSeenProvider(), lazy: true), + ChangeNotifierProvider(create: (_) => AssetTrackingStatusProvider(), lazy: true), + ChangeNotifierProvider(create: (_) => AssetTrackingDepartmentProvider(), lazy: true), ], child: GestureDetector( onTap: () { diff --git a/lib/modules/asset_tracking/asset_tracking_page.dart b/lib/modules/asset_tracking/asset_tracking_page.dart index 9432584a..a6c09649 100644 --- a/lib/modules/asset_tracking/asset_tracking_page.dart +++ b/lib/modules/asset_tracking/asset_tracking_page.dart @@ -1,10 +1,14 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/asset_tracking/asset_tracking_provider.dart'; +import 'package:test_sa/modules/asset_tracking/asset_tracking_search_screen.dart'; +import 'package:test_sa/modules/asset_tracking/models/asset_tracking_search_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; @@ -25,6 +29,7 @@ class _AssetTrackingPageState extends State with SingleTicker int selectedIndex = 1; late AnimationController _animationController; late AssetTrackingProvider assetTrackingProvider; + AssetTrackingSearchModel? _searchModel; @override void initState() { @@ -41,20 +46,51 @@ class _AssetTrackingPageState extends State with SingleTicker }); } - Future getAssetsFromPenguin({bool loadMore = false}) async { - await assetTrackingProvider.getAssetsFromPenguin( - loadMore: loadMore, - ); + Future getAssetsFromPenguin({bool loadMore = false, AssetTrackingSearchModel? searchModel}) async { + await assetTrackingProvider.getAssetsFromPenguin(loadMore: loadMore, searchModel: searchModel ?? _searchModel); } @override Widget build(BuildContext context) { return Scaffold( - appBar: const DefaultAppBar(title: "Live Asset Tracking"), + appBar: DefaultAppBar( + title: "Live Asset Tracking", + actions: [ + IconButton( + icon: Icon(Icons.search, color: AppColor.icon2Color(context)), + padding: EdgeInsets.zero, + iconSize: 20, + visualDensity: VisualDensity.compact, + tooltip: "Search", + onPressed: () async { + final result = await Navigator.push( + context, + CupertinoPageRoute( + fullscreenDialog: true, + builder: (context) => AssetTrackingSearchScreen( + searchModel: _searchModel, + ), + ), + ); + + if (result != null) { + assetTrackingProvider.reset(); + setState(() { + _searchModel = result; + }); + await assetTrackingProvider.getAssetsFromPenguin( + searchModel: result, + ); + } + }, + ), + ], + ), body: Column( // crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ + if (_filterIsNotEmpty()) _buildActiveFiltersChips(), SizedBox( width: double.infinity, child: SegmentedButton( @@ -244,4 +280,187 @@ class _AssetTrackingPageState extends State with SingleTicker ); }); } + + Widget _buildActiveFiltersChips() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + decoration: BoxDecoration( + color: AppColor.background(context), + border: Border( + bottom: BorderSide(color: AppColor.borderColor(context), width: 1), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 4, + children: [ + Text( + 'Active Filters', + style: AppTextStyles.tinyFont2.copyWith(color: AppColor.labelTextStyleColor(context), fontWeight: FontWeight.w600), + ), + Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16, + children: [ + SizedBox( + height: 40.toScreenHeight, + child: ListView.separated( + scrollDirection: Axis.horizontal, + padding: EdgeInsets.zero, + itemBuilder: (cxt, index) => _getActiveFilterChips()[index], + separatorBuilder: (cxt, index) => 8.width, + itemCount: _getActiveFilterChips().length, + ), + ).expanded, + TextButton( + onPressed: () { + setState(() { + _searchModel = AssetTrackingSearchModel(); + getAssetsFromPenguin(); + }); + }, + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + child: Text( + 'Clear Filters', + style: AppTextStyles.tinyFont.copyWith(color: AppColor.red30), + ), + ), + ], + ) + ], + ), + ); + } + + Widget _buildFilterChip({required String label, required VoidCallback onDelete}) { + return Theme( + data: Theme.of(context).copyWith(splashColor: Colors.transparent, highlightColor: Colors.transparent), + child: Chip( + backgroundColor: AppColor.backgroundTabBarColor(context), + side: BorderSide(color: AppColor.border2Color(context)), + visualDensity: VisualDensity.compact, + label: Text(label), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + labelStyle: AppTextStyles.tinyFont2.copyWith( + color: AppColor.labelTextStyleColor(context), + ), + deleteIconColor: AppColor.icon2Color(context), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onDeleted: onDelete, + ), + ); + } + + List _getActiveFilterChips() { + final chips = []; + + // Search + if (_searchModel?.search?.isNotEmpty ?? false) { + chips.add( + _buildFilterChip( + label: 'Search: ${_searchModel?.search}', + onDelete: () { + setState(() { + _searchModel?.search = null; + getAssetsFromPenguin(searchModel: _searchModel); + }); + }, + ), + ); + } + if (_searchModel?.types?.isNotEmpty ?? false) { + for (final type in _searchModel?.types ?? []) { + chips.add( + _buildFilterChip( + label: 'Type: ${type.name}', + onDelete: () { + setState(() { + _searchModel?.types!.remove(type); + getAssetsFromPenguin(searchModel: _searchModel); + }); + }, + ), + ); + } + } + if (_searchModel?.status?.isNotEmpty ?? false) { + for (final status in _searchModel?.status ?? []) { + chips.add( + _buildFilterChip( + label: 'Status: ${status.name}', + onDelete: () { + setState(() { + _searchModel?.status!.remove(status); + getAssetsFromPenguin(searchModel: _searchModel); + }); + }, + ), + ); + } + } + + if (_searchModel?.departments?.isNotEmpty ?? false) { + for (final department in _searchModel?.departments ?? []) { + chips.add( + _buildFilterChip( + label: 'Department: ${department.name}', + onDelete: () { + setState(() { + _searchModel?.departments?.remove(department); + getAssetsFromPenguin(searchModel: _searchModel); + }); + }, + ), + ); + } + } + + // Start Date + if (_searchModel?.startDate?.isNotEmpty ?? false) { + chips.add( + _buildFilterChip( + label: 'From: ${_searchModel?.startDate?.toAssetDetailsFormat}', + onDelete: () { + setState(() { + _searchModel?.startDate = null; + getAssetsFromPenguin(searchModel: _searchModel); + }); + }, + ), + ); + } + + // End Date + if (_searchModel?.endDate?.isNotEmpty ?? false) { + chips.add( + _buildFilterChip( + label: 'To: ${_searchModel?.endDate?.toAssetDetailsFormat}', + onDelete: () { + setState(() { + _searchModel?.endDate = null; + getAssetsFromPenguin(searchModel: _searchModel); + }); + }, + ), + ); + } + + return chips; + } + + bool _filterIsNotEmpty() { + return (_searchModel?.search?.isNotEmpty ?? false) || + (_searchModel?.types != null && _searchModel!.types!.isNotEmpty) || + (_searchModel?.status != null && _searchModel!.status!.isNotEmpty) || + (_searchModel?.departments != null && _searchModel!.departments!.isNotEmpty) || + (_searchModel?.startDate != null && _searchModel!.startDate!.isNotEmpty) || + (_searchModel?.endDate != null && _searchModel!.endDate!.isNotEmpty); + } + } diff --git a/lib/modules/asset_tracking/asset_tracking_provider.dart b/lib/modules/asset_tracking/asset_tracking_provider.dart index 9e148441..e5845573 100644 --- a/lib/modules/asset_tracking/asset_tracking_provider.dart +++ b/lib/modules/asset_tracking/asset_tracking_provider.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/modules/asset_tracking/models/asset_tracking_search_model.dart'; import 'models/asset_tracking_model.dart'; import 'models/floor_map_model.dart'; @@ -45,34 +46,35 @@ class AssetTrackingProvider extends ChangeNotifier { notifyListeners(); } - Future getAssetsFromPenguin({bool loadMore = false}) async { + Future getAssetsFromPenguin({bool loadMore = false,AssetTrackingSearchModel? searchModel}) async { if (isLoading || isNextPageLoading) return -2; if (loadMore) { isNextPageLoading = true; pageNo += 1; } else { isLoading = true; - pageNo = 1; // reset pagination + pageNo = 1; } notifyListeners(); try { - final payload = {"pageSize": pageItemNumber, "pageNumber": pageNo}; + final Map payload = { + "pageSize": pageItemNumber, + "pageNumber": pageNo, + }; + + if (searchModel != null) { + payload.addAll(searchModel.toJson()); + } final response = await ApiManager.instance.post(URLs.getAssetsFromPenguin, body: payload); if (response.statusCode >= 200 && response.statusCode < 300) { final Map jsonData = json.decode(response.body); List list = jsonData["data"] ?? []; List responseAssetList = list.map((item) => AssetTrackingModel.fromJson(item)).toList(); - // assetsList.addAll(list.map((item) => AssetTrackingModel.fromJson(item)).toList()); - // if (jsonData["totalRows"] <= assetsList.length) { - // nextPage = true; - // } if (loadMore) { assetsList.addAll(responseAssetList); - // assetInventoryResponse?.totalRows = newResponse.totalRows; } else { assetsList = responseAssetList; - // assetInventoryResponse = newResponse; } final int totalRows = (jsonData["totalRows"] as int?) ?? assetsList.length; nextPage = (assetsList.length) < totalRows; @@ -87,8 +89,6 @@ class AssetTrackingProvider extends ChangeNotifier { if (loadMore) pageNo -= 1; isLoading = false; isNextPageLoading = false; - // stateCode = -1; - // nextPage = false; notifyListeners(); return -1; } diff --git a/lib/modules/asset_tracking/asset_tracking_search_screen.dart b/lib/modules/asset_tracking/asset_tracking_search_screen.dart new file mode 100644 index 00000000..b9cd95bf --- /dev/null +++ b/lib/modules/asset_tracking/asset_tracking_search_screen.dart @@ -0,0 +1,253 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/modules/asset_tracking/filter_provider.dart'; +import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/new_views/common_widgets/multiple_item_drop_down_menu.dart'; +import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/views/widgets/item_views/info_header_widget.dart'; +import '../../../new_views/common_widgets/default_app_bar.dart'; +import 'models/asset_tracking_search_model.dart'; + +class AssetTrackingSearchScreen extends StatefulWidget { + static const String id = "asset_tracking_screen"; + AssetTrackingSearchModel? searchModel; + + AssetTrackingSearchScreen({Key? key, this.searchModel}) : super(key: key); + + @override + State createState() => _AssetTrackingSearchScreenState(); +} + +class _AssetTrackingSearchScreenState extends State { + late AssetTrackingSearchModel searchModel; + final GlobalKey _formKey = GlobalKey(); + late TextEditingController _searchController; + + @override + void initState() { + searchModel = widget.searchModel ?? AssetTrackingSearchModel(); + _searchController = TextEditingController(text: searchModel.search); + super.initState(); + } + + @override + void dispose() { + _searchController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: DefaultAppBar( + title: context.translation.search, + showBackButtonAsCancel: true, + actions: [ + if (_showResetButton()) + TextButton( + onPressed: () { + setState(() { + _searchController.text = ""; + searchModel = AssetTrackingSearchModel(); + + }); + }, + style: TextButton.styleFrom(padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap), + child: Text( + 'Clear Filters', + style: AppTextStyles.bodyText2.copyWith(color: AppColor.red30), + ), + ).paddingOnly(start: 16, end: 16), + ], + ), + body: Form( + key: _formKey, + child: SafeArea( + child: Column( + children: [ + ListView( + padding: const EdgeInsets.all(16), + children: [ + context.translation.searchBy.heading5(context).custom(color: AppColor.textStyleColor(context)), + 4.height, + context.translation.searchByDesc.bodyText2(context).custom(color: AppColor.lightTextColor(context)), + 16.height, + AppTextFormField( + controller: _searchController, + labelText: context.translation.search, + onChange: (text) { + _searchController.text = text; + _searchController.selection = TextSelection.fromPosition(TextPosition(offset: _searchController.text.length)); + setState(() {}); + }, + onSaved: (value) { + searchModel.search = value; + }, + ), + 8.height, + MultipleItemDropDownMenu( + context: context, + title: 'Type', + initialValue: searchModel.types != null ? searchModel.types! : [], + showAsBottomSheet: true, + showShadow: true, + height: 56.toScreenHeight, + showCancel: true, + onSelect: (value) { + if (value != null) { + setState(() { + searchModel.types = value; + }); + } + }, + ), + 8.height, + MultipleItemDropDownMenu( + context: context, + title: 'Department', + initialValue: searchModel.departments != null ? searchModel.departments! : [], + showAsBottomSheet: true, + showShadow: true, + height: 56.toScreenHeight, + showCancel: true, + onSelect: (value) { + if (value != null) { + setState(() { + searchModel.departments = value; + }); + } + }, + ), + 8.height, + MultipleItemDropDownMenu( + context: context, + title: 'Status', + initialValue: searchModel.status != null ? searchModel.status! : [], + showAsBottomSheet: true, + showShadow: true, + height: 56.toScreenHeight, + showCancel: true, + onSelect: (value) { + if (value != null) { + setState(() { + searchModel.status = value; + }); + } + }, + ), + 8.height, + // MultipleItemDropDownMenu( + // context: context, + // title: 'Last Seen', + // initialValue: searchModel.lastSeen != null ? searchModel.lastSeen! : [], + // showAsBottomSheet: true, + // showShadow: true, + // height: 56.toScreenHeight, + // showCancel: true, + // onSelect: (value) { + // if (value != null) { + // setState(() { + // searchModel.lastSeen = value; + // }); + // } + // }, + // ), + // 8.height, + // MultipleItemDropDownMenu( + // context: context, + // title: 'Tag Status', + // initialValue: searchModel.tagStatus != null ? searchModel.tagStatus! : [], + // showAsBottomSheet: true, + // showShadow: true, + // height: 56.toScreenHeight, + // showCancel: true, + // onSelect: (value) { + // if (value != null) { + // setState(() { + // searchModel.tagStatus = value; + // }); + // } + // }, + // ), + // 8.height, + // MultipleItemDropDownMenu( + // context: context, + // title: 'Tag Assignment', + // initialValue: searchModel.tagAssignment != null ? searchModel.tagAssignment! : [], + // showAsBottomSheet: true, + // showShadow: true, + // height: 56.toScreenHeight, + // showCancel: true, + // onSelect: (value) { + // if (value != null) { + // setState(() { + // searchModel.tagAssignment = value; + // }); + // } + // }, + // ), + 8.height, + InfoHeader16Widget('Last Seen'), + 8.height, + Row( + children: [ + ADatePicker( + label: context.translation.from, + from: DateTime(2000), + date: DateTime.tryParse(searchModel.startDate ?? ""), + onDatePicker: (date) { + setState(() { + searchModel.startDate = date.toIso8601String(); + }); + }, + ).expanded, + 8.width, + ADatePicker( + label: context.translation.to, + from: DateTime(2000), + date: DateTime.tryParse(searchModel.endDate ?? ""), + onDatePicker: (date) { + setState(() { + searchModel.endDate = date.toIso8601String(); + }); + }, + ).expanded, + ], + ), + ], + ).expanded, + FooterActionButton.footerContainer(context: context, child: AppFilledButton(onPressed: _search, label: context.translation.search)), + ], + ), + ), + ), + ); + } + + void _search() { + if (!_formKey.currentState!.validate()) { + return; + } + _formKey.currentState!.save(); + Navigator.pop(context, searchModel); + } + + bool _showResetButton() { + return (_searchController.text.isNotEmpty) || + // (searchModel.tagAssignment != null && searchModel.tagAssignment!.isNotEmpty) || + // (searchModel.tagStatus != null && searchModel.tagStatus!.isNotEmpty) || + // (searchModel.lastSeen != null && searchModel.lastSeen!.isNotEmpty) || + (searchModel.types != null && searchModel.types!.isNotEmpty) || + (searchModel.status != null && searchModel.status!.isNotEmpty) || + (searchModel.departments != null && searchModel.departments!.isNotEmpty)|| + (searchModel.startDate != null && searchModel.startDate!.isNotEmpty) || + (searchModel.endDate != null && searchModel.endDate!.isNotEmpty); + } +} diff --git a/lib/modules/asset_tracking/filter_provider.dart b/lib/modules/asset_tracking/filter_provider.dart new file mode 100644 index 00000000..bdb84209 --- /dev/null +++ b/lib/modules/asset_tracking/filter_provider.dart @@ -0,0 +1,182 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +import '../../controllers/api_routes/api_manager.dart'; +import '../../controllers/api_routes/urls.dart'; + +class AssetTrackingDepartmentProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return -2; + loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get(URLs.getPenguinDepartments,); + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final List listJson = json.decode(response.body)["data"] ?? []; + + items = listJson.map((item) { + return Lookup.fromJson({ + ...item, + "name": item["label"], + }); + }).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } +} + +class AssetTrackingStatusProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return -2; + loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get(URLs.getPenguinStatus); + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final List listJson = json.decode(response.body)["data"] ?? []; + + items = listJson.map((item) { + return Lookup.fromJson({ + ...item, + "name": item["label"], + }); + }).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } +} + +class LastSeenProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return -2; + loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.post(URLs.getDepartments, body: {"pageSize": 50}); + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List listJson = json.decode(response.body)["data"]; + items = listJson.map((department) => Lookup.fromJson(department)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } +} + +class TagStatusProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return -2; + loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get(URLs.getPenguinTagStatusLookup); + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List listJson = json.decode(response.body)["data"]; + items = listJson.map((department) => Lookup.fromJson(department)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } +} + +class TagAssignmentProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return -2; + loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get(URLs.getPenguinTagAssignmentLookup); + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List listJson = json.decode(response.body)["data"]; + items = listJson.map((department) => Lookup.fromJson(department)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } +} + +class TypeProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return -2; + loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get(URLs.getPenguinAssetTypes,); + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final List listJson = json.decode(response.body)["data"] ?? []; + + items = listJson.map((item) { + return Lookup.fromJson({ + ...item, + "name": item["label"], + }); + }).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } +} diff --git a/lib/modules/asset_tracking/models/asset_tracking_search_model.dart b/lib/modules/asset_tracking/models/asset_tracking_search_model.dart new file mode 100644 index 00000000..76457fad --- /dev/null +++ b/lib/modules/asset_tracking/models/asset_tracking_search_model.dart @@ -0,0 +1,64 @@ +import 'package:test_sa/models/lookup.dart'; + +class AssetTrackingSearchModel { + AssetTrackingSearchModel({ + this.search, + this.tagStatus, + this.lastSeen, + this.tagAssignment, + this.types, + this.departments, + this.status, + this.startDate, + this.endDate, + }); + + String? search; + List? tagStatus; + List? lastSeen; + List? tagAssignment; + List? departments; + List? types; + List? status; + String? startDate, endDate; + + Map toJson() { + final map = {}; + + if (search != null && search!.trim().isNotEmpty) { + map['searchString'] = search!.trim(); + } + + if (tagStatus?.isNotEmpty == true) { + map['tagStatusIds'] = tagStatus!.map((e) => e.id).toList(); + } + + if (lastSeen?.isNotEmpty == true) { + map['lastSeenIds'] = lastSeen!.map((e) => e.id).toList(); + } + + if (tagAssignment?.isNotEmpty == true) { + map['tagAssignmentIds'] = tagAssignment!.map((e) => e.id).toList(); + } + + if (types?.isNotEmpty == true) { + map['typeIds'] = types!.map((e) => e.id).toList(); + } + + if (departments?.isNotEmpty == true) { + map['departmentIds'] = departments!.map((e) => e.id).toList(); + } + + if (status?.isNotEmpty == true) { + map['statusIds'] = status!.map((e) => e.id).toList(); + } + if (startDate != null && startDate!.trim().isNotEmpty) { + map['lastSeenFrom'] = startDate!.trim(); + } + if (endDate != null && endDate!.trim().isNotEmpty) { + map['lastSeenTo'] = endDate!.trim(); + } + + return map; + } +} \ No newline at end of file