Latest
This commit is contained in:
132
Prefab.Web.Client/Models/Catalog/ProductDisplayModel.cs
Normal file
132
Prefab.Web.Client/Models/Catalog/ProductDisplayModel.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Prefab.Shared.Catalog.Products;
|
||||
|
||||
namespace Prefab.Web.Client.Models.Catalog;
|
||||
|
||||
/// <summary>
|
||||
/// UI-facing projection of the catalog product detail configuration payload.
|
||||
/// </summary>
|
||||
public sealed class ProductDisplayModel
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
|
||||
public string Slug { get; init; } = string.Empty;
|
||||
|
||||
public string Name { get; init; } = string.Empty;
|
||||
|
||||
public string? Description { get; init; }
|
||||
|
||||
public decimal? BasePrice { get; init; }
|
||||
|
||||
public string? Sku { get; init; }
|
||||
|
||||
public IReadOnlyList<CategoryRef> Categories { get; init; } = Array.Empty<CategoryRef>();
|
||||
|
||||
public IReadOnlyList<OptionDefinition> Options { get; init; } = Array.Empty<OptionDefinition>();
|
||||
|
||||
public IReadOnlyList<Spec> Specs { get; init; } = Array.Empty<Spec>();
|
||||
|
||||
public IReadOnlyDictionary<string, string>? GenericAttributes { get; init; }
|
||||
|
||||
public sealed record OptionDefinition(
|
||||
Guid Id,
|
||||
string Code,
|
||||
string Name,
|
||||
int DataType,
|
||||
bool IsVariantAxis,
|
||||
string? Unit,
|
||||
decimal? Min,
|
||||
decimal? Max,
|
||||
decimal? Step,
|
||||
decimal? PricePerUnit,
|
||||
IReadOnlyList<Tier> Tiers,
|
||||
IReadOnlyList<OptionValue> Values);
|
||||
|
||||
public sealed record OptionValue(
|
||||
Guid Id,
|
||||
string Code,
|
||||
string Label,
|
||||
decimal? PriceDelta,
|
||||
int PriceDeltaKind);
|
||||
|
||||
public sealed record Tier(
|
||||
decimal FromInclusive,
|
||||
decimal? ToInclusive,
|
||||
decimal UnitRate,
|
||||
decimal? FlatDelta);
|
||||
|
||||
public sealed record Spec(
|
||||
string Name,
|
||||
string? Value,
|
||||
decimal? NumericValue,
|
||||
string? UnitCode);
|
||||
|
||||
public sealed record CategoryRef(
|
||||
Guid Id,
|
||||
string Name,
|
||||
string Slug);
|
||||
|
||||
public static ProductDisplayModel From(GetProductDetail.ProductDetailDto product)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(product);
|
||||
|
||||
var options = product.Options?
|
||||
.Select(option => new OptionDefinition(
|
||||
option.Id,
|
||||
option.Code,
|
||||
option.Name,
|
||||
option.DataType,
|
||||
option.IsVariantAxis,
|
||||
option.Unit,
|
||||
option.Min,
|
||||
option.Max,
|
||||
option.Step,
|
||||
option.PricePerUnit,
|
||||
option.Tiers?
|
||||
.Select(tier => new Tier(
|
||||
tier.FromInclusive,
|
||||
tier.ToInclusive,
|
||||
tier.UnitRate,
|
||||
tier.FlatDelta))
|
||||
.ToList() ?? new List<Tier>(),
|
||||
option.Values?
|
||||
.Select(value => new OptionValue(
|
||||
value.Id,
|
||||
value.Code,
|
||||
value.Label,
|
||||
value.PriceDelta,
|
||||
value.PriceDeltaKind))
|
||||
.ToList() ?? new List<OptionValue>()))
|
||||
.ToList() ?? new List<OptionDefinition>();
|
||||
|
||||
var specs = product.Specs?
|
||||
.Select(spec => new Spec(
|
||||
spec.Name,
|
||||
spec.Value,
|
||||
spec.NumericValue,
|
||||
spec.UnitCode))
|
||||
.ToList() ?? new List<Spec>();
|
||||
|
||||
var categories = product.Categories?
|
||||
.Select(category => new CategoryRef(
|
||||
category.Id,
|
||||
category.Name,
|
||||
category.Slug))
|
||||
.ToList() ?? new List<CategoryRef>();
|
||||
|
||||
return new ProductDisplayModel
|
||||
{
|
||||
Id = product.Id,
|
||||
Slug = product.Slug,
|
||||
Name = product.Name,
|
||||
Description = product.Description,
|
||||
BasePrice = product.Price,
|
||||
Sku = product.Sku,
|
||||
Categories = categories,
|
||||
Options = options,
|
||||
Specs = specs,
|
||||
GenericAttributes = product.GenericAttributes
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user