import 'dart:async'; import 'package:isar/isar.dart'; import 'package:get_it/get_it.dart'; import 'package:okane/database/collections/account.dart'; import 'package:okane/database/collections/beneficiary.dart'; import 'package:okane/database/collections/expense_category.dart'; import 'package:okane/database/collections/recurrent.dart'; import 'package:okane/database/collections/template.dart'; import 'package:okane/database/collections/transaction.dart'; import 'package:okane/ui/state/core.dart'; import 'package:okane/ui/utils.dart'; import 'package:path_provider/path_provider.dart'; import 'collections/budget.dart'; Future openDatabase() async { final dir = await getApplicationDocumentsDirectory(); return Isar.open([ AccountSchema, BeneficiarySchema, TransactionSchema, TransactionTemplateSchema, RecurringTransactionSchema, ExpenseCategorySchema, BudgetSchema, BudgetItemSchema, ], directory: dir.path); } Future> getAccounts() { return GetIt.I.get().accounts.where().findAll(); } Future getTotalBalance(Account account) async { return GetIt.I .get() .transactions .filter() .account((q) => q.idEqualTo(account.id)) .amountProperty() .sum(); } Future> getLastTransactions( Account account, DateTime today, int days, ) async { return GetIt.I .get() .transactions .filter() .account((q) => q.idEqualTo(account.id)) .dateGreaterThan(toMidnight(today.subtract(Duration(days: days)))) .findAll(); } Future> getRecurringTransactions(Account? account) { if (account == null) { return Future.value([]); } return GetIt.I .get() .recurringTransactions .filter() .account((q) => q.idEqualTo(account.id)) .findAll(); } Stream watchRecurringTransactions(Account account) { final account = GetIt.I.get().activeAccount!; return GetIt.I .get() .recurringTransactions .filter() .account((q) => q.idEqualTo(account.id)) .build() .watchLazy(fireImmediately: true); } Future upsertAccount(Account account) async { final db = GetIt.I.get(); return db.writeTxn(() async { print("Before account insert"); final id = await db.accounts.put(account); print("After account insert: $id"); }); } Future upsertBeneficiary(Beneficiary beneficiary) async { final db = GetIt.I.get(); return db.writeTxn(() async { await db.beneficiarys.put(beneficiary); await beneficiary.account.save(); }); } Future getAccountBeneficiary(Account account) { return GetIt.I .get() .beneficiarys .filter() .account((q) => q.idEqualTo(account.id)) .findFirst(); } Future upsertTransactionTemplate(TransactionTemplate template) async { final db = GetIt.I.get(); return db.writeTxn(() async { await db.transactionTemplates.put(template); await template.beneficiary.save(); await template.account.save(); await template.expenseCategory.save(); }); } Future upsertRecurringTransaction(RecurringTransaction template) async { final db = GetIt.I.get(); return db.writeTxn(() async { await db.recurringTransactions.put(template); await template.template.save(); await template.account.save(); }); } Future upsertTransaction(Transaction transaction) async { final db = GetIt.I.get(); return db.writeTxn(() async { await db.transactions.put(transaction); await transaction.beneficiary.save(); await transaction.account.save(); await transaction.expenseCategory.save(); }); } Stream watchAccounts() { return GetIt.I.get().accounts.watchLazy(); } Stream watchTransactionTemplates(Account account) { return GetIt.I .get() .transactionTemplates .filter() .account((q) => q.idEqualTo(account.id)) .recurringEqualTo(false) .watchLazy(fireImmediately: true); } Future> getTransactionTemplates(Account? account) { if (account == null) { return Future.value([]); } return GetIt.I .get() .transactionTemplates .filter() .account((q) => q.idEqualTo(account.id)) .recurringEqualTo(false) .findAll(); } Stream watchTransactions(Account account) { return GetIt.I .get() .transactions .filter() .account((q) => q.idEqualTo(account.id)) .watchLazy(fireImmediately: true); } Future> getTransactions(Account? account) { if (account == null) { return Future.value([]); } return GetIt.I .get() .transactions .filter() .account((q) => q.idEqualTo(account.id)) .findAll(); } Stream watchBeneficiaries() { return GetIt.I.get().beneficiarys.watchLazy(fireImmediately: true); } Future> getBeneficiaries() { return GetIt.I.get().beneficiarys.where().findAll(); } Stream watchBeneficiaryObject(Id id) { return GetIt.I.get().beneficiarys.watchObject(id); } Future upsertExpenseCategory(ExpenseCategory category) { final db = GetIt.I.get(); return db.writeTxn(() => db.expenseCategorys.put(category)); } Future> getExpenseCategories() { return GetIt.I.get().expenseCategorys.where().findAll(); } Stream watchExpenseCategory() { return GetIt.I.get().expenseCategorys.watchLazy(fireImmediately: true); } Stream watchBudgets(Account account) { return GetIt.I.get().budgets.filter().account((q) => q.idEqualTo(account.id)).watchLazy(fireImmediately: true); } Future> getBudgets(Account? account) { if (account == null) { return Future.value([]); } return GetIt.I.get().budgets.filter().account((q) => q.idEqualTo(account.id)).findAll(); } Future upsertBudget(Budget budget) { final db = GetIt.I.get(); return db.writeTxn(() async { await db.budgets.put(budget); await budget.items.save(); await budget.account.save(); }); } Future upsertBudgetItem(BudgetItem item) { final db = GetIt.I.get(); return db.writeTxn(() async { await db.budgetItems.put(item); await item.expenseCategory.save(); }); } enum TransactionQueryDateOption { thisMonth, } Future> getTransactionsInTimeframe(Account account, DateTime today, TransactionQueryDateOption option) async { final lower = switch (option) { TransactionQueryDateOption.thisMonth => DateTime( today.year, today.month, 0, ), }; final upper = switch (option) { TransactionQueryDateOption.thisMonth => monthEnding(today), }; return GetIt.I.get() .transactions .filter() .account((q) => q.idEqualTo(account.id)) .dateBetween(lower, upper) .findAll(); }