From f95c4e240c4a5ca0fb88a09636c3d8a2266de279 Mon Sep 17 00:00:00 2001 From: Riqwan Thamir Date: Sun, 8 Dec 2024 13:13:31 +0100 Subject: [PATCH] fix(promotion, core-flows): updating cart with removed promotion removes adjustments (#10489) --- .changeset/empty-trees-walk.md | 6 ++ .../http/__tests__/cart/store/cart.spec.ts | 46 ++++++++++++++ .../src/cart/workflows/refresh-cart-items.ts | 15 +++-- .../promotion-module/compute-actions.spec.ts | 62 ------------------- .../src/services/promotion-module.ts | 9 +-- 5 files changed, 62 insertions(+), 76 deletions(-) create mode 100644 .changeset/empty-trees-walk.md diff --git a/.changeset/empty-trees-walk.md b/.changeset/empty-trees-walk.md new file mode 100644 index 0000000000000..3345800c5cee6 --- /dev/null +++ b/.changeset/empty-trees-walk.md @@ -0,0 +1,6 @@ +--- +"@medusajs/promotion": patch +"@medusajs/core-flows": patch +--- + +fix(promotion, core-flows): updating cart with removed promotion removes adjustments diff --git a/integration-tests/http/__tests__/cart/store/cart.spec.ts b/integration-tests/http/__tests__/cart/store/cart.spec.ts index c82ebaaaff5b5..0a5d36472ba00 100644 --- a/integration-tests/http/__tests__/cart/store/cart.spec.ts +++ b/integration-tests/http/__tests__/cart/store/cart.spec.ts @@ -1344,6 +1344,52 @@ medusaIntegrationTestRunner({ }) ) }) + + it("should remove promotion adjustments when promotion is deleted", async () => { + let cartBeforeRemovingPromotion = ( + await api.get(`/store/carts/${cart.id}`, storeHeaders) + ).data.cart + + expect(cartBeforeRemovingPromotion).toEqual( + expect.objectContaining({ + id: cart.id, + items: expect.arrayContaining([ + expect.objectContaining({ + adjustments: [ + { + id: expect.any(String), + code: "PROMOTION_APPLIED", + promotion_id: promotion.id, + amount: 100, + }, + ], + }), + ]), + }) + ) + + await api.delete(`/admin/promotions/${promotion.id}`, adminHeaders) + + let response = await api.post( + `/store/carts/${cart.id}`, + { + email: "test@test.com", + }, + storeHeaders + ) + + expect(response.status).toEqual(200) + expect(response.data.cart).toEqual( + expect.objectContaining({ + id: cart.id, + items: expect.arrayContaining([ + expect.objectContaining({ + adjustments: [], + }), + ]), + }) + ) + }) }) describe("POST /store/carts/:id/customer", () => { diff --git a/packages/core/core-flows/src/cart/workflows/refresh-cart-items.ts b/packages/core/core-flows/src/cart/workflows/refresh-cart-items.ts index 6a90feb1eca9c..93c4eadbe02a8 100644 --- a/packages/core/core-flows/src/cart/workflows/refresh-cart-items.ts +++ b/packages/core/core-flows/src/cart/workflows/refresh-cart-items.ts @@ -106,13 +106,16 @@ export const refreshCartItemsWorkflow = createWorkflow( input: { cart_id: cart.id }, }) - const cartPromoCodes = transform({ cart, input }, ({ cart, input }) => { - if (isDefined(input.promo_codes)) { - return input.promo_codes - } else { - return cart.promotions.map((p) => p.code) + const cartPromoCodes = transform( + { refetchedCart, input }, + ({ refetchedCart, input }) => { + if (isDefined(input.promo_codes)) { + return input.promo_codes + } else { + return refetchedCart.promotions.map((p) => p?.code).filter(Boolean) + } } - }) + ) updateCartPromotionsWorkflow.runAsStep({ input: { diff --git a/packages/modules/promotion/integration-tests/__tests__/services/promotion-module/compute-actions.spec.ts b/packages/modules/promotion/integration-tests/__tests__/services/promotion-module/compute-actions.spec.ts index 63f57081d3738..d839968794146 100644 --- a/packages/modules/promotion/integration-tests/__tests__/services/promotion-module/compute-actions.spec.ts +++ b/packages/modules/promotion/integration-tests/__tests__/services/promotion-module/compute-actions.spec.ts @@ -57,68 +57,6 @@ moduleIntegrationTestRunner({ expect(response).toEqual([]) }) - - it("should throw error when code in items adjustment does not exist", async () => { - await createDefaultPromotion(service, {}) - - const error = await service - .computeActions(["PROMOTION_TEST"], { - items: [ - { - id: "item_cotton_tshirt", - quantity: 1, - subtotal: 100, - adjustments: [ - { - id: "test-adjustment", - code: "DOES_NOT_EXIST", - }, - ], - }, - { - id: "item_cotton_sweater", - quantity: 5, - subtotal: 750, - }, - ], - }) - .catch((e) => e) - - expect(error.message).toContain( - "Applied Promotion for code (DOES_NOT_EXIST) not found" - ) - }) - - it("should throw error when code in shipping adjustment does not exist", async () => { - await createDefaultPromotion(service, {}) - - const error = await service - .computeActions(["PROMOTION_TEST"], { - items: [ - { - id: "item_cotton_tshirt", - quantity: 1, - subtotal: 100, - }, - { - id: "item_cotton_sweater", - quantity: 5, - subtotal: 750, - adjustments: [ - { - id: "test-adjustment", - code: "DOES_NOT_EXIST", - }, - ], - }, - ], - }) - .catch((e) => e) - - expect(error.message).toContain( - "Applied Promotion for code (DOES_NOT_EXIST) not found" - ) - }) }) describe("when promotion is for items and allocation is each", () => { diff --git a/packages/modules/promotion/src/services/promotion-module.ts b/packages/modules/promotion/src/services/promotion-module.ts index 5d3afdf86a50c..8ca859f3080cd 100644 --- a/packages/modules/promotion/src/services/promotion-module.ts +++ b/packages/modules/promotion/src/services/promotion-module.ts @@ -397,6 +397,7 @@ export default class PromotionModuleService ], }, { + take: null, relations: [ "application_method", "application_method.target_rules", @@ -421,19 +422,11 @@ export default class PromotionModuleService const appliedCodes = [...appliedShippingCodes, ...appliedItemCodes] for (const appliedCode of appliedCodes) { - const promotion = existingPromotionsMap.get(appliedCode) const adjustments = codeAdjustmentMap.get(appliedCode) || [] const action = appliedShippingCodes.includes(appliedCode) ? ComputedActions.REMOVE_SHIPPING_METHOD_ADJUSTMENT : ComputedActions.REMOVE_ITEM_ADJUSTMENT - if (!promotion) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Applied Promotion for code (${appliedCode}) not found` - ) - } - adjustments.forEach((adjustment) => computedActions.push({ action,