using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Webshop.Application; using Webshop.Application.DTOs.Shipping; using Webshop.Domain.Entities; using Webshop.Domain.Interfaces; using Webshop.Infrastructure.Data; namespace Webshop.Application.Services.Admin { public class AdminShippingMethodService : IAdminShippingMethodService { private readonly IShippingMethodRepository _shippingMethodRepository; private readonly ApplicationDbContext _context; public AdminShippingMethodService(IShippingMethodRepository shippingMethodRepository, ApplicationDbContext context) { _shippingMethodRepository = shippingMethodRepository; _context = context; } public async Task>> GetAllAsync() { var methods = await _shippingMethodRepository.GetAllAsync(); var dtos = methods.Select(MapToDto).ToList(); return ServiceResult.Ok>(dtos); } public async Task> GetByIdAsync(Guid id) { var sm = await _shippingMethodRepository.GetByIdAsync(id); if (sm == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Versandmethode mit ID '{id}' nicht gefunden."); } return ServiceResult.Ok(MapToDto(sm)); } public async Task> CreateAsync(ShippingMethodDto shippingMethodDto) { var allMethods = await _shippingMethodRepository.GetAllAsync(); if (allMethods.Any(sm => sm.Name.Equals(shippingMethodDto.Name, StringComparison.OrdinalIgnoreCase))) { return ServiceResult.Fail(ServiceResultType.Conflict, $"Eine Versandmethode mit dem Namen '{shippingMethodDto.Name}' existiert bereits."); } var newMethod = new ShippingMethod { Id = Guid.NewGuid(), Name = shippingMethodDto.Name, Description = shippingMethodDto.Description, BaseCost = shippingMethodDto.Cost, IsActive = shippingMethodDto.IsActive, MinDeliveryDays = shippingMethodDto.MinDeliveryDays, MaxDeliveryDays = shippingMethodDto.MaxDeliveryDays, // NEU: Gewichte mappen MinWeight = shippingMethodDto.MinWeight, MaxWeight = shippingMethodDto.MaxWeight }; await _shippingMethodRepository.AddAsync(newMethod); return ServiceResult.Ok(MapToDto(newMethod)); } public async Task UpdateAsync(ShippingMethodDto shippingMethodDto) { var existingMethod = await _shippingMethodRepository.GetByIdAsync(shippingMethodDto.Id); if (existingMethod == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Versandmethode mit ID '{shippingMethodDto.Id}' nicht gefunden."); } var allMethods = await _shippingMethodRepository.GetAllAsync(); // Prüfen, ob der Name von einer ANDEREN Methode bereits verwendet wird if (allMethods.Any(sm => sm.Name.Equals(shippingMethodDto.Name, StringComparison.OrdinalIgnoreCase) && sm.Id != shippingMethodDto.Id)) { return ServiceResult.Fail(ServiceResultType.Conflict, $"Eine andere Versandmethode mit dem Namen '{shippingMethodDto.Name}' existiert bereits."); } existingMethod.Name = shippingMethodDto.Name; existingMethod.Description = shippingMethodDto.Description; existingMethod.BaseCost = shippingMethodDto.Cost; existingMethod.IsActive = shippingMethodDto.IsActive; existingMethod.MinDeliveryDays = shippingMethodDto.MinDeliveryDays; existingMethod.MaxDeliveryDays = shippingMethodDto.MaxDeliveryDays; // NEU: Gewichte aktualisieren existingMethod.MinWeight = shippingMethodDto.MinWeight; existingMethod.MaxWeight = shippingMethodDto.MaxWeight; await _shippingMethodRepository.UpdateAsync(existingMethod); return ServiceResult.Ok(); } public async Task DeleteAsync(Guid id) { var method = await _shippingMethodRepository.GetByIdAsync(id); if (method == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Versandmethode mit ID '{id}' nicht gefunden."); } var isUsedInOrders = await _context.Orders.AnyAsync(o => o.ShippingMethodId == id); if (isUsedInOrders) { return ServiceResult.Fail(ServiceResultType.Conflict, "Diese Versandmethode kann nicht gelöscht werden, da sie noch in bestehenden Bestellungen verwendet wird."); } await _shippingMethodRepository.DeleteAsync(id); return ServiceResult.Ok(); } private ShippingMethodDto MapToDto(ShippingMethod sm) { return new ShippingMethodDto { Id = sm.Id, Name = sm.Name, Description = sm.Description, Cost = sm.BaseCost, IsActive = sm.IsActive, MinDeliveryDays = sm.MinDeliveryDays, MaxDeliveryDays = sm.MaxDeliveryDays, // NEU: Gewichte ins DTO übertragen MinWeight = sm.MinWeight, MaxWeight = sm.MaxWeight }; } } }