313 lines
9.6 KiB
Dart
313 lines
9.6 KiB
Dart
import 'dart:async';
|
|
import 'dart:isolate';
|
|
|
|
import 'package:drift/drift.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:logger/logger.dart';
|
|
import 'package:routemaster/routemaster.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 '../Services/navigation_service.dart';
|
|
import '../Services/transaction_service.dart';
|
|
import 'account_controller.dart';
|
|
import 'port_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());
|
|
});
|
|
|
|
if (!kIsWeb) {
|
|
final ReceivePort updateTransactionsReceivePort = ReceivePort()
|
|
..listen((_) {
|
|
Logger().i('Received update-transactions signal');
|
|
unawaited(updateTransactions());
|
|
});
|
|
|
|
PortController().addPort(
|
|
updateTransactionsReceivePort.sendPort,
|
|
'update-transactions',
|
|
);
|
|
|
|
final ReceivePort gotToTransactionsReceivePort = ReceivePort()
|
|
..listen((final value) {
|
|
Logger().i('Received go-to-transactions signal');
|
|
|
|
final List<Transaction> transactions =
|
|
TransactionService.transactionsFromString(value);
|
|
|
|
goToTransactions(transactions: transactions);
|
|
});
|
|
|
|
PortController().addPort(
|
|
gotToTransactionsReceivePort.sendPort,
|
|
'go-to-transactions',
|
|
);
|
|
}
|
|
|
|
unawaited(updateTransactions());
|
|
}
|
|
|
|
static final TransactionController _instance =
|
|
TransactionController._internal();
|
|
final TransactionRepository _transactionRepository = TransactionRepository();
|
|
final AccountController _accountController = AccountController();
|
|
|
|
DynamicDialog? _newTransactionDialog;
|
|
DynamicDialog? _errorTransactionValueEmptyDialog;
|
|
DynamicDialog? _transactionCreatedDialog;
|
|
|
|
final ValueNotifier<List<Transaction>> _transactions =
|
|
ValueNotifier<List<Transaction>>([]);
|
|
|
|
/// Stellt die Liste der Transaktionen dar
|
|
ValueNotifier<List<Transaction>> get transactions {
|
|
if (_transactions.value == []) {
|
|
unawaited(updateTransactions());
|
|
}
|
|
|
|
return _transactions;
|
|
}
|
|
|
|
set transactions(final List<Transaction> transactions) {
|
|
_transactions.value = transactions;
|
|
}
|
|
|
|
Account? _selectedAccount;
|
|
|
|
/// Aktualisiert die Transaktionen in der internen Liste
|
|
Future<void> updateTransactions() async {
|
|
if (_selectedAccount != null) {
|
|
final List<Transaction> transactions = await _transactionRepository
|
|
.findBy(account: _selectedAccount, orderBy: 'dateDesc');
|
|
|
|
_transactions.value = transactions;
|
|
}
|
|
}
|
|
|
|
/// Wechselt zur Übersicht über die Transaktionen
|
|
void goToTransactions({final List<Transaction>? transactions}) {
|
|
final BuildContext? context = NavigationService.getCurrentBuildContext();
|
|
|
|
if (context != null && transactions != null) {
|
|
if (transactions.length == 1) {
|
|
Routemaster.of(
|
|
context,
|
|
).push('/trend', queryParameters: {'name': transactions.first.name});
|
|
}
|
|
|
|
Routemaster.of(context).replace('/trend');
|
|
}
|
|
}
|
|
|
|
/// Startet den Prozess, um eine neue Transaktion anzulegen
|
|
void newTransactionHandler() {
|
|
unawaited(_newTransactionDialog?.show());
|
|
}
|
|
|
|
/// Startet den Prozess, um eine Transaktion zu bearbeiten
|
|
Future<void> editTransactionHandler(final int transactionId) async {
|
|
final Transaction? transaction = await _transactionRepository.find(
|
|
transactionId,
|
|
);
|
|
|
|
if (transaction != null) {
|
|
final String title;
|
|
final String submitButtonText;
|
|
|
|
if (transaction.checked) {
|
|
title = '${transaction.name} bearbeiten';
|
|
submitButtonText = 'Bearbeiten';
|
|
} else {
|
|
title = '${transaction.name} prüfen';
|
|
submitButtonText = 'Prüfen';
|
|
}
|
|
|
|
final editTransactionDialog = DynamicDialog(
|
|
title: title,
|
|
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: submitButtonText,
|
|
isPrimary: true,
|
|
onPressed: _editTransaction,
|
|
),
|
|
],
|
|
hiddenValues: {'transaction': transaction},
|
|
);
|
|
unawaited(editTransactionDialog.show());
|
|
}
|
|
}
|
|
|
|
/// Startet den Prozess, um eine Transaktion zu löschen
|
|
Future<void> 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<void> _saveNewTransaction(final Map<String, dynamic> 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<void> _editTransaction(final Map<String, dynamic> 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),
|
|
checked: const Value(true),
|
|
);
|
|
|
|
await _transactionRepository.update(rtc);
|
|
await updateTransactions();
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _deleteTransaction(final Map<String, dynamic> values) async {
|
|
if (values['transaction'] != null) {
|
|
final Transaction transaction = values['transaction'];
|
|
await _transactionRepository.remove(transaction);
|
|
|
|
await updateTransactions();
|
|
}
|
|
}
|
|
}
|