docs: update override price selection strategy documentation (#5438)

* docs: update override price selection strategy documentation

* fix eslint errors
This commit is contained in:
Shahed Nasser authored and GitHub committed 2023-10-20 20:17:45 +03:00
1 parent 8bc902fb0f
commit 1a10822cae
540 files changed
+244366 -18865

No files matched your search

@@ -1,128 +0,0 @@
---
description: 'Learn how to override the price selection strategy. The price selection strategy is used to determine the best price based on a specific context.'
addHowToData: true
---
# How to 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](../price-selection-strategy.md) instead.
:::
## 1. Create Class
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa backend project with a class that extends the `AbstractPriceSelectionStrategy` class:
```ts title=src/strategies/price.ts
import {
AbstractPriceSelectionStrategy,
IPriceSelectionStrategy,
PriceSelectionContext,
PriceSelectionResult,
} from "@medusajs/medusa"
import { EntityManager } from "typeorm"
export default class MyStrategy extends
AbstractPriceSelectionStrategy {
withTransaction(
manager: EntityManager
): IPriceSelectionStrategy {
if (!manager) {
return this
}
return new MyStrategy()
}
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 `MyStrategy` constructor in `withTransaction`. For example:
```ts
import {
AbstractPriceSelectionStrategy,
CustomerService,
IPriceSelectionStrategy,
PriceSelectionContext,
PriceSelectionResult,
} from "@medusajs/medusa"
export default class MyStrategy extends
AbstractPriceSelectionStrategy {
private customerService: CustomerService
constructor({
customerService,
}) {
super()
this.customerService = customerService
}
withTransaction(
manager: EntityManager
): IPriceSelectionStrategy {
if (!manager) {
return this
}
return new MyStrategy({
customerService: this.customerService,
})
}
// ...
}
```
---
## 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](../price-selection-strategy.md#context-object) object as a second parameter.
This method must return an object having the following fields:
```ts noReport
{
originalPrice, // number | null
calculatedPrice, // number | null
prices // MoneyAmount[]
}
```
You can learn more about optional properties and the meaning behind every property [here](../price-selection-strategy.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 backend to test it out:
```bash npm2yarn
npx medusa develop
```
Then, try out your strategy using any of the [Products](https://docs.medusajs.com/api/store#products) or [Carts](https://docs.medusajs.com/api/store#carts) API Routes which include retrieving product variants and line items respectively. You should then see the prices in the response based on your implemented strategy.
@@ -0,0 +1,295 @@
---
description: 'Learn how to override the price selection strategy. The price selection strategy is used to determine the best price based on a specific context.'
addHowToData: true
---
import ParameterTypes from "@site/src/components/ParameterTypes"
# How to 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](../price-selection-strategy.md) instead.
:::
## 1. Create Class
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa backend project with a class that extends the `AbstractPriceSelectionStrategy` class:
```ts title=src/strategies/price.ts
import {
AbstractPriceSelectionStrategy,
PriceSelectionContext,
PriceSelectionResult,
} from "@medusajs/medusa"
import {
TaxServiceRate,
} from "@medusajs/medusa/dist/types/tax-service"
export default class MyStrategy extends
AbstractPriceSelectionStrategy {
async calculateVariantPrice(
data: {
variantId: string;
taxRates: TaxServiceRate[];
quantity?: number
}[],
context: PriceSelectionContext
): Promise<Map<string, PriceSelectionResult>> {
throw new Error("Method not implemented.")
}
}
```
### Resolve Resources
You can resolve resources like services or repositories using [dependency injection](../../../development/fundamentals/dependency-injection.md).
For example:
```ts title=src/strategies/price.ts
import {
AbstractPriceSelectionStrategy,
CustomerService,
PriceSelectionContext,
PriceSelectionResult,
} from "@medusajs/medusa"
import {
TaxServiceRate,
} from "@medusajs/medusa/dist/types/tax-service"
type InjectedDependencies = {
customerService: CustomerService
}
export default class MyStrategy extends
AbstractPriceSelectionStrategy {
protected customerService_: CustomerService
constructor(container: InjectedDependencies) {
super(container)
this.customerService_ = container.customerService
}
// ...
}
```
---
## 2. Implement calculateVariantPrice
In this method, you can implement your price selection strategy.
### Parameters
You can learn more about optional properties and the meaning behind every property [here](../price-selection-strategy.md#calculatevariantprice-method).
<ParameterTypes parameters={[
{
name: "data",
type: "object[]",
description: "Holds the data necessary to perform the price selection for each variant ID.",
optional: false,
children: [
{
name: "variantId",
type: "string",
description: "The ID of the variant to retrieve the prices for.",
optional: false,
},
{
name: "taxRates",
type: "object[]",
description: "The tax rates to be applied. This is only used for [Tax-Inclusive Pricing](../../taxes/inclusive-pricing.md).",
optional: false,
children: [
{
name: "rate",
type: "number | null",
description: "The tax rate",
optional: true
},
{
name: "name",
type: "string",
description: "The name of the tax rate",
optional: false
},
{
name: "code",
type: "string | null",
description: "The code of the tax rate",
optional: false
}
],
},
{
name: "quantity",
type: "number",
description: "The quantity of the variant",
optional: true
}
],
},
{
name: "context",
type: "[PriceSelectionContext](../price-selection-strategy.md#context-object)",
description: "The context of the price selection",
optional: false,
children: [
{
name: "cart_id",
type: "string",
description: "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.",
optional: true
},
{
name: "customer_id",
type: "string",
description: "The ID of the customer. This is used to filter out price lists for a customer group that this customer doesn’t belong to.",
optional: true
},
{
name: "region_id",
type: "string",
description: "The ID of the region the customer is using.",
optional: true
},
{
name: "quantity",
type: "number",
description: "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.",
optional: true
},
{
name: "currency_code",
type: "string",
description: "The currency code the customer is using.",
optional: true
},
{
name: "include_discount_prices",
type: "boolean",
description: "Whether the price list's prices should be retrieved or not.",
optional: true
},
{
name: "taxRates",
type: "object[]",
description: "The tax rates to be applied. This is only used for [Tax-Inclusive Pricing](../../taxes/inclusive-pricing.md).",
optional: false,
children: [
{
name: "rate",
type: "number | null",
description: "The tax rate",
optional: true
},
{
name: "name",
type: "string",
description: "The name of the tax rate",
optional: false
},
{
name: "code",
type: "string | null",
description: "The code of the tax rate",
optional: false
}
],
},
{
name: "ignore_cache",
type: "boolean",
description: "Whether to calculate the prices even if the value of an earlier price calculation is available in the cache.",
optional: true
},
]
}
]} />
### Returns
<ParameterTypes parameters={[
{
name: "Promise",
type: "Promise<Map<string, PriceSelectionResult>>",
description: "A map, each key is an ID of a variant, and its value is an object holding the price selection result.",
optional: false,
children: [
{
name: "PriceSelectionResult",
type: "PriceSelectionResult",
description: "The price selection result of a variant.",
optional: false,
children: [
{
name: "originalPrice",
type: "number | null",
description: "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.",
optional: false
},
{
name: "originalPriceIncludesTax",
type: "boolean | null",
description: "Whether the original price includes taxes or not. This is only available for [Tax-Inclusive Pricing](../../taxes/inclusive-pricing.md).",
optional: true
},
{
name: "calculatedPrice",
type: "number | null",
description: "The lowest price among the prices of the product variant retrieved using the context object.",
optional: false
},
{
name: "calculatedPriceIncludesTax",
type: "boolean | null",
description: "Whether the calculated price includes taxes or not. This is only available for [Tax-Inclusive Pricing](../../taxes/inclusive-pricing.md).",
optional: true
},
{
name: "calculatedPriceType",
type: "enum",
description: "Either `default` if the `calculatedPrice` is the original price, or the type of the price list applied, which can be `override` or `sale`.",
optional: true
},
{
name: "prices",
type: "[MoneyAmount](../../../references/entities/classes/MoneyAmount.mdx)[]",
description: "The prices of the variant retrieved using the `context` object. It can include its original price and its price lists if there are any.",
optional: false
}
],
}
],
},
]} />
---
## 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 backend to test it out:
```bash npm2yarn
npx medusa develop
```
Then, try out your strategy using any of the [Products](https://docs.medusajs.com/api/store#products) or [Carts](https://docs.medusajs.com/api/store#carts) API Routes which include retrieving product variants and line items respectively. You should then see the prices in the response based on your implemented strategy.
@@ -20,7 +20,7 @@ Price lists can be used for a variety of use cases including:
### Price List Entity Overview
A price list is stored in the database as a [PriceList](../../references/entities/classes/PriceList.md) entity. Some of its important attributes are:
A price list is stored in the database as a [PriceList](../../references/entities/classes/PriceList.mdx) entity. Some of its important attributes are:
- `type`: The price list's type. Can be either a `sale` or an `override`.
- `status`: The status of the price list. Can be `active` or `draft`. If a price list is a `draft`, its prices won't be applied even if its conditions are met.
@@ -8,7 +8,7 @@ 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](./backend/override-price-selection-strategy.md) instead.
If you’re interested to learn how to override the price selection strategy, check out [this documentation](./backend/override-price-selection-strategy.mdx) instead.
:::
@@ -69,4 +69,4 @@ The context that is passed to the `calculateVariantPrice` method is an object th
## See Also
- [Override the Price Selection Strategy](./backend/override-price-selection-strategy.md)
- [Override the Price Selection Strategy](./backend/override-price-selection-strategy.mdx)