From 5d10c46bb1d8e87f72ef1f09c5b6e7a067440ba7 Mon Sep 17 00:00:00 2001 From: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com> Date: Wed, 13 Sep 2023 13:26:20 +0200 Subject: [PATCH] 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> --- .../admin/__snapshots__/price-list.js.snap | 37 +- .../api/__tests__/admin/order/order.js | 4 +- .../api/__tests__/admin/price-list.js | 36 + .../api/__tests__/admin/product.js | 6 +- .../admin/products/ff-product-categories.js | 4 +- .../api/__tests__/admin/returns.js | 4 +- .../__tests__/batch-jobs/price-list/import.js | 5 - .../api/__tests__/price-selection/index.js | 12 +- .../price-selection/tax-inclusive-prices.js | 12 +- .../api/__tests__/store/cart/cart.js | 10 +- .../development/database/customer.js | 2 +- .../factories/simple-price-list-factory.ts | 21 +- .../factories/simple-product-factory.ts | 2 +- .../simple-product-variant-factory.ts | 17 +- .../helpers/admin-variants-seeder.js | 146 ++- integration-tests/helpers/cart-seeder.js | 335 ++++-- integration-tests/helpers/customer-seeder.js | 18 +- .../helpers/draft-order-seeder.js | 53 +- integration-tests/helpers/order-seeder.js | 45 +- .../helpers/price-list-seeder.js | 38 +- .../helpers/price-selection-seeder.js | 1048 +++++++++++------ integration-tests/helpers/product-seeder.js | 137 ++- .../helpers/store-product-seeder.js | 204 +++- integration-tests/helpers/swap-seeder.js | 2 +- integration-tests/helpers/user-seeder.js | 6 +- .../plugins/__tests__/cart/store/index.ts | 8 +- .../src/api/routes/admin/price-lists/index.ts | 29 +- .../price-lists/list-price-list-products.ts | 2 +- .../src/api/routes/admin/products/index.ts | 1 - .../routes/admin/products/list-products.ts | 8 +- ...e-item-tax-adjustment-on-cascade-delete.ts | 4 +- ...3273-add-table-product-shipping-profile.ts | 4 +- ...y_amount_constraints_for_pricing_module.ts | 50 + packages/medusa/src/models/index.ts | 1 + packages/medusa/src/models/money-amount.ts | 49 +- .../medusa/src/models/product-category.ts | 2 +- .../models/product-variant-money-amount.ts | 21 + packages/medusa/src/models/product-variant.ts | 18 +- .../medusa/src/repositories/money-amount.ts | 311 ++++- .../src/services/__tests__/price-list.js | 7 +- .../src/services/__tests__/product-variant.js | 31 +- packages/medusa/src/services/price-list.ts | 61 +- packages/medusa/src/services/pricing.ts | 16 +- .../medusa/src/services/product-variant.ts | 113 +- .../batch-jobs/price-list/import.ts | 24 +- .../medusa/src/strategies/price-selection.ts | 10 +- packages/medusa/src/types/price-list.ts | 1 + .../__fixtures__/price-list/data.ts | 36 + .../__fixtures__/price-list/index.ts | 25 + .../services/price-list/index.spec.ts | 335 ++++++ .../__fixtures__/product-category/index.ts | 2 +- packages/product/src/scripts/seed.ts | 2 +- 52 files changed, 2465 insertions(+), 910 deletions(-) create mode 100644 packages/medusa/src/migrations/1692953518123-drop_money_amount_constraints_for_pricing_module.ts create mode 100644 packages/medusa/src/models/product-variant-money-amount.ts create mode 100644 packages/pricing/integration-tests/__fixtures__/price-list/data.ts create mode 100644 packages/pricing/integration-tests/__fixtures__/price-list/index.ts create mode 100644 packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts diff --git a/integration-tests/api/__tests__/admin/__snapshots__/price-list.js.snap b/integration-tests/api/__tests__/admin/__snapshots__/price-list.js.snap index 08b9f4d089..3eb969b1c4 100644 --- a/integration-tests/api/__tests__/admin/__snapshots__/price-list.js.snap +++ b/integration-tests/api/__tests__/admin/__snapshots__/price-list.js.snap @@ -21,7 +21,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 80, @@ -34,7 +36,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 50, @@ -47,7 +51,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, ], "starts_at": "2022-07-01T00:00:00.000Z", @@ -87,7 +93,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 80, @@ -100,7 +108,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 50, @@ -113,7 +123,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 85, @@ -126,7 +138,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant_1", + "variants": Any, }, Object { "amount": 10, @@ -139,7 +153,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, ], "starts_at": "2022-09-01T00:00:00.000Z", @@ -161,7 +177,9 @@ Object { "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, } `; @@ -178,7 +196,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 35, @@ -191,7 +211,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 25, @@ -204,7 +226,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, ] `; @@ -222,7 +246,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 80, @@ -235,7 +261,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 50, @@ -248,7 +276,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 45, @@ -261,7 +291,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 35, @@ -274,7 +306,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, Object { "amount": 25, @@ -287,8 +321,9 @@ Array [ "price_list_id": "pl_no_customer_groups", "region_id": null, "updated_at": Any, + "variant": Any, "variant_id": "test-variant", + "variants": Any, }, ] `; - diff --git a/integration-tests/api/__tests__/admin/order/order.js b/integration-tests/api/__tests__/admin/order/order.js index 836dbc6e84..9b98863d62 100644 --- a/integration-tests/api/__tests__/admin/order/order.js +++ b/integration-tests/api/__tests__/admin/order/order.js @@ -1177,7 +1177,7 @@ describe("/admin/orders", () => { const manager = dbConnection.manager // add a shipping method so we can fulfill the swap - const sm = await manager.create(ShippingMethod, { + const sm = manager.create(ShippingMethod, { id: "test-method-swap-cart", swap_id: sid, shipping_option_id: "test-option", @@ -1654,7 +1654,7 @@ describe("/admin/orders", () => { ) }) - it.only("fails to lists all orders with an invalid status", async () => { + it("fails to lists all orders with an invalid status", async () => { expect.assertions(3) const api = useApi() diff --git a/integration-tests/api/__tests__/admin/price-list.js b/integration-tests/api/__tests__/admin/price-list.js index e8087774c5..5c50792b2f 100644 --- a/integration-tests/api/__tests__/admin/price-list.js +++ b/integration-tests/api/__tests__/admin/price-list.js @@ -168,6 +168,8 @@ describe("/admin/price-lists", () => { price_list_id: "pl_no_customer_groups", created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -179,6 +181,8 @@ describe("/admin/price-lists", () => { price_list_id: "pl_no_customer_groups", created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -190,6 +194,8 @@ describe("/admin/price-lists", () => { price_list_id: "pl_no_customer_groups", created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, ], created_at: expect.any(String), @@ -452,6 +458,8 @@ describe("/admin/price-lists", () => { region_id: null, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), deleted_at: null, }, { @@ -461,6 +469,8 @@ describe("/admin/price-lists", () => { min_quantity: 101, max_quantity: 500, variant_id: "test-variant", + variant: expect.any(Object), + variants: expect.any(Array), price_list_id: "pl_no_customer_groups", region_id: null, created_at: expect.any(String), @@ -474,6 +484,8 @@ describe("/admin/price-lists", () => { min_quantity: 501, max_quantity: 1000, variant_id: "test-variant", + variant: expect.any(Object), + variants: expect.any(Array), price_list_id: "pl_no_customer_groups", region_id: null, created_at: expect.any(String), @@ -485,6 +497,8 @@ describe("/admin/price-lists", () => { amount: 85, currency_code: "usd", variant_id: "test-variant_1", + variant: expect.any(Object), + variants: expect.any(Array), price_list_id: "pl_no_customer_groups", min_quantity: null, max_quantity: null, @@ -498,6 +512,8 @@ describe("/admin/price-lists", () => { amount: 10, currency_code: "usd", variant_id: "test-variant", + variant: expect.any(Object), + variants: expect.any(Array), price_list_id: "pl_no_customer_groups", min_quantity: null, max_quantity: null, @@ -560,6 +576,8 @@ describe("/admin/price-lists", () => { region_id: null, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }) }) @@ -690,6 +708,8 @@ describe("/admin/price-lists", () => { variant_id: "test-variant", created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -701,6 +721,8 @@ describe("/admin/price-lists", () => { variant_id: "test-variant", created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -712,6 +734,8 @@ describe("/admin/price-lists", () => { variant_id: "test-variant", created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -723,6 +747,8 @@ describe("/admin/price-lists", () => { max_quantity: 2000, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -734,6 +760,8 @@ describe("/admin/price-lists", () => { max_quantity: 3000, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -745,6 +773,8 @@ describe("/admin/price-lists", () => { max_quantity: 4000, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, ]) }) @@ -802,6 +832,8 @@ describe("/admin/price-lists", () => { max_quantity: 2000, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -813,6 +845,8 @@ describe("/admin/price-lists", () => { max_quantity: 3000, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, { id: expect.any(String), @@ -824,6 +858,8 @@ describe("/admin/price-lists", () => { max_quantity: 4000, created_at: expect.any(String), updated_at: expect.any(String), + variant: expect.any(Object), + variants: expect.any(Array), }, ]) }) diff --git a/integration-tests/api/__tests__/admin/product.js b/integration-tests/api/__tests__/admin/product.js index 378dbb4006..cb2f88b953 100644 --- a/integration-tests/api/__tests__/admin/product.js +++ b/integration-tests/api/__tests__/admin/product.js @@ -372,10 +372,10 @@ describe("/admin/products", () => { expect(expectedVariantPrices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price4", + id: "test-price_4", }), expect.objectContaining({ - id: "test-price3", + id: "test-price_3", }), ]) ) @@ -1665,6 +1665,7 @@ describe("/admin/products", () => { it("successfully updates a variant's price by changing an existing price (given a region_id)", async () => { const api = useApi() + const data = { prices: [ { @@ -1745,6 +1746,7 @@ describe("/admin/products", () => { expect.objectContaining({ amount: 100, currency_code: "usd", + id: "test-price", }), expect.objectContaining({ amount: 4500, diff --git a/integration-tests/api/__tests__/admin/products/ff-product-categories.js b/integration-tests/api/__tests__/admin/products/ff-product-categories.js index 8e11aaa2b1..7fc6aef453 100644 --- a/integration-tests/api/__tests__/admin/products/ff-product-categories.js +++ b/integration-tests/api/__tests__/admin/products/ff-product-categories.js @@ -222,14 +222,14 @@ describe("/admin/products [MEDUSA_FF_PRODUCT_CATEGORIES=true]", () => { }) const manager = dbConnection.manager - categoryWithProduct = await manager.create(ProductCategory, { + categoryWithProduct = manager.create(ProductCategory, { id: categoryWithProductId, name: "category with Product", products: [{ id: testProductId }], }) await manager.save(categoryWithProduct) - categoryWithoutProduct = await manager.create(ProductCategory, { + categoryWithoutProduct = manager.create(ProductCategory, { id: categoryWithoutProductId, name: "category without product", }) diff --git a/integration-tests/api/__tests__/admin/returns.js b/integration-tests/api/__tests__/admin/returns.js index c89b7eae31..eb7852e668 100644 --- a/integration-tests/api/__tests__/admin/returns.js +++ b/integration-tests/api/__tests__/admin/returns.js @@ -1,5 +1,7 @@ const path = require("path") + import { ReturnReason, ShippingMethod } from "@medusajs/medusa" + import { createReturnableOrder } from "../claims" const setupServer = require("../../../environment-helpers/setup-server") @@ -77,7 +79,7 @@ describe("/admin/returns", () => { const manager = dbConnection.manager // add a shipping method so we can fulfill the swap - const sm = await manager.create(ShippingMethod, { + const sm = manager.create(ShippingMethod, { id: "test-method-swap-cart", swap_id: sid, shipping_option_id: "test-option", diff --git a/integration-tests/api/__tests__/batch-jobs/price-list/import.js b/integration-tests/api/__tests__/batch-jobs/price-list/import.js index 1913550148..a32344a83a 100644 --- a/integration-tests/api/__tests__/batch-jobs/price-list/import.js +++ b/integration-tests/api/__tests__/batch-jobs/price-list/import.js @@ -196,28 +196,23 @@ describe("Price list import batch job", () => { expect(priceListRes.data.price_list.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - variant_id: "test-pl-variant", currency_code: "usd", amount: 1111, }), expect.objectContaining({ - variant_id: "test-pl-variant", currency_code: "eur", region_id: "test-pl-region", amount: 2222, }), expect.objectContaining({ - variant_id: "test-pl-variant", currency_code: "jpy", amount: 3333, }), expect.objectContaining({ - variant_id: "test-pl-sku-variant", currency_code: "usd", amount: 4444, }), expect.objectContaining({ - variant_id: "test-pl-sku-variant", currency_code: "eur", region_id: "test-pl-region", amount: 5555, diff --git a/integration-tests/api/__tests__/price-selection/index.js b/integration-tests/api/__tests__/price-selection/index.js index f4bcdf6ec9..000db1ade4 100644 --- a/integration-tests/api/__tests__/price-selection/index.js +++ b/integration-tests/api/__tests__/price-selection/index.js @@ -86,13 +86,13 @@ describe("Promotions", () => { expect(variant.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price1", + id: "test-price-1", region_id: "test-region", currency_code: "usd", amount: 120, }), expect.objectContaining({ - id: "test-price3", + id: "test-price-3", region_id: "test-region", currency_code: "usd", price_list_id: "pl", @@ -141,13 +141,13 @@ describe("Promotions", () => { expect(variant.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price1", + id: "test-price-1", region_id: "test-region", currency_code: "usd", amount: 120, }), expect.objectContaining({ - id: "test-price3", + id: "test-price-3", region_id: "test-region", currency_code: "usd", price_list_id: "pl", @@ -436,13 +436,13 @@ describe("Promotions", () => { expect(variant.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price1", + id: "test-price-1", region_id: "test-region", currency_code: "usd", amount: 120, }), expect.objectContaining({ - id: "test-price3", + id: "test-price-3", region_id: "test-region", currency_code: "usd", price_list_id: "pl", diff --git a/integration-tests/api/__tests__/price-selection/tax-inclusive-prices.js b/integration-tests/api/__tests__/price-selection/tax-inclusive-prices.js index 9bee85d65f..2cb356acfa 100644 --- a/integration-tests/api/__tests__/price-selection/tax-inclusive-prices.js +++ b/integration-tests/api/__tests__/price-selection/tax-inclusive-prices.js @@ -804,13 +804,13 @@ describe("tax inclusive prices", () => { expect(variant.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price1", + id: "test-price-1", region_id: "test-region", currency_code: "usd", amount: 120, }), expect.objectContaining({ - id: "test-price3", + id: "test-price-3", region_id: "test-region", currency_code: "usd", price_list_id: "pl", @@ -859,13 +859,13 @@ describe("tax inclusive prices", () => { expect(variant.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price1", + id: "test-price-1", region_id: "test-region", currency_code: "usd", amount: 120, }), expect.objectContaining({ - id: "test-price3", + id: "test-price-3", region_id: "test-region", currency_code: "usd", price_list_id: "pl", @@ -1154,13 +1154,13 @@ describe("tax inclusive prices", () => { expect(variant.prices).toEqual( expect.arrayContaining([ expect.objectContaining({ - id: "test-price1", + id: "test-price-1", region_id: "test-region", currency_code: "usd", amount: 120, }), expect.objectContaining({ - id: "test-price3", + id: "test-price-3", region_id: "test-region", currency_code: "usd", price_list_id: "pl", diff --git a/integration-tests/api/__tests__/store/cart/cart.js b/integration-tests/api/__tests__/store/cart/cart.js index a17602d7f4..1061bb75e4 100644 --- a/integration-tests/api/__tests__/store/cart/cart.js +++ b/integration-tests/api/__tests__/store/cart/cart.js @@ -32,6 +32,7 @@ const { const { simpleCustomerGroupFactory, } = require("../../../../factories/simple-customer-group-factory") +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") jest.setTimeout(30000) @@ -144,7 +145,6 @@ describe("/store/carts", () => { await dbConnection.manager.save(priceList1) const ma_sale_1 = dbConnection.manager.create(MoneyAmount, { - variant_id: prodSale.variants[0].id, currency_code: "usd", amount: 800, price_list_id: "pl_current", @@ -152,6 +152,12 @@ describe("/store/carts", () => { await dbConnection.manager.save(ma_sale_1) + await dbConnection.manager.insert(ProductVariantMoneyAmount, { + id: `${prodSale.variants[0].id}-${ma_sale_1.id}`, + variant_id: prodSale.variants[0].id, + money_amount_id: ma_sale_1.id, + }) + const api = useApi() const response = await api @@ -2289,7 +2295,7 @@ describe("/store/carts", () => { await cartSeeder(dbConnection) const manager = dbConnection.manager - const _cart = await manager.create(Cart, { + const _cart = manager.create(Cart, { id: "test-cart-with-cso", customer_id: "some-customer", email: "some-customer@email.com", diff --git a/integration-tests/development/database/customer.js b/integration-tests/development/database/customer.js index 18b20bed8c..6277fac991 100644 --- a/integration-tests/development/database/customer.js +++ b/integration-tests/development/database/customer.js @@ -3,7 +3,7 @@ const { Customer } = require("@medusajs/medusa") module.exports = async (connection) => { const manager = connection.manager - const customer = await manager.create(Customer, { + const customer = manager.create(Customer, { id: "customer-1", email: "test1@email.com", first_name: "John", diff --git a/integration-tests/factories/simple-price-list-factory.ts b/integration-tests/factories/simple-price-list-factory.ts index 2a0000edd3..81c2214769 100644 --- a/integration-tests/factories/simple-price-list-factory.ts +++ b/integration-tests/factories/simple-price-list-factory.ts @@ -5,9 +5,11 @@ import { PriceListStatus, PriceListType, } from "@medusajs/medusa" -import faker from "faker" + import { DataSource } from "typeorm" +import faker from "faker" import { simpleCustomerGroupFactory } from "./simple-customer-group-factory" +import { ProductVariantMoneyAmount } from "@medusajs/medusa" type ProductListPrice = { variant_id: string @@ -64,18 +66,27 @@ export const simplePriceListFactory = async ( } const toSave = manager.create(PriceList, toCreate) - const toReturn = await manager.save(toSave) + const toReturn = await manager.save(toSave) as PriceList if (typeof data.prices !== "undefined") { - for (const ma of data.prices) { + toReturn.prices = await Promise.all(data.prices.map(async (ma) => { const factoryData = { ...ma, price_list_id: listId, } - const toSave = manager.create(MoneyAmount, factoryData) + const toSave: MoneyAmount = manager.create(MoneyAmount, factoryData) await manager.save(toSave) - } + + await manager.insert(ProductVariantMoneyAmount, { + id: `${ma.variant_id}-${toSave.id}`, + variant_id: ma.variant_id, + money_amount_id: toSave.id, + }) + + return toSave + })) } + return toReturn } diff --git a/integration-tests/factories/simple-product-factory.ts b/integration-tests/factories/simple-product-factory.ts index 703a66e491..c995d05a46 100644 --- a/integration-tests/factories/simple-product-factory.ts +++ b/integration-tests/factories/simple-product-factory.ts @@ -27,7 +27,7 @@ export type ProductFactoryData = { type?: string tags?: string[] options?: { id: string; title: string }[] - variants?: ProductVariantFactoryData[] + variants?: Omit[] sales_channels?: SalesChannelFactoryData[] metadata?: Record } diff --git a/integration-tests/factories/simple-product-variant-factory.ts b/integration-tests/factories/simple-product-variant-factory.ts index ca8bd54da5..ade5fe82c3 100644 --- a/integration-tests/factories/simple-product-variant-factory.ts +++ b/integration-tests/factories/simple-product-variant-factory.ts @@ -1,11 +1,13 @@ -import { DataSource } from "typeorm" -import faker from "faker" import { MoneyAmount, ProductOptionValue, ProductVariant, + ProductVariantMoneyAmount, } from "@medusajs/medusa" +import { DataSource } from "typeorm" +import faker from "faker" + export type ProductVariantFactoryData = { product_id: string id?: string @@ -31,6 +33,7 @@ export const simpleProductVariantFactory = async ( const manager = dataSource.manager const id = data.id || `simple-variant-${Math.random() * 1000}` + const toSave = manager.create(ProductVariant, { id, product_id: data.product_id, @@ -61,13 +64,19 @@ export const simpleProductVariantFactory = async ( const prices = data.prices || [{ currency: "usd", amount: 100 }] for (const p of prices) { + const ma_id = `${p.currency}-${p.amount}-${Math.random()}` await manager.insert(MoneyAmount, { - id: `${p.currency}-${p.amount}-${Math.random()}`, - variant_id: id, + id: ma_id, currency_code: p.currency, amount: p.amount, region_id: p.region_id, }) + + await manager.insert(ProductVariantMoneyAmount, { + id: `${ma_id}-${id}-${Math.random()}`, + money_amount_id: ma_id, + variant_id: id, + }) } return variant diff --git a/integration-tests/helpers/admin-variants-seeder.js b/integration-tests/helpers/admin-variants-seeder.js index 2698bb3bc5..1f1153a399 100644 --- a/integration-tests/helpers/admin-variants-seeder.js +++ b/integration-tests/helpers/admin-variants-seeder.js @@ -1,3 +1,5 @@ +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") +const { MoneyAmount } = require("@medusajs/medusa") const { Region, Product, @@ -48,7 +50,7 @@ module.exports = async (dataSource, data = {}) => { tax_rate: 0, }) - const customer = await manager.create(Customer, { + const customer = manager.create(Customer, { id: "test-customer", email: "john@doe.com", first_name: "John", @@ -58,7 +60,7 @@ module.exports = async (dataSource, data = {}) => { has_account: true, }) - const customerGroup = await manager.create(CustomerGroup, { + const customerGroup = manager.create(CustomerGroup, { id: "test-group", name: "test-group", }) @@ -67,7 +69,7 @@ module.exports = async (dataSource, data = {}) => { customer.groups = [customerGroup] await manager.save(customer) - const priceListActive = await manager.create(PriceList, { + const priceListActive = manager.create(PriceList, { id: "pl", name: "VIP sale", description: "All year sale for VIP customers.", @@ -77,7 +79,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceListActive) - const priceListExpired = await manager.create(PriceList, { + const priceListExpired = manager.create(PriceList, { id: "pl_expired", name: "VIP summer sale", description: "Summer sale for VIP customers.", @@ -89,7 +91,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceListExpired) - const priceListWithCustomers = await manager.create(PriceList, { + const priceListWithCustomers = manager.create(PriceList, { id: "pl_with_customers", name: "VIP winter sale", description: "Winter sale for VIP customers.", @@ -127,7 +129,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product", }) - const variantMultiReg = await manager.create(ProductVariant, { + const variantMultiReg = manager.create(ProductVariant, { id: "test-variant", inventory_quantity: 10, title: "Test variant", @@ -137,49 +139,6 @@ module.exports = async (dataSource, data = {}) => { upc: "test-upc", barcode: "test-barcode", product_id: "test-product", - prices: [ - { - id: "test-price-multi-usd", - currency_code: "usd", - type: "default", - amount: 100, - }, - { - id: "test-price-discount-multi-usd", - currency_code: "usd", - amount: 80, - price_list_id: "pl", - }, - { - id: "test-price-discount-expired-multi-usd", - currency_code: "usd", - amount: 70, - price_list_id: "pl_expired", - }, - { - id: "test-price-multi-eur", - currency_code: "eur", - amount: 100, - }, - { - id: "test-price-discount-multi-eur", - currency_code: "eur", - amount: 80, - price_list_id: "pl", - }, - { - id: "test-price-discount-multi-eur-with-customer", - currency_code: "eur", - amount: 40, - price_list_id: "pl_with_customers", - }, - { - id: "test-price-discount-expired-multi-eur", - currency_code: "eur", - amount: 70, - price_list_id: "pl_expired", - }, - ], options: [ { id: "test-variant-option-reg", @@ -189,5 +148,94 @@ module.exports = async (dataSource, data = {}) => { ], }) + await manager.insert(MoneyAmount, { + id: "test-price-multi-usd", + currency_code: "usd", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma", + money_amount_id: "test-price-multi-usd", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount-multi-usd", + currency_code: "usd", + amount: 80, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma1", + money_amount_id: "test-price-discount-multi-usd", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount-expired-multi-usd", + currency_code: "usd", + amount: 70, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma2", + money_amount_id: "test-price-discount-expired-multi-usd", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-multi-eur", + currency_code: "eur", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma3", + money_amount_id: "test-price-multi-eur", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount-multi-eur", + currency_code: "eur", + amount: 80, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma4", + money_amount_id: "test-price-discount-multi-eur", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount-multi-eur-with-customer", + currency_code: "eur", + amount: 40, + price_list_id: "pl_with_customers", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma5", + money_amount_id: "test-price-discount-multi-eur-with-customer", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount-expired-multi-eur", + currency_code: "eur", + amount: 70, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma6", + money_amount_id: "test-price-discount-expired-multi-eur", + variant_id: "test-variant", + }) + await manager.save(variantMultiReg) } diff --git a/integration-tests/helpers/cart-seeder.js b/integration-tests/helpers/cart-seeder.js index b539c68772..1d76f44726 100644 --- a/integration-tests/helpers/cart-seeder.js +++ b/integration-tests/helpers/cart-seeder.js @@ -1,3 +1,5 @@ +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") +const { ProductOption } = require("@medusajs/medusa") const { Customer, Region, @@ -86,7 +88,7 @@ module.exports = async (dataSource, data = {}) => { `UPDATE "country" SET region_id='test-region-multiple' WHERE iso_2 = 'dk'` ) - const customer5 = await manager.create(Customer, { + const customer5 = manager.create(Customer, { id: "test-customer-5", email: "test5@email.com", first_name: "John", @@ -97,7 +99,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(customer5) - const c_group_5 = await manager.create(CustomerGroup, { + const c_group_5 = manager.create(CustomerGroup, { id: "test-group-5", name: "test-group-5", }) @@ -106,7 +108,7 @@ module.exports = async (dataSource, data = {}) => { customer5.groups = [c_group_5] await manager.save(customer5) - const priceList_customer = await manager.create(PriceList, { + const priceList_customer = manager.create(PriceList, { id: "pl_customer", name: "VIP winter sale", description: "Winter sale for VIP customers.", @@ -221,7 +223,7 @@ module.exports = async (dataSource, data = {}) => { itemPerc15.rule = itemPerc15Rule await manager.save(itemPerc15) - const dUsageLimit = await manager.create(Discount, { + const dUsageLimit = manager.create(Discount, { id: "test-discount-usage-limit", code: "SPENT", is_dynamic: false, @@ -230,7 +232,7 @@ module.exports = async (dataSource, data = {}) => { usage_count: 10, }) - const drUsage = await manager.create(DiscountRule, { + const drUsage = manager.create(DiscountRule, { id: "test-discount-rule-usage-limit", description: "Created", type: "fixed", @@ -243,14 +245,14 @@ module.exports = async (dataSource, data = {}) => { await manager.save(dUsageLimit) - const d = await manager.create(Discount, { + const d = manager.create(Discount, { id: "test-discount", code: "CREATED", is_dynamic: false, is_disabled: false, }) - const dr = await manager.create(DiscountRule, { + const dr = manager.create(DiscountRule, { id: "test-discount-rule", description: "Created", type: "fixed", @@ -369,12 +371,12 @@ module.exports = async (dataSource, data = {}) => { email: "test@email.com", }) - const c2 = await manager.create(Customer, { + const c2 = manager.create(Customer, { id: "test-customer-2", email: "test-2@email.com", }) - const cg = await manager.create(CustomerGroup, { + const cg = manager.create(CustomerGroup, { id: "cgroup", name: "customer group", }) @@ -422,7 +424,7 @@ module.exports = async (dataSource, data = {}) => { data: {}, }) - const priceList = await manager.create(PriceList, { + const priceList = manager.create(PriceList, { id: "pl", name: "VIP winter sale", description: "Winter sale for VIP customers.", @@ -432,7 +434,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList) - const priceList1 = await manager.create(PriceList, { + const priceList1 = manager.create(PriceList, { id: "pl_current", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -444,6 +446,12 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList1) + const denomOp = manager.create(ProductOption, { + id: "denom", + title: "Denomination", + }) + await manager.save(denomOp) + const giftCardProduct = manager.create(Product, { id: "giftcard-product", title: "Giftcard", @@ -451,11 +459,11 @@ module.exports = async (dataSource, data = {}) => { discountable: false, profile_id: gcProfile.id, profiles: [{ id: gcProfile.id }], - options: [{ id: "denom", title: "Denomination" }], + options: [denomOp], }) await manager.save(Product, giftCardProduct) - await manager.insert(ProductVariant, { + const denom = manager.create(ProductVariant, { id: "giftcard-denom", title: "1000", product_id: "giftcard-product", @@ -467,17 +475,36 @@ module.exports = async (dataSource, data = {}) => { }, ], }) + await manager.save(denom) + + await manager.insert(MoneyAmount, { + id: "test-price_denom", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-denom", + money_amount_id: "test-price_denom", + variant_id: "giftcard-denom", + }) + + const op_1 = manager.create(ProductOption, { + id: "test-option", + title: "Size", + }) + await manager.save(op_1) const testProduct = manager.create(Product, { id: "test-product", title: "test product", profile_id: defaultProfile.id, profiles: [{ id: defaultProfile.id }], - options: [{ id: "test-option", title: "Size" }], + options: [op_1], }) - await manager.save(Product, testProduct) + await manager.save(testProduct) - await manager.insert(ProductVariant, { + const quantityVariant = manager.create(ProductVariant, { id: "test-variant-quantity", title: "test variant", product_id: "test-product", @@ -490,7 +517,48 @@ module.exports = async (dataSource, data = {}) => { ], }) - await manager.insert(ProductVariant, { + await manager.save(quantityVariant) + + await manager.insert(MoneyAmount, { + id: "test-price_quantity-1", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-quantity-1", + money_amount_id: "test-price_quantity-1", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price_quantity-2", + currency_code: "usd", + min_quantity: 10, + max_quantity: 100, + amount: 800, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-quantity-2", + money_amount_id: "test-price_quantity-2", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price_quantity-3", + currency_code: "usd", + min_quantity: 100, + amount: 700, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-quantity-3", + money_amount_id: "test-price_quantity-3", + variant_id: "test-variant-quantity", + }) + + const variantSale = manager.create(ProductVariant, { id: "test-variant-sale", title: "test variant", product_id: "test-product", @@ -503,7 +571,34 @@ module.exports = async (dataSource, data = {}) => { ], }) - await manager.insert(ProductVariant, { + await manager.save(variantSale) + + await manager.insert(MoneyAmount, { + id: "test-price_sale-1", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-sale-1", + money_amount_id: "test-price_sale-1", + variant_id: "test-variant-sale", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-sale-2", + currency_code: "usd", + amount: 800, + price_list_id: "pl_current", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-sale-2", + money_amount_id: "test-price-sale-2", + variant_id: "test-variant-sale", + }) + + const variantSaleCustomer = manager.create(ProductVariant, { id: "test-variant-sale-customer", title: "test variant", product_id: "test-product", @@ -515,8 +610,47 @@ module.exports = async (dataSource, data = {}) => { }, ], }) + await manager.save(variantSaleCustomer) - await manager.insert(ProductVariant, { + await manager.insert(MoneyAmount, { + id: "test-price_sale-customer-1", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-sale-customer-1", + money_amount_id: "test-price_sale-customer-1", + variant_id: "test-variant-sale-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price_sale-customer-2", + currency_code: "usd", + amount: 700, + price_list_id: "pl_customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-sale-customer-2", + money_amount_id: "test-price_sale-customer-2", + variant_id: "test-variant-sale-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-sale-customer-3", + currency_code: "usd", + amount: 800, + price_list_id: "pl_current", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-sale-customer-3", + money_amount_id: "test-price_sale-customer-3", + variant_id: "test-variant-sale-customer", + }) + + const testVariant = manager.create(ProductVariant, { id: "test-variant", title: "test variant", product_id: "test-product", @@ -528,8 +662,33 @@ module.exports = async (dataSource, data = {}) => { }, ], }) + await manager.save(testVariant) - await manager.insert(ProductVariant, { + await manager.insert(MoneyAmount, { + id: "test-price-1", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-1", + money_amount_id: "test-price-1", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-2", + currency_code: "eur", + amount: 2000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-2", + money_amount_id: "test-price-2", + variant_id: "test-variant", + }) + + const variant2 = await manager.insert(ProductVariant, { id: "test-variant-2", title: "test variant 2", product_id: "test-product", @@ -542,107 +701,18 @@ module.exports = async (dataSource, data = {}) => { ], }) - const ma = manager.create(MoneyAmount, { - variant_id: "test-variant", + await manager.insert(MoneyAmount, { + id: "test-price-2-2", currency_code: "usd", - type: "default", - amount: 1000, - }) - await manager.save(ma) - - const maEur = manager.create(MoneyAmount, { - variant_id: "test-variant", - currency_code: "eur", - type: "default", - amount: 2000, - }) - await manager.save(maEur) - - const ma_sale = manager.create(MoneyAmount, { - variant_id: "test-variant-sale", - currency_code: "usd", - amount: 1000, - }) - await manager.save(ma_sale) - - const ma_sale_1 = manager.create(MoneyAmount, { - variant_id: "test-variant-sale", - currency_code: "usd", - amount: 800, - price_list_id: "pl_current", - }) - await manager.save(ma_sale_1) - - const ma_sale_customer = manager.create(MoneyAmount, { - variant_id: "test-variant-sale-customer", - currency_code: "usd", - amount: 1000, - }) - await manager.save(ma_sale_customer) - - const ma_sale_customer_1 = manager.create(MoneyAmount, { - variant_id: "test-variant-sale-customer", - currency_code: "usd", - amount: 700, - price_list_id: "pl_customer", - }) - await manager.save(ma_sale_customer_1) - - const ma_sale_customer_2 = manager.create(MoneyAmount, { - variant_id: "test-variant-sale-customer", - currency_code: "usd", - amount: 800, - price_list_id: "pl_current", - }) - await manager.save(ma_sale_customer_2) - - const ma_quantity = manager.create(MoneyAmount, { - variant_id: "test-variant-quantity", - currency_code: "usd", - type: "default", - amount: 1000, - }) - await manager.save(ma_quantity) - - const ma_quantity_1 = manager.create(MoneyAmount, { - variant_id: "test-variant-quantity", - currency_code: "usd", - type: "sale", - min_quantity: 10, - max_quantity: 100, - amount: 800, - }) - - await manager.save(ma_quantity_1) - - const ma_quantity_2 = manager.create(MoneyAmount, { - variant_id: "test-variant-quantity", - currency_code: "usd", - type: "sale", - min_quantity: 100, - amount: 700, - }) - - await manager.save(ma_quantity_2) - - const ma2 = manager.create(MoneyAmount, { - variant_id: "test-variant-2", - currency_code: "usd", - type: "default", amount: 8000, }) - await manager.save(ma2) - - const ma3 = manager.create(MoneyAmount, { - variant_id: "giftcard-denom", - currency_code: "usd", - type: "default", - amount: 1000, + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-2-1", + money_amount_id: "test-price-2-2", + variant_id: "test-variant-2", }) - await manager.save(ma3) - const cart = manager.create(Cart, { id: "test-cart", customer_id: "some-customer", @@ -908,7 +978,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(cart4) - await manager.insert(ProductVariant, { + const variantSaleCG = manager.create(ProductVariant, { id: "test-variant-sale-cg", title: "test variant", product_id: "test-product", @@ -920,31 +990,46 @@ module.exports = async (dataSource, data = {}) => { }, ], }) + await manager.save(variantSaleCG) - const ma_cg = manager.create(MoneyAmount, { - variant_id: "test-variant-sale-cg", + await manager.insert(MoneyAmount, { + id: "test-test-variant-sale-cg-1", currency_code: "usd", amount: 1000, }) - await manager.save(ma_cg) - const ma_sale_cg = manager.create(MoneyAmount, { + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-cg-1", + money_amount_id: "test-test-variant-sale-cg-1", variant_id: "test-variant-sale-cg", + }) + + await manager.insert(MoneyAmount, { + id: "test-test-variant-sale-cg-2", currency_code: "usd", price_list_id: "pl", amount: 500, }) - await manager.save(ma_sale_cg) - const ma_sale_cg_new_region = manager.create(MoneyAmount, { + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-cg-2", + money_amount_id: "test-test-variant-sale-cg-2", variant_id: "test-variant-sale-cg", - region_id: "test-region-multiple", + }) + + await manager.insert(MoneyAmount, { + id: "test-test-variant-sale-cg-3", currency_code: "eur", amount: 700, }) - await manager.save(ma_sale_cg_new_region) - const li3 = await manager.create(LineItem, { + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-cg-3", + money_amount_id: "test-test-variant-sale-cg-3", + variant_id: "test-variant-sale-cg", + }) + + const li3 = manager.create(LineItem, { id: "test-item3", title: "Line Item", description: "Line Item Desc", diff --git a/integration-tests/helpers/customer-seeder.js b/integration-tests/helpers/customer-seeder.js index fe6085f47b..ab7ef6dddc 100644 --- a/integration-tests/helpers/customer-seeder.js +++ b/integration-tests/helpers/customer-seeder.js @@ -3,7 +3,7 @@ const { Customer, Address, CustomerGroup } = require("@medusajs/medusa") module.exports = async (dataSource, data = {}) => { const manager = dataSource.manager - const testAddr = await manager.create(Address, { + const testAddr = manager.create(Address, { id: "test-address", first_name: "Lebron", last_name: "James", @@ -11,7 +11,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(testAddr) - const customer = await manager.create(Customer, { + const customer = manager.create(Customer, { id: "test-customer-1", email: "test1@email.com", }) @@ -36,25 +36,25 @@ module.exports = async (dataSource, data = {}) => { has_account: true, }) - const customer5 = await manager.create(Customer, { + const customer5 = manager.create(Customer, { id: "test-customer-5", email: "test5@email.com", }) await manager.save(customer5) - const customer6 = await manager.create(Customer, { + const customer6 = manager.create(Customer, { id: "test-customer-6", email: "test6@email.com", }) await manager.save(customer6) - const customer7 = await manager.create(Customer, { + const customer7 = manager.create(Customer, { id: "test-customer-7", email: "test7@email.com", }) await manager.save(customer7) - const deletionCustomer = await manager.create(Customer, { + const deletionCustomer = manager.create(Customer, { id: "test-customer-delete-cg", email: "test-deletetion-cg@email.com", }) @@ -81,13 +81,13 @@ module.exports = async (dataSource, data = {}) => { name: "test-group-4", }) - const c_group_5 = await manager.create(CustomerGroup, { + const c_group_5 = manager.create(CustomerGroup, { id: "test-group-5", name: "test-group-5", }) await manager.save(c_group_5) - const c_group_6 = await manager.create(CustomerGroup, { + const c_group_6 = manager.create(CustomerGroup, { id: "test-group-6", name: "test-group-6", }) @@ -102,7 +102,7 @@ module.exports = async (dataSource, data = {}) => { customer7.groups = [c_group_5, c_group_6] await manager.save(customer7) - const c_group_delete = await manager.create(CustomerGroup, { + const c_group_delete = manager.create(CustomerGroup, { id: "test-group-delete", name: "test-group-delete", }) diff --git a/integration-tests/helpers/draft-order-seeder.js b/integration-tests/helpers/draft-order-seeder.js index 9ed9ec47df..6a0c62732a 100644 --- a/integration-tests/helpers/draft-order-seeder.js +++ b/integration-tests/helpers/draft-order-seeder.js @@ -17,6 +17,8 @@ const { ShippingProfileType, } = require("@medusajs/medusa") const { simpleSalesChannelFactory } = require("../factories") +const { ProductOption } = require("@medusajs/medusa") +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") module.exports = async (dataSource, data = {}) => { const manager = dataSource.manager @@ -30,12 +32,18 @@ module.exports = async (dataSource, data = {}) => { is_default: true, }) + const op = manager.create(ProductOption, { + id: "test-option", + title: "Size", + }) + + await manager.save(op) await manager.insert(Product, { id: "test-product", title: "test product", profile_id: defaultProfile.id, profiles: [{ id: defaultProfile.id }], - options: [{ id: "test-option", title: "Size" }], + options: [op], }) await manager.query( @@ -49,12 +57,18 @@ module.exports = async (dataSource, data = {}) => { country_code: "us", }) + const op1 = manager.create(ProductOption, { + id: "test-option-color", + title: "Color", + }) + await manager.save(op1) + await manager.insert(Product, { id: "test-product-2", title: "test product 2", profile_id: defaultProfile.id, profiles: [{ id: defaultProfile.id }], - options: [{ id: "test-option-color", title: "Color" }], + options: [op1], }) await manager.query( @@ -74,7 +88,7 @@ module.exports = async (dataSource, data = {}) => { ], }) - await manager.insert(ProductVariant, { + const pv1 = manager.create(ProductVariant, { id: "test-variant", title: "test variant", product_id: "test-product", @@ -86,8 +100,21 @@ module.exports = async (dataSource, data = {}) => { }, ], }) + await manager.save(pv1) - await manager.insert(ProductVariant, { + await manager.insert(MoneyAmount, { + id: "test-price", + currency_code: "usd", + amount: 8000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant", + money_amount_id: "test-price", + variant_id: "test-variant", + }) + + const pv2 = manager.create(ProductVariant, { id: "test-variant-2", title: "test variant-2", product_id: "test-product-2", @@ -99,21 +126,19 @@ module.exports = async (dataSource, data = {}) => { }, ], }) + await manager.save(pv2) - const ma = manager.create(MoneyAmount, { - variant_id: "test-variant", - currency_code: "usd", - amount: 8000, - }) - await manager.save(ma) - - const ma2 = manager.create(MoneyAmount, { - variant_id: "test-variant-2", + await manager.insert(MoneyAmount, { + id: "test-price-2", currency_code: "usd", amount: 10000, }) - await manager.save(ma2) + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-2", + money_amount_id: "test-price-2", + variant_id: "test-variant-2", + }) await manager.insert(Region, { id: "test-region", diff --git a/integration-tests/helpers/order-seeder.js b/integration-tests/helpers/order-seeder.js index a6d3c21108..f3b8b323de 100644 --- a/integration-tests/helpers/order-seeder.js +++ b/integration-tests/helpers/order-seeder.js @@ -16,6 +16,8 @@ const { ShippingProfileType, } = require("@medusajs/medusa") const { simpleSalesChannelFactory } = require("../factories") +const { ProductOption } = require("@medusajs/medusa") +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") module.exports = async (dataSource, data = {}) => { const manager = dataSource.manager @@ -34,14 +36,19 @@ module.exports = async (dataSource, data = {}) => { title: "test product", profile_id: defaultProfile.id, profiles: [{ id: defaultProfile.id }], - options: [{ id: "test-option", title: "Size" }], }) await manager.query( `insert into product_sales_channel values ('test-product', '${salesChannel.id}');` ) - await manager.insert(ProductVariant, { + await manager.save(ProductOption, { + id: "test-option", + title: "Size", + product_id: "test-product", + }) + + const variant = manager.create(ProductVariant, { id: "test-variant", title: "test variant", product_id: "test-product", @@ -54,7 +61,21 @@ module.exports = async (dataSource, data = {}) => { ], }) - await manager.insert(ProductVariant, { + await manager.save(variant) + + await manager.insert(MoneyAmount, { + id: "test-price", + currency_code: "usd", + amount: 8000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma", + money_amount_id: "test-price", + variant_id: "test-variant", + }) + + const variant2 = manager.create(ProductVariant, { id: "test-variant-2", title: "Swap product", product_id: "test-product", @@ -67,19 +88,19 @@ module.exports = async (dataSource, data = {}) => { ], }) - const ma2 = manager.create(MoneyAmount, { - variant_id: "test-variant-2", - currency_code: "usd", - amount: 8000, - }) - await manager.save(ma2) + await manager.save(variant2) - const ma = manager.create(MoneyAmount, { - variant_id: "test-variant", + await manager.insert(MoneyAmount, { + id: "test-price_2", currency_code: "usd", amount: 8000, }) - await manager.save(ma) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma4", + money_amount_id: "test-price_2", + variant_id: "test-variant-2", + }) await manager.insert(Region, { id: "test-region", diff --git a/integration-tests/helpers/price-list-seeder.js b/integration-tests/helpers/price-list-seeder.js index 8c97092de5..459c405bab 100644 --- a/integration-tests/helpers/price-list-seeder.js +++ b/integration-tests/helpers/price-list-seeder.js @@ -1,9 +1,10 @@ +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") const { Region, PriceList, MoneyAmount } = require("@medusajs/medusa") module.exports = async (dataSource, data = {}) => { const manager = dataSource.manager - const priceListNoCustomerGroups = await manager.create(PriceList, { + const priceListNoCustomerGroups = manager.create(PriceList, { id: "pl_no_customer_groups", name: "VIP winter sale", description: "Winter sale for VIP customers. 25% off selected items.", @@ -22,52 +23,69 @@ module.exports = async (dataSource, data = {}) => { tax_rate: 0, }) - const moneyAmount1 = await manager.create(MoneyAmount, { + const moneyAmount1 = manager.create(MoneyAmount, { id: "ma_test_1", amount: 100, currency_code: "usd", min_quantity: 1, max_quantity: 100, - variant_id: "test-variant", price_list_id: "pl_no_customer_groups", }) await manager.save(moneyAmount1) - const moneyAmount2 = await manager.create(MoneyAmount, { + const moneyAmount2 = manager.create(MoneyAmount, { id: "ma_test_2", amount: 80, currency_code: "usd", min_quantity: 101, max_quantity: 500, - variant_id: "test-variant", price_list_id: "pl_no_customer_groups", }) await manager.save(moneyAmount2) - const moneyAmount3 = await manager.create(MoneyAmount, { + const moneyAmount3 = manager.create(MoneyAmount, { id: "ma_test_3", amount: 50, currency_code: "usd", min_quantity: 501, max_quantity: 1000, - variant_id: "test-variant", price_list_id: "pl_no_customer_groups", }) await manager.save(moneyAmount3) - const moneyAmount4 = await manager.create(MoneyAmount, { + const moneyAmount4 = manager.create(MoneyAmount, { id: "ma_test_4", amount: 70, currency_code: "usd", - variant_id: "test-variant", }) await manager.save(moneyAmount4) - const priceListWithMA = await manager.create(PriceList, { + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma1-pl", + money_amount_id: "ma_test_1", + variant_id: "test-variant", + }) + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma2-pl", + money_amount_id: "ma_test_2", + variant_id: "test-variant", + }) + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma3-pl", + money_amount_id: "ma_test_3", + variant_id: "test-variant", + }) + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma4-pl", + money_amount_id: "ma_test_4", + variant_id: "test-variant", + }) + + const priceListWithMA = manager.create(PriceList, { id: "pl_with_some_ma", name: "Weeken sale", description: "Desc. of the list", diff --git a/integration-tests/helpers/price-selection-seeder.js b/integration-tests/helpers/price-selection-seeder.js index a3a053a5d5..0ea91094d4 100644 --- a/integration-tests/helpers/price-selection-seeder.js +++ b/integration-tests/helpers/price-selection-seeder.js @@ -1,3 +1,5 @@ +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") +const { MoneyAmount } = require("@medusajs/medusa") const { Customer, CustomerGroup, @@ -59,7 +61,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(coll) - const customer5 = await manager.create(Customer, { + const customer5 = manager.create(Customer, { id: "test-customer-5", email: "test5@email.com", first_name: "John", @@ -70,7 +72,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(customer5) - const customer6 = await manager.create(Customer, { + const customer6 = manager.create(Customer, { id: "test-customer-6", password_hash: "c2NyeXB0AAEAAAABAAAAAVMdaddoGjwU1TafDLLlBKnOTQga7P2dbrfgf3fB+rCD/cJOMuGzAvRdKutbYkVpuJWTU39P7OpuWNkUVoEETOVLMJafbI8qs8Qx/7jMQXkN", // password matching "test" @@ -79,7 +81,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(customer6) - const customer7 = await manager.create(Customer, { + const customer7 = manager.create(Customer, { id: "test-customer-7", password_hash: "c2NyeXB0AAEAAAABAAAAAVMdaddoGjwU1TafDLLlBKnOTQga7P2dbrfgf3fB+rCD/cJOMuGzAvRdKutbYkVpuJWTU39P7OpuWNkUVoEETOVLMJafbI8qs8Qx/7jMQXkN", // password matching "test" @@ -88,13 +90,13 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(customer7) - const c_group_5 = await manager.create(CustomerGroup, { + const c_group_5 = manager.create(CustomerGroup, { id: "test-group-5", name: "test-group-5", }) await manager.save(c_group_5) - const c_group_6 = await manager.create(CustomerGroup, { + const c_group_6 = manager.create(CustomerGroup, { id: "test-group-6", name: "test-group-6", }) @@ -109,7 +111,7 @@ module.exports = async (dataSource, data = {}) => { customer7.groups = [c_group_5, c_group_6] await manager.save(customer7) - const priceList = await manager.create(PriceList, { + const priceList = manager.create(PriceList, { id: "pl", name: "VIP winter sale", description: "Winter sale for VIP customers.", @@ -119,7 +121,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList) - const priceList1 = await manager.create(PriceList, { + const priceList1 = manager.create(PriceList, { id: "pl_1", name: "VIP winter sale", description: "Winter sale for VIP customers.", @@ -131,7 +133,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList1) - const priceList2 = await manager.create(PriceList, { + const priceList2 = manager.create(PriceList, { id: "pl_2", name: "VVIP winter sale", description: "Winter sale for key accounts.", @@ -143,7 +145,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList2) - const priceList3 = await manager.create(PriceList, { + const priceList3 = manager.create(PriceList, { id: "pl_expired", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -155,7 +157,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList3) - const priceList4 = await manager.create(PriceList, { + const priceList4 = manager.create(PriceList, { id: "pl_upcoming", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -167,7 +169,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList4) - const priceList5 = await manager.create(PriceList, { + const priceList5 = manager.create(PriceList, { id: "pl_current", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -179,7 +181,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList5) - const priceList6 = await manager.create(PriceList, { + const priceList6 = manager.create(PriceList, { id: "pl_current_1", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -191,7 +193,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList6) - const priceList7 = await manager.create(PriceList, { + const priceList7 = manager.create(PriceList, { id: "pl_upcoming-customer", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -205,7 +207,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList7) - const priceList8 = await manager.create(PriceList, { + const priceList8 = manager.create(PriceList, { id: "pl_current-customer", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -219,7 +221,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList8) - const priceList9 = await manager.create(PriceList, { + const priceList9 = manager.create(PriceList, { id: "pl_expired-customer", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -233,7 +235,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceList9) - const p1 = await manager.create(Product, { + const p1 = manager.create(Product, { id: "test-product", handle: "test-product", title: "Test product", @@ -252,7 +254,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product", }) - const variant4 = await manager.create(ProductVariant, { + const variant4 = manager.create(ProductVariant, { id: "test-variant", inventory_quantity: 10, title: "Test variant", @@ -261,35 +263,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc", product_id: "test-product", - prices: [ - { - id: "test-price", - region_id: "test-region", - currency_code: "usd", - amount: 100, - price_list_id: "pl_1", - }, - { - id: "test-price1", - region_id: "test-region", - currency_code: "usd", - amount: 120, - }, - { - id: "test-price2", - region_id: "test-region", - currency_code: "usd", - amount: 90, - price_list_id: "pl_2", - }, - { - id: "test-price3", - region_id: "test-region", - currency_code: "usd", - amount: 110, - price_list_id: "pl", - }, - ], options: [ { id: "test-variant-option", @@ -301,7 +274,62 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant4) - const p2 = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price", + region_id: "test-region", + currency_code: "usd", + amount: 100, + price_list_id: "pl_1", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant", + money_amount_id: "test-price", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-1", + region_id: "test-region", + currency_code: "usd", + amount: 120, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-1", + money_amount_id: "test-price-1", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-2", + region_id: "test-region", + currency_code: "usd", + amount: 90, + price_list_id: "pl_2", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-2", + money_amount_id: "test-price-2", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-3", + region_id: "test-region", + currency_code: "usd", + amount: 110, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-3", + money_amount_id: "test-price-3", + variant_id: "test-variant", + }) + + const p2 = manager.create(Product, { id: "test-product-quantity", handle: "test-product-quantity", title: "Test product", @@ -320,7 +348,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-quantity", }) - const variant_quantity = await manager.create(ProductVariant, { + const variant_quantity = manager.create(ProductVariant, { id: "test-variant-quantity", inventory_quantity: 10, title: "Test variant", @@ -329,76 +357,7 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-quantity", product_id: "test-product-quantity", - prices: [ - { - id: "test-price-quantity", - region_id: "test-region", - currency_code: "usd", - amount: 100, - price_list_id: "pl", - min_quantity: 10, - max_quantity: 100, - }, - { - id: "test-price1-quantity", - region_id: "test-region", - currency_code: "usd", - amount: 120, - price_list_id: "pl", - min_quantity: 101, - max_quantity: 1000, - }, - { - id: "test-price1-quantity-group", - region_id: "test-region", - currency_code: "usd", - amount: 120, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_1", - }, - { - id: "test-price2-quantity", - region_id: "test-region", - currency_code: "usd", - amount: 130, - price_list_id: "pl", - max_quantity: 9, - }, - { - id: "test-price3-quantity-expired", - region_id: "test-region", - currency_code: "usd", - amount: 120, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_expired", - }, - { - id: "test-price3-quantity-future", - region_id: "test-region", - currency_code: "usd", - amount: 120, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_upcoming", - }, - { - id: "test-price3-quantity-now", - region_id: "test-region", - currency_code: "usd", - amount: 140, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_current", - }, - { - id: "test-price3-quantity-default", - region_id: "test-region", - currency_code: "usd", - amount: 150, - }, - ], + prices: [], options: [ { id: "test-variant-option", @@ -410,7 +369,131 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_quantity) - const p3 = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price-quantity", + region_id: "test-region", + currency_code: "usd", + amount: 100, + price_list_id: "pl", + min_quantity: 10, + max_quantity: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity", + money_amount_id: "test-price-quantity", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-quantity", + region_id: "test-region", + currency_code: "usd", + amount: 120, + price_list_id: "pl", + min_quantity: 101, + max_quantity: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-1", + money_amount_id: "test-price1-quantity", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-quantity-group", + region_id: "test-region", + currency_code: "usd", + amount: 120, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_1", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-2", + money_amount_id: "test-price1-quantity-group", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-quantity", + region_id: "test-region", + currency_code: "usd", + amount: 130, + price_list_id: "pl", + max_quantity: 9, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-3", + money_amount_id: "test-price2-quantity", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-expired", + region_id: "test-region", + currency_code: "usd", + amount: 120, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-4", + money_amount_id: "test-price3-quantity-expired", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-future", + region_id: "test-region", + currency_code: "usd", + amount: 120, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_upcoming", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-5", + money_amount_id: "test-price3-quantity-future", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-now", + region_id: "test-region", + currency_code: "usd", + amount: 140, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_current", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-6", + money_amount_id: "test-price3-quantity-now", + variant_id: "test-variant-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-default", + region_id: "test-region", + currency_code: "usd", + amount: 150, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-quantity-7", + money_amount_id: "test-price3-quantity-default", + variant_id: "test-variant-quantity", + }) + + const p3 = manager.create(Product, { id: "test-product-sale", handle: "test-product-sale", title: "Test product sale", @@ -429,7 +512,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-sale", }) - const variant_sale = await manager.create(ProductVariant, { + const variant_sale = manager.create(ProductVariant, { id: "test-variant-sale", inventory_quantity: 10, title: "Test variant", @@ -438,35 +521,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-sale", product_id: "test-product-sale", - prices: [ - { - id: "test-price-sale", - region_id: "test-region", - currency_code: "usd", - amount: 100, - price_list_id: "pl_expired", - }, - { - id: "test-price1-sale", - region_id: "test-region", - currency_code: "usd", - amount: 120, - price_list_id: "pl_current", - }, - { - id: "test-price2-sale", - region_id: "test-region", - currency_code: "usd", - amount: 130, - price_list_id: "pl_upcoming", - }, - { - id: "test-price2-sale-default", - region_id: "test-region", - currency_code: "usd", - amount: 150, - }, - ], options: [ { id: "test-variant-option", @@ -478,7 +532,62 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_sale) - const p4 = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price-sale", + region_id: "test-region", + currency_code: "usd", + amount: 100, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale", + money_amount_id: "test-price-sale", + variant_id: "test-variant-sale", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-sale", + region_id: "test-region", + currency_code: "usd", + amount: 120, + price_list_id: "pl_current", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-1", + money_amount_id: "test-price1-sale", + variant_id: "test-variant-sale", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale", + region_id: "test-region", + currency_code: "usd", + amount: 130, + price_list_id: "pl_upcoming", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-2", + money_amount_id: "test-price2-sale", + variant_id: "test-variant-sale", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale-default", + region_id: "test-region", + currency_code: "usd", + amount: 150, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-3", + money_amount_id: "test-price2-sale-default", + variant_id: "test-variant-sale", + }) + + const p4 = manager.create(Product, { id: "test-product-sale-overlap", handle: "test-product-sale-overlap", title: "Test product sale", @@ -497,7 +606,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-sale-overlap", }) - const variant_sale_overlap = await manager.create(ProductVariant, { + const variant_sale_overlap = manager.create(ProductVariant, { id: "test-variant-sale-overlap", inventory_quantity: 10, title: "Test variant", @@ -506,28 +615,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-sale-overlap", product_id: "test-product-sale-overlap", - prices: [ - { - id: "test-price-sale-overlap-1", - region_id: "test-region", - currency_code: "usd", - amount: 140, - price_list_id: "pl_current_1", - }, - { - id: "test-price1-sale-overlap", - region_id: "test-region", - currency_code: "usd", - amount: 120, - price_list_id: "pl_current", - }, - { - id: "test-price2-sale-overlap-default", - region_id: "test-region", - currency_code: "usd", - amount: 150, - }, - ], options: [ { id: "test-variant-option-overlap", @@ -539,7 +626,48 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_sale_overlap) - const multiRegionProduct = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price-sale-overlap-1", + region_id: "test-region", + currency_code: "usd", + amount: 140, + price_list_id: "pl_current_1", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-overlap-1", + money_amount_id: "test-price-sale-overlap-1", + variant_id: "test-variant-sale-overlap", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-sale-overlap", + region_id: "test-region", + currency_code: "usd", + amount: 120, + price_list_id: "pl_current", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-overlap-2", + money_amount_id: "test-price1-sale-overlap", + variant_id: "test-variant-sale-overlap", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale-overlap-default", + region_id: "test-region", + currency_code: "usd", + amount: 150, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-variant-sale-overlap-3", + money_amount_id: "test-price2-sale-overlap-default", + variant_id: "test-variant-sale-overlap", + }) + + const multiRegionProduct = manager.create(Product, { id: "test-product-multi-region", handle: "test-product-multi-region", title: "Test product", @@ -558,7 +686,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-multi-region", }) - const variant_multi_region = await manager.create(ProductVariant, { + const variant_multi_region = manager.create(ProductVariant, { id: "test-variant-multi-region", inventory_quantity: 10, title: "Test variant", @@ -567,34 +695,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-multi-region", product_id: "test-product-multi-region", - prices: [ - { - id: "test-price-region-1", - region_id: "test-region", - currency_code: "usd", - amount: 100, - price_list_id: "pl", - }, - { - id: "test-price1-region-1", - region_id: "test-region", - currency_code: "usd", - amount: 120, - }, - { - id: "test-price1-region-2", - region_id: "test-region-2", - currency_code: "dkk", - amount: 130, - }, - { - id: "test-price3-region-2", - region_id: "test-region-2", - currency_code: "dkk", - price_list_id: "pl", - amount: 110, - }, - ], options: [ { id: "test-variant-option-multi-region", @@ -606,7 +706,61 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_multi_region) - const p5 = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price-region-1", + region_id: "test-region", + currency_code: "usd", + amount: 100, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-multi-region-1", + money_amount_id: "test-price-region-1", + variant_id: "test-variant-multi-region", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-region-1", + region_id: "test-region", + currency_code: "usd", + amount: 120, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-multi-region-2", + money_amount_id: "test-price1-region-1", + variant_id: "test-variant-multi-region", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-region-2", + region_id: "test-region-2", + currency_code: "dkk", + amount: 130, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-multi-region-3", + money_amount_id: "test-price1-region-2", + variant_id: "test-variant-multi-region", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-region-2", + region_id: "test-region-2", + currency_code: "dkk", + price_list_id: "pl", + amount: 110, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-multi-region-4", + money_amount_id: "test-price3-region-2", + variant_id: "test-variant-multi-region", + }) + + const p5 = manager.create(Product, { id: "test-product-quantity-customer", handle: "test-product-quantity-customer", title: "Test product", @@ -625,7 +779,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-quantity-customer", }) - const variant_quantity_customer = await manager.create(ProductVariant, { + const variant_quantity_customer = manager.create(ProductVariant, { id: "test-variant-quantity-customer", inventory_quantity: 10, title: "Test variant", @@ -634,75 +788,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-quantity-customer", product_id: "test-product-quantity-customer", - prices: [ - { - id: "test-price-quantity-customer", - region_id: "test-region", - currency_code: "usd", - amount: 100, - price_list_id: "pl", - min_quantity: 10, - max_quantity: 100, - }, - { - id: "test-price1-quantity-customer", - region_id: "test-region", - currency_code: "usd", - amount: 120, - price_list_id: "pl", - min_quantity: 101, - max_quantity: 1000, - }, - { - id: "test-price2-quantity-customer", - region_id: "test-region", - currency_code: "usd", - amount: 130, - price_list_id: "pl", - max_quantity: 9, - }, - { - id: "test-price2-quantity-customer-group", - region_id: "test-region", - currency_code: "usd", - amount: 100, - max_quantity: 9, - price_list_id: "pl_1", - }, - { - id: "test-price3-quantity-customer-expired", - region_id: "test-region", - currency_code: "usd", - amount: 120, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_expired", - }, - { - id: "test-price3-quantity-customer-future", - region_id: "test-region", - currency_code: "usd", - amount: 120, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_upcoming", - }, - { - id: "test-price3-quantity-customer-now", - region_id: "test-region", - currency_code: "usd", - amount: 140, - min_quantity: 101, - max_quantity: 1000, - price_list_id: "pl_current", - }, - { - id: "test-price3-quantity-customer-default", - region_id: "test-region", - currency_code: "usd", - amount: 150, - }, - ], options: [ { id: "test-variant-option", @@ -714,7 +799,130 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_quantity_customer) - const p6 = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price-quantity-customer", + region_id: "test-region", + currency_code: "usd", + amount: 100, + price_list_id: "pl", + min_quantity: 10, + max_quantity: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-1", + money_amount_id: "test-price-quantity-customer", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-quantity-customer", + region_id: "test-region", + currency_code: "usd", + amount: 120, + price_list_id: "pl", + min_quantity: 101, + max_quantity: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-2", + money_amount_id: "test-price1-quantity-customer", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-quantity-customer", + region_id: "test-region", + currency_code: "usd", + amount: 130, + price_list_id: "pl", + max_quantity: 9, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-3", + money_amount_id: "test-price2-quantity-customer", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-quantity-customer-group", + region_id: "test-region", + currency_code: "usd", + amount: 100, + max_quantity: 9, + price_list_id: "pl_1", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-4", + money_amount_id: "test-price2-quantity-customer-group", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-customer-expired", + region_id: "test-region", + currency_code: "usd", + amount: 120, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-5", + money_amount_id: "test-price3-quantity-customer-expired", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-customer-future", + region_id: "test-region", + currency_code: "usd", + amount: 120, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_upcoming", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-6", + money_amount_id: "test-price3-quantity-customer-future", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-customer-now", + region_id: "test-region", + currency_code: "usd", + amount: 140, + min_quantity: 101, + max_quantity: 1000, + price_list_id: "pl_current", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-7", + money_amount_id: "test-price3-quantity-customer-now", + variant_id: "test-variant-quantity-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price3-quantity-customer-default", + region_id: "test-region", + currency_code: "usd", + amount: 150, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-quantity-customer-8", + money_amount_id: "test-price3-quantity-customer-default", + variant_id: "test-variant-quantity-customer", + }) + + const p6 = manager.create(Product, { id: "test-product-sale-customer", handle: "test-product-sale-customer", title: "Test product sale", @@ -733,7 +941,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-sale-customer", }) - const variant_sale_customer = await manager.create(ProductVariant, { + const variant_sale_customer = manager.create(ProductVariant, { id: "test-variant-sale-customer", inventory_quantity: 10, title: "Test variant", @@ -742,36 +950,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-sale-customer", product_id: "test-product-sale-customer", - prices: [ - { - id: "test-price-sale-customer", - region_id: "test-region", - currency_code: "usd", - amount: 120, - price_list_id: "pl_expired-customer", - }, - { - id: "test-price1-sale-customer", - region_id: "test-region", - currency_code: "usd", - amount: 100, - price_list_id: "pl_current-customer", - }, - { - id: "test-price2-sale-customer", - region_id: "test-region", - currency_code: "usd", - amount: 130, - price_list_id: "pl_upcoming-customer", - }, - { - id: "test-price2-sale-customer-default", - region_id: "test-region", - currency_code: "usd", - amount: 150, - type: "default", - }, - ], options: [ { id: "test-variant-option", @@ -783,7 +961,63 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_sale_customer) - const p7 = await manager.create(Product, { + await manager.insert(MoneyAmount, { + id: "test-price-sale-customer", + region_id: "test-region", + currency_code: "usd", + amount: 120, + price_list_id: "pl_expired-customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-custome-1", + money_amount_id: "test-price-sale-customer", + variant_id: "test-variant-sale-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-sale-customer", + region_id: "test-region", + currency_code: "usd", + amount: 100, + price_list_id: "pl_current-customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-custome-2", + money_amount_id: "test-price1-sale-customer", + variant_id: "test-variant-sale-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale-customer", + region_id: "test-region", + currency_code: "usd", + amount: 130, + price_list_id: "pl_upcoming-customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-custome-3", + money_amount_id: "test-price2-sale-customer", + variant_id: "test-variant-sale-customer", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale-customer-default", + region_id: "test-region", + currency_code: "usd", + amount: 150, + type: "default", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-custome-4", + money_amount_id: "test-price2-sale-customer-default", + variant_id: "test-variant-sale-customer", + }) + + const p7 = manager.create(Product, { id: "test-product-sale-customer-quantity", handle: "test-product-sale-customer-quantity", title: "Test product sale", @@ -802,7 +1036,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-sale-customer-quantity", }) - const variant_sale_customer_quantity = await manager.create(ProductVariant, { + const variant_sale_customer_quantity = manager.create(ProductVariant, { id: "test-variant-sale-customer-quantity", inventory_quantity: 10, title: "Test variant", @@ -811,47 +1045,6 @@ module.exports = async (dataSource, data = {}) => { status: "published", upc: "test-upc-sale-customer-quantity", product_id: "test-product-sale-customer-quantity", - prices: [ - { - id: "test-price-sale-customer-quantity", - region_id: "test-region", - currency_code: "usd", - amount: 120, - min_quantity: 100, - max_quantity: 1000, - price_list_id: "pl_expired-customer", - }, - { - id: "test-price1-sale-customer-quantity-groups", - region_id: "test-region", - currency_code: "usd", - amount: 100, - max_quantity: 99, - price_list_id: "pl_current-customer", - }, - { - id: "test-price2-sale-customer-quantity", - region_id: "test-region", - currency_code: "usd", - amount: 130, - min_quantity: 500, - max_quantity: 900, - price_list_id: "pl_upcoming-customer", - }, - { - id: "test-price2-sale-customer-quantity-default", - region_id: "test-region", - currency_code: "usd", - amount: 150, - }, - { - id: "test-price1-sale-customer-quantity", - region_id: "test-region", - currency_code: "usd", - amount: 110, - max_quantity: 99, - }, - ], options: [ { id: "test-variant-option", @@ -863,7 +1056,81 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant_sale_customer_quantity) - const cart = await manager.create(Cart, { + await manager.insert(MoneyAmount, { + id: "test-price-sale-customer-quantity", + region_id: "test-region", + currency_code: "usd", + amount: 120, + min_quantity: 100, + max_quantity: 1000, + price_list_id: "pl_expired-customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-customer-quantity-1", + money_amount_id: "test-price-sale-customer-quantity", + variant_id: "test-variant-sale-customer-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-sale-customer-quantity-groups", + region_id: "test-region", + currency_code: "usd", + amount: 100, + max_quantity: 99, + price_list_id: "pl_current-customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-customer-quantity-2", + money_amount_id: "test-price1-sale-customer-quantity-groups", + variant_id: "test-variant-sale-customer-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale-customer-quantity", + region_id: "test-region", + currency_code: "usd", + amount: 130, + min_quantity: 500, + max_quantity: 900, + price_list_id: "pl_upcoming-customer", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-customer-quantity-3", + money_amount_id: "test-price2-sale-customer-quantity", + variant_id: "test-variant-sale-customer-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-sale-customer-quantity-default", + region_id: "test-region", + currency_code: "usd", + amount: 150, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-customer-quantity-4", + money_amount_id: "test-price2-sale-customer-quantity-default", + variant_id: "test-variant-sale-customer-quantity", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-sale-customer-quantity", + region_id: "test-region", + currency_code: "usd", + amount: 110, + max_quantity: 99, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-sale-customer-quantity-5", + money_amount_id: "test-price1-sale-customer-quantity", + variant_id: "test-variant-sale-customer-quantity", + }) + + const cart = manager.create(Cart, { id: "test-cart", region_id: "test-region", currency_code: "usd", @@ -872,7 +1139,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(cart) - const cart_region2 = await manager.create(Cart, { + const cart_region2 = manager.create(Cart, { id: "test-cart-1", region_id: "test-region-2", currency_code: "dkk", @@ -881,7 +1148,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(cart_region2) - const cart_region1 = await manager.create(Cart, { + const cart_region1 = manager.create(Cart, { id: "test-cart-2", region_id: "test-region-1", currency_code: "usd", @@ -890,7 +1157,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(cart_region1) - const customerPl = await manager.create(Customer, { + const customerPl = manager.create(Customer, { id: "test-customer-5-pl", email: "test5@email-pl.com", first_name: "John", @@ -901,7 +1168,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(customerPl) - const pPl = await manager.create(Product, { + const pPl = manager.create(Product, { id: "test-product-pl", handle: "test-product-pl", title: "Test product", @@ -919,7 +1186,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product-pl", }) - const c_group_pl = await manager.create(CustomerGroup, { + const c_group_pl = manager.create(CustomerGroup, { id: "test-group-pl", name: "test-group-pl", }) @@ -928,13 +1195,13 @@ module.exports = async (dataSource, data = {}) => { customerPl.groups = [c_group_pl] await manager.save(customerPl) - const c_group_not_pl = await manager.create(CustomerGroup, { + const c_group_not_pl = manager.create(CustomerGroup, { id: "test-group-not-pl", name: "test-group-not-pl", }) await manager.save(c_group_not_pl) - const priceListPl = await manager.create(PriceList, { + const priceListPl = manager.create(PriceList, { id: "pl_current_pl", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -945,7 +1212,7 @@ module.exports = async (dataSource, data = {}) => { priceListPl.customer_groups = [c_group_pl] await manager.save(priceListPl) - const priceListNotPL = await manager.create(PriceList, { + const priceListNotPL = manager.create(PriceList, { id: "pl_current_not_pl", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -956,35 +1223,13 @@ module.exports = async (dataSource, data = {}) => { await manager.save(priceListNotPL) - const variantPl = await manager.create(ProductVariant, { + const variantPl = manager.create(ProductVariant, { id: "test-variant-pl", inventory_quantity: 10, title: "Test variant", sku: "test-sku-pl", status: "published", product_id: "test-product-pl", - prices: [ - { - id: "test-price120", - region_id: "test-region", - currency_code: "usd", - amount: 90, - price_list_id: "pl_current_not_pl", - }, - { - id: "test-price1120", - region_id: "test-region", - currency_code: "usd", - amount: 120, - }, - { - id: "test-price2120", - region_id: "test-region", - currency_code: "usd", - amount: 110, - price_list_id: "pl_current_pl", - }, - ], options: [ { id: "test-variant-option-pl", @@ -995,4 +1240,45 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(variantPl) + + await manager.insert(MoneyAmount, { + id: "test-price120", + region_id: "test-region", + currency_code: "usd", + amount: 90, + price_list_id: "pl_current_not_pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-pl-1", + money_amount_id: "test-price120", + variant_id: "test-variant-pl", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1120", + region_id: "test-region", + currency_code: "usd", + amount: 120, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-pl-2", + money_amount_id: "test-price1120", + variant_id: "test-variant-pl", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2120", + region_id: "test-region", + currency_code: "usd", + amount: 110, + price_list_id: "pl_current_pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-pl-3", + money_amount_id: "test-price2120", + variant_id: "test-variant-pl", + }) } diff --git a/integration-tests/helpers/product-seeder.js b/integration-tests/helpers/product-seeder.js index dffad8b68f..90cb384c20 100644 --- a/integration-tests/helpers/product-seeder.js +++ b/integration-tests/helpers/product-seeder.js @@ -9,6 +9,8 @@ const { ProductVariant, Image, ShippingProfileType, + MoneyAmount, + ProductVariantMoneyAmount, } = require("@medusajs/medusa") module.exports = async (dataSource, data = {}) => { @@ -20,7 +22,7 @@ module.exports = async (dataSource, data = {}) => { }, }) - const coll = await manager.create(ProductCollection, { + const coll = manager.create(ProductCollection, { id: "test-collection", handle: "test-collection", title: "Test collection", @@ -28,7 +30,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(coll) - const coll1 = await manager.create(ProductCollection, { + const coll1 = manager.create(ProductCollection, { id: "test-collection1", handle: "test-collection1", title: "Test collection 1", @@ -36,7 +38,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(coll1) - const coll2 = await manager.create(ProductCollection, { + const coll2 = manager.create(ProductCollection, { id: "test-collection2", handle: "test-collection2", title: "Test collection 2", @@ -44,35 +46,35 @@ module.exports = async (dataSource, data = {}) => { await manager.save(coll2) - const tag = await manager.create(ProductTag, { + const tag = manager.create(ProductTag, { id: "tag1", value: "123", }) await manager.save(tag) - const tag3 = await manager.create(ProductTag, { + const tag3 = manager.create(ProductTag, { id: "tag3", value: "1235", }) await manager.save(tag3) - const tag4 = await manager.create(ProductTag, { + const tag4 = manager.create(ProductTag, { id: "tag4", value: "1234", }) await manager.save(tag4) - const type = await manager.create(ProductType, { + const type = manager.create(ProductType, { id: "test-type", value: "test-type", }) await manager.save(type) - const type2 = await manager.create(ProductType, { + const type2 = manager.create(ProductType, { id: "test-type-new", value: "test-type-new", }) @@ -93,7 +95,7 @@ module.exports = async (dataSource, data = {}) => { tax_rate: 0, }) - const p = await manager.create(Product, { + const p = manager.create(Product, { id: "test-product", handle: "test-product", title: "Test product", @@ -118,7 +120,7 @@ module.exports = async (dataSource, data = {}) => { product_id: "test-product", }) - const variant1 = await manager.create(ProductVariant, { + const variant1 = manager.create(ProductVariant, { id: "test-variant", inventory_quantity: 10, title: "Test variant", @@ -128,7 +130,6 @@ module.exports = async (dataSource, data = {}) => { upc: "test-upc", barcode: "test-barcode", product_id: "test-product", - prices: [{ id: "test-price", currency_code: "usd", amount: 100 }], options: [ { id: "test-variant-option", @@ -140,7 +141,19 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant1) - const sale = await manager.create(ProductVariant, { + const ma = await manager.insert(MoneyAmount, { + id: "test-price", + currency_code: "usd", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma0", + money_amount_id: "test-price", + variant_id: "test-variant", + }) + + const sale = manager.create(ProductVariant, { id: "test-variant-sale", inventory_quantity: 10, title: "Test variant", @@ -150,13 +163,6 @@ module.exports = async (dataSource, data = {}) => { upc: "test-upc-sale", barcode: "test-barcode-sale", product_id: "test-product", - prices: [ - { - id: "test-price-sale", - currency_code: "usd", - amount: 1000, - }, - ], options: [ { id: "test-variant-option-sale", @@ -168,7 +174,19 @@ module.exports = async (dataSource, data = {}) => { await manager.save(sale) - const variant2 = await manager.create(ProductVariant, { + const ma_sale = await manager.insert(MoneyAmount, { + id: "test-price-sale", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma1", + money_amount_id: "test-price-sale", + variant_id: "test-variant-sale", + }) + + const variant2 = manager.create(ProductVariant, { id: "test-variant_1", inventory_quantity: 10, title: "Test variant rank (1)", @@ -178,7 +196,6 @@ module.exports = async (dataSource, data = {}) => { upc: "test-upc1", barcode: "test-barcode 1", product_id: "test-product", - prices: [{ id: "test-price1", currency_code: "usd", amount: 100 }], options: [ { id: "test-variant-option-1", @@ -190,7 +207,19 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant2) - const variant3 = await manager.create(ProductVariant, { + const ma_1 = await manager.insert(MoneyAmount, { + id: "test-price_1", + currency_code: "usd", + amount: 1000, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma2", + money_amount_id: "test-price_1", + variant_id: "test-variant_1", + }) + + const variant3 = manager.create(ProductVariant, { id: "test-variant_2", inventory_quantity: 10, title: "Test variant rank (2)", @@ -199,7 +228,6 @@ module.exports = async (dataSource, data = {}) => { ean: "test-ean2", upc: "test-upc2", product_id: "test-product", - prices: [{ id: "test-price2", currency_code: "usd", amount: 100 }], options: [ { id: "test-variant-option-2", @@ -211,7 +239,19 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant3) - const p1 = await manager.create(Product, { + const ma_2 = await manager.insert(MoneyAmount, { + id: "test-price_2", + currency_code: "usd", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma3", + money_amount_id: "test-price_2", + variant_id: "test-variant_2", + }) + + const p1 = manager.create(Product, { id: "test-product1", handle: "test-product1", title: "Test product1", @@ -228,7 +268,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(p1) - const variant4 = await manager.create(ProductVariant, { + const variant4 = manager.create(ProductVariant, { id: "test-variant_3", inventory_quantity: 10, title: "Test variant rank (2)", @@ -237,15 +277,6 @@ module.exports = async (dataSource, data = {}) => { ean: "test-ean3", upc: "test-upc3", product_id: "test-product1", - prices: [ - { - id: "test-price3", - region_id: "test-region", - currency_code: "usd", - amount: 100, - type: "default", - }, - ], options: [ { id: "test-variant-option-3", @@ -257,7 +288,20 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant4) - const variant5 = await manager.create(ProductVariant, { + const ma_3 = await manager.insert(MoneyAmount, { + id: "test-price_3", + currency_code: "usd", + amount: 100, + region_id: "test-region", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma4", + money_amount_id: "test-price_3", + variant_id: "test-variant_3", + }) + + const variant5 = manager.create(ProductVariant, { id: "test-variant_4", inventory_quantity: 10, title: "Test variant rank (2)", @@ -266,9 +310,6 @@ module.exports = async (dataSource, data = {}) => { ean: "test-ean4", upc: "test-upc4", product_id: "test-product1", - prices: [ - { id: "test-price4", currency_code: "usd", amount: 100, type: "default" }, - ], options: [ { id: "test-variant-option-4", @@ -280,7 +321,19 @@ module.exports = async (dataSource, data = {}) => { await manager.save(variant5) - const product1 = await manager.create(Product, { + const ma_4 = await manager.insert(MoneyAmount, { + id: "test-price_4", + currency_code: "usd", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma5", + money_amount_id: "test-price_4", + variant_id: "test-variant_4", + }) + + const product1 = manager.create(Product, { id: "test-product_filtering_1", handle: "test-product_filtering_1", title: "Test product filtering 1", @@ -295,7 +348,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(product1) - const product2 = await manager.create(Product, { + const product2 = manager.create(Product, { id: "test-product_filtering_2", handle: "test-product_filtering_2", title: "Test product filtering 2", @@ -310,7 +363,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(product2) - const product3 = await manager.create(Product, { + const product3 = manager.create(Product, { id: "test-product_filtering_3", handle: "test-product_filtering_3", title: "Test product filtering 3", @@ -325,7 +378,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(product3) - const product4 = await manager.create(Product, { + const product4 = manager.create(Product, { id: "test-product_filtering_4", handle: "test-product_filtering_4", title: "Test product filtering 4", diff --git a/integration-tests/helpers/store-product-seeder.js b/integration-tests/helpers/store-product-seeder.js index 30af9cdfe7..3b61e48fd4 100644 --- a/integration-tests/helpers/store-product-seeder.js +++ b/integration-tests/helpers/store-product-seeder.js @@ -1,3 +1,5 @@ +const { ProductVariantMoneyAmount } = require("@medusajs/medusa") +const { MoneyAmount } = require("@medusajs/medusa") const { ProductCollection, ProductTag, @@ -26,7 +28,7 @@ module.exports = async (dataSource, defaultSalesChannel) => { new Date() ) - const priceList = await manager.create(PriceList, { + const priceList = manager.create(PriceList, { id: "pl", name: "VIP winter sale", description: "Winter sale for VIP customers.", @@ -36,7 +38,7 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(priceList) - const priceList1 = await manager.create(PriceList, { + const priceList1 = manager.create(PriceList, { id: "pl_expired", name: "Past winter sale", description: "Winter sale for key accounts.", @@ -152,7 +154,7 @@ module.exports = async (dataSource, defaultSalesChannel) => { product_id: "test-product", }) - const variant1 = await manager.create(ProductVariant, { + const variant1 = manager.create(ProductVariant, { id: "test-variant", inventory_quantity: 10, title: "Test variant", @@ -162,21 +164,6 @@ module.exports = async (dataSource, defaultSalesChannel) => { upc: "test-upc", barcode: "test-barcode", product_id: "test-product", - prices: [ - { id: "test-price", currency_code: "usd", type: "default", amount: 100 }, - { - id: "test-price-discount", - currency_code: "usd", - amount: 80, - price_list_id: "pl", - }, - { - id: "test-price-discount-expired", - currency_code: "usd", - amount: 70, - price_list_id: "pl_expired", - }, - ], options: [ { id: "test-variant-option", @@ -188,7 +175,46 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(variant1) - const variant2 = await manager.create(ProductVariant, { + await manager.insert(MoneyAmount, { + id: "test-price", + currency_code: "usd", + type: "default", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-1", + money_amount_id: "test-price", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount", + currency_code: "usd", + amount: 80, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-2", + money_amount_id: "test-price-discount", + variant_id: "test-variant", + }) + + await manager.insert(MoneyAmount, { + id: "test-price-discount-expired", + currency_code: "usd", + amount: 70, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant-3", + money_amount_id: "test-price-discount-expired", + variant_id: "test-variant", + }) + + const variant2 = manager.create(ProductVariant, { id: "test-variant_1", inventory_quantity: 10, title: "Test variant rank (1)", @@ -198,21 +224,6 @@ module.exports = async (dataSource, defaultSalesChannel) => { upc: "test-upc1", barcode: "test-barcode 1", product_id: "test-product", - prices: [ - { id: "test-price1", currency_code: "usd", type: "default", amount: 100 }, - { - id: "test-price1-discount", - currency_code: "usd", - amount: 80, - price_list_id: "pl", - }, - { - id: "test-price1-discount-expired", - currency_code: "usd", - amount: 70, - price_list_id: "pl_expired", - }, - ], options: [ { id: "test-variant-option-1", @@ -224,7 +235,46 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(variant2) - const variant3 = await manager.create(ProductVariant, { + await manager.insert(MoneyAmount, { + id: "test-price1", + currency_code: "usd", + type: "default", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_1-1", + money_amount_id: "test-price1", + variant_id: "test-variant_1", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-discount", + currency_code: "usd", + amount: 80, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_1-2", + money_amount_id: "test-price1-discount", + variant_id: "test-variant_1", + }) + + await manager.insert(MoneyAmount, { + id: "test-price1-discount-expired", + currency_code: "usd", + amount: 70, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_1-3", + money_amount_id: "test-price1-discount-expired", + variant_id: "test-variant_1", + }) + + const variant3 = manager.create(ProductVariant, { id: "test-variant_2", inventory_quantity: 10, title: "Test variant rank (2)", @@ -233,21 +283,6 @@ module.exports = async (dataSource, defaultSalesChannel) => { ean: "test-ean2", upc: "test-upc2", product_id: "test-product", - prices: [ - { id: "test-price2", currency_code: "usd", type: "default", amount: 100 }, - { - id: "test-price2-discount", - currency_code: "usd", - amount: 80, - price_list_id: "pl", - }, - { - id: "test-price2-discount-expired", - currency_code: "usd", - amount: 70, - price_list_id: "pl_expired", - }, - ], options: [ { id: "test-variant-option-2", @@ -259,6 +294,45 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(variant3) + await manager.insert(MoneyAmount, { + id: "test-price2", + currency_code: "usd", + type: "default", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_2-1", + money_amount_id: "test-price2", + variant_id: "test-variant_2", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-discount", + currency_code: "usd", + amount: 80, + price_list_id: "pl", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_2-2", + money_amount_id: "test-price2-discount", + variant_id: "test-variant_2", + }) + + await manager.insert(MoneyAmount, { + id: "test-price2-discount-expired", + currency_code: "usd", + amount: 70, + price_list_id: "pl_expired", + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_2-3", + money_amount_id: "test-price2-discount-expired", + variant_id: "test-variant_2", + }) + const p1 = manager.create(Product, { id: "test-product1", handle: "test-product1", @@ -277,7 +351,7 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(p1) - const variant4 = await manager.create(ProductVariant, { + const variant4 = manager.create(ProductVariant, { id: "test-variant_3", inventory_quantity: 10, title: "Test variant rank (2)", @@ -286,7 +360,6 @@ module.exports = async (dataSource, defaultSalesChannel) => { ean: "test-ean3", upc: "test-upc3", product_id: "test-product1", - prices: [{ id: "test-price3", currency_code: "usd", amount: 100 }], options: [ { id: "test-variant-option-3", @@ -298,7 +371,19 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(variant4) - const variant5 = await manager.create(ProductVariant, { + await manager.insert(MoneyAmount, { + id: "test-price3", + currency_code: "usd", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_3-1", + money_amount_id: "test-price3", + variant_id: "test-variant_3", + }) + + const variant5 = manager.create(ProductVariant, { id: "test-variant_4", inventory_quantity: 10, title: "Test variant rank (2)", @@ -307,7 +392,6 @@ module.exports = async (dataSource, defaultSalesChannel) => { ean: "test-ean4", upc: "test-upc4", product_id: "test-product1", - prices: [{ id: "test-price4", currency_code: "usd", amount: 100 }], options: [ { id: "test-variant-option-4", @@ -319,6 +403,18 @@ module.exports = async (dataSource, defaultSalesChannel) => { await manager.save(variant5) + await manager.insert(MoneyAmount, { + id: "test-price4", + currency_code: "usd", + amount: 100, + }) + + await manager.insert(ProductVariantMoneyAmount, { + id: "pvma-test-variant_4-1", + money_amount_id: "test-price4", + variant_id: "test-variant_4", + }) + const product1 = manager.create(Product, { id: "test-product_filtering_1", handle: "test-product_filtering_1", diff --git a/integration-tests/helpers/swap-seeder.js b/integration-tests/helpers/swap-seeder.js index 2ee8b88828..fa738990f9 100644 --- a/integration-tests/helpers/swap-seeder.js +++ b/integration-tests/helpers/swap-seeder.js @@ -264,7 +264,7 @@ module.exports = async (dataSource, data = {}) => { await manager.save(li2) - const swapReturn = await manager.create(Return, { + const swapReturn = manager.create(Return, { swap_id: swap.id, order_id: orderWithSwap.id, item_id: li.id, diff --git a/integration-tests/helpers/user-seeder.js b/integration-tests/helpers/user-seeder.js index 2724cac368..6a86955700 100644 --- a/integration-tests/helpers/user-seeder.js +++ b/integration-tests/helpers/user-seeder.js @@ -14,7 +14,7 @@ expires_at.setDate(expires_at.getDate() + 8) module.exports = async (dataSource, data = {}) => { const manager = dataSource.manager - const memberUser = await manager.create(User, { + const memberUser = manager.create(User, { id: "member-user", role: "member", email: "member@test.com", @@ -23,7 +23,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(memberUser) - const memberInvite = await manager.create(Invite, { + const memberInvite = manager.create(Invite, { id: "memberInvite", user_email: "invite-member@test.com", role: "member", @@ -37,7 +37,7 @@ module.exports = async (dataSource, data = {}) => { }) await manager.save(memberInvite) - const adminInvite = await manager.create(Invite, { + const adminInvite = manager.create(Invite, { id: "adminInvite", user_email: "invite-admin@test.com", role: "admin", diff --git a/integration-tests/plugins/__tests__/cart/store/index.ts b/integration-tests/plugins/__tests__/cart/store/index.ts index 164209820f..14eae47236 100644 --- a/integration-tests/plugins/__tests__/cart/store/index.ts +++ b/integration-tests/plugins/__tests__/cart/store/index.ts @@ -6,6 +6,7 @@ import setupServer from "../../../../environment-helpers/setup-server" import { setPort, useApi } from "../../../../environment-helpers/use-api" import { initDb, useDb } from "../../../../environment-helpers/use-db" import { simpleProductFactory } from "../../../../factories" +import { ProductVariantMoneyAmount } from "@medusajs/medusa" jest.setTimeout(30000) @@ -125,7 +126,6 @@ describe("/store/carts", () => { await dbConnection.manager.save(priceList1) const ma_sale_1 = dbConnection.manager.create(MoneyAmount, { - variant_id: prodSale.variants[0].id, currency_code: "usd", amount: 800, price_list_id: "pl_current", @@ -133,6 +133,12 @@ describe("/store/carts", () => { await dbConnection.manager.save(ma_sale_1) + await dbConnection.manager.insert(ProductVariantMoneyAmount, { + id: 'pvma-test', + variant_id: prodSale.variants[0].id, + money_amount_id: ma_sale_1.id, + }) + const api = useApi() const response = await api diff --git a/packages/medusa/src/api/routes/admin/price-lists/index.ts b/packages/medusa/src/api/routes/admin/price-lists/index.ts index 261150a244..8cadbd7f0d 100644 --- a/packages/medusa/src/api/routes/admin/price-lists/index.ts +++ b/packages/medusa/src/api/routes/admin/price-lists/index.ts @@ -1,20 +1,22 @@ -import { FlagRouter } from "@medusajs/utils" -import { Router } from "express" import "reflect-metadata" -import { PriceList, Product } from "../../../.." -import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing" + import { DeleteResponse, PaginatedResponse } from "../../../../types/common" -import middlewares, { - transformBody, - transformQuery, -} from "../../../middlewares" +import { PriceList, Product } from "../../../.." import { defaultAdminProductFields, defaultAdminProductRelations, } from "../products" -import { AdminPostPriceListsPriceListReq } from "./create-price-list" -import { AdminGetPriceListsPriceListProductsParams } from "./list-price-list-products" +import middlewares, { + transformBody, + transformQuery, +} from "../../../middlewares" + import { AdminGetPriceListPaginationParams } from "./list-price-lists" +import { AdminGetPriceListsPriceListProductsParams } from "./list-price-list-products" +import { AdminPostPriceListsPriceListReq } from "./create-price-list" +import { FlagRouter } from "@medusajs/utils" +import { Router } from "express" +import TaxInclusivePricingFeatureFlag from "../../../../loaders/feature-flags/tax-inclusive-pricing" const route = Router() @@ -91,7 +93,11 @@ export const defaultAdminPriceListFields = [ "deleted_at", ] -export const defaultAdminPriceListRelations = ["prices", "customer_groups"] +export const defaultAdminPriceListRelations = [ + "prices", + "prices.variants", + "customer_groups", +] /** * @schema AdminPriceListRes @@ -285,4 +291,3 @@ export * from "./get-price-list" export * from "./list-price-list-products" export * from "./list-price-lists" export * from "./update-price-list" - diff --git a/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts b/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts index e0e6ea2520..9d49569ae4 100644 --- a/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts +++ b/packages/medusa/src/api/routes/admin/price-lists/list-price-list-products.ts @@ -10,6 +10,7 @@ import { IsString, ValidateNested, } from "class-validator" +import { MedusaError, isDefined } from "medusa-core-utils" import { FilterableProductProps } from "../../../../types/product" import PriceListService from "../../../../services/price-list" @@ -17,7 +18,6 @@ import { ProductStatus } from "../../../../models" import { Request } from "express" import { Type } from "class-transformer" import { pickBy } from "lodash" -import { isDefined } from "medusa-core-utils" /** * @oas [get] /admin/price-lists/{id}/products diff --git a/packages/medusa/src/api/routes/admin/products/index.ts b/packages/medusa/src/api/routes/admin/products/index.ts index 0afc8c1394..8b40526ab0 100644 --- a/packages/medusa/src/api/routes/admin/products/index.ts +++ b/packages/medusa/src/api/routes/admin/products/index.ts @@ -407,4 +407,3 @@ export * from "./set-metadata" export * from "./update-option" export * from "./update-product" export * from "./update-variant" - diff --git a/packages/medusa/src/api/routes/admin/products/list-products.ts b/packages/medusa/src/api/routes/admin/products/list-products.ts index ccbe3ec840..4640a87e33 100644 --- a/packages/medusa/src/api/routes/admin/products/list-products.ts +++ b/packages/medusa/src/api/routes/admin/products/list-products.ts @@ -6,11 +6,11 @@ import { SalesChannelService, } from "../../../../services" -import { IInventoryService } from "@medusajs/types" -import { Type } from "class-transformer" -import { Product } from "../../../../models" -import { PricedProduct } from "../../../../types/pricing" import { FilterableProductProps } from "../../../../types/product" +import { IInventoryService } from "@medusajs/types" +import { PricedProduct } from "../../../../types/pricing" +import { Product } from "../../../../models" +import { Type } from "class-transformer" /** * @oas [get] /admin/products diff --git a/packages/medusa/src/migrations/1680857773272-line-item-tax-adjustment-on-cascade-delete.ts b/packages/medusa/src/migrations/1680857773272-line-item-tax-adjustment-on-cascade-delete.ts index c9940d56a4..943e4d847b 100644 --- a/packages/medusa/src/migrations/1680857773272-line-item-tax-adjustment-on-cascade-delete.ts +++ b/packages/medusa/src/migrations/1680857773272-line-item-tax-adjustment-on-cascade-delete.ts @@ -5,14 +5,14 @@ export class lineItemTaxAdjustmentOnCascadeDelete1680857773272 { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( - `ALTER TABLE "line_item_tax_line" DROP CONSTRAINT "FK_5077fa54b0d037e984385dfe8ad"` + `ALTER TABLE "line_item_tax_line" DROP CONSTRAINT IF EXISTS "FK_5077fa54b0d037e984385dfe8ad"` ) await queryRunner.query( `ALTER TABLE "line_item_tax_line" ADD CONSTRAINT "FK_5077fa54b0d037e984385dfe8ad" FOREIGN KEY ("item_id") REFERENCES "line_item"("id") ON DELETE CASCADE ON UPDATE NO ACTION` ) await queryRunner.query( - `ALTER TABLE "line_item_adjustment" DROP CONSTRAINT "FK_be9aea2ccf3567007b6227da4d2"` + `ALTER TABLE "line_item_adjustment" DROP CONSTRAINT IF EXISTS "FK_be9aea2ccf3567007b6227da4d2"` ) await queryRunner.query( `ALTER TABLE "line_item_adjustment" ADD CONSTRAINT "FK_be9aea2ccf3567007b6227da4d2" FOREIGN KEY ("item_id") REFERENCES "line_item"("id") ON DELETE CASCADE ON UPDATE NO ACTION` diff --git a/packages/medusa/src/migrations/1680857773273-add-table-product-shipping-profile.ts b/packages/medusa/src/migrations/1680857773273-add-table-product-shipping-profile.ts index 2a081010a4..ea57470a57 100644 --- a/packages/medusa/src/migrations/1680857773273-add-table-product-shipping-profile.ts +++ b/packages/medusa/src/migrations/1680857773273-add-table-product-shipping-profile.ts @@ -32,14 +32,14 @@ export class addTableProductShippingProfile1680857773273 DROP INDEX IF EXISTS "idx_product_shipping_profile_product_id"; DROP INDEX IF EXISTS "idx_product_shipping_profile_profile_id"; - DROP TABLE IF EXISTS "product_shipping_profile"; - ALTER TABLE "product" ADD COLUMN IF NOT EXISTS "profile_id"; UPDATE "product" SET "profile_id" = "product_shipping_profile"."profile_id" FROM "product_shipping_profile" WHERE "product"."id" = "product_shipping_profile"."product_id"; + DROP TABLE IF EXISTS "product_shipping_profile"; + ALTER TABLE "product" ALTER COLUMN profile_id SET NOT NULL; CREATE INDEX IF NOT EXISTS "IDX_80823b7ae866dc5acae2dac6d2" ON "product" ("profile_id"); diff --git a/packages/medusa/src/migrations/1692953518123-drop_money_amount_constraints_for_pricing_module.ts b/packages/medusa/src/migrations/1692953518123-drop_money_amount_constraints_for_pricing_module.ts new file mode 100644 index 0000000000..e9c622bcb8 --- /dev/null +++ b/packages/medusa/src/migrations/1692953518123-drop_money_amount_constraints_for_pricing_module.ts @@ -0,0 +1,50 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class dropMoneyAmountConstraintsForPricingModule1692953518123 + implements MigrationInterface +{ + name = "dropMoneyAmountConstraintsForPricingModule1692953518123" + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + ` + CREATE TABLE IF NOT EXISTS "product_variant_money_amount" + ( + "id" character varying NOT NULL, + "money_amount_id" text NOT NULL, + "variant_id" text NOT NULL, + "deleted_at" TIMESTAMP WITH TIME ZONE, + "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + CONSTRAINT "PK_product_variant_money_amount" PRIMARY KEY ("id") + ); + + INSERT INTO "product_variant_money_amount"("id", "money_amount_id", "variant_id") + SELECT CONCAT('pvma_', id), "id", "variant_id" FROM "money_amount"; + + ALTER TABLE "money_amount" DROP COLUMN IF EXISTS "variant_id"; + CREATE UNIQUE INDEX IF NOT EXISTS "idx_product_variant_money_amount_money_amount_id_unique" ON "product_variant_money_amount" ("money_amount_id"); + CREATE INDEX IF NOT EXISTS "idx_product_variant_money_amount_variant_id" ON "product_variant_money_amount" ("variant_id"); + ` + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + ` + DROP INDEX IF EXISTS "idx_product_variant_money_amount_money_amount_id_unique"; + DROP INDEX IF EXISTS "idx_product_variant_money_amount_variant_id"; + + ALTER TABLE "product_variant_money_amount" ADD COLUMN IF NOT EXISTS "variant_id"; + + UPDATE "money_amount" SET "variant_id" = "product_variant_money_amount"."variant_id" + FROM "product_variant_money_amount" + WHERE "money_amount"."id" = "product_variant_money_amount"."money_amount_id"; + + DROP TABLE IF EXISTS "product_variant_money_amount"; + + CREATE INDEX IF NOT EXISTS idx_product_variant_money_amount_id ON money_amount (variant_id); + ` + ) + } +} diff --git a/packages/medusa/src/models/index.ts b/packages/medusa/src/models/index.ts index 82e7064636..24be85e01a 100644 --- a/packages/medusa/src/models/index.ts +++ b/packages/medusa/src/models/index.ts @@ -54,6 +54,7 @@ export * from "./product-type" export * from "./product-type-tax-rate" export * from "./product-variant" export * from "./product-variant-inventory-item" +export * from "./product-variant-money-amount" export * from "./publishable-api-key" export * from "./publishable-api-key-sales-channel" export * from "./refund" diff --git a/packages/medusa/src/models/money-amount.ts b/packages/medusa/src/models/money-amount.ts index 6251008249..3c630ef0c0 100644 --- a/packages/medusa/src/models/money-amount.ts +++ b/packages/medusa/src/models/money-amount.ts @@ -1,9 +1,13 @@ import { + AfterLoad, BeforeInsert, + BeforeUpdate, Column, Entity, Index, JoinColumn, + JoinTable, + ManyToMany, ManyToOne, } from "typeorm" @@ -43,17 +47,27 @@ export class MoneyAmount extends SoftDeletableEntity { @JoinColumn({ name: "price_list_id" }) price_list: PriceList | null - @Index('idx_money_amount_variant_id') - @Column({ nullable: true }) - variant_id: string - - @ManyToOne(() => ProductVariant, (variant) => variant.prices, { + @ManyToMany(() => ProductVariant, { onDelete: "CASCADE", }) - @JoinColumn({ name: "variant_id" }) + @JoinTable({ + name: "product_variant_money_amount", + joinColumn: { + name: "money_amount_id", + referencedColumnName: "id", + }, + inverseJoinColumn: { + name: "variant_id", + referencedColumnName: "id", + }, + }) + variants: ProductVariant[] + variant: ProductVariant - @Index('idx_money_amount_region_id') + variant_id: string + + @Index("idx_money_amount_region_id") @Column({ nullable: true }) region_id: string @@ -64,6 +78,27 @@ export class MoneyAmount extends SoftDeletableEntity { @BeforeInsert() private beforeInsert(): undefined | void { this.id = generateEntityId(this.id, "ma") + + if (this.variant || this.variant_id) { + this.variants = [ + { id: this.variant?.id || this.variant_id }, + ] as ProductVariant[] + } + } + + @BeforeUpdate() + private beforeUpdate(): void { + if (this.variant || this.variant_id) { + this.variants = [ + { id: this.variant?.id || this.variant_id }, + ] as ProductVariant[] + } + } + + @AfterLoad() + private afterLoad() { + this.variant = this.variants?.[0] + this.variant_id = this.variant?.id } } diff --git a/packages/medusa/src/models/product-category.ts b/packages/medusa/src/models/product-category.ts index d86245be47..fc2d539ec3 100644 --- a/packages/medusa/src/models/product-category.ts +++ b/packages/medusa/src/models/product-category.ts @@ -25,7 +25,7 @@ export class ProductCategory extends BaseEntity { @Column() name: string - @Column({ nullable: false, default: '' }) + @Column({ nullable: false, default: "" }) description: string @Index({ unique: true }) diff --git a/packages/medusa/src/models/product-variant-money-amount.ts b/packages/medusa/src/models/product-variant-money-amount.ts new file mode 100644 index 0000000000..75a82febae --- /dev/null +++ b/packages/medusa/src/models/product-variant-money-amount.ts @@ -0,0 +1,21 @@ +import { BeforeInsert, Column, Entity, Index } from "typeorm" +import { generateEntityId } from "../utils" +import { SoftDeletableEntity } from "../interfaces" + +@Entity() +export class ProductVariantMoneyAmount extends SoftDeletableEntity { + @Index("idx_product_variant_money_amount_money_amount_id_unique", { + unique: true, + }) + @Column() + money_amount_id: string + + @Index("idx_product_variant_money_amount_variant_id") + @Column() + variant_id: string + + @BeforeInsert() + private beforeInsert(): void { + this.id = generateEntityId(this.id, "pvma_") + } +} diff --git a/packages/medusa/src/models/product-variant.ts b/packages/medusa/src/models/product-variant.ts index a130656480..896877e1ea 100644 --- a/packages/medusa/src/models/product-variant.ts +++ b/packages/medusa/src/models/product-variant.ts @@ -4,6 +4,8 @@ import { Entity, Index, JoinColumn, + JoinTable, + ManyToMany, ManyToOne, OneToMany, } from "typeorm" @@ -28,9 +30,19 @@ export class ProductVariant extends SoftDeletableEntity { @JoinColumn({ name: "product_id" }) product: Product - @OneToMany(() => MoneyAmount, (ma) => ma.variant, { - cascade: true, - onDelete: "CASCADE", + @ManyToMany(() => MoneyAmount, { + cascade: ["remove", "soft-remove", "recover"], + }) + @JoinTable({ + name: "product_variant_money_amount", + joinColumn: { + name: "variant_id", + referencedColumnName: "id", + }, + inverseJoinColumn: { + name: "money_amount_id", + referencedColumnName: "id", + }, }) prices: MoneyAmount[] diff --git a/packages/medusa/src/repositories/money-amount.ts b/packages/medusa/src/repositories/money-amount.ts index b7b85787c3..df4d1ffb30 100644 --- a/packages/medusa/src/repositories/money-amount.ts +++ b/packages/medusa/src/repositories/money-amount.ts @@ -6,18 +6,24 @@ import { ObjectLiteral, WhereExpressionBuilder, } from "typeorm" +import { + MoneyAmount, + ProductVariant, + ProductVariantMoneyAmount, +} from "../models" import { PriceListPriceCreateInput, PriceListPriceUpdateInput, } from "../types/price-list" -import { MoneyAmount } from "../models" +import { MedusaError } from "medusa-core-utils" import { ProductVariantPrice } from "../types/product-variant" import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity" import { dataSource } from "../loaders/database" import { groupBy } from "lodash" import { isString } from "../utils" import partition from "lodash/partition" +import { ulid } from "ulid" type Price = Partial< Omit @@ -36,15 +42,37 @@ export const MoneyAmountRepository = dataSource .into(MoneyAmount) .values(data) + let rawMoneyAmounts if (!queryBuilder.connection.driver.isReturningSqlSupported("insert")) { - const rawMoneyAmounts = await queryBuilder.execute() - return rawMoneyAmounts.generatedMaps.map((d) => - this.create(d) - ) as MoneyAmount[] + rawMoneyAmounts = await queryBuilder.execute() + } else { + rawMoneyAmounts = await queryBuilder.returning("*").execute() } - const rawMoneyAmounts = await queryBuilder.returning("*").execute() - return rawMoneyAmounts.generatedMaps.map((d) => this.create(d)) + const created = rawMoneyAmounts.generatedMaps.map((d) => + this.create(d) + ) as MoneyAmount[] + + const variantMoneyAmounts = this.manager.create( + ProductVariantMoneyAmount, + data + .filter( + ( + d + ): d is { + variant: QueryDeepPartialEntity + id: string + } => !!d.variant + ) + .map((d) => ({ + variant_id: d.variant.id, + money_amount_id: d.id, + })) + ) + + await this.manager.save(variantMoneyAmounts) + + return created }, /** @@ -57,8 +85,15 @@ export const MoneyAmountRepository = dataSource prices: Price[] ): Promise { const pricesNotInPricesPayload = await this.createQueryBuilder() - .where({ + .leftJoinAndSelect( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .where("pvma.variant_id = :variant_id", { variant_id: variantId, + }) + .andWhere({ price_list_id: IsNull(), }) .andWhere( @@ -87,11 +122,27 @@ export const MoneyAmountRepository = dataSource ] : variantIdOrData - const queryBuilder = this.createQueryBuilder().delete() + const maDeleteQueryBuilder = this.createQueryBuilder("ma") + const mavDeleteQueryBuilder = this.createQueryBuilder() + .delete() + .from("product_variant_money_amount") for (const data_ of data) { + const maIdsForVariant = await this.createQueryBuilder("ma") + .leftJoin( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .addSelect("pvma.variant_id", "variant_id") + .addSelect("pvma.money_amount_id", "money_amount_id") + .where("pvma.variant_id = :variant_id", { + variant_id: data_.variantId, + }) + .getMany() + const where = { - variant_id: data_.variantId, + id: In(maIdsForVariant.map((ma) => ma.id)), price_list_id: IsNull(), } @@ -119,40 +170,72 @@ export const MoneyAmountRepository = dataSource } } - queryBuilder.orWhere( + maDeleteQueryBuilder.orWhere( new Brackets((localQueryBuild) => { localQueryBuild.where(where).andWhere(orWhere) }) ) } + const deleteAmounts = await maDeleteQueryBuilder.getMany() - await queryBuilder.execute() + if (!deleteAmounts.length) { + return + } + + await Promise.all([ + this.delete(deleteAmounts.map((mav) => mav.id)), + mavDeleteQueryBuilder + .where( + deleteAmounts.map((mav) => ({ + money_amount_id: mav.id, + })) + ) + .execute(), + ]) }, async upsertVariantCurrencyPrice( variantId: string, price: Price ): Promise { - let moneyAmount = await this.findOne({ - where: { - currency_code: price.currency_code, - variant_id: variantId, - region_id: IsNull(), - price_list_id: IsNull(), - }, - }) + let moneyAmount = await this.createQueryBuilder() + .leftJoinAndSelect( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .where("pvma.variant_id = :variantId", { variantId }) + .andWhere("ma.currency_code = :currencyCode", { + currencyCode: price.currency_code, + }) + .andWhere("ma.region_id IS NULL") + .andWhere("ma.price_list_id IS NULL") + .getOne() + + const created = !moneyAmount if (!moneyAmount) { moneyAmount = this.create({ ...price, currency_code: price.currency_code?.toLowerCase(), - variant_id: variantId, + variant: { id: variantId }, }) } else { moneyAmount.amount = price.amount } - return await this.save(moneyAmount) + const createdAmount = await this.save(moneyAmount) + + if (created) { + await this.createProductVariantMoneyAmounts([ + { + variant_id: variantId, + money_amount_id: createdAmount.id, + }, + ]) + } + + return createdAmount }, async addPriceListPrices( @@ -160,11 +243,29 @@ export const MoneyAmountRepository = dataSource prices: PriceListPriceCreateInput[], overrideExisting = false ): Promise { - const toInsert = prices.map((price) => - this.create({ - ...price, - price_list_id: priceListId, - }) + const [toInsert, joinTableValues] = prices.reduce( + (acc, price) => { + const [prices, joinTableValues] = acc + const id = `ma_${ulid()}` + const variant = this.create({ + ...price, + id, + price_list_id: priceListId, + }) + const joinTableValue = this.manager.create( + ProductVariantMoneyAmount, + { + variant_id: price.variant_id!, + money_amount_id: id, + } + ) + + return [ + [...prices, variant], + [...joinTableValues, joinTableValue], + ] + }, + [[], []] as [MoneyAmount[], ProductVariantMoneyAmount[]] ) const insertResult = await this.createQueryBuilder() @@ -172,19 +273,31 @@ export const MoneyAmountRepository = dataSource .orIgnore(true) .into(MoneyAmount) .values(toInsert as QueryDeepPartialEntity[]) + .returning("*") .execute() if (overrideExisting) { - await this.createQueryBuilder() + const { raw } = await this.createQueryBuilder() .delete() .from(MoneyAmount) .where({ price_list_id: priceListId, id: Not(In(insertResult.identifiers.map((ma) => ma.id))), }) + .returning("id") + .execute() + + await this.createQueryBuilder() + .delete() + .from("product_variant_money_amount") + .where({ + money_amount_id: In(raw.map((deletedMa) => deletedMa.id)), + }) .execute() } + await this.manager.save(joinTableValues) + return await this.manager .createQueryBuilder(MoneyAmount, "ma") .select() @@ -210,7 +323,12 @@ export const MoneyAmountRepository = dataSource ): Promise<[MoneyAmount[], number]> { const qb = this.createQueryBuilder("ma") .leftJoinAndSelect("ma.price_list", "price_list") - .where("ma.variant_id = :variant_id", { variant_id }) + .leftJoin( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .where("pvma.variant_id = :variant_id", { variant_id }) const getAndWhere = (subQb): WhereExpressionBuilder => { const andWhere = subQb.where("ma.price_list_id = :price_list_id", { @@ -256,6 +374,60 @@ export const MoneyAmountRepository = dataSource return [result[0][variant_id], result[1]] }, + async findCurrencyMoneyAmounts( + where: { variant_id: string; currency_code: string }[] + ) { + const qb = this.createQueryBuilder("ma") + .leftJoin( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .addSelect("pvma.variant_id", "variant_id") + + where.forEach((variantCurrency, i) => + qb.orWhere( + `(pvma.variant_id = :variant_id_${i} AND ma.currency_code = :currency_code_${i} AND ma.region_id IS NULL AND ma.price_list_id IS NULL)`, + { + [`variant_id_${i}`]: variantCurrency.variant_id, + [`currency_code_${i}`]: variantCurrency.currency_code, + } + ) + ) + + const rawAndEntities = await qb.getRawAndEntities() + return rawAndEntities.entities.map((e, i) => { + return { ...e, variant_id: rawAndEntities.raw[i].variant_id } + }) + }, + + async findRegionMoneyAmounts( + where: { variant_id: string; region_id: string }[] + ) { + const qb = this.createQueryBuilder("ma") + .leftJoin( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .addSelect("pvma.variant_id", "variant_id") + + where.forEach((w, i) => + qb.orWhere( + `(pvma.variant_id = :variant_id_${i} AND ma.region_id = :region_id_${i} AND ma.price_list_id IS NULL)`, + { + [`variant_id_${i}`]: w.variant_id, + [`region_id_${i}`]: w.region_id, + } + ) + ) + + const rawAndEntities = await qb.getRawAndEntities() + return rawAndEntities.entities.map((e, i) => { + return { ...e, variant_id: rawAndEntities.raw[i].variant_id } + }) + }, + async findManyForVariantsInRegion( variant_ids: string | string[], region_id?: string, @@ -266,11 +438,22 @@ export const MoneyAmountRepository = dataSource ): Promise<[Record, number]> { variant_ids = Array.isArray(variant_ids) ? variant_ids : [variant_ids] + if (!variant_ids.length) { + return [{}, 0] + } const date = new Date() const qb = this.createQueryBuilder("ma") .leftJoinAndSelect("ma.price_list", "price_list") - .where({ variant_id: In(variant_ids) }) + .leftJoinAndSelect( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .addSelect("pvma.variant_id", "variant_id") + .andWhere("pvma.variant_id IN (:...variantIds)", { + variantIds: variant_ids, + }) .andWhere("(ma.price_list_id is null or price_list.status = 'active')") .andWhere( "(price_list.ends_at is null OR price_list.ends_at > :date)", @@ -326,7 +509,16 @@ export const MoneyAmountRepository = dataSource ) } - const [prices, count] = await qb.getManyAndCount() + const count = await qb.getCount() + const res = await qb.getRawAndEntities() + + const { entities, raw } = res + + const prices = entities.map((p, i) => { + p["variant_id"] = raw[i]["variant_id"] + return p + }) + const groupedPrices = groupBy(prices, "variant_id") return [groupedPrices, count] @@ -341,11 +533,62 @@ export const MoneyAmountRepository = dataSource (update) => update.id ) - const newPriceEntities = newPrices.map((price) => - this.create({ ...price, price_list_id: priceListId }) + const [newPriceEntities, joinTableValues] = newPrices.reduce( + (acc, price) => { + const [prices, joinTableValues] = acc + const id = `ma_${ulid()}` + const variantPrice = this.create({ + ...price, + id, + price_list_id: priceListId, + }) + const joinTableValue = this.manager.create( + ProductVariantMoneyAmount, + { + variant_id: price.variant_id!, + money_amount_id: id, + } + ) + + prices.push(variantPrice) + joinTableValues.push(joinTableValue) + + return [prices, joinTableValues] + }, + [[], []] as [MoneyAmount[], ProductVariantMoneyAmount[]] ) - return await this.save([...existingPrices, ...newPriceEntities]) + const [prices] = await Promise.all([ + this.save([...existingPrices, ...newPriceEntities]), + await this.manager.save(joinTableValues), + ]) + + return prices + }, + + async getPricesForVariantInRegion( + variantId: string, + regionId: string | undefined + ): Promise { + return this.createQueryBuilder() + .leftJoinAndSelect( + "product_variant_money_amount", + "pvma", + "pvma.money_amount_id = ma.id" + ) + .where("pvma.variant_id = :variantId", { variantId }) + .where("ma.region_id = :regionId", { regionId }) + .getMany() + }, + + async createProductVariantMoneyAmounts( + toCreate: { variant_id: string; money_amount_id: string }[] + ) { + return await this.createQueryBuilder() + .insert() + .into("product_variant_money_amount") + .values(toCreate) + .execute() }, }) diff --git a/packages/medusa/src/services/__tests__/price-list.js b/packages/medusa/src/services/__tests__/price-list.js index 1d6d5dc50a..752f5520de 100644 --- a/packages/medusa/src/services/__tests__/price-list.js +++ b/packages/medusa/src/services/__tests__/price-list.js @@ -127,14 +127,19 @@ describe("PriceListService", () => { updateRelatedMoneyAmountRepository.create = jest .fn() .mockImplementation((rawEntity) => Promise.resolve(rawEntity)) + updateRelatedMoneyAmountRepository.save = jest .fn() .mockImplementation(() => Promise.resolve()) updateRelatedMoneyAmountRepository.updatePriceListPrices = MoneyAmountRepository.updatePriceListPrices + const manager = { + save: (entities) => Promise.resolve(entities), + create: (entities) => Promise.resolve(entities), + } const updateRelatedPriceListService = new PriceListService({ - manager: MockManager, + manager: { ...MockManager, ...manager }, customerGroupService, priceListRepository, moneyAmountRepository: updateRelatedMoneyAmountRepository, diff --git a/packages/medusa/src/services/__tests__/product-variant.js b/packages/medusa/src/services/__tests__/product-variant.js index f3a5ef8426..37d1c2f8f0 100644 --- a/packages/medusa/src/services/__tests__/product-variant.js +++ b/packages/medusa/src/services/__tests__/product-variant.js @@ -670,6 +670,16 @@ describe("ProductVariantService", () => { insertBulk: (data) => data, }) + const productVariantRepository = MockRepository({ + find: (query) => { + return Promise.resolve([ + { + id: IdMap.getId("ironman"), + }, + ]) + }, + }) + const oldPrices = [ { currency_code: "dkk", @@ -686,6 +696,20 @@ describe("ProductVariantService", () => { moneyAmountRepository.upsertVariantCurrencyPrice = jest .fn() .mockImplementation(() => Promise.resolve()) + moneyAmountRepository.findCurrencyMoneyAmounts = jest + .fn() + .mockImplementation(() => + Promise.resolve([ + { + id: IdMap.getId("dkk"), + variant_id: IdMap.getId("ironman"), + currency_code: "dkk", + }, + ]) + ) + moneyAmountRepository.findRegionMoneyAmounts = jest + .fn() + .mockImplementation(() => Promise.resolve([])) const priceSelectionStrategy = { withTransaction: function () { @@ -723,6 +747,7 @@ describe("ProductVariantService", () => { regionService, priceSelectionStrategy, moneyAmountRepository, + productVariantRepository, }) beforeEach(async () => { @@ -730,7 +755,7 @@ describe("ProductVariantService", () => { }) it("successfully removes obsolete prices and create new prices", async () => { - await productVariantService.updateVariantPrices("ironman", [ + await productVariantService.updateVariantPrices(IdMap.getId("ironman"), [ { currency_code: "usd", amount: 4000, @@ -744,7 +769,7 @@ describe("ProductVariantService", () => { expect(moneyAmountRepository.insertBulk).toHaveBeenCalledTimes(1) expect(moneyAmountRepository.insertBulk).toHaveBeenCalledWith([ { - variant_id: "ironman", + variant: { id: IdMap.getId("ironman") }, currency_code: "usd", amount: 4000, }, @@ -761,7 +786,7 @@ describe("ProductVariantService", () => { expect(moneyAmountRepository.create).toHaveBeenCalledTimes(1) expect(moneyAmountRepository.create).toHaveBeenCalledWith({ - variant_id: IdMap.getId("ironman"), + variant: { id: IdMap.getId("ironman") }, region_id: IdMap.getId("cali"), currency_code: "usd", amount: 100, diff --git a/packages/medusa/src/services/price-list.ts b/packages/medusa/src/services/price-list.ts index 36f8fc81cb..b70946d69f 100644 --- a/packages/medusa/src/services/price-list.ts +++ b/packages/medusa/src/services/price-list.ts @@ -1,27 +1,28 @@ -import { FlagRouter } from "@medusajs/utils" -import { isDefined, MedusaError } from "medusa-core-utils" -import { DeepPartial, EntityManager } from "typeorm" -import { CustomerGroupService } from "." -import { TransactionBaseService } from "../interfaces" -import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" -import { CustomerGroup, PriceList, Product, ProductVariant } from "../models" -import { MoneyAmountRepository } from "../repositories/money-amount" -import { PriceListRepository } from "../repositories/price-list" -import { ProductVariantRepository } from "../repositories/product-variant" -import { FindConfig, Selector } from "../types/common" import { - CreatePriceListInput, - FilterablePriceListProps, - PriceListPriceCreateInput, - PriceListPriceUpdateInput, - UpdatePriceListInput, + CreatePriceListInput, + FilterablePriceListProps, + PriceListPriceCreateInput, + PriceListPriceUpdateInput, + UpdatePriceListInput, } from "../types/price-list" +import { CustomerGroup, PriceList, Product, ProductVariant } from "../models" +import { DeepPartial, EntityManager } from "typeorm" +import { FindConfig, Selector } from "../types/common" +import { MedusaError, isDefined } from "medusa-core-utils" + +import { CustomerGroupService } from "." import { FilterableProductProps } from "../types/product" import { FilterableProductVariantProps } from "../types/product-variant" -import { buildQuery } from "../utils" +import { FlagRouter } from "@medusajs/utils" +import { MoneyAmountRepository } from "../repositories/money-amount" +import { PriceListRepository } from "../repositories/price-list" import ProductService from "./product" +import { ProductVariantRepository } from "../repositories/product-variant" import ProductVariantService from "./product-variant" import RegionService from "./region" +import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" +import { TransactionBaseService } from "../interfaces" +import { buildQuery } from "../utils" type PriceListConstructorProps = { manager: EntityManager @@ -366,10 +367,12 @@ class PriceListService extends TransactionBaseService { requiresPriceList ) - return productVariantRepo.create({ + const variant = productVariantRepo.create({ ...v, - prices, }) + + variant.prices = prices + return variant }) ) } @@ -497,13 +500,29 @@ class PriceListService extends TransactionBaseService { const regionServiceTx = this.regionService_.withTransaction( this.activeManager_ ) + + const regions = await regionServiceTx.list( + { + id: [ + ...new Set( + prices + .map((p) => p.region_id) + .filter((p: string | undefined): p is string => !!p) + ), + ], + }, + {} + ) + + const regionsMap = new Map(regions.map((r) => [r.id, r])) + for (const price of prices) { const p = { ...price } if (p.region_id) { - const region = await regionServiceTx.retrieve(p.region_id) + const region = regionsMap.get(p.region_id) - p.currency_code = region.currency_code + p.currency_code = region!.currency_code } prices_.push(p) diff --git a/packages/medusa/src/services/pricing.ts b/packages/medusa/src/services/pricing.ts index b8fe585015..4bbf411b74 100644 --- a/packages/medusa/src/services/pricing.ts +++ b/packages/medusa/src/services/pricing.ts @@ -4,18 +4,18 @@ import { EntityManager } from "typeorm" import { ProductVariantService, RegionService, TaxProviderService } from "." import { TransactionBaseService } from "../interfaces" import { - IPriceSelectionStrategy, - PriceSelectionContext, + IPriceSelectionStrategy, + PriceSelectionContext, } from "../interfaces/price-selection-strategy" import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" import { Product, ProductVariant, Region, ShippingOption } from "../models" import { - PricedProduct, - PricedShippingOption, - PricedVariant, - PricingContext, - ProductVariantPricing, - TaxedPricing, + PricedProduct, + PricedShippingOption, + PricedVariant, + PricingContext, + ProductVariantPricing, + TaxedPricing, } from "../types/pricing" import { TaxServiceRate } from "../types/tax-service" import { calculatePriceTaxAmount } from "../utils" diff --git a/packages/medusa/src/services/product-variant.ts b/packages/medusa/src/services/product-variant.ts index e4dec40b1f..a66dee1137 100644 --- a/packages/medusa/src/services/product-variant.ts +++ b/packages/medusa/src/services/product-variant.ts @@ -1,4 +1,3 @@ -import { isDefined, MedusaError } from "medusa-core-utils" import { Brackets, EntityManager, @@ -8,25 +7,8 @@ import { FindOptionsWhere, ILike, In, - IsNull, SelectQueryBuilder, } from "typeorm" -import { - IPriceSelectionStrategy, - PriceSelectionContext, - TransactionBaseService, -} from "../interfaces" -import { - MoneyAmount, - Product, - ProductOptionValue, - ProductVariant, -} from "../models" -import { - FindWithRelationsOptions, - ProductVariantRepository, -} from "../repositories/product-variant" -import { FindConfig, WithRequiredProperty } from "../types/common" import { CreateProductVariantInput, FilterableProductVariantProps, @@ -38,6 +20,23 @@ import { UpdateVariantPricesData, UpdateVariantRegionPriceData, } from "../types/product-variant" +import { FindConfig, WithRequiredProperty } from "../types/common" +import { + FindWithRelationsOptions, + ProductVariantRepository, +} from "../repositories/product-variant" +import { + IPriceSelectionStrategy, + PriceSelectionContext, + TransactionBaseService, +} from "../interfaces" +import { MedusaError, isDefined } from "medusa-core-utils" +import { + MoneyAmount, + Product, + ProductOptionValue, + ProductVariant, +} from "../models" import { buildQuery, hasChanges, @@ -46,12 +45,12 @@ import { setMetadata, } from "../utils" -import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity" import { CartRepository } from "../repositories/cart" -import { MoneyAmountRepository } from "../repositories/money-amount" -import { ProductRepository } from "../repositories/product" -import { ProductOptionValueRepository } from "../repositories/product-option-value" import EventBusService from "./event-bus" +import { MoneyAmountRepository } from "../repositories/money-amount" +import { ProductOptionValueRepository } from "../repositories/product-option-value" +import { ProductRepository } from "../repositories/product" +import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity" import RegionService from "./region" import { buildRelations } from "@medusajs/utils" @@ -398,6 +397,7 @@ class ProductVariantService extends TransactionBaseService { { id }, { id, ...toUpdate } ) + result = variantRepo.create({ ...variant, ...rawResult.generatedMaps[0], @@ -544,16 +544,16 @@ class ProductVariantService extends TransactionBaseService { const moneyAmountRepo = manager.withRepository( this.moneyAmountRepository_ ) + const productVariantRepo = this.activeManager_.withRepository( + this.productVariantRepository_ + ) const where = data.map((data_) => ({ variant_id: data_.variantId, region_id: data_.price.region_id, - price_list_id: IsNull(), })) - const moneyAmounts = await moneyAmountRepo.find({ - where, - }) + const moneyAmounts = await moneyAmountRepo.findRegionMoneyAmounts(where) const moneyAmountsMapToVariantId = new Map() moneyAmounts.map((d) => { @@ -582,12 +582,11 @@ class ProductVariantService extends TransactionBaseService { }) } } else { - dataToCreate.push( - moneyAmountRepo.create({ - ...price, - variant_id: variantId, - }) as QueryDeepPartialEntity - ) + const ma = moneyAmountRepo.create({ + ...price, + }) as QueryDeepPartialEntity + ma.variant = { id: variantId } + dataToCreate.push(ma) } }) @@ -626,17 +625,16 @@ class ProductVariantService extends TransactionBaseService { const moneyAmountRepo = manager.withRepository( this.moneyAmountRepository_ ) + const productVariantRepo = this.activeManager_.withRepository( + this.productVariantRepository_ + ) const where = data.map((data_) => ({ variant_id: data_.variantId, currency_code: data_.price.currency_code, - region_id: IsNull(), - price_list_id: IsNull(), })) - const moneyAmounts = await moneyAmountRepo.find({ - where, - }) + const moneyAmounts = await moneyAmountRepo.findCurrencyMoneyAmounts(where) const moneyAmountsMapToVariantId = new Map() moneyAmounts.map((d) => { @@ -665,13 +663,12 @@ class ProductVariantService extends TransactionBaseService { }) } } else { - dataToCreate.push( - moneyAmountRepo.create({ - ...price, - variant_id: variantId, - currency_code: price.currency_code.toLowerCase(), - }) as QueryDeepPartialEntity - ) + const ma = moneyAmountRepo.create({ + ...price, + currency_code: price.currency_code.toLowerCase(), + }) as QueryDeepPartialEntity + ma.variant = { id: variantId } + dataToCreate.push(ma) } }) @@ -746,24 +743,34 @@ class ProductVariantService extends TransactionBaseService { this.moneyAmountRepository_ ) - let moneyAmount = await moneyAmountRepo.findOne({ - where: { - variant_id: variantId, - region_id: price.region_id, - price_list_id: IsNull(), - }, - }) + let [moneyAmount] = await moneyAmountRepo.getPricesForVariantInRegion( + variantId, + price.region_id + ) + + const created = !moneyAmount if (!moneyAmount) { moneyAmount = moneyAmountRepo.create({ ...price, - variant_id: variantId, + variant: { id: variantId }, }) } else { moneyAmount.amount = price.amount } - return await moneyAmountRepo.save(moneyAmount) + const createdAmount = await moneyAmountRepo.save(moneyAmount) + + if (created) { + await moneyAmountRepo.createProductVariantMoneyAmounts([ + { + variant_id: variantId, + money_amount_id: createdAmount.id, + }, + ]) + } + + return createdAmount }) } diff --git a/packages/medusa/src/strategies/batch-jobs/price-list/import.ts b/packages/medusa/src/strategies/batch-jobs/price-list/import.ts index 3c36ae71fd..6ed42bde1d 100644 --- a/packages/medusa/src/strategies/batch-jobs/price-list/import.ts +++ b/packages/medusa/src/strategies/batch-jobs/price-list/import.ts @@ -1,15 +1,10 @@ -import { EntityManager } from "typeorm" -import { computerizeAmount, MedusaError } from "medusa-core-utils" - import { AbstractBatchJobStrategy, IFileService } from "../../../interfaces" -import CsvParser from "../../../services/csv-parser" import { BatchJobService, PriceListService, ProductVariantService, RegionService, } from "../../../services" -import { CreateBatchJobInput } from "../../../types/batch-job" import { InjectedProps, OperationType, @@ -21,9 +16,14 @@ import { TBuiltPriceListImportLine, TParsedPriceListImportRowData, } from "./types" +import { MedusaError, computerizeAmount } from "medusa-core-utils" + import { BatchJob } from "../../../models" -import { TParsedProductImportRowData } from "../product/types" +import { CreateBatchJobInput } from "../../../types/batch-job" +import CsvParser from "../../../services/csv-parser" +import { EntityManager } from "typeorm" import { PriceListPriceCreateInput } from "../../../types/price-list" +import { TParsedProductImportRowData } from "../product/types" /* * Default strategy class used for a batch import of products/variants. @@ -309,12 +309,14 @@ class PriceListImportStrategy extends AbstractBatchJobStrategy { try { await txPriceListService.addPrices( priceListId, - (op.prices as PriceListPriceCreateInput[]).map((p) => { - return { - ...p, - variant_id: op.variant_id, + (op.prices as PriceListPriceCreateInput[]).map( + (p: PriceListPriceCreateInput) => { + return { + ...p, + variant_id: op.variant_id as string, + } } - }) + ) ) } catch (e) { PriceListImportStrategy.throwDescriptiveError(op, e.message) diff --git a/packages/medusa/src/strategies/price-selection.ts b/packages/medusa/src/strategies/price-selection.ts index 84f789c97f..e5a23fc820 100644 --- a/packages/medusa/src/strategies/price-selection.ts +++ b/packages/medusa/src/strategies/price-selection.ts @@ -1,13 +1,13 @@ import { - AbstractPriceSelectionStrategy, - PriceSelectionContext, - PriceSelectionResult, - PriceType, + AbstractPriceSelectionStrategy, + PriceSelectionContext, + PriceSelectionResult, + PriceType, } from "../interfaces" import { ICacheService } from "@medusajs/types" import { FlagRouter } from "@medusajs/utils" -import { isDefined } from "medusa-core-utils" +import { MedusaError, isDefined } from "medusa-core-utils" import { EntityManager } from "typeorm" import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing" import { MoneyAmountRepository } from "../repositories/money-amount" diff --git a/packages/medusa/src/types/price-list.ts b/packages/medusa/src/types/price-list.ts index 3ff5f32640..dc1d8babc5 100644 --- a/packages/medusa/src/types/price-list.ts +++ b/packages/medusa/src/types/price-list.ts @@ -158,6 +158,7 @@ export type PriceListPriceUpdateInput = { export type PriceListPriceCreateInput = { region_id?: string currency_code?: string + variant_id: string amount: number min_quantity?: number max_quantity?: number diff --git a/packages/pricing/integration-tests/__fixtures__/price-list/data.ts b/packages/pricing/integration-tests/__fixtures__/price-list/data.ts new file mode 100644 index 0000000000..67fe3cd354 --- /dev/null +++ b/packages/pricing/integration-tests/__fixtures__/price-list/data.ts @@ -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' + }] + } +] \ No newline at end of file diff --git a/packages/pricing/integration-tests/__fixtures__/price-list/index.ts b/packages/pricing/integration-tests/__fixtures__/price-list/index.ts new file mode 100644 index 0000000000..45caafde49 --- /dev/null +++ b/packages/pricing/integration-tests/__fixtures__/price-list/index.ts @@ -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 { + 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 +} diff --git a/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts new file mode 100644 index 0000000000..3e817b97b8 --- /dev/null +++ b/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts @@ -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", + }) + ) + }) + }) +}) diff --git a/packages/product/integration-tests/__fixtures__/product-category/index.ts b/packages/product/integration-tests/__fixtures__/product-category/index.ts index 7a9b15e699..662bb835cf 100644 --- a/packages/product/integration-tests/__fixtures__/product-category/index.ts +++ b/packages/product/integration-tests/__fixtures__/product-category/index.ts @@ -17,7 +17,7 @@ export async function createProductCategories( parentCategory = await manager.findOne(ProductCategory, parentCategoryId) } - const category = await manager.create(ProductCategory, { + const category = manager.create(ProductCategory, { ...categoryDataClone, parent_category: parentCategory, }) diff --git a/packages/product/src/scripts/seed.ts b/packages/product/src/scripts/seed.ts index 6c3eb5fb66..31bd14b28e 100644 --- a/packages/product/src/scripts/seed.ts +++ b/packages/product/src/scripts/seed.ts @@ -72,7 +72,7 @@ async function createProductCategories( parentCategory = await manager.findOne(ProductCategory, parentCategoryId) } - const category = await manager.create(ProductCategory, { + const category = manager.create(ProductCategory, { ...categoryDataClone, parent_category: parentCategory, })