// src/Webshop.Application/Services/Admin/AdminDiscountService.cs using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Webshop.Application.DTOs.Discounts; using Webshop.Application.Services.Admin.Interfaces; using Webshop.Domain.Entities; using Webshop.Domain.Enums; using Webshop.Domain.Interfaces; using Webshop.Infrastructure.Data; namespace Webshop.Application.Services.Admin { public class AdminDiscountService : IAdminDiscountService { private readonly IDiscountRepository _discountRepository; private readonly ApplicationDbContext _context; // Für Unique-Prüfungen public AdminDiscountService(IDiscountRepository discountRepository, ApplicationDbContext context) { _discountRepository = discountRepository; _context = context; } public async Task> GetAllDiscountsAsync() { var discounts = await _discountRepository.GetAllAsync(); return discounts.Select(MapToDto).ToList(); } public async Task GetDiscountByIdAsync(Guid id) { var discount = await _discountRepository.GetByIdAsync(id); return discount != null ? MapToDto(discount) : null; } public async Task> CreateDiscountAsync(DiscountDto discountDto) { // Validierung: Gutscheincode muss eindeutig sein, wenn er benötigt wird if (discountDto.RequiresCouponCode && !string.IsNullOrEmpty(discountDto.CouponCode)) { var existing = await _context.Discounts.FirstOrDefaultAsync(d => d.CouponCode == discountDto.CouponCode); if (existing != null) { return ServiceResult.Fail(ServiceResultType.InvalidInput, $"Der Gutscheincode '{discountDto.CouponCode}' existiert bereits."); } } var discount = MapToEntity(discountDto); discount.Id = Guid.NewGuid(); await _discountRepository.AddAsync(discount); return ServiceResult.Ok(MapToDto(discount)); } public async Task UpdateDiscountAsync(DiscountDto discountDto) { var existingDiscount = await _discountRepository.GetByIdAsync(discountDto.Id); if (existingDiscount == null) { return ServiceResult.Fail(ServiceResultType.NotFound, "Rabatt nicht gefunden."); } if (discountDto.RequiresCouponCode && !string.IsNullOrEmpty(discountDto.CouponCode)) { var existing = await _context.Discounts.FirstOrDefaultAsync(d => d.CouponCode == discountDto.CouponCode && d.Id != discountDto.Id); if (existing != null) { return ServiceResult.Fail(ServiceResultType.InvalidInput, $"Der Gutscheincode '{discountDto.CouponCode}' wird bereits von einem anderen Rabatt verwendet."); } } // Update simple properties existingDiscount.Name = discountDto.Name; existingDiscount.Description = discountDto.Description; existingDiscount.DiscountType = discountDto.DiscountType.ToString(); existingDiscount.DiscountValue = discountDto.DiscountValue; existingDiscount.StartDate = discountDto.StartDate; existingDiscount.EndDate = discountDto.EndDate; existingDiscount.IsActive = discountDto.IsActive; existingDiscount.RequiresCouponCode = discountDto.RequiresCouponCode; existingDiscount.CouponCode = discountDto.CouponCode; existingDiscount.MinimumOrderAmount = discountDto.MinimumOrderAmount; existingDiscount.MaximumUsageCount = discountDto.MaximumUsageCount; // << HIER IST DER WICHTIGE, WIEDERHERGESTELLTE TEIL >> // Sync assigned products existingDiscount.ProductDiscounts.Clear(); foreach (var productId in discountDto.AssignedProductIds) { existingDiscount.ProductDiscounts.Add(new ProductDiscount { DiscountId = existingDiscount.Id, ProductId = productId }); } // Sync assigned categories existingDiscount.categorieDiscounts.Clear(); foreach (var categoryId in discountDto.AssignedCategoryIds) { existingDiscount.categorieDiscounts.Add(new CategorieDiscount { DiscountId = existingDiscount.Id, categorieId = categoryId }); } // << ENDE DES WICHTIGEN TEILS >> await _discountRepository.UpdateAsync(existingDiscount); return ServiceResult.Ok(); } public async Task DeleteDiscountAsync(Guid id) { var discount = await _discountRepository.GetByIdAsync(id); if (discount == null) { return ServiceResult.Fail(ServiceResultType.NotFound, "Rabatt nicht gefunden."); } await _discountRepository.DeleteAsync(id); return ServiceResult.Ok(); } // Helper methods for mapping private DiscountDto MapToDto(Discount discount) { return new DiscountDto { Id = discount.Id, Name = discount.Name, Description = discount.Description, DiscountType = Enum.Parse(discount.DiscountType), DiscountValue = discount.DiscountValue, StartDate = discount.StartDate, EndDate = discount.EndDate, IsActive = discount.IsActive, RequiresCouponCode = discount.RequiresCouponCode, CouponCode = discount.CouponCode, MinimumOrderAmount = discount.MinimumOrderAmount, MaximumUsageCount = discount.MaximumUsageCount, CurrentUsageCount = discount.CurrentUsageCount, AssignedProductIds = discount.ProductDiscounts.Select(pd => pd.ProductId).ToList(), AssignedCategoryIds = discount.categorieDiscounts.Select(cd => cd.categorieId).ToList() }; } private Discount MapToEntity(DiscountDto dto) { return new Discount { Id = dto.Id, Name = dto.Name, Description = dto.Description, DiscountType = dto.DiscountType.ToString(), DiscountValue = dto.DiscountValue, StartDate = dto.StartDate, EndDate = dto.EndDate, IsActive = dto.IsActive, RequiresCouponCode = dto.RequiresCouponCode, CouponCode = dto.CouponCode, MinimumOrderAmount = dto.MinimumOrderAmount, MaximumUsageCount = dto.MaximumUsageCount, CurrentUsageCount = dto.CurrentUsageCount, ProductDiscounts = dto.AssignedProductIds.Select(pid => new ProductDiscount { ProductId = pid }).ToList(), categorieDiscounts = dto.AssignedCategoryIds.Select(cid => new CategorieDiscount { categorieId = cid }).ToList() }; } } }