From 6055f4c9cf5477f2646ffb0d04075e68b9a5a399 Mon Sep 17 00:00:00 2001 From: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:55:53 +0200 Subject: [PATCH] fix: If country on cart has no tax region, clear tax lines (#9447) **What** If the country on the shipping address changes to a country without an associated tax region, we clear the tax lines on shipping methods and line items. --- .../__tests__/cart/store/carts.spec.ts | 162 ++++++++++++++++++ .../src/cart/steps/set-tax-lines-for-items.ts | 23 +-- 2 files changed, 166 insertions(+), 19 deletions(-) diff --git a/integration-tests/modules/__tests__/cart/store/carts.spec.ts b/integration-tests/modules/__tests__/cart/store/carts.spec.ts index 00c8907532..7bac952090 100644 --- a/integration-tests/modules/__tests__/cart/store/carts.spec.ts +++ b/integration-tests/modules/__tests__/cart/store/carts.spec.ts @@ -1533,6 +1533,168 @@ medusaIntegrationTestRunner({ ) }) + it("should remove tax lines on cart items and shipping methods when country changes and there is no tax region for that country", async () => { + await setupTaxStructure(taxModule) + + const region = await regionModule.createRegions({ + name: "us", + currency_code: "usd", + countries: ["us"], + }) + + const otherRegion = await regionModule.createRegions({ + name: "Italy", + currency_code: "eur", + countries: ["it"], + }) + + const shippingProfile = + await fulfillmentModule.createShippingProfiles({ + name: "Test", + type: "default", + }) + + const fulfillmentSet = await fulfillmentModule.createFulfillmentSets({ + name: "Test", + type: "test-type", + service_zones: [ + { + name: "Test", + geo_zones: [ + { type: "country", country_code: "us" }, + { type: "country", country_code: "it" }, + ], + }, + ], + }) + + const shippingOption = await fulfillmentModule.createShippingOptions({ + name: "Test shipping option", + service_zone_id: fulfillmentSet.service_zones[0].id, + shipping_profile_id: shippingProfile.id, + provider_id: "manual_test-provider", + price_type: "flat", + type: { + label: "Test type", + description: "Test description", + code: "test-code", + }, + }) + + const cart = await cartModule.createCarts({ + currency_code: "eur", + email: "tony@stark.com", + items: [ + { + id: "item-1", + unit_price: 2000, + quantity: 1, + title: "Test item", + product_id: "prod_tshirt", + } as any, + ], + }) + + // Manually inserting shipping methods here since the cart does not + // currently support it. Move to API when ready. + await cartModule.addShippingMethods(cart.id, [ + { + amount: 500, + name: "express", + shipping_option_id: shippingOption.id, + }, + ]) + + let response = await api.post( + `/store/carts/${cart.id}`, + { + region_id: region.id, + shipping_address: { + country_code: "us", + }, + }, + storeHeaders + ) + + expect(response.data.cart).toEqual( + expect.objectContaining({ + id: response.data.cart.id, + currency_code: "usd", + region_id: region.id, + items: expect.arrayContaining([ + expect.objectContaining({ + unit_price: 2000, + quantity: 1, + title: "Test item", + tax_lines: [ + // Uses the california default rate + expect.objectContaining({ + description: "US Default Rate", + code: "US_DEF", + rate: 2, + provider_id: "system", + }), + ], + }), + ]), + shipping_methods: expect.arrayContaining([ + expect.objectContaining({ + shipping_option_id: shippingOption.id, + amount: 500, + tax_lines: [ + expect.objectContaining({ + description: "US Default Rate", + code: "US_DEF", + rate: 2, + provider_id: "system", + }), + ], + adjustments: [], + }), + ]), + }) + ) + + response = await api.post( + `/store/carts/${response.data.cart.id}`, + { + region_id: otherRegion.id, + shipping_address: { + country_code: "it", + }, + }, + storeHeaders + ) + + expect(response.data.cart).toEqual( + expect.objectContaining({ + id: response.data.cart.id, + currency_code: "eur", + region_id: otherRegion.id, + items: expect.arrayContaining([ + expect.objectContaining({ + unit_price: 2000, + quantity: 1, + title: "Test item", + tax_lines: [ + // Italy has no tax region, so we clear the tax lines + ], + }), + ]), + shipping_methods: expect.arrayContaining([ + expect.objectContaining({ + shipping_option_id: shippingOption.id, + amount: 500, + tax_lines: [ + // Italy has no tax region, so we clear the tax lines + ], + adjustments: [], + }), + ]), + }) + ) + }) + it("should remove invalid shipping methods", async () => { await setupTaxStructure(taxModule) diff --git a/packages/core/core-flows/src/cart/steps/set-tax-lines-for-items.ts b/packages/core/core-flows/src/cart/steps/set-tax-lines-for-items.ts index a19728d17f..b7c7c237a7 100644 --- a/packages/core/core-flows/src/cart/steps/set-tax-lines-for-items.ts +++ b/packages/core/core-flows/src/cart/steps/set-tax-lines-for-items.ts @@ -25,36 +25,21 @@ export const setTaxLinesForItemsStep = createStep( const { cart, item_tax_lines, shipping_tax_lines } = data const cartService = container.resolve(Modules.CART) - const getShippingTaxLinesPromise = + const existingShippingMethodTaxLines = await cartService.listShippingMethodTaxLines({ shipping_method_id: shipping_tax_lines.map((t) => t.shipping_line_id), }) - const getItemTaxLinesPromise = await cartService.listLineItemTaxLines({ + const existingLineItemTaxLines = await cartService.listLineItemTaxLines({ item_id: item_tax_lines.map((t) => t.line_item_id), }) const itemsTaxLinesData = normalizeItemTaxLinesForCart(item_tax_lines) - const setItemTaxLinesPromise = itemsTaxLinesData.length - ? cartService.setLineItemTaxLines(cart.id, itemsTaxLinesData) - : 0 + await cartService.setLineItemTaxLines(cart.id, itemsTaxLinesData) const shippingTaxLinesData = normalizeShippingTaxLinesForCart(shipping_tax_lines) - const setShippingTaxLinesPromise = shippingTaxLinesData.length - ? await cartService.setShippingMethodTaxLines( - cart.id, - shippingTaxLinesData - ) - : 0 - - const [existingShippingMethodTaxLines, existingLineItemTaxLines] = - await Promise.all([ - getShippingTaxLinesPromise, - getItemTaxLinesPromise, - setItemTaxLinesPromise, - setShippingTaxLinesPromise, - ]) + await cartService.setShippingMethodTaxLines(cart.id, shippingTaxLinesData) return new StepResponse(null, { cart,