// 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; using Webshop.Application.DTOs.Discounts; using Webshop.Application.Services.Admin.Interfaces; using Webshop.Domain.Entities; using Webshop.Domain.Enums; using Webshop.Domain.Interfaces; namespace Webshop.Application.Services.Admin { public class AdminDiscountService : IAdminDiscountService { private readonly IDiscountRepository _discountRepository; public AdminDiscountService(IDiscountRepository discountRepository) { _discountRepository = discountRepository; } public async Task>> GetAllDiscountsAsync() { var discounts = await _discountRepository.GetAllAsync(); var dtos = discounts.Select(MapToDto).ToList(); return ServiceResult.Ok>(dtos); } public async Task> GetDiscountByIdAsync(Guid id) { var discount = await _discountRepository.GetByIdAsync(id); if (discount == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Rabatt mit ID '{id}' nicht gefunden."); } return ServiceResult.Ok(MapToDto(discount)); } public async Task> CreateDiscountAsync(DiscountDto discountDto) { if (discountDto.RequiresCouponCode && !string.IsNullOrEmpty(discountDto.CouponCode)) { var existing = await _discountRepository.GetByCouponCodeAsync(discountDto.CouponCode); if (existing != null) { return ServiceResult.Fail(ServiceResultType.Conflict, $"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 mit ID '{discountDto.Id}' nicht gefunden."); } if (discountDto.RequiresCouponCode && !string.IsNullOrEmpty(discountDto.CouponCode)) { var existing = await _discountRepository.GetByCouponCodeAsync(discountDto.CouponCode); if (existing != null && existing.Id != discountDto.Id) { return ServiceResult.Fail(ServiceResultType.Conflict, $"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.RequiresCouponCode ? discountDto.CouponCode : null; existingDiscount.MinimumOrderAmount = discountDto.MinimumOrderAmount; existingDiscount.MaximumUsageCount = discountDto.MaximumUsageCount; // Sync assigned products existingDiscount.ProductDiscounts.Clear(); if (discountDto.AssignedProductIds != null) { foreach (var productId in discountDto.AssignedProductIds) { existingDiscount.ProductDiscounts.Add(new ProductDiscount { DiscountId = existingDiscount.Id, ProductId = productId }); } } // Sync assigned categories existingDiscount.categorieDiscounts.Clear(); if (discountDto.AssignedCategoryIds != null) { foreach (var categoryId in discountDto.AssignedCategoryIds) { existingDiscount.categorieDiscounts.Add(new CategorieDiscount { DiscountId = existingDiscount.Id, categorieId = categoryId }); } } 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 mit ID '{id}' 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.RequiresCouponCode ? dto.CouponCode : null, 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() }; } } }