Files
Distribution_GL/Repositories/BudgetRepository.cs
T

73 lines
3.0 KiB
C#

using General_Ledger_Service.DTOs.Reports;
using General_Ledger_Service.Infra;
using General_Ledger_Service.Interfaces.Repositories;
using General_Ledger_Service.Models;
using Microsoft.EntityFrameworkCore;
namespace General_Ledger_Service.Repositories
{
public class BudgetRepository(AppDBContext context) : IBudgetRepository
{
private readonly AppDBContext _context = context;
public Task<Budget?> GetByIdAsync(long budgetId) =>
RepositoryHelpers.GetByIdAsync(_context.Budgets, budgetId);
public Task<Budget> AddAsync(Budget budget) =>
RepositoryHelpers.AddAsync(_context.Budgets, budget);
public async Task AddLinesAsync(IEnumerable<BudgetLine> lines) =>
await _context.BudgetLines.AddRangeAsync(lines);
public async Task<List<Budget>> GetAllAsync() =>
await _context.Budgets.OrderBy(b => b.Name).ToListAsync();
public async Task<List<BudgetVsActualRowDto>> GetBudgetVsActualAsync(long budgetId)
{
var budgetLines = await _context.BudgetLines
.Where(bl => bl.BudgetId == budgetId)
.OrderBy(bl => bl.Account.AccountCode)
.Select(bl => new
{
bl.BudgetLineId,
bl.AccountId,
bl.Account.AccountCode,
bl.Account.AccountName,
bl.PeriodId,
bl.BudgetedAmount
})
.ToListAsync();
var accountIds = budgetLines.Select(bl => bl.AccountId).Distinct().ToList();
var periodIds = budgetLines.Select(bl => bl.PeriodId).Distinct().ToList();
// Actual = posted base debit - credit per (account, period), summed in the database.
var actuals = await _context.JournalEntryLines
.Where(l => l.Journal.IsPosted
&& l.Journal.JournalType != "CLOSING"
&& accountIds.Contains(l.AccountId)
&& periodIds.Contains(l.Journal.PeriodId))
.GroupBy(l => new { l.AccountId, l.Journal.PeriodId })
.Select(g => new { g.Key.AccountId, g.Key.PeriodId, Amount = g.Sum(l => l.BaseDebit - l.BaseCredit) })
.ToListAsync();
var actualByAccountAndPeriod = actuals.ToDictionary(a => (a.AccountId, a.PeriodId), a => a.Amount);
return [.. budgetLines.Select(bl =>
{
actualByAccountAndPeriod.TryGetValue((bl.AccountId, bl.PeriodId), out var actual);
return new BudgetVsActualRowDto
{
BudgetLineId = bl.BudgetLineId,
AccountCode = bl.AccountCode,
AccountName = bl.AccountName,
PeriodId = bl.PeriodId,
BudgetedAmount = bl.BudgetedAmount,
ActualAmount = actual,
Variance = bl.BudgetedAmount - actual
};
})];
}
}
}