docs: conceptual and how-to docs for price lists and price selection strategy (#2259)
* docs: price lists and price selection strategy * added missing type property * Removed duplicate links
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# Price Selection Strategy
|
||||
|
||||
In this document, you’ll learn what a price selection strategy is.
|
||||
|
||||
:::note
|
||||
|
||||
If you’re interested to learn how to override the price selection strategy, check out [this documentation](./override.md) instead.
|
||||
|
||||
:::
|
||||
|
||||
## What's a Price Selection Strategy
|
||||
|
||||
Medusa provides many features and different ways to control the price of a product variant. This includes price lists and their different conditions, products’ original prices, and taxes.
|
||||
|
||||
Medusa uses the `PriceSelectionStrategy` class to retrieve the best price for a product variant for a specific context. This strategy is used whenever products and line items are retrieved or manipulated on the storefront.
|
||||
|
||||
---
|
||||
|
||||
## PriceSelectionStrategy Overview
|
||||
|
||||
The `PriceSelectionStrategy` class extends the `AbstractPriceSelectionStrategy` class. Its main method is the `calculateVariantPrice` which is used to retrieve a product variant’s price in a given context.
|
||||
|
||||
### calculateVariantPrice Method
|
||||
|
||||
Medusa uses this method to retrieve a product variant’s price when a product variant or line item is retrieved or manipulated. This includes when other entities that product variants and line items belong to are retrieved, such as products and carts respectively.
|
||||
|
||||
This method accepts two parameters:
|
||||
|
||||
1. The ID of the variant.
|
||||
2. A [context](#context-object) object.
|
||||
|
||||
The method retrieves all the available prices of the variant based on the conditions in the context object.
|
||||
|
||||
It returns an object with the following properties:
|
||||
|
||||
1. `originalPrice`: The original price of the variant which depends on the selected region or currency code in the context object. If both region ID and currency code are available in the context object, the region has higher precedence.
|
||||
2. `originalPriceIncludesTax`: A boolean value indicating whether the original price includes taxes or not. This is only available for [Tax-Inclusive Pricing](../taxes/inclusive-pricing.md).
|
||||
3. `calculatedPrice`: The lowest price among the prices of the product variant retrieved using the context object.
|
||||
4. `calculatedPriceIncludesTax`: A boolean value indicating whether the calculated price includes taxes or not. This is only available for [Tax-Inclusive Pricing](../taxes/inclusive-pricing.md).
|
||||
5. `calculatedPriceType`: Either `default` if the `calculatedPrice` is the original price, or the type of the price list applied.
|
||||
6. `prices`: an array of all the prices of the variant retrieved using the context object. It can include its original price and its price lists if there are any.
|
||||
|
||||
:::info
|
||||
|
||||
You can learn more about price lists and how they’re used in [this documentation](../price-lists/index.md).
|
||||
|
||||
:::
|
||||
|
||||
### Context Object
|
||||
|
||||
The context that is passed to the `calculateVariantPrice` method is an object that has the following optional properties:
|
||||
|
||||
- `cart_id`: The ID of the customer’s cart. This is used when the prices are being retrieved for the variant of a line item, as it is used to determine the current region and currency code of the context.
|
||||
- `customer_id`: The ID of the customer. This is used to filter out price lists for a customer group that this customer doesn’t belong to.
|
||||
- `quantity`: The quantity of the item in the cart. This is used to filter out price lists that have `min_quantity` or `max_quantity` conditions set.
|
||||
- `region_id`: The ID of the region the customer is using.
|
||||
- `currency_code`: The currency code the customer is using.
|
||||
- `include_discount_prices`: A boolean value indicating whether price list prices should be retrieved or not.
|
||||
- `tax_rates`: The tax rates to be applied. This is only used for [Tax-Inclusive Pricing](../taxes/inclusive-pricing.md).
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
|
||||
- Learn [how to override the price selection strategy](./override.md).
|
||||
- Learn more about [price lists](./../price-lists/index.md).
|
||||
@@ -0,0 +1,111 @@
|
||||
# Override Price Selection Strategy
|
||||
|
||||
In this document, you’ll learn how to override Medusa’s price selection strategy to create a custom pricing strategy.
|
||||
|
||||
:::note
|
||||
|
||||
If you’re interested in learning what a price selection strategy is and how it works, check out [this documentation](./index.md) instead.
|
||||
|
||||
:::
|
||||
|
||||
## 1. Create Class
|
||||
|
||||
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa server project with a class that extends the `AbstractPriceSelectionStrategy` class:
|
||||
|
||||
```typescript
|
||||
import { AbstractPriceSelectionStrategy, IPriceSelectionStrategy, PriceSelectionContext, PriceSelectionResult } from "@medusajs/medusa";
|
||||
|
||||
import { EntityManager } from "typeorm";
|
||||
|
||||
export default class MyPriceListStrategy extends AbstractPriceSelectionStrategy {
|
||||
|
||||
withTransaction(manager: EntityManager): IPriceSelectionStrategy {
|
||||
if (!manager) {
|
||||
return this
|
||||
}
|
||||
|
||||
return new MyPriceListStrategy()
|
||||
}
|
||||
|
||||
async calculateVariantPrice(
|
||||
variant_id: string,
|
||||
context: PriceSelectionContext
|
||||
): Promise<PriceSelectionResult> {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can use services or repositories in the strategy by adding them to the constructor and updating the parameters passed to the `MyPriceListStrategy` constructor in `withTransaction`. For example:
|
||||
|
||||
```typescript
|
||||
export default class MyPriceListStrategy extends AbstractPriceSelectionStrategy {
|
||||
private productsService: ProductService
|
||||
|
||||
constructor({
|
||||
productsService
|
||||
}) {
|
||||
super()
|
||||
this.productsService = productsService
|
||||
}
|
||||
|
||||
withTransaction(manager: EntityManager): IPriceSelectionStrategy {
|
||||
if (!manager) {
|
||||
return this
|
||||
}
|
||||
|
||||
return new MyPriceListStrategy({
|
||||
productsService: this.productsService
|
||||
})
|
||||
}
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Implement calculateVariantPrice
|
||||
|
||||
Implement the price selection strategy you want inside the `calculateVariantPrice` method.
|
||||
|
||||
This method accepts the variant ID as a first parameter and the [context](./index.md#context-object) object as a second parameter.
|
||||
|
||||
This method must return an object having the following fields:
|
||||
|
||||
```typescript
|
||||
{
|
||||
originalPrice, //number | null
|
||||
calculatedPrice, //number | null
|
||||
prices // MoneyAmount[]
|
||||
}
|
||||
```
|
||||
|
||||
You can learn more about optional properties and the meaning behind every property [here](./index.md#calculatevariantprice-method).
|
||||
|
||||
---
|
||||
|
||||
## 3. Run Build Command
|
||||
|
||||
In your terminal, run the build command to transpile the files in the `src` directory into the `dist` directory:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test it Out
|
||||
|
||||
Run your server to test it out:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run start
|
||||
```
|
||||
|
||||
Then, try out your strategy using any of the [Products](https://docs.medusajs.com/api/store/#tag/Product) or [Carts](https://docs.medusajs.com/api/store/#tag/Cart) endpoints which include retrieving product variants and line items respectively. You should then see the prices in the response based on your implemented strategy.
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
|
||||
- Learn more about [price list selection strategy](./index.md).
|
||||
Reference in New Issue
Block a user