sonderangebot artikel
This commit is contained in:
@@ -49,5 +49,15 @@ namespace Webshop.Api.Controllers.Public
|
||||
|
||||
return Ok(product);
|
||||
}
|
||||
/// <summary>
|
||||
/// Ruft eine Liste der Sonderangebote f<>r die Startseite ab, sortiert nach Anzeigereihenfolge.
|
||||
/// </summary>
|
||||
[HttpGet("featured")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProductDto>), 200)]
|
||||
public async Task<ActionResult<IEnumerable<ProductDto>>> GetFeaturedProducts()
|
||||
{
|
||||
var products = await _productService.GetFeaturedProductsAsync();
|
||||
return Ok(products);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,16 @@ namespace Webshop.Application.DTOs.Products
|
||||
public bool IsInStock { get; set; } = true;
|
||||
public int StockQuantity { get; set; }
|
||||
public decimal? Weight { get; set; }
|
||||
// << ENTFERNT: ImageUrl >>
|
||||
public string Slug { get; set; } = string.Empty;
|
||||
public DateTimeOffset CreatedDate { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset? LastModifiedDate { get; set; }
|
||||
public Guid? SupplierId { get; set; }
|
||||
public decimal? PurchasePrice { get; set; }
|
||||
public List<Guid> categorieIds { get; set; } = new List<Guid>();
|
||||
public List<ProductImageDto> Images { get; set; } = new List<ProductImageDto>(); // << NEU >>
|
||||
public List<ProductImageDto> Images { get; set; } = new List<ProductImageDto>();
|
||||
|
||||
// << NEU >>
|
||||
public bool IsFeatured { get; set; }
|
||||
public int FeaturedDisplayOrder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -30,5 +30,8 @@ namespace Webshop.Application.DTOs.Products
|
||||
public decimal? OldPrice { get; set; }
|
||||
public Guid? SupplierId { get; set; }
|
||||
public decimal? PurchasePrice { get; set; }
|
||||
|
||||
public bool IsFeatured { get; set; } = false;
|
||||
public int FeaturedDisplayOrder { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,7 @@ namespace Webshop.Application.DTOs.Products
|
||||
public decimal? OldPrice { get; set; }
|
||||
public Guid? SupplierId { get; set; }
|
||||
public decimal? PurchasePrice { get; set; }
|
||||
public bool IsFeatured { get; set; }
|
||||
public int FeaturedDisplayOrder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -137,6 +137,8 @@ namespace Webshop.Application.Services.Admin
|
||||
OldPrice = productDto.OldPrice,
|
||||
SupplierId = productDto.SupplierId,
|
||||
PurchasePrice = productDto.PurchasePrice,
|
||||
IsFeatured = productDto.IsFeatured, // << NEU >>
|
||||
FeaturedDisplayOrder = productDto.FeaturedDisplayOrder, // << NEU >>
|
||||
Images = images,
|
||||
Productcategories = productDto.CategorieIds.Select(cId => new Productcategorie { categorieId = cId }).ToList()
|
||||
};
|
||||
@@ -196,6 +198,8 @@ namespace Webshop.Application.Services.Admin
|
||||
existingProduct.SupplierId = productDto.SupplierId;
|
||||
existingProduct.PurchasePrice = productDto.PurchasePrice;
|
||||
existingProduct.LastModifiedDate = DateTimeOffset.UtcNow;
|
||||
existingProduct.IsFeatured = productDto.IsFeatured; // << NEU >>
|
||||
existingProduct.FeaturedDisplayOrder = productDto.FeaturedDisplayOrder; // << NEU >>
|
||||
|
||||
// Kategorien synchronisieren
|
||||
existingProduct.Productcategories.Clear();
|
||||
|
||||
@@ -10,5 +10,6 @@ namespace Webshop.Application.Services.Public.Interfaces
|
||||
Task<IEnumerable<ProductDto>> GetAllProductsAsync();
|
||||
|
||||
Task<ProductDto?> GetProductBySlugAsync(string slug);
|
||||
Task<IEnumerable<ProductDto>> GetFeaturedProductsAsync(); // << NEU >>
|
||||
}
|
||||
}
|
||||
@@ -89,5 +89,42 @@ namespace Webshop.Application.Services.Public
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProductDto>> GetFeaturedProductsAsync()
|
||||
{
|
||||
var products = await _context.Products
|
||||
.Where(p => p.IsActive && p.IsFeatured)
|
||||
.OrderBy(p => p.FeaturedDisplayOrder)
|
||||
.Include(p => p.Images)
|
||||
.Include(p => p.Productcategories).ThenInclude(pc => pc.categorie)
|
||||
.ToListAsync();
|
||||
|
||||
return products.Select(p => new ProductDto
|
||||
{
|
||||
Id = p.Id,
|
||||
Name = p.Name,
|
||||
Description = p.ShortDescription, // F<>r die Startseite ist die Kurzbeschreibung ideal
|
||||
SKU = p.SKU,
|
||||
Price = p.Price,
|
||||
IsActive = p.IsActive,
|
||||
IsInStock = p.IsInStock,
|
||||
StockQuantity = p.StockQuantity,
|
||||
Slug = p.Slug,
|
||||
categories = p.Productcategories.Select(pc => new CategorieDto
|
||||
{
|
||||
Id = pc.categorie.Id,
|
||||
Name = pc.categorie.Name,
|
||||
Slug = pc.categorie.Slug
|
||||
}).ToList(),
|
||||
Images = p.Images.OrderBy(i => i.DisplayOrder).Select(img => new ProductImageDto
|
||||
{
|
||||
Id = img.Id,
|
||||
Url = img.Url,
|
||||
IsMainImage = img.IsMainImage,
|
||||
DisplayOrder = img.DisplayOrder
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,9 +33,6 @@ namespace Webshop.Domain.Entities
|
||||
public decimal? Height { get; set; }
|
||||
public decimal? Length { get; set; }
|
||||
|
||||
// << ENTFERNT: ImageUrl wird durch Images ersetzt >>
|
||||
// public string? ImageUrl { get; set; }
|
||||
|
||||
[Required, MaxLength(255)]
|
||||
public string Slug { get; set; } = string.Empty;
|
||||
[Required]
|
||||
@@ -45,13 +42,16 @@ namespace Webshop.Domain.Entities
|
||||
public Guid? SupplierId { get; set; }
|
||||
public decimal? PurchasePrice { get; set; }
|
||||
|
||||
// << NEUE EIGENSCHAFTEN FÜR SONDERANGEBOTE >>
|
||||
public bool IsFeatured { get; set; } = false;
|
||||
public int FeaturedDisplayOrder { get; set; } = 0;
|
||||
// << ENDE NEUE EIGENSCHAFTEN >>
|
||||
|
||||
public virtual Supplier? Supplier { get; set; }
|
||||
public virtual ICollection<ProductVariant> Variants { get; set; } = new List<ProductVariant>();
|
||||
public virtual ICollection<Review> Reviews { get; set; } = new List<Review>();
|
||||
public virtual ICollection<ProductDiscount> ProductDiscounts { get; set; } = new List<ProductDiscount>();
|
||||
public virtual ICollection<Productcategorie> Productcategories { get; set; } = new List<Productcategorie>();
|
||||
|
||||
// << NEU: Navigation Property zu Bildern >>
|
||||
public virtual ICollection<ProductImage> Images { get; set; } = new List<ProductImage>();
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ using Webshop.Infrastructure.Data;
|
||||
namespace Webshop.Infrastructure.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250812113218_checkout")]
|
||||
partial class checkout
|
||||
[Migration("20250812123244_featureartikel")]
|
||||
partial class featureartikel
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@@ -576,6 +576,9 @@ namespace Webshop.Infrastructure.Migrations
|
||||
.HasMaxLength(4000)
|
||||
.HasColumnType("character varying(4000)");
|
||||
|
||||
b.Property<int>("FeaturedDisplayOrder")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal?>("Height")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
@@ -583,6 +586,9 @@ namespace Webshop.Infrastructure.Migrations
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsFeatured")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsInStock")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
@@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
namespace Webshop.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class checkout : Migration
|
||||
public partial class featureartikel : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
@@ -460,7 +460,9 @@ namespace Webshop.Infrastructure.Migrations
|
||||
CreatedDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
|
||||
LastModifiedDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
||||
SupplierId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
PurchasePrice = table.Column<decimal>(type: "numeric(18,2)", precision: 18, scale: 2, nullable: true)
|
||||
PurchasePrice = table.Column<decimal>(type: "numeric(18,2)", precision: 18, scale: 2, nullable: true),
|
||||
IsFeatured = table.Column<bool>(type: "boolean", nullable: false),
|
||||
FeaturedDisplayOrder = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
@@ -573,6 +573,9 @@ namespace Webshop.Infrastructure.Migrations
|
||||
.HasMaxLength(4000)
|
||||
.HasColumnType("character varying(4000)");
|
||||
|
||||
b.Property<int>("FeaturedDisplayOrder")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal?>("Height")
|
||||
.HasPrecision(18, 2)
|
||||
.HasColumnType("numeric(18,2)");
|
||||
@@ -580,6 +583,9 @@ namespace Webshop.Infrastructure.Migrations
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsFeatured")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsInStock")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user