240 lines
7.0 KiB
Dart
240 lines
7.0 KiB
Dart
import 'package:drift/drift.dart';
|
|
|
|
import '../Entities/drift_database.dart';
|
|
import '../Services/database_service.dart';
|
|
|
|
/// Funktionen zum interagieren mit der Datenbank für die Transaktionen
|
|
class TransactionRepository {
|
|
final AppDatabase _db = DatabaseService().database;
|
|
|
|
/// Fügt eine neue Transaktion zur Datenbank hinzu
|
|
Future<Transaction?> add(final TransactionsCompanion transaction) async {
|
|
final int id = await _db.into(_db.transactions).insert(transaction);
|
|
return find(id);
|
|
}
|
|
|
|
/// Aktualisiert eine Transaktion in der Datenbank
|
|
Future<bool> update(final TransactionsCompanion transaction) {
|
|
final TransactionsCompanion transactionToUpdate = TransactionsCompanion(
|
|
id: transaction.id,
|
|
name: transaction.name,
|
|
date: transaction.date,
|
|
amount: transaction.amount,
|
|
checked: transaction.checked,
|
|
accountId: transaction.accountId,
|
|
recurringTransactionId: transaction.recurringTransactionId,
|
|
updatedAt: Value(DateTime.now()),
|
|
);
|
|
|
|
return _db.update(_db.transactions).replace(transactionToUpdate);
|
|
}
|
|
|
|
/// Entfernt eine Transaktion aus der Datenbank
|
|
Future<int> remove(final Transaction transaction) => (_db.delete(
|
|
_db.transactions,
|
|
)..where((final t) => t.id.equals(transaction.id))).go();
|
|
|
|
/// Sucht eine Transaktion anhand seiner Id aus der Datenbank
|
|
Future<Transaction?> find(final int id) => (_db.select(
|
|
_db.transactions,
|
|
)..where((final t) => t.id.equals(id))).getSingleOrNull();
|
|
|
|
/// Sucht Transaktionen anhand der gegebenen Parameter aus der Datenbank
|
|
Future<List<Transaction>> findBy({
|
|
final int? id,
|
|
final String? name,
|
|
final DateTime? date,
|
|
final DateTime? dateFrom,
|
|
final DateTime? dateTo,
|
|
final double? amount,
|
|
final double? amountMin,
|
|
final double? amountMax,
|
|
final Account? account,
|
|
final int? limit,
|
|
final int? offset,
|
|
final String? orderBy,
|
|
}) {
|
|
final SimpleSelectStatement<$TransactionsTable, Transaction> query = _db
|
|
.select(_db.transactions);
|
|
|
|
if (id != null) {
|
|
query.where((final t) => t.id.equals(id));
|
|
}
|
|
|
|
if (name != null && name.isNotEmpty) {
|
|
query.where((final t) => t.name.like('%$name%'));
|
|
}
|
|
|
|
if (date != null) {
|
|
query.where((final t) => t.date.equals(date));
|
|
}
|
|
|
|
if (dateFrom != null) {
|
|
query.where((final t) => t.date.isBiggerThanValue(dateFrom));
|
|
}
|
|
|
|
if (dateTo != null) {
|
|
query.where((final t) => t.date.isSmallerThanValue(dateTo));
|
|
}
|
|
|
|
if (amount != null) {
|
|
query.where((final t) => t.amount.equals(amount));
|
|
}
|
|
|
|
if (amountMin != null) {
|
|
query.where((final t) => t.amount.isBiggerThanValue(amountMin));
|
|
}
|
|
|
|
if (amountMax != null) {
|
|
query.where((final t) => t.amount.isSmallerThanValue(amountMax));
|
|
}
|
|
|
|
if (account != null) {
|
|
query.where((final t) => t.accountId.equals(account.id));
|
|
}
|
|
|
|
if (limit != null) {
|
|
query.limit(limit, offset: offset);
|
|
}
|
|
|
|
if (orderBy != null) {
|
|
switch (orderBy) {
|
|
case 'nameAsc':
|
|
query.orderBy([(final t) => OrderingTerm.asc(t.name)]);
|
|
case 'nameDesc':
|
|
query.orderBy([(final t) => OrderingTerm.desc(t.name)]);
|
|
case 'dateAsc':
|
|
query.orderBy([(final t) => OrderingTerm.asc(t.date)]);
|
|
case 'dateDesc':
|
|
query.orderBy([(final t) => OrderingTerm.desc(t.date)]);
|
|
case 'amountAsc':
|
|
query.orderBy([(final t) => OrderingTerm.asc(t.amount)]);
|
|
case 'amountDesc':
|
|
query.orderBy([(final t) => OrderingTerm.desc(t.amount)]);
|
|
}
|
|
}
|
|
|
|
return query.get();
|
|
}
|
|
|
|
/// Gibt den Kontostand zurück
|
|
Future<double> balance({
|
|
final Account? account,
|
|
final DateTime? until,
|
|
}) async {
|
|
final JoinedSelectStatement<$TransactionsTable, Transaction> query =
|
|
_db.selectOnly(_db.transactions)
|
|
..addColumns([_db.transactions.amount.sum()]);
|
|
|
|
if (account != null) {
|
|
query.where(_db.transactions.accountId.equals(account.id));
|
|
}
|
|
|
|
if (until != null) {
|
|
query.where(_db.transactions.date.isSmallerOrEqualValue(until));
|
|
}
|
|
|
|
return (await query
|
|
.map((final row) => row.read(_db.transactions.amount.sum()) ?? 0)
|
|
.getSingle()) *
|
|
-1;
|
|
}
|
|
|
|
/// Gibt den Kontostand der letzten 12 Monate zurück
|
|
Future<List<Map<String, dynamic>>> monthlyBalances({
|
|
final Account? account,
|
|
final String? name,
|
|
final double? amountMin,
|
|
final double? amountMax,
|
|
DateTime? dateFrom,
|
|
DateTime? dateTo,
|
|
}) async {
|
|
final now = DateTime.now();
|
|
|
|
final monthStart = DateTime(now.year, now.month - 12);
|
|
final monthEnd = DateTime(now.year, now.month + 1, 0);
|
|
|
|
if (dateFrom == null || dateFrom.compareTo(monthStart) < 0) {
|
|
dateFrom = monthStart;
|
|
}
|
|
|
|
if (dateTo == null || dateTo.compareTo(monthEnd) > 0) {
|
|
dateTo = monthEnd;
|
|
}
|
|
|
|
final Expression<int> yearExpr = _db.transactions.date.year;
|
|
final Expression<int> monthExpr = _db.transactions.date.month;
|
|
final Expression<double> sumExpr = _db.transactions.amount.sum();
|
|
|
|
final JoinedSelectStatement<$TransactionsTable, Transaction> query =
|
|
_db.selectOnly(_db.transactions)
|
|
..addColumns([yearExpr, monthExpr, sumExpr])
|
|
..groupBy([yearExpr, monthExpr])
|
|
..orderBy([OrderingTerm.asc(yearExpr), OrderingTerm.asc(monthExpr)])
|
|
..where(_db.transactions.date.isBiggerOrEqualValue(dateFrom))
|
|
..where(_db.transactions.date.isSmallerOrEqualValue(dateTo));
|
|
|
|
if (account != null) {
|
|
query.where(_db.transactions.accountId.equals(account.id));
|
|
}
|
|
|
|
if (name != null && name.isNotEmpty) {
|
|
query.where(_db.transactions.name.like('%$name%'));
|
|
}
|
|
|
|
if (amountMin != null) {
|
|
query.where(_db.transactions.amount.isBiggerOrEqualValue(amountMin));
|
|
}
|
|
|
|
if (amountMax != null) {
|
|
query.where(_db.transactions.amount.isSmallerOrEqualValue(amountMax));
|
|
}
|
|
|
|
final List<Map<String, Object>> rows = (await query.get()).map((final row) {
|
|
final int year = row.read(yearExpr)!;
|
|
final int month = row.read(monthExpr)!;
|
|
|
|
return {
|
|
'date': DateTime(year, month),
|
|
'balance': (row.read(sumExpr) ?? 0) * -1,
|
|
};
|
|
}).toList();
|
|
|
|
double amount = await balance(account: account, until: dateFrom);
|
|
|
|
DateTime dateTimeLoop = dateFrom;
|
|
int loop = 0;
|
|
|
|
final List<Map<String, Object>> result = [];
|
|
|
|
while (dateTimeLoop.compareTo(monthEnd) < 0) {
|
|
Map<String, Object>? row;
|
|
for (final value in rows) {
|
|
final Object? rowDate = value['date'];
|
|
|
|
if (rowDate is DateTime) {
|
|
if (dateTimeLoop.compareTo(rowDate) == 0) {
|
|
row = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (row == null) {
|
|
result.add({'date': dateTimeLoop, 'balance': 0.0});
|
|
} else {
|
|
result.add(row);
|
|
}
|
|
|
|
final double balance = double.parse(result[loop]['balance'].toString());
|
|
amount = balance + amount;
|
|
|
|
result[loop]['balance'] = amount;
|
|
|
|
loop = loop + 1;
|
|
dateTimeLoop = DateTime(dateTimeLoop.year, dateTimeLoop.month + 1);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|