feat(pricing) Add Price Set Rule Type (#4977)
* initial * initial service * update pricing module service * add integration test for rule-type * update pricing-module integration tests * update pricing service interface * feat(pricing): PriceSets as entry point to pricing module * chore: add price set money amount * chore: add price set money amount * chore: change name of test * chore: added changeset * chore: use filterable props from money amount in price sets * chore: update migrations * test update integration test * fix weird behavior * Update packages/pricing/integration-tests/__fixtures__/rule-type/index.ts Co-authored-by: Riqwan Thamir <rmthamir@gmail.com> * Apply suggestions from code review Co-authored-by: Riqwan Thamir <rmthamir@gmail.com> * move rule-type to common * chore: reset migration * chore: remove incorrect conflicts * chore: address review * chore: remove ghost price list * Apply suggestions from code review Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> * update id prefix * use persist not persistAndflush * rename key_value to rule_attribute * more renaming --------- Co-authored-by: Riqwan Thamir <rmthamir@gmail.com> Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
22 files changed
+1120
-86
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/pricing": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(pricing,types): Add price set rule type
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
|
|
||||||
export const defaultPriceListData = [
|
|
||||||
{
|
|
||||||
name: 'pl-1',
|
|
||||||
description: 'pl-1',
|
|
||||||
prices: [ {
|
|
||||||
id: "money-amount-USD",
|
|
||||||
currency_code: "USD",
|
|
||||||
amount: 500,
|
|
||||||
min_quantity: 1,
|
|
||||||
max_quantity: 10,
|
|
||||||
price_list_id: 'pl-1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "money-amount-EUR",
|
|
||||||
currency_code: "EUR",
|
|
||||||
amount: 400,
|
|
||||||
min_quantity: 1,
|
|
||||||
max_quantity: 5,
|
|
||||||
price_list_id: 'pl-1'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'pl-2',
|
|
||||||
name: 'pl-2',
|
|
||||||
description: 'pl-2',
|
|
||||||
prices: [{
|
|
||||||
id: "money-amount-CAD",
|
|
||||||
currency_code: "CAD",
|
|
||||||
amount: 600,
|
|
||||||
min_quantity: 1,
|
|
||||||
max_quantity: 8,
|
|
||||||
price_list_id: 'pl-2'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
|
||||||
import { MoneyAmount, PriceList } from "@models"
|
|
||||||
import { defaultPriceListData } from "./data"
|
|
||||||
|
|
||||||
export async function createPriceLists(
|
|
||||||
manager: SqlEntityManager,
|
|
||||||
priceListsData: any[] = defaultPriceListData,
|
|
||||||
): Promise<MoneyAmount[]> {
|
|
||||||
const priceLists: PriceList[] = []
|
|
||||||
const moneyAmounts: MoneyAmount[] = []
|
|
||||||
|
|
||||||
for (let priceListdata of priceListsData) {
|
|
||||||
const { prices, ...rest } = priceListdata
|
|
||||||
const priceList = manager.create(MoneyAmount, rest)
|
|
||||||
priceLists.push(priceList)
|
|
||||||
|
|
||||||
const createdPrices = manager.create(MoneyAmount, prices)
|
|
||||||
moneyAmounts.push(createdPrices)
|
|
||||||
}
|
|
||||||
|
|
||||||
await manager.persistAndFlush(priceLists)
|
|
||||||
await manager.persistAndFlush(moneyAmounts)
|
|
||||||
|
|
||||||
return priceLists
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export const defaultRuleTypesData = [
|
||||||
|
{
|
||||||
|
id: "rule-type-1",
|
||||||
|
name: "rule 1",
|
||||||
|
rule_attribute: "region_id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "rule-type-2",
|
||||||
|
name: "rule 2",
|
||||||
|
rule_attribute: "currency_code",
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
import { RuleType } from "@models"
|
||||||
|
import { defaultRuleTypesData } 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
|
||||||
|
}
|
||||||
+252
@@ -0,0 +1,252 @@
|
|||||||
|
import { IPricingModuleService } from "@medusajs/types"
|
||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
|
||||||
|
import { initialize } from "../../../../src"
|
||||||
|
import { createRuleTypes } from "../../../__fixtures__/rule-type"
|
||||||
|
import { DB_URL, MikroOrmWrapper } from "../../../utils"
|
||||||
|
|
||||||
|
describe("PricingModuleService ruleType", () => {
|
||||||
|
let service: IPricingModuleService
|
||||||
|
let testManager: SqlEntityManager
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await MikroOrmWrapper.setupDatabase()
|
||||||
|
MikroOrmWrapper.forkManager()
|
||||||
|
|
||||||
|
service = await initialize({
|
||||||
|
database: {
|
||||||
|
clientUrl: DB_URL,
|
||||||
|
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
testManager = MikroOrmWrapper.forkManager()
|
||||||
|
|
||||||
|
await createRuleTypes(testManager)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await MikroOrmWrapper.clearDatabase()
|
||||||
|
})
|
||||||
|
|
||||||
|
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('"ruleTypeId" 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",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
|
||||||
|
import { RuleTypeRepository } from "@repositories"
|
||||||
|
import { RuleTypeService } from "@services"
|
||||||
|
|
||||||
|
import { MikroOrmWrapper } from "../../../utils"
|
||||||
|
import { createRuleTypes } from "../../../__fixtures__/rule-type"
|
||||||
|
|
||||||
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
|
describe("RuleType Service", () => {
|
||||||
|
let service: RuleTypeService
|
||||||
|
let testManager: SqlEntityManager
|
||||||
|
let repositoryManager: SqlEntityManager
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await MikroOrmWrapper.setupDatabase()
|
||||||
|
repositoryManager = await MikroOrmWrapper.forkManager()
|
||||||
|
|
||||||
|
const ruleTypeRepository = new RuleTypeRepository({
|
||||||
|
manager: repositoryManager,
|
||||||
|
})
|
||||||
|
|
||||||
|
service = new RuleTypeService({
|
||||||
|
ruleTypeRepository,
|
||||||
|
})
|
||||||
|
|
||||||
|
testManager = await MikroOrmWrapper.forkManager()
|
||||||
|
|
||||||
|
await createRuleTypes(testManager)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await MikroOrmWrapper.clearDatabase()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("list", () => {
|
||||||
|
it("list rule types", async () => {
|
||||||
|
const ruleTypeResult = await service.list()
|
||||||
|
|
||||||
|
expect(ruleTypeResult).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "rule-type-1",
|
||||||
|
name: "rule 1",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "rule-type-2",
|
||||||
|
name: "rule 2",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("list rule types by id", async () => {
|
||||||
|
const ruleTypeResult = await service.list({ id: ["rule-type-1"] })
|
||||||
|
|
||||||
|
expect(ruleTypeResult).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "rule-type-1",
|
||||||
|
name: "rule 1",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("listAndCount", () => {
|
||||||
|
it("should return rule types and count", async () => {
|
||||||
|
const [ruleTypeResult, count] = await service.listAndCount()
|
||||||
|
|
||||||
|
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.listAndCount({
|
||||||
|
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.listAndCount(
|
||||||
|
{},
|
||||||
|
{ 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.listAndCount(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
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("retrieve", () => {
|
||||||
|
|
||||||
|
it("should return ruleType for the given id", async () => {
|
||||||
|
const ruleType = await service.retrieve('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.retrieve("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.retrieve(undefined as unknown as string)
|
||||||
|
} catch (e) {
|
||||||
|
error = e
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual('"ruleTypeId" must be defined')
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return ruleType based on config select param", async () => {
|
||||||
|
const ruleTypeResult = await service.retrieve('rule-type-1', {
|
||||||
|
select: ["name"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const serialized = JSON.parse(JSON.stringify(ruleTypeResult))
|
||||||
|
|
||||||
|
expect(serialized).toEqual({
|
||||||
|
name: 'rule 1',
|
||||||
|
id: 'rule-type-1'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("delete", () => {
|
||||||
|
const id = "rule-type-1"
|
||||||
|
|
||||||
|
it("should delete the ruleTypes given an id successfully", async () => {
|
||||||
|
await service.delete([id])
|
||||||
|
|
||||||
|
const currencies = await service.list({
|
||||||
|
id: [id],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(currencies).toHaveLength(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("update", () => {
|
||||||
|
const id = "rule-type-1"
|
||||||
|
|
||||||
|
it("should update the name of the ruleType successfully", async () => {
|
||||||
|
await service.update([
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
name: "rule 3",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const ruletype = await service.retrieve(id)
|
||||||
|
|
||||||
|
expect(ruletype.name).toEqual("rule 3")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw an error when a id does not exist", async () => {
|
||||||
|
let error
|
||||||
|
|
||||||
|
try {
|
||||||
|
await service.update([
|
||||||
|
{
|
||||||
|
id: "does-not-exist",
|
||||||
|
name: "rule 3",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
} catch (e) {
|
||||||
|
error = e
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual(
|
||||||
|
'RuleType with id "does-not-exist" not found'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("create", () => {
|
||||||
|
it("should create a ruleType successfully", async () => {
|
||||||
|
await service.create([
|
||||||
|
{
|
||||||
|
name: "Test Rule",
|
||||||
|
rule_attribute: 'region_id',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const [ruleType] = await service.list({
|
||||||
|
name: ["Test Rule"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(ruleType).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
name: "Test Rule",
|
||||||
|
rule_attribute: 'region_id',
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -21,6 +21,7 @@ export default async ({
|
|||||||
currencyService: asClass(defaultServices.CurrencyService).singleton(),
|
currencyService: asClass(defaultServices.CurrencyService).singleton(),
|
||||||
moneyAmountService: asClass(defaultServices.MoneyAmountService).singleton(),
|
moneyAmountService: asClass(defaultServices.MoneyAmountService).singleton(),
|
||||||
priceSetService: asClass(defaultServices.PriceSetService).singleton(),
|
priceSetService: asClass(defaultServices.PriceSetService).singleton(),
|
||||||
|
ruleTypeService: asClass(defaultServices.RuleTypeService).singleton(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (customRepositories) {
|
if (customRepositories) {
|
||||||
@@ -46,5 +47,8 @@ function loadDefaultRepositories({ container }) {
|
|||||||
priceSetRepository: asClass(
|
priceSetRepository: asClass(
|
||||||
defaultRepositories.PriceSetRepository
|
defaultRepositories.PriceSetRepository
|
||||||
).singleton(),
|
).singleton(),
|
||||||
|
ruleTypeRepository: asClass(
|
||||||
|
defaultRepositories.RuleTypeRepository
|
||||||
|
).singleton(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -185,13 +185,22 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
|
"title": {
|
||||||
|
"name": "title",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
"price_set_id": {
|
"price_set_id": {
|
||||||
"name": "price_set_id",
|
"name": "price_set_id",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": true,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
},
|
},
|
||||||
"money_amount_id": {
|
"money_amount_id": {
|
||||||
@@ -200,15 +209,6 @@
|
|||||||
"unsigned": false,
|
"unsigned": false,
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": true,
|
|
||||||
"mappedType": "text"
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"name": "title",
|
|
||||||
"type": "text",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
}
|
}
|
||||||
@@ -217,13 +217,29 @@
|
|||||||
"schema": "public",
|
"schema": "public",
|
||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
{
|
||||||
"keyName": "price_set_money_amount_pkey",
|
|
||||||
"columnNames": [
|
"columnNames": [
|
||||||
"id",
|
"price_set_id"
|
||||||
"price_set_id",
|
],
|
||||||
|
"composite": false,
|
||||||
|
"keyName": "IDX_price_set_money_amount_price_set_id",
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columnNames": [
|
||||||
"money_amount_id"
|
"money_amount_id"
|
||||||
],
|
],
|
||||||
"composite": true,
|
"composite": false,
|
||||||
|
"keyName": "IDX_price_set_money_amount_money_amount_id",
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "price_set_money_amount_pkey",
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
"primary": true,
|
"primary": true,
|
||||||
"unique": true
|
"unique": true
|
||||||
}
|
}
|
||||||
@@ -240,6 +256,7 @@
|
|||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.price_set",
|
"referencedTableName": "public.price_set",
|
||||||
|
"deleteRule": "cascade",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
},
|
},
|
||||||
"price_set_money_amount_money_amount_id_foreign": {
|
"price_set_money_amount_money_amount_id_foreign": {
|
||||||
@@ -255,6 +272,71 @@
|
|||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "rule_type",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"columnNames": [
|
||||||
|
"rule_attribute"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"keyName": "IDX_rule_type_rule_attribute",
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "rule_type_pkey",
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+20
-4
@@ -1,6 +1,6 @@
|
|||||||
import { Migration } from "@mikro-orm/migrations"
|
import { Migration } from "@mikro-orm/migrations"
|
||||||
|
|
||||||
export class Migration20230907144224 extends Migration {
|
export class Migration20230913123118 extends Migration {
|
||||||
async up(): Promise<void> {
|
async up(): Promise<void> {
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));'
|
'create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));'
|
||||||
@@ -9,6 +9,7 @@ export class Migration20230907144224 extends Migration {
|
|||||||
this.addSql(
|
this.addSql(
|
||||||
'create table "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));'
|
'create table "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));'
|
||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create index "IDX_money_amount_currency_code" on "money_amount" ("currency_code");'
|
'create index "IDX_money_amount_currency_code" on "money_amount" ("currency_code");'
|
||||||
)
|
)
|
||||||
@@ -18,7 +19,23 @@ export class Migration20230907144224 extends Migration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'create table "price_set_money_amount" ("id" text not null, "price_set_id" text null, "money_amount_id" text null, "title" text not null, constraint "price_set_money_amount_pkey" primary key ("id", "price_set_id", "money_amount_id"));'
|
'create table "price_set_money_amount" ("id" text not null, "title" text not null, "price_set_id" text not null, "money_amount_id" text not null, constraint "price_set_money_amount_pkey" primary key ("id"));'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create index "IDX_price_set_money_amount_price_set_id" on "price_set_money_amount" ("price_set_id");'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create index "IDX_price_set_money_amount_money_amount_id" on "price_set_money_amount" ("money_amount_id");'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create table "rule_type" ("id" text not null, "name" text not null, "rule_attribute" text not null, "default_priority" integer not null default 0, constraint "rule_type_pkey" primary key ("id"));'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create index "IDX_rule_type_rule_attribute" on "rule_type" ("rule_attribute");'
|
||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
@@ -26,9 +43,8 @@ export class Migration20230907144224 extends Migration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'alter table "price_set_money_amount" add constraint "price_set_money_amount_price_set_id_foreign" foreign key ("price_set_id") references "price_set" ("id") on update cascade;'
|
'alter table "price_set_money_amount" add constraint "price_set_money_amount_price_set_id_foreign" foreign key ("price_set_id") references "price_set" ("id") on update cascade on delete cascade;'
|
||||||
)
|
)
|
||||||
|
|
||||||
this.addSql(
|
this.addSql(
|
||||||
'alter table "price_set_money_amount" add constraint "price_set_money_amount_money_amount_id_foreign" foreign key ("money_amount_id") references "money_amount" ("id") on update cascade;'
|
'alter table "price_set_money_amount" add constraint "price_set_money_amount_money_amount_id_foreign" foreign key ("money_amount_id") references "money_amount" ("id") on update cascade;'
|
||||||
)
|
)
|
||||||
@@ -2,3 +2,4 @@ export { default as Currency } from "./currency"
|
|||||||
export { default as MoneyAmount } from "./money-amount"
|
export { default as MoneyAmount } from "./money-amount"
|
||||||
export { default as PriceSet } from "./price-set"
|
export { default as PriceSet } from "./price-set"
|
||||||
export { default as PriceSetMoneyAmount } from "./price-set-money-amount"
|
export { default as PriceSetMoneyAmount } from "./price-set-money-amount"
|
||||||
|
export { default as RuleType } from "./rule-type"
|
||||||
@@ -19,10 +19,15 @@ export default class PriceSetMoneyAmount {
|
|||||||
@Property({ columnType: "text" })
|
@Property({ columnType: "text" })
|
||||||
title!: string
|
title!: string
|
||||||
|
|
||||||
@ManyToOne(() => PriceSet, { onDelete: "cascade" })
|
@ManyToOne(() => PriceSet, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
index: "IDX_price_set_money_amount_price_set_id",
|
||||||
|
})
|
||||||
price_set?: PriceSet
|
price_set?: PriceSet
|
||||||
|
|
||||||
@ManyToOne(() => MoneyAmount, {})
|
@ManyToOne(() => MoneyAmount, {
|
||||||
|
index: "IDX_price_set_money_amount_money_amount_id",
|
||||||
|
})
|
||||||
money_amount?: MoneyAmount
|
money_amount?: MoneyAmount
|
||||||
|
|
||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { generateEntityId } from "@medusajs/utils"
|
||||||
|
import {
|
||||||
|
BeforeCreate,
|
||||||
|
Entity,
|
||||||
|
OptionalProps,
|
||||||
|
PrimaryKey,
|
||||||
|
Property,
|
||||||
|
} from "@mikro-orm/core"
|
||||||
|
|
||||||
|
type OptionalFields = "default_priority"
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
class RuleType {
|
||||||
|
[OptionalProps]?: OptionalFields
|
||||||
|
|
||||||
|
@PrimaryKey({ columnType: "text" })
|
||||||
|
id!: string
|
||||||
|
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@Property({ columnType: "text", index: "IDX_rule_type_rule_attribute" })
|
||||||
|
rule_attribute: string
|
||||||
|
|
||||||
|
@Property({ columnType: "integer", default: 0 })
|
||||||
|
default_priority: number
|
||||||
|
|
||||||
|
@BeforeCreate()
|
||||||
|
onCreate() {
|
||||||
|
this.id = generateEntityId(this.id, "rul-typ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RuleType
|
||||||
@@ -2,3 +2,4 @@ export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils"
|
|||||||
export { CurrencyRepository } from "./currency"
|
export { CurrencyRepository } from "./currency"
|
||||||
export { MoneyAmountRepository } from "./money-amount"
|
export { MoneyAmountRepository } from "./money-amount"
|
||||||
export { PriceSetRepository } from "./price-set"
|
export { PriceSetRepository } from "./price-set"
|
||||||
|
export { RuleTypeRepository } from "./rule-type"
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
import {
|
||||||
|
Context,
|
||||||
|
CreateRuleTypeDTO,
|
||||||
|
DAL,
|
||||||
|
UpdateRuleTypeDTO,
|
||||||
|
} from "@medusajs/types"
|
||||||
|
import { DALUtils, MedusaError } from "@medusajs/utils"
|
||||||
|
import {
|
||||||
|
LoadStrategy,
|
||||||
|
FilterQuery as MikroFilterQuery,
|
||||||
|
FindOptions as MikroOptions,
|
||||||
|
} from "@mikro-orm/core"
|
||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
import { RuleType } from "@models"
|
||||||
|
|
||||||
|
export class RuleTypeRepository extends DALUtils.MikroOrmBaseRepository {
|
||||||
|
protected readonly manager_: SqlEntityManager
|
||||||
|
|
||||||
|
constructor({ manager }: { manager: SqlEntityManager }) {
|
||||||
|
// @ts-ignore
|
||||||
|
// eslint-disable-next-line prefer-rest-params
|
||||||
|
super(...arguments)
|
||||||
|
this.manager_ = manager
|
||||||
|
}
|
||||||
|
|
||||||
|
async find(
|
||||||
|
findOptions: DAL.FindOptions<RuleType> = { where: {} },
|
||||||
|
context: Context = {}
|
||||||
|
): Promise<RuleType[]> {
|
||||||
|
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||||
|
|
||||||
|
const findOptions_ = { ...findOptions }
|
||||||
|
findOptions_.options ??= {}
|
||||||
|
|
||||||
|
Object.assign(findOptions_.options, {
|
||||||
|
strategy: LoadStrategy.SELECT_IN,
|
||||||
|
})
|
||||||
|
|
||||||
|
return await manager.find(
|
||||||
|
RuleType,
|
||||||
|
findOptions_.where as MikroFilterQuery<RuleType>,
|
||||||
|
findOptions_.options as MikroOptions<RuleType>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAndCount(
|
||||||
|
findOptions: DAL.FindOptions<RuleType> = { where: {} },
|
||||||
|
context: Context = {}
|
||||||
|
): Promise<[RuleType[], number]> {
|
||||||
|
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||||
|
|
||||||
|
const findOptions_ = { ...findOptions }
|
||||||
|
findOptions_.options ??= {}
|
||||||
|
|
||||||
|
Object.assign(findOptions_.options, {
|
||||||
|
strategy: LoadStrategy.SELECT_IN,
|
||||||
|
})
|
||||||
|
|
||||||
|
return await manager.findAndCount(
|
||||||
|
RuleType,
|
||||||
|
findOptions_.where as MikroFilterQuery<RuleType>,
|
||||||
|
findOptions_.options as MikroOptions<RuleType>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(ids: string[], context: Context = {}): Promise<void> {
|
||||||
|
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||||
|
await manager.nativeDelete(RuleType, { id: { $in: ids } }, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(
|
||||||
|
data: CreateRuleTypeDTO[],
|
||||||
|
context: Context = {}
|
||||||
|
): Promise<RuleType[]> {
|
||||||
|
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||||
|
|
||||||
|
const ruleTypes = data.map((ruleTypeData) => {
|
||||||
|
return manager.create(RuleType, ruleTypeData)
|
||||||
|
})
|
||||||
|
|
||||||
|
manager.persist(ruleTypes)
|
||||||
|
|
||||||
|
return ruleTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(
|
||||||
|
data: UpdateRuleTypeDTO[],
|
||||||
|
context: Context = {}
|
||||||
|
): Promise<RuleType[]> {
|
||||||
|
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||||
|
const ruleTypeIds = data.map((ruleType) => ruleType.id)
|
||||||
|
const existingRuleTypes = await this.find(
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
id: {
|
||||||
|
$in: ruleTypeIds,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
|
const existingRuleTypesMap = new Map(
|
||||||
|
existingRuleTypes.map<[string, RuleType]>((ruleType) => [
|
||||||
|
ruleType.id,
|
||||||
|
ruleType,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
|
||||||
|
const ruleTypes = data.map((ruleTypeData) => {
|
||||||
|
const existingRuleType = existingRuleTypesMap.get(ruleTypeData.id)
|
||||||
|
|
||||||
|
if (!existingRuleType) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`RuleType with id "${ruleTypeData.id}" not found`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return manager.assign(existingRuleType, ruleTypeData)
|
||||||
|
})
|
||||||
|
|
||||||
|
manager.persist(ruleTypes)
|
||||||
|
|
||||||
|
return ruleTypes
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,3 +2,4 @@ export { default as CurrencyService } from "./currency"
|
|||||||
export { default as MoneyAmountService } from "./money-amount"
|
export { default as MoneyAmountService } from "./money-amount"
|
||||||
export { default as PriceSetService } from "./price-set"
|
export { default as PriceSetService } from "./price-set"
|
||||||
export { default as PricingModuleService } from "./pricing-module"
|
export { default as PricingModuleService } from "./pricing-module"
|
||||||
|
export { default as RuleTypeService } from "./rule-type"
|
||||||
@@ -8,34 +8,42 @@ import {
|
|||||||
PricingFilters,
|
PricingFilters,
|
||||||
PricingTypes,
|
PricingTypes,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { Currency, MoneyAmount, PriceSet } from "@models"
|
import { Currency, MoneyAmount, PriceSet, RuleType } from "@models"
|
||||||
import { CurrencyService, MoneyAmountService, PriceSetService } from "@services"
|
import {
|
||||||
|
CurrencyService,
|
||||||
|
MoneyAmountService,
|
||||||
|
PriceSetService,
|
||||||
|
RuleTypeService,
|
||||||
|
} from "@services"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InjectManager,
|
InjectManager,
|
||||||
InjectTransactionManager,
|
InjectTransactionManager,
|
||||||
MedusaContext,
|
MedusaContext,
|
||||||
|
shouldForceTransaction,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
import { shouldForceTransaction } from "@medusajs/utils"
|
|
||||||
import { joinerConfig } from "../joiner-config"
|
import { joinerConfig } from "../joiner-config"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
baseRepository: DAL.RepositoryService
|
baseRepository: DAL.RepositoryService
|
||||||
currencyService: CurrencyService<any>
|
currencyService: CurrencyService<any>
|
||||||
moneyAmountService: MoneyAmountService<any>
|
moneyAmountService: MoneyAmountService<any>
|
||||||
|
ruleTypeService: RuleTypeService<any>
|
||||||
priceSetService: PriceSetService<any>
|
priceSetService: PriceSetService<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PricingModuleService<
|
export default class PricingModuleService<
|
||||||
TPriceSet extends PriceSet = PriceSet,
|
TPriceSet extends PriceSet = PriceSet,
|
||||||
TMoneyAmount extends MoneyAmount = MoneyAmount,
|
TMoneyAmount extends MoneyAmount = MoneyAmount,
|
||||||
TCurrency extends Currency = Currency
|
TCurrency extends Currency = Currency,
|
||||||
|
TRuleType extends RuleType = RuleType
|
||||||
> implements PricingTypes.IPricingModuleService
|
> implements PricingTypes.IPricingModuleService
|
||||||
{
|
{
|
||||||
protected baseRepository_: DAL.RepositoryService
|
protected baseRepository_: DAL.RepositoryService
|
||||||
protected readonly currencyService_: CurrencyService<TCurrency>
|
protected readonly currencyService_: CurrencyService<TCurrency>
|
||||||
protected readonly moneyAmountService_: MoneyAmountService<TMoneyAmount>
|
protected readonly moneyAmountService_: MoneyAmountService<TMoneyAmount>
|
||||||
|
protected readonly ruleTypeService_: RuleTypeService<TRuleType>
|
||||||
protected readonly priceSetService_: PriceSetService<TPriceSet>
|
protected readonly priceSetService_: PriceSetService<TPriceSet>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -43,6 +51,7 @@ export default class PricingModuleService<
|
|||||||
baseRepository,
|
baseRepository,
|
||||||
moneyAmountService,
|
moneyAmountService,
|
||||||
currencyService,
|
currencyService,
|
||||||
|
ruleTypeService,
|
||||||
priceSetService,
|
priceSetService,
|
||||||
}: InjectedDependencies,
|
}: InjectedDependencies,
|
||||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||||
@@ -50,6 +59,7 @@ export default class PricingModuleService<
|
|||||||
this.baseRepository_ = baseRepository
|
this.baseRepository_ = baseRepository
|
||||||
this.currencyService_ = currencyService
|
this.currencyService_ = currencyService
|
||||||
this.moneyAmountService_ = moneyAmountService
|
this.moneyAmountService_ = moneyAmountService
|
||||||
|
this.ruleTypeService_ = ruleTypeService
|
||||||
this.priceSetService_ = priceSetService
|
this.priceSetService_ = priceSetService
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,4 +422,102 @@ export default class PricingModuleService<
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await this.currencyService_.delete(currencyCodes, sharedContext)
|
await this.currencyService_.delete(currencyCodes, sharedContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async retrieveRuleType(
|
||||||
|
id: string,
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricingTypes.RuleTypeDTO> {
|
||||||
|
const ruleType = await this.ruleTypeService_.retrieve(
|
||||||
|
id,
|
||||||
|
config,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return this.baseRepository_.serialize<PricingTypes.RuleTypeDTO>(ruleType, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async listRuleTypes(
|
||||||
|
filters: PricingTypes.FilterableRuleTypeProps = {},
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricingTypes.RuleTypeDTO[]> {
|
||||||
|
const ruleTypes = await this.ruleTypeService_.list(
|
||||||
|
filters,
|
||||||
|
config,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return this.baseRepository_.serialize<PricingTypes.RuleTypeDTO[]>(
|
||||||
|
ruleTypes,
|
||||||
|
{
|
||||||
|
populate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async listAndCountRuleTypes(
|
||||||
|
filters: PricingTypes.FilterableRuleTypeProps = {},
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<[PricingTypes.RuleTypeDTO[], number]> {
|
||||||
|
const [ruleTypes, count] = await this.ruleTypeService_.listAndCount(
|
||||||
|
filters,
|
||||||
|
config,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return [
|
||||||
|
await this.baseRepository_.serialize<PricingTypes.RuleTypeDTO[]>(
|
||||||
|
ruleTypes,
|
||||||
|
{
|
||||||
|
populate: true,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
count,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||||
|
async createRuleTypes(
|
||||||
|
data: PricingTypes.CreateRuleTypeDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricingTypes.RuleTypeDTO[]> {
|
||||||
|
const ruleTypes = await this.ruleTypeService_.create(data, sharedContext)
|
||||||
|
|
||||||
|
return this.baseRepository_.serialize<PricingTypes.RuleTypeDTO[]>(
|
||||||
|
ruleTypes,
|
||||||
|
{
|
||||||
|
populate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||||
|
async updateRuleTypes(
|
||||||
|
data: PricingTypes.UpdateRuleTypeDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricingTypes.RuleTypeDTO[]> {
|
||||||
|
const ruleTypes = await this.ruleTypeService_.update(data, sharedContext)
|
||||||
|
|
||||||
|
return this.baseRepository_.serialize<PricingTypes.RuleTypeDTO[]>(
|
||||||
|
ruleTypes,
|
||||||
|
{
|
||||||
|
populate: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||||
|
async deleteRuleTypes(
|
||||||
|
ruleTypes: string[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<void> {
|
||||||
|
await this.ruleTypeService_.delete(ruleTypes, sharedContext)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import { Context, DAL, FindConfig, PricingTypes } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
InjectManager,
|
||||||
|
InjectTransactionManager,
|
||||||
|
MedusaContext,
|
||||||
|
ModulesSdkUtils,
|
||||||
|
retrieveEntity,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import { RuleType } from "@models"
|
||||||
|
|
||||||
|
import { doNotForceTransaction, shouldForceTransaction } from "@medusajs/utils"
|
||||||
|
|
||||||
|
type InjectedDependencies = {
|
||||||
|
ruleTypeRepository: DAL.RepositoryService
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class RuleTypeService<TEntity extends RuleType = RuleType> {
|
||||||
|
protected readonly ruleTypeRepository_: DAL.RepositoryService
|
||||||
|
|
||||||
|
constructor({ ruleTypeRepository }: InjectedDependencies) {
|
||||||
|
this.ruleTypeRepository_ = ruleTypeRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectManager("ruleTypeRepository_")
|
||||||
|
async retrieve(
|
||||||
|
ruleTypeId: string,
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TEntity> {
|
||||||
|
return (await retrieveEntity<RuleType, PricingTypes.RuleTypeDTO>({
|
||||||
|
id: ruleTypeId,
|
||||||
|
identifierColumn: "id",
|
||||||
|
entityName: RuleType.name,
|
||||||
|
repository: this.ruleTypeRepository_,
|
||||||
|
config,
|
||||||
|
sharedContext,
|
||||||
|
})) as TEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectManager("ruleTypeRepository_")
|
||||||
|
async list(
|
||||||
|
filters: PricingTypes.FilterableRuleTypeProps = {},
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TEntity[]> {
|
||||||
|
return (await this.ruleTypeRepository_.find(
|
||||||
|
this.buildQueryForList(filters, config),
|
||||||
|
sharedContext
|
||||||
|
)) as TEntity[]
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectManager("ruleTypeRepository_")
|
||||||
|
async listAndCount(
|
||||||
|
filters: PricingTypes.FilterableRuleTypeProps = {},
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {},
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<[TEntity[], number]> {
|
||||||
|
return (await this.ruleTypeRepository_.findAndCount(
|
||||||
|
this.buildQueryForList(filters, config),
|
||||||
|
sharedContext
|
||||||
|
)) as [TEntity[], number]
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildQueryForList(
|
||||||
|
filters: PricingTypes.FilterableRuleTypeProps = {},
|
||||||
|
config: FindConfig<PricingTypes.RuleTypeDTO> = {}
|
||||||
|
) {
|
||||||
|
const queryOptions = ModulesSdkUtils.buildQuery<RuleType>(filters, config)
|
||||||
|
|
||||||
|
if (filters.id) {
|
||||||
|
queryOptions.where["id"] = { $in: filters.id }
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager(shouldForceTransaction, "ruleTypeRepository_")
|
||||||
|
async create(
|
||||||
|
data: PricingTypes.CreateRuleTypeDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TEntity[]> {
|
||||||
|
return (await this.ruleTypeRepository_.create(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)) as TEntity[]
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager(shouldForceTransaction, "ruleTypeRepository_")
|
||||||
|
async update(
|
||||||
|
data: PricingTypes.UpdateRuleTypeDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<TEntity[]> {
|
||||||
|
return (await this.ruleTypeRepository_.update(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)) as TEntity[]
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectTransactionManager(doNotForceTransaction, "ruleTypeRepository_")
|
||||||
|
async delete(
|
||||||
|
ids: string[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<void> {
|
||||||
|
await this.ruleTypeRepository_.delete(ids, sharedContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from "./currency"
|
export * from "./currency"
|
||||||
export * from "./money-amount"
|
export * from "./money-amount"
|
||||||
export * from "./price-set"
|
export * from "./price-set"
|
||||||
|
export * from "./rule-type"
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { BaseFilterable } from "../../dal"
|
||||||
|
|
||||||
|
export interface RuleTypeDTO {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
rule_attribute: string
|
||||||
|
default_priority: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateRuleTypeDTO {
|
||||||
|
id?: string
|
||||||
|
name: string
|
||||||
|
rule_attribute: string
|
||||||
|
default_priority?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateRuleTypeDTO {
|
||||||
|
id: string
|
||||||
|
name?: string
|
||||||
|
rule_attribute?: string
|
||||||
|
default_priority?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterableRuleTypeProps
|
||||||
|
extends BaseFilterable<FilterableRuleTypeProps> {
|
||||||
|
id?: string[]
|
||||||
|
name?: string[]
|
||||||
|
}
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
export * from "./common"
|
export * from "./common"
|
||||||
export * from "./service"
|
export * from "./service"
|
||||||
@@ -6,17 +6,21 @@ import {
|
|||||||
CreateCurrencyDTO,
|
CreateCurrencyDTO,
|
||||||
CreateMoneyAmountDTO,
|
CreateMoneyAmountDTO,
|
||||||
CreatePriceSetDTO,
|
CreatePriceSetDTO,
|
||||||
|
CreateRuleTypeDTO,
|
||||||
CurrencyDTO,
|
CurrencyDTO,
|
||||||
FilterableCurrencyProps,
|
FilterableCurrencyProps,
|
||||||
FilterableMoneyAmountProps,
|
FilterableMoneyAmountProps,
|
||||||
FilterablePriceSetProps,
|
FilterablePriceSetProps,
|
||||||
|
FilterableRuleTypeProps,
|
||||||
MoneyAmountDTO,
|
MoneyAmountDTO,
|
||||||
PriceSetDTO,
|
PriceSetDTO,
|
||||||
PricingContext,
|
PricingContext,
|
||||||
PricingFilters,
|
PricingFilters,
|
||||||
|
RuleTypeDTO,
|
||||||
UpdateCurrencyDTO,
|
UpdateCurrencyDTO,
|
||||||
UpdateMoneyAmountDTO,
|
UpdateMoneyAmountDTO,
|
||||||
UpdatePriceSetDTO,
|
UpdatePriceSetDTO,
|
||||||
|
UpdateRuleTypeDTO,
|
||||||
} from "./common"
|
} from "./common"
|
||||||
|
|
||||||
export interface IPricingModuleService {
|
export interface IPricingModuleService {
|
||||||
@@ -120,4 +124,34 @@ export interface IPricingModuleService {
|
|||||||
currencyCodes: string[],
|
currencyCodes: string[],
|
||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
|
|
||||||
|
retrieveRuleType(
|
||||||
|
code: string,
|
||||||
|
config?: FindConfig<RuleTypeDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<RuleTypeDTO>
|
||||||
|
|
||||||
|
listRuleTypes(
|
||||||
|
filters?: FilterableRuleTypeProps,
|
||||||
|
config?: FindConfig<RuleTypeDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<RuleTypeDTO[]>
|
||||||
|
|
||||||
|
listAndCountRuleTypes(
|
||||||
|
filters?: FilterableRuleTypeProps,
|
||||||
|
config?: FindConfig<RuleTypeDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<[RuleTypeDTO[], number]>
|
||||||
|
|
||||||
|
createRuleTypes(
|
||||||
|
data: CreateRuleTypeDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<RuleTypeDTO[]>
|
||||||
|
|
||||||
|
updateRuleTypes(
|
||||||
|
data: UpdateRuleTypeDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<RuleTypeDTO[]>
|
||||||
|
|
||||||
|
deleteRuleTypes(ruleTypes: string[], sharedContext?: Context): Promise<void>
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user