feat(medusa): Separate money amount and variant (#4906)
* initial changes * working test * final changes to product tests * update integration tests * update price list integration tests * update integration tests * update unit tests * update plugin integration tests * remove catch from integration test * undo change * add andWhere * update upsertCurrencyMoneyAmount method * undo line item changes * undo changes * update deprecated method * Update packages/medusa/src/migrations/1692953518123-drop_money_amount_constraints_for_pricing_module.ts Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> * rename joinTable * update with joinTable entity * update load methods * remove await create * re-add context test * update price list behavior for prices * update price list snapshots * re-add admin seeder * pr feedback * fix unit tests * fix plugin integration tests * initial review changes * redo changes to variant creation --------- Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
co-authored by
Carlos R. L. Rodrigues
Oli Juhl
parent
3d68be2b6b
commit
5d10c46bb1
@@ -0,0 +1,36 @@
|
||||
|
||||
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'
|
||||
}]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
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,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",
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user