first commit
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using Fitness_core_BE.DTOs.Ledger;
|
||||
using Fitness_core_BE.Interfaces;
|
||||
using Fitness_core_BE.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Fitness_core_BE.Repos
|
||||
{
|
||||
public class ProfitLossRepository : IProfitLossRepository
|
||||
{
|
||||
// Every method here is already scoped to a single caller-owned clientId (resolved
|
||||
// from the ambient tenant), so no cross-tenant fan-out is needed. PaymentTransactions
|
||||
// (member-payment rows), StaffPayments and LedgerEntries are tenant-bucket;
|
||||
// ClientInvoices (platform billing) is central.
|
||||
private readonly TenantDbContext _context;
|
||||
private readonly CentralDbContext _central;
|
||||
|
||||
public ProfitLossRepository(TenantDbContext context, CentralDbContext central)
|
||||
{
|
||||
_context = context;
|
||||
_central = central;
|
||||
}
|
||||
|
||||
public async Task<List<LedgerEntryDto>> GetDerivedEntriesAsync(
|
||||
Guid clientId,
|
||||
DateTime fromUtc,
|
||||
DateTime toUtc,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var memberPayments = await _context.PaymentTransactions
|
||||
.AsNoTracking()
|
||||
.Where(payment =>
|
||||
payment.FK_ClientId == clientId &&
|
||||
payment.FK_CustomerInvoiceId != null &&
|
||||
payment.IsApproved == true &&
|
||||
payment.IsActive == true &&
|
||||
payment.PayDate != null &&
|
||||
payment.PayDate >= fromUtc &&
|
||||
payment.PayDate < toUtc)
|
||||
.Select(payment => new LedgerEntryDto
|
||||
{
|
||||
EntryType = "Income",
|
||||
Category = "Member Payments",
|
||||
Description = payment.PayNote,
|
||||
Amount = payment.PayAmount,
|
||||
EntryDate = payment.PayDate!.Value,
|
||||
IsManual = false
|
||||
})
|
||||
.ToListAsync(ct);
|
||||
|
||||
var platformInvoices = await _central.ClientInvoices
|
||||
.AsNoTracking()
|
||||
.Where(invoice =>
|
||||
invoice.ClientSubscription.FKClientId == clientId &&
|
||||
invoice.PaidAmount > 0 &&
|
||||
invoice.ClientInvoiceDate >= fromUtc &&
|
||||
invoice.ClientInvoiceDate < toUtc)
|
||||
.Select(invoice => new LedgerEntryDto
|
||||
{
|
||||
EntryType = "Expense",
|
||||
Category = "Platform Fees",
|
||||
Description = "HexaFitness platform invoice",
|
||||
Amount = invoice.PaidAmount,
|
||||
EntryDate = invoice.ClientInvoiceDate,
|
||||
IsManual = false
|
||||
})
|
||||
.ToListAsync(ct);
|
||||
|
||||
var staffPayments = await _context.StaffPayments
|
||||
.AsNoTracking()
|
||||
.Where(payment =>
|
||||
payment.Staff.FKClientId == clientId &&
|
||||
payment.PaidAt >= fromUtc &&
|
||||
payment.PaidAt < toUtc)
|
||||
.Select(payment => new LedgerEntryDto
|
||||
{
|
||||
EntryType = "Expense",
|
||||
Category = "Staff Payroll",
|
||||
Description = payment.Note,
|
||||
Amount = payment.Amount,
|
||||
EntryDate = payment.PaidAt,
|
||||
IsManual = false
|
||||
})
|
||||
.ToListAsync(ct);
|
||||
|
||||
memberPayments.AddRange(platformInvoices);
|
||||
memberPayments.AddRange(staffPayments);
|
||||
return memberPayments;
|
||||
}
|
||||
|
||||
public Task<List<LedgerEntry>> GetManualEntriesAsync(
|
||||
Guid clientId,
|
||||
DateTime fromUtc,
|
||||
DateTime toUtc,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
return _context.LedgerEntries
|
||||
.AsNoTracking()
|
||||
.Where(entry =>
|
||||
entry.FKClientId == clientId &&
|
||||
entry.EntryDate >= fromUtc &&
|
||||
entry.EntryDate < toUtc)
|
||||
.ToListAsync(ct);
|
||||
}
|
||||
|
||||
public Task<LedgerEntry?> GetManualEntryByIdAsync(
|
||||
Guid id,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
return _context.LedgerEntries.FirstOrDefaultAsync(entry => entry.Id == id, ct);
|
||||
}
|
||||
|
||||
public async Task AddManualEntryAsync(
|
||||
LedgerEntry entry,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
await _context.LedgerEntries.AddAsync(entry, ct);
|
||||
}
|
||||
|
||||
public void RemoveManualEntry(LedgerEntry entry)
|
||||
{
|
||||
_context.LedgerEntries.Remove(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user