Skip to content

Commit

Permalink
fix(promotion, core-flows): updating cart with removed promotion remo…
Browse files Browse the repository at this point in the history
…ves adjustments (medusajs#10489)
  • Loading branch information
riqwan authored Dec 8, 2024
1 parent 864f530 commit f95c4e2
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 76 deletions.
6 changes: 6 additions & 0 deletions .changeset/empty-trees-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@medusajs/promotion": patch
"@medusajs/core-flows": patch
---

fix(promotion, core-flows): updating cart with removed promotion removes adjustments
46 changes: 46 additions & 0 deletions integration-tests/http/__tests__/cart/store/cart.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: "[email protected]",
},
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", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
9 changes: 1 addition & 8 deletions packages/modules/promotion/src/services/promotion-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ export default class PromotionModuleService
],
},
{
take: null,
relations: [
"application_method",
"application_method.target_rules",
Expand All @@ -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,
Expand Down

0 comments on commit f95c4e2

Please sign in to comment.