Files
Core_Be/Repos/PlatformBillingRepository.cs
T
Dhananjaya99 bffc9b1686 first commit
2026-09-28 11:44:26 +05:30

265 lines
9.7 KiB
C#

using Fitness_core_BE.Interfaces;
using Fitness_core_BE.Models;
using Microsoft.EntityFrameworkCore;
namespace Fitness_core_BE.Repos
{
public class PlatformBillingRepository : IPlatformBillingRepository
{
// Platform billing is central-bucket (HexaFitness's own revenue relationship with
// each gym); AccessDevices (used only to check device-billing eligibility) is tenant.
private readonly CentralDbContext _context;
private readonly TenantDbContext _tenant;
public PlatformBillingRepository(CentralDbContext context, TenantDbContext tenant)
{
_context = context;
_tenant = tenant;
}
public Task<List<ClientPackage>> GetPricingPlansAsync(CancellationToken ct = default)
{
return _context.ClientPackages
.AsNoTracking()
.OrderByDescending(package => package.IsDefault)
.ThenBy(package => package.PackageName)
.ToListAsync(ct);
}
public async Task<ClientPackage?> GetPackageByIdAsync(
Guid packageId,
CancellationToken ct = default)
{
return await _context.ClientPackages.FindAsync(new object[] { packageId }, ct);
}
public async Task AddPackageAsync(
ClientPackage package,
CancellationToken ct = default)
{
await _context.ClientPackages.AddAsync(package, ct);
}
public Task<List<ClientPackage>> GetOtherDefaultPackagesAsync(
Guid exceptPackageId,
CancellationToken ct = default)
{
return _context.ClientPackages
.Where(package =>
package.IsDefault &&
package.ClientPackageId != exceptPackageId)
.ToListAsync(ct);
}
public Task<ClientPackage?> GetDefaultPackageAsync(CancellationToken ct = default)
{
return _context.ClientPackages
.FirstOrDefaultAsync(package => package.IsDefault, ct);
}
public async Task<ClientPackage?> GetActivePackageForClientAsync(
Guid clientId,
CancellationToken ct = default)
{
return await _context.ClientSubscriptions
.AsNoTracking()
.Where(subscription =>
subscription.FKClientId == clientId &&
subscription.IsActive)
.OrderByDescending(subscription => subscription.OnboardDate)
.Select(subscription => subscription.ClientPackage)
.FirstOrDefaultAsync(ct);
}
public Task<Client?> GetClientByIdAsync(
Guid clientId,
CancellationToken ct = default)
{
return _context.Client
.FirstOrDefaultAsync(client => client.ClientId == clientId, ct);
}
public Task<List<ClientSubscription>> GetActiveClientSubscriptionsAsync(
Guid clientId,
CancellationToken ct = default)
{
return _context.ClientSubscriptions
.Where(subscription =>
subscription.FKClientId == clientId &&
subscription.IsActive)
.ToListAsync(ct);
}
public Task<ClientSubscription?> GetActiveClientSubscriptionAsync(
Guid clientId,
CancellationToken ct = default)
{
return _context.ClientSubscriptions
.Where(subscription =>
subscription.FKClientId == clientId &&
subscription.IsActive)
.OrderByDescending(subscription => subscription.OnboardDate)
.FirstOrDefaultAsync(ct);
}
public async Task AddClientSubscriptionAsync(
ClientSubscription subscription,
CancellationToken ct = default)
{
await _context.ClientSubscriptions.AddAsync(subscription, ct);
}
public Task<List<ClientDeviceBilling>> GetActiveDeviceBillingsAsync(
Guid clientId,
CancellationToken ct = default)
{
return _context.ClientDeviceBillings
.Where(billing =>
billing.FKClientId == clientId &&
billing.IsActive)
.ToListAsync(ct);
}
public Task<ClientDeviceBilling?> GetLatestActiveDeviceBillingAsync(
Guid clientId,
CancellationToken ct = default)
{
return _context.ClientDeviceBillings
.Where(billing =>
billing.FKClientId == clientId &&
billing.IsActive)
.OrderByDescending(billing => billing.AssignedAt)
.FirstOrDefaultAsync(ct);
}
public async Task AddDeviceBillingAsync(
ClientDeviceBilling billing,
CancellationToken ct = default)
{
await _context.ClientDeviceBillings.AddAsync(billing, ct);
}
public Task<bool> HasActiveDeviceAsync(
Guid clientId,
CancellationToken ct = default)
{
return _tenant.AccessDevices.AnyAsync(device =>
device.FKClientId == clientId &&
device.IsActive, ct);
}
public Task<List<Guid>> GetMonthlyBillingCandidatesAsync(
DateTime startOfMonth,
CancellationToken ct = default)
{
return _context.Client
.AsNoTracking()
.Where(client =>
_context.ClientCard.Any(card =>
card.FK_ClientId == client.ClientId) &&
!_context.ClientInvoices.Any(invoice =>
invoice.ClientSubscription.FKClientId == client.ClientId &&
invoice.ClientInvoiceDate >= startOfMonth))
.Select(client => client.ClientId)
.ToListAsync(ct);
}
public Task<List<ClientInvoice>> GetInvoicesByStatusAsync(
string status,
bool newestFirst,
CancellationToken ct = default)
{
var query = _context.ClientInvoices
.AsNoTracking()
.Include(invoice => invoice.ClientSubscription)
.ThenInclude(subscription => subscription.Client)
.ThenInclude(client => client.ClientBusinesses)
.Where(invoice =>
status == "Outstanding"
? invoice.Status == "Pending" || invoice.Status == "Partial"
: invoice.Status == status);
query = newestFirst
? query.OrderByDescending(invoice => invoice.ClientInvoiceDate)
: query.OrderBy(invoice => invoice.ClientInvoiceDate);
return query.ToListAsync(ct);
}
public Task<ClientInvoice?> GetInvoiceWithClientAsync(
Guid invoiceId,
bool includeBusinesses,
CancellationToken ct = default)
{
var query = _context.ClientInvoices
.Include(invoice => invoice.ClientSubscription)
.ThenInclude(subscription => subscription.Client)
.AsQueryable();
if (includeBusinesses)
{
query = query.Include(invoice =>
invoice.ClientSubscription.Client.ClientBusinesses);
}
return query.FirstOrDefaultAsync(
invoice => invoice.ClientInvoiceId == invoiceId, ct);
}
public Task<ClientCard?> GetClientCardAsync(
Guid clientId,
CancellationToken ct = default)
{
// The card billing charges: the active card marked primary. CardToken != null
// excludes legacy rows created by ActivationService.ChargeAndActivateAsync before
// real card onboarding existed — those were never confirmed by Payment-Service and
// can't actually be charged, so they must never outrank (or stand in for) a real card.
return _context.ClientCard
.Where(card => card.FK_ClientId == clientId && card.IsActive && card.CardToken != null)
.OrderByDescending(card => card.IsPrimary)
.FirstOrDefaultAsync(ct);
}
public Task<List<ClientCard>> GetClientCardsAsync(
Guid clientId,
CancellationToken ct = default)
{
return _context.ClientCard
.Where(card => card.FK_ClientId == clientId && card.IsActive && card.CardToken != null)
.OrderByDescending(card => card.IsPrimary)
.ToListAsync(ct);
}
public Task<ClientCard?> GetClientCardByTokenAsync(
Guid clientId,
string cardToken,
CancellationToken ct = default)
{
return _context.ClientCard
.FirstOrDefaultAsync(card => card.FK_ClientId == clientId && card.CardToken == cardToken, ct);
}
public async Task AddInvoiceAsync(
ClientInvoice invoice,
IReadOnlyCollection<ClientInvoiceItem> items,
CancellationToken ct = default)
{
await _context.ClientInvoices.AddAsync(invoice, ct);
await _context.ClientInvoiceItems.AddRangeAsync(items, ct);
}
public Task<DevicePricingConfig?> GetDevicePricingConfigAsync(
CancellationToken ct = default)
{
return _context.DevicePricingConfigs.FirstOrDefaultAsync(ct);
}
public async Task AddDevicePricingConfigAsync(
DevicePricingConfig config,
CancellationToken ct = default)
{
await _context.DevicePricingConfigs.AddAsync(config, ct);
}
}
}