Pricing
Overview
In Elastic Path, product and SKU prices are stored in price lists. In the case where both a product and a SKU of that product have a price defined in a price list, the SKU price takes precedence over the product price. There is at least one price list for each supported currency and catalog.
Product and SKU prices in Elastic Path Commerce are represented by implementations of the Price
interface. The Price
interface is designed to support multiple price tiers in which the price of an item depends on the quantity in which it is purchased. The interface also supports clients that require only one price for any quantity and do not provide quantity parameters. A price is specific to a particular currency and objects aggregating prices typically maintain a map from currency to price.
note
Before version 6.2, price information in Elastic Path Commerce was tightly coupled with the product catalog. As of 6.2, all price information (price tiers, sale and list prices, etc.) is now stored in separate price lists. For an overview of how the new price list stack mechanism works, see How pricing is applied section below.
How pricing is applied
When a shopper accesses a storefront, the system must determine that shopper’s selling context. The selling context is determined by evaluating a series of Tagging Framework against:
- The current time
- The store that the shopper is accessing
- Various information that has been collected about the shopper, such the referring URL, the landing page, or geolocation
After the selling context has been identified, the the price lists for the selling context are retrieved via their price list associations. Next, promotion rules are executed to apply discounts to those prices, if any. These price lists are placed in an ordered stack and assigned to the user. This is referred to as the shopper’s price list stack. The order of price lists within the stack is determined by a priority value, which is set by the person who assigned the price list to the selling context.
As the shopper browses the store’s catalog, the system looks up each product’s price in the price list stack, beginning with the topmost price list in the stack. If a product’s price is not found in that price list, the system will look in the next price list, and so on, until a price is found.
Selling context re-evaluation
During the course of a shopping session, the shopper segment may change. For example, if the shopper was browsing anonymously and then decided to sign in to their account. When this occurs, the selling context conditions are re-evaluated, promotion rules are executed again, and the price list stack is rebuilt.
When items are added to the shopping cart, the promotions are executed to apply cart discounts as required.
Customizing the price list stack lookup strategy
As mentioned in the topic on How pricing is applied, every shopper is given a price list stack, which contains the prices of all catalog items for that specific shopper at that specific time in the given currency. Internally, the system calls the PriceListLookupService
's getPriceListStack
method to generate and return the price list stack.
The actual process of building the price list stack is delegated to a strategy. Out of the box, Elastic Path Commerce provides one strategy implementation, the PLAStackLookupStrategy
. The business logic of this strategy can be summarized as follows:
- Get all price lists assigned to the specified catalog and currency
- Sort them by priority
- Remove the price lists that do not match the selling context (based on the conditions in the shopper’s tag set)
You can customize how price list stacks are created by creating a custom price list lookup strategy.
First, create a class that implements the PriceListStackLookupStrategy
interface (in the com.elasticpath.common.pricing.service
package). This interface defines a single method, which you must implement to return the shopper’s price list stack:
PriceListStack getPriceListStack(String catalogCode, Currency currency, TagSet tagSet);
catalogCode
is the GUID of the catalog the shopper is currently browsingcurrency
is the currencytagSet
is the set of Tagging Framework assigned to the shopper
Next, in the com.elasticpath.core
project, edit WEB-INF/conf/spring/service/service.xml
. Add a bean definition for your custom strategy bean.
<bean id="customPLStackLookupStrategy" class="org.example.CustomPriceListStackLookupStrategy">
...
</bean>
Then, locate the priceListLookupService
bean definition. Set the plStackLookupStrategy
property to point to your custom strategy.
<bean id="priceListLookupService" class="com.elasticpath.common.pricing.service.impl.PriceListLookupServiceImpl">
<property name="plStackLookupStrategy" ref="customPLStackLookupStrategy"/>
</bean>
Managing pricing
Getting Prices in the Cart
The shopping cart uses the PriceLookupFacade
service to retrieve prices. For example AbstractCatalogControllerImpl
contains the following code:
protected Map<String, Price> getProductPrices(final Collection<StoreProduct> products, final ShoppingCart cart) {
if (products == null) {
return Collections.EMPTY_MAP;
}
return priceLookupFacade.getPromotedPricesForProducts(
new ArrayList<Product>(products),
cart.getStore(),
cart.getCustomerSession(),
cart.getAppliedRules());
}
The getPromotedPricesForProducts
method of PriceLookupFacade returns a map of prices (keyed on product code) for the current shopper for the specified products with all cart promotion rules applied.
Getting the Shopper’s Price List Stack
The PriceListLookupService's retrievePriceListStack
method is called to fetch the price list stack.
void retrievePriceListStack(final CustomerSession customerSession) {
customerSession.setPriceListStack(
priceListLookupService.getPriceListStack(
customerSession.getCustomer().getStore().getCatalog().getCode(),
customerSession.getCurrency(),
customerSession.getCustomerTagSet()
)
);
}
getPriceListStack
gets the price list stack for a shopper in the specified currency. Note that you can customize how it determines which price lists are in the stack by Customizing the price list stack lookup strategy and wiring it to the PriceListLookupService
bean.
Getting Prices in the Commerce Manger
The PriceListService
is used in the CM to retrieve price list descriptors and prices. Note that this service uses DTOs to minimize overhead of working with domain objects, which contain additional data and persistence method that are not required on the client.
PriceListService priceListService = getBeanFactory().getBean(ContextIdNames.PRICE_LIST_CLIENT_SERVICE);
BaseAmountDTO baseAmount = priceListService.getBaseAmount(baseAmountGuid);
Price classes and interfaces
The price domain objects are located in the com.elasticpath.domain.catalog
package of the core library:
- Price - contains the tiered prices for a product or SKU in a specific currency, including the list price, sale price, and computed price (after Promotion rule engine have been applied)
- PriceTier - contains the price of an item when purchased in a given quantity
The price list domain objects are located in the com.elasticpath.domain.pricing
package of the core library, including:
- BaseAmount - information about a price list item for a quantity (tier), including list price and sale price
- PriceListDescriptor - metadata about a price list (its name, its priority, the currency, etc.)
- PriceListStack - the set of price lists assigned to the shopper
- ItemPricing - contains price information for a line item in an order
Price related services are in the com.elasticpath.common.pricing.service
package of the core library:
Main interface used to retrieve the promoted prices for products and SKUs
Used to return the price list stack for a specific shopper
The building of the stack is delegated to a Customizing the price list stack lookup strategy
PriceListAssignmentHelperService
- Used when working with price lists in the Commerce ManagerThese services use lightweight versions of the price list domain objects (DTOs) to reduce the overhead of working with the standard domain objects
Additional price list services are in the com.elasticpath.service.pricing
package of the core library:
PriceLookupService
- contains methods that take products, SKUs, and price list stacks as parameters and return the appropriate pricesPriceListDescriptorService
- contains methods for persisting price list descriptor objects
Price database schema
The following database tables are used to store Pricing:
TPRICELIST
: Contains the price lists descriptors (metadata about price lists)TBASEAMOUNT
: Contains the base and sale prices and price tiersTPRICELISTASSIGNMENT
: Contins the prioritized associations between price lists, selling context, and catalogsTSELLINGCONTEXT
: Contains the selling contextsTSELLINGCONTEXTCONDITION
: Associates the selling context with the conditions that define it. For more information on conditions, see the Tagging Framework section