LCOV - code coverage report
Current view: top level - lib/pages/invoice - invoice_search_page.dart Coverage Total Hit
Test: lcov.info Lines: 0.0 % 99 0
Test Date: 2026-11-14 15:04:37 Functions: - 0 0

            Line data    Source code
       1              : // Copyright 2025 The terCAD team. All rights reserved.
       2              : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
       3              : 
       4              : import 'package:app_finance/_classes/controller/iterator_controller.dart';
       5              : import 'package:app_finance/_classes/controller/focus_controller.dart';
       6              : import 'package:app_finance/_classes/herald/app_design.dart';
       7              : import 'package:app_finance/_classes/herald/app_locale.dart';
       8              : import 'package:app_finance/_classes/storage/app_data.dart';
       9              : import 'package:app_finance/_classes/structure/invoice_app_data.dart';
      10              : import 'package:app_finance/_configs/account_type.dart';
      11              : import 'package:app_finance/_configs/screen_helper.dart';
      12              : import 'package:app_finance/_configs/theme_helper.dart';
      13              : import 'package:app_finance/_ext/build_context_ext.dart';
      14              : import 'package:app_finance/design/form/date_range_input.dart';
      15              : import 'package:app_finance/design/form/list_account_selector.dart';
      16              : import 'package:app_finance/design/form/simple_input.dart';
      17              : import 'package:app_finance/design/wrapper/input_wrapper.dart';
      18              : import 'package:app_finance/design/wrapper/row_widget.dart';
      19              : import 'package:app_finance/design/wrapper/single_scroll_wrapper.dart';
      20              : import 'package:app_finance/design/wrapper/text_wrapper.dart';
      21              : import 'package:app_finance/pages/invoice/invoice_page.dart';
      22              : import 'package:material_ui/material_ui.dart';
      23              : import 'package:flutter_currency_picker/flutter_currency_picker.dart';
      24              : 
      25              : class InvoiceSearchPage extends StatefulWidget {
      26            0 :   const InvoiceSearchPage({super.key});
      27              : 
      28            0 :   @override
      29            0 :   InvoiceSearchPageState createState() => InvoiceSearchPageState();
      30              : }
      31              : 
      32              : class InvoiceSearchPageState extends InvoicePageState<InvoiceSearchPage> {
      33              :   String? account;
      34              :   String? type;
      35              :   Currency? currency;
      36              :   DateTime? startDate;
      37              :   DateTime? endDate;
      38              :   late TextEditingController description;
      39              :   late TextEditingController amountFrom;
      40              :   late TextEditingController amountTo;
      41              :   late FocusController focus;
      42              : 
      43              :   late List<ListAccountSelectorItem> accountList =
      44              :       state.getList(AppDataType.accounts).map((item) => ListAccountSelectorItem(item: item)).toList();
      45              : 
      46            0 :   @override
      47              :   void initState() {
      48            0 :     description = TextEditingController();
      49            0 :     amountFrom = TextEditingController();
      50            0 :     amountTo = TextEditingController();
      51            0 :     focus = FocusController();
      52            0 :     super.initState();
      53              :   }
      54              : 
      55            0 :   @override
      56              :   dispose() {
      57            0 :     description.dispose();
      58            0 :     amountFrom.dispose();
      59            0 :     amountTo.dispose();
      60            0 :     focus.dispose();
      61            0 :     super.dispose();
      62              :   }
      63              : 
      64            0 :   @override
      65            0 :   String getTitle() => AppLocale.labels.searchTooltip;
      66              : 
      67            0 :   @override
      68            0 :   String getButtonName() => AppLocale.labels.searchTooltip;
      69              : 
      70            0 :   @override
      71              :   Widget buildButton(BuildContext context, BoxConstraints constraints) {
      72            0 :     return FloatingActionButton(
      73              :       heroTag: 'invoice_search_page',
      74            0 :       onPressed: () => setState(clearState),
      75            0 :       tooltip: getButtonName(),
      76              :       child: const Icon(Icons.search),
      77              :     );
      78              :   }
      79              : 
      80            0 :   @override
      81              :   bool getContentFilter(InvoiceAppData o) {
      82            0 :     final descriptionMatch = o.title.toLowerCase().contains(description.text.toLowerCase());
      83            0 :     final accountMatch = account == null || o.account == account;
      84            0 :     final typeMatch = type == null || state.getByUuid(o.account)?.type == type;
      85            0 :     final currencyMatch = currency == null || o.currency == currency;
      86            0 :     final startDateMatch = startDate == null || o.createdAt.isAfter(startDate!);
      87            0 :     final endDateMatch = endDate == null || o.createdAt.isBefore(endDate!);
      88            0 :     final amountFromMatch = amountFrom.text.isEmpty || o.details >= double.tryParse(amountFrom.text)!;
      89            0 :     final amountToMatch = amountTo.text.isEmpty || o.details <= double.tryParse(amountTo.text)!;
      90              : 
      91              :     return !(descriptionMatch &&
      92              :             accountMatch &&
      93              :             typeMatch &&
      94              :             currencyMatch &&
      95              :             startDateMatch &&
      96              :             endDateMatch &&
      97              :             amountFromMatch &&
      98              :             amountToMatch) ||
      99            0 :         o.accountFrom != null;
     100              :   }
     101              : 
     102            0 :   @override
     103              :   InterfaceIterator getContentStream() =>
     104            0 :       state.getStream<InvoiceAppData>(AppDataType.invoice, filter: getContentFilter);
     105              : 
     106            0 :   @override
     107              :   Widget addHeaderWidget() {
     108            0 :     final width = ScreenHelper.state().width - ThemeHelper.getIndent(4);
     109            0 :     final indent = ThemeHelper.getIndent(2);
     110            0 :     return SliverToBoxAdapter(
     111            0 :       child: SingleScrollWrapper(
     112            0 :         controller: focus,
     113            0 :         child: Column(
     114            0 :           crossAxisAlignment: AppDesign.getAlignment(),
     115            0 :           children: [
     116            0 :             InputWrapper.text(
     117            0 :               title: AppLocale.labels.description,
     118            0 :               controller: description,
     119            0 :               tooltip: AppLocale.labels.descriptionTooltip,
     120              :             ),
     121            0 :             RowWidget(
     122              :               indent: indent,
     123            0 :               maxWidth: width + indent,
     124              :               chunk: const [0.5, 0.5],
     125            0 :               children: [
     126            0 :                 [
     127            0 :                   InputWrapper.text(
     128            0 :                     title: AppLocale.labels.amountFrom,
     129            0 :                     tooltip: AppLocale.labels.billSetTooltip,
     130            0 :                     controller: amountFrom,
     131              :                     inputType: const TextInputType.numberWithOptions(decimal: true),
     132            0 :                     formatter: [
     133            0 :                       SimpleInputFormatter.filterDouble,
     134              :                     ],
     135              :                   ),
     136              :                 ],
     137            0 :                 [
     138            0 :                   InputWrapper.text(
     139            0 :                     title: AppLocale.labels.amountTo,
     140            0 :                     tooltip: AppLocale.labels.billSetTooltip,
     141            0 :                     controller: amountTo,
     142              :                     inputType: const TextInputType.numberWithOptions(decimal: true),
     143            0 :                     formatter: [
     144            0 :                       SimpleInputFormatter.filterDouble,
     145              :                     ],
     146              :                   ),
     147              :                 ],
     148              :               ],
     149              :             ),
     150            0 :             InputWrapper.select(
     151            0 :               value: type,
     152            0 :               title: AppLocale.labels.accountType,
     153            0 :               tooltip: AppLocale.labels.accountTypeTooltip,
     154            0 :               options: AccountType.getList(),
     155            0 :               onChange: (value) => setState(() {
     156            0 :                 if (value != type) clearState();
     157            0 :                 type = value;
     158              :               }),
     159              :             ),
     160            0 :             InputWrapper(
     161              :               type: NamedInputType.accountSelector,
     162            0 :               value: account != null ? state.getByUuid(account!) : null,
     163            0 :               title: AppLocale.labels.account,
     164            0 :               tooltip: AppLocale.labels.titleAccountTooltip,
     165            0 :               state: state,
     166            0 :               options: accountList,
     167            0 :               onChange: (value) => setState(() {
     168            0 :                 if (value?.uuid != account) clearState();
     169            0 :                 account = value?.uuid;
     170              :               }),
     171              :               width: width,
     172              :             ),
     173            0 :             InputWrapper.currency(
     174            0 :               value: currency,
     175            0 :               title: AppLocale.labels.currency,
     176            0 :               tooltip: AppLocale.labels.currencyTooltip,
     177            0 :               onChange: (value) => setState(() {
     178            0 :                 if (value != currency) clearState();
     179            0 :                 currency = value;
     180              :               }),
     181              :             ),
     182            0 :             TextWrapper(
     183            0 :               AppLocale.labels.dateRange,
     184            0 :               style: context.textTheme.bodyLarge,
     185              :             ),
     186            0 :             DateRangeInput(
     187            0 :               valueFrom: startDate,
     188            0 :               value: endDate,
     189            0 :               setState: (start, end) => setState(() {
     190            0 :                 startDate = start;
     191            0 :                 endDate = end;
     192            0 :                 clearState();
     193              :               }),
     194              :             ),
     195              :           ],
     196              :         ),
     197              :       ),
     198              :     );
     199              :   }
     200              : }
        

Generated by: LCOV version 2.0-1