From 79c87c09de78576d3e6dfbeda2f4637763406487 Mon Sep 17 00:00:00 2001 From: Anuchit <36580439+daykrm@users.noreply.github.com> Date: Sun, 5 Jan 2025 20:39:29 +0700 Subject: [PATCH] fix(core-flow): invalid update quantity in update line item in cart workflow (#10405) * fix: invalid update quantity in update line item in cart workflow * test: update cart workflow test * fix: rm shallow copy in transform --- .../cart/store/cart.workflows.spec.ts | 116 +++++++++++++++++- .../workflows/update-line-item-in-cart.ts | 4 +- 2 files changed, 117 insertions(+), 3 deletions(-) diff --git a/integration-tests/modules/__tests__/cart/store/cart.workflows.spec.ts b/integration-tests/modules/__tests__/cart/store/cart.workflows.spec.ts index 10c888c40efd5..616839d75553b 100644 --- a/integration-tests/modules/__tests__/cart/store/cart.workflows.spec.ts +++ b/integration-tests/modules/__tests__/cart/store/cart.workflows.spec.ts @@ -2036,6 +2036,121 @@ medusaIntegrationTestRunner({ ) }) + it("should throw insufficient inventory", async () => { + const salesChannel = await scModuleService.createSalesChannels({ + name: "Webshop", + }) + + const location = await stockLocationModule.createStockLocations({ + name: "Warehouse", + }) + + const [product] = await productModule.createProducts([ + { + title: "Test product", + variants: [ + { + title: "Test variant", + }, + ], + }, + ]) + + const inventoryItem = await inventoryModule.createInventoryItems({ + sku: "inv-1234", + }) + + await inventoryModule.createInventoryLevels([ + { + inventory_item_id: inventoryItem.id, + location_id: location.id, + stocked_quantity: 2, + }, + ]) + + const priceSet = await pricingModule.createPriceSets({ + prices: [ + { + amount: 3000, + currency_code: "usd", + }, + ], + }) + + await remoteLink.create([ + { + [Modules.PRODUCT]: { + variant_id: product.variants[0].id, + }, + [Modules.PRICING]: { + price_set_id: priceSet.id, + }, + }, + { + [Modules.SALES_CHANNEL]: { + sales_channel_id: salesChannel.id, + }, + [Modules.STOCK_LOCATION]: { + stock_location_id: location.id, + }, + }, + { + [Modules.PRODUCT]: { + variant_id: product.variants[0].id, + }, + [Modules.INVENTORY]: { + inventory_item_id: inventoryItem.id, + }, + }, + ]) + + let cart = await cartModuleService.createCarts({ + currency_code: "usd", + sales_channel_id: salesChannel.id, + items: [ + { + variant_id: product.variants[0].id, + quantity: 1, + unit_price: 5000, + title: "Test item", + }, + ], + }) + + cart = await cartModuleService.retrieveCart(cart.id, { + select: ["id", "region_id", "currency_code"], + relations: ["items", "items.variant_id", "items.metadata"], + }) + + const item = cart.items?.[0]! + + const { errors } = await updateLineItemInCartWorkflow( + appContainer + ).run({ + input: { + cart_id: cart.id, + item_id: item.id, + update: { + metadata: { + foo: "bar", + }, + quantity: 3, + }, + }, + throwOnError: false, + }) + + expect(errors).toEqual([ + { + action: "confirm-item-inventory-as-step", + handlerType: "invoke", + error: expect.objectContaining({ + message: `Some variant does not have the required inventory`, + }), + }, + ]) + }) + describe("compensation", () => { it("should revert line item update to original state", async () => { expect.assertions(2) @@ -2075,7 +2190,6 @@ medusaIntegrationTestRunner({ inventory_item_id: inventoryItem.id, location_id: location.id, stocked_quantity: 2, - reserved_quantity: 0, }, ]) diff --git a/packages/core/core-flows/src/cart/workflows/update-line-item-in-cart.ts b/packages/core/core-flows/src/cart/workflows/update-line-item-in-cart.ts index 630f085d5d5f6..3243a198b1db2 100644 --- a/packages/core/core-flows/src/cart/workflows/update-line-item-in-cart.ts +++ b/packages/core/core-flows/src/cart/workflows/update-line-item-in-cart.ts @@ -62,8 +62,8 @@ export const updateLineItemInCartWorkflow = createWorkflow( validateVariantPricesStep({ variants }) - const items = transform({ item }, ({ item }) => { - return [item] + const items = transform({ input, item }, (data) => { + return [Object.assign(data.item, { quantity: data.input.update.quantity })] }) confirmVariantInventoryWorkflow.runAsStep({