feat(pricing,types): price list API + price calculations with price lists (#5498)

**what:**

**PriceList Service APIs:**

- createPriceList
- updatePriceList
- addPriceListPrices
- removePriceListRules
- setPriceListRules
- deletePriceList
- listPriceLists
- listAndCountPriceLists

**Price Calculations**

- Returns prices with price list prices
- Returns a new shape with calculated and original prices


Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com>
This commit is contained in:
Riqwan Thamir
2023-11-15 20:24:29 +00:00
committed by GitHub
co-authored by Philip Korsholm
parent 2947f57db1
commit 1772e80ed1
58 changed files with 5745 additions and 1112 deletions
@@ -42,20 +42,22 @@ describe("MoneyAmount Service", () => {
it("should list all moneyAmounts", async () => {
const moneyAmountsResult = await service.list()
expect(moneyAmountsResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
amount: "500",
}),
expect.objectContaining({
id: "money-amount-EUR",
amount: "400",
}),
expect.objectContaining({
id: "money-amount-CAD",
amount: "600",
}),
])
expect(JSON.parse(JSON.stringify(moneyAmountsResult))).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: "money-amount-USD",
amount: 500,
}),
expect.objectContaining({
id: "money-amount-EUR",
amount: 400,
}),
expect.objectContaining({
id: "money-amount-CAD",
amount: 600,
}),
])
)
})
it("should list moneyAmounts by id", async () => {
@@ -63,7 +65,7 @@ describe("MoneyAmount Service", () => {
id: ["money-amount-USD"],
})
expect(moneyAmountsResult).toEqual([
expect(JSON.parse(JSON.stringify(moneyAmountsResult))).toEqual([
expect.objectContaining({
id: "money-amount-USD",
}),
@@ -76,7 +78,7 @@ describe("MoneyAmount Service", () => {
id: ["money-amount-USD"],
},
{
select: ["id", "min_quantity", "currency.code"],
select: ["id", "min_quantity", "currency.code", "amount"],
relations: ["currency"],
}
)
@@ -86,6 +88,7 @@ describe("MoneyAmount Service", () => {
expect(serialized).toEqual([
{
id: "money-amount-USD",
amount: 500,
min_quantity: "1",
currency_code: "USD",
currency: {
@@ -101,7 +104,7 @@ describe("MoneyAmount Service", () => {
currency_code: ["USD"],
},
{
select: ["id", "min_quantity", "currency.code"],
select: ["id", "min_quantity", "currency.code", "amount"],
relations: ["currency"],
}
)
@@ -113,6 +116,7 @@ describe("MoneyAmount Service", () => {
id: "money-amount-USD",
min_quantity: "1",
currency_code: "USD",
amount: 500,
currency: {
code: "USD",
},
@@ -126,17 +130,19 @@ describe("MoneyAmount Service", () => {
const [moneyAmountsResult, count] = await service.listAndCount()
expect(count).toEqual(3)
expect(moneyAmountsResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
}),
expect.objectContaining({
id: "money-amount-EUR",
}),
expect.objectContaining({
id: "money-amount-CAD",
}),
])
expect(JSON.parse(JSON.stringify(moneyAmountsResult))).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: "money-amount-USD",
}),
expect.objectContaining({
id: "money-amount-EUR",
}),
expect.objectContaining({
id: "money-amount-CAD",
}),
])
)
})
it("should return moneyAmounts and count when filtered", async () => {
@@ -158,7 +164,7 @@ describe("MoneyAmount Service", () => {
id: ["money-amount-USD"],
},
{
select: ["id", "min_quantity", "currency.code"],
select: ["id", "min_quantity", "currency.code", "amount"],
relations: ["currency"],
}
)
@@ -169,6 +175,7 @@ describe("MoneyAmount Service", () => {
expect(serialized).toEqual([
{
id: "money-amount-USD",
amount: 500,
min_quantity: "1",
currency_code: "USD",
currency: {
@@ -197,7 +204,7 @@ describe("MoneyAmount Service", () => {
{},
{
take: 1,
select: ["id"],
select: ["id", "amount"],
}
)
@@ -207,6 +214,7 @@ describe("MoneyAmount Service", () => {
expect(serialized).toEqual([
{
id: "money-amount-USD",
amount: 500,
},
])
})
@@ -214,7 +222,7 @@ describe("MoneyAmount Service", () => {
describe("retrieve", () => {
const id = "money-amount-USD"
const amount = "500"
const amount = 500
it("should return moneyAmount for the given id", async () => {
const moneyAmount = await service.retrieve(id)
@@ -291,9 +299,9 @@ describe("MoneyAmount Service", () => {
},
])
const moneyAmount = await service.retrieve(id)
const moneyAmount = JSON.parse(JSON.stringify(await service.retrieve(id)))
expect(moneyAmount.amount).toEqual("700")
expect(moneyAmount.amount).toEqual(700)
})
it("should update the currency of the moneyAmount successfully", async () => {
@@ -346,11 +354,11 @@ describe("MoneyAmount Service", () => {
id: ["money-amount-TESM"],
})
expect(moneyAmount).toEqual(
expect(JSON.parse(JSON.stringify(moneyAmount))).toEqual(
expect.objectContaining({
id: "money-amount-TESM",
currency_code: "USD",
amount: "333",
amount: 333,
min_quantity: "1",
max_quantity: "4",
})
@@ -0,0 +1,243 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceListRuleRepository } from "@repositories"
import { PriceListRuleService } from "@services"
import { createPriceLists } from "../../../__fixtures__/price-list"
import { createPriceListRules } from "../../../__fixtures__/price-list-rules"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
describe("PriceListRule Service", () => {
let service: PriceListRuleService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
const priceListRuleRepository = new PriceListRuleRepository({
manager: repositoryManager,
})
service = new PriceListRuleService({
priceListRuleRepository,
})
testManager = await MikroOrmWrapper.forkManager()
await createRuleTypes(testManager)
await createPriceLists(testManager)
await createPriceListRules(testManager)
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("list", () => {
it("should list all priceListRules", async () => {
const priceListRuleResult = await service.list()
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
expect.objectContaining({
id: "price-list-rule-2",
}),
])
})
it("should list priceListRules scoped by priceListRule id", async () => {
const priceListRuleResult = await service.list({
id: ["price-list-rule-1"],
})
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
])
})
})
describe("listAndCount", () => {
it("should return pricelistrules and count", async () => {
const [priceListRuleResult, count] = await service.listAndCount()
expect(count).toEqual(2)
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
expect.objectContaining({
id: "price-list-rule-2",
}),
])
})
it("should return pricelistrules and count when filtered", async () => {
const [priceListRuleResult, count] = await service.listAndCount({
id: ["price-list-rule-1"],
})
expect(count).toEqual(1)
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
])
})
it("should return pricelistrules and count when using skip and take", async () => {
const [priceListRuleResult, count] = await service.listAndCount(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-2",
}),
])
})
it("should return requested fields", async () => {
const [priceListRuleResult, count] = await service.listAndCount(
{},
{
take: 1,
select: ["id"],
}
)
const serialized = JSON.parse(JSON.stringify(priceListRuleResult))
expect(count).toEqual(2)
expect(serialized).toEqual([
{
id: "price-list-rule-1",
},
])
})
})
describe("retrieve", () => {
const id = "price-list-rule-1"
it("should return priceList for the given id", async () => {
const priceListRuleResult = await service.retrieve(id)
expect(priceListRuleResult).toEqual(
expect.objectContaining({
id,
})
)
})
it("should throw an error when priceListRule with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"PriceListRule with id: does-not-exist was not found"
)
})
it("should throw an error when a id is not provided", async () => {
let error
try {
await service.retrieve(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual('"priceListRuleId" must be defined')
})
})
describe("delete", () => {
const id = "price-list-rule-1"
it("should delete the pricelists given an id successfully", async () => {
await service.delete([id])
const priceListResult = await service.list({
id: [id],
})
expect(priceListResult).toHaveLength(0)
})
})
describe("update", () => {
const id = "price-list-rule-2"
it("should update the value of the priceListRule successfully", async () => {
await service.update([
{
id,
price_list_id: "price-list-1",
},
])
const priceList = await service.retrieve(id, {
relations: ["price_list"],
})
expect(priceList.price_list.id).toEqual("price-list-1")
})
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'PriceListRule with id(s) "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a priceListRule successfully", async () => {
const [created] = await service.create([
{
price_list_id: "price-list-2",
rule_type_id: "rule-type-1",
},
])
const [priceListRule] = await service.list(
{
id: [created.id],
},
{
relations: ["price_list", "rule_type"],
select: ["price_list.id", "rule_type.id"],
}
)
expect(priceListRule.price_list.id).toEqual("price-list-2")
expect(priceListRule.rule_type.id).toEqual("rule-type-1")
})
})
})
@@ -1,37 +1,31 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Currency, MoneyAmount } from "@models"
import { MoneyAmountRepository } from "@repositories"
import { MoneyAmountService } from "@services"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import { PriceListRepository } from "@repositories"
import { PriceListService } from "@services"
import { MikroOrmWrapper } from "../../../utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { createPriceLists } from "../../../__fixtures__/price-list"
jest.setTimeout(30000)
describe("MoneyAmount Service", () => {
let service: MoneyAmountService
describe("PriceList Service", () => {
let service: PriceListService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let data!: MoneyAmount[]
let currencyData!: Currency[]
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
const moneyAmountRepository = new MoneyAmountRepository({
const priceListRepository = new PriceListRepository({
manager: repositoryManager,
})
service = new MoneyAmountService({
moneyAmountRepository,
service = new PriceListService({
priceListRepository,
})
testManager = await MikroOrmWrapper.forkManager()
currencyData = await createCurrencies(testManager)
data = await createMoneyAmounts(testManager)
await createPriceLists(testManager)
})
afterEach(async () => {
@@ -39,136 +33,76 @@ describe("MoneyAmount Service", () => {
})
describe("list", () => {
it("list moneyAmounts", async () => {
const moneyAmountsResult = await service.list()
it("should return list priceLists", async () => {
const priceListResult = await service.list()
expect(moneyAmountsResult).toEqual([
expect(priceListResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
amount: "500",
id: "price-list-1",
}),
expect.objectContaining({
id: "money-amount-EUR",
amount: "400",
}),
expect.objectContaining({
id: "money-amount-CAD",
amount: "600",
id: "price-list-2",
}),
])
})
it("list moneyAmounts by id", async () => {
const moneyAmountsResult = await service.list({
id: ["money-amount-USD"],
it("should list pricelists by id", async () => {
const priceListResult = await service.list({
id: ["price-list-1"],
})
expect(moneyAmountsResult).toEqual([
expect(priceListResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
id: "price-list-1",
}),
])
})
it("list moneyAmounts with relations and selects", async () => {
const moneyAmountsResult = await service.list(
{
id: ["money-amount-USD"],
},
{
select: ["id", "min_quantity", "currency.code"],
relations: ["currency"],
}
)
const serialized = JSON.parse(JSON.stringify(moneyAmountsResult))
expect(serialized).toEqual([
{
id: "money-amount-USD",
min_quantity: "1",
currency_code: "USD",
currency: {
code: "USD",
},
},
])
})
})
describe("listAndCount", () => {
it("should return moneyAmounts and count", async () => {
const [moneyAmountsResult, count] = await service.listAndCount()
it("should return pricelists and count", async () => {
const [priceListResult, count] = await service.listAndCount()
expect(count).toEqual(3)
expect(moneyAmountsResult).toEqual([
expect(count).toEqual(2)
expect(priceListResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
id: "price-list-1",
}),
expect.objectContaining({
id: "money-amount-EUR",
}),
expect.objectContaining({
id: "money-amount-CAD",
id: "price-list-2",
}),
])
})
it("should return moneyAmounts and count when filtered", async () => {
const [moneyAmountsResult, count] = await service.listAndCount({
id: ["money-amount-USD"],
it("should return pricelists and count when filtered", async () => {
const [priceListResult, count] = await service.listAndCount({
id: ["price-list-1"],
})
expect(count).toEqual(1)
expect(moneyAmountsResult).toEqual([
expect(priceListResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
id: "price-list-1",
}),
])
})
it("list moneyAmounts with relations and selects", async () => {
const [moneyAmountsResult, count] = await service.listAndCount(
{
id: ["money-amount-USD"],
},
{
select: ["id", "min_quantity", "currency.code"],
relations: ["currency"],
}
)
const serialized = JSON.parse(JSON.stringify(moneyAmountsResult))
expect(count).toEqual(1)
expect(serialized).toEqual([
{
id: "money-amount-USD",
min_quantity: "1",
currency_code: "USD",
currency: {
code: "USD",
},
},
])
})
it("should return moneyAmounts and count when using skip and take", async () => {
const [moneyAmountsResult, count] = await service.listAndCount(
it("should return pricelists and count when using skip and take", async () => {
const [priceListResult, count] = await service.listAndCount(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(3)
expect(moneyAmountsResult).toEqual([
expect(count).toEqual(2)
expect(priceListResult).toEqual([
expect.objectContaining({
id: "money-amount-EUR",
id: "price-list-2",
}),
])
})
it("should return requested fields", async () => {
const [moneyAmountsResult, count] = await service.listAndCount(
const [priceListResult, count] = await service.listAndCount(
{},
{
take: 1,
@@ -176,32 +110,31 @@ describe("MoneyAmount Service", () => {
}
)
const serialized = JSON.parse(JSON.stringify(moneyAmountsResult))
const serialized = JSON.parse(JSON.stringify(priceListResult))
expect(count).toEqual(3)
expect(count).toEqual(2)
expect(serialized).toEqual([
{
id: "money-amount-USD",
id: "price-list-1",
},
])
})
})
describe("retrieve", () => {
const id = "money-amount-USD"
const amount = "500"
const id = "price-list-1"
it("should return moneyAmount for the given id", async () => {
const moneyAmount = await service.retrieve(id)
it("should return priceList for the given id", async () => {
const priceListResult = await service.retrieve(id)
expect(moneyAmount).toEqual(
expect(priceListResult).toEqual(
expect.objectContaining({
id,
})
)
})
it("should throw an error when moneyAmount with id does not exist", async () => {
it("should throw an error when priceList with id does not exist", async () => {
let error
try {
@@ -211,7 +144,7 @@ describe("MoneyAmount Service", () => {
}
expect(error.message).toEqual(
"MoneyAmount with id: does-not-exist was not found"
"PriceList with id: does-not-exist was not found"
)
})
@@ -224,65 +157,39 @@ describe("MoneyAmount Service", () => {
error = e
}
expect(error.message).toEqual('"moneyAmountId" must be defined')
})
it("should return moneyAmount based on config select param", async () => {
const moneyAmount = await service.retrieve(id, {
select: ["id", "amount"],
})
const serialized = JSON.parse(JSON.stringify(moneyAmount))
expect(serialized).toEqual({
id,
amount,
})
expect(error.message).toEqual('"priceListId" must be defined')
})
})
describe("delete", () => {
const id = "money-amount-USD"
const id = "price-list-1"
it("should delete the moneyAmounts given an id successfully", async () => {
it("should delete the pricelists given an id successfully", async () => {
await service.delete([id])
const moneyAmounts = await service.list({
const priceListResult = await service.list({
id: [id],
})
expect(moneyAmounts).toHaveLength(0)
expect(priceListResult).toHaveLength(0)
})
})
describe("update", () => {
const id = "money-amount-USD"
const id = "price-list-2"
it("should update the amount of the moneyAmount successfully", async () => {
it("should update the starts_at date of the priceList successfully", async () => {
const updateDate = new Date()
await service.update([
{
id,
amount: 700,
starts_at: updateDate.toISOString(),
},
])
const moneyAmount = await service.retrieve(id)
const priceList = await service.retrieve(id)
expect(moneyAmount.amount).toEqual("700")
})
it("should update the currency of the moneyAmount successfully", async () => {
await service.update([
{
id,
currency_code: "EUR",
},
])
const moneyAmount = await service.retrieve(id)
expect(moneyAmount.currency_code).toEqual("EUR")
expect(moneyAmount.currency?.code).toEqual("EUR")
expect(priceList.starts_at).toEqual(updateDate)
})
it("should throw an error when a id does not exist", async () => {
@@ -292,7 +199,6 @@ describe("MoneyAmount Service", () => {
await service.update([
{
id: "does-not-exist",
amount: 666,
},
])
} catch (e) {
@@ -300,36 +206,25 @@ describe("MoneyAmount Service", () => {
}
expect(error.message).toEqual(
'MoneyAmount with id "does-not-exist" not found'
'PriceList with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a moneyAmount successfully", async () => {
await service.create([
it("should create a priceList successfully", async () => {
const [created] = await service.create([
{
id: "money-amount-TESM",
currency_code: "USD",
amount: 333,
min_quantity: 1,
max_quantity: 4,
title: "test",
description: "test",
},
])
const [moneyAmount] = await service.list({
id: ["money-amount-TESM"],
const [priceList] = await service.list({
id: [created.id],
})
expect(moneyAmount).toEqual(
expect.objectContaining({
id: "money-amount-TESM",
currency_code: "USD",
amount: "333",
min_quantity: "1",
max_quantity: "4",
})
)
expect(priceList.title).toEqual("test")
})
})
})
@@ -124,9 +124,9 @@ describe("PriceSet Service", () => {
{
id: "price-set-1",
money_amounts: [
{
expect.objectContaining({
id: "money-amount-USD",
},
}),
],
},
])
@@ -151,9 +151,9 @@ describe("PriceSet Service", () => {
{
id: "price-set-1",
money_amounts: [
{
expect.objectContaining({
id: "money-amount-USD",
},
}),
],
},
])
@@ -227,9 +227,9 @@ describe("PriceSet Service", () => {
{
id: "price-set-1",
money_amounts: [
{
expect.objectContaining({
id: "money-amount-USD",
},
}),
],
},
])
@@ -42,20 +42,22 @@ describe("PricingModule Service - MoneyAmount", () => {
it("list moneyAmounts", async () => {
const moneyAmountsResult = await service.listMoneyAmounts()
expect(moneyAmountsResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
amount: "500",
}),
expect.objectContaining({
id: "money-amount-EUR",
amount: "400",
}),
expect.objectContaining({
id: "money-amount-CAD",
amount: "600",
}),
])
expect(moneyAmountsResult).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: "money-amount-USD",
amount: 500,
}),
expect.objectContaining({
id: "money-amount-EUR",
amount: 400,
}),
expect.objectContaining({
id: "money-amount-CAD",
amount: 600,
}),
])
)
})
it("should list moneyAmounts by id", async () => {
@@ -86,6 +88,7 @@ describe("PricingModule Service - MoneyAmount", () => {
expect(serialized).toEqual([
{
id: "money-amount-USD",
amount: null,
min_quantity: "1",
currency_code: "USD",
currency: {
@@ -102,17 +105,19 @@ describe("PricingModule Service - MoneyAmount", () => {
await service.listAndCountMoneyAmounts()
expect(count).toEqual(3)
expect(moneyAmountsResult).toEqual([
expect.objectContaining({
id: "money-amount-USD",
}),
expect.objectContaining({
id: "money-amount-EUR",
}),
expect.objectContaining({
id: "money-amount-CAD",
}),
])
expect(moneyAmountsResult).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: "money-amount-USD",
}),
expect.objectContaining({
id: "money-amount-EUR",
}),
expect.objectContaining({
id: "money-amount-CAD",
}),
])
)
})
it("should return moneyAmounts and count when filtered", async () => {
@@ -136,7 +141,7 @@ describe("PricingModule Service - MoneyAmount", () => {
id: ["money-amount-USD"],
},
{
select: ["id", "min_quantity", "currency.code"],
select: ["id", "min_quantity", "currency.code", "amount"],
relations: ["currency"],
}
)
@@ -147,6 +152,7 @@ describe("PricingModule Service - MoneyAmount", () => {
expect(serialized).toEqual([
{
id: "money-amount-USD",
amount: 500,
min_quantity: "1",
currency_code: "USD",
currency: {
@@ -184,6 +190,7 @@ describe("PricingModule Service - MoneyAmount", () => {
expect(serialized).toEqual([
{
id: "money-amount-USD",
amount: null,
},
])
})
@@ -191,7 +198,7 @@ describe("PricingModule Service - MoneyAmount", () => {
describe("retrieveMoneyAmount", () => {
const id = "money-amount-USD"
const amount = "500"
const amount = 500
it("should return moneyAmount for the given id", async () => {
const moneyAmount = await service.retrieveMoneyAmount(id)
@@ -268,9 +275,13 @@ describe("PricingModule Service - MoneyAmount", () => {
},
])
const moneyAmount = await service.retrieveMoneyAmount(id)
const moneyAmount = JSON.parse(
JSON.stringify(
await service.retrieveMoneyAmount(id, { select: ["amount"] })
)
)
expect(moneyAmount.amount).toEqual("700")
expect(moneyAmount.amount).toEqual(700)
})
it("should update the currency of the moneyAmount successfully", async () => {
@@ -329,7 +340,7 @@ describe("PricingModule Service - MoneyAmount", () => {
expect.objectContaining({
id: "money-amount-TESM",
currency_code: "USD",
amount: "333",
amount: 333,
min_quantity: "1",
max_quantity: "4",
})
@@ -0,0 +1,348 @@
import { DB_URL, MikroOrmWrapper } from "../../../utils"
import { IPricingModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { initialize } from "../../../../src"
import { createPriceLists } from "../../../__fixtures__/price-list"
import { createPriceListRules } from "../../../__fixtures__/price-list-rules"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
jest.setTimeout(30000)
describe("PriceListRule Service", () => {
let service: IPricingModuleService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
service = await initialize({
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
testManager = await MikroOrmWrapper.forkManager()
await createRuleTypes(testManager)
await createPriceLists(testManager)
await createPriceListRules(testManager)
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("list", () => {
it("should list priceListRules", async () => {
const priceListRuleResult = await service.listPriceListRules()
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
expect.objectContaining({
id: "price-list-rule-2",
}),
])
})
it("should list priceListRules by pricelist id", async () => {
const priceListRuleResult = await service.listPriceListRules({
id: ["price-list-rule-1"],
})
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
])
})
})
describe("listAndCount", () => {
it("should return pricelistrules and count", async () => {
const [priceListRuleResult, count] =
await service.listAndCountPriceListRules()
expect(count).toEqual(2)
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
expect.objectContaining({
id: "price-list-rule-2",
}),
])
})
it("should return pricelistrules and count when filtered", async () => {
const [priceListRuleResult, count] =
await service.listAndCountPriceListRules({
id: ["price-list-rule-1"],
})
expect(count).toEqual(1)
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-1",
}),
])
})
it("should return pricelistrules and count when using skip and take", async () => {
const [priceListRuleResult, count] =
await service.listAndCountPriceListRules({}, { skip: 1, take: 1 })
expect(count).toEqual(2)
expect(priceListRuleResult).toEqual([
expect.objectContaining({
id: "price-list-rule-2",
}),
])
})
it("should return requested fields", async () => {
const [priceListRuleResult, count] =
await service.listAndCountPriceListRules(
{},
{
take: 1,
select: ["id"],
}
)
const serialized = JSON.parse(JSON.stringify(priceListRuleResult))
expect(count).toEqual(2)
expect(serialized).toEqual([
{
id: "price-list-rule-1",
},
])
})
})
describe("retrieve", () => {
const id = "price-list-rule-1"
it("should return priceList for the given id", async () => {
const priceListRuleResult = await service.retrievePriceListRule(id)
expect(priceListRuleResult).toEqual(
expect.objectContaining({
id,
})
)
})
it("should throw an error when priceListRule with id does not exist", async () => {
let error
try {
await service.retrievePriceListRule("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"PriceListRule with id: does-not-exist was not found"
)
})
it("should throw an error when a id is not provided", async () => {
let error
try {
await service.retrievePriceListRule(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual('"priceListRuleId" must be defined')
})
})
describe("delete", () => {
const id = "price-list-rule-1"
it("should delete the pricelists given an id successfully", async () => {
await service.deletePriceListRules([id])
const priceListResult = await service.listPriceListRules({
id: [id],
})
expect(priceListResult).toHaveLength(0)
})
})
describe("update", () => {
const id = "price-list-rule-2"
it("should update the value of the priceListRule successfully", async () => {
await service.updatePriceListRules([
{
id,
price_list_id: "price-list-2",
rule_type_id: "rule-type-2",
},
])
const priceList = await service.retrievePriceListRule(id, {
relations: ["price_list", "rule_type"],
})
expect(priceList.price_list.id).toEqual("price-list-2")
expect(priceList.rule_type.id).toEqual("rule-type-2")
})
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.updatePriceListRules([
{
id: "does-not-exist",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'PriceListRule with id(s) "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a priceListRule successfully", async () => {
const [created] = await service.createPriceListRules([
{
price_list_id: "price-list-2",
rule_type_id: "rule-type-2",
},
])
const [priceListRule] = await service.listPriceListRules(
{
id: [created.id],
},
{
relations: ["price_list", "rule_type"],
}
)
expect(priceListRule.price_list.id).toEqual("price-list-2")
expect(priceListRule.rule_type.id).toEqual("rule-type-2")
})
})
describe("setPriceListRules", () => {
it("should add a priceListRule to a priceList", async () => {
await createRuleTypes(testManager, [
{
id: "rule-type-3",
name: "test",
rule_attribute: "sales_channel",
},
])
await service.setPriceListRules({
priceListId: "price-list-1",
rules: {
sales_channel: "sc-1",
},
})
const [priceList] = await service.listPriceLists(
{
id: ["price-list-1"],
},
{
relations: [
"price_list_rules",
"price_list_rules.price_list_rule_values",
],
}
)
expect(priceList.price_list_rules).toEqual(
expect.arrayContaining([
expect.objectContaining({
rule_type: "rule-type-3",
price_list_rule_values: [
expect.objectContaining({ 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({
priceListId: "price-list-1",
rules: {
sales_channel: ["sc-1", "sc-2"],
},
})
const [priceList] = await service.listPriceLists(
{
id: ["price-list-1"],
},
{
relations: [
"price_list_rules",
"price_list_rules.price_list_rule_values",
],
}
)
expect(priceList.price_list_rules).toEqual(
expect.arrayContaining([
expect.objectContaining({
rule_type: "rule-type-3",
price_list_rule_values: expect.arrayContaining([
expect.objectContaining({ value: "sc-1" }),
expect.objectContaining({ value: "sc-2" }),
]),
}),
])
)
})
})
describe("removePriceListRules", () => {
it("should remove a priceListRule from a priceList", async () => {
await service.removePriceListRules({
priceListId: "price-list-1",
rules: ["currency_code"],
})
const [priceList] = await service.listPriceLists(
{
id: ["price-list-1"],
},
{
relations: ["price_list_rules"],
}
)
expect(priceList.price_list_rules).toEqual([
expect.objectContaining({ rule_type: "rule-type-2" }),
])
})
})
})
@@ -0,0 +1,397 @@
import { IPricingModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { initialize } from "../../../../src"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createPriceLists } from "../../../__fixtures__/price-list"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { DB_URL, MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
describe("PriceList Service", () => {
let service: IPricingModuleService
let testManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
await MikroOrmWrapper.forkManager()
service = await initialize({
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
testManager = await MikroOrmWrapper.forkManager()
await createCurrencies(testManager)
await createPriceSets(testManager)
await createPriceLists(testManager)
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("list", () => {
it("list priceLists", async () => {
const priceListResult = await service.listPriceLists()
expect(priceListResult).toEqual([
expect.objectContaining({
id: "price-list-1",
}),
expect.objectContaining({
id: "price-list-2",
}),
])
})
it("list pricelists by id", async () => {
const priceListResult = await service.listPriceLists({
id: ["price-list-1"],
})
expect(priceListResult).toEqual([
expect.objectContaining({
id: "price-list-1",
}),
])
})
})
describe("listAndCount", () => {
it("should return pricelists and count", async () => {
const [priceListResult, count] = await service.listAndCountPriceLists()
expect(count).toEqual(2)
expect(priceListResult).toEqual([
expect.objectContaining({
id: "price-list-1",
}),
expect.objectContaining({
id: "price-list-2",
}),
])
})
it("should return pricelists and count when filtered", async () => {
const [priceListResult, count] = await service.listAndCountPriceLists({
id: ["price-list-1"],
})
expect(count).toEqual(1)
expect(priceListResult).toEqual([
expect.objectContaining({
id: "price-list-1",
}),
])
})
it("should return pricelists and count when using skip and take", async () => {
const [priceListResult, count] = await service.listAndCountPriceLists(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(priceListResult).toEqual([
expect.objectContaining({
id: "price-list-2",
}),
])
})
it("should return requested fields", async () => {
const [priceListResult, count] = await service.listAndCountPriceLists(
{},
{
take: 1,
select: ["id"],
}
)
const serialized = JSON.parse(JSON.stringify(priceListResult))
expect(count).toEqual(2)
expect(serialized).toEqual([
{
id: "price-list-1",
},
])
})
})
describe("retrieve", () => {
const id = "price-list-1"
it("should return priceList for the given id", async () => {
const priceListResult = await service.retrievePriceList(id)
expect(priceListResult).toEqual(
expect.objectContaining({
id,
})
)
})
it("should throw an error when priceList with id does not exist", async () => {
let error
try {
await service.retrievePriceList("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"PriceList with id: does-not-exist was not found"
)
})
it("should throw an error when a id is not provided", async () => {
let error
try {
await service.retrievePriceList(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual('"priceListId" must be defined')
})
})
describe("delete", () => {
const id = "price-list-1"
it("should delete the pricelists given an id successfully", async () => {
await service.deletePriceLists([id])
const priceListResult = await service.listPriceLists({
id: [id],
})
expect(priceListResult).toHaveLength(0)
})
})
describe("update", () => {
const id = "price-list-2"
it("should update the starts_at date of the priceList successfully", async () => {
const [created] = await service.createPriceLists([
{
title: "test",
description: "test",
starts_at: "10/01/2023",
ends_at: "10/30/2023",
rules: {
customer_group_id: [
"vip-customer-group-id",
"another-vip-customer-group-id",
],
region_id: ["DE", "DK"],
},
prices: [
{
amount: 400,
currency_code: "EUR",
price_set_id: "price-set-1",
},
],
},
])
const updateDate = new Date()
await service.updatePriceLists([
{
id: created.id,
starts_at: updateDate.toISOString(),
rules: {
new_rule: ["new-rule-value"],
},
},
])
const [priceList] = await service.listPriceLists(
{
id: [created.id],
},
{
relations: [
"price_set_money_amounts.money_amount",
"price_set_money_amounts.price_set",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
],
select: [
"id",
"starts_at",
"price_set_money_amounts.money_amount.amount",
"price_set_money_amounts.money_amount.currency_code",
"price_set_money_amounts.money_amount.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
],
}
)
expect(priceList).toEqual(
expect.objectContaining({
id: expect.any(String),
starts_at: updateDate,
price_set_money_amounts: expect.arrayContaining([
expect.objectContaining({
price_list: expect.objectContaining({
id: expect.any(String),
}),
money_amount: expect.objectContaining({
amount: 400,
currency_code: "EUR",
}),
}),
]),
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",
}),
],
}),
]),
})
)
})
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.updatePriceLists([
{
id: "does-not-exist",
number_rules: 2,
rules: {},
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'PriceList with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a priceList successfully", async () => {
const [created] = await service.createPriceLists([
{
title: "test",
description: "test",
starts_at: "10/01/2023",
ends_at: "10/30/2023",
rules: {
customer_group_id: [
"vip-customer-group-id",
"another-vip-customer-group-id",
],
region_id: ["DE", "DK"],
},
prices: [
{
amount: 400,
currency_code: "EUR",
price_set_id: "price-set-1",
},
],
},
])
const [priceList] = await service.listPriceLists(
{
id: [created.id],
},
{
relations: [
"price_set_money_amounts.money_amount",
"price_set_money_amounts.price_set",
"price_list_rules.price_list_rule_values",
"price_list_rules.rule_type",
],
select: [
"id",
"price_set_money_amounts.money_amount.amount",
"price_set_money_amounts.money_amount.currency_code",
"price_set_money_amounts.money_amount.price_list_id",
"price_list_rules.price_list_rule_values.value",
"price_list_rules.rule_type.rule_attribute",
],
}
)
expect(priceList).toEqual(
expect.objectContaining({
id: expect.any(String),
price_set_money_amounts: expect.arrayContaining([
expect.objectContaining({
price_list: expect.objectContaining({
id: expect.any(String),
}),
money_amount: expect.objectContaining({
amount: 400,
currency_code: "EUR",
}),
}),
]),
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",
}),
]),
}),
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",
}),
]),
}),
]),
})
)
})
})
})
@@ -106,7 +106,9 @@ describe("PricingModule Service - PriceSet", () => {
expect(serialized).toEqual([
{
id: "price-set-1",
money_amounts: [{ id: "money-amount-USD", amount: "500" }],
money_amounts: [
expect.objectContaining({ id: "money-amount-USD", amount: 500 }),
],
},
])
})
@@ -160,7 +162,7 @@ describe("PricingModule Service - PriceSet", () => {
expect(serialized).toEqual([
{
id: "price-set-1",
money_amounts: [{ id: "money-amount-USD" }],
money_amounts: [expect.objectContaining({ id: "money-amount-USD" })],
},
])
})
@@ -375,7 +377,7 @@ describe("PricingModule Service - PriceSet", () => {
],
money_amounts: [
expect.objectContaining({
amount: "100",
amount: 100,
currency_code: "USD",
}),
],
@@ -413,11 +415,11 @@ describe("PricingModule Service - PriceSet", () => {
],
money_amounts: expect.arrayContaining([
expect.objectContaining({
amount: "100",
amount: 100,
currency_code: "USD",
}),
expect.objectContaining({
amount: "150",
amount: 150,
currency_code: "USD",
}),
]),
@@ -450,7 +452,7 @@ describe("PricingModule Service - PriceSet", () => {
],
money_amounts: [
expect.objectContaining({
amount: "100",
amount: 100,
currency_code: "USD",
}),
],
@@ -544,7 +546,7 @@ describe("PricingModule Service - PriceSet", () => {
],
money_amounts: [
expect.objectContaining({
amount: "500",
amount: 500,
currency_code: "EUR",
}),
],
@@ -608,7 +610,7 @@ describe("PricingModule Service - PriceSet", () => {
id: "price-set-1",
money_amounts: expect.arrayContaining([
expect.objectContaining({
amount: "100",
amount: 100,
currency_code: "USD",
}),
]),
@@ -650,7 +652,7 @@ describe("PricingModule Service - PriceSet", () => {
id: "price-set-1",
money_amounts: expect.arrayContaining([
expect.objectContaining({
amount: "100",
amount: 100,
currency_code: "USD",
}),
]),
@@ -659,7 +661,7 @@ describe("PricingModule Service - PriceSet", () => {
id: "price-set-2",
money_amounts: expect.arrayContaining([
expect.objectContaining({
amount: "150",
amount: 150,
currency_code: "EUR",
}),
]),