diff --git a/lib/contract/frequency.dart b/lib/contract/frequency.dart index 1f1837d..2fc5f6e 100644 --- a/lib/contract/frequency.dart +++ b/lib/contract/frequency.dart @@ -7,24 +7,3 @@ enum Frequency { halfYearly, yearly, } - -DateTime getNextOccurrenceDateTime(DateTime dateTime, Frequency frequency) { - switch (frequency) { - case Frequency.daily: - return DateTime(dateTime.year, dateTime.month, dateTime.day + 1); - case Frequency.weekly: - return DateTime(dateTime.year, dateTime.month, dateTime.day + 7); - case Frequency.biweekly: - return DateTime(dateTime.year, dateTime.month, dateTime.day + 14); - case Frequency.monthly: - return DateTime(dateTime.year, dateTime.month + 1, dateTime.day); - case Frequency.quarterly: - return DateTime(dateTime.year, dateTime.month + 3, dateTime.day); - case Frequency.halfYearly: - return DateTime(dateTime.year, dateTime.month + 6, dateTime.day); - case Frequency.yearly: - return DateTime(dateTime.year + 1, dateTime.month + 6, dateTime.day); - default: - throw Exception('Invalid frequency'); - } -} diff --git a/lib/domain/models/sip.dart b/lib/domain/models/sip.dart index 45b7df8..186df88 100644 --- a/lib/domain/models/sip.dart +++ b/lib/domain/models/sip.dart @@ -24,15 +24,37 @@ class Sip { List getFuturePayment({required final DateTime till}) { final List payments = []; - final DateTime? endDate = this.endDate; - for (var i = executedTill ?? startDate; - i.isBefore(till) && (endDate == null || i.isBefore(endDate)); - i = getNextOccurrenceDateTime(i, frequency)) { - payments.add(Payment.from(amount: amount, createdOn: i)); + DateTime nextPaymentDate = executedTill ?? startDate; + + while (nextPaymentDate.compareTo(till) <= 0 && + (endDate == null || nextPaymentDate.compareTo(endDate!) < 0)) { + payments.add(Payment.from(amount: amount, createdOn: nextPaymentDate)); + nextPaymentDate = _getNextOccurrenceDateTime(nextPaymentDate, frequency); } return payments; } + DateTime _getNextOccurrenceDateTime(DateTime dateTime, Frequency frequency) { + switch (frequency) { + case Frequency.daily: + return DateTime(dateTime.year, dateTime.month, dateTime.day + 1); + case Frequency.weekly: + return DateTime(dateTime.year, dateTime.month, dateTime.day + 7); + case Frequency.biweekly: + return DateTime(dateTime.year, dateTime.month, dateTime.day + 14); + case Frequency.monthly: + return DateTime(dateTime.year, dateTime.month + 1, dateTime.day); + case Frequency.quarterly: + return DateTime(dateTime.year, dateTime.month + 3, dateTime.day); + case Frequency.halfYearly: + return DateTime(dateTime.year, dateTime.month + 6, dateTime.day); + case Frequency.yearly: + return DateTime(dateTime.year + 1, dateTime.month + 6, dateTime.day); + default: + throw Exception('Invalid frequency'); + } + } + factory Sip.from({required final SipDO sipDO}) => Sip._( id: sipDO.id, investmentId: sipDO.investmentId, diff --git a/test/domain/models/sip_test.dart b/test/domain/models/sip_test.dart new file mode 100644 index 0000000..c9038fa --- /dev/null +++ b/test/domain/models/sip_test.dart @@ -0,0 +1,58 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:wealth_wave/api/db/app_database.dart'; +import 'package:wealth_wave/contract/frequency.dart'; +import 'package:wealth_wave/domain/models/sip.dart'; + +void main() { + group('Sip', () { + test('should return correct future payments for daily frequency', () { + final sip = Sip.from( + sipDO: SipDO( + id: 1, + investmentId: 1, + description: "Test SIP", + amount: 100.0, + startDate: DateTime(2023, 1, 1), + endDate: null, + frequency: Frequency.daily, + executedTill: null, + ), + ); + + final payments = sip.getFuturePayment(till: DateTime(2023, 1, 5)); + + expect(payments.length, 5); + expect(payments[0].amount, 100.0); + expect(payments[0].createdOn, DateTime(2023, 1, 1)); + expect(payments[1].createdOn, DateTime(2023, 1, 2)); + expect(payments[2].createdOn, DateTime(2023, 1, 3)); + expect(payments[3].createdOn, DateTime(2023, 1, 4)); + expect(payments[4].createdOn, DateTime(2023, 1, 5)); + }); + + test('should return correct future payments for monthly frequency', () { + final sip = Sip.from( + sipDO: SipDO( + id: 1, + investmentId: 1, + description: "Test SIP", + amount: 100.0, + startDate: DateTime(2023, 1, 1), + endDate: null, + frequency: Frequency.monthly, + executedTill: null, + ), + ); + + final payments = sip.getFuturePayment(till: DateTime(2023, 5, 1)); + + expect(payments.length, 5); + expect(payments[0].amount, 100.0); + expect(payments[0].createdOn, DateTime(2023, 1, 1)); + expect(payments[1].createdOn, DateTime(2023, 2, 1)); + expect(payments[2].createdOn, DateTime(2023, 3, 1)); + expect(payments[3].createdOn, DateTime(2023, 4, 1)); + expect(payments[4].createdOn, DateTime(2023, 5, 1)); + }); + }); +} \ No newline at end of file