Feat: use price selection strategy (#1165)

* init

* add query params

* added buld id validation to repo

* admin done

* updated price reqs

* initial price selection strategy

* update customer seeder

* format models

* price selection strategy

* price selection testing

* update price selection tests

* update price selection strategy

* remove console.warn

* update price seleciton strategy

* use price selection strategy in "get-product"

* price selection strategy integration testing

* update integration tests

* update price selection strat

* remove console.log

* fix unit tests

* update product snapshot integration tests

* fix failing unit tests

* update variant test snapshots

* update variant test snapshots

* fix failing unit tests

* update product snapshot integration tests

* intial implementation of PriceList

* add price selection strategy test to list-products

* add price selection to list products

* add price selection strategy to getRegionPrice

* add price selection strategy to get variant

* update product snapshot test

* store testing of price selection

* variant services

* update cart service

* update product tests

* update test

* unit testing with price selection strategy

* integration tests for price lists

* update sort prices for consistent results

* update snapshot

* update product snapshot with product ids

* this time pipelines work

* swap tests

* redo ordering

* updated admin/product integration tests

* update updateVariantPrices method

* remove comment from error handler

* add integration test for batch deleting prices associated with price list

* named ids

* run with verbose

* add console.log

* sort products in integration test

* remove verbose flag

* make update to prices through variant service limited to default prices

* update store/products.js snapshot

* update comment

* add todo

* lift existing price calculations to variant level

* remove unused import

* add api unit tests and update product integration tests to validate that prices from Price List are ignored

* fix product test

* update integration tests

* pre merge commit

* requested changes

* cascade

* ensure delete variant cascades to MoneyAmount

* fetch variants correctly

* use find options

* add pricelist to relevant seeders

* update integration tests

* update price selection with "includeDiscountPrices"

* use transaction with price selection strategy

* add await to prevent store test errors

* remove verbose

* addresses PR feedback

* removed unused endpoint

* remove unused repository from constructor

* remove from constructor argument

* update mock

* update unit tests

* fix failing store integration tests

* remove medusajs ressource

* re add env.template

* price selection strategy methods

* fix integration tests

* update unit tests

* remove commented out code

* update jsdoc

* update price selection strategy parameter

* update snapshots

* integration tests cleanup

* pr feedback

* update integration tests

* pr feedback

* price selection unit tests

* add calculated price type to results

* cleanup include discount prices and price selection configs

* refactor price selection params to a separate file

* update tests and refactor price selection seeder

* remove prices from variant update

* rename result

* pr feedback

* remove unused import

* create getRegionPriceContext

* remove from params in search

* remove unused import

Co-authored-by: Kasper <kasper@medusajs.com>
Co-authored-by: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com>
This commit is contained in:
Philip Korsholm
2022-03-23 17:17:19 +01:00
committed by GitHub
co-authored by Kasper Kasper Fabricius Kristensen
parent 491b6eba2d
commit e2423020c0
36 changed files with 3794 additions and 533 deletions
@@ -21,7 +21,7 @@ Array [
"handle": "test-product",
"height": null,
"hs_code": null,
"id": StringMatching /\\^test-\\*/,
"id": "test-product",
"images": Array [
Object {
"created_at": Any<String>,
@@ -78,6 +78,7 @@ Array [
Object {
"allow_backorder": false,
"barcode": "test-barcode",
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean",
@@ -103,15 +104,17 @@ Array [
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": StringMatching /\\^test-price\\*/,
"id": "test-price",
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -129,6 +132,7 @@ Array [
Object {
"allow_backorder": false,
"barcode": null,
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean2",
@@ -154,6 +158,7 @@ Array [
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
@@ -163,10 +168,11 @@ Array [
"id": StringMatching /\\^test-price\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
"variant_id": StringMatching /\\^test-variant\\*/,
"variant_id": "test-variant_2",
},
],
"product_id": StringMatching /\\^test-\\*/,
@@ -180,6 +186,7 @@ Array [
Object {
"allow_backorder": false,
"barcode": "test-barcode 1",
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean1",
@@ -205,6 +212,7 @@ Array [
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
@@ -214,6 +222,7 @@ Array [
"id": StringMatching /\\^test-price\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -228,6 +237,60 @@ Array [
"weight": null,
"width": null,
},
Object {
"allow_backorder": false,
"barcode": "test-barcode-sale",
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean-sale",
"height": null,
"hs_code": null,
"id": "test-variant-sale",
"inventory_quantity": 10,
"length": null,
"manage_inventory": true,
"material": null,
"metadata": null,
"mid_code": null,
"options": Array [
Object {
"created_at": Any<String>,
"deleted_at": null,
"id": StringMatching /\\^test-variant-option\\*/,
"metadata": null,
"option_id": StringMatching /\\^test-opt\\*/,
"updated_at": Any<String>,
"value": "Default variant",
"variant_id": StringMatching /\\^test-variant\\*/,
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 1000,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": "test-price-sale",
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
"variant_id": StringMatching /\\^test-variant\\*/,
},
],
"product_id": StringMatching /\\^test-\\*/,
"sku": "test-sku-sale",
"title": "Test variant",
"upc": "test-upc-sale",
"updated_at": Any<String>,
"weight": null,
"width": null,
},
],
"weight": null,
"width": null,
@@ -251,7 +314,7 @@ Array [
"handle": "test-product1",
"height": null,
"hs_code": null,
"id": StringMatching /\\^test-\\*/,
"id": "test-product1",
"images": Array [],
"is_giftcard": false,
"length": null,
@@ -289,6 +352,7 @@ Array [
Object {
"allow_backorder": false,
"barcode": null,
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean4",
@@ -314,6 +378,7 @@ Array [
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
@@ -323,6 +388,7 @@ Array [
"id": StringMatching /\\^test-price\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -340,6 +406,7 @@ Array [
Object {
"allow_backorder": false,
"barcode": null,
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean3",
@@ -365,6 +432,7 @@ Array [
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
@@ -374,6 +442,7 @@ Array [
"id": StringMatching /\\^test-price\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": "test-region",
"updated_at": Any<String>,
@@ -392,39 +461,6 @@ Array [
"weight": null,
"width": null,
},
Object {
"collection": Any<Object>,
"collection_id": "test-collection1",
"created_at": Any<String>,
"deleted_at": null,
"description": "test-product-description",
"discountable": true,
"external_id": null,
"handle": "test-product_filtering_3",
"height": null,
"hs_code": null,
"id": StringMatching /\\^test-\\*/,
"images": Array [],
"is_giftcard": false,
"length": null,
"material": null,
"metadata": null,
"mid_code": null,
"options": Any<Array>,
"origin_country": null,
"profile_id": StringMatching /\\^sp_\\*/,
"status": "draft",
"subtitle": null,
"tags": Any<Array>,
"thumbnail": null,
"title": "Test product filtering 3",
"type": Any<Object>,
"type_id": "test-type",
"updated_at": Any<String>,
"variants": Any<Array>,
"weight": null,
"width": null,
},
Object {
"collection": Any<Object>,
"collection_id": "test-collection1",
@@ -436,7 +472,7 @@ Array [
"handle": "test-product_filtering_1",
"height": null,
"hs_code": null,
"id": StringMatching /\\^test-\\*/,
"id": "test-product_filtering_1",
"images": Array [],
"is_giftcard": false,
"length": null,
@@ -469,7 +505,7 @@ Array [
"handle": "test-product_filtering_2",
"height": null,
"hs_code": null,
"id": StringMatching /\\^test-\\*/,
"id": "test-product_filtering_2",
"images": Array [],
"is_giftcard": false,
"length": null,
@@ -491,6 +527,39 @@ Array [
"weight": null,
"width": null,
},
Object {
"collection": Any<Object>,
"collection_id": "test-collection1",
"created_at": Any<String>,
"deleted_at": null,
"description": "test-product-description",
"discountable": true,
"external_id": null,
"handle": "test-product_filtering_3",
"height": null,
"hs_code": null,
"id": "test-product_filtering_3",
"images": Array [],
"is_giftcard": false,
"length": null,
"material": null,
"metadata": null,
"mid_code": null,
"options": Any<Array>,
"origin_country": null,
"profile_id": StringMatching /\\^sp_\\*/,
"status": "draft",
"subtitle": null,
"tags": Any<Array>,
"thumbnail": null,
"title": "Test product filtering 3",
"type": Any<Object>,
"type_id": "test-type",
"updated_at": Any<String>,
"variants": Any<Array>,
"weight": null,
"width": null,
},
]
`;
@@ -539,6 +608,7 @@ Array [
Object {
"allow_backorder": false,
"barcode": null,
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": null,
@@ -564,6 +634,7 @@ Array [
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
@@ -573,6 +644,7 @@ Array [
"id": Any<String>,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -696,6 +768,7 @@ Object {
Object {
"allow_backorder": false,
"barcode": null,
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": null,
@@ -731,6 +804,7 @@ Object {
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 100,
@@ -740,6 +814,7 @@ Object {
"id": StringMatching /\\^ma_\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -753,6 +828,7 @@ Object {
"id": StringMatching /\\^ma_\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -766,6 +842,7 @@ Object {
"id": StringMatching /\\^ma_\\*/,
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
@@ -855,6 +932,7 @@ Object {
Object {
"allow_backorder": false,
"barcode": "test-barcode",
"calculated_price": null,
"created_at": Any<String>,
"deleted_at": null,
"ean": "test-ean",
@@ -880,6 +958,7 @@ Object {
},
],
"origin_country": null,
"original_price": null,
"prices": Array [
Object {
"amount": 75,
@@ -889,6 +968,7 @@ Object {
"id": "test-price",
"max_quantity": null,
"min_quantity": null,
"price_list": null,
"price_list_id": null,
"region_id": null,
"updated_at": Any<String>,
+66 -152
View File
@@ -522,10 +522,13 @@ describe("/admin/products", () => {
console.log(err)
})
response.data.products.sort((a, b) =>
a.created_at > b.created_at ? 1 : -1
)
expect(response.data.products).toMatchSnapshot([
{
id: expect.stringMatching(/^test-*/),
created_at: expect.any(String),
id: "test-product",
options: [
{
id: expect.stringMatching(/^test-*/),
@@ -543,7 +546,53 @@ describe("/admin/products", () => {
],
variants: [
{
id: "test-variant", // expect.stringMatching(/^test-variant*/),
id: "test-variant",
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
prices: [
{
id: "test-price",
variant_id: expect.stringMatching(/^test-variant*/),
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
options: [
{
id: expect.stringMatching(/^test-variant-option*/),
variant_id: expect.stringMatching(/^test-variant*/),
option_id: expect.stringMatching(/^test-opt*/),
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
},
{
id: "test-variant_2",
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
prices: [
{
id: expect.stringMatching(/^test-price*/),
variant_id: "test-variant_2",
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
options: [
{
id: expect.stringMatching(/^test-variant-option*/),
variant_id: expect.stringMatching(/^test-variant*/),
option_id: expect.stringMatching(/^test-opt*/),
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
},
{
id: "test-variant_1",
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
@@ -566,36 +615,13 @@ describe("/admin/products", () => {
],
},
{
id: "test-variant_2", // expect.stringMatching(/^test-variant*/),
id: "test-variant-sale",
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
prices: [
{
id: expect.stringMatching(/^test-price*/),
variant_id: expect.stringMatching(/^test-variant*/),
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
options: [
{
id: expect.stringMatching(/^test-variant-option*/),
variant_id: expect.stringMatching(/^test-variant*/),
option_id: expect.stringMatching(/^test-opt*/),
created_at: expect.any(String),
updated_at: expect.any(String),
},
],
},
{
id: "test-variant_1", // expect.stringMatching(/^test-variant*/),
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
prices: [
{
id: expect.stringMatching(/^test-price*/),
id: "test-price-sale",
variant_id: expect.stringMatching(/^test-variant*/),
created_at: expect.any(String),
updated_at: expect.any(String),
@@ -634,12 +660,12 @@ describe("/admin/products", () => {
updated_at: expect.any(String),
},
{
id: expect.stringMatching(/^test-*/),
id: "test-product1",
created_at: expect.any(String),
options: [],
variants: [
{
id: "test-variant_4", // expect.stringMatching(/^test-variant*/),
id: "test-variant_4",
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
@@ -662,7 +688,7 @@ describe("/admin/products", () => {
],
},
{
id: "test-variant_3", // expect.stringMatching(/^test-variant*/),
id: "test-variant_3",
created_at: expect.any(String),
updated_at: expect.any(String),
product_id: expect.stringMatching(/^test-*/),
@@ -703,11 +729,10 @@ describe("/admin/products", () => {
updated_at: expect.any(String),
},
profile_id: expect.stringMatching(/^sp_*/),
created_at: expect.any(String),
updated_at: expect.any(String),
},
{
id: expect.stringMatching(/^test-*/),
id: "test-product_filtering_1",
profile_id: expect.stringMatching(/^sp_*/),
created_at: expect.any(String),
type: expect.any(Object),
@@ -718,7 +743,7 @@ describe("/admin/products", () => {
updated_at: expect.any(String),
},
{
id: expect.stringMatching(/^test-*/),
id: "test-product_filtering_2",
profile_id: expect.stringMatching(/^sp_*/),
created_at: expect.any(String),
type: expect.any(Object),
@@ -729,7 +754,7 @@ describe("/admin/products", () => {
updated_at: expect.any(String),
},
{
id: expect.stringMatching(/^test-*/),
id: "test-product_filtering_3",
profile_id: expect.stringMatching(/^sp_*/),
created_at: expect.any(String),
type: expect.any(Object),
@@ -1357,7 +1382,6 @@ describe("/admin/products", () => {
})
expect(response.status).toEqual(200)
expect(response.data).toEqual({
product: expect.objectContaining({
id: "test-product",
@@ -1369,33 +1393,6 @@ describe("/admin/products", () => {
amount: 1500,
currency_code: "usd",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
]),
}),
]),
@@ -1451,8 +1448,9 @@ describe("/admin/products", () => {
prices: [
// usd price coming from the product seeder
{
currency_code: "usd",
id: "test-price",
amount: 100,
currency_code: "usd",
},
{
currency_code: "eur",
@@ -1489,33 +1487,6 @@ describe("/admin/products", () => {
amount: 4500,
currency_code: "eur",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
]),
}),
]),
@@ -1547,42 +1518,13 @@ describe("/admin/products", () => {
expect(response.status).toEqual(200)
expect(response.data.product.variants[0].prices.length).toEqual(
4 // 3 prices from Price List + 1 default price
)
expect(response.data.product.variants[0].prices.length).toEqual(1)
expect(response.data.product.variants[0].prices).toEqual(
expect.arrayContaining([
expect.objectContaining({
amount: 4500,
currency_code: "usd",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
])
)
})
@@ -1614,9 +1556,8 @@ describe("/admin/products", () => {
expect(response.status).toEqual(200)
expect(response.data.product.variants[0].prices.length).toEqual(
5 // 2 default prices + 3 prices from Price List
)
expect(response.data.product.variants[0].prices.length).toEqual(2)
expect(response.data.product.variants[0].prices).toEqual(
expect.arrayContaining([
expect.objectContaining({
@@ -1627,33 +1568,6 @@ describe("/admin/products", () => {
amount: 900,
currency_code: "eur",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
expect.objectContaining({
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",
}),
])
)
})
@@ -1951,7 +1865,7 @@ describe("/admin/products", () => {
it("successfully creates soft-deleted product variant", async () => {
const api = useApi()
const product = await api
await api
.get("/admin/products/test-product", {
headers: {
Authorization: "bearer test_token",