namespace Service; public interface IBudgetService { Task> GetAllAsync(); Task GetByIdAsync(long id); Task AddAsync(BudgetRecord budget); Task DeleteAsync(long id); Task UpdateAsync(BudgetRecord budget); Task CalculateCurrentAmountAsync(BudgetRecord budget, DateTime? now = null); Task ToggleStopAsync(long id); } public class BudgetService( IBudgetRepository budgetRepository ) : IBudgetService { public async Task> GetAllAsync() { var list = await budgetRepository.GetAllAsync(); return list.ToList(); } public async Task GetByIdAsync(long id) { return await budgetRepository.GetByIdAsync(id); } public async Task AddAsync(BudgetRecord budget) { return await budgetRepository.AddAsync(budget); } public async Task DeleteAsync(long id) { return await budgetRepository.DeleteAsync(id); } public async Task UpdateAsync(BudgetRecord budget) { return await budgetRepository.UpdateAsync(budget); } public async Task ToggleStopAsync(long id) { var budget = await budgetRepository.GetByIdAsync(id); if (budget == null) return false; budget.IsStopped = !budget.IsStopped; return await budgetRepository.UpdateAsync(budget); } public async Task CalculateCurrentAmountAsync(BudgetRecord budget, DateTime? now = null) { if (budget.IsStopped) return 0; var referenceDate = now ?? DateTime.Now; var (startDate, endDate) = GetPeriodRange(budget.StartDate, budget.Type, referenceDate); return await budgetRepository.GetCurrentAmountAsync(budget, startDate, endDate); } public static (DateTime start, DateTime end) GetPeriodRange(DateTime startDate, BudgetPeriodType type, DateTime referenceDate) { if (type == BudgetPeriodType.Longterm) return (startDate, DateTime.MaxValue); DateTime start; DateTime end; if (type == BudgetPeriodType.Week) { var daysFromStart = (referenceDate.Date - startDate.Date).Days; var weeksFromStart = daysFromStart / 7; start = startDate.Date.AddDays(weeksFromStart * 7); end = start.AddDays(6).AddHours(23).AddMinutes(59).AddSeconds(59); } else if (type == BudgetPeriodType.Month) { start = new DateTime(referenceDate.Year, referenceDate.Month, 1); end = start.AddMonths(1).AddDays(-1).AddHours(23).AddMinutes(59).AddSeconds(59); } else if (type == BudgetPeriodType.Year) { start = new DateTime(referenceDate.Year, 1, 1); end = new DateTime(referenceDate.Year, 12, 31).AddHours(23).AddMinutes(59).AddSeconds(59); } else { start = startDate; end = DateTime.MaxValue; } return (start, end); } }