namespace WheresMyMoney.Maui.Core; public enum ReoccurenceType { Days, Weeks, Months, Years, EveryLastDayOfMonth } public record PlannedPayment( int Id, decimal Amount, string Name, DateTime DateStart, DateTime? DateEnd, bool IsSubscription, int? Reoccurences, ReoccurenceType? ReoccurenceType) { public List ExpandSubscription(DateTime startDate, DateTime endDate) { var expandedPayments = new List(); if (!IsSubscription || Reoccurences is null || Reoccurences < 1 || ReoccurenceType is null) return DateStart >= startDate && DateStart <= endDate ? [this] : []; var occurrence = DateStart; while (occurrence <= endDate && (DateEnd == null || occurrence <= DateEnd)) { if (occurrence >= startDate) { expandedPayments.Add(new PlannedPayment( 0, // New ID not assigned Amount, Name, occurrence, null, false, null, null )); } occurrence = GetNextOccurence(occurrence, Reoccurences.Value, ReoccurenceType.Value); } return expandedPayments; DateTime GetNextOccurence(DateTime dateStart, int reoccurences, ReoccurenceType reoccurenceType) { switch (reoccurenceType) { case Core.ReoccurenceType.Days: return dateStart.AddDays(reoccurences); case Core.ReoccurenceType.Weeks: return dateStart.AddDays(reoccurences * 7); break; case Core.ReoccurenceType.Months: return dateStart.AddMonths(reoccurences); break; case Core.ReoccurenceType.Years: return dateStart.AddYears(reoccurences); break; case Core.ReoccurenceType.EveryLastDayOfMonth: var result = new DateTime(startDate.Year, startDate.Month, DateTime.DaysInMonth(dateStart.Year, dateStart.Month)); if (result.Date != dateStart.Date) return result; result = result.AddDays(1); return new DateTime(result.Year, result.Month, DateTime.DaysInMonth(result.Year, result.Month)); default: throw new ArgumentOutOfRangeException(nameof(reoccurenceType), reoccurenceType, null); } } } }