In this multi-part article, we will review the Sellable Item/Variant price calculation processes that determines and differentiates the list pricing from the sell pricing.
As this is one of the more complex areas of Sitecore Commerce, Part 1 will cover the business logic used to apply the pricing, while Pricing Calculation Logic – Part 2 will highlight the expected pricing outcomes through decision tables.
This article is intended to suplement the official Pricing transparency documentation.
Introduction
The MessagesComponent on the SellableItem entity, ItemVariationComponent, and CartProductComponent provides the audit trail for how the sellable item/variant pricing was calculated. The ‘<=‘ in the Text property is not a logic operator, but instead represents the assignment of the source to the price type.
{ "@odata.type": "#Sitecore.Commerce.Core.MessagesComponent", "Id": "47edb873fe754c89ae4bc41d7c309811", "Name": "", "Comments": "", "Policies": [], "Messages": [ { "Code": "Pricing", "Text": "SellPrice<=PriceCard.Snapshot: Price=$10.00|Qty=1.0|PriceCard=Habitat_PriceCard" }, { "Code": "Pricing", "Text": "ListPrice<=PricingPolicy: Price=$1,919.69" } ], "ChildComponents": [] }
{ "@odata.type": "#Sitecore.Commerce.Core.MessagesComponent", "Id": "ed77a9de5db941ffbfcf0b217e3affda", "Name": "", "Comments": "", "Policies": [], "Messages": [ { "Code": "Pricing", "Text": "Variation.SellPrice<=Variation.PriceCard.Snapshot: Price=$9.00|Qty=1.0|Variation=56042567|PriceCard=Habitat_VariantsPriceCard" }, { "Code": "Pricing", "Text": "Variation.ListPrice<=Variation.PricePolicy: Variation=56042567|Price=$2,429.99" } ], "ChildComponents": [] }
{ "@odata.type": "#Sitecore.Commerce.Core.MessagesComponent", "Id": "7e6bc27965ef4f3a954e6fcdadb96fa5", "Name": "", "Comments": "", "Policies": [], "Messages": [ { "Code": "Pricing", "Text": "SellPrice<=PriceCard.Snapshot: Price=$10.00|Qty=1.0|PriceCard=Habitat_PriceCard" }, { "Code": "Pricing", "Text": "ListPrice<=PricingPolicy: Price=$1,919.69" }, { "Code": "Pricing", "Text": "Variation.SellPrice<=Variation.PriceCard.Snapshot: Price=$9.00|Qty=1.0|Variation=56042567|PriceCard=Habitat_VariantsPriceCard" }, { "Code": "Pricing", "Text": "Variation.ListPrice<=Variation.PricePolicy: Variation=56042567|Price=$2,429.99" }, { "Code": "Pricing", "Text": "CartItem.SellPrice<=PriceCard.ActiveSnapshot: Price=$6.00|Qty=5.0" }, { "Code": "Pricing", "Text": "CartItem.ListPrice<=SellableItem.Variation.ListPrice: Price=$2,429.99" } ], "ChildComponents": [] }
The 2 primary pricing scenarios we see in Sitecore Commerce are:
- The pricing of a sellable item/variant as is (per single unit)
- The pricing of a sellable item/variant once added to the cart. Pricing calculations here may also affected by quantity, via price tiers of associated price cards, and specific promotions that affect the sell price.
Sellable Item/Variant Pricing Calculations
The first scenario, where we are retrieving a sellable item/variant, to display on the Product Listing or Product Details pages for example, calculates the pricing through the following steps:
- Calculate Sellable Item Sell Price
- Calculate Variations Sell Price
- Calculate Sellable Item List Price
- Calculate Variations List Price
- Reconcile Sellable Item Prices
Important notes:
- The business logic applies to the OOTB Sitecore Commerce solution.
- Price cards are resolved by the price book associated to the catalog.
- These findings do not take into consideration promotions, specifically those that affect sellable item/variant sell price.
Calculate Sellable Item Sell Price
The CalculateSellableItemSellPriceBlock will attempt to determine the sell price for the sellable item, adding it to the PurchaseOptionMoneyPolicy.
Notable flow aspects
- Only the first attempt at resolving a price card will be utilised. i.e. if the price card name associated to the sellable item cannot be resolved to a price card or valid snapshot, the price card by tags logic is not used as a fall back.
Calculate Variations Sell Price
The CalculateVariationsSellPriceBlock will attempt to determine the sell price for each variant of the sellable item.
Notable flow aspects
- The flow diagram represents a single variant. The pipeline block will utilise this flow for each variant.
- Only the first attempt at resolving a price card will be utilised.
- If the price card is resolved from the sellable item, the message will not reflect that the price card was retrieved from the sellable item.
Calculate Sellable Item List Price
The CalculateSellableItemListPriceBlock will attempt to determine the list price for sellable item.
Notable flow aspects
- The GlobalPricingPolicy‘s CalculateItemListPriceInDepth property is set to false by default.
- When iterating over variants for a valid ListPricingPolicy, the first variant to have a valid ListPricingPolicy will be used. The logic does not look for the lowest or highest price amongst all variants.
Calculate Variations List Price
The CalculateVariationsListPriceBlock will attempt to determine the list price for each variant of the sellable item.
Reconcile Sellable Item Prices
The ReconcileSellableItemPricesBlock will attempt to resolve missing List Prices and Sell Prices from the sellable item and variants. A flow diagram has been created for the Sellable Item and Variants separately.
Notable flow aspects
- Setting the list price to 0 will ensure a price has been assigned.
Notable flow aspects
- Setting the list price to 0 will ensure a price has been assigned.
Cart Line Calculations
The second scenario mentioned was that where the pricing calculation of sellable items/variants that have been added to the cart. The following step is performed after the standard pricing calculations to take into consideration the price tiers from price cards:
- Calculate Cart Line Price
Calculate Cart Line Price
The CalculateCartLinePricesBlock will determine and apply the appropriate list and sell prices for each cart line.
Notable flow aspects
- There is an expectation that the list price and sell prices would have been resolved in Reconcile Sellable Item Prices.
- Where a snapshot exists on a sellable item/variant the cart line’s quantity value will determine the price tier that will be utilised to retrieve the sell price from.
- The messages from the Sellable Item and, if applicable, Variant are copied into the cart line MessagesComponent to document the pricing stacks, which assist in auditing pricing overrides in determining the final pricing.
Glossary
Navigating the pricing logic can be time-consuming due to similar and varied terms being used for similar or varying components, so here is a short glossary for better clarification.
- Sellable Item/Variant List Pricing (Policy): The list pricing policy represents an array of prices (only one price per currency) that are associated to a sellable item/variant is specified under the Pricing entity view of the sellable item/variant in the Merchanding manager.
- Price Card (Name): The price card or price card name associated to the sellable item/variant is specified under the Pricing entity view of the sellable item/variant in the Merchanding manager.
- Sellable Item/Variant list price: This is the ListPrice property of a Sellable Item/Variant, not to be confused with the ListPricingPolicy.
"Policies": [ { "@odata.type": "#Sitecore.Commerce.Plugin.Pricing.ListPricingPolicy", "PolicyId": "0d4cee51dffd44aa8a019394dd5ad1b1", "Prices": [ { "CurrencyCode": "USD", "Amount": 1919.69 }, { "CurrencyCode": "CAD", "Amount": 2078.26 } ] } ], "ListPrice": { "CurrencyCode": "USD", "Amount": 1919.69 }
- Sell Price: The sell price is associated to a Sellable Item/Variant or Cart Line via the PurchaseOptionMoneyPolicy.
"Policies": [ { "@odata.type": "#Sitecore.Commerce.Plugin.Pricing.PurchaseOptionMoneyPolicy", "PolicyId": "12b963fe3b2b47618555c8783c877002", "Models": [], "Expires": "2019-04-22T12:30:46.5380974Z", "SellPrice": { "CurrencyCode": "USD", "Amount": 10 }, "FixedSellPrice": false } ]
- (Cart Line) Unit List Price: This is the determined list price of the cart line.
"Policies": [ { "@odata.type": "#Sitecore.Commerce.Plugin.Pricing.PurchaseOptionMoneyPolicy", "PolicyId": "5e6c1f42c7c94bc4b79696e716b6cda5", "Models": [], "Expires": "2019-04-22T13:13:18.8117816Z", "SellPrice": { "CurrencyCode": "USD", "Amount": 6 }, "FixedSellPrice": false } ], "UnitListPrice": { "CurrencyCode": "USD", "Amount": 2429.99 }