Files
CMS/src/CMSMicroservice.Application/ClubMembershipCQ/Queries/GetClubStatistics/GetClubStatisticsQueryHandler.cs

96 lines
3.7 KiB
C#

namespace CMSMicroservice.Application.ClubMembershipCQ.Queries.GetClubStatistics;
public class GetClubStatisticsQueryHandler : IRequestHandler<GetClubStatisticsQuery, GetClubStatisticsResponseDto>
{
private readonly IApplicationDbContext _context;
public GetClubStatisticsQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetClubStatisticsResponseDto> Handle(GetClubStatisticsQuery request, CancellationToken cancellationToken)
{
var now = DateTime.UtcNow;
// Basic statistics
var totalMembers = await _context.ClubMemberships.CountAsync(cancellationToken);
var activeMembers = await _context.ClubMemberships
.Where(x => x.IsActive)
.CountAsync(cancellationToken);
var inactiveMembers = totalMembers - activeMembers;
var expiredMembers = 0; // Since there's no expiration tracking in the model
double activePercentage = totalMembers > 0 ? (activeMembers / (double)totalMembers) * 100 : 0;
// Package distribution - ClubMembership doesn't have PackageId
// We'll return empty list for now or create mock data
var packageDistribution = new List<PackageLevelDistributionModel>();
// Monthly trend (last 6 months)
var sixMonthsAgo = now.AddMonths(-6);
var activations = await _context.ClubMemberships
.Where(x => x.ActivatedAt >= sixMonthsAgo && x.ActivatedAt != null)
.GroupBy(x => new { x.ActivatedAt!.Value.Year, x.ActivatedAt.Value.Month })
.Select(g => new { g.Key.Year, g.Key.Month, Count = g.Count() })
.ToListAsync(cancellationToken);
var monthlyTrend = new List<MonthlyMembershipTrendModel>();
for (int i = 5; i >= 0; i--)
{
var targetDate = now.AddMonths(-i);
var year = targetDate.Year;
var month = targetDate.Month;
var activationCount = activations.FirstOrDefault(x => x.Year == year && x.Month == month)?.Count ?? 0;
monthlyTrend.Add(new MonthlyMembershipTrendModel
{
Month = $"{year}-{month:D2}",
Activations = activationCount,
Expirations = 0, // No expiration tracking
NetChange = activationCount
});
}
// Total revenue - sum of initial contributions
var totalRevenue = await _context.ClubMemberships
.SumAsync(x => x.InitialContribution, cancellationToken);
// Average membership duration - calculate from ActivatedAt to now
var activeMemberships = await _context.ClubMemberships
.Where(x => x.IsActive && x.ActivatedAt != null)
.Select(x => x.ActivatedAt!.Value)
.ToListAsync(cancellationToken);
double averageDuration = 0;
if (activeMemberships.Any())
{
var durations = activeMemberships
.Select(activatedAt => (now - activatedAt).TotalDays)
.ToList();
averageDuration = durations.Average();
}
// Expiring soon count - not applicable since no expiration tracking
int expiringSoonCount = 0;
return new GetClubStatisticsResponseDto
{
TotalMembers = totalMembers,
ActiveMembers = activeMembers,
InactiveMembers = inactiveMembers,
ExpiredMembers = expiredMembers,
ActivePercentage = activePercentage,
PackageDistribution = packageDistribution,
MonthlyTrend = monthlyTrend,
TotalRevenue = totalRevenue,
AverageMembershipDurationDays = averageDuration,
ExpiringSoonCount = expiringSoonCount
};
}
}