prasule/lib/api/wallet.dart

178 lines
5.6 KiB
Dart
Raw Normal View History

2023-09-08 11:50:21 +02:00
import 'package:currency_picker/currency_picker.dart';
import 'package:intl/intl.dart';
2023-09-08 11:50:21 +02:00
import 'package:json_annotation/json_annotation.dart';
import 'package:prasule/api/category.dart';
import 'package:prasule/api/recurring_entry.dart';
import 'package:prasule/api/wallet_entry.dart';
import 'package:prasule/api/wallet_manager.dart';
import 'package:prasule/main.dart';
2023-09-08 11:50:21 +02:00
part 'wallet.g.dart';
Currency _currencyFromJson(Map<String, dynamic> data) =>
Currency.from(json: data);
/// Represents a single wallet
///
/// A wallet stores [WalletSingleEntry]s categorized under [WalletCategory]s
2023-09-08 11:50:21 +02:00
@JsonSerializable()
class Wallet {
/// A wallet stores [WalletSingleEntry]s categorized under [WalletCategory]s
Wallet({
required this.name,
required this.currency,
this.categories = const [],
this.entries = const [],
this.recurringEntries = const [],
this.starterBalance = 0,
});
2023-09-08 11:50:21 +02:00
/// Connects generated fromJson method
2023-09-08 11:50:21 +02:00
factory Wallet.fromJson(Map<String, dynamic> json) => _$WalletFromJson(json);
/// A list of all [RecurringWalletEntry]s
final List<RecurringWalletEntry> recurringEntries;
/// Name of the wallet
final String name;
/// A list of available categories
final List<WalletCategory> categories;
/// List of saved entries
final List<WalletSingleEntry> entries;
/// The starting balance of the wallet
///
/// Used to calculate current balance
double starterBalance;
/// Selected currency
@JsonKey(fromJson: _currencyFromJson)
final Currency currency;
/// Connects generated toJson method
2023-09-08 11:50:21 +02:00
Map<String, dynamic> toJson() => _$WalletToJson(this);
/// Getter for the next unused unique number ID in the wallet's **entry** list
int get nextId {
var id = 1;
while (entries.where((element) => element.id == id).isNotEmpty) {
id++; // create unique ID
}
return id;
}
/// Getter for the next unused unique number ID in the wallet's **category**
/// list
int get nextCategoryId {
var id = 0;
while (categories.where((element) => element.id == id).isNotEmpty) {
id++; // create unique 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}")
..d("Current entry count: ${entries.length}");
recurringEntries[recurringEntries.indexOf(ent)].lastRunDate =
m; // update date on recurring entry
final addedEntry = WalletSingleEntry(
data: recurringEntries[recurringEntries.indexOf(ent)].data,
type: recurringEntries[recurringEntries.indexOf(ent)].type,
date: m,
category: recurringEntries[recurringEntries.indexOf(ent)].category,
2024-01-08 23:24:17 +01:00
id: nextId,
);
entries.add(addedEntry);
m = DateTime(
(ent.recurType == RecurType.year)
? recurringEntries[recurringEntries.indexOf(ent)]
.lastRunDate
.year +
ent.repeatAfter
: recurringEntries[recurringEntries.indexOf(ent)]
.lastRunDate
.year,
(ent.recurType == RecurType.month)
? recurringEntries[recurringEntries.indexOf(ent)]
.lastRunDate
.month +
ent.repeatAfter
: recurringEntries[recurringEntries.indexOf(ent)]
.lastRunDate
.month,
(ent.recurType == RecurType.day)
? recurringEntries[recurringEntries.indexOf(ent)]
.lastRunDate
.day +
ent.repeatAfter
: recurringEntries[recurringEntries.indexOf(ent)].lastRunDate.day,
); // add the 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.
///
/// All [WalletSingleEntry]s will have their category reassigned
/// to the default *No category*
Future<void> removeCategory(WalletCategory category) async {
// First remove the category from existing entries
for (final entryToChange
in entries.where((element) => element.category.id == category.id)) {
entryToChange.category =
categories.where((element) => element.id == 0).first;
}
// Remove the category
categories.removeWhere((element) => element.id == category.id);
// Save
await WalletManager.saveWallet(this);
}
/// Empty wallet used for placeholders
static final Wallet empty = Wallet(
name: "Empty",
currency: Currency.from(
json: {
"code": "USD",
"name": "United States Dollar",
"symbol": r"$",
"flag": "USD",
"decimal_digits": 2,
"number": 840,
"name_plural": "US dollars",
"thousands_separator": ",",
"decimal_separator": ".",
"space_between_amount_and_symbol": false,
"symbol_on_left": true,
},
),
);
2023-09-08 11:50:21 +02:00
}