feat: add recurring entries into the entrylist on start

This commit is contained in:
Matyáš Caras 2024-01-08 21:11:39 +01:00
parent 741fb1f11a
commit 2873848e74
Signed by untrusted user who does not match committer: hernik
GPG key ID: 2A3175F98820C5C6
4 changed files with 97 additions and 29 deletions

View file

@ -1,9 +1,11 @@
import 'package:currency_picker/currency_picker.dart'; import 'package:currency_picker/currency_picker.dart';
import 'package:intl/intl.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:prasule/api/category.dart'; import 'package:prasule/api/category.dart';
import 'package:prasule/api/recurring_entry.dart'; import 'package:prasule/api/recurring_entry.dart';
import 'package:prasule/api/wallet_entry.dart'; import 'package:prasule/api/wallet_entry.dart';
import 'package:prasule/api/wallet_manager.dart'; import 'package:prasule/api/wallet_manager.dart';
import 'package:prasule/main.dart';
part 'wallet.g.dart'; part 'wallet.g.dart';
Currency _currencyFromJson(Map<String, dynamic> data) => Currency _currencyFromJson(Map<String, dynamic> data) =>
@ -70,6 +72,56 @@ class Wallet {
return id; return id;
} }
/// Handles adding recurring entries to the entry list
void recurEntries() {
final n = DateTime.now();
for (final ent in recurringEntries) {
var m = DateTime(
(ent.recurType == RecurType.year)
? ent.lastRunDate.year + ent.repeatAfter
: ent.lastRunDate.year,
(ent.recurType == RecurType.month)
? ent.lastRunDate.month + ent.repeatAfter
: ent.lastRunDate.month,
(ent.recurType == RecurType.day)
? ent.lastRunDate.day + ent.repeatAfter
: ent.lastRunDate.day,
); // create the date after which we should recur
while (n.isAfter(
m,
)) {
logger.i("Adding recurring entry ${ent.data.name}");
recurringEntries[recurringEntries.indexOf(ent)].lastRunDate =
m; // update date on recurring entry
logger.i(recurringEntries[recurringEntries.indexOf(ent)].lastRunDate);
final addedEntry = (recurringEntries[recurringEntries.indexOf(ent)]
as WalletSingleEntry)
..date = DateTime.now()
..id = nextId; // copy entry with today's date and unique ID
entries.add(
addedEntry,
); // add it to entries
m = DateTime(
(ent.recurType == RecurType.year)
? ent.lastRunDate.year + ent.repeatAfter
: ent.lastRunDate.year,
(ent.recurType == RecurType.month)
? ent.lastRunDate.month + ent.repeatAfter
: ent.lastRunDate.month,
(ent.recurType == RecurType.day)
? ent.lastRunDate.day + ent.repeatAfter
: ent.lastRunDate.day,
); // add tne variable again to check if we aren't missing any entries
logger.i(
"Last recurred date is now on ${DateFormat.yMMMMd().format(m)} (${n.isAfter(m)})");
}
WalletManager.saveWallet(this); // save wallet
}
}
/// Removes the specified category. /// Removes the specified category.
/// ///
/// All [WalletSingleEntry]s will have their category reassigned /// All [WalletSingleEntry]s will have their category reassigned

View file

@ -1,4 +1,3 @@
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -11,7 +10,6 @@ import 'package:prasule/api/wallet_manager.dart';
import 'package:prasule/main.dart'; import 'package:prasule/main.dart';
import 'package:prasule/pw/platformbutton.dart'; import 'package:prasule/pw/platformbutton.dart';
import 'package:prasule/pw/platformfield.dart'; import 'package:prasule/pw/platformfield.dart';
import 'package:prasule/util/text_color.dart';
/// Used when user wants to add new entry /// Used when user wants to add new entry
class CreateRecurringEntryView extends StatefulWidget { class CreateRecurringEntryView extends StatefulWidget {
@ -225,6 +223,10 @@ class _CreateRecurringEntryViewState extends State<CreateRecurringEntryView> {
RegExp(r"^0$"), RegExp(r"^0$"),
replacementString: "1", replacementString: "1",
), ),
FilteringTextInputFormatter.deny(
r"\d+[\.,]{0,1}\d{0,}",
replacementString: "1",
),
], ],
onChanged: (s) { onChanged: (s) {
final n = int.tryParse(s); final n = int.tryParse(s);
@ -290,28 +292,7 @@ class _CreateRecurringEntryViewState extends State<CreateRecurringEntryView> {
PlatformButton( PlatformButton(
text: DateFormat.yMMMMd(widget.locale) text: DateFormat.yMMMMd(widget.locale)
.format(newEntry.lastRunDate), .format(newEntry.lastRunDate),
style: (widget.editEntry != null)
? ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Colors.grey.harmonizeWith(
Theme.of(context).colorScheme.primary,
),
),
foregroundColor: MaterialStateProperty.all(
Colors.grey
.harmonizeWith(
Theme.of(context).colorScheme.primary,
)
.calculateTextColor()
.harmonizeWith(
Theme.of(context).colorScheme.primary),
),
)
: null,
onPressed: () async { onPressed: () async {
if (widget.editEntry != null) {
return; // disabled on edit
}
final d = await showDatePicker( final d = await showDatePicker(
context: context, context: context,
firstDate: DateTime.now(), firstDate: DateTime.now(),

View file

@ -15,6 +15,7 @@ import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:prasule/api/category.dart'; import 'package:prasule/api/category.dart';
import 'package:prasule/api/entry_data.dart'; import 'package:prasule/api/entry_data.dart';
import 'package:prasule/api/recurring_entry.dart';
import 'package:prasule/api/wallet.dart'; import 'package:prasule/api/wallet.dart';
import 'package:prasule/api/wallet_entry.dart'; import 'package:prasule/api/wallet_entry.dart';
import 'package:prasule/api/wallet_manager.dart'; import 'package:prasule/api/wallet_manager.dart';
@ -67,6 +68,7 @@ class _HomeViewState extends State<HomeView> {
return; return;
} }
selectedWallet = wallets.first; selectedWallet = wallets.first;
selectedWallet!.recurEntries();
setState(() {}); setState(() {});
} }
@ -86,6 +88,7 @@ class _HomeViewState extends State<HomeView> {
// debug option to quickly fill a wallet with data // debug option to quickly fill a wallet with data
if (selectedWallet == null) return; if (selectedWallet == null) return;
selectedWallet!.entries.clear(); selectedWallet!.entries.clear();
selectedWallet!.recurringEntries.clear();
final random = Random(); final random = Random();
for (var i = 0; i < 30; i++) { for (var i = 0; i < 30; i++) {
selectedWallet!.entries.add( selectedWallet!.entries.add(
@ -109,7 +112,41 @@ class _HomeViewState extends State<HomeView> {
); );
} }
logger.i(selectedWallet!.entries.length); logger.d(
"Created ${selectedWallet!.entries.length} regular entries",
);
for (var i = 0; i < 3; i++) {
final type = random.nextInt(3);
selectedWallet!.recurringEntries.add(
RecurringWalletEntry(
data: EntryData(
name: "Recurring Entry #${i + 1}",
amount: random.nextInt(20000).toDouble(),
),
type: (random.nextInt(3) > 0)
? EntryType.expense
: EntryType.income,
date: DateTime(
2023,
random.nextInt(12) + 1,
random.nextInt(28) + 1,
),
category: selectedWallet!.categories[
random.nextInt(selectedWallet!.categories.length)],
id: selectedWallet!.nextId,
lastRunDate: DateTime.now().subtract(
Duration(
days: (type > 0) ? 3 : 3 * 31,
),
),
recurType: (type > 0) ? RecurType.day : RecurType.month,
),
);
}
logger.d(
"Created ${selectedWallet!.recurringEntries.length} recurring entries");
// save and reload // save and reload
WalletManager.saveWallet(selectedWallet!).then((value) { WalletManager.saveWallet(selectedWallet!).then((value) {

View file

@ -129,6 +129,7 @@ class _RecurringEntriesViewState extends State<RecurringEntriesView> {
], ],
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
shape: const CircleBorder(),
child: const Icon(Icons.add), child: const Icon(Icons.add),
onPressed: () { onPressed: () {
Navigator.of(context).push( Navigator.of(context).push(
@ -225,11 +226,8 @@ class _RecurringEntriesViewState extends State<RecurringEntriesView> {
text: AppLocalizations.of(context).yes, text: AppLocalizations.of(context).yes,
onPressed: () { onPressed: () {
selectedWallet!.recurringEntries selectedWallet!.recurringEntries
.removeWhere( .remove(
(e) => selectedWallet!.recurringEntries[i],
e.id ==
selectedWallet!
.recurringEntries[i].id,
); );
WalletManager.saveWallet( WalletManager.saveWallet(
selectedWallet!, selectedWallet!,