47 lines
1.5 KiB
C#
47 lines
1.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Prefab.Catalog.Domain.Entities;
|
|
|
|
namespace Prefab.Web.Pricing;
|
|
|
|
public sealed record FromPriceResult(decimal? Amount, string? Currency, bool IsPriced);
|
|
|
|
/// <summary>
|
|
/// Computes a display-friendly "from price" for catalog products by examining model and variant pricing.
|
|
/// </summary>
|
|
public sealed class FromPriceCalculator
|
|
{
|
|
private const string DefaultCurrency = "USD";
|
|
private readonly string _currencyCode;
|
|
|
|
public FromPriceCalculator(string? currencyCode = null)
|
|
{
|
|
_currencyCode = string.IsNullOrWhiteSpace(currencyCode) ? DefaultCurrency : currencyCode.Trim();
|
|
}
|
|
|
|
public FromPriceResult Compute(Product product)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(product);
|
|
|
|
if (product.Price.HasValue)
|
|
{
|
|
return new FromPriceResult(product.Price.Value, _currencyCode, true);
|
|
}
|
|
|
|
var variantPrices = ExtractVariantPrices(product.Variants);
|
|
if (variantPrices.Count > 0)
|
|
{
|
|
var minimum = variantPrices.Min();
|
|
return new FromPriceResult(minimum, _currencyCode, true);
|
|
}
|
|
|
|
return new FromPriceResult(null, null, false);
|
|
}
|
|
|
|
private static List<decimal> ExtractVariantPrices(IEnumerable<Product> variants) =>
|
|
variants
|
|
.Where(variant => variant is { Kind: ProductKind.Variant, Price: not null })
|
|
.Select(variant => variant.Price!.Value)
|
|
.ToList();
|
|
}
|