feat: Completely revamp the pricing module (#7852)

* feat: Completely revamp the pricing module

* chore: Update all places to the new pricing interfaces

* fix: Remove unnecessary join to itself

* chore: Add data migration for existing users

* fix: Apply the correct index to price rule
This commit is contained in:
Stevche Radevski
2024-07-01 09:47:03 +02:00
committed by GitHub
parent 1f360a3245
commit c661180c44
84 changed files with 661 additions and 3725 deletions
@@ -2,11 +2,13 @@ export const defaultPriceListRuleData = [
{
id: "price-list-rule-1",
price_list_id: "price-list-1",
rule_type_id: "rule-type-1",
attribute: "currency_code",
value: [],
},
{
id: "price-list-rule-2",
price_list_id: "price-list-1",
rule_type_id: "rule-type-2",
attribute: "region_id",
value: [],
},
]
@@ -6,7 +6,7 @@ export const defaultPriceRuleData = [
{
id: "price-rule-1",
price_set_id: "price-set-1",
rule_type_id: "rule-type-1",
attribute: "currency_code",
value: "USD",
price_list_id: "test",
price_id: "price-set-money-amount-USD",
@@ -14,7 +14,7 @@ export const defaultPriceRuleData = [
{
id: "price-rule-2",
price_set_id: "price-set-2",
rule_type_id: "rule-type-2",
attribute: "region_id",
value: "region_1",
price_list_id: "test",
price_id: "price-set-money-amount-EUR",
@@ -16,7 +16,7 @@ export async function createPriceRules(
const priceRuleDataClone: CreatePriceRuleDTO = { ...priceRuleData }
priceRuleDataClone.price_set_id = priceRuleDataClone.price_set_id
priceRuleDataClone.rule_type_id = priceRuleDataClone.rule_type_id
priceRuleDataClone.attribute = priceRuleDataClone.attribute
priceRuleDataClone.price_id = priceRuleDataClone.price_id
const priceRule = manager.create(PriceRule, priceRuleDataClone)
@@ -1,12 +0,0 @@
export const defaultRuleTypesData = [
{
id: "rule-type-1",
name: "rule 1",
rule_attribute: "currency_code",
},
{
id: "rule-type-2",
name: "rule 2",
rule_attribute: "region_id",
},
]
@@ -1,22 +0,0 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { RuleType } from "@models"
import { defaultRuleTypesData } from "./data"
export * from "./data"
export async function createRuleTypes(
manager: SqlEntityManager,
ruletypesData: any[] = defaultRuleTypesData
): Promise<RuleType[]> {
const ruleTypes: RuleType[] = []
for (let ruleTypeData of ruletypesData) {
const ruleType = manager.create(RuleType, ruleTypeData)
ruleTypes.push(ruleType)
}
await manager.persistAndFlush(ruleTypes)
return ruleTypes
}
@@ -2,7 +2,6 @@ import { SqlEntityManager } from "@mikro-orm/postgresql"
import { createPrices, defaultPricesData } from "./price"
import { createPriceRules, defaultPriceRuleData } from "./price-rule"
import { createPriceSets, defaultPriceSetsData } from "./price-set"
import { createRuleTypes, defaultRuleTypesData } from "./rule-type"
jest.setTimeout(30000)
@@ -12,11 +11,9 @@ export async function seedPriceData(
priceSetsData = defaultPriceSetsData,
priceRuleData = defaultPriceRuleData,
pricesData = defaultPricesData,
ruleTypesData = defaultRuleTypesData,
} = {}
) {
await createPriceSets(testManager, priceSetsData)
await createPrices(testManager, pricesData)
await createRuleTypes(testManager, ruleTypesData)
await createPriceRules(testManager, priceRuleData)
}
@@ -154,32 +154,11 @@ moduleIntegrationTestRunner<IPricingModuleService>({
},
]
const ruleTypesData = [
{
id: "rule-type-company_id",
name: "rule type company id",
rule_attribute: "company_id",
default_priority: 2,
},
{
id: "rule-type-region_id",
name: "rule type region id",
rule_attribute: "region_id",
default_priority: 1,
},
{
id: "rule-type-customer_group_id",
name: "rule type customer group id",
rule_attribute: "customer_group_id",
default_priority: 3,
},
]
const priceRuleData = [
{
id: "price-rule-company_id-EUR",
price_set_id: "price-set-EUR",
rule_type_id: "rule-type-company_id",
attribute: "company_id",
value: "EUR",
price_list_id: "test",
price_id: "price-company_id-EUR",
@@ -187,7 +166,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-company_id-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-company_id",
attribute: "company_id",
value: "medusa-company-id",
price_list_id: "test",
price_id: "price-company_id-PLN",
@@ -195,7 +174,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
attribute: "region_id",
value: "PL",
price_list_id: "test",
price_id: "price-region_id-PLN",
@@ -203,7 +182,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id+company_id-PL",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
attribute: "region_id",
value: "PL",
price_list_id: "test",
price_id: "price-region_id+company_id-PLN",
@@ -211,7 +190,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id+company_id-medusa-company-id",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-company_id",
attribute: "company_id",
value: "medusa-company-id",
price_list_id: "test",
price_id: "price-region_id+company_id-PLN",
@@ -219,7 +198,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-PLN-5-qty",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
attribute: "region_id",
value: "PL",
price_list_id: "test",
price_id: "price-region_id-PLN-5-qty",
@@ -227,7 +206,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-company_id-PL",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
attribute: "region_id",
value: "PL",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR",
@@ -235,7 +214,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-company_id-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-company_id",
attribute: "company_id",
value: "medusa-company-id",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR",
@@ -243,7 +222,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-company_id-PL-4-qty",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
attribute: "region_id",
value: "PL",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR-4-qty",
@@ -251,7 +230,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-company_id-PLN-4-qty",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-company_id",
attribute: "company_id",
value: "medusa-company-id",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR-4-qty",
@@ -259,7 +238,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-currency_customer_group_code-PL",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
attribute: "region_id",
value: "PL",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR-customer-group",
@@ -267,7 +246,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-currency_customer_group_code-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-company_id",
attribute: "company_id",
value: "medusa-company-id",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR-customer-group",
@@ -275,7 +254,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
{
id: "price-rule-region_id-currency_customer_group_code-test_customer_group",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-customer_group_id",
attribute: "customer_group_id",
value: "test-customer-group",
price_list_id: "test",
price_id: "price-region_id_company_id-PL-EUR-customer-group",
@@ -286,7 +265,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
priceSetsData,
pricesData,
priceRuleData,
ruleTypesData,
})
})
@@ -3,7 +3,6 @@ import { SqlEntityManager } from "@mikro-orm/postgresql"
import { moduleIntegrationTestRunner } from "medusa-test-utils"
import { createPriceLists } from "../../../__fixtures__/price-list"
import { createPriceListRules } from "../../../__fixtures__/price-list-rules"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { Modules } from "@medusajs/utils"
jest.setTimeout(30000)
@@ -15,7 +14,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
let testManager: SqlEntityManager
beforeEach(async () => {
testManager = await MikroOrmWrapper.forkManager()
await createRuleTypes(testManager)
await createPriceLists(testManager)
await createPriceListRules(testManager)
})
@@ -166,14 +164,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
describe("setPriceListRules", () => {
it("should add a price list rule to a price list", async () => {
await createRuleTypes(testManager, [
{
id: "rule-type-3",
name: "test",
rule_attribute: "sales_channel",
},
])
await service.setPriceListRules({
price_list_id: "price-list-1",
rules: {
@@ -184,34 +174,21 @@ moduleIntegrationTestRunner<IPricingModuleService>({
const [priceList] = await service.listPriceLists(
{ id: ["price-list-1"] },
{
relations: [
"price_list_rules",
"price_list_rules.price_list_rule_values",
],
relations: ["price_list_rules"],
}
)
expect(priceList.price_list_rules).toEqual(
expect.arrayContaining([
expect.objectContaining({
rule_type: { id: "rule-type-3" },
price_list_rule_values: [
expect.objectContaining({ value: "sc-1" }),
],
attribute: "sales_channel",
value: "sc-1",
}),
])
)
})
it("should multiple priceListRules to a priceList", async () => {
await createRuleTypes(testManager, [
{
id: "rule-type-3",
name: "test",
rule_attribute: "sales_channel",
},
])
await service.setPriceListRules({
price_list_id: "price-list-1",
rules: {
@@ -224,21 +201,15 @@ moduleIntegrationTestRunner<IPricingModuleService>({
id: ["price-list-1"],
},
{
relations: [
"price_list_rules",
"price_list_rules.price_list_rule_values",
],
relations: ["price_list_rules"],
}
)
expect(priceList.price_list_rules).toEqual(
expect.arrayContaining([
expect.objectContaining({
rule_type: { id: "rule-type-3" },
price_list_rule_values: expect.arrayContaining([
expect.objectContaining({ value: "sc-1" }),
expect.objectContaining({ value: "sc-2" }),
]),
attribute: "sales_channel",
value: ["sc-1", "sc-2"],
}),
])
)
@@ -262,7 +233,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
)
expect(priceList.price_list_rules).toEqual([
expect.objectContaining({ rule_type: { id: "rule-type-2" } }),
expect.objectContaining({ attribute: "region_id" }),
])
})
})
@@ -32,16 +32,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
const testManager = await MikroOrmWrapper.forkManager()
await createPriceSets(testManager)
await createPriceLists(testManager)
await service.createRuleTypes([
{
name: "Region ID",
rule_attribute: "region_id",
},
{
name: "Customer Group ID",
rule_attribute: "customer_group_id",
},
])
})
describe("list", () => {
@@ -287,20 +277,15 @@ moduleIntegrationTestRunner<IPricingModuleService>({
const [priceList] = await service.listPriceLists(
{ id: [createdId] },
{
relations: [
"prices",
"prices.price_set",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
],
relations: ["prices", "price_list_rules"],
select: [
"id",
"starts_at",
"prices.amount",
"prices.currency_code",
"prices.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
],
}
)
@@ -317,17 +302,8 @@ moduleIntegrationTestRunner<IPricingModuleService>({
]),
price_list_rules: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
rule_type: expect.objectContaining({
id: expect.any(String),
rule_attribute: "new_rule",
}),
price_list_rule_values: [
expect.objectContaining({
id: expect.any(String),
value: "new-rule-value",
}),
],
attribute: "new_rule",
value: ["new-rule-value"],
}),
]),
})
@@ -349,7 +325,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
}
expect(error.message).toEqual(
'PriceList with id "does-not-exist" not found'
"Price lists with ids: 'does-not-exist' not found"
)
})
})
@@ -439,19 +415,14 @@ moduleIntegrationTestRunner<IPricingModuleService>({
id: [created.id],
},
{
relations: [
"prices",
"prices.price_set",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
],
relations: ["prices", "prices.price_set", "price_list_rules"],
select: [
"id",
"prices.amount",
"prices.currency_code",
"prices.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
],
}
)
@@ -468,37 +439,16 @@ moduleIntegrationTestRunner<IPricingModuleService>({
price_list_rules: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
rule_type: expect.objectContaining({
id: expect.any(String),
rule_attribute: "customer_group_id",
}),
price_list_rule_values: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: "vip-customer-group-id",
}),
expect.objectContaining({
id: expect.any(String),
value: "another-vip-customer-group-id",
}),
]),
attribute: "customer_group_id",
value: [
"vip-customer-group-id",
"another-vip-customer-group-id",
],
}),
expect.objectContaining({
id: expect.any(String),
rule_type: expect.objectContaining({
id: expect.any(String),
rule_attribute: "region_id",
}),
price_list_rule_values: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: "DE",
}),
expect.objectContaining({
id: expect.any(String),
value: "DK",
}),
]),
attribute: "region_id",
value: ["DE", "DK"],
}),
]),
})
@@ -581,8 +531,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
"prices",
"prices.price_set",
"prices.price_rules",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
"price_list_rules",
],
select: [
"id",
@@ -591,8 +540,8 @@ moduleIntegrationTestRunner<IPricingModuleService>({
"prices.amount",
"prices.currency_code",
"prices.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
],
}
)
@@ -622,72 +571,21 @@ moduleIntegrationTestRunner<IPricingModuleService>({
price_list_rules: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
rule_type: expect.objectContaining({
id: expect.any(String),
rule_attribute: "customer_group_id",
}),
price_list_rule_values: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: "vip-customer-group-id",
}),
expect.objectContaining({
id: expect.any(String),
value: "another-vip-customer-group-id",
}),
]),
attribute: "customer_group_id",
value: [
"vip-customer-group-id",
"another-vip-customer-group-id",
],
}),
expect.objectContaining({
id: expect.any(String),
rule_type: expect.objectContaining({
id: expect.any(String),
rule_attribute: "region_id",
}),
price_list_rule_values: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: "DE",
}),
expect.objectContaining({
id: expect.any(String),
value: "DK",
}),
]),
attribute: "region_id",
value: ["DE", "DK"],
}),
]),
})
)
})
it("should throw error when rule type does not exist", async () => {
const error = await service
.createPriceLists([
{
title: "test",
description: "test",
rules: {
region_id: ["DE", "DK"],
missing_1: ["test-missing-1"],
},
prices: [
{
amount: 400,
currency_code: "EUR",
price_set_id: "price-set-1",
rules: {
region_id: "DE",
missing_2: "test-missing-2",
},
},
],
},
])
.catch((e) => e)
expect(error.message).toEqual(
"Cannot find RuleTypes with rule_attribute - missing_1, missing_2"
)
})
})
describe("addPriceListPrices", () => {
@@ -714,8 +612,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
"prices",
"prices.price_set",
"prices.price_rules",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
"price_list_rules",
],
select: [
"id",
@@ -724,8 +621,8 @@ moduleIntegrationTestRunner<IPricingModuleService>({
"prices.amount",
"prices.currency_code",
"prices.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
],
}
)
@@ -746,13 +643,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
})
it("should add a price with rules to a priceList successfully", async () => {
await service.createRuleTypes([
{
name: "region_id",
rule_attribute: "region_id",
},
])
await service.addPriceListPrices([
{
price_list_id: "price-list-1",
@@ -778,20 +668,18 @@ moduleIntegrationTestRunner<IPricingModuleService>({
"prices",
"prices.price_set",
"prices.price_rules",
"prices.price_rules.rule_type",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
"price_list_rules",
],
select: [
"id",
"prices.price_rules.value",
"prices.price_rules.rule_type.rule_attribute",
"prices.price_rules.attribute",
"prices.rules_count",
"prices.amount",
"prices.currency_code",
"prices.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
],
}
)
@@ -805,9 +693,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
price_rules: [
expect.objectContaining({
value: "EU",
rule_type: expect.objectContaining({
rule_attribute: "region_id",
}),
attribute: "region_id",
}),
],
amount: 123,
@@ -884,20 +770,18 @@ moduleIntegrationTestRunner<IPricingModuleService>({
"prices",
"prices.price_set",
"prices.price_rules",
"prices.price_rules.rule_type",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
"price_list_rules",
],
select: [
"id",
"prices.price_rules.value",
"prices.price_rules.rule_type.rule_attribute",
"prices.price_rules.attribute",
"prices.rules_count",
"prices.amount",
"prices.currency_code",
"prices.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
"price_list_rules.value",
"price_list_rules.attribute",
],
}
)
@@ -911,15 +795,11 @@ moduleIntegrationTestRunner<IPricingModuleService>({
price_rules: expect.arrayContaining([
expect.objectContaining({
value: "new test",
rule_type: expect.objectContaining({
rule_attribute: "region_id",
}),
attribute: "region_id",
}),
expect.objectContaining({
value: "new test",
rule_type: expect.objectContaining({
rule_attribute: "customer_group_id",
}),
attribute: "customer_group_id",
}),
]),
amount: 123,
@@ -934,9 +814,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
describe("removePrices", () => {
it("should remove prices from a priceList successfully", async () => {
const [priceSet] = await service.createPriceSets([
{ rules: [{ rule_attribute: "region_id" }] },
])
const [priceSet] = await service.createPriceSets([{}])
await service.addPriceListPrices([
{
@@ -5,7 +5,6 @@ import { Price } from "../../../../src/models"
import { createPrices } from "../../../__fixtures__/price"
import { createPriceRules } from "../../../__fixtures__/price-rule"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { Modules } from "@medusajs/utils"
jest.setTimeout(30000)
@@ -19,7 +18,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
testManager = await MikroOrmWrapper.forkManager()
await createPriceSets(testManager)
await createRuleTypes(testManager)
await createPrices(testManager)
await createPriceRules(testManager)
})
@@ -57,8 +55,8 @@ moduleIntegrationTestRunner<IPricingModuleService>({
id: ["price-rule-1"],
},
{
select: ["id", "price_set.id"],
relations: ["price_set"],
select: ["id", "price.id"],
relations: ["price"],
}
)
@@ -67,10 +65,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
expect(serialized).toEqual([
{
id: "price-rule-1",
price_set: {
id: "price-set-1",
price: {
id: "price-set-money-amount-USD",
},
price_set_id: "price-set-1",
price_id: "price-set-money-amount-USD",
},
])
})
@@ -112,8 +110,8 @@ moduleIntegrationTestRunner<IPricingModuleService>({
id: ["price-rule-1"],
},
{
select: ["id", "price_set.id"],
relations: ["price_set"],
select: ["id", "price.id"],
relations: ["price"],
}
)
@@ -123,10 +121,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
expect(serialized).toEqual([
{
id: "price-rule-1",
price_set: {
id: "price-set-1",
price: {
id: "price-set-money-amount-USD",
},
price_set_id: "price-set-1",
price_id: "price-set-money-amount-USD",
},
])
})
@@ -283,7 +281,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
await service.createPriceRules({
id: "price-rule-new",
price_set_id: "price-set-1",
rule_type_id: "rule-type-1",
attribute: "region_id",
value: "region_1",
price_list_id: "test",
price_id: price.id,
@@ -1,39 +1,18 @@
import {
CreatePriceSetDTO,
CreatePriceSetRuleTypeDTO,
IPricingModuleService,
} from "@medusajs/types"
import { CreatePriceSetDTO, IPricingModuleService } from "@medusajs/types"
import {
CommonEvents,
composeMessage,
Modules,
PricingEvents,
} from "@medusajs/utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import {
MockEventBusService,
moduleIntegrationTestRunner,
} from "medusa-test-utils"
import { PriceSetRuleType } from "../../../../src/models"
import { seedPriceData } from "../../../__fixtures__/seed-price-data"
jest.setTimeout(30000)
async function createPriceSetPriceRules(
manager: SqlEntityManager,
priceSetRulesData: CreatePriceSetRuleTypeDTO[]
): Promise<void> {
const priceSetRules: PriceSetRuleType[] = []
for (let priceSetRuleData of priceSetRulesData) {
const priceRule = manager.create(PriceSetRuleType, priceSetRuleData as any)
priceSetRules.push(priceRule)
}
await manager.persistAndFlush(priceSetRules)
}
moduleIntegrationTestRunner<IPricingModuleService>({
moduleName: Modules.PRICING,
testSuite: ({ MikroOrmWrapper, service }) => {
@@ -51,16 +30,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
await seedPriceData(testManager)
await createPriceSetPriceRules(testManager, [
{
price_set_id: "price-set-1",
rule_type_id: "rule-type-1",
},
{
price_set_id: "price-set-2",
rule_type_id: "rule-type-2",
},
])
})
describe("list", () => {
@@ -346,32 +315,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
})
describe("create", () => {
it("should fail to create a price set with rule types and money amounts with rule types that don't exits", async () => {
let error
try {
await service.createPriceSets([
{
rules: [{ rule_attribute: "region_id" }],
prices: [
{
amount: 100,
currency_code: "USD",
rules: {
city: "Berlin",
},
},
],
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
"Rule types don't exist for prices with rule attribute: city"
)
})
it("should create a price set with rule types and money amounts", async () => {
const [priceSet] = await service.createPriceSets([
{
@@ -399,10 +342,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
})
)
const [priceRules] = await service.listPriceRules({
price_set_id: [priceSet.id],
})
const events = eventBusEmitSpy.mock.calls[0][0]
expect(events).toHaveLength(3)
expect(events[0]).toEqual(
@@ -429,7 +368,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
action: CommonEvents.CREATED,
object: "price_rule",
data: {
id: priceRules.id,
id: (priceSet as any).prices![0].price_rules[0].id,
},
})
)
@@ -591,26 +530,6 @@ moduleIntegrationTestRunner<IPricingModuleService>({
}),
])
})
it("should fail with an appropriate error when trying to add a price with rule that doesn't exist", async () => {
let error
try {
await service.addPrices({
priceSetId: "price-set-1",
prices: [
{
amount: 100,
currency_code: "USD",
rules: { city: "Paris" },
},
],
})
} catch (e) {
error = e
}
expect(error.message).toEqual("Rule types don't exist for: city")
})
})
})
},
@@ -1,239 +0,0 @@
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { moduleIntegrationTestRunner } from "medusa-test-utils"
import { IPricingModuleService } from "@medusajs/types"
import { Modules } from "@medusajs/utils"
jest.setTimeout(30000)
moduleIntegrationTestRunner<IPricingModuleService>({
moduleName: Modules.PRICING,
testSuite: ({ MikroOrmWrapper, service }) => {
describe("PricingModuleService ruleType", () => {
beforeEach(async () => {
const testManager = MikroOrmWrapper.forkManager()
await createRuleTypes(testManager)
})
describe("listRuleTypes", () => {
it("should list rule types", async () => {
const ruleTypeResult = await service.listRuleTypes()
expect(ruleTypeResult).toEqual([
expect.objectContaining({
id: "rule-type-1",
name: "rule 1",
}),
expect.objectContaining({
id: "rule-type-2",
name: "rule 2",
}),
])
})
it("should list rule types by id", async () => {
const ruleTypeResult = await service.listRuleTypes({
id: ["rule-type-1"],
})
expect(ruleTypeResult).toEqual([
expect.objectContaining({
id: "rule-type-1",
name: "rule 1",
}),
])
})
})
describe("listAndCountRuleTypes", () => {
it("should return rule types and count", async () => {
const [ruleTypeResult, count] = await service.listAndCountRuleTypes()
expect(count).toEqual(2)
expect(ruleTypeResult).toEqual([
expect.objectContaining({
id: "rule-type-1",
name: "rule 1",
}),
expect.objectContaining({
id: "rule-type-2",
name: "rule 2",
}),
])
})
it("should return rule types and count when filtered", async () => {
const [ruleTypeResult, count] = await service.listAndCountRuleTypes({
id: ["rule-type-1"],
})
expect(count).toEqual(1)
expect(ruleTypeResult).toEqual([
expect.objectContaining({
id: "rule-type-1",
name: "rule 1",
}),
])
})
it("should return rule types and count when using skip and take", async () => {
const [ruleTypeResult, count] = await service.listAndCountRuleTypes(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(ruleTypeResult).toEqual([
expect.objectContaining({
id: "rule-type-2",
name: "rule 2",
}),
])
})
it("should return requested fields", async () => {
const [ruleTypeResult, count] = await service.listAndCountRuleTypes(
{},
{
take: 1,
select: ["name"],
}
)
const serialized = JSON.parse(JSON.stringify(ruleTypeResult))
expect(count).toEqual(2)
expect(serialized).toEqual([
{
id: "rule-type-1",
name: "rule 1",
},
])
})
})
describe("retrieveRuleType", () => {
it("should return ruleType for the given id", async () => {
const ruleType = await service.retrieveRuleType("rule-type-1")
expect(ruleType).toEqual(
expect.objectContaining({
id: "rule-type-1",
name: "rule 1",
})
)
})
it("should throw an error when ruleType with id does not exist", async () => {
let error
try {
await service.retrieveRuleType("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"RuleType with id: does-not-exist was not found"
)
})
it("should throw an error when an id is not provided", async () => {
let error
try {
await service.retrieveRuleType(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual("ruleType - id must be defined")
})
it("should return ruleType based on config select param", async () => {
const ruleTypeResult = await service.retrieveRuleType("rule-type-1", {
select: ["name"],
})
const serialized = JSON.parse(JSON.stringify(ruleTypeResult))
expect(serialized).toEqual({
name: "rule 1",
id: "rule-type-1",
})
})
})
describe("deleteRuleTypes", () => {
const id = "rule-type-1"
it("should delete the ruleTypes given an id successfully", async () => {
await service.deleteRuleTypes([id])
const currencies = await service.listRuleTypes({
id: [id],
})
expect(currencies).toHaveLength(0)
})
})
describe("updateRuleTypes", () => {
const id = "rule-type-1"
it("should update the name of the ruleType successfully", async () => {
await service.updateRuleTypes([
{
id,
name: "rule 3",
},
])
const ruletype = await service.retrieveRuleType(id)
expect(ruletype.name).toEqual("rule 3")
})
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.updateRuleTypes([
{
id: "does-not-exist",
name: "rule 3",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'RuleType with id "does-not-exist" not found'
)
})
})
describe("createRuleTypes", () => {
it("should create a ruleType successfully", async () => {
await service.createRuleTypes([
{
name: "Test Rule",
rule_attribute: "region_id",
},
])
const [ruleType] = await service.listRuleTypes({
name: ["Test Rule"],
})
expect(ruleType).toEqual(
expect.objectContaining({
name: "Test Rule",
rule_attribute: "region_id",
})
)
})
})
})
},
})
@@ -4,15 +4,14 @@ import {
MapToConfig,
Modules,
} from "@medusajs/utils"
import { Price, PriceList, PriceSet, RuleType } from "@models"
import { Price, PriceList, PriceSet } from "@models"
export const joinerConfig = defineJoinerConfig(Modules.PRICING, {
entityQueryingConfig: [PriceSet, PriceList, Price, RuleType],
entityQueryingConfig: [PriceSet, PriceList, Price],
linkableKeys: {
price_set_id: PriceSet.name,
price_list_id: PriceList.name,
price_id: Price.name,
rule_type_id: RuleType.name,
},
})
@@ -150,6 +150,127 @@
"checks": [],
"foreignKeys": {}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"attribute": {
"name": "attribute",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"value": {
"name": "value",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "json"
},
"price_list_id": {
"name": "price_list_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "price_list_rule",
"schema": "public",
"indexes": [
{
"keyName": "IDX_price_list_rule_price_list_id",
"columnNames": [
"price_list_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_list_rule_price_list_id\" ON \"price_list_rule\" (price_list_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_list_rule_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_list_rule_deleted_at\" ON \"price_list_rule\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "price_list_rule_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"price_list_rule_price_list_id_foreign": {
"constraintName": "price_list_rule_price_list_id_foreign",
"columnNames": [
"price_list_id"
],
"localTableName": "public.price_list_rule",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.price_list",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
},
{
"columns": {
"id": {
@@ -440,260 +561,8 @@
"nullable": false,
"mappedType": "text"
},
"name": {
"name": "name",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"rule_attribute": {
"name": "rule_attribute",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"default_priority": {
"name": "default_priority",
"type": "integer",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"default": "0",
"mappedType": "integer"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "rule_type",
"schema": "public",
"indexes": [
{
"keyName": "IDX_rule_type_rule_attribute",
"columnNames": [
"rule_attribute"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_rule_type_rule_attribute\" ON \"rule_type\" (rule_attribute) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_rule_type_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_rule_type_deleted_at\" ON \"rule_type\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "rule_type_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": false,
"mappedType": "text"
},
"rule_type_id": {
"name": "rule_type_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "price_set_rule_type",
"schema": "public",
"indexes": [
{
"keyName": "IDX_price_set_rule_type_price_set_id",
"columnNames": [
"price_set_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_set_rule_type_price_set_id\" ON \"price_set_rule_type\" (price_set_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_set_rule_type_rule_type_id",
"columnNames": [
"rule_type_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_set_rule_type_rule_type_id\" ON \"price_set_rule_type\" (rule_type_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_set_rule_type_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_set_rule_type_deleted_at\" ON \"price_set_rule_type\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "price_set_rule_type_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"price_set_rule_type_price_set_id_foreign": {
"constraintName": "price_set_rule_type_price_set_id_foreign",
"columnNames": [
"price_set_id"
],
"localTableName": "public.price_set_rule_type",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.price_set",
"deleteRule": "cascade",
"updateRule": "cascade"
},
"price_set_rule_type_rule_type_id_foreign": {
"constraintName": "price_set_rule_type_rule_type_id_foreign",
"columnNames": [
"rule_type_id"
],
"localTableName": "public.price_set_rule_type",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.rule_type",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
},
{
"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": false,
"mappedType": "text"
},
"rule_type_id": {
"name": "rule_type_id",
"attribute": {
"name": "attribute",
"type": "text",
"unsigned": false,
"autoincrement": false,
@@ -766,34 +635,14 @@
"schema": "public",
"indexes": [
{
"keyName": "IDX_price_rule_price_set_id",
"columnNames": [
"price_set_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_rule_price_set_id\" ON \"price_rule\" (price_set_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_rule_rule_type_id",
"columnNames": [
"rule_type_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_rule_rule_type_id\" ON \"price_rule\" (rule_type_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_rule_price_id_rule_type_id_unique",
"keyName": "IDX_price_rule_price_id_attribute_unique",
"columnNames": [
"price_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_price_rule_price_id_rule_type_id_unique\" ON \"price_rule\" (price_id, rule_type_id) WHERE deleted_at IS NULL"
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_price_rule_price_id_attribute_unique\" ON \"price_rule\" (price_id, attribute) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_rule_deleted_at",
@@ -817,31 +666,6 @@
],
"checks": [],
"foreignKeys": {
"price_rule_price_set_id_foreign": {
"constraintName": "price_rule_price_set_id_foreign",
"columnNames": [
"price_set_id"
],
"localTableName": "public.price_rule",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.price_set",
"deleteRule": "cascade",
"updateRule": "cascade"
},
"price_rule_rule_type_id_foreign": {
"constraintName": "price_rule_rule_type_id_foreign",
"columnNames": [
"rule_type_id"
],
"localTableName": "public.price_rule",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.rule_type",
"updateRule": "cascade"
},
"price_rule_price_id_foreign": {
"constraintName": "price_rule_price_id_foreign",
"columnNames": [
@@ -856,252 +680,6 @@
"updateRule": "cascade"
}
}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"rule_type_id": {
"name": "rule_type_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"price_list_id": {
"name": "price_list_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "price_list_rule",
"schema": "public",
"indexes": [
{
"keyName": "IDX_price_list_rule_rule_type_id_unique",
"columnNames": [
"rule_type_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_price_list_rule_rule_type_id_unique\" ON \"price_list_rule\" (rule_type_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_list_rule_price_list_id",
"columnNames": [
"price_list_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_list_rule_price_list_id\" ON \"price_list_rule\" (price_list_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_list_rule_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_list_rule_deleted_at\" ON \"price_list_rule\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "price_list_rule_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"price_list_rule_rule_type_id_foreign": {
"constraintName": "price_list_rule_rule_type_id_foreign",
"columnNames": [
"rule_type_id"
],
"localTableName": "public.price_list_rule",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.rule_type",
"updateRule": "cascade"
},
"price_list_rule_price_list_id_foreign": {
"constraintName": "price_list_rule_price_list_id_foreign",
"columnNames": [
"price_list_id"
],
"localTableName": "public.price_list_rule",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.price_list",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"price_list_rule_id": {
"name": "price_list_rule_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"value": {
"name": "value",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "price_list_rule_value",
"schema": "public",
"indexes": [
{
"keyName": "IDX_price_list_rule_value_price_list_rule_id",
"columnNames": [
"price_list_rule_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_list_rule_value_price_list_rule_id\" ON \"price_list_rule_value\" (price_list_rule_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_price_list_rule_value_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_list_rule_value_deleted_at\" ON \"price_list_rule_value\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "price_list_rule_value_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"price_list_rule_value_price_list_rule_id_foreign": {
"constraintName": "price_list_rule_value_price_list_rule_id_foreign",
"columnNames": [
"price_list_rule_id"
],
"localTableName": "public.price_list_rule_value",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.price_list_rule",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
}
]
}
@@ -0,0 +1,72 @@
import { Migration } from "@mikro-orm/migrations"
export class Migration20240626133555 extends Migration {
async up(): Promise<void> {
this.addSql(
'alter table if exists "price_list_rule" add column if not exists "value" jsonb;'
)
// TODO: Added on 28.06.2024, Drop defaults after a while.
this.addSql(
'alter table if exists "price_list_rule" add column if not exists "attribute" text not null DEFAULT \'\';'
)
this.addSql(
'alter table if exists "price_rule" add column if not exists "attribute" text not null DEFAULT \'\';'
)
/* DATA MIGRATION */
this.addSql(
"update price_rule set attribute = (SELECT rule_attribute FROM rule_type WHERE rule_type.id = price_rule.rule_type_id);"
)
this.addSql(
"update price_list_rule set value = (SELECT array_to_json(ARRAY(SELECT value FROM price_list_rule_value WHERE price_list_rule_value.price_list_rule_id = price_list_rule.id))::jsonb);"
)
this.addSql(
"update price_list_rule set attribute = (SELECT rule_attribute FROM rule_type WHERE rule_type.id = price_list_rule.rule_type_id);"
)
/* DATA MIGRATION END */
this.addSql(
'alter table if exists "price_set_rule_type" drop constraint if exists "price_set_rule_type_rule_type_id_foreign";'
)
this.addSql(
'alter table if exists "price_rule" drop constraint if exists "price_rule_rule_type_id_foreign";'
)
this.addSql(
'alter table if exists "price_list_rule" drop constraint if exists "price_list_rule_rule_type_id_foreign";'
)
this.addSql(
'alter table if exists "price_rule" drop constraint if exists "price_rule_price_set_id_foreign";'
)
this.addSql(
'drop index if exists "IDX_price_list_rule_rule_type_id_unique";'
)
this.addSql('drop index if exists "IDX_price_rule_price_set_id";')
this.addSql('drop index if exists "IDX_price_rule_rule_type_id";')
this.addSql('drop index if exists "IDX_price_rule_price_id_unique";')
this.addSql(
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_price_rule_price_id_attribute_unique" ON "price_rule" (price_id, attribute) WHERE deleted_at IS NULL;'
)
this.addSql(
'alter table if exists "price_rule" drop column if exists "price_set_id";'
)
this.addSql(
'alter table if exists "price_rule" drop column if exists "rule_type_id";'
)
this.addSql(
'alter table if exists "price_list_rule" drop column if exists "rule_type_id";'
)
this.addSql('drop table if exists "rule_type" cascade;')
this.addSql('drop table if exists "price_set_rule_type" cascade;')
this.addSql('drop table if exists "price_list_rule_value" cascade;')
}
}
@@ -1,8 +1,5 @@
export { default as Price } from "./price"
export { default as PriceList } from "./price-list"
export { default as PriceListRule } from "./price-list-rule"
export { default as PriceListRuleValue } from "./price-list-rule-value"
export { default as PriceRule } from "./price-rule"
export { default as PriceSet } from "./price-set"
export { default as PriceSetRuleType } from "./price-set-rule-type"
export { default as RuleType } from "./rule-type"
@@ -1,88 +0,0 @@
import { DAL } from "@medusajs/types"
import {
createPsqlIndexStatementHelper,
DALUtils,
generateEntityId,
} from "@medusajs/utils"
import {
BeforeCreate,
Entity,
Filter,
ManyToOne,
OnInit,
OptionalProps,
PrimaryKey,
Property,
Rel,
} from "@mikro-orm/core"
import PriceListRule from "./price-list-rule"
type OptionalFields = DAL.SoftDeletableEntityDateColumns
const tableName = "price_list_rule_value"
const PriceListRuleValueDeletedAtIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
const PriceListPriceListRuleIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "price_list_rule_id",
where: "deleted_at IS NULL",
})
@Entity({ tableName })
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
export default class PriceListRuleValue {
[OptionalProps]?: OptionalFields
@PrimaryKey({ columnType: "text" })
id!: string
@PriceListPriceListRuleIdIndex.MikroORMIndex()
@ManyToOne(() => PriceListRule, {
columnType: "text",
mapToPk: true,
fieldName: "price_list_rule_id",
onDelete: "cascade",
})
price_list_rule_id: string
@ManyToOne(() => PriceListRule, { persist: false })
price_list_rule: Rel<PriceListRule>
@Property({ columnType: "text" })
value: string
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@PriceListRuleValueDeletedAtIndex.MikroORMIndex()
@Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "plrv")
this.price_list_rule_id ??= this.price_list_rule?.id
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "plrv")
this.price_list_rule_id ??= this.price_list_rule?.id
}
}
@@ -6,12 +6,9 @@ import {
} from "@medusajs/utils"
import {
BeforeCreate,
Cascade,
Collection,
Entity,
Filter,
ManyToOne,
OneToMany,
OnInit,
OptionalProps,
PrimaryKey,
@@ -19,8 +16,6 @@ import {
Rel,
} from "@mikro-orm/core"
import PriceList from "./price-list"
import PriceListRuleValue from "./price-list-rule-value"
import RuleType from "./rule-type"
type OptionalFields = DAL.SoftDeletableEntityDateColumns
@@ -31,13 +26,6 @@ const PriceListRuleDeletedAtIndex = createPsqlIndexStatementHelper({
where: "deleted_at IS NOT NULL",
})
const PriceListRuleRuleTypeIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "rule_type_id",
where: "deleted_at IS NULL",
unique: true,
})
const PriceListRulePriceListIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "price_list_id",
@@ -52,21 +40,11 @@ export default class PriceListRule {
@PrimaryKey({ columnType: "text" })
id!: string
@PriceListRuleRuleTypeIdIndex.MikroORMIndex()
@ManyToOne(() => RuleType, {
columnType: "text",
mapToPk: true,
fieldName: "rule_type_id",
})
rule_type_id: string
@Property({ columnType: "text" })
attribute: string
@ManyToOne(() => RuleType, { persist: false })
rule_type: Rel<RuleType>
@OneToMany(() => PriceListRuleValue, (plrv) => plrv.price_list_rule, {
cascade: [Cascade.PERSIST, "soft-remove" as Cascade],
})
price_list_rule_values = new Collection<Rel<PriceListRuleValue>>(this)
@Property({ columnType: "jsonb", nullable: true })
value: string | string[] | null = null
@PriceListRulePriceListIdIndex.MikroORMIndex()
@ManyToOne(() => PriceList, {
@@ -103,13 +81,11 @@ export default class PriceListRule {
beforeCreate() {
this.id = generateEntityId(this.id, "plrule")
this.price_list_id ??= this.price_list?.id!
this.rule_type_id ??= this.rule_type?.id!
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "plrule")
this.price_list_id ??= this.price_list?.id!
this.rule_type_id ??= this.rule_type?.id!
}
}
@@ -14,7 +14,6 @@ import {
Entity,
Enum,
Filter,
ManyToMany,
OneToMany,
OnInit,
OptionalProps,
@@ -24,7 +23,6 @@ import {
} from "@mikro-orm/core"
import Price from "./price"
import PriceListRule from "./price-list-rule"
import RuleType from "./rule-type"
type OptionalFields =
| "starts_at"
@@ -84,12 +82,6 @@ export default class PriceList {
})
price_list_rules = new Collection<Rel<PriceListRule>>(this)
@ManyToMany({
entity: () => RuleType,
pivotEntity: () => PriceListRule,
})
rule_types = new Collection<Rel<RuleType>>(this)
@Property({ columnType: "integer", default: 0 })
rules_count: number = 0
@@ -16,8 +16,6 @@ import {
Rel,
} from "@mikro-orm/core"
import Price from "./price"
import PriceSet from "./price-set"
import RuleType from "./rule-type"
type OptionalFields = DAL.SoftDeletableEntityDateColumns
@@ -28,21 +26,9 @@ const PriceRuleDeletedAtIndex = createPsqlIndexStatementHelper({
where: "deleted_at IS NOT NULL",
})
const PriceRulePriceSetIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "price_set_id",
where: "deleted_at IS NULL",
})
const PriceRuleRuleTypeIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "rule_type_id",
where: "deleted_at IS NULL",
})
const PriceRulePriceIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: ["price_id", "rule_type_id"],
columns: ["price_id", "attribute"],
where: "deleted_at IS NULL",
unique: true,
})
@@ -55,28 +41,8 @@ export default class PriceRule {
@PrimaryKey({ columnType: "text" })
id!: string
@PriceRulePriceSetIdIndex.MikroORMIndex()
@ManyToOne(() => PriceSet, {
columnType: "text",
mapToPk: true,
fieldName: "price_set_id",
onDelete: "cascade",
})
price_set_id: string
@ManyToOne(() => PriceSet, { persist: false })
price_set: Rel<PriceSet>
@PriceRuleRuleTypeIdIndex.MikroORMIndex()
@ManyToOne(() => RuleType, {
columnType: "text",
mapToPk: true,
fieldName: "rule_type_id",
})
rule_type_id: string
@ManyToOne(() => RuleType, { persist: false })
rule_type: Rel<RuleType>
@Property({ columnType: "text" })
attribute: string
@Property({ columnType: "text" })
value: string
@@ -118,16 +84,12 @@ export default class PriceRule {
@BeforeCreate()
beforeCreate() {
this.id = generateEntityId(this.id, "prule")
this.rule_type_id ??= this.rule_type?.id!
this.price_set_id ??= this.price_set?.id!
this.price_id ??= this.price?.id!
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "prule")
this.rule_type_id ??= this.rule_type?.id!
this.price_set_id ??= this.price_set?.id!
this.price_id ??= this.price?.id!
}
}
@@ -1,89 +0,0 @@
import {
DALUtils,
createPsqlIndexStatementHelper,
generateEntityId,
} from "@medusajs/utils"
import {
BeforeCreate,
Entity,
Filter,
ManyToOne,
OnInit,
PrimaryKey,
Property,
} from "@mikro-orm/core"
import PriceSet from "./price-set"
import RuleType from "./rule-type"
const tableName = "price_set_rule_type"
const PriceSetRuleTypeDeletedAtIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
const PriceSetRuleTypePriceSetIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "price_set_id",
where: "deleted_at IS NULL",
})
const PriceSetRuleTypeRuleTypeIdIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "rule_type_id",
where: "deleted_at IS NULL",
})
@Entity({ tableName })
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
export default class PriceSetRuleType {
@PrimaryKey({ columnType: "text" })
id!: string
@PriceSetRuleTypePriceSetIdIndex.MikroORMIndex()
@ManyToOne(() => PriceSet, {
columnType: "text",
mapToPk: true,
fieldName: "price_set_id",
onDelete: "cascade",
})
price_set_id: string
@PriceSetRuleTypeRuleTypeIdIndex.MikroORMIndex()
@ManyToOne(() => RuleType, {
columnType: "text",
mapToPk: true,
fieldName: "rule_type_id",
onDelete: "cascade",
})
rule_type_id: string
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@PriceSetRuleTypeDeletedAtIndex.MikroORMIndex()
@Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "psrt")
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "psrt")
}
}
@@ -9,7 +9,6 @@ import {
Collection,
Entity,
Filter,
ManyToMany,
OneToMany,
OnInit,
PrimaryKey,
@@ -17,9 +16,6 @@ import {
Rel,
} from "@mikro-orm/core"
import Price from "./price"
import PriceRule from "./price-rule"
import PriceSetRuleType from "./price-set-rule-type"
import RuleType from "./rule-type"
const tableName = "price_set"
const PriceSetDeletedAtIndex = createPsqlIndexStatementHelper({
@@ -41,18 +37,6 @@ export default class PriceSet {
})
prices = new Collection<Rel<Price>>(this)
@OneToMany(() => PriceRule, (pr) => pr.price_set, {
cascade: [Cascade.PERSIST, "soft-remove" as Cascade],
})
price_rules = new Collection<Rel<PriceRule>>(this)
@ManyToMany({
entity: () => RuleType,
pivotEntity: () => PriceSetRuleType,
cascade: ["soft-remove" as Cascade],
})
rule_types = new Collection<Rel<RuleType>>(this)
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
@@ -1,86 +0,0 @@
import {
DALUtils,
createPsqlIndexStatementHelper,
generateEntityId,
} from "@medusajs/utils"
import {
BeforeCreate,
Collection,
Entity,
Filter,
ManyToMany,
OnInit,
OptionalProps,
PrimaryKey,
Property,
Rel,
} from "@mikro-orm/core"
import PriceSet from "./price-set"
type OptionalFields = "default_priority"
const tableName = "rule_type"
const RuleTypeDeletedAtIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
const RuleTypeRuleAttributeIndex = createPsqlIndexStatementHelper({
tableName: tableName,
columns: "rule_attribute",
where: "deleted_at IS NULL",
})
@Entity({ tableName })
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
class RuleType {
[OptionalProps]?: OptionalFields
@PrimaryKey({ columnType: "text" })
id!: string
@Property({ columnType: "text" })
name: string
@RuleTypeRuleAttributeIndex.MikroORMIndex()
@Property({ columnType: "text" })
rule_attribute: string
@Property({ columnType: "integer", default: 0 })
default_priority: number
@ManyToMany(() => PriceSet, (priceSet) => priceSet.rule_types)
price_sets = new Collection<Rel<PriceSet>>(this)
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@RuleTypeDeletedAtIndex.MikroORMIndex()
@Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "rul-typ")
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "rul-typ")
}
}
export default RuleType
@@ -61,65 +61,57 @@ export class PricingRepository
price: "price",
})
.select({
id: "price1.id",
amount: "price1.amount",
min_quantity: "price1.min_quantity",
max_quantity: "price1.max_quantity",
currency_code: "price1.currency_code",
price_set_id: "price1.price_set_id",
rules_count: "price1.rules_count",
price_list_id: "price1.price_list_id",
id: "price.id",
amount: "price.amount",
min_quantity: "price.min_quantity",
max_quantity: "price.max_quantity",
currency_code: "price.currency_code",
price_set_id: "price.price_set_id",
rules_count: "price.rules_count",
price_list_id: "price.price_list_id",
pl_rules_count: "pl.rules_count",
pl_type: "pl.type",
has_price_list: knex.raw(
"case when price1.price_list_id IS NULL then False else True end"
"case when price.price_list_id IS NULL then False else True end"
),
})
.leftJoin("price as price1", "price1.id", "price1.id")
.leftJoin("price_rule as pr", "pr.price_id", "price1.id")
.leftJoin("price_rule as pr", "pr.price_id", "price.id")
.leftJoin("price_list as pl", function () {
this.on("pl.id", "price1.price_list_id").andOn(
this.on("pl.id", "price.price_list_id").andOn(
"pl.status",
knex.raw("?", [PriceListStatus.ACTIVE])
)
})
.leftJoin("price_list_rule as plr", "plr.price_list_id", "pl.id")
.leftJoin(
"price_list_rule_value as plrv",
"plrv.price_list_rule_id",
"plr.id"
)
.leftJoin("rule_type as plrt", "plrt.id", "plr.rule_type_id")
.leftJoin("rule_type as rt", "rt.id", "pr.rule_type_id")
.orderBy([
{ column: "rules_count", order: "desc" },
{ column: "pl.rules_count", order: "desc" },
])
.groupBy("price1.id", "pl.id")
.groupBy("price.id", "pl.id")
.having(
knex.raw(
"count(DISTINCT rt.rule_attribute) = price1.rules_count AND price1.price_list_id IS NULL"
"count(DISTINCT pr.attribute) = price.rules_count AND price.price_list_id IS NULL"
)
)
.orHaving(
knex.raw(
"count(DISTINCT plrt.rule_attribute) = pl.rules_count AND price1.price_list_id IS NOT NULL"
"count(DISTINCT plr.attribute) = pl.rules_count AND price.price_list_id IS NOT NULL"
)
)
priceSubQueryKnex.orWhere((q) => {
for (const [key, value] of Object.entries(context)) {
q.orWhere({
"rt.rule_attribute": key,
"pr.attribute": key,
"pr.value": value,
})
}
q.orWhere("price1.rules_count", "=", 0)
q.whereNull("price1.price_list_id")
q.orWhere("price.rules_count", "=", 0)
q.whereNull("price.price_list_id")
})
priceSubQueryKnex.orWhere((q) => {
q.whereNotNull("price1.price_list_id")
q.whereNotNull("price.price_list_id")
.andWhere(function () {
this.whereNull("pl.starts_at").orWhere("pl.starts_at", "<=", date)
})
@@ -130,9 +122,13 @@ export class PricingRepository
this.andWhere(function () {
for (const [key, value] of Object.entries(context)) {
this.orWhere({
"plrt.rule_attribute": key,
"plr.attribute": key,
})
this.whereIn("plrv.value", [value])
this.where(
"plr.value",
"@>",
JSON.stringify(Array.isArray(value) ? value : [value])
)
}
this.orWhere("pl.rules_count", "=", 0)
@@ -142,13 +138,13 @@ export class PricingRepository
this.andWhere(function () {
for (const [key, value] of Object.entries(context)) {
this.orWhere({
"rt.rule_attribute": key,
"pr.attribute": key,
"pr.value": value,
})
}
this.andWhere("price1.rules_count", ">", 0)
this.andWhere("price.rules_count", ">", 0)
})
this.orWhere("price1.rules_count", "=", 0)
this.orWhere("price.rules_count", "=", 0)
})
})
})
@@ -163,7 +159,6 @@ export class PricingRepository
min_quantity: "price.min_quantity",
max_quantity: "price.max_quantity",
currency_code: "price.currency_code",
default_priority: "rt.default_priority",
rules_count: "price.rules_count",
pl_rules_count: "price.pl_rules_count",
price_list_type: "price.pl_type",
@@ -171,7 +166,6 @@ export class PricingRepository
})
.join(priceSubQueryKnex.as("price"), "price.price_set_id", "ps.id")
.leftJoin("price_rule as pr", "pr.price_id", "price.id")
.leftJoin("rule_type as rt", "rt.id", "pr.rule_type_id")
.whereIn("ps.id", pricingFilters.id)
.andWhere("price.currency_code", "=", currencyCode)
@@ -179,7 +173,6 @@ export class PricingRepository
{ column: "price.has_price_list", order: "asc" },
{ column: "amount", order: "asc" },
{ column: "rules_count", order: "desc" },
{ column: "default_priority", order: "desc" },
])
if (quantity) {
@@ -1,3 +1 @@
export { default as PriceListService } from "./price-list"
export { default as PricingModuleService } from "./pricing-module"
export { default as RuleTypeService } from "./rule-type"
@@ -1,67 +0,0 @@
import { Context, DAL } from "@medusajs/types"
import { GetIsoStringFromDate, ModulesSdkUtils } from "@medusajs/utils"
import { PriceList } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceListRepository: DAL.RepositoryService
}
export default class PriceListService extends ModulesSdkUtils.MedusaInternalService<InjectedDependencies>(
PriceList
)<PriceList> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
create(
data: ServiceTypes.CreatePriceListDTO[],
sharedContext?: Context
): Promise<PriceList[]>
create(
data: ServiceTypes.CreatePriceListDTO,
sharedContext?: Context
): Promise<PriceList>
async create(
data: ServiceTypes.CreatePriceListDTO | ServiceTypes.CreatePriceListDTO[],
sharedContext?: Context
): Promise<PriceList | PriceList[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceLists = this.normalizePriceListDate(data_)
return await super.create(priceLists, sharedContext)
}
// @ts-ignore
update(data: any[], sharedContext?: Context): Promise<PriceList[]>
// @ts-ignore
update(data: any, sharedContext?: Context): Promise<PriceList>
// TODO: Add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data: ServiceTypes.UpdatePriceListDTO | ServiceTypes.UpdatePriceListDTO[],
sharedContext?: Context
): Promise<PriceList | PriceList[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceLists = this.normalizePriceListDate(data_)
return await super.update(priceLists, sharedContext)
}
protected normalizePriceListDate(
data: (ServiceTypes.UpdatePriceListDTO | ServiceTypes.CreatePriceListDTO)[]
) {
return data.map((priceListData: any) => {
if (!!priceListData.starts_at) {
priceListData.starts_at = GetIsoStringFromDate(priceListData.starts_at)
}
if (!!priceListData.ends_at) {
priceListData.ends_at = GetIsoStringFromDate(priceListData.ends_at)
}
return priceListData
})
}
}
File diff suppressed because it is too large Load Diff
@@ -1,66 +0,0 @@
import { Context, DAL, PricingTypes } from "@medusajs/types"
import {
InjectTransactionManager,
MedusaContext,
ModulesSdkUtils,
validateRuleAttributes,
} from "@medusajs/utils"
import { RuleType } from "@models"
type InjectedDependencies = {
ruleTypeRepository: DAL.RepositoryService
}
export default class RuleTypeService extends ModulesSdkUtils.MedusaInternalService<InjectedDependencies>(
RuleType
)<RuleType> {
protected readonly ruleTypeRepository_: DAL.RepositoryService<RuleType>
constructor({ ruleTypeRepository }: InjectedDependencies) {
// @ts-ignore
super(...arguments)
this.ruleTypeRepository_ = ruleTypeRepository
}
create(
data: PricingTypes.CreateRuleTypeDTO,
sharedContext: Context
): Promise<RuleType>
create(
data: PricingTypes.CreateRuleTypeDTO[],
sharedContext: Context
): Promise<RuleType[]>
@InjectTransactionManager("ruleTypeRepository_")
async create(
data: PricingTypes.CreateRuleTypeDTO | PricingTypes.CreateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<RuleType | RuleType[]> {
const data_ = Array.isArray(data) ? data : [data]
validateRuleAttributes(data_.map((d) => d.rule_attribute))
return await super.create(data, sharedContext)
}
// @ts-ignore
update(
data: PricingTypes.UpdateRuleTypeDTO[],
sharedContext: Context
): Promise<RuleType[]>
// @ts-ignore
update(
data: PricingTypes.UpdateRuleTypeDTO,
sharedContext: Context
): Promise<RuleType>
@InjectTransactionManager("ruleTypeRepository_")
// TODO: add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data: PricingTypes.UpdateRuleTypeDTO | PricingTypes.UpdateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<RuleType | RuleType[]> {
const data_ = Array.isArray(data) ? data : [data]
validateRuleAttributes(data_.map((d) => d.rule_attribute))
return await super.update(data, sharedContext)
}
}
@@ -1,13 +1,12 @@
import { PriceListStatus, PriceListType } from "@medusajs/types"
import { PriceListStatus, PricingTypes } from "@medusajs/types"
export interface CreatePriceListDTO {
title: string
description: string
starts_at?: string | null
ends_at?: string | null
status?: PriceListStatus
type?: PriceListType
number_rules?: number
export interface CreatePriceListDTO extends PricingTypes.CreatePriceListDTO {
rules_count?: number
price_list_rules?: {
attribute: string
value: string
}[]
prices?: PricingTypes.CreatePriceListPriceDTO[]
}
export interface UpdatePriceListDTO {
@@ -12,12 +12,6 @@ export const eventBuilders = {
object: "price_set",
eventsEnum: PricingEvents,
}),
createdPriceSetRuleType: eventBuilderFactory({
source: Modules.PRICING,
action: CommonEvents.CREATED,
object: "price_set_rule_type",
eventsEnum: PricingEvents,
}),
createdPrice: eventBuilderFactory({
source: Modules.PRICING,
action: CommonEvents.CREATED,