Start migration to sqlite using drift

This commit is contained in:
2025-05-17 23:51:51 +02:00
parent 4d267eff88
commit 5dc474407c
50 changed files with 9549 additions and 6972 deletions

View File

@@ -1,7 +1,7 @@
import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:okane/database/collections/budget.dart';
import 'package:okane/database/database.dart';
import 'package:okane/database/sqlite.dart';
import 'package:okane/i18n/strings.g.dart';
import 'package:okane/ui/state/core.dart';
@@ -52,14 +52,17 @@ class AddBudgetState extends State<AddBudgetPopup> {
}
final bloc = GetIt.I.get<CoreCubit>();
final budget =
Budget()
..name = _budgetNameEditController.text
..period = BudgetPeriod.month
..includeOtherSpendings = false
..income = double.parse(_budgetIncomeEditController.text)
..account.value = bloc.activeAccount!;
await upsertBudget(budget);
await GetIt.I.get<OkaneDatabase>().budgetsDao.upsertBudget(
BudgetsCompanion(
name: Value(_budgetNameEditController.text),
period: Value(BudgetPeriod.month),
includeOtherSpendings: Value(false),
income: Value(
double.parse(_budgetIncomeEditController.text),
),
accountId: Value(bloc.activeAccount!.id),
),
);
widget.onDone();
},
child: Text(t.modals.add),

View File

@@ -1,16 +1,14 @@
import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:okane/database/collections/budget.dart';
import 'package:okane/database/collections/expense_category.dart';
import 'package:okane/database/database.dart';
import 'package:okane/database/sqlite.dart';
import 'package:okane/i18n/strings.g.dart';
import 'package:okane/ui/state/core.dart';
import 'package:okane/ui/utils.dart';
import 'package:okane/ui/widgets/add_expense_category.dart';
class AddBudgetItemPopup extends StatefulWidget {
final VoidCallback onDone;
final Budget budget;
final BudgetsDto budget;
const AddBudgetItemPopup({
super.key,
@@ -74,26 +72,24 @@ class AddBudgetItemState extends State<AddBudgetItemPopup> {
_expenseCategory == null) {
return;
}
if (widget.budget.items
if (widget.budget.budgetItems
.where(
(i) =>
i.expenseCategory.value!.name ==
_expenseCategory!.name,
i.expenseCategory.name == _expenseCategory!.name,
)
.firstOrNull !=
null) {
return;
}
final item =
BudgetItem()
..expenseCategory.value = _expenseCategory
..amount = double.parse(
_budgetItemAmountEditController.text,
);
await upsertBudgetItem(item);
widget.budget.items.add(item);
await upsertBudget(widget.budget);
await GetIt.I.get<OkaneDatabase>().budgetsDao.upsertBudgetItem(
BudgetItemsCompanion(
expenseCategoryId: Value(_expenseCategory!.id),
amount: Value(
double.parse(_budgetItemAmountEditController.text),
),
),
);
widget.onDone();
},
child: Text(t.modals.add),

View File

@@ -1,8 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import 'package:okane/database/collections/budget.dart';
import 'package:okane/database/database.dart';
import 'package:okane/database/sqlite.dart';
import 'package:okane/i18n/strings.g.dart';
import 'package:okane/ui/pages/budgets/add_budget_item.dart';
import 'package:okane/ui/state/core.dart';
@@ -56,7 +55,7 @@ class BudgetDetailsPage extends StatelessWidget {
return Text(t.pages.budgets.details.noBudgetSelected);
}
if (state.activeBudget!.items.isEmpty) {
if (state.activeBudget!.budgetItems.isEmpty) {
return Row(
children: [
Text(t.pages.budgets.details.noBudgetItems),
@@ -73,14 +72,15 @@ class BudgetDetailsPage extends StatelessWidget {
final bloc = GetIt.I.get<CoreCubit>();
final today = DateTime.now();
final db = GetIt.I.get<OkaneDatabase>();
return FutureBuilder(
future: getTransactionsInTimeframe(
future: db.transactionsDao.getTransactionsInTimeframe(
bloc.activeAccount!,
today,
TransactionQueryDateOption.thisMonth,
),
builder: (context, snapshot) {
final daysLeft = switch (state.activeBudget!.period) {
final daysLeft = switch (state.activeBudget!.budget.period) {
BudgetPeriod.month =>
monthEnding(today).difference(today).inDays,
};
@@ -95,16 +95,17 @@ class BudgetDetailsPage extends StatelessWidget {
),
ListView.builder(
shrinkWrap: true,
itemCount: state.activeBudget!.items.length,
itemCount: state.activeBudget!.budgetItems.length,
itemBuilder: (context, index) {
final item = state.activeBudget!.items.elementAt(
index,
);
final amount = formatCurrency(item.amount);
final item = state.activeBudget!.budgetItems
.elementAt(index);
final amount = formatCurrency(item.item.amount);
return ListTile(
title: Text(
t.pages.budgets.details.items.title(
name: item.expenseCategory.value!.name,
// TODO
name: "lol",
//name: item.expenseCategory.value!.name,
amount: amount,
),
),
@@ -119,26 +120,28 @@ class BudgetDetailsPage extends StatelessWidget {
}
final categories =
state.activeBudget!.items
.map((i) => i.expenseCategory.value!.name)
state.activeBudget!.budgetItems
// TODO
//.map((i) => i.expenseCategory.value!.name)
.map((i) => "lol")
.toList();
final spending = <String, double>{};
for (final t in snapshot.data!) {
String categoryName;
if (!categories.contains(t.expenseCategory.value?.name)) {
if (!state.activeBudget!.includeOtherSpendings) {
if (!categories.contains(t.expenseCategory?.name)) {
if (!state.activeBudget!.budget.includeOtherSpendings) {
continue;
}
categoryName = "Other";
} else {
categoryName = t.expenseCategory.value!.name;
categoryName = t.expenseCategory!.name;
}
spending.update(
categoryName,
(value) => value + t.amount,
ifAbsent: () => t.amount,
(value) => value + t.transaction.amount,
ifAbsent: () => t.transaction.amount,
);
}
@@ -146,8 +149,8 @@ class BudgetDetailsPage extends StatelessWidget {
spending.isEmpty
? 0
: spending.values.reduce((acc, val) => acc + val);
final budgetTotal = state.activeBudget!.items
.map((i) => i.amount)
final budgetTotal = state.activeBudget!.budgetItems
.map((i) => i.item.amount)
.reduce((acc, val) => acc + val);
return Column(
mainAxisSize: MainAxisSize.min,
@@ -268,13 +271,13 @@ class BudgetDetailsPage extends StatelessWidget {
fallbackText: "",
valueConverter: formatCurrency,
items:
state.activeBudget!.items
state.activeBudget!.budgetItems
.map(
(i) => (
title: i.expenseCategory.value!.name,
value: i.amount,
title: i.expenseCategory.name,
value: i.item.amount,
color: colorHash(
i.expenseCategory.value!.name,
i.expenseCategory.name,
),
),
)
@@ -339,18 +342,16 @@ class BudgetDetailsPage extends StatelessWidget {
padding: EdgeInsets.all(8),
child: ListView.builder(
shrinkWrap: true,
itemCount: state.activeBudget!.items.length,
itemCount: state.activeBudget!.budgetItems.length,
itemBuilder: (context, index) {
final item = state.activeBudget!.items.elementAt(
index,
);
final amount = formatCurrency(item.amount);
final spent =
spending[item.expenseCategory.value!.name];
final item = state.activeBudget!.budgetItems
.elementAt(index);
final amount = formatCurrency(item.item.amount);
final spent = spending[item.expenseCategory.name];
final left =
spent == null
? item.amount
: item.amount + spent;
? item.item.amount
: item.item.amount + spent;
final subtitleText =
left < 0
? t.pages.budgets.details.items.over(
@@ -361,7 +362,7 @@ class BudgetDetailsPage extends StatelessWidget {
);
return ListTile(
title: Text(
"${item.expenseCategory.value!.name} ($amount)",
"${item.expenseCategory.name} ($amount)",
),
subtitle: Text(
subtitleText,

View File

@@ -28,7 +28,7 @@ class BudgetListPage extends StatelessWidget {
itemCount: state.budgets.length,
itemBuilder:
(context, index) => ListTile(
title: Text(state.budgets[index].name),
title: Text(state.budgets[index].budget.name),
selected: state.budgets[index] == state.activeBudget,
trailing: Row(
mainAxisSize: MainAxisSize.min,

View File

@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:okane/database/collections/budget.dart';
import 'package:okane/database/database.dart';
import 'package:get_it/get_it.dart';
import 'package:okane/database/sqlite.dart';
import 'package:okane/i18n/strings.g.dart';
class EditBudgetPopup extends StatefulWidget {
final Budget budget;
final BudgetsDto budget;
final VoidCallback onDone;
@@ -27,8 +27,8 @@ class EditBudgetState extends State<EditBudgetPopup> {
void initState() {
super.initState();
_budgetNameEditController.text = widget.budget.name;
_includeOtherSpendings = widget.budget.includeOtherSpendings;
_budgetNameEditController.text = widget.budget.budget.name;
_includeOtherSpendings = widget.budget.budget.includeOtherSpendings;
}
@override
@@ -61,17 +61,22 @@ class EditBudgetState extends State<EditBudgetPopup> {
if (_budgetNameEditController.text.isEmpty) {
return;
}
if (_budgetNameEditController.text == widget.budget.name &&
if (_budgetNameEditController.text ==
widget.budget.budget.name &&
_includeOtherSpendings ==
widget.budget.includeOtherSpendings) {
widget.budget.budget.includeOtherSpendings) {
widget.onDone();
return;
}
widget.budget
..name = _budgetNameEditController.text
..includeOtherSpendings = _includeOtherSpendings;
await upsertBudget(widget.budget);
await GetIt.I.get<OkaneDatabase>().budgetsDao.upsertBudget(
widget.budget.budget
.copyWith(
name: _budgetNameEditController.text,
includeOtherSpendings: _includeOtherSpendings,
)
.toCompanion(false),
);
widget.onDone();
},
child: Text(t.modals.save),