Handler.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Store.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Admin.Store.Coupon.ListCodes;
  6. public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  7. {
  8. public async Task<Response> Handle(Query request, CancellationToken ct)
  9. {
  10. var baseQuery = db.CouponCode.AsNoTracking().Where(c => c.CouponID == request.CouponID);
  11. // 상태별 카운트 (필터 무관, 전체 통계)
  12. var counts = await db.CouponCode
  13. .AsNoTracking()
  14. .Where(c => c.CouponID == request.CouponID)
  15. .GroupBy(c => c.Status)
  16. .Select(g => new { Status = g.Key, Count = g.Count() })
  17. .ToListAsync(ct);
  18. var available = counts.FirstOrDefault(x => x.Status == CouponCodeStatus.Available)?.Count ?? 0;
  19. var reserved = counts.FirstOrDefault(x => x.Status == CouponCodeStatus.Reserved)?.Count ?? 0;
  20. var issued = counts.FirstOrDefault(x => x.Status == CouponCodeStatus.Issued)?.Count ?? 0;
  21. var used = counts.FirstOrDefault(x => x.Status == CouponCodeStatus.Used)?.Count ?? 0;
  22. var expired = counts.FirstOrDefault(x => x.Status == CouponCodeStatus.Expired)?.Count ?? 0;
  23. // 필터 적용
  24. var query = baseQuery;
  25. if (request.Status.HasValue)
  26. {
  27. query = query.Where(c => c.Status == request.Status.Value);
  28. }
  29. var total = await query.CountAsync(ct);
  30. var list = await query
  31. .Include(c => c.IssuedToMember)
  32. .OrderByDescending(c => c.ID)
  33. .Skip((request.Page - 1) * request.PerPage)
  34. .Take(request.PerPage)
  35. .Select(c => new
  36. {
  37. c.ID,
  38. c.Code,
  39. c.Status,
  40. c.IssuedToMemberID,
  41. IssuedToMemberName = c.IssuedToMember != null ? c.IssuedToMember.Name : null,
  42. IssuedToMemberEmail = c.IssuedToMember != null ? c.IssuedToMember.Email : null,
  43. c.IssuedAt,
  44. c.UsedAt,
  45. c.CreatedAt
  46. })
  47. .ToListAsync(ct);
  48. var startNum = total - ((request.Page - 1) * request.PerPage);
  49. return new Response(
  50. Total: total,
  51. AvailableCount: available,
  52. ReservedCount: reserved,
  53. IssuedCount: issued,
  54. UsedCount: used,
  55. ExpiredCount: expired,
  56. List: [.. list.Select((c, i) => new Response.Row(
  57. Num: startNum - i,
  58. c.ID,
  59. c.Code,
  60. c.Status,
  61. c.IssuedToMemberID,
  62. c.IssuedToMemberName,
  63. c.IssuedToMemberEmail,
  64. c.IssuedAt,
  65. c.UsedAt,
  66. c.CreatedAt
  67. ))]
  68. );
  69. }
  70. }