fix(): Pricing preference context loss (#13626)
**What** The context reference is being mutated by the repository leading to an empty context. Also, the filter is built from the pricing context instead of pricing context -> context leading to always fetch all preferences all the time
This commit is contained in:
1 parent
087887fefb
commit
9c7c1d48c7
7 files changed
+111
-65
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { BaseFilterable } from "../../dal"
|
||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||
|
||||
/**
|
||||
* @interface
|
||||
@@ -83,13 +83,13 @@ export interface FilterablePricePreferenceProps
|
||||
/**
|
||||
* The IDs to filter the price preferences by.
|
||||
*/
|
||||
id?: string[]
|
||||
id?: string | string[] | OperatorMap<string | string[]>
|
||||
/**
|
||||
* Attributes to filter price preferences by.
|
||||
*/
|
||||
attribute?: string | string[]
|
||||
attribute?: string | string[] | OperatorMap<string | string[]>
|
||||
/**
|
||||
* Values to filter price preferences by.
|
||||
*/
|
||||
value?: string | string[]
|
||||
value?: string | string[] | OperatorMap<string | string[]>
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BaseFilterable } from "../../dal"
|
||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||
import { PriceSetDTO } from "./price-set"
|
||||
|
||||
/**
|
||||
@@ -123,15 +123,20 @@ export interface FilterablePriceRuleProps
|
||||
/**
|
||||
* The IDs to filter price rules by.
|
||||
*/
|
||||
id?: string[]
|
||||
id?: string | string[] | OperatorMap<string | string[]>
|
||||
/**
|
||||
* The names to filter price rules by.
|
||||
*/
|
||||
name?: string[]
|
||||
name?: string | string[] | OperatorMap<string | string[]>
|
||||
/**
|
||||
* The IDs to filter the price rule's associated price set.
|
||||
*/
|
||||
price_set_id?: string[]
|
||||
price_set_id?: string | string[] | OperatorMap<string | string[]>
|
||||
|
||||
/**
|
||||
* The IDs to filter the price rule's associated price.
|
||||
*/
|
||||
price_id?: string | string[] | OperatorMap<string | string[]>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,21 +150,21 @@ export type PricingRuleOperatorValues = "gt" | "lt" | "eq" | "lte" | "gte"
|
||||
export interface PriceRule {
|
||||
/**
|
||||
* The attribute to compare.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* amount
|
||||
*/
|
||||
attribute: string
|
||||
/**
|
||||
* The operator to use in the comparison.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* gt
|
||||
*/
|
||||
operator: PricingRuleOperatorValues
|
||||
/**
|
||||
* The value to compare against.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* 100
|
||||
*/
|
||||
|
||||
@@ -69,7 +69,7 @@ export class PricingRepository
|
||||
): Promise<CalculatedPriceSetDTO[]> {
|
||||
const manager = this.getActiveManager<SqlEntityManager>(sharedContext)
|
||||
const knex = manager.getKnex()
|
||||
const context = pricingContext.context || {}
|
||||
const context = { ...(pricingContext.context || {}) }
|
||||
|
||||
// Extract quantity and currency from context
|
||||
const quantity = context.quantity
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
FindConfig,
|
||||
InferEntityType,
|
||||
InternalModuleDeclaration,
|
||||
MedusaContainer,
|
||||
ModuleJoinerConfig,
|
||||
ModulesSdkTypes,
|
||||
PricePreferenceDTO,
|
||||
@@ -95,6 +96,7 @@ export default class PricingModuleService
|
||||
extends BaseClass
|
||||
implements PricingTypes.IPricingModuleService
|
||||
{
|
||||
protected readonly container_: MedusaContainer
|
||||
protected baseRepository_: DAL.RepositoryService
|
||||
protected readonly pricingRepository_: PricingRepositoryService & {
|
||||
clearAvailableAttributes?: () => Promise<void>
|
||||
@@ -134,6 +136,7 @@ export default class PricingModuleService
|
||||
// @ts-ignore
|
||||
super(...arguments)
|
||||
|
||||
this.container_ = arguments[0]
|
||||
this.baseRepository_ = baseRepository
|
||||
this.pricingRepository_ = pricingRepository
|
||||
this.priceSetService_ = priceSetService
|
||||
@@ -327,6 +330,62 @@ export default class PricingModuleService
|
||||
return [serializedPriceSets, count]
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
// @ts-expect-error
|
||||
async listPriceRules(
|
||||
filters: PricingTypes.FilterablePriceRuleProps,
|
||||
config: FindConfig<PricingTypes.PriceRuleDTO> = {},
|
||||
sharedContext?: Context
|
||||
): Promise<PricingTypes.PriceRuleDTO[]> {
|
||||
const priceRules = await this.listPriceRules_(
|
||||
filters,
|
||||
config,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<PricingTypes.PriceRuleDTO[]>(
|
||||
priceRules
|
||||
)
|
||||
}
|
||||
|
||||
protected async listPriceRules_(
|
||||
filters: PricingTypes.FilterablePriceRuleProps,
|
||||
config: FindConfig<PricingTypes.PriceRuleDTO> = {},
|
||||
sharedContext?: Context
|
||||
): Promise<InferEntityType<typeof PriceRule>[]> {
|
||||
return await this.priceRuleService_.list(filters, config, sharedContext)
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
// @ts-expect-error
|
||||
async listPricePreferences(
|
||||
filters: PricingTypes.FilterablePricePreferenceProps,
|
||||
config: FindConfig<PricingTypes.PricePreferenceDTO> = {},
|
||||
sharedContext?: Context
|
||||
): Promise<PricingTypes.PricePreferenceDTO[]> {
|
||||
const pricePreferences = await this.listPricePreferences_(
|
||||
filters,
|
||||
{ ...config, select: [...(config.select || []), "id"] },
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<
|
||||
PricingTypes.PricePreferenceDTO[]
|
||||
>(pricePreferences)
|
||||
}
|
||||
|
||||
protected async listPricePreferences_(
|
||||
filters: PricingTypes.FilterablePricePreferenceProps,
|
||||
config: FindConfig<PricingTypes.PricePreferenceDTO> = {},
|
||||
sharedContext?: Context
|
||||
): Promise<InferEntityType<typeof PricePreference>[]> {
|
||||
return await this.pricePreferenceService_.list(
|
||||
filters,
|
||||
config,
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async calculatePrices(
|
||||
pricingFilters: PricingFilters,
|
||||
@@ -395,29 +454,37 @@ export default class PricingModuleService
|
||||
)
|
||||
|
||||
// We use the price rules to get the right preferences for the price
|
||||
const priceRulesForPrices = await this.priceRuleService_.list(
|
||||
const priceRulesForPrices = await this.listPriceRules(
|
||||
{ price_id: priceIds },
|
||||
{}
|
||||
{},
|
||||
sharedContext
|
||||
)
|
||||
|
||||
const priceRulesPriceMap = groupBy(priceRulesForPrices, "price_id")
|
||||
|
||||
// Note: For now the preferences are intentionally kept very simple and explicit - they use either the region or currency,
|
||||
// so we hard-code those as the possible filters here. This can be made more flexible if needed later on.
|
||||
const pricingPreferences = await this.pricePreferenceService_.list(
|
||||
{
|
||||
$or: Object.entries(pricingContext)
|
||||
.filter(([key, val]) => {
|
||||
return key === "region_id" || key === "currency_code"
|
||||
})
|
||||
.map(([key, val]) => ({
|
||||
attribute: key,
|
||||
value: val,
|
||||
})),
|
||||
},
|
||||
{},
|
||||
sharedContext
|
||||
)
|
||||
const preferenceContext = Object.entries(
|
||||
pricingContext.context ?? {}
|
||||
).filter(([key, val]) => {
|
||||
return key === "region_id" || key === "currency_code"
|
||||
})
|
||||
let pricingPreferences: InferEntityType<typeof PricePreference>[] = []
|
||||
if (preferenceContext.length) {
|
||||
const preferenceFilters = preferenceContext.length
|
||||
? {
|
||||
$or: preferenceContext.map(([key, val]) => ({
|
||||
attribute: key,
|
||||
value: val,
|
||||
})),
|
||||
}
|
||||
: {}
|
||||
pricingPreferences = await this.listPricePreferences_(
|
||||
preferenceFilters as PricingTypes.FilterablePricePreferenceProps,
|
||||
{},
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
const calculatedPrices: PricingTypes.CalculatedPriceSet[] = []
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"@medusajs/icons": "2.10.3",
|
||||
"@medusajs/test-utils": "2.10.3",
|
||||
"@medusajs/types": "2.10.3",
|
||||
"@medusajs/ui": "4.0.21",
|
||||
"@medusajs/ui": "4.0.23",
|
||||
"@medusajs/ui-preset": "2.10.3",
|
||||
"@swc/core": "1.5.7",
|
||||
"@types/lodash": "^4.17.15",
|
||||
@@ -74,7 +74,7 @@
|
||||
"@medusajs/framework": "2.10.3",
|
||||
"@medusajs/icons": "2.10.3",
|
||||
"@medusajs/test-utils": "2.10.3",
|
||||
"@medusajs/ui": "4.0.21",
|
||||
"@medusajs/ui": "4.0.23",
|
||||
"lodash": "^4.17.21",
|
||||
"react-router-dom": "6.20.1"
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user