Price for sale computation algorithm
This chapter details the algorithm behind sale price calculation, exploring how it incorporates factors such as currency selection, applicable discounts, and price list selection based on user context. We'll walk through the logic with code snippets and real-world scenarios, providing a clear understanding of how the algorithm functions to accurately compute sale prices in a dynamic e-commerce environment.
Terms used in this document
- ERP
Enterprise Resource Planning (ERP) is a type of software system that helps organizations automate and manage core business processes for optimal performance. ERP software coordinates the flow of data between an organization's business processes, providing a single source of truth and streamlining operations across the enterprise. It's capable of linking a company's financial, supply chain, operations, trading, reporting, manufacturing, and human resources activities on one platform.
- product
- A product is an entity that represents the item sold at an e-commerce store. The products represent the very core of each e-commerce application.
- product with variants
- A product with a variant is a "virtual product" that cannot be bought directly. A customer must choose one of its variants
instead. Products with variants are very often seen in e-commerce fashion stores where clothes come in various sizes
and colors. A single product can have dozens combinations of size and color. If each combination represented standard
product, a product listing in a category and other places would become unusable.
In this situation, products with variants become very handy. This "virtual product" can be listed instead of variants
and a variant selection is performed at the time of placing the goods into the cart. Let's have an example:
We have a T-Shirt with a unicorn picture on it. The T-Shirt is produced in different sizes and colors - namely:
– size: S, M, L, XL, XXL
– color: blue, pink, violet
That represents 15 possible combinations (variants). Because we only want a single unicorn T-Shirt in our listings, we create a product with variants and enclose all variant combinations to this virtual product. - product set
- A product set is a product that consists of several sub products, but is purchased as a whole. A real life example of such
product set is a drawer - it consists of the body, the door and handles. A customer could even choose which type of doors
or handles they want in the set - but there always be some defaults.
When displaying and filtering by a product set in the listings on the e-commerce site, we need some price assigned for it but there may be a none exact price assigned to the set and the e-commerce owner expects that price would be computed as an aggregation of the prices of sub-products. This behaviour is supported by setting proper PriceInnerEntityReferenceHandling.
The price calculation logic in evitaDB is designed in a very simple way that supports common pricing mechanisms and allows adaptation to even uncommon ones.
- in a specific currency (priceInCurrency)
- that are valid at a certain time (priceValidIn)
- that belong to some defined sets or price lists to which the end user has access (priceInPriceLists)
Model examples for standard cases
Let's have the following products:
Product | Baseline price | Price list A | Price list B | Price list C |
---|---|---|---|---|
Honor 10 | €10000 | €9000 (valid 1.1.2020 00:00:000 - 31.1.2020 23:59:59) | €7500 | |
HUAWEI 20 Pro | €12000 | €14000 | €8500 | |
iPhone Xs Max | €21000 | €23000 | €19000 (valid 1.1.2020 01:00:000 - 31.1.2020 22:59:59) |
Client logic could work as follows: list all user price lists whose validity overlaps an interval from now to +1 hour, ordered by priority/order attribute, cache for one hour (this could be handled by a single EvitaDB query).
These results are expected for the following queries:
First query
- price lists: A, Baseline (argument order controls price list priority)
- valid in: 1.11.2020 13:00:00
Product | Price for sale |
---|---|
Honor 10 | €10000 |
HUAWEI 20 Pro | €14000 |
iPhone Xs Max | €23000 |
Second query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 1.11.2020 13:00:00
Product | Price for sale |
---|---|
Honor 10 | €10000 |
HUAWEI 20 Pro | €14000 |
iPhone Xs Max | €23000 |
Third query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 2.1.2020 13:00:00
Product | Price for sale |
---|---|
Honor 10 | €9000 |
HUAWEI 20 Pro | €14000 |
iPhone Xs Max | €19000 |
Fourth query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 2.1.2020 13:00:00
- price between: €8000 and €10000 (both inclusive)
Product | Price for sale |
---|---|
Honor 10 | €9000 |
Product variants extension
In this product setup, the selling price is selected as the lowest selling price of all variants. This price is used to filter products by price.
The entity will also provide calculated prices for each of the product variants, selecting the first price ranked by priority for each inner entity identifier. This information can be used to display the price range for the product with variants (i.e. price from €5 to €6.5) or to calculate an average price for sale of all product variants.
Model example
Let's have the following products:
Product | Master product | Baseline price | Price list A | Price list B | Price list C |
---|---|---|---|---|---|
Variant: blue | T-Shirt I Rock | €10 | €9 (valid 1.1.2020 00:00:000 - 31.1.2020 23:59:59) | €7.5 | |
Variant: red | T-Shirt I Rock | €12 | €14 | €8.5 | |
Variant: green | T-Shirt I Rock | €21 | €23 | €19 (valid 1.1.2020 01:00:000 - 31.1.2020 22:59:59) | |
Variant: blue | Jumper X-Mas Deer | €26 | €19 (valid 1.1.2020 02:00:000 - 31.1.2020 21:59:59) | €9 | |
Variant: red | Jumper X-Mas Deer | €26 | €22 | €9 | |
Variant: green | Jumper X-Mas Deer | €26 | €21 | €18 (valid 1.1.2020 03:00:000 - 31.1.2020 20:59:59) |
These results are expected for the following queries:
First query
- price lists: Baseline
- valid in: 1.11.2020 13:00:00
Product | Price for sale |
---|---|
T-Shirt I Rock | from €10 to €21 |
Jumper X-Mas Deer | €26 |
Second query
- price lists: B, Baseline, C (argument order controls price list priority)
- valid in: 1.11.2020 13:00:00
Product | Price for sale |
---|---|
T-Shirt I Rock | from €10 to €21 |
Jumper X-Mas Deer | €26 |
Third query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 2.1.2020 13:00:00
Product | Price for sale |
---|---|
T-Shirt I Rock | from €9 to €19 |
Jumper X-Mas Deer | from €18 to €22 |
Fourth query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 2.1.2020 13:00:00
- price range between: €8 and €11 (both inclusive)
Product | Price for sale |
---|---|
T-Shirt I Rock | from €9 to €19 |
Product sets extension
In this setup, the product sales price is calculated on the fly as the sum of the sales prices of all its components. This aggregated price is used for filtering products by price.
If the component does not have a sales price for the query passed, the product set sales price is calculated without that particular component.
Model example
Let's have the following products:
Product | Product set | Baseline price | Price list A | Price list B | Price list C |
---|---|---|---|---|---|
Frame | Drawer | €100 | €90 (valid 1.1.2020 00:00:000 - 31.1.2020 23:59:59) | €75 | |
Set of knobs | Drawer | €120 | €140 | €85 | |
Hinges | Drawer | €210 | €230 | €190 (valid 1.1.2020 01:00:000 - 31.1.2020 22:59:59) | |
Head/footboard slat | Bed | €260 | €190 (valid 1.1.2020 02:00:000 - 31.1.2020 21:59:59) | €90 | |
Torso | Bed | €260 | €220 | €90 | |
Drawers | Bed | €260 | €210 | €180 (valid 1.1.2020 03:00:000 - 31.1.2020 20:59:59) |
These results are expected for the following queries:
First query
- price lists: Baseline
- valid in: 1.11.2020 13:00:00
Product | Price for sale |
---|---|
Drawer | €430 (€100 + €120 + €210) |
Bed | €780 (€260 + €260 + €260) |
Product sets have a selling price that is the sum of the selling prices of their parts.
Second query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 1.11.2020 13:00:00
Product | Price for sale |
---|---|
Drawer | €470 (€100 + €140 + €230) |
Bed | €690 (€260 + €220 + €210) |
Third query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 2.1.2020 13:00:00
Product | Price for sale |
---|---|
Drawer | €420 (€90 + €140 + €190) |
Bed | €590 (€190 + €220 + €180) |
Fourth query
- price lists: B, A, Baseline, C (argument order controls price list priority)
- valid in: 2.1.2020 13:00:00
- price between: €0 and €500
Product | Price for sale |
---|---|
Drawer | €420 (€90 + €140 + €190) |