public async Task <bool> HasBudgetCategoryAccessAsync(BudgetCategoryId budgetCategoryBudgetCategoryId) { return(await _readDbContext.BudgetCategories .AnyAsync(x => x.BudgetCategoryId == budgetCategoryBudgetCategoryId && _readDbContext.Budgets .Any(b => b.BudgetId == x.BudgetId && b.OwnerUserId == _userContext.UserId))); }
public static BudgetCategoryBalance Create(BudgetCategoryId budgetCategoryId, int year, int month) { return(new BudgetCategoryBalance() { BudgetCategoryId = budgetCategoryId, Year = year, Month = month }); }
public async Task <MoneyAmount> GetCategoryBalance(BudgetCategoryId budgetCategoryId, DateTime?from, DateTime?to, CancellationToken cancellationToken) { var budgetCategory = _writeDb.BudgetCategories.FirstOrDefault(x => x.BudgetCategoryId == budgetCategoryId) ?? throw new NotFoundException(Localization.For(() => ErrorMessages.BudgetCategoryNotFound)); var currency = (await _writeDb.Budgets.FirstOrDefaultAsync(x => x.BudgetId == budgetCategory.BudgetId, cancellationToken: cancellationToken)).Currency; var amount = 0m; foreach (var balance in GetCategoryBalances(budgetCategoryId, from, to)) { amount += balance.BudgetedAmount.Amount - balance.TransactionsTotal.Amount + balance.AllocationsTotal.Amount; } return(new MoneyAmount(currency.CurrencyCode, amount)); }
public IEnumerable <ReadModels.BudgetCategoryBalance> GetCategoryBalances(BudgetCategoryId budgetCategoryId, DateTime?from, DateTime?to) { var budgetCategory = _readDb.BudgetCategories.FirstOrDefault(x => x.BudgetCategoryId == budgetCategoryId) ?? throw new NotFoundException(Localization.For(() => ErrorMessages.BudgetCategoryNotFound)); if (!budgetCategory.BudgetedAmounts.Any()) { yield break; } from ??= budgetCategory.BudgetedAmounts.Min(x => x.ValidFrom); to ??= DateTime.Today; var fromYear = from.Value.Year; var fromMonth = from.Value.Month; var toYear = to.Value.Year; var toMonth = to.Value.Month; var balances = _readDb.BudgetCategoryBalances .Where(x => x.BudgetCategoryId == budgetCategoryId && ((x.Year == fromYear && x.Month >= fromMonth) || x.Year > fromYear) && ((x.Year == toYear && x.Month <= toMonth) || x.Year < toYear)) .ToList(); foreach (var month in DateTimeExtensions.MonthRange(from.Value, to.Value)) { var categoryBalance = balances.FirstOrDefault(x => x.Year == month.Year && x.Month == month.Month); if (categoryBalance == null) { CalculateBudgetCategoryBalance(budgetCategory, month.Year, month.Month, CancellationToken.None).GetAwaiter().GetResult(); categoryBalance = _readDb.BudgetCategoryBalances.FirstOrDefault(x => x.Year == month.Year && x.Month == month.Month); } if (categoryBalance != null) { yield return(categoryBalance); } } }
public async Task CalculateBudgetCategoryBalance(BudgetCategoryId budgetCategoryId, CancellationToken cancellationToken) { if (_writeDb.BudgetCategoryBalances.Any(x => x.BudgetCategoryId == budgetCategoryId)) { _writeDb.BudgetCategoryBalances.RemoveRange(_writeDb.BudgetCategoryBalances.Where(x => x.BudgetCategoryId == budgetCategoryId)); await _writeDb.SaveChangesAsync(cancellationToken); } var budgetCategory = _readDb.BudgetCategories.FirstOrDefault(x => x.BudgetCategoryId == budgetCategoryId) ?? throw new NotFoundException(Localization.For(() => ErrorMessages.BudgetCategoryNotFound)); if (!budgetCategory.BudgetedAmounts.Any()) { return; } var from = budgetCategory.BudgetedAmounts.Min(x => x.ValidFrom); var to = new[] { budgetCategory.BudgetedAmounts.Max(x => x.ValidFrom), new DateTime(DateTime.Today.Year, 12, 1) }.Max(); foreach (var month in DateTimeExtensions.MonthRange(from, to)) { await CalculateBudgetCategoryBalance(budgetCategory, month.Year, month.Month, CancellationToken.None); } }
public ReadModels.TotalBudgetCategoryBalance GetTotalCategoryBalance(BudgetCategoryId budgetCategoryId) { var endDate = new DateTime(DateTime.Today.Year, 12, 1); var categoryBalance = new TotalBudgetCategoryBalance() { BudgetCategoryId = budgetCategoryId }; foreach (var budgetCategoryBalance in GetCategoryBalances(budgetCategoryId, null, endDate)) { if (categoryBalance.TotalCategoryBalance == null) { categoryBalance.TotalCategoryBalance = (budgetCategoryBalance.BudgetedAmount + budgetCategoryBalance.AllocationsTotal) - budgetCategoryBalance.TransactionsTotal; } else if (budgetCategoryBalance.Year < DateTime.Today.Year || (budgetCategoryBalance.Year == DateTime.Today.Year && budgetCategoryBalance.Month <= DateTime.Today.Month)) { categoryBalance.TotalCategoryBalance += (budgetCategoryBalance.BudgetedAmount + budgetCategoryBalance.AllocationsTotal) - budgetCategoryBalance.TransactionsTotal; } if (categoryBalance.BudgetLeftToEndOfYear == null) { categoryBalance.BudgetLeftToEndOfYear = (budgetCategoryBalance.BudgetedAmount + budgetCategoryBalance.AllocationsTotal) - budgetCategoryBalance.TransactionsTotal; } else { categoryBalance.BudgetLeftToEndOfYear += (budgetCategoryBalance.BudgetedAmount + budgetCategoryBalance.AllocationsTotal) - budgetCategoryBalance.TransactionsTotal; } if (budgetCategoryBalance.Month == DateTime.Today.Month && budgetCategoryBalance.Year == DateTime.Today.Year) { categoryBalance.ThisMonthTransactionsTotal = budgetCategoryBalance.TransactionsTotal; categoryBalance.ThisMonthBudgetedAmount = budgetCategoryBalance.BudgetedAmount; } if (budgetCategoryBalance.Year == DateTime.Today.Year) { if (categoryBalance.ThisYearBudgetedAmount == null) { categoryBalance.ThisYearBudgetedAmount = budgetCategoryBalance.BudgetedAmount; } else { categoryBalance.ThisYearBudgetedAmount += budgetCategoryBalance.BudgetedAmount; } } if (!(budgetCategoryBalance.Year == DateTime.Today.Year && budgetCategoryBalance.Month > DateTime.Today.Month)) { if (categoryBalance.TotalBudgetedAmount == null) { categoryBalance.TotalBudgetedAmount = budgetCategoryBalance.BudgetedAmount; } else { categoryBalance.TotalBudgetedAmount += budgetCategoryBalance.BudgetedAmount; } } } return(categoryBalance); }
public async Task <BudgetCategoryBalance> CalculateBudgetCategoryBalance(BudgetCategoryId budgetCategoryId, int year, int month, CancellationToken cancellationToken) { return(await CalculateBudgetCategoryBalance(_readDb.BudgetCategories.FirstOrDefault(x => x.BudgetCategoryId == budgetCategoryId), year, month, cancellationToken)); }