This commit is contained in:
PapaTutuWawa 2025-05-18 15:09:05 +02:00
parent facbc16bb2
commit baf0dfa99d
7 changed files with 72 additions and 42 deletions

View File

@ -75,13 +75,8 @@ class LoanChanges extends Table {
class LoanDto { class LoanDto {
final Loan loan; final Loan loan;
final Beneficiary beneficiary; final Beneficiary beneficiary;
final List<LoanChange> changes;
LoanDto({ LoanDto({required this.loan, required this.beneficiary});
required this.loan,
required this.beneficiary,
required this.changes,
});
} }
class RecurringTransactions extends Table { class RecurringTransactions extends Table {
@ -454,12 +449,10 @@ class LoansDao extends DatabaseAccessor<OkaneDatabase> with _$LoansDaoMixin {
.watch() .watch()
.map((rows) { .map((rows) {
return rows.map((row) { return rows.map((row) {
return ( return LoanDto(
loan: row.readTable(loans), loan: row.readTable(loans),
beneficiary: row.readTable(beneficiaries), beneficiary: row.readTable(beneficiaries),
changes: List.empty(), );
)
as LoanDto;
}).toList(); }).toList();
}); });
} }
@ -479,12 +472,10 @@ class LoansDao extends DatabaseAccessor<OkaneDatabase> with _$LoansDaoMixin {
.get() .get()
.then((rows) { .then((rows) {
return rows.map((row) { return rows.map((row) {
return ( return LoanDto(
loan: row.readTable(loans), loan: row.readTable(loans),
beneficiary: row.readTable(beneficiaries), beneficiary: row.readTable(beneficiaries),
changes: List.empty(), );
)
as LoanDto;
}).toList(); }).toList();
}); });
} }
@ -508,6 +499,11 @@ class LoansDao extends DatabaseAccessor<OkaneDatabase> with _$LoansDaoMixin {
).insertReturning(loanChange, mode: InsertMode.insertOrReplace); ).insertReturning(loanChange, mode: InsertMode.insertOrReplace);
} }
Stream<List<LoanChange>> watchLoanChanges(Loan loan) {
return (select(loanChanges)
..where((c) => c.loanId.equals(loan.id))).watch();
}
Future<void> deleteLoanChange(int id) { Future<void> deleteLoanChange(int id) {
return (delete(loanChanges)..where((c) => c.id.equals(id))).go(); return (delete(loanChanges)..where((c) => c.id.equals(id))).go();
} }

View File

@ -44,7 +44,7 @@ class AccountListPageState extends State<AccountListPage> {
width: 150, width: 150,
height: 100, height: 100,
child: Card( child: Card(
color: colorHash(state.accounts[index].name!), color: colorHash(state.accounts[index].name),
shape: shape:
index == state.activeAccountIndex index == state.activeAccountIndex
? RoundedRectangleBorder( ? RoundedRectangleBorder(
@ -61,7 +61,7 @@ class AccountListPageState extends State<AccountListPage> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text(state.accounts[index].name!), Text(state.accounts[index].name),
FutureBuilder( FutureBuilder(
future: GetIt.I future: GetIt.I
.get<OkaneDatabase>() .get<OkaneDatabase>()

View File

@ -91,6 +91,7 @@ class AddLoanPopupState extends State<AddLoanChangePopup> {
sign * double.parse(_amountController.text).abs(), sign * double.parse(_amountController.text).abs(),
), ),
date: Value(DateTime.now()), date: Value(DateTime.now()),
loanId: Value(widget.loan.loan.id),
), ),
); );
widget.onDone(); widget.onDone();

View File

@ -43,10 +43,9 @@ class LoanDetailsPage extends StatelessWidget {
return Text("No loan selected"); return Text("No loan selected");
} }
final loanChanges = state.activeLoan!.changes.toList();
final loanSum = final loanSum =
loanChanges.isNotEmpty state.loanChanges.isNotEmpty
? loanChanges ? state.loanChanges
.map((c) => c.amount) .map((c) => c.amount)
.reduce((acc, val) => acc + val) .reduce((acc, val) => acc + val)
: 0.0; : 0.0;
@ -94,9 +93,9 @@ class LoanDetailsPage extends StatelessWidget {
SliverToBoxAdapter( SliverToBoxAdapter(
child: child:
loanChanges.isNotEmpty state.loanChanges.isNotEmpty
? GroupedListView( ? GroupedListView(
elements: loanChanges, elements: state.loanChanges,
shrinkWrap: true, shrinkWrap: true,
reverse: true, reverse: true,
groupBy: groupBy:

View File

@ -23,6 +23,7 @@ abstract class CoreState with _$CoreState {
@Default([]) List<BudgetItemDto> budgetItems, @Default([]) List<BudgetItemDto> budgetItems,
@Default(null) BudgetsDto? activeBudget, @Default(null) BudgetsDto? activeBudget,
@Default([]) List<LoanDto> loans, @Default([]) List<LoanDto> loans,
@Default([]) List<LoanChange> loanChanges,
@Default(null) LoanDto? activeLoan, @Default(null) LoanDto? activeLoan,
@Default(false) bool isDeletingAccount, @Default(false) bool isDeletingAccount,
}) = _CoreState; }) = _CoreState;
@ -40,6 +41,7 @@ class CoreCubit extends Cubit<CoreState> {
StreamSubscription<void>? _budgetsStreamSubscription; StreamSubscription<void>? _budgetsStreamSubscription;
StreamSubscription<void>? _budgetItemsStreamSubscription; StreamSubscription<void>? _budgetItemsStreamSubscription;
StreamSubscription<void>? _loanStreamSubscription; StreamSubscription<void>? _loanStreamSubscription;
StreamSubscription<void>? _loanChangesSubscription;
void setupAccountStream() { void setupAccountStream() {
_accountsStreamSubscription?.cancel(); _accountsStreamSubscription?.cancel();
@ -95,7 +97,6 @@ class CoreCubit extends Cubit<CoreState> {
_budgetsStreamSubscription = db.budgetsDao _budgetsStreamSubscription = db.budgetsDao
.budgetsStream(activeAccount!) .budgetsStream(activeAccount!)
.listen((budgets) async { .listen((budgets) async {
print("BUDGETS: $budgets");
emit(state.copyWith(budgets: budgets)); emit(state.copyWith(budgets: budgets));
}); });
_loanStreamSubscription?.cancel(); _loanStreamSubscription?.cancel();
@ -125,17 +126,6 @@ class CoreCubit extends Cubit<CoreState> {
state.copyWith( state.copyWith(
accounts: accounts, accounts: accounts,
activeAccountIndex: accounts.isEmpty ? null : 0, activeAccountIndex: accounts.isEmpty ? null : 0,
transactions: await db.transactionsDao.getTransactions(account),
beneficiaries: await db.beneficiariesDao.getBeneficiaries(),
transactionTemplates: await db.transactionTemplatesDao
.getTransactionTemplates(account),
recurringTransactions: await db.recurringTransactionsDao
.getRecurringTransactions(account),
expenseCategories: await db.expenseCategoriesDao.getExpenseCategories(
account,
),
//budgets: await db.budgetsDao.getBudgets(account),
loans: await db.loansDao.getLoans(account),
), ),
); );
@ -211,8 +201,18 @@ class CoreCubit extends Cubit<CoreState> {
await init(); await init();
} }
void setActiveLoan(LoanDto loan) { void setActiveLoan(LoanDto? loan) {
emit(state.copyWith(activeLoan: loan)); emit(state.copyWith(activeLoan: loan, loanChanges: []));
_loanChangesSubscription?.cancel();
if (loan != null) {
_loanChangesSubscription = GetIt.I
.get<OkaneDatabase>()
.loansDao
.watchLoanChanges(loan.loan)
.listen((changes) {
emit(state.copyWith(loanChanges: changes));
});
}
} }
Account? get activeAccount => Account? get activeAccount =>

View File

@ -33,6 +33,7 @@ mixin _$CoreState {
List<BudgetItemDto> get budgetItems => throw _privateConstructorUsedError; List<BudgetItemDto> get budgetItems => throw _privateConstructorUsedError;
BudgetsDto? get activeBudget => throw _privateConstructorUsedError; BudgetsDto? get activeBudget => throw _privateConstructorUsedError;
List<LoanDto> get loans => throw _privateConstructorUsedError; List<LoanDto> get loans => throw _privateConstructorUsedError;
List<LoanChange> get loanChanges => throw _privateConstructorUsedError;
LoanDto? get activeLoan => throw _privateConstructorUsedError; LoanDto? get activeLoan => throw _privateConstructorUsedError;
bool get isDeletingAccount => throw _privateConstructorUsedError; bool get isDeletingAccount => throw _privateConstructorUsedError;
@ -60,6 +61,7 @@ abstract class $CoreStateCopyWith<$Res> {
List<BudgetItemDto> budgetItems, List<BudgetItemDto> budgetItems,
BudgetsDto? activeBudget, BudgetsDto? activeBudget,
List<LoanDto> loans, List<LoanDto> loans,
List<LoanChange> loanChanges,
LoanDto? activeLoan, LoanDto? activeLoan,
bool isDeletingAccount, bool isDeletingAccount,
}); });
@ -91,6 +93,7 @@ class _$CoreStateCopyWithImpl<$Res, $Val extends CoreState>
Object? budgetItems = null, Object? budgetItems = null,
Object? activeBudget = freezed, Object? activeBudget = freezed,
Object? loans = null, Object? loans = null,
Object? loanChanges = null,
Object? activeLoan = freezed, Object? activeLoan = freezed,
Object? isDeletingAccount = null, Object? isDeletingAccount = null,
}) { }) {
@ -161,6 +164,11 @@ class _$CoreStateCopyWithImpl<$Res, $Val extends CoreState>
? _value.loans ? _value.loans
: loans // ignore: cast_nullable_to_non_nullable : loans // ignore: cast_nullable_to_non_nullable
as List<LoanDto>, as List<LoanDto>,
loanChanges:
null == loanChanges
? _value.loanChanges
: loanChanges // ignore: cast_nullable_to_non_nullable
as List<LoanChange>,
activeLoan: activeLoan:
freezed == activeLoan freezed == activeLoan
? _value.activeLoan ? _value.activeLoan
@ -200,6 +208,7 @@ abstract class _$$CoreStateImplCopyWith<$Res>
List<BudgetItemDto> budgetItems, List<BudgetItemDto> budgetItems,
BudgetsDto? activeBudget, BudgetsDto? activeBudget,
List<LoanDto> loans, List<LoanDto> loans,
List<LoanChange> loanChanges,
LoanDto? activeLoan, LoanDto? activeLoan,
bool isDeletingAccount, bool isDeletingAccount,
}); });
@ -230,6 +239,7 @@ class __$$CoreStateImplCopyWithImpl<$Res>
Object? budgetItems = null, Object? budgetItems = null,
Object? activeBudget = freezed, Object? activeBudget = freezed,
Object? loans = null, Object? loans = null,
Object? loanChanges = null,
Object? activeLoan = freezed, Object? activeLoan = freezed,
Object? isDeletingAccount = null, Object? isDeletingAccount = null,
}) { }) {
@ -300,6 +310,11 @@ class __$$CoreStateImplCopyWithImpl<$Res>
? _value._loans ? _value._loans
: loans // ignore: cast_nullable_to_non_nullable : loans // ignore: cast_nullable_to_non_nullable
as List<LoanDto>, as List<LoanDto>,
loanChanges:
null == loanChanges
? _value._loanChanges
: loanChanges // ignore: cast_nullable_to_non_nullable
as List<LoanChange>,
activeLoan: activeLoan:
freezed == activeLoan freezed == activeLoan
? _value.activeLoan ? _value.activeLoan
@ -332,6 +347,7 @@ class _$CoreStateImpl implements _CoreState {
final List<BudgetItemDto> budgetItems = const [], final List<BudgetItemDto> budgetItems = const [],
this.activeBudget = null, this.activeBudget = null,
final List<LoanDto> loans = const [], final List<LoanDto> loans = const [],
final List<LoanChange> loanChanges = const [],
this.activeLoan = null, this.activeLoan = null,
this.isDeletingAccount = false, this.isDeletingAccount = false,
}) : _accounts = accounts, }) : _accounts = accounts,
@ -342,7 +358,8 @@ class _$CoreStateImpl implements _CoreState {
_expenseCategories = expenseCategories, _expenseCategories = expenseCategories,
_budgets = budgets, _budgets = budgets,
_budgetItems = budgetItems, _budgetItems = budgetItems,
_loans = loans; _loans = loans,
_loanChanges = loanChanges;
@override @override
@JsonKey() @JsonKey()
@ -439,6 +456,15 @@ class _$CoreStateImpl implements _CoreState {
return EqualUnmodifiableListView(_loans); return EqualUnmodifiableListView(_loans);
} }
final List<LoanChange> _loanChanges;
@override
@JsonKey()
List<LoanChange> get loanChanges {
if (_loanChanges is EqualUnmodifiableListView) return _loanChanges;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_loanChanges);
}
@override @override
@JsonKey() @JsonKey()
final LoanDto? activeLoan; final LoanDto? activeLoan;
@ -448,7 +474,7 @@ class _$CoreStateImpl implements _CoreState {
@override @override
String toString() { String toString() {
return 'CoreState(activePage: $activePage, activeAccountIndex: $activeAccountIndex, activeTransaction: $activeTransaction, accounts: $accounts, recurringTransactions: $recurringTransactions, transactions: $transactions, transactionTemplates: $transactionTemplates, beneficiaries: $beneficiaries, expenseCategories: $expenseCategories, budgets: $budgets, budgetItems: $budgetItems, activeBudget: $activeBudget, loans: $loans, activeLoan: $activeLoan, isDeletingAccount: $isDeletingAccount)'; return 'CoreState(activePage: $activePage, activeAccountIndex: $activeAccountIndex, activeTransaction: $activeTransaction, accounts: $accounts, recurringTransactions: $recurringTransactions, transactions: $transactions, transactionTemplates: $transactionTemplates, beneficiaries: $beneficiaries, expenseCategories: $expenseCategories, budgets: $budgets, budgetItems: $budgetItems, activeBudget: $activeBudget, loans: $loans, loanChanges: $loanChanges, activeLoan: $activeLoan, isDeletingAccount: $isDeletingAccount)';
} }
@override @override
@ -491,6 +517,10 @@ class _$CoreStateImpl implements _CoreState {
(identical(other.activeBudget, activeBudget) || (identical(other.activeBudget, activeBudget) ||
other.activeBudget == activeBudget) && other.activeBudget == activeBudget) &&
const DeepCollectionEquality().equals(other._loans, _loans) && const DeepCollectionEquality().equals(other._loans, _loans) &&
const DeepCollectionEquality().equals(
other._loanChanges,
_loanChanges,
) &&
(identical(other.activeLoan, activeLoan) || (identical(other.activeLoan, activeLoan) ||
other.activeLoan == activeLoan) && other.activeLoan == activeLoan) &&
(identical(other.isDeletingAccount, isDeletingAccount) || (identical(other.isDeletingAccount, isDeletingAccount) ||
@ -513,6 +543,7 @@ class _$CoreStateImpl implements _CoreState {
const DeepCollectionEquality().hash(_budgetItems), const DeepCollectionEquality().hash(_budgetItems),
activeBudget, activeBudget,
const DeepCollectionEquality().hash(_loans), const DeepCollectionEquality().hash(_loans),
const DeepCollectionEquality().hash(_loanChanges),
activeLoan, activeLoan,
isDeletingAccount, isDeletingAccount,
); );
@ -539,6 +570,7 @@ abstract class _CoreState implements CoreState {
final List<BudgetItemDto> budgetItems, final List<BudgetItemDto> budgetItems,
final BudgetsDto? activeBudget, final BudgetsDto? activeBudget,
final List<LoanDto> loans, final List<LoanDto> loans,
final List<LoanChange> loanChanges,
final LoanDto? activeLoan, final LoanDto? activeLoan,
final bool isDeletingAccount, final bool isDeletingAccount,
}) = _$CoreStateImpl; }) = _$CoreStateImpl;
@ -570,6 +602,8 @@ abstract class _CoreState implements CoreState {
@override @override
List<LoanDto> get loans; List<LoanDto> get loans;
@override @override
List<LoanChange> get loanChanges;
@override
LoanDto? get activeLoan; LoanDto? get activeLoan;
@override @override
bool get isDeletingAccount; bool get isDeletingAccount;

View File

@ -25,7 +25,7 @@ class AccountSwitcher extends StatelessWidget {
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = state.accounts[index]; final item = state.accounts[index];
return ListTile( return ListTile(
title: Text(item.name!), title: Text(item.name),
trailing: IconButton( trailing: IconButton(
icon: Icon(Icons.delete), icon: Icon(Icons.delete),
color: Colors.red, color: Colors.red,