feat(modules-sdk): remote query context filter (#7153)

What:

- Remote query now handles `context` keywork in the arguments to forward it as a filter to the method `list`
- Pricing module `list` method returning `calculated_price` if requested as a field
This commit is contained in:
Carlos R. L. Rodrigues
2024-04-26 10:20:42 +00:00
committed by GitHub
parent aef222278b
commit 4b57c5d286
10 changed files with 202 additions and 21 deletions
@@ -6,6 +6,7 @@ import {
CreatePricesDTO,
CreatePriceSetDTO,
DAL,
FindConfig,
InternalModuleDeclaration,
ModuleJoinerConfig,
ModulesSdkTypes,
@@ -152,6 +153,95 @@ export default class PricingModuleService<
return joinerConfig
}
private setupCalculatedPriceConfig_(
filters,
config
): PricingContext["context"] | undefined {
const fieldIdx = config.relations?.indexOf("calculated_price")
const shouldCalculatePrice = fieldIdx > -1
if (!shouldCalculatePrice) {
return
}
let pricingContext = filters.context ?? {}
// cleanup virtual field "calculated_price"
config.relations?.splice(fieldIdx, 1)
delete filters.context
return pricingContext
}
@InjectManager("baseRepository_")
async list(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<PriceSetDTO[]> {
const pricingContext = this.setupCalculatedPriceConfig_(filters, config)
const priceSets = await super.list(filters, config, sharedContext)
if (pricingContext && priceSets.length) {
const priceSetIds: string[] = []
const priceSetMap = new Map()
for (const priceSet of priceSets) {
priceSetIds.push(priceSet.id)
priceSetMap.set(priceSet.id, priceSet)
}
const calculatedPrices = await this.calculatePrices(
{ id: priceSets.map((p) => p.id) },
{ context: pricingContext },
sharedContext
)
for (const calculatedPrice of calculatedPrices) {
const priceSet = priceSetMap.get(calculatedPrice.id)
priceSet.calculated_price = calculatedPrice
}
}
return priceSets
}
@InjectManager("baseRepository_")
async listAndCount(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[PriceSetDTO[], number]> {
const pricingContext = this.setupCalculatedPriceConfig_(filters, config)
const [priceSets, count] = await super.listAndCount(
filters,
config,
sharedContext
)
if (pricingContext && priceSets.length) {
const priceSetIds: string[] = []
const priceSetMap = new Map()
for (const priceSet of priceSets) {
priceSetIds.push(priceSet.id)
priceSetMap.set(priceSet.id, priceSet)
}
const calculatedPrices = await this.calculatePrices(
{ id: priceSets.map((p) => p.id) },
{ context: pricingContext },
sharedContext
)
for (const calculatedPrice of calculatedPrices) {
const priceSet = priceSetMap.get(calculatedPrice.id)
priceSet.calculated_price = calculatedPrice
}
}
return [priceSets, count]
}
@InjectManager("baseRepository_")
async calculatePrices(
pricingFilters: PricingFilters,
@@ -171,7 +261,9 @@ export default class PricingModuleService<
(priceSetId: string): PricingTypes.CalculatedPriceSet => {
// This is where we select prices, for now we just do a first match based on the database results
// which is prioritized by rules_count first for exact match and then deafult_priority of the rule_type
// inject custom price selection here
// TODO: inject custom price selection here
const prices = pricesSetPricesMap.get(priceSetId) || []
const priceListPrice = prices.find((p) => p.price_list_id)
@@ -749,7 +841,7 @@ export default class PricingModuleService<
return {
...rest,
title: "test", // TODO: accept title
title: "", // TODO: accept title
rules_count: numberOfRules,
price_rules: Array.from(rulesDataMap.values()),
}