diff --git a/Webshop.Application/Services/Public/ProductService.cs b/Webshop.Application/Services/Public/ProductService.cs
index a745af1..4eee385 100644
--- a/Webshop.Application/Services/Public/ProductService.cs
+++ b/Webshop.Application/Services/Public/ProductService.cs
@@ -1,4 +1,5 @@
-// src/Webshop.Application/Services/Public/ProductService.cs
+// /src/Webshop.Application/Services/Public/ProductService.cs
+
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
@@ -12,6 +13,10 @@ using Webshop.Infrastructure.Data;
namespace Webshop.Application.Services.Public
{
+ ///
+ /// Service, der für die Abfrage von Produktinformationen für den öffentlichen Shop-Bereich zuständig ist.
+ /// Alle hier zurückgegebenen Daten sind für jeden Besucher sichtbar.
+ ///
public class ProductService : IProductService
{
private readonly ApplicationDbContext _context;
@@ -21,53 +26,96 @@ namespace Webshop.Application.Services.Public
_context = context;
}
+ ///
+ /// Ruft eine Liste aller aktiven Produkte für die allgemeine Produktübersicht ab.
+ ///
+ /// Eine Liste von ProductDto-Objekten.
public async Task>> GetAllProductsAsync()
{
+ // Startet eine Abfrage auf die 'Products'-Tabelle in der Datenbank.
var products = await _context.Products
- .Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
+ // Lädt die zugehörigen 'Productcategories'-Verknüpfungen mit.
+ .Include(p => p.Productcategories)
+ // Lädt von dort aus die eigentliche 'categorie'-Entität.
+ .ThenInclude(pc => pc.categorie)
+ // Lädt auch die zugehörigen Produktbilder mit.
.Include(p => p.Images)
+ // Filtert die Ergebnisse: Nur Produkte, die als 'IsActive' markiert sind.
.Where(p => p.IsActive)
+ // Führt die Abfrage auf der Datenbank aus und lädt die Ergebnisse in eine Liste.
.ToListAsync();
+ // Wandelt jede Product-Entität in ein ProductDto um.
+ // 'useShortDescription: true' sorgt dafür, dass die kürzere Beschreibung für die Listenansicht verwendet wird.
var dtos = products.Select(p => MapToDto(p, useShortDescription: true)).ToList();
+
+ // Gibt das erfolgreiche Ergebnis mit der DTO-Liste zurück.
return ServiceResult.Ok>(dtos);
}
+ ///
+ /// Ruft ein einzelnes, aktives Produkt anhand seines eindeutigen Slugs ab (für die Produktdetailseite).
+ ///
+ /// Der URL-freundliche Slug des Produkts.
+ /// Ein einzelnes ProductDto oder ein NotFound-Ergebnis.
public async Task> GetProductBySlugAsync(string slug)
{
+ // Startet eine Abfrage auf die 'Products'-Tabelle.
var product = await _context.Products
+ // Lädt alle notwendigen verknüpften Daten für die Detailansicht.
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
.Include(p => p.Images)
+ // Findet das erste Produkt, das dem Slug entspricht UND aktiv ist.
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsActive);
+ // Wenn kein Produkt gefunden wurde (oder es inaktiv ist), wird ein Fehler zurückgegeben.
if (product == null)
{
return ServiceResult.Fail(ServiceResultType.NotFound, $"Produkt mit dem Slug '{slug}' wurde nicht gefunden.");
}
+ // Wandelt die gefundene Entität in ein DTO um.
+ // 'useShortDescription: false' sorgt dafür, dass die vollständige, lange Beschreibung verwendet wird.
return ServiceResult.Ok(MapToDto(product, useShortDescription: false));
}
+ ///
+ /// Ruft eine Liste der als "hervorgehoben" markierten Produkte ab (z.B. für die Startseite).
+ ///
+ /// Eine Liste von ProductDto-Objekten, sortiert nach ihrer Anzeigereihenfolge.
public async Task>> GetFeaturedProductsAsync()
{
+ // Startet eine Abfrage auf die 'Products'-Tabelle.
var products = await _context.Products
+ // Filtert nur Produkte, die sowohl aktiv als auch als "featured" markiert sind.
.Where(p => p.IsActive && p.IsFeatured)
+ // Sortiert die Ergebnisse nach der vom Admin festgelegten Reihenfolge.
.OrderBy(p => p.FeaturedDisplayOrder)
+ // Lädt die zugehörigen Bilder und Kategorien.
.Include(p => p.Images)
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
.ToListAsync();
+ // Wandelt die Entitäten in DTOs um (mit kurzer Beschreibung).
var dtos = products.Select(p => MapToDto(p, useShortDescription: true)).ToList();
+
return ServiceResult.Ok>(dtos);
}
- // Private Hilfsmethode, um Codeduplizierung zu vermeiden
+ ///
+ /// Private Hilfsmethode, um eine Product-Entität in ein ProductDto zu konvertieren.
+ /// Dies vermeidet Codeduplizierung und stellt eine konsistente Datenstruktur sicher.
+ ///
+ /// Die Product-Entität aus der Datenbank.
+ /// Gibt an, ob die Kurz- oder Langbeschreibung verwendet werden soll.
+ /// Ein befülltes ProductDto-Objekt.
private ProductDto MapToDto(Product product, bool useShortDescription)
{
return new ProductDto
{
Id = product.Id,
Name = product.Name,
+ // Wählt die passende Beschreibung basierend auf dem 'useShortDescription'-Flag.
Description = useShortDescription ? product.ShortDescription : product.Description,
Price = product.Price,
OldPrice = product.OldPrice,
@@ -75,12 +123,14 @@ namespace Webshop.Application.Services.Public
IsInStock = product.IsInStock,
StockQuantity = product.StockQuantity,
Slug = product.Slug,
+ // Mappt die verknüpften Kategorien auf eine Liste von CategorieDto.
categories = product.Productcategories.Select(pc => new CategorieDto
{
Id = pc.categorie.Id,
Name = pc.categorie.Name,
Slug = pc.categorie.Slug
}).ToList(),
+ // Mappt die verknüpften Bilder, sortiert nach DisplayOrder, auf eine Liste von ProductImageDto.
Images = product.Images.OrderBy(i => i.DisplayOrder).Select(img => new ProductImageDto
{
Id = img.Id,