This commit is contained in:
Tizian.Breuch
2025-08-12 13:32:25 +02:00
parent 3d206eda4e
commit f91fc13a87
8 changed files with 290 additions and 21 deletions

View File

@@ -0,0 +1,90 @@
// src/Webshop.Application/Services/Public/DiscountService.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Webshop.Application.Services.Public.Interfaces;
using Webshop.Domain.Entities;
using Webshop.Domain.Interfaces;
using Webshop.Infrastructure.Data;
namespace Webshop.Application.Services.Public
{
public class DiscountService : IDiscountService
{
private readonly ApplicationDbContext _context; // Direkter Zugriff auf DbSets
private readonly IDiscountRepository _discountRepository;
private readonly IProductRepository _productRepository;
public DiscountService(
ApplicationDbContext context,
IDiscountRepository discountRepository,
IProductRepository productRepository)
{
_context = context;
_discountRepository = discountRepository;
_productRepository = productRepository;
}
public async Task<decimal> CalculateDiscountAsync(List<OrderItem> orderItems, string? couponCode)
{
decimal totalDiscount = 0;
// 1. Hole alle relevanten Rabatte
var discounts = await _context.Discounts
.Include(d => d.ProductDiscounts)
.Include(d => d.categorieDiscounts)
.Where(d => d.IsActive && d.StartDate <= DateTimeOffset.UtcNow && (!d.EndDate.HasValue || d.EndDate >= DateTimeOffset.UtcNow))
.ToListAsync();
// Filtern nach Gutscheincode
if (!string.IsNullOrEmpty(couponCode))
{
discounts = discounts.Where(d => d.CouponCode == couponCode && d.RequiresCouponCode).ToList();
}
else
{
// Rabatte ohne Gutscheincode, falls zutreffend
discounts = discounts.Where(d => !d.RequiresCouponCode).ToList();
}
// 2. Wende Rabatte auf Artikel an
foreach (var item in orderItems)
{
decimal itemDiscount = 0;
// Wir nehmen an, dass ein Artikel nur den besten Rabatt erhalten kann
var applicableDiscount = discounts.FirstOrDefault(d =>
d.ProductDiscounts.Any(pd => pd.ProductId == item.ProductId) || // Rabatt auf Produkt
d.categorieDiscounts.Any(cd => _context.Productcategories.Any(pc => pc.ProductId == item.ProductId && pc.categorieId == cd.categorieId)) // Rabatt auf Kategorie
);
if (applicableDiscount != null)
{
itemDiscount = item.UnitPrice * item.Quantity * (applicableDiscount.DiscountValue / 100);
// Hier müsste die Logik für FixedAmount-Rabatte hin
}
totalDiscount += itemDiscount;
}
// 3. Wende Warenkorb-Rabatte an (falls keine spezifischen Produkte/Kategorien zugewiesen sind)
var cartDiscounts = discounts.Where(d => !d.ProductDiscounts.Any() && !d.categorieDiscounts.Any()).ToList();
decimal cartTotal = orderItems.Sum(i => i.TotalPrice);
foreach (var discount in cartDiscounts)
{
if (discount.MinimumOrderAmount.HasValue && cartTotal < discount.MinimumOrderAmount.Value) continue;
// Beispiel: Prozentualer Rabatt auf den Warenkorb
if (discount.DiscountType == DiscountType.Percentage.ToString())
{
totalDiscount += cartTotal * (discount.DiscountValue / 100);
}
}
return totalDiscount;
}
}
}