diff --git a/lib/custom_widgets/transactions_list.dart b/lib/custom_widgets/transactions_list.dart index d248e944..c3d652e9 100644 --- a/lib/custom_widgets/transactions_list.dart +++ b/lib/custom_widgets/transactions_list.dart @@ -224,6 +224,8 @@ class TransactionRow extends ConsumerWidget with Functions { const SizedBox(height: 11), Row( children: [ + if (transaction.recurring) // Check if the transaction is recurring + const Icon(Icons.repeat, color: Colors.blueAccent), // Add an icon for recurring transactions if (transaction.note != null) Text( transaction.note!, diff --git a/lib/database/sossoldi_database.dart b/lib/database/sossoldi_database.dart index 356df6a3..740f8d3d 100644 --- a/lib/database/sossoldi_database.dart +++ b/lib/database/sossoldi_database.dart @@ -156,7 +156,7 @@ class SossoldiDatabase { (13, "Shopping", "shopping_cart", 3, '', null, '${DateTime.now()}', '${DateTime.now()}'), (14, "Leisure", "subscriptions", 4, '', null, '${DateTime.now()}', '${DateTime.now()}'), (15, "Salary", "work", 5, '', null, '${DateTime.now()}', '${DateTime.now()}'), - (16, "Transports", "directions_car", 6, '', null, '${DateTime.now()}', '${DateTime.now()}'); + (16, "Transports", "directions_car_rounded", 6, '', null, '${DateTime.now()}', '${DateTime.now()}'); '''); // Add currencies @@ -171,14 +171,14 @@ class SossoldiDatabase { // Add fake budgets await _database?.execute(''' INSERT INTO budget(idCategory, name, amountLimit, active, createdAt, updatedAt) VALUES - (13, "Grocery", 400.00, 1, '${DateTime.now()}', '${DateTime.now()}'), + (13, "Grocery", 900.00, 1, '${DateTime.now()}', '${DateTime.now()}'), (11, "Home", 123.45, 0, '${DateTime.now()}', '${DateTime.now()}'); '''); // Add fake recurring transactions await _database?.execute(''' INSERT INTO recurringTransaction(fromDate, toDate, amount, note, recurrency, idCategory, idBankAccount, createdAt, updatedAt) VALUES - ("2024-02-23", null, 10.99, "Spotify", "MONTHLY", 14, 70, '${DateTime.now()}', '${DateTime.now()}'), + ("2024-02-23", null, 10.99, "404 Books", "MONTHLY", 14, 70, '${DateTime.now()}', '${DateTime.now()}'), ("2023-12-13", null, 4.97, "ETF Consultant Parcel", "DAILY", 14, 70, '${DateTime.now()}', '${DateTime.now()}'), ("2023-02-11", "2028-02-11", 1193.40, "Car Loan", "QUARTERLY", 16, 72, '${DateTime.now()}', '${DateTime.now()}'); '''); @@ -187,7 +187,7 @@ class SossoldiDatabase { // First initialize some config stuff final rnd = Random(); var accounts = [70,71,72]; - var outNotes = ['Grocery', 'Tolls', 'Toys', 'ETF Consultant Parcel', 'Concert', 'Clothing', 'Pizza', 'Drugs', 'Laundry', 'Taxes', 'Health insurance', 'Furniture', 'Car Fuel', 'Train', 'Amazon', 'Delivery', 'CHEK dividends', 'Babysitter', 'sono.pove.ro Fees', 'Quingentole trip']; + var outNotes = ['Grocery', 'Tolls', 'Toys', 'Boardgames', 'Concert', 'Clothing', 'Pizza', 'Drugs', 'Laundry', 'Taxes', 'Health insurance', 'Furniture', 'Car Fuel', 'Train', 'Amazon', 'Delivery', 'CHEK dividends', 'Babysitter', 'sono.pove.ro Fees', 'Quingentole trip']; var categories = [10,11,12,13,14]; double maxAmountOfSingleTransaction = 250.00; int dateInPastMaxRange = (countOfGeneratedTransaction / 90 ).round() * 30; // we want simulate about 90 transactions per month @@ -282,7 +282,7 @@ class SossoldiDatabase { await batch.commit(); }); } catch(error){ - // throw Exception('DbBase.cleanDatabase: $error'); + throw Exception('DbBase.cleanDatabase: $error'); } } diff --git a/lib/model/recurring_transaction.dart b/lib/model/recurring_transaction.dart index 11fe4855..a0d7f4bf 100644 --- a/lib/model/recurring_transaction.dart +++ b/lib/model/recurring_transaction.dart @@ -59,7 +59,7 @@ Map recurrenciesMap = { 'amount': 3 }, 'SEMESTER': { - 'label': 'Semester', + 'label': 'Half Yearly', 'entity': 'months', 'amount': 6 }, @@ -350,8 +350,7 @@ class RecurringTransactionMethods extends SossoldiDatabase { return; } - if (transaction.toDate?.isAfter(lastTransactionDate) ?? true) { - // TODO no future dates + if ((transaction.toDate?.isAfter(lastTransactionDate) ?? true) && lastTransactionDate.isBefore(DateTime.now())) { transactions2Add.add(lastTransactionDate); } diff --git a/test/model/bank_account_test.dart b/test/model/bank_account_test.dart index 5b6cdcaf..cd78c4db 100644 --- a/test/model/bank_account_test.dart +++ b/test/model/bank_account_test.dart @@ -94,7 +94,7 @@ void main() { sossoldiDatabase = SossoldiDatabase(dbName: 'test.db'); db = await sossoldiDatabase.database; - await sossoldiDatabase.clearDatabase(); + await sossoldiDatabase.resetDatabase(); }); tearDown(() async => { @@ -121,7 +121,7 @@ void main() { var transactions = await db.rawQuery("SELECT * FROM `transaction`"); expect(0, transactions.length); - const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, recurrencyType, recurrencyPayDay, recurrencyFrom, recurrencyTo, createdAt, updatedAt) VALUES '''; + const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, idRecurringTransaction, createdAt, updatedAt) VALUES '''; final List demoTransactions = []; final today = DateTime.now(); @@ -187,7 +187,7 @@ void main() { var transactions = await db.rawQuery("SELECT * FROM `transaction`"); expect(0, transactions.length); - const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, recurrencyType, recurrencyPayDay, recurrencyFrom, recurrencyTo, createdAt, updatedAt) VALUES '''; + const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, idRecurringTransaction, createdAt, updatedAt) VALUES '''; final List demoTransactions = []; final today = DateTime.now(); diff --git a/test/model/recurring_transaction_amount_test.dart b/test/model/recurring_transaction_amount_test.dart deleted file mode 100644 index f4277f95..00000000 --- a/test/model/recurring_transaction_amount_test.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; - -import 'package:sossoldi/model/recurring_transaction_amount.dart'; -import 'package:sossoldi/model/base_entity.dart'; - -void main() { - test('Test Copy Recurring Transaction Amount', () { - RecurringTransactionAmount t = RecurringTransactionAmount( - id: 2, - from: DateTime.utc(2022), - to: DateTime.utc(2023), - amount: 0, - idTransaction: 0, - createdAt: DateTime.utc(2022), - updatedAt: DateTime.utc(2022)); - - RecurringTransactionAmount tCopy = t.copy(id: 10); - - assert(tCopy.id == 10); - assert(tCopy.from == t.from); - assert(tCopy.to == t.to); - assert(tCopy.amount == t.amount); - assert(tCopy.idTransaction == t.idTransaction); - assert(tCopy.createdAt == t.createdAt); - assert(tCopy.updatedAt == t.updatedAt); - }); - - test("Test fromJson Recurring Transaction Amount", () { - Map json = { - BaseEntityFields.id: 0, - RecurringTransactionAmountFields.from: - DateTime.utc(2022).toIso8601String(), - RecurringTransactionAmountFields.to: DateTime.utc(2023).toIso8601String(), - RecurringTransactionAmountFields.amount: 0, - RecurringTransactionAmountFields.idTransaction: 0, - BaseEntityFields.createdAt: DateTime.utc(2022).toIso8601String(), - BaseEntityFields.updatedAt: DateTime.utc(2022).toIso8601String(), - }; - - RecurringTransactionAmount t = RecurringTransactionAmount.fromJson(json); - - assert(t.id == json[BaseEntityFields.id]); - assert(t.from.toUtc().toIso8601String() == - json[RecurringTransactionAmountFields.from]); - assert(t.to.toUtc().toIso8601String() == - json[RecurringTransactionAmountFields.to]); - assert(t.amount == json[RecurringTransactionAmountFields.amount]); - assert(t.idTransaction == - json[RecurringTransactionAmountFields.idTransaction]); - assert(t.createdAt?.toUtc().toIso8601String() == - json[BaseEntityFields.createdAt]); - assert(t.updatedAt?.toUtc().toIso8601String() == - json[BaseEntityFields.updatedAt]); - }); - - test("Test toJson Recurring Transaction Amount", () { - RecurringTransactionAmount t = RecurringTransactionAmount( - id: 2, - from: DateTime.utc(2022), - to: DateTime.utc(2023), - amount: 0, - idTransaction: 0, - createdAt: DateTime.utc(2022), - updatedAt: DateTime.utc(2022)); - - Map json = t.toJson(); - - assert(t.id == json[BaseEntityFields.id]); - assert(t.from.toUtc().toIso8601String() == - json[RecurringTransactionAmountFields.from]); - assert(t.to.toUtc().toIso8601String() == - json[RecurringTransactionAmountFields.to]); - assert(t.amount == json[RecurringTransactionAmountFields.amount]); - assert(t.idTransaction == - json[RecurringTransactionAmountFields.idTransaction]); - assert(t.createdAt?.toUtc().toIso8601String() == - json[BaseEntityFields.createdAt]); - assert(t.updatedAt?.toUtc().toIso8601String() == - json[BaseEntityFields.updatedAt]); - }); -} diff --git a/test/model/recurring_transaction_test.dart b/test/model/recurring_transaction_test.dart new file mode 100644 index 00000000..848f49c2 --- /dev/null +++ b/test/model/recurring_transaction_test.dart @@ -0,0 +1,89 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'package:sossoldi/model/recurring_transaction.dart'; +import 'package:sossoldi/model/base_entity.dart'; + +void main() { + test('Test Copy Recurring Transaction Amount', () { + RecurringTransaction t = RecurringTransaction( + id: 2, + fromDate: DateTime.utc(2022), + toDate: DateTime.utc(2023), + amount: 14, + note: 'Test Transaction', + recurrency: 'MONTHLY', + idBankAccount: 34, + idCategory: 24, + createdAt: DateTime.utc(2022), + updatedAt: DateTime.utc(2022) + ); + + RecurringTransaction tCopy = t.copy(id: 10); + + assert(tCopy.id == 10); + assert(tCopy.fromDate == t.fromDate); + assert(tCopy.toDate == t.toDate); + assert(tCopy.amount == t.amount); + assert(tCopy.note == t.note); + assert(tCopy.recurrency == t.recurrency); + assert(tCopy.idBankAccount == t.idBankAccount); + assert(tCopy.idCategory == t.idCategory); + assert(tCopy.createdAt == t.createdAt); + assert(tCopy.updatedAt == t.updatedAt); + }); + + test("Test fromJson Recurring Transaction Amount", () { + Map json = { + BaseEntityFields.id: 0, + RecurringTransactionFields.fromDate: DateTime.utc(2022).toIso8601String(), + RecurringTransactionFields.toDate: DateTime.utc(2023).toIso8601String(), + RecurringTransactionFields.amount: 50, + RecurringTransactionFields.note: "Test Transaction", + RecurringTransactionFields.recurrency: "WEEKLY", + RecurringTransactionFields.idBankAccount: 44, + RecurringTransactionFields.idCategory: 4, + BaseEntityFields.createdAt: DateTime.utc(2022).toIso8601String(), + BaseEntityFields.updatedAt: DateTime.utc(2022).toIso8601String(), + }; + + RecurringTransaction t = RecurringTransaction.fromJson(json); + + assert(t.id == json[BaseEntityFields.id]); + assert(t.fromDate.toUtc().toIso8601String() == json[RecurringTransactionFields.fromDate]); + assert(t.toDate?.toUtc().toIso8601String() == json[RecurringTransactionFields.toDate]); + assert(t.amount == json[RecurringTransactionFields.amount]); + assert(t.note == json[RecurringTransactionFields.note]); + assert(t.recurrency == json[RecurringTransactionFields.recurrency]); + assert(t.idBankAccount == json[RecurringTransactionFields.idBankAccount]); + assert(t.idCategory == json[RecurringTransactionFields.idCategory]); + assert(t.createdAt?.toUtc().toIso8601String() == json[BaseEntityFields.createdAt]); + assert(t.updatedAt?.toUtc().toIso8601String() == json[BaseEntityFields.updatedAt]); + }); + + test("Test toJson Recurring Transaction Amount", () { + RecurringTransaction t = RecurringTransaction( + id: 2, + fromDate: DateTime.utc(2022), + toDate: DateTime.utc(2023), + amount: 0, + note: "Test transaction", + recurrency: "MONTHLY", + idBankAccount: 4, + idCategory: 45, + createdAt: DateTime.utc(2022), + updatedAt: DateTime.utc(2022)); + + Map json = t.toJson(); + + assert(t.id == json[BaseEntityFields.id]); + assert(t.fromDate.toUtc().toIso8601String() == json[RecurringTransactionFields.fromDate]); + assert(t.toDate?.toUtc().toIso8601String() == json[RecurringTransactionFields.toDate]); + assert(t.amount == json[RecurringTransactionFields.amount]); + assert(t.note == json[RecurringTransactionFields.note]); + assert(t.recurrency == json[RecurringTransactionFields.recurrency]); + assert(t.idBankAccount == json[RecurringTransactionFields.idBankAccount]); + assert(t.idCategory == json[RecurringTransactionFields.idCategory]); + assert(t.createdAt?.toUtc().toIso8601String() == json[BaseEntityFields.createdAt]); + assert(t.updatedAt?.toUtc().toIso8601String() == json[BaseEntityFields.updatedAt]); + }); +} diff --git a/test/model/transaction_test.dart b/test/model/transaction_test.dart index d3ac4518..d7ea30bc 100644 --- a/test/model/transaction_test.dart +++ b/test/model/transaction_test.dart @@ -22,13 +22,11 @@ void main() { idBankAccount: 0, idBankAccountTransfer: null, recurring: false, - recurrencyType: null, - recurrencyPayDay: null, - recurrencyFrom: null, - recurrencyTo: null, + idRecurringTransaction: null, idCategory: 1, createdAt: DateTime.utc(2022), - updatedAt: DateTime.utc(2022)); + updatedAt: DateTime.utc(2022) + ); Transaction tCopy = t.copy(id: 10); @@ -36,16 +34,13 @@ void main() { assert(tCopy.date == t.date); assert(tCopy.amount == t.amount); assert(tCopy.date == t.date); - assert(tCopy.note == t.note); assert(tCopy.type == t.type); + assert(tCopy.note == t.note); assert(tCopy.idBankAccount == t.idBankAccount); assert(tCopy.idCategory == t.idCategory); assert(tCopy.idBankAccountTransfer == t.idBankAccountTransfer); assert(tCopy.recurring == t.recurring); - assert(tCopy.recurrencyType == t.recurrencyType); - assert(tCopy.recurrencyPayDay == t.recurrencyPayDay); - assert(tCopy.recurrencyFrom == t.recurrencyFrom); - assert(tCopy.recurrencyTo == t.recurrencyTo); + assert(tCopy.idRecurringTransaction == t.idRecurringTransaction); assert(tCopy.createdAt == t.createdAt); assert(tCopy.updatedAt == t.updatedAt); }); @@ -61,10 +56,7 @@ void main() { TransactionFields.idCategory: 0, TransactionFields.idBankAccountTransfer: null, TransactionFields.recurring: false, - TransactionFields.recurrencyType: null, - TransactionFields.recurrencyPayDay: null, - TransactionFields.recurrencyFrom: null, - TransactionFields.recurrencyTo: null, + TransactionFields.idRecurringTransaction: null, BaseEntityFields.createdAt: DateTime.utc(2022).toIso8601String(), BaseEntityFields.updatedAt: DateTime.utc(2022).toIso8601String(), }; @@ -79,10 +71,7 @@ void main() { assert(t.idBankAccount == json[TransactionFields.idBankAccount]); assert(t.idBankAccountTransfer == json[TransactionFields.idBankAccountTransfer]); assert(t.recurring == json[TransactionFields.recurring]); - assert(t.recurrencyType == json[TransactionFields.recurrencyType]); - assert(t.recurrencyPayDay == json[TransactionFields.recurrencyPayDay]); - assert(t.recurrencyFrom == json[TransactionFields.recurrencyFrom]); - assert(t.recurrencyTo == json[TransactionFields.recurrencyTo]); + assert(t.idRecurringTransaction == json[TransactionFields.idRecurringTransaction]); assert(t.idCategory == json[TransactionFields.idCategory]); assert(t.createdAt?.toUtc().toIso8601String() == json[BaseEntityFields.createdAt]); @@ -101,10 +90,7 @@ void main() { idBankAccount: 0, idBankAccountTransfer: null, recurring: false, - recurrencyType: null, - recurrencyPayDay: null, - recurrencyFrom: null, - recurrencyTo: null + idRecurringTransaction: null ); Map json = t.toJson(); @@ -118,10 +104,7 @@ void main() { assert(t.idBankAccount == json[TransactionFields.idBankAccount]); assert(t.idBankAccountTransfer == json[TransactionFields.idBankAccountTransfer]); assert((t.recurring ? 1 : 0) == json[TransactionFields.recurring]); - assert(t.recurrencyType == json[TransactionFields.recurrencyType]); - assert(t.recurrencyPayDay == json[TransactionFields.recurrencyPayDay]); - assert(t.recurrencyFrom == json[TransactionFields.recurrencyFrom]); - assert(t.recurrencyTo == json[TransactionFields.recurrencyTo]); + assert(t.idRecurringTransaction == json[TransactionFields.idRecurringTransaction]); }); group("Transaction Methods", () { @@ -158,7 +141,7 @@ void main() { throw Exception('DbBase.cleanDatabase: $error'); } - const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, recurrencyType, recurrencyPayDay, recurrencyFrom, recurrencyTo, createdAt, updatedAt) VALUES '''; + const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, idRecurringTransaction, createdAt, updatedAt) VALUES '''; final List demoTransactions = []; final today = DateTime.now(); @@ -211,7 +194,7 @@ void main() { throw Exception('DbBase.cleanDatabase: $error'); } - const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, recurrencyType, recurrencyPayDay, recurrencyFrom, recurrencyTo, createdAt, updatedAt) VALUES '''; + const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, idRecurringTransaction, createdAt, updatedAt) VALUES '''; final List demoTransactions = []; final today = DateTime.now(); @@ -264,7 +247,7 @@ void main() { throw Exception('DbBase.cleanDatabase: $error'); } - const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, recurrencyType, recurrencyPayDay, recurrencyFrom, recurrencyTo, createdAt, updatedAt) VALUES '''; + const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, idRecurringTransaction, createdAt, updatedAt) VALUES '''; final List demoTransactions = []; final today = DateTime.now(); @@ -322,7 +305,7 @@ void main() { throw Exception('DbBase.cleanDatabase: $error'); } - const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, recurrencyType, recurrencyPayDay, recurrencyFrom, recurrencyTo, createdAt, updatedAt) VALUES '''; + const insertDemoTransactionsQuery = '''INSERT INTO `transaction` (date, amount, type, note, idCategory, idBankAccount, idBankAccountTransfer, recurring, idRecurringTransaction, createdAt, updatedAt) VALUES '''; final List demoTransactions = []; final today = DateTime.now(); diff --git a/test/test_utils/sql_utils.dart b/test/test_utils/sql_utils.dart index 48b7a176..098f9214 100644 --- a/test/test_utils/sql_utils.dart +++ b/test/test_utils/sql_utils.dart @@ -10,7 +10,8 @@ String createInsertSqlTransaction({ int idBankAccount = 70, // Revolut int? idBankTransfert, bool recurring = false, - Recurrence? recurrencyType, + int? idRecurringTransaction, + Recurrence? recurrencyType, int? recurrencyPayDay, DateTime? recurrencyFrom, DateTime? recurrencyTo, @@ -20,5 +21,5 @@ String createInsertSqlTransaction({ createdAt = date; updatedAt = date; int recurringInt = recurring ? 1 : 0; - return '''('$date', $amount, '$type', '$note', $idCategory, $idBankAccount, $idBankTransfert, $recurringInt, $recurrencyType, $recurrencyPayDay, $recurrencyFrom, $recurrencyTo, '$createdAt', '$updatedAt')'''; + return '''('$date', $amount, '$type', '$note', $idCategory, $idBankAccount, $idBankTransfert, $recurringInt, $idRecurringTransaction, '$createdAt', '$updatedAt')'''; } \ No newline at end of file