From b9f1b3fb7a348799af2d8b159fff60af436679c6 Mon Sep 17 00:00:00 2001 From: "Tizian.Breuch" Date: Tue, 12 Aug 2025 11:52:50 +0200 Subject: [PATCH] discount und summary --- .../Admin/AdminDiscountsController.cs | 86 +++++++++++- .../Admin/AdminShopInfoController.cs | 16 +++ .../Controllers/Public/ShopInfoController.cs | 9 ++ Webshop.Api/Program.cs | 10 +- .../DTOs/Discounts/DiscountDto.cs | 84 ++++++++++-- .../DTOs/Shop/AdminShopInfoDto.cs | 44 +++++- .../DTOs/Shop/PublicShopInfoDto.cs | 47 ++++++- .../Services/Admin/AdminDiscountService.cs | 128 +++++++++++++++++- .../Admin/Interfaces/IAdminDiscountService.cs | 15 +- .../Interfaces/IDiscountRepository.cs | 11 +- .../Data/ApplicationDbContext.cs | 26 ++++ .../Repositories/DiscountRepository.cs | 49 +++++-- 12 files changed, 481 insertions(+), 44 deletions(-) diff --git a/Webshop.Api/Controllers/Admin/AdminDiscountsController.cs b/Webshop.Api/Controllers/Admin/AdminDiscountsController.cs index 03f098a..ceea512 100644 --- a/Webshop.Api/Controllers/Admin/AdminDiscountsController.cs +++ b/Webshop.Api/Controllers/Admin/AdminDiscountsController.cs @@ -1,18 +1,98 @@ -// Auto-generiert von CreateWebshopFiles.ps1 +// src/Webshop.Api/Controllers/Admin/AdminDiscountsController.cs using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; - using System; using System.Collections.Generic; using System.Threading.Tasks; +using Webshop.Application.DTOs.Discounts; +using Webshop.Application.Services.Admin.Interfaces; namespace Webshop.Api.Controllers.Admin { + /// + /// API-Endpunkte zur Verwaltung von Rabatten und Gutscheincodes. + /// [ApiController] [Route("api/v1/admin/[controller]")] [Authorize(Roles = "Admin")] public class AdminDiscountsController : ControllerBase { + private readonly IAdminDiscountService _adminDiscountService; + public AdminDiscountsController(IAdminDiscountService adminDiscountService) + { + _adminDiscountService = adminDiscountService; + } + + /// + /// Ruft eine Liste aller konfigurierten Rabatte ab. + /// + [HttpGet] + public async Task>> GetAllDiscounts() + { + var discounts = await _adminDiscountService.GetAllDiscountsAsync(); + return Ok(discounts); + } + + /// + /// Ruft einen einzelnen Rabatt anhand seiner eindeutigen ID ab. + /// + /// Die ID des Rabatts. + [HttpGet("{id}")] + public async Task> GetDiscountById(Guid id) + { + var discount = await _adminDiscountService.GetDiscountByIdAsync(id); + if (discount == null) return NotFound(); + return Ok(discount); + } + + /// + /// Erstellt einen neuen Rabatt. + /// + /// + /// **Funktionsweise von Rabatten:** + /// - **DiscountType:** 'Percentage' (z.B. 10 für 10%) oder 'FixedAmount' (z.B. 5 für 5,00€). + /// - **CouponCode:** Wenn `requiresCouponCode` auf `true` gesetzt ist, muss ein eindeutiger `couponCode` angegeben werden. + /// - **Gültigkeit:** Kann durch `startDate` und `endDate` zeitlich begrenzt werden. + /// - **Zuweisung:** Der Rabatt kann entweder bestimmten Produkten (`assignedProductIds`) oder ganzen Kategorien (`assignedCategoryIds`) zugewiesen werden. Wenn beide Listen leer sind, gilt der Rabatt für den gesamten Warenkorb (sofern `minimumOrderAmount` erreicht ist). + /// + /// Das Datenobjekt des zu erstellenden Rabatts. + [HttpPost] + public async Task> CreateDiscount([FromBody] DiscountDto discountDto) + { + if (!ModelState.IsValid) return BadRequest(ModelState); + var createdDiscount = await _adminDiscountService.CreateDiscountAsync(discountDto); + return CreatedAtAction(nameof(GetDiscountById), new { id = createdDiscount.Id }, createdDiscount); + } + + /// + /// Aktualisiert einen bestehenden Rabatt. + /// + /// Die ID des zu aktualisierenden Rabatts. + /// Die neuen Daten für den Rabatt. + [HttpPut("{id}")] + public async Task UpdateDiscount(Guid id, [FromBody] DiscountDto discountDto) + { + if (id != discountDto.Id) return BadRequest(); + if (!ModelState.IsValid) return BadRequest(ModelState); + + var success = await _adminDiscountService.UpdateDiscountAsync(discountDto); + if (!success) return NotFound(); + + return NoContent(); + } + + /// + /// Löscht einen Rabatt. + /// + /// Die ID des zu löschenden Rabatts. + [HttpDelete("{id}")] + public async Task DeleteDiscount(Guid id) + { + var success = await _adminDiscountService.DeleteDiscountAsync(id); + if (!success) return NotFound(); + + return NoContent(); + } } -} +} \ No newline at end of file diff --git a/Webshop.Api/Controllers/Admin/AdminShopInfoController.cs b/Webshop.Api/Controllers/Admin/AdminShopInfoController.cs index a319c41..ce3284f 100644 --- a/Webshop.Api/Controllers/Admin/AdminShopInfoController.cs +++ b/Webshop.Api/Controllers/Admin/AdminShopInfoController.cs @@ -7,6 +7,9 @@ using Webshop.Application.Services.Admin; namespace Webshop.Api.Controllers.Admin { + /// + /// API-Endpunkte zur Verwaltung der zentralen Shop-Stammdaten. + /// [ApiController] [Route("api/v1/admin/[controller]")] [Authorize(Roles = "Admin")] @@ -19,6 +22,12 @@ namespace Webshop.Api.Controllers.Admin _shopInfoService = shopInfoService; } + /// + /// Ruft die aktuellen Stammdaten des Shops ab. + /// + /// + /// Diese Daten werden typischerweise in einem "Stammdaten"- oder "Shop-Einstellungen"-Formular im Admin-Dashboard angezeigt. + /// [HttpGet] public async Task> GetShopInfo() { @@ -26,6 +35,13 @@ namespace Webshop.Api.Controllers.Admin return Ok(info); } + /// + /// Aktualisiert die zentralen Stammdaten des Shops. + /// + /// + /// Sendet das gesamte, ausgefüllte DTO. Alle Felder werden überschrieben. + /// + /// Das Datenobjekt mit den neuen Shop-Informationen. [HttpPut] public async Task UpdateShopInfo([FromBody] AdminShopInfoDto shopInfoDto) { diff --git a/Webshop.Api/Controllers/Public/ShopInfoController.cs b/Webshop.Api/Controllers/Public/ShopInfoController.cs index 86dcd89..7f76e03 100644 --- a/Webshop.Api/Controllers/Public/ShopInfoController.cs +++ b/Webshop.Api/Controllers/Public/ShopInfoController.cs @@ -7,6 +7,9 @@ using Webshop.Application.Services.Public; namespace Webshop.Api.Controllers.Public { + /// + /// API-Endpunkte zum Abrufen öffentlicher Shop-Informationen. + /// [ApiController] [Route("api/v1/public/[controller]")] [AllowAnonymous] @@ -19,6 +22,12 @@ namespace Webshop.Api.Controllers.Public _shopInfoService = shopInfoService; } + /// + /// Ruft die öffentlichen Stammdaten des Shops ab. + /// + /// + /// Diese Informationen sind für jeden Besucher sichtbar und werden typischerweise im Footer, auf der Kontaktseite oder im Impressum verwendet. + /// [HttpGet] public async Task> GetPublicShopInfo() { diff --git a/Webshop.Api/Program.cs b/Webshop.Api/Program.cs index 980fe29..61df538 100644 --- a/Webshop.Api/Program.cs +++ b/Webshop.Api/Program.cs @@ -103,9 +103,12 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); + +//fehlt noch +builder.Services.AddScoped(); // Services builder.Services.AddScoped(); @@ -125,11 +128,14 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); + +//fehlt noch +builder.Services.AddScoped(); // Controller und API-Infrastruktur diff --git a/Webshop.Application/DTOs/Discounts/DiscountDto.cs b/Webshop.Application/DTOs/Discounts/DiscountDto.cs index 934cb39..0354c38 100644 --- a/Webshop.Application/DTOs/Discounts/DiscountDto.cs +++ b/Webshop.Application/DTOs/Discounts/DiscountDto.cs @@ -1,24 +1,86 @@ -// Auto-generiert von CreateWebshopFiles.ps1 +// src/Webshop.Application/DTOs/Discounts/DiscountDto.cs using System; using System.Collections.Generic; -using System.Threading.Tasks; - - +using Webshop.Domain.Enums; namespace Webshop.Application.DTOs.Discounts { + /// + /// Repräsentiert einen Rabatt mit all seinen Konfigurationen und Zuweisungen. + /// public class DiscountDto { public Guid Id { get; set; } + + /// + /// Der Name des Rabatts (z.B. "Sommerschlussverkauf", "10% auf alles"). + /// public string Name { get; set; } = string.Empty; - public DiscountType Type { get; set; } - public decimal Value { get; set; } - public string? CouponCode { get; set; } + + /// + /// Der Typ des Rabatts. 'Percentage' für prozentuale Rabatte, 'FixedAmount' für feste Beträge. + /// + public DiscountType DiscountType { get; set; } + + /// + /// Der Wert des Rabatts. Bei 'Percentage' z.B. 10 für 10%. Bei 'FixedAmount' z.B. 5 für 5,00€. + /// + public decimal DiscountValue { get; set; } + + /// + /// Das Datum, an dem der Rabatt aktiv wird. + /// public DateTimeOffset StartDate { get; set; } - public DateTimeOffset EndDate { get; set; } + + /// + /// Optionales Enddatum. Wenn null, ist der Rabatt unbegrenzt gültig. + /// + public DateTimeOffset? EndDate { get; set; } + + /// + /// Gibt an, ob der Rabatt derzeit aktiv ist und angewendet werden kann. + /// public bool IsActive { get; set; } - public int? MaxUses { get; set; } - public int CurrentUses { get; set; } + + /// + /// Wenn 'true', muss ein Gutscheincode eingegeben werden, um den Rabatt zu erhalten. + /// + public bool RequiresCouponCode { get; set; } + + /// + /// Der Gutscheincode, der eingegeben werden muss (z.B. "SUMMER2025"). Muss eindeutig sein. + /// + public string? CouponCode { get; set; } + + /// + /// Der Mindestbestellwert, der erreicht werden muss, damit der Rabatt angewendet wird. + /// + public decimal? MinimumOrderAmount { get; set; } + + /// + /// Die maximale Anzahl, wie oft dieser Rabatt insgesamt eingelöst werden kann. + /// + public int? MaximumUsageCount { get; set; } + + /// + /// Die aktuelle Anzahl der Einlösungen. Wird vom System verwaltet. + /// + public int CurrentUsageCount { get; set; } + + /// + /// Eine interne Beschreibung für den Admin. + /// public string? Description { get; set; } + + /// + /// Eine Liste von Produkt-IDs, auf die dieser Rabatt exklusiv angewendet wird. + /// Wenn leer, gilt der Rabatt für alle Produkte (sofern keine Kategorien zugewiesen sind). + /// + public List AssignedProductIds { get; set; } = new List(); + + /// + /// Eine Liste von Kategorie-IDs. Der Rabatt wird auf alle Produkte in diesen Kategorien angewendet. + /// + public List AssignedCategoryIds { get; set; } = new List(); } -} +} \ No newline at end of file diff --git a/Webshop.Application/DTOs/Shop/AdminShopInfoDto.cs b/Webshop.Application/DTOs/Shop/AdminShopInfoDto.cs index b6c9bde..96145d5 100644 --- a/Webshop.Application/DTOs/Shop/AdminShopInfoDto.cs +++ b/Webshop.Application/DTOs/Shop/AdminShopInfoDto.cs @@ -1,46 +1,88 @@ -// src/Webshop.Application/DTOs/Admin/AdminShopInfoDto.cs +// src/Webshop.Application/DTOs/Shop/AdminShopInfoDto.cs using System.ComponentModel.DataAnnotations; namespace Webshop.Application.DTOs.Shop { + /// + /// Repräsentiert alle zentralen Stammdaten des Shops für die administrative Verwaltung. + /// public class AdminShopInfoDto { + /// + /// Der offizielle Name des Webshops. + /// [Required, MaxLength(255)] public string ShopName { get; set; } = string.Empty; + /// + /// Ein kurzer Marketing-Slogan, der auf der Startseite angezeigt werden kann. + /// [MaxLength(500)] public string? Slogan { get; set; } + /// + /// Die primäre Kontakt-E-Mail-Adresse für Kundenanfragen. + /// [Required, EmailAddress, MaxLength(255)] public string ContactEmail { get; set; } = string.Empty; + /// + /// Die offizielle Telefonnummer des Shops. + /// [Phone, MaxLength(50)] public string? PhoneNumber { get; set; } + /// + /// Straße und Hausnummer der Firmenadresse. + /// [MaxLength(255)] public string? Street { get; set; } + /// + /// Stadt der Firmenadresse. + /// [MaxLength(100)] public string? City { get; set; } + /// + /// Postleitzahl der Firmenadresse. + /// [MaxLength(20)] public string? PostalCode { get; set; } + /// + /// Land der Firmenadresse. + /// [MaxLength(100)] public string? Country { get; set; } + /// + /// Die Umsatzsteuer-Identifikationsnummer des Unternehmens. + /// [MaxLength(50)] public string? VatNumber { get; set; } + /// + /// Die Handelsregisternummer des Unternehmens. + /// [MaxLength(100)] public string? CompanyRegistrationNumber { get; set; } + /// + /// Die URL zur offiziellen Facebook-Seite. + /// [Url, MaxLength(255)] public string? FacebookUrl { get; set; } + /// + /// Die URL zum offiziellen Instagram-Profil. + /// [Url, MaxLength(255)] public string? InstagramUrl { get; set; } + /// + /// Die URL zum offiziellen Twitter/X-Profil. + /// [Url, MaxLength(255)] public string? TwitterUrl { get; set; } } diff --git a/Webshop.Application/DTOs/Shop/PublicShopInfoDto.cs b/Webshop.Application/DTOs/Shop/PublicShopInfoDto.cs index c1815d4..8983c79 100644 --- a/Webshop.Application/DTOs/Shop/PublicShopInfoDto.cs +++ b/Webshop.Application/DTOs/Shop/PublicShopInfoDto.cs @@ -1,19 +1,64 @@ // src/Webshop.Application/DTOs/Shop/PublicShopInfoDto.cs namespace Webshop.Application.DTOs.Shop { - // Dieses DTO enthält nur die Informationen, die ein normaler Kunde sehen soll. + /// + /// Enthält die öffentlichen Stammdaten des Shops, die für Kunden sichtbar sind (z.B. im Footer oder auf der Kontaktseite). + /// public class PublicShopInfoDto { + /// + /// Der offizielle Name des Webshops. + /// public string ShopName { get; set; } = string.Empty; + + /// + /// Ein kurzer Marketing-Slogan. + /// public string? Slogan { get; set; } + + /// + /// Die primäre Kontakt-E-Mail-Adresse. + /// public string ContactEmail { get; set; } = string.Empty; + + /// + /// Die offizielle Telefonnummer. + /// public string? PhoneNumber { get; set; } + + /// + /// Straße und Hausnummer. + /// public string? Street { get; set; } + + /// + /// Stadt. + /// public string? City { get; set; } + + /// + /// Postleitzahl. + /// public string? PostalCode { get; set; } + + /// + /// Land. + /// public string? Country { get; set; } + + /// + /// URL zur Facebook-Seite. + /// public string? FacebookUrl { get; set; } + + /// + /// URL zum Instagram-Profil. + /// public string? InstagramUrl { get; set; } + + /// + /// URL zum Twitter/X-Profil. + /// public string? TwitterUrl { get; set; } } } \ No newline at end of file diff --git a/Webshop.Application/Services/Admin/AdminDiscountService.cs b/Webshop.Application/Services/Admin/AdminDiscountService.cs index bb1b78d..2e14c84 100644 --- a/Webshop.Application/Services/Admin/AdminDiscountService.cs +++ b/Webshop.Application/Services/Admin/AdminDiscountService.cs @@ -1,18 +1,134 @@ -// Auto-generiert von CreateWebshopFiles.ps1 +// src/Webshop.Application/Services/Admin/AdminDiscountService.cs 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; namespace Webshop.Application.Services.Admin { public class AdminDiscountService : IAdminDiscountService { - // Fügen Sie hier Abhängigkeiten per Dependency Injection hinzu (z.B. Repositories) + private readonly IDiscountRepository _discountRepository; - // public AdminDiscountService(IYourRepository repository) { } + public AdminDiscountService(IDiscountRepository discountRepository) + { + _discountRepository = discountRepository; + } - // Fügen Sie hier Service-Methoden hinzu + 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) + { + var discount = MapToEntity(discountDto); + discount.Id = Guid.NewGuid(); + + await _discountRepository.AddAsync(discount); + return MapToDto(discount); + } + + public async Task UpdateDiscountAsync(DiscountDto discountDto) + { + var existingDiscount = await _discountRepository.GetByIdAsync(discountDto.Id); + if (existingDiscount == null) return false; + + // 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; + + // Sync assigned products + existingDiscount.ProductDiscounts.Clear(); + foreach (var productId in discountDto.AssignedProductIds) + { + existingDiscount.ProductDiscounts.Add(new ProductDiscount { ProductId = productId }); + } + + // Sync assigned categories + existingDiscount.categorieDiscounts.Clear(); + foreach (var categoryId in discountDto.AssignedCategoryIds) + { + existingDiscount.categorieDiscounts.Add(new CategorieDiscount { categorieId = categoryId }); + } + + await _discountRepository.UpdateAsync(existingDiscount); + return true; + } + + public async Task DeleteDiscountAsync(Guid id) + { + var discount = await _discountRepository.GetByIdAsync(id); + if (discount == null) return false; + + await _discountRepository.DeleteAsync(id); + return true; + } + + // 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() + }; + } } -} +} \ No newline at end of file diff --git a/Webshop.Application/Services/Admin/Interfaces/IAdminDiscountService.cs b/Webshop.Application/Services/Admin/Interfaces/IAdminDiscountService.cs index ba0aa1a..3d41737 100644 --- a/Webshop.Application/Services/Admin/Interfaces/IAdminDiscountService.cs +++ b/Webshop.Application/Services/Admin/Interfaces/IAdminDiscountService.cs @@ -1,16 +1,17 @@ -// Auto-generiert von CreateWebshopFiles.ps1 +// src/Webshop.Application/Services/Admin/Interfaces/IAdminDiscountService.cs using System; using System.Collections.Generic; using System.Threading.Tasks; -using Webshop.Application.DTOs; -using Webshop.Application.DTOs.Auth; -using Webshop.Application.DTOs.Users; - +using Webshop.Application.DTOs.Discounts; namespace Webshop.Application.Services.Admin.Interfaces { public interface IAdminDiscountService { - // Fügen Sie hier Methodensignaturen hinzu + Task> GetAllDiscountsAsync(); + Task GetDiscountByIdAsync(Guid id); + Task CreateDiscountAsync(DiscountDto discountDto); + Task UpdateDiscountAsync(DiscountDto discountDto); + Task DeleteDiscountAsync(Guid id); } -} +} \ No newline at end of file diff --git a/Webshop.Domain/Interfaces/IDiscountRepository.cs b/Webshop.Domain/Interfaces/IDiscountRepository.cs index b5429f8..f3f3dd0 100644 --- a/Webshop.Domain/Interfaces/IDiscountRepository.cs +++ b/Webshop.Domain/Interfaces/IDiscountRepository.cs @@ -1,14 +1,17 @@ -// Auto-generiert von CreateWebshopFiles.ps1 +// src/Webshop.Domain/Interfaces/IDiscountRepository.cs using System; using System.Collections.Generic; using System.Threading.Tasks; using Webshop.Domain.Entities; - namespace Webshop.Domain.Interfaces { public interface IDiscountRepository { -// Fügen Sie hier Methodensignaturen hinzu + Task> GetAllAsync(); + Task GetByIdAsync(Guid id); + Task AddAsync(Discount discount); + Task UpdateAsync(Discount discount); + Task DeleteAsync(Guid id); } -} +} \ No newline at end of file diff --git a/Webshop.Infrastructure/Data/ApplicationDbContext.cs b/Webshop.Infrastructure/Data/ApplicationDbContext.cs index c7a00b0..beaa2c5 100644 --- a/Webshop.Infrastructure/Data/ApplicationDbContext.cs +++ b/Webshop.Infrastructure/Data/ApplicationDbContext.cs @@ -145,6 +145,32 @@ namespace Webshop.Infrastructure.Data .HasOne(a => a.Customer) // Ein ApplicationUser hat ein optionales Customer-Profil .WithOne(c => c.User) // Ein Customer-Profil ist mit genau einem User verknüpft .HasForeignKey(c => c.AspNetUserId); + + modelBuilder.Entity(entity => + { + entity.HasOne(pd => pd.Product) + .WithMany(p => p.ProductDiscounts) + .HasForeignKey(pd => pd.ProductId); + + entity.HasOne(pd => pd.Discount) + .WithMany(d => d.ProductDiscounts) + .HasForeignKey(pd => pd.DiscountId); + }); + + + // << NEU: Beziehungskonfiguration für CategorieDiscount >> + modelBuilder.Entity(entity => + { + entity.HasOne(cd => cd.categorie) + .WithMany(c => c.categorieDiscounts) + .HasForeignKey(cd => cd.categorieId); + + entity.HasOne(cd => cd.Discount) + .WithMany(d => d.categorieDiscounts) + .HasForeignKey(cd => cd.DiscountId); + }); + + } } } \ No newline at end of file diff --git a/Webshop.Infrastructure/Repositories/DiscountRepository.cs b/Webshop.Infrastructure/Repositories/DiscountRepository.cs index 8fc24c5..bae5945 100644 --- a/Webshop.Infrastructure/Repositories/DiscountRepository.cs +++ b/Webshop.Infrastructure/Repositories/DiscountRepository.cs @@ -1,4 +1,4 @@ -// Auto-generiert von CreateWebshopFiles.ps1 +// src/Webshop.Infrastructure/Repositories/DiscountRepository.cs using Microsoft.EntityFrameworkCore; using Webshop.Domain.Entities; using Webshop.Domain.Interfaces; @@ -18,12 +18,43 @@ namespace Webshop.Infrastructure.Repositories _context = context; } - // Fügen Sie hier Repository-Methoden hinzu - // Beispiel: - // public async Task> GetAllAsync() { return await _context.Set().ToListAsync(); } - // public async Task GetByIdAsync(Guid id) { return await _context.Set().FindAsync(id); } - // public async Task AddAsync(T entity) { _context.Set().Add(entity); await _context.SaveChangesAsync(); } - // public async Task UpdateAsync(T entity) { _context.Set().Update(entity); await _context.SaveChangesAsync(); } - // public async Task DeleteAsync(Guid id) { var entity = await _context.Set().FindAsync(id); if (entity != null) { _context.Set().Remove(entity); await _context.SaveChangesAsync(); } } + public async Task> GetAllAsync() + { + return await _context.Discounts + .Include(d => d.ProductDiscounts) + .Include(d => d.categorieDiscounts) + .OrderBy(d => d.Name) + .ToListAsync(); + } + + public async Task GetByIdAsync(Guid id) + { + return await _context.Discounts + .Include(d => d.ProductDiscounts) + .Include(d => d.categorieDiscounts) + .FirstOrDefaultAsync(d => d.Id == id); + } + + public async Task AddAsync(Discount discount) + { + await _context.Discounts.AddAsync(discount); + await _context.SaveChangesAsync(); + } + + public async Task UpdateAsync(Discount discount) + { + _context.Discounts.Update(discount); + await _context.SaveChangesAsync(); + } + + public async Task DeleteAsync(Guid id) + { + var discount = await _context.Discounts.FindAsync(id); + if (discount != null) + { + _context.Discounts.Remove(discount); + await _context.SaveChangesAsync(); + } + } } -} +} \ No newline at end of file