import 'dart:async'; import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import '../Entities/drift_database.dart'; import '../Pages/Dialog/dialog_action.dart'; import '../Pages/Dialog/dialog_input_field.dart'; import '../Pages/Dialog/dialog_input_field_type_enum.dart'; import '../Pages/Dialog/dialog_type_enum.dart'; import '../Pages/Dialog/dynamic_dialog.dart'; import '../Repositories/transaction_repository.dart'; import 'account_controller.dart'; /// Steuert die Interaktion mit den Transaktionen class TransactionController { /// Gibt die aktuell gültige Instanz der Klasse zurück factory TransactionController() => _instance; /// Erstellt eine neue Instanz dieser Klasse TransactionController._internal() { _newTransactionDialog = DynamicDialog( title: 'Neue Transaktion erstellen', icon: Icons.swap_horiz, inputFields: [ const DialogInputField(id: 'name', label: 'Name', autoFocus: true), DialogInputField( id: 'date', label: 'Transaktionsdatum', keyboardType: TextInputType.datetime, inputType: DialogInputFieldTypeEnum.date, initialValue: DateTime.now(), ), const DialogInputField( id: 'amount', label: 'Betrag €', keyboardType: TextInputType.number, ), ], actions: [ DialogAction(label: 'Abbruch'), DialogAction( label: 'Speichern', isPrimary: true, onPressed: _saveNewTransaction, ), ], ); _errorTransactionValueEmptyDialog = DynamicDialog( title: 'Fehler!', icon: Icons.error, content: const Text('Es wurden nicht alle Werte eingetragen!'), dialogType: DialogTypeEnum.error, ); _transactionCreatedDialog = DynamicDialog( title: 'Transaktion erstellt!', icon: Icons.check_circle, content: const Text('Die Transaktion wurde erfolgreich erstellt!'), dialogType: DialogTypeEnum.success, ); _selectedAccount = _accountController.selected.value; _accountController.selected.addListener(() { _selectedAccount = _accountController.selected.value; unawaited(updateTransactions()); }); unawaited(updateTransactions()); } static final TransactionController _instance = TransactionController._internal(); final TransactionRepository _transactionRepository = TransactionRepository(); final AccountController _accountController = AccountController(); DynamicDialog? _newTransactionDialog; DynamicDialog? _errorTransactionValueEmptyDialog; DynamicDialog? _transactionCreatedDialog; final ValueNotifier> _transactions = ValueNotifier>([]); /// Stellt die Liste der Transaktionen dar ValueNotifier> get transactions { if (_transactions.value == []) { unawaited(updateTransactions()); } return _transactions; } set transactions(final List transactions) { _transactions.value = transactions; } Account? _selectedAccount; /// Aktualisiert die Transaktionen in der internen Liste Future updateTransactions() async { if (_selectedAccount != null) { final List transactions = await _transactionRepository .findBy(account: _selectedAccount, orderBy: 'dateDesc'); _transactions.value = transactions; } } /// Startet den Prozess, um eine neue Transaktion anzulegen void newTransactionHandler() { unawaited(_newTransactionDialog?.show()); } /// Startet den Prozess, um eine Transaktion zu bearbeiten Future editTransaction(final int transactionId) async { final Transaction? transaction = await _transactionRepository.find( transactionId, ); if (transaction != null) { final editTransactionDialog = DynamicDialog( title: '${transaction.name} umbenennen', icon: Icons.edit, inputFields: [ DialogInputField( id: 'name', label: 'Name', autoFocus: true, initialValue: transaction.name, ), DialogInputField( id: 'date', label: 'Transaktionsdatum', keyboardType: TextInputType.datetime, inputType: DialogInputFieldTypeEnum.date, initialValue: transaction.date, ), DialogInputField( id: 'amount', label: 'Betrag €', keyboardType: TextInputType.number, initialValue: transaction.amount.toString(), ), ], actions: [ DialogAction(label: 'Abbruch'), DialogAction( label: 'Speichern', isPrimary: true, onPressed: _editTransaction, ), ], hiddenValues: {'transaction': transaction}, ); unawaited(editTransactionDialog.show()); } } /// Startet den Prozess, um eine Transaktion zu löschen Future deleteTransactionHandler(final int transactionId) async { final Transaction? transaction = await _transactionRepository.find( transactionId, ); if (transaction != null) { final deleteTransactionDialog = DynamicDialog( dialogType: DialogTypeEnum.error, title: '${transaction.name} löschen', content: Text('Willst du ${transaction.name} wirklich löschen?'), icon: Icons.delete_forever, actions: [ DialogAction(label: 'Abbruch', isPrimary: true), DialogAction( label: 'Transaktion löschen', onPressed: _deleteTransaction, ), ], hiddenValues: {'transaction': transaction}, ); unawaited(deleteTransactionDialog.show()); } } Future _saveNewTransaction(final Map values) async { if (values['name'] == null || values['name'] == '' || values['date'] == null || values['date'] == '' || values['amount'] == null || values['amount'] == '' || _selectedAccount == null) { await _errorTransactionValueEmptyDialog?.show(); } else { final String amount = values['amount']; values['amount'] = double.tryParse(amount); if (values['amount'] == null || values['amount'] == 0) { await _errorTransactionValueEmptyDialog?.show(); } else { final transaction = TransactionsCompanion( name: Value(values['name']), date: Value(values['date']), amount: Value(values['amount']), accountId: Value(_selectedAccount!.id), ); await _transactionRepository.add(transaction); await _transactionCreatedDialog?.show(); await updateTransactions(); } } } Future _editTransaction(final Map values) async { if (values['transaction'] != null && values['transaction'] != null && values['date'] != null && values['date'] != '' && values['amount'] != null && values['amount'] != '') { final String amount = values['amount']; values['amount'] = double.tryParse(amount); if (values['amount'] != null && values['amount'] != 0) { final Transaction transaction = values['transaction']; final rtc = TransactionsCompanion( id: Value(transaction.id), name: Value(values['name']), date: Value(values['date']), amount: Value(values['amount']), accountId: Value(transaction.accountId), ); await _transactionRepository.update(rtc); await updateTransactions(); } } } Future _deleteTransaction(final Map values) async { if (values['transaction'] != null) { final Transaction transaction = values['transaction']; await _transactionRepository.remove(transaction); await updateTransactions(); } } }