using CoreConnect.Commerce.Core;
using HotChocolate.Types;
using Attribute = CoreConnect.Commerce.Core.Attribute;
namespace CoreConnect.Commerce.Catalog;
public class Product : Node
/// The ID of the Product.
public required string Id { get; set; }
/// The Key of the Product.
public string? Key { get; set; }
/// The SKU of the Product.
public required string Sku { get; set; }
/// The Name of the Product.
public required string Name { get; set; }
/// The Slug of the Product.
public required string Slug { get; set; }
/// The Description of the Product.
public required string Description { get; set; }
/// The Product version/revision.
public long? Version { get; set; }
/// The Price Include Tax of the Product.
public Money? PriceInclTax { get; set; }
/// The Price Exclude Tax of the Product.
public Money? PriceExclTax { get; set; }
/// The Sale Price Include Tax (Discounted Price Include Tax) of the Product.
public Money? SalePriceInclTax { get; set; }
/// The Sale Price Exclude Tax (Discounted Price Exclude Tax) of the Product.
public Money? SalePriceExclTax { get; set; }
/// The Default Image of the Product.
public Image? DefaultImage { get; set; }
/// The Images of the Product.
public required IEnumerable<Image> Images { get; set; }
/// Gets or sets the categories.
public required IEnumerable<Category> Categories { get; set; }
/// The Attributes of the Product.
public required IEnumerable<Attribute> Attributes { get; set; }
/// The Specifications of the Product.
public required IEnumerable<Attribute>? Specifications { get; set; }
/// The Variants of the Product.
public required IEnumerable<ProductVariant> Variants { get; set; }
public IEnumerable<ProductVariant>? AllVariants { get; set; }
/// The SEO of the Product.
public required Seo Seo { get; set; }
public ProductsResponse? ProductsResponse { get; set; }
/// Gets or sets the created at.
public DateTime CreatedAt { get; set; }
/// Gets or sets the last modified at.
public DateTime LastModifiedAt { get; set; }
/// Gets or sets the first live at.
public DateTime? FirstLiveAt { get; set; }
/// Gets or sets the breadcrumbs.
public required IEnumerable<Breadcrumbs> Breadcrumbs { get; set; }
/// List of related products
public required List<Product> RelatedProducts { get; set; }
[GraphQLType(typeof(AnyType))]
public Dictionary<string, object>? LocalizedSlugs { get; set; }
/// Price Custom fields. Should be manipulated by the consumer to display the right values. Object is of type CentPrecisionMoney
[GraphQLType(typeof(AnyType))]
public Dictionary<string, object>? CustomFields { get; set; }
/// Discounted prices for a product based on quantity tiers
public IEnumerable<TierPrices>? TierPrices { get; set; }
/// Whether the product is published or not
public bool? IsPublished { get; set; }
public List<string>? Discounts { get; set; }
/// Product product type information.
public ProductTypeInfo? ProductTypeInfo { get; set; }
/// Gets or sets the slug.
public required string Slug { get; set; }
/// Gets or sets the key.
public string? Key { get; set; }
/// Gets or sets the name.
public required string Name { get; set; }
/// Gets or sets the path.
public string? Path { get; set; }
public int depth { get; set; }
[ExtendObjectType<Product>]
public class ProductExtension
private const string _variantTotals = "variantTotals";
public ProductMetadata GetMetadata([Parent] Product product)
return SetMetadata(product);
private static ProductMetadata SetMetadata(Product product)
var attributes = product.Variants
.SelectMany(v => v.Attributes)
g => g.Select(a => AttributeValueHelper.GetAttributeValue(a.Value ?? new AttributeValue())).Distinct().ToList()
var jsonAttributes = JsonSerializer.Serialize(attributes);
var jsonBuilder = new StringBuilder();
jsonBuilder.Append(jsonAttributes);
return new ProductMetadata(_variantTotals, JsonDocument.Parse(jsonBuilder.ToString()).RootElement);
public class ProductMetadata
public ProductMetadata(string key, JsonElement value)
public string Key { get; set; }
public JsonElement Value { get; set; }
public class ProductsResponse
public ProductsResponse(List<Product> products, ProductsResponseTotals productsResponseTotals)
ProductsResponseTotals = productsResponseTotals;
public List<Product> Products { get; set; }
public ProductsResponseTotals ProductsResponseTotals { get; set; }
public class ProductsResponseTotals
public ProductsResponseTotals(long limit, long offset, long? total)
/// The maximum number of records to retrieve.
public long Limit { get; set; }
/// By specifying offset, you retrieve a subset of records starting with the offset.
public long Offset { get; set; }
public long? Total { get; set; }
public class ProductTypeInfo
public string? Name { get; set; }
public string? ProductTypeId { get; set; }