diff --git a/Webshop.Api/Controllers/Admin/AdminOrdersController.cs b/Webshop.Api/Controllers/Admin/AdminOrdersController.cs index ddc55e3..e173a2c 100644 --- a/Webshop.Api/Controllers/Admin/AdminOrdersController.cs +++ b/Webshop.Api/Controllers/Admin/AdminOrdersController.cs @@ -1,9 +1,11 @@ // src/Webshop.Api/Controllers/Admin/AdminOrdersController.cs using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Threading.Tasks; +using Webshop.Application; using Webshop.Application.DTOs.Orders; using Webshop.Application.Services.Admin; using Webshop.Domain.Enums; @@ -23,29 +25,48 @@ namespace Webshop.Api.Controllers.Admin } [HttpGet] - public async Task>> GetAllOrders() + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task GetAllOrders() { - var orders = await _adminOrderService.GetAllOrdersAsync(); - return Ok(orders); + var result = await _adminOrderService.GetAllOrdersAsync(); + return Ok(result.Value); } [HttpGet("{id}")] - public async Task> GetOrderById(Guid id) + [ProducesResponseType(typeof(OrderDetailDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] + public async Task GetOrderById(Guid id) { - var order = await _adminOrderService.GetOrderByIdAsync(id); - if (order == null) return NotFound(); - return Ok(order); + var result = await _adminOrderService.GetOrderByIdAsync(id); + + return result.Type switch + { + ServiceResultType.Success => Ok(result.Value), + ServiceResultType.NotFound => NotFound(new { Message = result.ErrorMessage }), + _ => StatusCode(StatusCodes.Status500InternalServerError, new { Message = result.ErrorMessage ?? "Ein unerwarteter Fehler ist aufgetreten." }) + }; } [HttpPut("{id}/status")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] public async Task UpdateOrderStatus(Guid id, [FromBody] UpdateOrderStatusRequest request) { - var (success, errorMessage) = await _adminOrderService.UpdateOrderStatusAsync(id, request.NewStatus); - if (!success) + if (!ModelState.IsValid) { - return BadRequest(new { Message = errorMessage }); + return BadRequest(ModelState); } - return NoContent(); + + var result = await _adminOrderService.UpdateOrderStatusAsync(id, request.NewStatus); + + return result.Type switch + { + ServiceResultType.Success => NoContent(), + ServiceResultType.NotFound => NotFound(new { Message = result.ErrorMessage }), + ServiceResultType.InvalidInput => BadRequest(new { Message = result.ErrorMessage }), + _ => StatusCode(StatusCodes.Status500InternalServerError, new { Message = result.ErrorMessage ?? "Ein unerwarteter Fehler ist aufgetreten." }) + }; } // Ein kleines DTO für die Status-Update-Anfrage diff --git a/Webshop.Application/Services/Admin/AdminOrderService.cs b/Webshop.Application/Services/Admin/AdminOrderService.cs index 083cae4..728bede 100644 --- a/Webshop.Application/Services/Admin/AdminOrderService.cs +++ b/Webshop.Application/Services/Admin/AdminOrderService.cs @@ -3,9 +3,10 @@ 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.Enums; // Wichtig für Enum-Konvertierung +using Webshop.Domain.Enums; using Webshop.Domain.Interfaces; namespace Webshop.Application.Services.Admin @@ -19,28 +20,32 @@ namespace Webshop.Application.Services.Admin _orderRepository = orderRepository; } - public async Task> GetAllOrdersAsync() + public async Task>> GetAllOrdersAsync() { var orders = await _orderRepository.GetAllAsync(); - return orders.Select(o => new OrderSummaryDto + var dtos = orders.Select(o => new OrderSummaryDto { Id = o.Id, OrderNumber = o.OrderNumber, OrderDate = o.OrderDate, CustomerName = o.Customer != null ? $"{o.Customer.FirstName} {o.Customer.LastName}" : o.GuestEmail ?? "Gastbestellung", TotalAmount = o.OrderTotal, - // << KORREKTUR: String zu Enum parsen >> Status = Enum.TryParse(o.OrderStatus, true, out var orderStatus) ? orderStatus : OrderStatus.Pending, PaymentStatus = Enum.TryParse(o.PaymentStatus, true, out var paymentStatus) ? paymentStatus : PaymentStatus.Pending }).ToList(); + + return ServiceResult.Ok>(dtos); } - public async Task GetOrderByIdAsync(Guid id) + public async Task> GetOrderByIdAsync(Guid id) { var order = await _orderRepository.GetByIdAsync(id); - if (order == null) return null; + if (order == null) + { + return ServiceResult.Fail(ServiceResultType.NotFound, $"Bestellung mit ID '{id}' nicht gefunden."); + } - return new OrderDetailDto + var orderDetailDto = new OrderDetailDto { Id = order.Id, OrderNumber = order.OrderNumber, @@ -48,8 +53,6 @@ namespace Webshop.Application.Services.Admin CustomerId = order.CustomerId, Status = Enum.TryParse(order.OrderStatus, true, out var orderStatus) ? orderStatus : OrderStatus.Pending, TotalAmount = order.OrderTotal, - - // << KORREKTUR: Manuelles Mapping von Address-Entität zu AddressDto >> ShippingAddress = new AddressDto { Id = order.ShippingAddress.Id, @@ -70,7 +73,6 @@ namespace Webshop.Application.Services.Admin Country = order.BillingAddress.Country, Type = order.BillingAddress.Type }, - PaymentMethod = order.PaymentMethod, PaymentStatus = Enum.TryParse(order.PaymentStatus, true, out var paymentStatus) ? paymentStatus : PaymentStatus.Pending, OrderItems = order.OrderItems.Select(oi => new OrderItemDto @@ -85,26 +87,33 @@ namespace Webshop.Application.Services.Admin TotalPrice = oi.TotalPrice }).ToList() }; + + return ServiceResult.Ok(orderDetailDto); } - public async Task<(bool Success, string? ErrorMessage)> UpdateOrderStatusAsync(Guid id, OrderStatus newStatus) + public async Task UpdateOrderStatusAsync(Guid id, OrderStatus newStatus) { + if (!Enum.IsDefined(typeof(OrderStatus), newStatus)) + { + return ServiceResult.Fail(ServiceResultType.InvalidInput, $"Der Status '{newStatus}' ist ungültig."); + } + var order = await _orderRepository.GetByIdAsync(id); if (order == null) { - return (false, "Bestellung nicht gefunden."); + return ServiceResult.Fail(ServiceResultType.NotFound, $"Bestellung mit ID '{id}' nicht gefunden."); } - // << KORREKTUR: Enum zu String konvertieren >> order.OrderStatus = newStatus.ToString(); + // Hier könnte zusätzliche Logik stehen (z.B. Tracking-Nummer verlangen) if (newStatus == OrderStatus.Shipped && string.IsNullOrEmpty(order.ShippingTrackingNumber)) { - // Hier könnten Sie Logik hinzufügen, um eine Tracking-Nummer zu verlangen + // return ServiceResult.Fail(ServiceResultType.InvalidInput, "Für den Status 'Versandt' wird eine Tracking-Nummer benötigt."); } await _orderRepository.UpdateAsync(order); - return (true, null); + return ServiceResult.Ok(); } } } \ No newline at end of file diff --git a/Webshop.Application/Services/Admin/Interfaces/IAdminOrderService.cs b/Webshop.Application/Services/Admin/Interfaces/IAdminOrderService.cs index 9e8cbc7..38af2ff 100644 --- a/Webshop.Application/Services/Admin/Interfaces/IAdminOrderService.cs +++ b/Webshop.Application/Services/Admin/Interfaces/IAdminOrderService.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Webshop.Application; using Webshop.Application.DTOs.Orders; using Webshop.Domain.Enums; @@ -9,8 +10,8 @@ namespace Webshop.Application.Services.Admin { public interface IAdminOrderService { - Task> GetAllOrdersAsync(); - Task GetOrderByIdAsync(Guid id); - Task<(bool Success, string? ErrorMessage)> UpdateOrderStatusAsync(Guid id, OrderStatus newStatus); + Task>> GetAllOrdersAsync(); + Task> GetOrderByIdAsync(Guid id); + Task UpdateOrderStatusAsync(Guid id, OrderStatus newStatus); } } \ No newline at end of file