using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Schaad.Accounting.Datasets; using Schaad.Accounting.Datasets.Charts; using Schaad.Accounting.Interfaces; namespace Schaad.Accounting.Services { public class ChartService : IChartService { private readonly ISettingsService settingsService; private readonly IViewService viewService; public ChartService(ISettingsService settingsService, IViewService viewService) { this.settingsService = settingsService; this.viewService = viewService; } public async Task> GetExpensesPerMonthAsync() { var expenseTransactions = (await viewService.GetTransactionViewListAsync()) .Where(t => t.TargetAccount.Class == ClassIds.Expenses) .ToList(); var distinctSubClasses = expenseTransactions .Select(t => t.TargetAccount.SubClass) .Distinct() .Count(); return distinctSubClasses > 1 ? GetSubClassExpensesPerMonth(expenseTransactions) : await GetAccountExpensesPerMonthAsync(); } private List GetSubClassExpensesPerMonth(List expenseTransactions) { var year = settingsService.GetYear(); var maxMonth = expenseTransactions .OrderByDescending(t => t.ValueDate) .FirstOrDefault()?.ValueDate.Month ?? 12; var list = new List(); foreach (var grp in expenseTransactions.GroupBy(t => t.TargetAccount.SubClass)) { var groupedByMonth = grp .GroupBy(t => t.ValueDate.Month) .ToDictionary(g => g.Key, g => g.Sum(t => t.Value)); EnsureEntryForEveryMonth(groupedByMonth, maxMonth); list.Add(new DataSerie( Id: grp.Key.ToString(), Name: grp.First().TargetAccount.Name, X: groupedByMonth.OrderBy(g => g.Key).Select(g => new DateOnly(year, g.Key, 1)).ToList(), Y: groupedByMonth.OrderBy(g => g.Key).Select(g => g.Value).ToList() )); } return list; } private async Task> GetAccountExpensesPerMonthAsync() { var year = settingsService.GetYear(); var allTransactions = await viewService.GetTransactionViewListAsync(); var expenseAccounts = (await viewService.GetAccountViewListAsync()).Where(a => a.Class == ClassIds.Expenses); var list = new List(); foreach (var account in expenseAccounts) { var transactions = allTransactions.Where(t => t.TargetAccountId == account.Id).ToList(); if (transactions.Count == 0) { continue; } var maxMonth = transactions.Max(t => t.ValueDate.Month); var groupedByMonth = transactions .GroupBy(t => t.ValueDate.Month) .ToDictionary(g => g.Key, g => g.Sum(t => t.Value)); EnsureEntryForEveryMonth(groupedByMonth, maxMonth); list.Add(new DataSerie( Id: account.Id, Name: account.Name, X: groupedByMonth.OrderBy(g => g.Key).Select(g => new DateOnly(year, g.Key, 1)).ToList(), Y: groupedByMonth.OrderBy(g => g.Key).Select(g => g.Value).ToList() )); } return list; } private static void EnsureEntryForEveryMonth(Dictionary values, int maxMonth = 12) { for (int i = 1; i <= maxMonth; i++) { if (values.ContainsKey(i) == false) { values.Add(i, 0); } } } } }