LCOV - code coverage report
Current view: top level - lib/pages/bill/widgets - transfer_tab.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1 113 0.9 %
Date: 2024-10-04 11:12:13 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 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/exchange_controller.dart';
       5             : import 'package:app_finance/_classes/herald/app_design.dart';
       6             : import 'package:app_finance/_classes/herald/app_locale.dart';
       7             : import 'package:app_finance/_classes/structure/currency/exchange.dart';
       8             : import 'package:app_finance/_classes/structure/invoice_app_data.dart';
       9             : import 'package:app_finance/_classes/structure/navigation/app_route.dart';
      10             : import 'package:app_finance/_classes/controller/focus_controller.dart';
      11             : import 'package:app_finance/_classes/storage/app_data.dart';
      12             : import 'package:app_finance/_configs/screen_helper.dart';
      13             : import 'package:app_finance/_configs/theme_helper.dart';
      14             : import 'package:app_finance/_ext/build_context_ext.dart';
      15             : import 'package:app_finance/_ext/double_ext.dart';
      16             : import 'package:app_finance/design/wrapper/input_wrapper.dart';
      17             : import 'package:app_finance/pages/bill/widgets/interface_bill_page_inject.dart';
      18             : import 'package:app_finance/design/form/currency_exchange_input.dart';
      19             : import 'package:app_finance/design/form/date_time_input.dart';
      20             : import 'package:app_finance/design/button/full_sized_button_widget.dart';
      21             : import 'package:app_finance/design/wrapper/row_widget.dart';
      22             : import 'package:app_finance/design/form/simple_input.dart';
      23             : import 'package:app_finance/design/wrapper/single_scroll_wrapper.dart';
      24             : import 'package:flutter/material.dart';
      25             : import 'package:flutter_currency_picker/flutter_currency_picker.dart';
      26             : 
      27             : class TransferTab<T> extends StatefulWidget {
      28             :   final String? accountFrom;
      29             :   final String? accountTo;
      30             :   final double? amount;
      31             :   final String? description;
      32             :   final Currency? currency;
      33             :   final DateTime? createdAt;
      34             :   final AppData state;
      35             :   final bool isLeft;
      36             :   final FnBillPageCallback callback;
      37             : 
      38           1 :   const TransferTab({
      39             :     super.key,
      40             :     required this.state,
      41             :     required this.callback,
      42             :     this.accountFrom,
      43             :     this.accountTo,
      44             :     this.amount,
      45             :     this.description,
      46             :     this.currency,
      47             :     this.createdAt,
      48             :     this.isLeft = false,
      49             :   });
      50             : 
      51           0 :   @override
      52           0 :   TransferTabState createState() => TransferTabState();
      53             : }
      54             : 
      55             : class TransferTabState<T extends TransferTab> extends State<T> {
      56             :   late FocusController focus;
      57             :   String? accountFrom;
      58             :   String? accountTo;
      59             :   Currency? accountFromCurrency;
      60             :   Currency? accountToCurrency;
      61             :   late TextEditingController amount;
      62             :   late TextEditingController description;
      63             :   late ExchangeController exchange;
      64             :   late DateTime createdAt;
      65             :   Currency? currency;
      66             :   bool hasErrors = false;
      67             :   bool isPushed = false;
      68             : 
      69           0 :   @override
      70             :   void initState() {
      71           0 :     focus = FocusController();
      72           0 :     accountFrom = widget.accountFrom;
      73           0 :     accountTo = widget.accountTo;
      74           0 :     createdAt = widget.createdAt ?? DateTime.now();
      75           0 :     amount = TextEditingController(text: widget.amount != null ? widget.amount.toString() : '');
      76           0 :     description = TextEditingController(text: widget.description);
      77           0 :     currency = widget.currency ?? Exchange.defaultCurrency;
      78           0 :     exchange = ExchangeController({}, store: widget.state, targetController: amount, target: currency, source: []);
      79             : 
      80           0 :     widget.callback((
      81           0 :       buildButton: buildButton,
      82           0 :       buttonName: getButtonName(),
      83           0 :       title: getTitle(),
      84             :     ));
      85           0 :     super.initState();
      86             :   }
      87             : 
      88           0 :   @override
      89             :   dispose() {
      90           0 :     isPushed = false;
      91           0 :     amount.dispose();
      92           0 :     description.dispose();
      93           0 :     focus.dispose();
      94           0 :     super.dispose();
      95             :   }
      96             : 
      97           0 :   bool hasFormErrors() {
      98           0 :     setState(() => hasErrors = accountFrom == null || accountTo == null);
      99           0 :     return hasErrors;
     100             :   }
     101             : 
     102           0 :   String getTitle() => AppLocale.labels.createBillHeader;
     103             : 
     104           0 :   void updateStorage() {
     105           0 :     final uuid = accountFrom ?? '';
     106           0 :     exchange.save();
     107           0 :     widget.state.add(InvoiceAppData(
     108           0 :       title: description.text,
     109           0 :       color: widget.state.getByUuid(uuid)?.color,
     110           0 :       account: accountTo ?? '',
     111             :       accountFrom: uuid,
     112           0 :       details: double.tryParse(amount.text)?.toFixed(currency?.decimalDigits) ?? 0.0,
     113           0 :       currency: currency,
     114           0 :       createdAt: createdAt,
     115             :     ));
     116             :   }
     117             : 
     118           0 :   String getButtonName() => AppLocale.labels.createTransferTooltip;
     119             : 
     120           0 :   Widget buildButton(BuildContext context, BoxConstraints constraints) {
     121           0 :     final nav = Navigator.of(context);
     122           0 :     return FullSizedButtonWidget(
     123             :       constraints: constraints,
     124           0 :       controller: focus,
     125           0 :       onPressed: () => {
     126           0 :         setState(() {
     127           0 :           if (hasFormErrors()) {
     128             :             return;
     129             :           }
     130           0 :           updateStorage();
     131           0 :           nav.popAndPushNamed(AppRoute.homeRoute);
     132             :         })
     133             :       },
     134           0 :       title: getButtonName(),
     135             :       icon: Icons.save,
     136             :     );
     137             :   }
     138             : 
     139           0 :   @override
     140             :   Widget build(BuildContext context) {
     141           0 :     final textTheme = context.textTheme;
     142           0 :     final indent = ThemeHelper.getIndent(2);
     143           0 :     double width = ScreenHelper.state().width - indent * 3;
     144           0 :     if (widget.isLeft) {
     145           0 :       width -= ThemeHelper.barHeight;
     146             :     }
     147           0 :     return SingleScrollWrapper(
     148           0 :       controller: focus,
     149           0 :       child: Container(
     150           0 :         margin: EdgeInsets.fromLTRB(indent, indent, indent, 240),
     151             :         width: width,
     152           0 :         child: Column(
     153           0 :           crossAxisAlignment: AppDesign.getAlignment(),
     154           0 :           children: [
     155           0 :             InputWrapper(
     156             :               type: NamedInputType.accountSelector,
     157             :               isRequired: true,
     158           0 :               value: accountFrom != null ? widget.state.getByUuid(accountFrom!) : null,
     159           0 :               title: AppLocale.labels.accountFrom,
     160           0 :               tooltip: '${AppLocale.labels.titleAccountTooltip} (${AppLocale.labels.accountFrom})',
     161           0 :               showError: hasErrors && accountFrom == null,
     162           0 :               state: widget.state,
     163           0 :               onChange: (value) => setState(() {
     164           0 :                 accountFrom = value?.uuid;
     165             :                 if (value != null) {
     166           0 :                   accountFromCurrency = value.currency;
     167           0 :                   currency = accountFromCurrency;
     168             :                 }
     169             :               }),
     170             :               width: width,
     171             :             ),
     172           0 :             InputWrapper(
     173             :               type: NamedInputType.accountSelector,
     174             :               isRequired: true,
     175           0 :               value: accountTo != null ? widget.state.getByUuid(accountTo!) : null,
     176           0 :               title: AppLocale.labels.accountTo,
     177           0 :               tooltip: '${AppLocale.labels.titleAccountTooltip} (${AppLocale.labels.accountTo})',
     178           0 :               showError: hasErrors && accountTo == null,
     179           0 :               state: widget.state,
     180           0 :               onChange: (value) => setState(() {
     181           0 :                 accountTo = value?.uuid;
     182             :                 if (value != null) {
     183           0 :                   accountToCurrency = value.currency;
     184           0 :                   currency ??= accountToCurrency;
     185             :                 }
     186             :               }),
     187             :               width: width,
     188             :             ),
     189           0 :             RowWidget(
     190             :               indent: indent,
     191           0 :               maxWidth: width + indent,
     192             :               chunk: const [125, null],
     193           0 :               children: [
     194           0 :                 [
     195           0 :                   InputWrapper.currency(
     196             :                     type: NamedInputType.currencyShort,
     197           0 :                     value: currency,
     198           0 :                     title: AppLocale.labels.currency,
     199           0 :                     tooltip: AppLocale.labels.currencyTooltip,
     200           0 :                     onChange: (value) => setState(() => currency = value),
     201             :                   ),
     202             :                 ],
     203           0 :                 [
     204           0 :                   InputWrapper.text(
     205           0 :                     title: AppLocale.labels.expenseTransfer,
     206           0 :                     tooltip: AppLocale.labels.billSetTooltip,
     207           0 :                     controller: amount,
     208             :                     inputType: const TextInputType.numberWithOptions(decimal: true),
     209           0 :                     formatter: [
     210           0 :                       SimpleInputFormatter.filterDouble,
     211             :                     ],
     212             :                   ),
     213             :                 ],
     214             :               ],
     215             :             ),
     216           0 :             CurrencyExchangeInput(
     217           0 :               key: ValueKey('transfer${currency?.code}${accountFromCurrency?.code}${accountToCurrency?.code}'),
     218           0 :               width: width + indent,
     219             :               indent: indent,
     220           0 :               target: currency,
     221           0 :               controller: exchange,
     222           0 :               source: [accountFromCurrency, accountToCurrency],
     223             :             ),
     224           0 :             InputWrapper.text(
     225           0 :               title: AppLocale.labels.description,
     226           0 :               tooltip: AppLocale.labels.transferTooltip,
     227           0 :               controller: description,
     228             :             ),
     229           0 :             Text(
     230           0 :               AppLocale.labels.balanceDate,
     231           0 :               style: textTheme.bodyLarge,
     232             :             ),
     233           0 :             DateTimeInput(
     234             :               width: width,
     235           0 :               value: createdAt,
     236           0 :               setState: (value) => setState(() => createdAt = value),
     237             :             ),
     238             :             ThemeHelper.formEndBox,
     239             :           ],
     240             :         ),
     241             :       ),
     242             :     );
     243             :   }
     244             : }

Generated by: LCOV version 1.14