using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Payment.Toss.Cancel.Search; public sealed class Handler(IAppDbContext db) : IQueryHandler { public async Task Handle(Query request, CancellationToken ct) { var query = db.TossCancel.AsNoTracking().Include(c => c.Member).AsQueryable(); if (!string.IsNullOrWhiteSpace(request.Keyword)) { query = request.Search switch { 1 => query.Where(c => c.PaymentKey.Contains(request.Keyword)), 2 => query.Where(c => c.OrderID.Contains(request.Keyword)), 3 => query.Where(c => c.Member != null && c.Member.ID.ToString().Contains(request.Keyword)), 4 => query.Where(c => c.Member != null && c.Member.Name != null && c.Member.Name.Contains(request.Keyword)), 5 => query.Where(c => c.Member != null && c.Member.SID.Contains(request.Keyword)), _ => query }; } if (!string.IsNullOrWhiteSpace(request.StartAt) && DateTime.TryParse(request.StartAt, out var startAt)) { query = query.Where(c => c.CreatedAt >= startAt); } if (!string.IsNullOrWhiteSpace(request.EndAt) && DateTime.TryParse(request.EndAt, out var endAt)) { query = query.Where(c => c.CreatedAt <= endAt); } // 탭별 건수 (State 필터 전) var counts = await query.GroupBy(c => 1).Select(c => new Response.StateCounts { Success = c.Count(x => x.ResponseCode == "SUCCESS"), Failed = c.Count(x => x.ResponseCode != null && x.ResponseCode != "SUCCESS"), Pending = c.Count(x => x.ResponseCode == null) }).FirstOrDefaultAsync(ct) ?? new Response.StateCounts(); if (request.State.HasValue) { query = request.State.Value switch { 1 => query.Where(c => c.ResponseCode == "SUCCESS"), 2 => query.Where(c => c.ResponseCode != null && c.ResponseCode != "SUCCESS"), 3 => query.Where(c => c.ResponseCode == null), _ => query }; } var total = await query.CountAsync(ct); var skip = (request.Page - 1) * request.PerPage; var list = await query .OrderByDescending(c => c.ID) .Skip(skip) .Take(request.PerPage) .Select(c => new { c.ID, c.MemberID, MemberEmail = c.Member != null ? c.Member.Email : string.Empty, MemberName = c.Member != null ? c.Member.Name : null, c.PaymentKey, c.OrderID, c.CancelAmount, c.CancelReason, c.CancelRequester, c.Status, c.ResponseCode, c.ResponseMessage, c.CreatedAt }) .ToListAsync(ct); var rows = list.Select((c, idx) => new Response.Row { Num = total - skip - idx, ID = c.ID, MemberID = c.MemberID, MemberEmail = c.MemberEmail, MemberName = c.MemberName, PaymentKey = c.PaymentKey, OrderID = c.OrderID, CancelAmount = c.CancelAmount, CancelReason = c.CancelReason, CancelRequester = c.CancelRequester, Status = c.Status, ResponseCode = c.ResponseCode, ResponseMessage = c.ResponseMessage, CreatedAt = c.CreatedAt }).ToList(); return new Response { Total = total, Counts = counts, List = rows }; } }