using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Store.Orders.Get; internal sealed class Handler(IAppDbContext db) : IQueryHandler> { public async Task> Handle(Query request, CancellationToken ct) { var order = await db.Order.AsNoTracking() .Include(o => o.Channel) .Include(o => o.Items).ThenInclude(i => i.Product) .Where(o => o.ID == request.OrderID && o.MemberID == request.MemberID) .FirstOrDefaultAsync(ct); if (order is null) { return Result.Failure(Error.NotFound("Order.NotFound", "주문을 찾을 수 없습니다.")); } var shipment = await db.Shipment.AsNoTracking() .Where(s => s.OrderID == order.ID) .Select(s => new Response.ShipmentRow( s.ID, s.Status, s.Carrier, s.TrackingNumber, s.ShippingFee, s.ShippedAt, s.DeliveredAt )) .FirstOrDefaultAsync(ct); var items = order.Items .OrderBy(i => i.ID) .Select(i => new Response.ItemRow( i.ID, i.ProductID, i.Product!.Name, i.Product.Thumbnail, i.Product.Type, i.Quantity, i.UnitPrice, i.IssuedCouponCodeID )) .ToList(); var refunds = await db.OrderRefund.AsNoTracking() .Where(r => r.OrderID == order.ID) .OrderByDescending(r => r.ID) .Select(r => new Response.RefundRow( r.ID, r.Type, r.ReasonType, r.Status, r.Amount, r.Reason, r.AdminMemo, r.RequestedAt, r.ResolvedAt )) .ToListAsync(ct); return Result.Success(new Response( ID: order.ID, OrderNumber: order.OrderNumber, TotalAmount: order.TotalAmount, PlatformFeeAmount: order.PlatformFeeAmount, GameRevenueAmount: order.GameRevenueAmount, ChannelRewardAmount: order.ChannelRewardAmount, Status: order.Status, ChannelID: order.ChannelID, ChannelName: order.Channel?.Name, CreatedAt: order.CreatedAt, PaidAt: order.PaidAt, Items: items, Shipment: shipment, Refunds: refunds )); } }