Handler.cs 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Wallets.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Admin.Donation.List.Export;
  6. public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  7. {
  8. public async Task<Response> Handle(Query request, CancellationToken ct)
  9. {
  10. var query = db.Donation.AsNoTracking().Include(x => x.Sponsor).Include(x => x.Receiver).AsQueryable();
  11. if (!string.IsNullOrWhiteSpace(request.Keyword))
  12. {
  13. query = request.Search switch
  14. {
  15. 1 => query.Where(x => x.Sponsor != null && x.Sponsor.ID.ToString().Contains(request.Keyword)),
  16. 2 => query.Where(x => x.Sponsor != null && x.Sponsor.SID.Contains(request.Keyword)),
  17. 3 => query.Where(x => x.Sponsor != null && x.Sponsor.Name != null && x.Sponsor.Name.Contains(request.Keyword)),
  18. 4 => query.Where(x => x.Receiver != null && x.Receiver.ID.ToString().Contains(request.Keyword)),
  19. 5 => query.Where(x => x.Receiver != null && x.Receiver.SID.Contains(request.Keyword)),
  20. 6 => query.Where(x => x.Receiver != null && x.Receiver.Name != null && x.Receiver.Name.Contains(request.Keyword)),
  21. 7 => query.Where(x => x.SendName.Contains(request.Keyword)),
  22. _ => query
  23. };
  24. }
  25. if (!string.IsNullOrWhiteSpace(request.StartAt) && DateTime.TryParse(request.StartAt, out var startAt))
  26. {
  27. query = query.Where(x => x.CreatedAt >= startAt);
  28. }
  29. if (!string.IsNullOrWhiteSpace(request.EndAt) && DateTime.TryParse(request.EndAt, out var endAt))
  30. {
  31. query = query.Where(x => x.CreatedAt <= endAt);
  32. }
  33. var list = await query.OrderByDescending(x => x.ID).Select(x => new
  34. {
  35. x.ID,
  36. x.Amount,
  37. x.SendName,
  38. x.Message,
  39. x.CreatedAt,
  40. x.SponsorMemberID,
  41. x.ReceiverMemberID,
  42. SponsorEmail = x.Sponsor != null ? x.Sponsor.Email : string.Empty,
  43. SponsorName = x.Sponsor != null ? x.Sponsor.Name : null,
  44. SponsorID = x.Sponsor != null ? x.Sponsor.ID : 0,
  45. ReceiverEmail = x.Receiver != null ? x.Receiver.Email : string.Empty,
  46. ReceiverName = x.Receiver != null ? x.Receiver.Name : null,
  47. ReceiverID = x.Receiver != null ? x.Receiver.ID : 0
  48. }).ToListAsync(ct);
  49. var memberIDs = list.Select(x => x.SponsorMemberID).Concat(list.Select(x => x.ReceiverMemberID)).Distinct().ToArray();
  50. var wallets = await db.Wallet.AsNoTracking().Where(w => memberIDs.Contains(w.MemberID)).Include(w => w.Balances).ToListAsync(ct);
  51. var balanceByMember = wallets.ToDictionary(
  52. w => w.MemberID,
  53. w => new
  54. {
  55. Total = (long)w.Balances.Where(b => b.Type != WalletBalanceType.Locked).Sum(b => b.Amount.Value),
  56. Donation = (long)(w.Balances.FirstOrDefault(b => b.Type == WalletBalanceType.Donation)?.Amount.Value ?? 0)
  57. });
  58. var rows = list.Select(x =>
  59. {
  60. var sponsorBalance = balanceByMember.TryGetValue(x.SponsorMemberID, out var sb) ? sb.Total : 0L;
  61. var receiverBalance = balanceByMember.TryGetValue(x.ReceiverMemberID, out var rb) ? rb.Donation : 0L;
  62. return new Dictionary<string, object?>
  63. {
  64. ["ID"] = x.ID,
  65. ["후원금액"] = x.Amount,
  66. ["보낸이름"] = x.SendName,
  67. ["후원자"] = $"[{x.SponsorID}] {x.SponsorEmail}, {x.SponsorName ?? "-"}",
  68. ["후원자잔고"] = sponsorBalance,
  69. ["피후원자"] = $"[{x.ReceiverID}] {x.ReceiverEmail}, {x.ReceiverName ?? "-"}",
  70. ["피후원자잔고"] = receiverBalance,
  71. ["전달내용"] = x.Message ?? string.Empty,
  72. ["등록일시KST"] = x.CreatedAt.AddHours(9).ToString("yyyy-MM-dd HH:mm:ss")
  73. };
  74. }).ToList();
  75. return new Response
  76. {
  77. Rows = rows
  78. };
  79. }
  80. }