using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Domain.Entities.Store.ValueObject; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Store.Settlement.Search; public sealed class Handler(IAppDbContext db) : IQueryHandler { public async Task Handle(Query request, CancellationToken ct) { // navtab counts (필터 무관 전체) var counts = await db.GameSettlement.AsNoTracking() .GroupBy(s => s.Status) .Select(g => new { Status = g.Key, Count = g.Count() }) .ToListAsync(ct); int CountOf(GameSettlementStatus s) => counts.FirstOrDefault(x => x.Status == s)?.Count ?? 0; var statusCounts = new Response.StatusCounts( All: counts.Sum(x => x.Count), Pending: CountOf(GameSettlementStatus.Pending), Settled: CountOf(GameSettlementStatus.Settled) ); // 필터 적용 var query = db.GameSettlement.AsNoTracking() .Include(s => s.Game) .AsQueryable(); if (request.GameID is > 0) { query = query.Where(s => s.GameID == request.GameID); } if (request.Year is > 0) { query = query.Where(s => s.Year == request.Year); } if (request.Month is > 0) { query = query.Where(s => s.Month == request.Month); } if (request.Status.HasValue) { query = query.Where(s => s.Status == request.Status.Value); } var total = await query.CountAsync(ct); // 합계 (필터 적용 후) var summary = await query .GroupBy(s => 1) .Select(g => new { Sum = g.Sum(s => (long)s.TotalRevenueAmount), Orders = g.Sum(s => s.OrderCount) }) .FirstOrDefaultAsync(ct); var list = await query .OrderByDescending(s => s.Year) .ThenByDescending(s => s.Month) .ThenBy(s => s.GameID) .Skip((request.Page - 1) * request.PerPage) .Take(request.PerPage) .Select(s => new { s.ID, s.GameID, GameName = s.Game!.KorName, GamePublisher = s.Game.Publisher, s.Year, s.Month, s.TotalRevenueAmount, s.OrderCount, s.Status, s.CreatedAt, s.SettledAt, s.SettledByAdminUserId, s.SettledByAdminEmail, s.AdminMemo }) .ToListAsync(ct); var startNum = total - ((request.Page - 1) * request.PerPage); return new Response( Total: total, List: [.. list.Select((c, i) => new Response.Row( Num: startNum - i, c.ID, c.GameID, c.GameName, c.GamePublisher, c.Year, c.Month, c.TotalRevenueAmount, c.OrderCount, c.Status, c.CreatedAt, c.SettledAt, c.SettledByAdminUserId, c.SettledByAdminEmail, c.AdminMemo ))], Counts: statusCounts, Totals: new Response.Summary( TotalRevenue: summary?.Sum ?? 0, TotalOrders: summary?.Orders ?? 0 ) ); } }