feat: Implement Approve and Reject Withdrawal commands with handlers
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
namespace CMSMicroservice.Application.ClubMembershipCQ.Queries.GetClubStatistics;
|
||||
|
||||
public class GetClubStatisticsQuery : IRequest<GetClubStatisticsResponseDto>
|
||||
{
|
||||
// No parameters - returns overall statistics
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
namespace CMSMicroservice.Application.ClubMembershipCQ.Queries.GetClubStatistics;
|
||||
|
||||
public class GetClubStatisticsResponseDto
|
||||
{
|
||||
public int TotalMembers { get; set; }
|
||||
public int ActiveMembers { get; set; }
|
||||
public int InactiveMembers { get; set; }
|
||||
public int ExpiredMembers { get; set; }
|
||||
public double ActivePercentage { get; set; }
|
||||
public List<PackageLevelDistributionModel> PackageDistribution { get; set; } = new();
|
||||
public List<MonthlyMembershipTrendModel> MonthlyTrend { get; set; } = new();
|
||||
public long TotalRevenue { get; set; }
|
||||
public double AverageMembershipDurationDays { get; set; }
|
||||
public int ExpiringSoonCount { get; set; }
|
||||
}
|
||||
|
||||
public class PackageLevelDistributionModel
|
||||
{
|
||||
public long PackageId { get; set; }
|
||||
public string PackageName { get; set; } = string.Empty;
|
||||
public int MemberCount { get; set; }
|
||||
public double Percentage { get; set; }
|
||||
}
|
||||
|
||||
public class MonthlyMembershipTrendModel
|
||||
{
|
||||
public string Month { get; set; } = string.Empty;
|
||||
public int Activations { get; set; }
|
||||
public int Expirations { get; set; }
|
||||
public int NetChange { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user