using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Domain.Entities.Store.ValueObject; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Store.Shipment.Search; public sealed class Handler(IAppDbContext db) : IQueryHandler { public async Task Handle(Query request, CancellationToken ct) { // navtab 카운트 (필터 무관 전체) var counts = await db.Shipment.AsNoTracking() .GroupBy(s => s.Status) .Select(g => new { Status = g.Key, Count = g.Count() }) .ToListAsync(ct); int CountOf(ShipmentStatus s) => counts.FirstOrDefault(x => x.Status == s)?.Count ?? 0; var statusCounts = new Response.StatusCounts( All: counts.Sum(x => x.Count), Preparing: CountOf(ShipmentStatus.Preparing), Pickup: CountOf(ShipmentStatus.Pickup), InTransit: CountOf(ShipmentStatus.InTransit), Delivered: CountOf(ShipmentStatus.Delivered), Failed: CountOf(ShipmentStatus.Failed) ); var query = db.Shipment.AsNoTracking() .Include(s => s.Order).ThenInclude(o => o!.Member) .AsQueryable(); if (request.Status.HasValue) { query = query.Where(s => s.Status == request.Status.Value); } if (!string.IsNullOrWhiteSpace(request.Keyword)) { var kw = request.Keyword.Trim(); query = request.Search switch { 1 => query.Where(s => s.Order!.OrderNumber.Contains(kw)), 2 => query.Where(s => s.Order!.Member!.Email.Contains(kw)), 3 => query.Where(s => s.TrackingNumber != null && s.TrackingNumber.Contains(kw)), _ => query.Where(s => s.Order!.OrderNumber.Contains(kw) || (s.TrackingNumber != null && s.TrackingNumber.Contains(kw))) }; } if (DateTime.TryParse(request.StartAt, out var startAt)) { query = query.Where(s => s.CreatedAt >= startAt); } if (DateTime.TryParse(request.EndAt, out var endAt)) { query = query.Where(s => s.CreatedAt <= endAt); } var total = await query.CountAsync(ct); var list = await query .OrderByDescending(s => s.ID) .Skip((request.Page - 1) * request.PerPage) .Take(request.PerPage) .Select(s => new Response.Row( 0, s.ID, s.OrderID, s.Order!.OrderNumber, s.Order.Member!.Email, s.Status, s.Carrier, s.TrackingNumber, s.CreatedAt, s.ShippedAt, s.DeliveredAt )) .ToListAsync(ct); var startNum = total - ((request.Page - 1) * request.PerPage); return new Response( total, [.. list.Select((c, i) => c with { Num = startNum - i })], statusCounts ); } }