Files
2025-10-10 13:35:08 +02:00

147 lines
6.5 KiB
C#

// src/Webshop.Application/Services/Customers/OrderService.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Webshop.Application;
using Webshop.Application.DTOs.Customers;
using Webshop.Application.DTOs.Orders;
using Webshop.Domain.Entities;
using Webshop.Domain.Enums;
using Webshop.Domain.Interfaces;
using Webshop.Infrastructure.Data;
namespace Webshop.Application.Services.Customers
{
public class OrderService : IOrderService
{
private readonly ApplicationDbContext _context;
private readonly ICustomerRepository _customerRepository;
public OrderService(ApplicationDbContext context, ICustomerRepository customerRepository)
{
_context = context;
_customerRepository = customerRepository;
}
public async Task<ServiceResult<IEnumerable<OrderSummaryDto>>> GetMyOrdersAsync(string userId)
{
var customer = await _customerRepository.GetByUserIdAsync(userId);
if (customer == null)
{
return ServiceResult.Ok<IEnumerable<OrderSummaryDto>>(new List<OrderSummaryDto>());
}
var orders = await _context.Orders
.Where(o => o.CustomerId == customer.Id)
.OrderByDescending(o => o.OrderDate)
// +++ KORREKTUR: Verknüpfte Entitäten explizit laden +++
.Include(o => o.ShippingMethodInfo)
.Include(o => o.PaymentMethodInfo)
.ToListAsync();
var dtos = orders.Select(o => new OrderSummaryDto
{
Id = o.Id,
OrderNumber = o.OrderNumber,
OrderDate = o.OrderDate,
CustomerName = $"{customer.FirstName} {customer.LastName}",
TotalAmount = o.OrderTotal,
Status = Enum.TryParse<OrderStatus>(o.OrderStatus, true, out var os) ? os : OrderStatus.Pending,
PaymentStatus = Enum.TryParse<PaymentStatus>(o.PaymentStatus, true, out var ps) ? ps : PaymentStatus.Pending,
// +++ KORREKTUR: Daten aus den geladenen Entitäten zuweisen +++
ShippingMethodName = o.ShippingMethodInfo?.Name,
PaymentMethodName = o.PaymentMethodInfo?.Name
}).ToList();
return ServiceResult.Ok<IEnumerable<OrderSummaryDto>>(dtos);
}
public async Task<ServiceResult<OrderDetailDto>> GetMyOrderByIdAsync(Guid orderId, string userId)
{
var customer = await _customerRepository.GetByUserIdAsync(userId);
if (customer == null)
{
return ServiceResult.Fail<OrderDetailDto>(ServiceResultType.Unauthorized, "Kundenprofil nicht gefunden.");
}
var order = await _context.Orders
.Include(o => o.BillingAddress)
.Include(o => o.ShippingAddress)
.Include(o => o.OrderItems)
// +++ KORREKTUR: Verknüpfte Entitäten explizit laden +++
.Include(o => o.ShippingMethodInfo)
.Include(o => o.PaymentMethodInfo)
.FirstOrDefaultAsync(o => o.Id == orderId);
if (order == null)
{
return ServiceResult.Fail<OrderDetailDto>(ServiceResultType.NotFound, $"Bestellung mit ID '{orderId}' nicht gefunden.");
}
if (order.CustomerId != customer.Id)
{
return ServiceResult.Fail<OrderDetailDto>(ServiceResultType.Forbidden, "Zugriff auf diese Bestellung verweigert.");
}
return ServiceResult.Ok(MapToOrderDetailDto(order));
}
private OrderDetailDto MapToOrderDetailDto(Order order)
{
// Die `MapToDto`-Methode muss die neuen Daten ebenfalls verwenden.
// Die `PaymentMethod`-Eigenschaft in `OrderDetailDto` scheint den Namen zu erwarten.
return new OrderDetailDto
{
Id = order.Id,
OrderNumber = order.OrderNumber,
OrderDate = order.OrderDate,
CustomerId = order.CustomerId,
Status = Enum.TryParse<OrderStatus>(order.OrderStatus, true, out var os) ? os : OrderStatus.Pending,
TotalAmount = order.OrderTotal,
ShippingAddress = new AddressDto
{
Id = order.ShippingAddress.Id,
Street = order.ShippingAddress.Street,
HouseNumber = order.ShippingAddress.HouseNumber,
City = order.ShippingAddress.City,
PostalCode = order.ShippingAddress.PostalCode,
Country = order.ShippingAddress.Country,
Type = order.ShippingAddress.Type,
FirstName = order.ShippingAddress.FirstName,
LastName = order.ShippingAddress.LastName
},
BillingAddress = new AddressDto
{
Id = order.BillingAddress.Id,
Street = order.BillingAddress.Street,
HouseNumber = order.BillingAddress.HouseNumber,
City = order.BillingAddress.City,
PostalCode = order.BillingAddress.PostalCode,
Country = order.BillingAddress.Country,
Type = order.BillingAddress.Type,
FirstName = order.BillingAddress.FirstName,
LastName = order.BillingAddress.LastName
},
// +++ KORREKTUR: Den Namen aus der geladenen Entität verwenden +++
PaymentMethod = order.PaymentMethodInfo?.Name,
PaymentStatus = Enum.TryParse<PaymentStatus>(order.PaymentStatus, true, out var ps) ? ps : PaymentStatus.Pending,
ShippingTrackingNumber = order.ShippingTrackingNumber,
ShippedDate = order.ShippedDate,
DeliveredDate = order.DeliveredDate,
OrderItems = order.OrderItems.Select(oi => new OrderItemDto
{
Id = oi.Id,
ProductId = oi.ProductId,
ProductVariantId = oi.ProductVariantId,
ProductName = oi.ProductName,
ProductSKU = oi.ProductSKU,
Quantity = oi.Quantity,
UnitPrice = oi.UnitPrice,
TotalPrice = oi.TotalPrice
}).ToList()
};
}
}
}