import 'dart:async'; import 'package:drift/drift.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:logger/logger.dart'; import '../Controller/port_controller.dart'; import '../Controller/transaction_controller.dart'; import '../Entities/drift_database.dart'; import '../Entities/time_frame_enum.dart'; import '../Repositories/recurring_transacation_repository.dart'; import '../Repositories/transaction_repository.dart'; import 'task.dart'; /// Generiert neue Transaktionen /// anhand der erstellten wiederkehrenden Transaktionen class GenerateTransactionsTask extends Task { final TransactionRepository _transactionRepository = TransactionRepository(); final RecurringTransactionRepository _recurringTransactionRepository = RecurringTransactionRepository(); final Logger _logger = Logger(); @override Future execute() async { _logger.i('Generating Transactions of recurring Transactions...'); final List recurringTransactions = await _recurringTransactionRepository.findBy(); for (final recurringTransaction in recurringTransactions) { _logger.i('Generating Transactions of ${recurringTransaction.name}...'); final List transactions = await _transactionRepository .findBy( recurringTransaction: recurringTransaction, orderBy: 'dateDesc', ); final Transaction? transaction = transactions.firstOrNull; await _generateTransactions( recurringTransaction, transaction?.date, number: transactions.length, ); } _logger.i('Generating transactions completed.'); if (!kIsWeb) { PortController().getPort('update-transactions')?.send('ready'); } else { unawaited(TransactionController().updateTransactions()); } return true; } Future _generateTransactions( final RecurringTransaction recurringTransaction, final DateTime? lastTransactionDate, { final int number = 0, }) async { final DateTime newTransactionDate; if (lastTransactionDate != null) { switch (recurringTransaction.timeFrame) { case TimeFrameEnum.daily: newTransactionDate = lastTransactionDate.add(const Duration(days: 1)); case TimeFrameEnum.weekly: newTransactionDate = lastTransactionDate.add(const Duration(days: 7)); case TimeFrameEnum.monthly: newTransactionDate = DateUtils.addMonthsToMonthDate( lastTransactionDate, 1, ); case TimeFrameEnum.yearly: newTransactionDate = DateUtils.addMonthsToMonthDate( lastTransactionDate, 12, ); } } else { newTransactionDate = recurringTransaction.startDate!; } _logger.i('New transaction-date is $newTransactionDate'); final DateTime endOfMonth = DateTime( DateTime.now().year, DateTime.now().month + 1, 0, ); if (endOfMonth.compareTo(newTransactionDate) >= 0) { _logger.i('$newTransactionDate is before $endOfMonth'); final TransactionsCompanion transaction = TransactionsCompanion( name: Value('${recurringTransaction.name} #$number'), date: Value(newTransactionDate), amount: Value(recurringTransaction.amount), checked: const Value(false), accountId: Value(recurringTransaction.accountId), recurringTransactionId: Value(recurringTransaction.id), ); _logger.i( 'Adding transaction ${transaction.name.value}' ' on ${transaction.date.value}', ); await _transactionRepository.add(transaction); return _generateTransactions( recurringTransaction, newTransactionDate, number: number + 1, ); } else { _logger.i('$newTransactionDate is after $endOfMonth'); return true; } } }