feat(pricing, utils, types): adds money amount to pricing module (#4909)
What: - Adds money amount service / repo / model - Adds money amount to entry service - Adds tests for services - Refreshes schema - Update joiner config to include money amounts RESOLVES CORE-1478 RESOLVES CORE-1479 Co-authored-by: Shahed Nasser <27354907+shahednasser@users.noreply.github.com> Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
7
.changeset/odd-coats-learn.md
Normal file
7
.changeset/odd-coats-learn.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@medusajs/pricing": patch
|
||||
"@medusajs/types": patch
|
||||
"@medusajs/utils": patch
|
||||
---
|
||||
|
||||
feat(pricing, utils, types): adds money amount to pricing module
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./inventory-level-stock-location"
|
||||
export * from "./product-variant-inventory-item"
|
||||
export * from "./product-variant-money-amount"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||
import { LINKS } from "../links"
|
||||
|
||||
export const ProductVariantMoneyAmount: ModuleJoinerConfig = {
|
||||
serviceName: LINKS.ProductVariantMoneyAmount,
|
||||
isLink: true,
|
||||
databaseConfig: {
|
||||
tableName: "product_variant_money_amount",
|
||||
idPrefix: "pvma",
|
||||
},
|
||||
alias: [
|
||||
{
|
||||
name: "product_variant_money_amount",
|
||||
},
|
||||
{
|
||||
name: "product_variant_money_amounts",
|
||||
},
|
||||
],
|
||||
primaryKeys: ["id", "variant_id", "money_amount_id"],
|
||||
relationships: [
|
||||
{
|
||||
serviceName: Modules.PRODUCT,
|
||||
primaryKey: "id",
|
||||
foreignKey: "variant_id",
|
||||
alias: "variant",
|
||||
args: {
|
||||
methodSuffix: "Variants",
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceName: Modules.PRICING,
|
||||
primaryKey: "id",
|
||||
foreignKey: "money_amount_id",
|
||||
alias: "money_amount",
|
||||
deleteCascade: true,
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
{
|
||||
serviceName: Modules.PRODUCT,
|
||||
relationship: {
|
||||
serviceName: LINKS.ProductVariantMoneyAmount,
|
||||
primaryKey: "variant_id",
|
||||
foreignKey: "id",
|
||||
alias: "prices",
|
||||
isList: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceName: Modules.PRICING,
|
||||
relationship: {
|
||||
serviceName: LINKS.ProductVariantMoneyAmount,
|
||||
primaryKey: "money_amount_id",
|
||||
foreignKey: "id",
|
||||
alias: "variant_link",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -93,8 +93,7 @@ export const initialize = async (
|
||||
!modulesLoadedKeys.includes(primary.serviceName) ||
|
||||
!modulesLoadedKeys.includes(foreign.serviceName)
|
||||
) {
|
||||
// TODO: This should be uncommented when all modules are done
|
||||
// continue
|
||||
continue
|
||||
}
|
||||
|
||||
const moduleDefinition = getLinkModuleDefinition(
|
||||
@@ -180,8 +179,7 @@ export async function runMigrations(
|
||||
!modulesLoadedKeys.includes(primary.serviceName) ||
|
||||
!modulesLoadedKeys.includes(foreign.serviceName)
|
||||
) {
|
||||
// TODO: This should be uncommented when all modules are done
|
||||
// continue
|
||||
continue
|
||||
}
|
||||
|
||||
const migrate = getMigration(definition, serviceKey, primary, foreign)
|
||||
|
||||
@@ -8,4 +8,10 @@ export const LINKS = {
|
||||
Modules.INVENTORY,
|
||||
"inventory_item_id"
|
||||
),
|
||||
ProductVariantMoneyAmount: composeLinkName(
|
||||
Modules.PRODUCT,
|
||||
"variant_id",
|
||||
Modules.PRICING,
|
||||
"money_amount_id"
|
||||
),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
export const defaultMoneyAmountsData = [
|
||||
{
|
||||
id: "money-amount-USD",
|
||||
currency_code: "USD",
|
||||
amount: 500,
|
||||
min_quantity: 1,
|
||||
max_quantity: 10,
|
||||
},
|
||||
{
|
||||
id: "money-amount-EUR",
|
||||
currency_code: "EUR",
|
||||
amount: 400,
|
||||
min_quantity: 1,
|
||||
max_quantity: 5,
|
||||
},
|
||||
{
|
||||
id: "money-amount-CAD",
|
||||
currency_code: "CAD",
|
||||
amount: 600,
|
||||
min_quantity: 1,
|
||||
max_quantity: 8,
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
import { MoneyAmount } from "@models"
|
||||
import { defaultMoneyAmountsData } from "./data"
|
||||
|
||||
export async function createMoneyAmounts(
|
||||
manager: SqlEntityManager,
|
||||
moneyAmountsData: any[] = defaultMoneyAmountsData
|
||||
): Promise<MoneyAmount[]> {
|
||||
const moneyAmounts: MoneyAmount[] = []
|
||||
|
||||
for (let moneyAmountData of moneyAmountsData) {
|
||||
const moneyAmount = manager.create(MoneyAmount, moneyAmountData)
|
||||
|
||||
moneyAmounts.push(moneyAmount)
|
||||
}
|
||||
|
||||
await manager.persistAndFlush(moneyAmounts)
|
||||
|
||||
return moneyAmounts
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
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 { MikroOrmWrapper } from "../../../utils"
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
describe("MoneyAmount Service", () => {
|
||||
let service: MoneyAmountService
|
||||
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({
|
||||
manager: repositoryManager,
|
||||
})
|
||||
|
||||
service = new MoneyAmountService({
|
||||
moneyAmountRepository,
|
||||
})
|
||||
|
||||
testManager = await MikroOrmWrapper.forkManager()
|
||||
currencyData = await createCurrencies(testManager)
|
||||
data = await createMoneyAmounts(testManager)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await MikroOrmWrapper.clearDatabase()
|
||||
})
|
||||
|
||||
describe("list", () => {
|
||||
it("list 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",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("list moneyAmounts by id", async () => {
|
||||
const moneyAmountsResult = await service.list({
|
||||
id: ["money-amount-USD"],
|
||||
})
|
||||
|
||||
expect(moneyAmountsResult).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "money-amount-USD",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
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()
|
||||
|
||||
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",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should return moneyAmounts and count when filtered", async () => {
|
||||
const [moneyAmountsResult, count] = await service.listAndCount({
|
||||
id: ["money-amount-USD"],
|
||||
})
|
||||
|
||||
expect(count).toEqual(1)
|
||||
expect(moneyAmountsResult).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "money-amount-USD",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
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(
|
||||
{},
|
||||
{ skip: 1, take: 1 }
|
||||
)
|
||||
|
||||
expect(count).toEqual(3)
|
||||
expect(moneyAmountsResult).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "money-amount-EUR",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should return requested fields", async () => {
|
||||
const [moneyAmountsResult, count] = await service.listAndCount(
|
||||
{},
|
||||
{
|
||||
take: 1,
|
||||
select: ["id"],
|
||||
}
|
||||
)
|
||||
|
||||
const serialized = JSON.parse(JSON.stringify(moneyAmountsResult))
|
||||
|
||||
expect(count).toEqual(3)
|
||||
expect(serialized).toEqual([
|
||||
{
|
||||
id: "money-amount-USD",
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe("retrieve", () => {
|
||||
const id = "money-amount-USD"
|
||||
const amount = "500"
|
||||
|
||||
it("should return moneyAmount for the given id", async () => {
|
||||
const moneyAmount = await service.retrieve(id)
|
||||
|
||||
expect(moneyAmount).toEqual(
|
||||
expect.objectContaining({
|
||||
id,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw an error when moneyAmount with id does not exist", async () => {
|
||||
let error
|
||||
|
||||
try {
|
||||
await service.retrieve("does-not-exist")
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(
|
||||
"MoneyAmount 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('"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,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("delete", () => {
|
||||
const id = "money-amount-USD"
|
||||
|
||||
it("should delete the moneyAmounts given an id successfully", async () => {
|
||||
await service.delete([id])
|
||||
|
||||
const moneyAmounts = await service.list({
|
||||
id: [id],
|
||||
})
|
||||
|
||||
expect(moneyAmounts).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("update", () => {
|
||||
const id = "money-amount-USD"
|
||||
|
||||
it("should update the amount of the moneyAmount successfully", async () => {
|
||||
await service.update([
|
||||
{
|
||||
id,
|
||||
amount: 700,
|
||||
},
|
||||
])
|
||||
|
||||
const moneyAmount = 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")
|
||||
})
|
||||
|
||||
it("should throw an error when a id does not exist", async () => {
|
||||
let error
|
||||
|
||||
try {
|
||||
await service.update([
|
||||
{
|
||||
id: "does-not-exist",
|
||||
amount: 666,
|
||||
},
|
||||
])
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(
|
||||
'MoneyAmount with id "does-not-exist" not found'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("create", () => {
|
||||
it("should create a moneyAmount successfully", async () => {
|
||||
await service.create([
|
||||
{
|
||||
id: "money-amount-TESM",
|
||||
currency_code: "USD",
|
||||
amount: 333,
|
||||
min_quantity: 1,
|
||||
max_quantity: 4,
|
||||
},
|
||||
])
|
||||
|
||||
const [moneyAmount] = await service.list({
|
||||
id: ["money-amount-TESM"],
|
||||
})
|
||||
|
||||
expect(moneyAmount).toEqual(
|
||||
expect.objectContaining({
|
||||
id: "money-amount-TESM",
|
||||
currency_code: "USD",
|
||||
amount: "333",
|
||||
min_quantity: "1",
|
||||
max_quantity: "4",
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,11 +1,8 @@
|
||||
import { initialize } from "../../../../src"
|
||||
|
||||
import { IPricingModuleService } from "@medusajs/types"
|
||||
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
|
||||
import { Currency } from "@models"
|
||||
|
||||
import { initialize } from "../../../../src"
|
||||
import { createCurrencies } from "../../../__fixtures__/currency"
|
||||
import { DB_URL, MikroOrmWrapper } from "../../../utils"
|
||||
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
import { IPricingModuleService } from "@medusajs/types"
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
import { Currency, MoneyAmount } from "@models"
|
||||
|
||||
import { initialize } from "../../../../src"
|
||||
import { createCurrencies } from "../../../__fixtures__/currency"
|
||||
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
|
||||
import { DB_URL, MikroOrmWrapper } from "../../../utils"
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
describe("MoneyAmount Service", () => {
|
||||
let service: IPricingModuleService
|
||||
let testManager: SqlEntityManager
|
||||
let repositoryManager: SqlEntityManager
|
||||
let data!: MoneyAmount[]
|
||||
let currencyData!: Currency[]
|
||||
|
||||
beforeEach(async () => {
|
||||
await MikroOrmWrapper.setupDatabase()
|
||||
repositoryManager = MikroOrmWrapper.forkManager()
|
||||
|
||||
service = await initialize({
|
||||
database: {
|
||||
clientUrl: DB_URL,
|
||||
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
|
||||
},
|
||||
})
|
||||
|
||||
testManager = MikroOrmWrapper.forkManager()
|
||||
|
||||
testManager = await MikroOrmWrapper.forkManager()
|
||||
currencyData = await createCurrencies(testManager)
|
||||
data = await createMoneyAmounts(testManager)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await MikroOrmWrapper.clearDatabase()
|
||||
})
|
||||
|
||||
describe("list", () => {
|
||||
it("list 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",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("list moneyAmounts by id", async () => {
|
||||
const moneyAmountsResult = await service.list({
|
||||
id: ["money-amount-USD"],
|
||||
})
|
||||
|
||||
expect(moneyAmountsResult).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "money-amount-USD",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
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()
|
||||
|
||||
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",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should return moneyAmounts and count when filtered", async () => {
|
||||
const [moneyAmountsResult, count] = await service.listAndCount({
|
||||
id: ["money-amount-USD"],
|
||||
})
|
||||
|
||||
expect(count).toEqual(1)
|
||||
expect(moneyAmountsResult).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "money-amount-USD",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
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(
|
||||
{},
|
||||
{ skip: 1, take: 1 }
|
||||
)
|
||||
|
||||
expect(count).toEqual(3)
|
||||
expect(moneyAmountsResult).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "money-amount-EUR",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should return requested fields", async () => {
|
||||
const [moneyAmountsResult, count] = await service.listAndCount(
|
||||
{},
|
||||
{
|
||||
take: 1,
|
||||
select: ["id"],
|
||||
}
|
||||
)
|
||||
|
||||
const serialized = JSON.parse(JSON.stringify(moneyAmountsResult))
|
||||
|
||||
expect(count).toEqual(3)
|
||||
expect(serialized).toEqual([
|
||||
{
|
||||
id: "money-amount-USD",
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe("retrieve", () => {
|
||||
const id = "money-amount-USD"
|
||||
const amount = "500"
|
||||
|
||||
it("should return moneyAmount for the given id", async () => {
|
||||
const moneyAmount = await service.retrieve(id)
|
||||
|
||||
expect(moneyAmount).toEqual(
|
||||
expect.objectContaining({
|
||||
id,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw an error when moneyAmount with id does not exist", async () => {
|
||||
let error
|
||||
|
||||
try {
|
||||
await service.retrieve("does-not-exist")
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(
|
||||
"MoneyAmount 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('"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,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("delete", () => {
|
||||
const id = "money-amount-USD"
|
||||
|
||||
it("should delete the moneyAmounts given an id successfully", async () => {
|
||||
await service.delete([id])
|
||||
|
||||
const moneyAmounts = await service.list({
|
||||
id: [id],
|
||||
})
|
||||
|
||||
expect(moneyAmounts).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("update", () => {
|
||||
const id = "money-amount-USD"
|
||||
|
||||
it("should update the amount of the moneyAmount successfully", async () => {
|
||||
await service.update([
|
||||
{
|
||||
id,
|
||||
amount: 700,
|
||||
},
|
||||
])
|
||||
|
||||
const moneyAmount = 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, {
|
||||
relations: ["currency"],
|
||||
})
|
||||
|
||||
expect(moneyAmount.currency_code).toEqual("EUR")
|
||||
expect(moneyAmount.currency?.code).toEqual("EUR")
|
||||
})
|
||||
|
||||
it("should throw an error when a id does not exist", async () => {
|
||||
let error
|
||||
|
||||
try {
|
||||
await service.update([
|
||||
{
|
||||
id: "does-not-exist",
|
||||
amount: 666,
|
||||
},
|
||||
])
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(
|
||||
'MoneyAmount with id "does-not-exist" not found'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("create", () => {
|
||||
it("should create a moneyAmount successfully", async () => {
|
||||
await service.create([
|
||||
{
|
||||
id: "money-amount-TESM",
|
||||
currency_code: "USD",
|
||||
amount: 333,
|
||||
min_quantity: 1,
|
||||
max_quantity: 4,
|
||||
},
|
||||
])
|
||||
|
||||
const [moneyAmount] = await service.list({
|
||||
id: ["money-amount-TESM"],
|
||||
})
|
||||
|
||||
expect(moneyAmount).toEqual(
|
||||
expect.objectContaining({
|
||||
id: "money-amount-TESM",
|
||||
currency_code: "USD",
|
||||
amount: "333",
|
||||
min_quantity: "1",
|
||||
max_quantity: "4",
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,27 +1,31 @@
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { JoinerServiceConfig } from "@medusajs/types"
|
||||
import { ModuleJoinerConfig } from "@medusajs/types"
|
||||
import { MapToConfig } from "@medusajs/utils"
|
||||
import { Currency } from "@models"
|
||||
import { Currency, MoneyAmount } from "@models"
|
||||
|
||||
export enum LinkableKeys {
|
||||
MONEY_AMOUNT_ID = "money_amount_id",
|
||||
CURRENCY_CODE = "code",
|
||||
CURRENCY_CODE = "currency_code",
|
||||
}
|
||||
|
||||
export const entityNameToLinkableKeysMap: MapToConfig = {
|
||||
[Currency.name]: [{ mapTo: LinkableKeys.CURRENCY_CODE, valueFrom: "code" }],
|
||||
[MoneyAmount.name]: [
|
||||
{ mapTo: LinkableKeys.MONEY_AMOUNT_ID, valueFrom: "id" },
|
||||
],
|
||||
}
|
||||
|
||||
export const joinerConfig: JoinerServiceConfig = {
|
||||
export const joinerConfig: ModuleJoinerConfig = {
|
||||
serviceName: Modules.PRICING,
|
||||
primaryKeys: ["code"],
|
||||
primaryKeys: ["id", "currency_code"],
|
||||
linkableKeys: Object.values(LinkableKeys),
|
||||
alias: [
|
||||
// {
|
||||
// name: "money_amount",
|
||||
// },
|
||||
// {
|
||||
// name: "money_amounts",
|
||||
// },
|
||||
{
|
||||
name: "money_amount",
|
||||
},
|
||||
{
|
||||
name: "money_amounts",
|
||||
},
|
||||
{
|
||||
name: "currency",
|
||||
args: {
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { ModulesSdkTypes } from "@medusajs/types"
|
||||
import * as defaultRepositories from "@repositories"
|
||||
import { BaseRepository, CurrencyRepository } from "@repositories"
|
||||
import { CurrencyService } from "@services"
|
||||
import {
|
||||
BaseRepository,
|
||||
CurrencyRepository,
|
||||
MoneyAmountRepository,
|
||||
} from "@repositories"
|
||||
import { CurrencyService, MoneyAmountService } from "@services"
|
||||
|
||||
import { LoaderOptions } from "@medusajs/modules-sdk"
|
||||
import { loadCustomRepositories } from "@medusajs/utils"
|
||||
@@ -20,6 +24,7 @@ export default async ({
|
||||
|
||||
container.register({
|
||||
currencyService: asClass(CurrencyService).singleton(),
|
||||
moneyAmountService: asClass(MoneyAmountService).singleton(),
|
||||
})
|
||||
|
||||
if (customRepositories) {
|
||||
@@ -37,5 +42,6 @@ function loadDefaultRepositories({ container }) {
|
||||
container.register({
|
||||
baseRepository: asClass(BaseRepository).singleton(),
|
||||
currencyRepository: asClass(CurrencyRepository).singleton(),
|
||||
moneyAmountRepository: asClass(MoneyAmountRepository).singleton(),
|
||||
})
|
||||
}
|
||||
|
||||
150
packages/pricing/src/migrations/.snapshot-medusa-pricing-1.json
Normal file
150
packages/pricing/src/migrations/.snapshot-medusa-pricing-1.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"namespaces": [
|
||||
"public"
|
||||
],
|
||||
"name": "public",
|
||||
"tables": [
|
||||
{
|
||||
"columns": {
|
||||
"code": {
|
||||
"name": "code",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"symbol": {
|
||||
"name": "symbol",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"symbol_native": {
|
||||
"name": "symbol_native",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
}
|
||||
},
|
||||
"name": "currency",
|
||||
"schema": "public",
|
||||
"indexes": [
|
||||
{
|
||||
"keyName": "currency_pkey",
|
||||
"columnNames": [
|
||||
"code"
|
||||
],
|
||||
"composite": false,
|
||||
"primary": true,
|
||||
"unique": true
|
||||
}
|
||||
],
|
||||
"checks": [],
|
||||
"foreignKeys": {}
|
||||
},
|
||||
{
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"currency_code": {
|
||||
"name": "currency_code",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": true,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"amount": {
|
||||
"name": "amount",
|
||||
"type": "numeric",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": true,
|
||||
"mappedType": "decimal"
|
||||
},
|
||||
"min_quantity": {
|
||||
"name": "min_quantity",
|
||||
"type": "numeric",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": true,
|
||||
"mappedType": "decimal"
|
||||
},
|
||||
"max_quantity": {
|
||||
"name": "max_quantity",
|
||||
"type": "numeric",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": true,
|
||||
"mappedType": "decimal"
|
||||
}
|
||||
},
|
||||
"name": "money_amount",
|
||||
"schema": "public",
|
||||
"indexes": [
|
||||
{
|
||||
"columnNames": [
|
||||
"currency_code"
|
||||
],
|
||||
"composite": false,
|
||||
"keyName": "IDX_money_amount_currency_code",
|
||||
"primary": false,
|
||||
"unique": false
|
||||
},
|
||||
{
|
||||
"keyName": "money_amount_pkey",
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"composite": false,
|
||||
"primary": true,
|
||||
"unique": true
|
||||
}
|
||||
],
|
||||
"checks": [],
|
||||
"foreignKeys": {
|
||||
"money_amount_currency_code_foreign": {
|
||||
"constraintName": "money_amount_currency_code_foreign",
|
||||
"columnNames": [
|
||||
"currency_code"
|
||||
],
|
||||
"localTableName": "public.money_amount",
|
||||
"referencedColumnNames": [
|
||||
"code"
|
||||
],
|
||||
"referencedTableName": "public.currency",
|
||||
"deleteRule": "set null",
|
||||
"updateRule": "cascade"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
{
|
||||
"namespaces": [
|
||||
"public"
|
||||
],
|
||||
"name": "public",
|
||||
"tables": [
|
||||
{
|
||||
"columns": {
|
||||
"code": {
|
||||
"name": "code",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"symbol": {
|
||||
"name": "symbol",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"symbol_native": {
|
||||
"name": "symbol_native",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
}
|
||||
},
|
||||
"name": "currency",
|
||||
"schema": "public",
|
||||
"indexes": [
|
||||
{
|
||||
"keyName": "currency_pkey",
|
||||
"columnNames": [
|
||||
"code"
|
||||
],
|
||||
"composite": false,
|
||||
"primary": true,
|
||||
"unique": true
|
||||
}
|
||||
],
|
||||
"checks": [],
|
||||
"foreignKeys": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20230828182018 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql('create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));');
|
||||
}
|
||||
|
||||
}
|
||||
14
packages/pricing/src/migrations/Migration20230830085850.ts
Normal file
14
packages/pricing/src/migrations/Migration20230830085850.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20230830085850 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql('create table "currency" ("code" text not null, "symbol" text not null, "symbol_native" text not null, "name" text not null, constraint "currency_pkey" primary key ("code"));');
|
||||
|
||||
this.addSql('create table "money_amount" ("id" text not null, "currency_code" text null, "amount" numeric null, "min_quantity" numeric null, "max_quantity" numeric null, constraint "money_amount_pkey" primary key ("id"));');
|
||||
this.addSql('create index "IDX_money_amount_currency_code" on "money_amount" ("currency_code");');
|
||||
|
||||
this.addSql('alter table "money_amount" add constraint "money_amount_currency_code_foreign" foreign key ("currency_code") references "currency" ("code") on update cascade on delete set null;');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export { default as Currency } from "./currency"
|
||||
export { default as MoneyAmount } from "./money-amount"
|
||||
|
||||
42
packages/pricing/src/models/money-amount.ts
Normal file
42
packages/pricing/src/models/money-amount.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { generateEntityId } from "@medusajs/utils"
|
||||
import {
|
||||
BeforeCreate,
|
||||
Entity,
|
||||
ManyToOne,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
} from "@mikro-orm/core"
|
||||
|
||||
import Currency from "./currency"
|
||||
|
||||
@Entity()
|
||||
class MoneyAmount {
|
||||
@PrimaryKey({ columnType: "text" })
|
||||
id!: string
|
||||
|
||||
@Property({ columnType: "text", nullable: true })
|
||||
currency_code?: string
|
||||
|
||||
@ManyToOne(() => Currency, {
|
||||
nullable: true,
|
||||
index: "IDX_money_amount_currency_code",
|
||||
fieldName: "currency_code",
|
||||
})
|
||||
currency?: Currency
|
||||
|
||||
@Property({ columnType: "numeric", nullable: true })
|
||||
amount?: number
|
||||
|
||||
@Property({ columnType: "numeric", nullable: true })
|
||||
min_quantity?: number | null
|
||||
|
||||
@Property({ columnType: "numeric", nullable: true })
|
||||
max_quantity?: number | null
|
||||
|
||||
@BeforeCreate()
|
||||
onCreate() {
|
||||
this.id = generateEntityId(this.id, "ma")
|
||||
}
|
||||
}
|
||||
|
||||
export default MoneyAmount
|
||||
@@ -1,2 +1,3 @@
|
||||
export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils"
|
||||
export { CurrencyRepository } from "./currency"
|
||||
export { MoneyAmountRepository } from "./money-amount"
|
||||
|
||||
127
packages/pricing/src/repositories/money-amount.ts
Normal file
127
packages/pricing/src/repositories/money-amount.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import {
|
||||
Context,
|
||||
CreateMoneyAmountDTO,
|
||||
DAL,
|
||||
UpdateMoneyAmountDTO,
|
||||
} 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 { MoneyAmount } from "@models"
|
||||
|
||||
export class MoneyAmountRepository 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<MoneyAmount> = { where: {} },
|
||||
context: Context = {}
|
||||
): Promise<MoneyAmount[]> {
|
||||
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||
|
||||
const findOptions_ = { ...findOptions }
|
||||
findOptions_.options ??= {}
|
||||
|
||||
Object.assign(findOptions_.options, {
|
||||
strategy: LoadStrategy.SELECT_IN,
|
||||
})
|
||||
|
||||
return await manager.find(
|
||||
MoneyAmount,
|
||||
findOptions_.where as MikroFilterQuery<MoneyAmount>,
|
||||
findOptions_.options as MikroOptions<MoneyAmount>
|
||||
)
|
||||
}
|
||||
|
||||
async findAndCount(
|
||||
findOptions: DAL.FindOptions<MoneyAmount> = { where: {} },
|
||||
context: Context = {}
|
||||
): Promise<[MoneyAmount[], number]> {
|
||||
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||
|
||||
const findOptions_ = { ...findOptions }
|
||||
findOptions_.options ??= {}
|
||||
|
||||
Object.assign(findOptions_.options, {
|
||||
strategy: LoadStrategy.SELECT_IN,
|
||||
})
|
||||
|
||||
return await manager.findAndCount(
|
||||
MoneyAmount,
|
||||
findOptions_.where as MikroFilterQuery<MoneyAmount>,
|
||||
findOptions_.options as MikroOptions<MoneyAmount>
|
||||
)
|
||||
}
|
||||
|
||||
async delete(ids: string[], context: Context = {}): Promise<void> {
|
||||
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||
await manager.nativeDelete(MoneyAmount, { id: { $in: ids } }, {})
|
||||
}
|
||||
|
||||
async create(
|
||||
data: CreateMoneyAmountDTO[],
|
||||
context: Context = {}
|
||||
): Promise<MoneyAmount[]> {
|
||||
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||
|
||||
const moneyAmounts = data.map((moneyAmountData) => {
|
||||
return manager.create(MoneyAmount, moneyAmountData)
|
||||
})
|
||||
|
||||
manager.persist(moneyAmounts)
|
||||
|
||||
return moneyAmounts
|
||||
}
|
||||
|
||||
async update(
|
||||
data: UpdateMoneyAmountDTO[],
|
||||
context: Context = {}
|
||||
): Promise<MoneyAmount[]> {
|
||||
const manager = this.getActiveManager<SqlEntityManager>(context)
|
||||
const moneyAmountIds = data.map((moneyAmountData) => moneyAmountData.id)
|
||||
const existingMoneyAmounts = await this.find(
|
||||
{
|
||||
where: {
|
||||
id: {
|
||||
$in: moneyAmountIds,
|
||||
},
|
||||
},
|
||||
},
|
||||
context
|
||||
)
|
||||
|
||||
const existingMoneyAmountMap = new Map(
|
||||
existingMoneyAmounts.map<[string, MoneyAmount]>((moneyAmount) => [
|
||||
moneyAmount.id,
|
||||
moneyAmount,
|
||||
])
|
||||
)
|
||||
|
||||
const moneyAmounts = data.map((moneyAmountData) => {
|
||||
const existingMoneyAmount = existingMoneyAmountMap.get(moneyAmountData.id)
|
||||
|
||||
if (!existingMoneyAmount) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`MoneyAmount with id "${moneyAmountData.id}" not found`
|
||||
)
|
||||
}
|
||||
|
||||
return manager.assign(existingMoneyAmount, moneyAmountData)
|
||||
})
|
||||
|
||||
manager.persist(moneyAmounts)
|
||||
|
||||
return moneyAmounts
|
||||
}
|
||||
}
|
||||
@@ -22,14 +22,14 @@ export async function run({
|
||||
|
||||
logger.info(`Loading seed data from ${path}...`)
|
||||
|
||||
const { currenciesData } = await import(resolve(process.cwd(), path)).catch(
|
||||
(e) => {
|
||||
logger?.error(
|
||||
`Failed to load seed data from ${path}. Please, provide a relative path and check that you export the following currenciesData.${EOL}${e}`
|
||||
)
|
||||
throw e
|
||||
}
|
||||
)
|
||||
const { currenciesData, moneyAmountsData } = await import(
|
||||
resolve(process.cwd(), path)
|
||||
).catch((e) => {
|
||||
logger?.error(
|
||||
`Failed to load seed data from ${path}. Please, provide a relative path and check that you export the following: currenciesData, moneyAmountsData.${EOL}${e}`
|
||||
)
|
||||
throw e
|
||||
})
|
||||
|
||||
const dbData = ModulesSdkUtils.loadDatabaseConfig("pricing", options)!
|
||||
const entities = Object.values(PricingModels) as unknown as EntitySchema[]
|
||||
@@ -40,12 +40,14 @@ export async function run({
|
||||
entities,
|
||||
pathToMigrations
|
||||
)
|
||||
|
||||
const manager = orm.em.fork()
|
||||
|
||||
try {
|
||||
logger.info("Inserting currencies")
|
||||
logger.info("Inserting currencies & money_amounts")
|
||||
|
||||
await createCurrencies(manager, currenciesData)
|
||||
await createMoneyAmounts(manager, moneyAmountsData)
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
`Failed to insert the seed data in the PostgreSQL database ${dbData.clientUrl}.${EOL}${e}`
|
||||
@@ -59,7 +61,7 @@ async function createCurrencies(
|
||||
manager: SqlEntityManager,
|
||||
data: RequiredEntityData<PricingModels.Currency>[]
|
||||
) {
|
||||
const currencies: any[] = data.map((currencyData) => {
|
||||
const currencies = data.map((currencyData) => {
|
||||
return manager.create(PricingModels.Currency, currencyData)
|
||||
})
|
||||
|
||||
@@ -67,3 +69,16 @@ async function createCurrencies(
|
||||
|
||||
return currencies
|
||||
}
|
||||
|
||||
async function createMoneyAmounts(
|
||||
manager: SqlEntityManager,
|
||||
data: RequiredEntityData<PricingModels.MoneyAmount>[]
|
||||
) {
|
||||
const moneyAmounts = data.map((moneyAmountData) => {
|
||||
return manager.create(PricingModels.MoneyAmount, moneyAmountData)
|
||||
})
|
||||
|
||||
await manager.persistAndFlush(moneyAmounts)
|
||||
|
||||
return moneyAmounts
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as CurrencyService } from "./currency"
|
||||
export { default as MoneyAmountService } from "./money-amount"
|
||||
export { default as PricingModuleService } from "./pricing-module"
|
||||
|
||||
111
packages/pricing/src/services/money-amount.ts
Normal file
111
packages/pricing/src/services/money-amount.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { Context, DAL, FindConfig, PricingTypes } from "@medusajs/types"
|
||||
import {
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
ModulesSdkUtils,
|
||||
retrieveEntity,
|
||||
} from "@medusajs/utils"
|
||||
import { MoneyAmount } from "@models"
|
||||
import { MoneyAmountRepository } from "@repositories"
|
||||
|
||||
import { doNotForceTransaction, shouldForceTransaction } from "@medusajs/utils"
|
||||
|
||||
type InjectedDependencies = {
|
||||
moneyAmountRepository: DAL.RepositoryService
|
||||
}
|
||||
|
||||
export default class MoneyAmountService<
|
||||
TEntity extends MoneyAmount = MoneyAmount
|
||||
> {
|
||||
protected readonly moneyAmountRepository_: DAL.RepositoryService
|
||||
|
||||
constructor({ moneyAmountRepository }: InjectedDependencies) {
|
||||
this.moneyAmountRepository_ = moneyAmountRepository
|
||||
}
|
||||
|
||||
@InjectManager("moneyAmountRepository_")
|
||||
async retrieve(
|
||||
moneyAmountId: string,
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TEntity> {
|
||||
return (await retrieveEntity<MoneyAmount, PricingTypes.MoneyAmountDTO>({
|
||||
id: moneyAmountId,
|
||||
entityName: MoneyAmount.name,
|
||||
repository: this.moneyAmountRepository_,
|
||||
config,
|
||||
sharedContext,
|
||||
})) as TEntity
|
||||
}
|
||||
|
||||
@InjectManager("moneyAmountRepository_")
|
||||
async list(
|
||||
filters: PricingTypes.FilterableMoneyAmountProps = {},
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TEntity[]> {
|
||||
return (await this.moneyAmountRepository_.find(
|
||||
this.buildQueryForList(filters, config),
|
||||
sharedContext
|
||||
)) as TEntity[]
|
||||
}
|
||||
|
||||
@InjectManager("moneyAmountRepository_")
|
||||
async listAndCount(
|
||||
filters: PricingTypes.FilterableMoneyAmountProps = {},
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<[TEntity[], number]> {
|
||||
return (await this.moneyAmountRepository_.findAndCount(
|
||||
this.buildQueryForList(filters, config),
|
||||
sharedContext
|
||||
)) as [TEntity[], number]
|
||||
}
|
||||
|
||||
private buildQueryForList(
|
||||
filters: PricingTypes.FilterableMoneyAmountProps = {},
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {}
|
||||
) {
|
||||
const queryOptions = ModulesSdkUtils.buildQuery<MoneyAmount>(
|
||||
filters,
|
||||
config
|
||||
)
|
||||
|
||||
if (filters.id) {
|
||||
queryOptions.where["id"] = { $in: filters.id }
|
||||
}
|
||||
|
||||
return queryOptions
|
||||
}
|
||||
|
||||
@InjectTransactionManager(shouldForceTransaction, "moneyAmountRepository_")
|
||||
async create(
|
||||
data: PricingTypes.CreateMoneyAmountDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TEntity[]> {
|
||||
return (await (this.moneyAmountRepository_ as MoneyAmountRepository).create(
|
||||
data,
|
||||
sharedContext
|
||||
)) as TEntity[]
|
||||
}
|
||||
|
||||
@InjectTransactionManager(shouldForceTransaction, "moneyAmountRepository_")
|
||||
async update(
|
||||
data: PricingTypes.UpdateMoneyAmountDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<TEntity[]> {
|
||||
return (await (this.moneyAmountRepository_ as MoneyAmountRepository).update(
|
||||
data,
|
||||
sharedContext
|
||||
)) as TEntity[]
|
||||
}
|
||||
|
||||
@InjectTransactionManager(doNotForceTransaction, "moneyAmountRepository_")
|
||||
async delete(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<void> {
|
||||
await this.moneyAmountRepository_.delete(ids, sharedContext)
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,11 @@ import {
|
||||
DAL,
|
||||
FindConfig,
|
||||
InternalModuleDeclaration,
|
||||
JoinerServiceConfig,
|
||||
ModuleJoinerConfig,
|
||||
PricingTypes,
|
||||
} from "@medusajs/types"
|
||||
import { Currency } from "@models"
|
||||
import { CurrencyService } from "@services"
|
||||
import { Currency, MoneyAmount } from "@models"
|
||||
import { CurrencyService, MoneyAmountService } from "@services"
|
||||
|
||||
import {
|
||||
InjectManager,
|
||||
@@ -21,26 +21,142 @@ import { joinerConfig } from "../joiner-config"
|
||||
type InjectedDependencies = {
|
||||
baseRepository: DAL.RepositoryService
|
||||
currencyService: CurrencyService<any>
|
||||
moneyAmountService: MoneyAmountService<any>
|
||||
}
|
||||
|
||||
export default class PricingModuleService<TCurrency extends Currency = Currency>
|
||||
implements PricingTypes.IPricingModuleService
|
||||
export default class PricingModuleService<
|
||||
TMoneyAmount extends MoneyAmount = MoneyAmount,
|
||||
TCurrency extends Currency = Currency
|
||||
> implements PricingTypes.IPricingModuleService
|
||||
{
|
||||
protected baseRepository_: DAL.RepositoryService
|
||||
protected readonly currencyService_: CurrencyService<TCurrency>
|
||||
protected readonly moneyAmountService_: MoneyAmountService<TMoneyAmount>
|
||||
|
||||
constructor(
|
||||
{ baseRepository, currencyService }: InjectedDependencies,
|
||||
{
|
||||
baseRepository,
|
||||
moneyAmountService,
|
||||
currencyService,
|
||||
}: InjectedDependencies,
|
||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||
) {
|
||||
this.baseRepository_ = baseRepository
|
||||
this.currencyService_ = currencyService
|
||||
this.moneyAmountService_ = moneyAmountService
|
||||
}
|
||||
|
||||
__joinerConfig(): JoinerServiceConfig {
|
||||
__joinerConfig(): ModuleJoinerConfig {
|
||||
return joinerConfig
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
async retrieve(
|
||||
id: string,
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PricingTypes.MoneyAmountDTO> {
|
||||
const moneyAmount = await this.moneyAmountService_.retrieve(
|
||||
id,
|
||||
config,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO>(
|
||||
moneyAmount,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
async list(
|
||||
filters: PricingTypes.FilterableMoneyAmountProps = {},
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<PricingTypes.MoneyAmountDTO[]> {
|
||||
const moneyAmounts = await this.moneyAmountService_.list(
|
||||
filters,
|
||||
config,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO[]>(
|
||||
moneyAmounts,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
async listAndCount(
|
||||
filters: PricingTypes.FilterableMoneyAmountProps = {},
|
||||
config: FindConfig<PricingTypes.MoneyAmountDTO> = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<[PricingTypes.MoneyAmountDTO[], number]> {
|
||||
const [moneyAmounts, count] = await this.moneyAmountService_.listAndCount(
|
||||
filters,
|
||||
config,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return [
|
||||
await this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO[]>(
|
||||
moneyAmounts,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
),
|
||||
count,
|
||||
]
|
||||
}
|
||||
|
||||
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||
async create(
|
||||
data: PricingTypes.CreateMoneyAmountDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
) {
|
||||
const moneyAmounts = await this.moneyAmountService_.create(
|
||||
data,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO[]>(
|
||||
moneyAmounts,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||
async update(
|
||||
data: PricingTypes.UpdateMoneyAmountDTO[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
) {
|
||||
const moneyAmounts = await this.moneyAmountService_.update(
|
||||
data,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return this.baseRepository_.serialize<PricingTypes.MoneyAmountDTO[]>(
|
||||
moneyAmounts,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||
async delete(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<void> {
|
||||
await this.moneyAmountService_.delete(ids, sharedContext)
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
async retrieveCurrency(
|
||||
code: string,
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from "./currency"
|
||||
export * from "./money-amount"
|
||||
|
||||
33
packages/types/src/pricing/common/money-amount.ts
Normal file
33
packages/types/src/pricing/common/money-amount.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { BaseFilterable } from "../../dal"
|
||||
import { CreateCurrencyDTO, CurrencyDTO } from "./currency"
|
||||
|
||||
export interface MoneyAmountDTO {
|
||||
id: string
|
||||
currency_code?: string
|
||||
currency?: CurrencyDTO
|
||||
amount?: number
|
||||
min_quantity?: number
|
||||
max_quantity?: number
|
||||
}
|
||||
|
||||
export interface CreateMoneyAmountDTO {
|
||||
id: string
|
||||
currency_code: string
|
||||
currency?: CreateCurrencyDTO
|
||||
amount?: number
|
||||
min_quantity?: number
|
||||
max_quantity?: number
|
||||
}
|
||||
|
||||
export interface UpdateMoneyAmountDTO {
|
||||
id: string
|
||||
currency_code?: string
|
||||
amount?: number
|
||||
min_quantity?: number
|
||||
max_quantity?: number
|
||||
}
|
||||
|
||||
export interface FilterableMoneyAmountProps
|
||||
extends BaseFilterable<FilterableMoneyAmountProps> {
|
||||
id?: string[]
|
||||
}
|
||||
@@ -1,14 +1,49 @@
|
||||
import { FindConfig } from "../common"
|
||||
import { JoinerServiceConfig } from "../joiner"
|
||||
import { ModuleJoinerConfig } from "../modules-sdk"
|
||||
import { Context } from "../shared-context"
|
||||
import {
|
||||
CreateCurrencyDTO,
|
||||
CreateMoneyAmountDTO,
|
||||
CurrencyDTO,
|
||||
FilterableCurrencyProps,
|
||||
FilterableMoneyAmountProps,
|
||||
MoneyAmountDTO,
|
||||
UpdateCurrencyDTO,
|
||||
UpdateMoneyAmountDTO,
|
||||
} from "./common"
|
||||
|
||||
export interface IPricingModuleService {
|
||||
__joinerConfig(): JoinerServiceConfig
|
||||
__joinerConfig(): ModuleJoinerConfig
|
||||
|
||||
retrieve(
|
||||
id: string,
|
||||
config?: FindConfig<MoneyAmountDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<MoneyAmountDTO>
|
||||
|
||||
list(
|
||||
filters?: FilterableMoneyAmountProps,
|
||||
config?: FindConfig<MoneyAmountDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<MoneyAmountDTO[]>
|
||||
|
||||
listAndCount(
|
||||
filters?: FilterableMoneyAmountProps,
|
||||
config?: FindConfig<MoneyAmountDTO>,
|
||||
sharedContext?: Context
|
||||
): Promise<[MoneyAmountDTO[], number]>
|
||||
|
||||
create(
|
||||
data: CreateMoneyAmountDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<MoneyAmountDTO[]>
|
||||
|
||||
update(
|
||||
data: UpdateMoneyAmountDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<MoneyAmountDTO[]>
|
||||
|
||||
delete(ids: string[], sharedContext?: Context): Promise<void>
|
||||
|
||||
retrieveCurrency(
|
||||
code: string,
|
||||
|
||||
Reference in New Issue
Block a user