using System; using System.Collections.Generic; using System.Linq; 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 IReadOnlyList GetExpensesPerMonth() { var expenseTransactions = viewService.GetTransactionViewList() .Where(t => t.TargetAccount.Class == ClassIds.Expenses) .ToList(); var distinctSubClasses = expenseTransactions .Select(t => t.TargetAccount.SubClass) .Distinct() .Count(); return distinctSubClasses > 1 ? GetSubClassExpensesPerMonth(expenseTransactions) : GetAccountExpensesPerMonth(); } 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 List GetAccountExpensesPerMonth() { var year = settingsService.GetYear(); var allTransactions = viewService.GetTransactionViewList(); var expenseAccounts = viewService.GetAccountViewList().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); } } } } }