| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Messaging;
- using Application.Features.Api.Studio.Helpers;
- using Microsoft.EntityFrameworkCore;
- using SharedKernel.Results;
- namespace Application.Features.Api.Studio.Wallet.GetRevenue;
- internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
- {
- public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
- {
- var (start, end) = PeriodHelper.GetRange(request.Period);
- var baseQuery = db.Donation.AsNoTracking()
- .Where(d => d.ReceiverMemberID == request.MemberID && !d.IsTest && d.CreatedAt >= start && d.CreatedAt <= end);
- // Summary
- var total = await baseQuery.CountAsync(ct);
- var grossSum = total > 0 ? await baseQuery.SumAsync(d => d.Amount, ct) : 0;
- var feeSum = total > 0 ? await baseQuery.SumAsync(d => d.FeeAmount, ct) : 0;
- var netSum = total > 0 ? await baseQuery.SumAsync(d => d.NetAmount, ct) : 0;
- var summary = new RevenueSummary(grossSum, feeSum, netSum);
- // Paged list
- var list = await baseQuery
- .OrderByDescending(d => d.CreatedAt)
- .Skip((request.Page - 1) * request.PerPage)
- .Take(request.PerPage)
- .Select(d => new RevenueItem(
- d.ID,
- d.SendName,
- d.Sponsor != null ? d.Sponsor.SID : null,
- d.Amount,
- d.FeeAmount,
- d.NetAmount,
- d.CrewSessionID != null ? "crew_donation" : "donation",
- d.CrewMember != null ? d.CrewMember.Nickname : null,
- d.CreatedAt
- ))
- .ToListAsync(ct);
- // Chart data — daily grouping
- var chartRaw = await baseQuery
- .GroupBy(d => d.CreatedAt.Date)
- .Select(g => new
- {
- Date = g.Key,
- GrossAmount = g.Sum(d => d.Amount),
- PlatformFee = g.Sum(d => d.FeeAmount),
- NetAmount = g.Sum(d => d.NetAmount)
- })
- .OrderBy(x => x.Date)
- .ToListAsync(ct);
- var chartData = chartRaw.Select(c => new ChartItem(c.Date.ToString("MM/dd"), c.GrossAmount, c.PlatformFee, c.NetAmount)).ToList();
- return Result.Success(new Response(total, summary, list, chartData));
- }
- }
|