feat(pricing, types): PriceSets as entry point to pricing module (#4978)

What:
- Adds PriceSet, PriceSetMoneyAmount, updates schema
- Adds service/repo for PriceSet
- Shifts entry point to use PriceSet
- Updates link/joiner config

RESOLVES CORE-1495
This commit is contained in:
Riqwan Thamir
2023-09-11 19:24:31 +02:00
committed by GitHub
parent adf4903003
commit 834da5c41a
29 changed files with 1853 additions and 113 deletions

View File

@@ -1,16 +1,22 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import { Currency, MoneyAmount } from "@models"
import * as Models from "@models"
export enum LinkableKeys {
MONEY_AMOUNT_ID = "money_amount_id",
CURRENCY_CODE = "currency_code",
PRICE_SET_ID = "price_set_id",
}
export const entityNameToLinkableKeysMap: MapToConfig = {
[Currency.name]: [{ mapTo: LinkableKeys.CURRENCY_CODE, valueFrom: "code" }],
[MoneyAmount.name]: [
[Models.PriceSet.name]: [
{ mapTo: LinkableKeys.PRICE_SET_ID, valueFrom: "id" },
],
[Models.Currency.name]: [
{ mapTo: LinkableKeys.CURRENCY_CODE, valueFrom: "code" },
],
[Models.MoneyAmount.name]: [
{ mapTo: LinkableKeys.MONEY_AMOUNT_ID, valueFrom: "id" },
],
}
@@ -20,11 +26,23 @@ export const joinerConfig: ModuleJoinerConfig = {
primaryKeys: ["id", "currency_code"],
linkableKeys: Object.values(LinkableKeys),
alias: [
{
name: "price_set",
},
{
name: "price_sets",
},
{
name: "money_amount",
args: {
methodSuffix: "MoneyAmounts",
},
},
{
name: "money_amounts",
args: {
methodSuffix: "MoneyAmounts",
},
},
{
name: "currency",

View File

@@ -1,11 +1,6 @@
import { ModulesSdkTypes } from "@medusajs/types"
import * as defaultRepositories from "@repositories"
import {
BaseRepository,
CurrencyRepository,
MoneyAmountRepository,
} from "@repositories"
import { CurrencyService, MoneyAmountService } from "@services"
import * as defaultServices from "@services"
import { LoaderOptions } from "@medusajs/modules-sdk"
import { loadCustomRepositories } from "@medusajs/utils"
@@ -23,8 +18,9 @@ export default async ({
)?.repositories
container.register({
currencyService: asClass(CurrencyService).singleton(),
moneyAmountService: asClass(MoneyAmountService).singleton(),
currencyService: asClass(defaultServices.CurrencyService).singleton(),
moneyAmountService: asClass(defaultServices.MoneyAmountService).singleton(),
priceSetService: asClass(defaultServices.PriceSetService).singleton(),
})
if (customRepositories) {
@@ -40,8 +36,15 @@ export default async ({
function loadDefaultRepositories({ container }) {
container.register({
baseRepository: asClass(BaseRepository).singleton(),
currencyRepository: asClass(CurrencyRepository).singleton(),
moneyAmountRepository: asClass(MoneyAmountRepository).singleton(),
baseRepository: asClass(defaultRepositories.BaseRepository).singleton(),
currencyRepository: asClass(
defaultRepositories.CurrencyRepository
).singleton(),
moneyAmountRepository: asClass(
defaultRepositories.MoneyAmountRepository
).singleton(),
priceSetRepository: asClass(
defaultRepositories.PriceSetRepository
).singleton(),
})
}

View File

@@ -0,0 +1,260 @@
{
"namespaces": [
"public"
],
"name": "public",
"tables": [
{
"columns": {
"code": {
"name": "code",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"symbol": {
"name": "symbol",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"symbol_native": {
"name": "symbol_native",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"name": {
"name": "name",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
}
},
"name": "currency",
"schema": "public",
"indexes": [
{
"keyName": "currency_pkey",
"columnNames": [
"code"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"currency_code": {
"name": "currency_code",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"amount": {
"name": "amount",
"type": "numeric",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "decimal"
},
"min_quantity": {
"name": "min_quantity",
"type": "numeric",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "decimal"
},
"max_quantity": {
"name": "max_quantity",
"type": "numeric",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "decimal"
}
},
"name": "money_amount",
"schema": "public",
"indexes": [
{
"columnNames": [
"currency_code"
],
"composite": false,
"keyName": "IDX_money_amount_currency_code",
"primary": false,
"unique": false
},
{
"keyName": "money_amount_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"money_amount_currency_code_foreign": {
"constraintName": "money_amount_currency_code_foreign",
"columnNames": [
"currency_code"
],
"localTableName": "public.money_amount",
"referencedColumnNames": [
"code"
],
"referencedTableName": "public.currency",
"deleteRule": "set null",
"updateRule": "cascade"
}
}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
}
},
"name": "price_set",
"schema": "public",
"indexes": [
{
"keyName": "price_set_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"price_set_id": {
"name": "price_set_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"money_amount_id": {
"name": "money_amount_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"title": {
"name": "title",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
}
},
"name": "price_set_money_amount",
"schema": "public",
"indexes": [
{
"keyName": "price_set_money_amount_pkey",
"columnNames": [
"id",
"price_set_id",
"money_amount_id"
],
"composite": true,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"price_set_money_amount_price_set_id_foreign": {
"constraintName": "price_set_money_amount_price_set_id_foreign",
"columnNames": [
"price_set_id"
],
"localTableName": "public.price_set_money_amount",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.price_set",
"updateRule": "cascade"
},
"price_set_money_amount_money_amount_id_foreign": {
"constraintName": "price_set_money_amount_money_amount_id_foreign",
"columnNames": [
"money_amount_id"
],
"localTableName": "public.price_set_money_amount",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.money_amount",
"updateRule": "cascade"
}
}
}
]
}

View File

@@ -1,14 +0,0 @@
import { Migration } from '@mikro-orm/migrations';
export class Migration20230830085850 extends Migration {
async up(): Promise<void> {
this.addSql('create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));');
this.addSql('create table "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));');
this.addSql('create index "IDX_money_amount_currency_code" on "money_amount" ("currency_code");');
this.addSql('alter table "money_amount" add constraint "money_amount_currency_code_foreign" foreign key ("currency_code") references "currency" ("code") on update cascade on delete set null;');
}
}

View File

@@ -0,0 +1,36 @@
import { Migration } from "@mikro-orm/migrations"
export class Migration20230907144224 extends Migration {
async up(): Promise<void> {
this.addSql(
'create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));'
)
this.addSql(
'create table "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));'
)
this.addSql(
'create index "IDX_money_amount_currency_code" on "money_amount" ("currency_code");'
)
this.addSql(
'create table "price_set" ("id" text not null, constraint "price_set_pkey" primary key ("id"));'
)
this.addSql(
'create table "price_set_money_amount" ("id" text not null, "price_set_id" text null, "money_amount_id" text null, "title" text not null, constraint "price_set_money_amount_pkey" primary key ("id", "price_set_id", "money_amount_id"));'
)
this.addSql(
'alter table "money_amount" add constraint "money_amount_currency_code_foreign" foreign key ("currency_code") references "currency" ("code") on update cascade on delete set null;'
)
this.addSql(
'alter table "price_set_money_amount" add constraint "price_set_money_amount_price_set_id_foreign" foreign key ("price_set_id") references "price_set" ("id") on update cascade;'
)
this.addSql(
'alter table "price_set_money_amount" add constraint "price_set_money_amount_money_amount_id_foreign" foreign key ("money_amount_id") references "money_amount" ("id") on update cascade;'
)
}
}

View File

@@ -1,2 +1,4 @@
export { default as Currency } from "./currency"
export { default as MoneyAmount } from "./money-amount"
export { default as PriceSet } from "./price-set"
export { default as PriceSetMoneyAmount } from "./price-set-money-amount"

View File

@@ -1,13 +1,16 @@
import { generateEntityId } from "@medusajs/utils"
import {
BeforeCreate,
Collection,
Entity,
ManyToMany,
ManyToOne,
PrimaryKey,
Property,
} from "@mikro-orm/core"
import Currency from "./currency"
import PriceSet from "./price-set"
@Entity()
class MoneyAmount {
@@ -17,6 +20,12 @@ class MoneyAmount {
@Property({ columnType: "text", nullable: true })
currency_code?: string
@ManyToMany({
entity: () => PriceSet,
mappedBy: (ps) => ps.money_amounts,
})
price_sets = new Collection<PriceSet>(this)
@ManyToOne(() => Currency, {
nullable: true,
index: "IDX_money_amount_currency_code",

View File

@@ -0,0 +1,39 @@
import { generateEntityId } from "@medusajs/utils"
import {
BeforeCreate,
Entity,
ManyToOne,
PrimaryKey,
PrimaryKeyType,
Property,
} from "@mikro-orm/core"
import MoneyAmount from "./money-amount"
import PriceSet from "./price-set"
@Entity()
export default class PriceSetMoneyAmount {
@PrimaryKey({ columnType: "text" })
id!: string
@Property({ columnType: "text" })
title!: string
@ManyToOne(() => PriceSet, { onDelete: "cascade" })
price_set?: PriceSet
@ManyToOne(() => MoneyAmount, {})
money_amount?: MoneyAmount
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "psma")
}
[PrimaryKeyType]?: [string, string]
constructor(money_amount: MoneyAmount, price_set: PriceSet) {
this.money_amount = money_amount
this.price_set = price_set
}
}

View File

@@ -0,0 +1,28 @@
import { generateEntityId } from "@medusajs/utils"
import {
BeforeCreate,
Collection,
Entity,
ManyToMany,
PrimaryKey,
} from "@mikro-orm/core"
import MoneyAmount from "./money-amount"
import PriceSetMoneyAmount from "./price-set-money-amount"
@Entity()
export default class PriceSet {
@PrimaryKey({ columnType: "text" })
id!: string
@ManyToMany({
entity: () => MoneyAmount,
pivotEntity: () => PriceSetMoneyAmount,
})
money_amounts = new Collection<MoneyAmount>(this)
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "pset")
}
}

View File

@@ -1,3 +1,4 @@
export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils"
export { CurrencyRepository } from "./currency"
export { MoneyAmountRepository } from "./money-amount"
export { PriceSetRepository } from "./price-set"

View File

@@ -0,0 +1,127 @@
import {
Context,
CreatePriceSetDTO,
DAL,
UpdatePriceSetDTO,
} from "@medusajs/types"
import { DALUtils, MedusaError } from "@medusajs/utils"
import {
LoadStrategy,
FilterQuery as MikroFilterQuery,
FindOptions as MikroOptions,
} from "@mikro-orm/core"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSet } from "@models"
export class PriceSetRepository extends DALUtils.MikroOrmBaseRepository {
protected readonly manager_: SqlEntityManager
constructor({ manager }: { manager: SqlEntityManager }) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(...arguments)
this.manager_ = manager
}
async find(
findOptions: DAL.FindOptions<PriceSet> = { where: {} },
context: Context = {}
): Promise<PriceSet[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.find(
PriceSet,
findOptions_.where as MikroFilterQuery<PriceSet>,
findOptions_.options as MikroOptions<PriceSet>
)
}
async findAndCount(
findOptions: DAL.FindOptions<PriceSet> = { where: {} },
context: Context = {}
): Promise<[PriceSet[], number]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const findOptions_ = { ...findOptions }
findOptions_.options ??= {}
Object.assign(findOptions_.options, {
strategy: LoadStrategy.SELECT_IN,
})
return await manager.findAndCount(
PriceSet,
findOptions_.where as MikroFilterQuery<PriceSet>,
findOptions_.options as MikroOptions<PriceSet>
)
}
async delete(ids: string[], context: Context = {}): Promise<void> {
const manager = this.getActiveManager<SqlEntityManager>(context)
await manager.nativeDelete(PriceSet, { id: { $in: ids } }, {})
}
async create(
data: CreatePriceSetDTO[],
context: Context = {}
): Promise<PriceSet[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const priceSets = data.map((priceSetData) => {
return manager.create(PriceSet, priceSetData)
})
manager.persist(priceSets)
return priceSets
}
async update(
data: UpdatePriceSetDTO[],
context: Context = {}
): Promise<PriceSet[]> {
const manager = this.getActiveManager<SqlEntityManager>(context)
const priceSetIds = data.map((priceSetData) => priceSetData.id)
const existingPriceSets = await this.find(
{
where: {
id: {
$in: priceSetIds,
},
},
},
context
)
const existingPriceSetMap = new Map(
existingPriceSets.map<[string, PriceSet]>((priceSet) => [
priceSet.id,
priceSet,
])
)
const priceSets = data.map((priceSetData) => {
const existingPriceSet = existingPriceSetMap.get(priceSetData.id)
if (!existingPriceSet) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`PriceSet with id "${priceSetData.id}" not found`
)
}
return manager.assign(existingPriceSet, priceSetData)
})
manager.persist(priceSets)
return priceSets
}
}

View File

@@ -22,11 +22,14 @@ export async function run({
logger.info(`Loading seed data from ${path}...`)
const { currenciesData, moneyAmountsData } = await import(
resolve(process.cwd(), path)
).catch((e) => {
const {
currenciesData,
moneyAmountsData,
priceSetsData,
priceSetMoneyAmountsData,
} = await import(resolve(process.cwd(), path)).catch((e) => {
logger?.error(
`Failed to load seed data from ${path}. Please, provide a relative path and check that you export the following: currenciesData, moneyAmountsData.${EOL}${e}`
`Failed to load seed data from ${path}. Please, provide a relative path and check that you export the following: priceSetsData, currenciesData, moneyAmountsData and priceSetMoneyAmountsData.${EOL}${e}`
)
throw e
})
@@ -44,10 +47,12 @@ export async function run({
const manager = orm.em.fork()
try {
logger.info("Inserting currencies & money_amounts")
logger.info("Inserting price_sets, currencies & money_amounts")
await createCurrencies(manager, currenciesData)
await createMoneyAmounts(manager, moneyAmountsData)
await createPriceSets(manager, priceSetsData)
await createPriceSetMoneyAmounts(manager, priceSetMoneyAmountsData)
} catch (e) {
logger.error(
`Failed to insert the seed data in the PostgreSQL database ${dbData.clientUrl}.${EOL}${e}`
@@ -82,3 +87,32 @@ async function createMoneyAmounts(
return moneyAmounts
}
async function createPriceSets(
manager: SqlEntityManager,
data: RequiredEntityData<PricingModels.PriceSet>[]
) {
const priceSets = data.map((priceSetData) => {
return manager.create(PricingModels.PriceSet, priceSetData)
})
await manager.persistAndFlush(priceSets)
return priceSets
}
async function createPriceSetMoneyAmounts(
manager: SqlEntityManager,
data: RequiredEntityData<PricingModels.PriceSetMoneyAmount>[]
) {
const priceSetMoneyAmounts = data.map((priceSetMoneyAmountData) => {
return manager.create(
PricingModels.PriceSetMoneyAmount,
priceSetMoneyAmountData
)
})
await manager.persistAndFlush(priceSetMoneyAmounts)
return priceSetMoneyAmounts
}

View File

@@ -1,3 +1,4 @@
export { default as CurrencyService } from "./currency"
export { default as MoneyAmountService } from "./money-amount"
export { default as PriceSetService } from "./price-set"
export { default as PricingModuleService } from "./pricing-module"

View File

@@ -0,0 +1,106 @@
import { Context, DAL, FindConfig, PricingTypes } from "@medusajs/types"
import {
InjectManager,
InjectTransactionManager,
MedusaContext,
ModulesSdkUtils,
doNotForceTransaction,
retrieveEntity,
shouldForceTransaction,
} from "@medusajs/utils"
import { PriceSet } from "@models"
import { PriceSetRepository } from "@repositories"
type InjectedDependencies = {
priceSetRepository: DAL.RepositoryService
}
export default class PriceSetService<TEntity extends PriceSet = PriceSet> {
protected readonly priceSetRepository_: DAL.RepositoryService
constructor({ priceSetRepository }: InjectedDependencies) {
this.priceSetRepository_ = priceSetRepository
}
@InjectManager("priceSetRepository_")
async retrieve(
priceSetId: string,
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity> {
return (await retrieveEntity<PriceSet, PricingTypes.PriceSetDTO>({
id: priceSetId,
entityName: PriceSet.name,
repository: this.priceSetRepository_,
config,
sharedContext,
})) as TEntity
}
@InjectManager("priceSetRepository_")
async list(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> {
return (await this.priceSetRepository_.find(
this.buildQueryForList(filters, config),
sharedContext
)) as TEntity[]
}
@InjectManager("priceSetRepository_")
async listAndCount(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[TEntity[], number]> {
return (await this.priceSetRepository_.findAndCount(
this.buildQueryForList(filters, config),
sharedContext
)) as [TEntity[], number]
}
private buildQueryForList(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {}
) {
const queryOptions = ModulesSdkUtils.buildQuery<PriceSet>(filters, config)
if (filters.id) {
queryOptions.where.id = { $in: filters.id }
}
return queryOptions
}
@InjectTransactionManager(shouldForceTransaction, "priceSetRepository_")
async create(
data: PricingTypes.CreatePriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> {
return (await (this.priceSetRepository_ as PriceSetRepository).create(
data,
sharedContext
)) as TEntity[]
}
@InjectTransactionManager(shouldForceTransaction, "priceSetRepository_")
async update(
data: PricingTypes.UpdatePriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> {
return (await (this.priceSetRepository_ as PriceSetRepository).update(
data,
sharedContext
)) as TEntity[]
}
@InjectTransactionManager(doNotForceTransaction, "priceSetRepository_")
async delete(
ids: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
await this.priceSetRepository_.delete(ids, sharedContext)
}
}

View File

@@ -6,8 +6,8 @@ import {
ModuleJoinerConfig,
PricingTypes,
} from "@medusajs/types"
import { Currency, MoneyAmount } from "@models"
import { CurrencyService, MoneyAmountService } from "@services"
import { Currency, MoneyAmount, PriceSet } from "@models"
import { CurrencyService, MoneyAmountService, PriceSetService } from "@services"
import {
InjectManager,
@@ -22,9 +22,15 @@ type InjectedDependencies = {
baseRepository: DAL.RepositoryService
currencyService: CurrencyService<any>
moneyAmountService: MoneyAmountService<any>
priceSetService: PriceSetService<any>
}
type PricingContext = {
currency_code?: string
}
export default class PricingModuleService<
TPriceSet extends PriceSet = PriceSet,
TMoneyAmount extends MoneyAmount = MoneyAmount,
TCurrency extends Currency = Currency
> implements PricingTypes.IPricingModuleService
@@ -32,26 +38,180 @@ export default class PricingModuleService<
protected baseRepository_: DAL.RepositoryService
protected readonly currencyService_: CurrencyService<TCurrency>
protected readonly moneyAmountService_: MoneyAmountService<TMoneyAmount>
protected readonly priceSetService_: PriceSetService<TPriceSet>
constructor(
{
baseRepository,
moneyAmountService,
currencyService,
priceSetService,
}: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
this.baseRepository_ = baseRepository
this.currencyService_ = currencyService
this.moneyAmountService_ = moneyAmountService
this.priceSetService_ = priceSetService
}
__joinerConfig(): ModuleJoinerConfig {
return joinerConfig
}
@InjectManager("baseRepository_")
async calculatePrices(
priceSetIds: string[],
pricingContext: PricingContext,
@MedusaContext() sharedContext: Context = {}
): Promise<PricingTypes.CalculatedPriceSetDTO> {
// Keeping this whole logic raw in here for now as they will undergo
// some changes, will abstract them out once we have a final version
const priceSetFilters: PricingTypes.FilterablePriceSetProps = {
id: priceSetIds,
}
const priceSets = await this.list(
priceSetFilters,
{
select: [
"id",
"money_amounts.id",
"money_amounts.currency_code",
"money_amounts.amount",
"money_amounts.min_quantity",
"money_amounts.max_quantity",
],
relations: ["money_amounts"],
},
sharedContext
)
const calculatedPrices = priceSets.map(
(priceSet): PricingTypes.CalculatedPriceSetDTO => {
// TODO: This will change with the rules engine selection,
// making a DB query directly instead
// This should look for a default price when no rules apply
// When no price is set, return null values for all cases
const selectedMoneyAmount = priceSet.money_amounts?.find(
(ma) =>
pricingContext.currency_code &&
ma.currency_code === pricingContext.currency_code
)
return {
id: priceSet.id,
amount: selectedMoneyAmount?.amount || null,
currency_code: selectedMoneyAmount?.currency_code || null,
min_quantity: selectedMoneyAmount?.min_quantity || null,
max_quantity: selectedMoneyAmount?.max_quantity || null,
}
}
)
return JSON.parse(JSON.stringify(calculatedPrices))
}
@InjectManager("baseRepository_")
async retrieve(
id: string,
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<PricingTypes.PriceSetDTO> {
const priceSet = await this.priceSetService_.retrieve(
id,
config,
sharedContext
)
return this.baseRepository_.serialize<PricingTypes.PriceSetDTO>(priceSet, {
populate: true,
})
}
@InjectManager("baseRepository_")
async list(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<PricingTypes.PriceSetDTO[]> {
const priceSets = await this.priceSetService_.list(
filters,
config,
sharedContext
)
return this.baseRepository_.serialize<PricingTypes.PriceSetDTO[]>(
priceSets,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async listAndCount(
filters: PricingTypes.FilterablePriceSetProps = {},
config: FindConfig<PricingTypes.PriceSetDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[PricingTypes.PriceSetDTO[], number]> {
const [priceSets, count] = await this.priceSetService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<PricingTypes.PriceSetDTO[]>(
priceSets,
{
populate: true,
}
),
count,
]
}
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
async create(
data: PricingTypes.CreatePriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
) {
const priceSets = await this.priceSetService_.create(data, sharedContext)
return this.baseRepository_.serialize<PricingTypes.PriceSetDTO[]>(
priceSets,
{
populate: true,
}
)
}
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
async update(
data: PricingTypes.UpdatePriceSetDTO[],
@MedusaContext() sharedContext: Context = {}
) {
const priceSets = await this.priceSetService_.update(data, sharedContext)
return this.baseRepository_.serialize<PricingTypes.PriceSetDTO[]>(
priceSets,
{
populate: true,
}
)
}
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
async delete(
ids: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
await this.priceSetService_.delete(ids, sharedContext)
}
@InjectManager("baseRepository_")
async retrieveMoneyAmount(
id: string,
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
@MedusaContext() sharedContext: Context = {}
@@ -71,7 +231,7 @@ export default class PricingModuleService<
}
@InjectManager("baseRepository_")
async list(
async listMoneyAmounts(
filters: PricingTypes.FilterableMoneyAmountProps = {},
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
@MedusaContext() sharedContext: Context = {}
@@ -91,7 +251,7 @@ export default class PricingModuleService<
}
@InjectManager("baseRepository_")
async listAndCount(
async listAndCountMoneyAmounts(
filters: PricingTypes.FilterableMoneyAmountProps = {},
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
@MedusaContext() sharedContext: Context = {}
@@ -114,7 +274,7 @@ export default class PricingModuleService<
}
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
async create(
async createMoneyAmounts(
data: PricingTypes.CreateMoneyAmountDTO[],
@MedusaContext() sharedContext: Context = {}
) {
@@ -132,7 +292,7 @@ export default class PricingModuleService<
}
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
async update(
async updateMoneyAmounts(
data: PricingTypes.UpdateMoneyAmountDTO[],
@MedusaContext() sharedContext: Context = {}
) {
@@ -150,7 +310,7 @@ export default class PricingModuleService<
}
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
async delete(
async deleteMoneyAmounts(
ids: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<void> {