Handler.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Application.Features.Api.Studio.Helpers;
  4. using Microsoft.EntityFrameworkCore;
  5. using SharedKernel.Results;
  6. namespace Application.Features.Api.Studio.Wallet.GetRevenue;
  7. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  8. {
  9. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  10. {
  11. var (start, end) = PeriodHelper.GetRange(request.Period);
  12. var baseQuery = db.Donation.AsNoTracking()
  13. .Where(d => d.ReceiverMemberID == request.MemberID && !d.IsTest && d.CreatedAt >= start && d.CreatedAt <= end);
  14. // Summary
  15. var total = await baseQuery.CountAsync(ct);
  16. var grossSum = total > 0 ? await baseQuery.SumAsync(d => d.Amount, ct) : 0;
  17. var feeSum = total > 0 ? await baseQuery.SumAsync(d => d.FeeAmount, ct) : 0;
  18. var netSum = total > 0 ? await baseQuery.SumAsync(d => d.NetAmount, ct) : 0;
  19. var summary = new RevenueSummary(grossSum, feeSum, netSum);
  20. // Paged list
  21. var list = await baseQuery
  22. .OrderByDescending(d => d.CreatedAt)
  23. .Skip((request.Page - 1) * request.PerPage)
  24. .Take(request.PerPage)
  25. .Select(d => new RevenueItem(
  26. d.ID,
  27. d.SendName,
  28. d.Sponsor != null ? d.Sponsor.SID : null,
  29. d.Amount,
  30. d.FeeAmount,
  31. d.NetAmount,
  32. d.CrewSessionID != null ? "crew_donation" : "donation",
  33. d.CrewMember != null ? d.CrewMember.Nickname : null,
  34. d.CreatedAt
  35. ))
  36. .ToListAsync(ct);
  37. // Chart data — daily grouping
  38. var chartRaw = await baseQuery
  39. .GroupBy(d => d.CreatedAt.Date)
  40. .Select(g => new
  41. {
  42. Date = g.Key,
  43. GrossAmount = g.Sum(d => d.Amount),
  44. PlatformFee = g.Sum(d => d.FeeAmount),
  45. NetAmount = g.Sum(d => d.NetAmount)
  46. })
  47. .OrderBy(x => x.Date)
  48. .ToListAsync(ct);
  49. var chartData = chartRaw.Select(c => new ChartItem(c.Date.ToString("MM/dd"), c.GrossAmount, c.PlatformFee, c.NetAmount)).ToList();
  50. return Result.Success(new Response(total, summary, list, chartData));
  51. }
  52. }