73 lines
3.0 KiB
C#
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
|
|
};
|
|
})];
|
|
}
|
|
}
|
|
}
|