fix: Update tax lines on cart when region changes (#9367)
**What** - Removes broken cart retrieval step `retrieveWithCartLinks` in favor of `useRemoteQueryStep` in `updateTaxLinesWorkflows` **Why** - Filters variables in the step were passed with an incorrect shape - I removed the step, since it's only used once and the behavior is identical to the generic remote query step **Note** - Because the filters were passed incorrectly, the, now-removed, step has always returned the first cart in the database. As a result all tax calculations so far have been based on whatever the shape of that cart has. It basically ignores all input to this workflow
This commit is contained in:
1 parent
852df3f764
commit
8851ae7b51
9 files changed
+151
-63
No files matched your search
@@ -1001,6 +1001,137 @@ medusaIntegrationTestRunner({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should update tax lines on cart items when region changes", async () => {
|
||||||
|
await setupTaxStructure(taxModule)
|
||||||
|
|
||||||
|
const region = await regionModule.createRegions({
|
||||||
|
name: "us",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const otherRegion = await regionModule.createRegions({
|
||||||
|
name: "dk",
|
||||||
|
currency_code: "dkk",
|
||||||
|
countries: ["dk"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const salesChannel = await scModule.createSalesChannels({
|
||||||
|
name: "Webshop",
|
||||||
|
})
|
||||||
|
|
||||||
|
const [productWithDefaultTax] = await productModule.createProducts([
|
||||||
|
{
|
||||||
|
title: "Test product default tax",
|
||||||
|
variants: [
|
||||||
|
{ title: "Test variant default tax", manage_inventory: false },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const [priceSetDefaultTax] = await pricingModule.createPriceSets([
|
||||||
|
{
|
||||||
|
prices: [{ amount: 2000, currency_code: "usd" }],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
await remoteLink.create([
|
||||||
|
{
|
||||||
|
Product: {
|
||||||
|
variant_id: productWithDefaultTax.variants[0].id,
|
||||||
|
},
|
||||||
|
Pricing: { price_set_id: priceSetDefaultTax.id },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
"/admin/price-preferences",
|
||||||
|
{
|
||||||
|
attribute: "currency_code",
|
||||||
|
value: "usd",
|
||||||
|
is_tax_inclusive: true,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
let response = await api.post(
|
||||||
|
`/store/carts`,
|
||||||
|
{
|
||||||
|
sales_channel_id: salesChannel.id,
|
||||||
|
shipping_address: {
|
||||||
|
country_code: "us",
|
||||||
|
},
|
||||||
|
region_id: region.id,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
variant_id: productWithDefaultTax.variants[0].id,
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
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 variant default tax",
|
||||||
|
tax_lines: [
|
||||||
|
// Uses the california default rate
|
||||||
|
expect.objectContaining({
|
||||||
|
description: "US Default Rate",
|
||||||
|
code: "US_DEF",
|
||||||
|
rate: 2,
|
||||||
|
provider_id: "system",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await api.post(
|
||||||
|
`/store/carts/${response.data.cart.id}`,
|
||||||
|
{
|
||||||
|
region_id: otherRegion.id,
|
||||||
|
shipping_address: {
|
||||||
|
country_code: "dk",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
storeHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.cart).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: response.data.cart.id,
|
||||||
|
currency_code: "dkk",
|
||||||
|
region_id: otherRegion.id,
|
||||||
|
items: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
unit_price: 2000,
|
||||||
|
quantity: 1,
|
||||||
|
title: "Test variant default tax",
|
||||||
|
tax_lines: [
|
||||||
|
// Uses the danish default rate
|
||||||
|
expect.objectContaining({
|
||||||
|
description: "Denmark Default Rate",
|
||||||
|
code: "DK_DEF",
|
||||||
|
rate: 25,
|
||||||
|
provider_id: "system",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it("should remove invalid shipping methods", async () => {
|
it("should remove invalid shipping methods", async () => {
|
||||||
await setupTaxStructure(taxModule)
|
await setupTaxStructure(taxModule)
|
||||||
|
|
||||||
@@ -1714,6 +1845,7 @@ medusaIntegrationTestRunner({
|
|||||||
name: "US",
|
name: "US",
|
||||||
currency_code: "usd",
|
currency_code: "usd",
|
||||||
automatic_taxes: false,
|
automatic_taxes: false,
|
||||||
|
countries: ["us"],
|
||||||
})
|
})
|
||||||
|
|
||||||
const cart = await cartModule.createCarts({
|
const cart = await cartModule.createCarts({
|
||||||
|
|||||||
@@ -16,12 +16,11 @@ export * from "./get-variant-price-sets"
|
|||||||
export * from "./get-variants"
|
export * from "./get-variants"
|
||||||
export * from "./prepare-adjustments-from-promotion-actions"
|
export * from "./prepare-adjustments-from-promotion-actions"
|
||||||
export * from "./refresh-cart-shipping-methods"
|
export * from "./refresh-cart-shipping-methods"
|
||||||
export * from "./reserve-inventory"
|
|
||||||
export * from "./remove-line-item-adjustments"
|
export * from "./remove-line-item-adjustments"
|
||||||
export * from "./remove-shipping-method-adjustments"
|
export * from "./remove-shipping-method-adjustments"
|
||||||
export * from "./remove-shipping-method-from-cart"
|
export * from "./remove-shipping-method-from-cart"
|
||||||
|
export * from "./reserve-inventory"
|
||||||
export * from "./retrieve-cart"
|
export * from "./retrieve-cart"
|
||||||
export * from "./retrieve-cart-with-links"
|
|
||||||
export * from "./set-tax-lines-for-items"
|
export * from "./set-tax-lines-for-items"
|
||||||
export * from "./update-cart-promotions"
|
export * from "./update-cart-promotions"
|
||||||
export * from "./update-carts"
|
export * from "./update-carts"
|
||||||
@@ -29,3 +28,4 @@ export * from "./update-line-items"
|
|||||||
export * from "./validate-cart-payments"
|
export * from "./validate-cart-payments"
|
||||||
export * from "./validate-cart-shipping-options"
|
export * from "./validate-cart-shipping-options"
|
||||||
export * from "./validate-variant-prices"
|
export * from "./validate-variant-prices"
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { CartWorkflowDTO } from "@medusajs/framework/types"
|
|
||||||
import { ContainerRegistrationKeys, isObject } from "@medusajs/framework/utils"
|
|
||||||
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
|
|
||||||
|
|
||||||
export interface RetrieveCartWithLinksStepInput {
|
|
||||||
cart_or_cart_id: string | CartWorkflowDTO
|
|
||||||
fields: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const retrieveCartWithLinksStepId = "retrieve-cart-with-links"
|
|
||||||
/**
|
|
||||||
* This step retrieves a cart's details with its linked records.
|
|
||||||
*/
|
|
||||||
export const retrieveCartWithLinksStep = createStep(
|
|
||||||
retrieveCartWithLinksStepId,
|
|
||||||
async (data: RetrieveCartWithLinksStepInput, { container }) => {
|
|
||||||
const { cart_or_cart_id: cartOrCartId, fields } = data
|
|
||||||
|
|
||||||
if (isObject(cartOrCartId)) {
|
|
||||||
return new StepResponse(cartOrCartId)
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = cartOrCartId
|
|
||||||
const remoteQuery = container.resolve(
|
|
||||||
ContainerRegistrationKeys.REMOTE_QUERY
|
|
||||||
)
|
|
||||||
const query = {
|
|
||||||
entryPoint: "cart",
|
|
||||||
fields,
|
|
||||||
variables: {
|
|
||||||
cart: {
|
|
||||||
id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const [cart] = await remoteQuery(query)
|
|
||||||
|
|
||||||
return new StepResponse(cart)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -112,7 +112,7 @@ export const addShippingMethodToWorkflow = createWorkflow(
|
|||||||
|
|
||||||
updateTaxLinesWorkflow.runAsStep({
|
updateTaxLinesWorkflow.runAsStep({
|
||||||
input: {
|
input: {
|
||||||
cart_or_cart_id: input.cart_id,
|
cart_id: input.cart_id,
|
||||||
shipping_methods: shippingMethodsToAdd,
|
shipping_methods: shippingMethodsToAdd,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export const addToCartWorkflow = createWorkflow(
|
|||||||
refreshCartShippingMethodsStep({ cart }),
|
refreshCartShippingMethodsStep({ cart }),
|
||||||
updateTaxLinesWorkflow.runAsStep({
|
updateTaxLinesWorkflow.runAsStep({
|
||||||
input: {
|
input: {
|
||||||
cart_or_cart_id: input.cart.id,
|
cart_id: input.cart.id,
|
||||||
items,
|
items,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ export const createCartWorkflow = createWorkflow(
|
|||||||
|
|
||||||
updateTaxLinesWorkflow.runAsStep({
|
updateTaxLinesWorkflow.runAsStep({
|
||||||
input: {
|
input: {
|
||||||
cart_or_cart_id: cart.id,
|
cart_id: cart.id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export const updateCartWorkflow = createWorkflow(
|
|||||||
refreshCartShippingMethodsStep({ cart }),
|
refreshCartShippingMethodsStep({ cart }),
|
||||||
updateTaxLinesWorkflow.runAsStep({
|
updateTaxLinesWorkflow.runAsStep({
|
||||||
input: {
|
input: {
|
||||||
cart_or_cart_id: carts[0].id,
|
cart_id: carts[0].id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
CartLineItemDTO,
|
CartLineItemDTO,
|
||||||
CartShippingMethodDTO,
|
CartShippingMethodDTO,
|
||||||
CartWorkflowDTO,
|
|
||||||
} from "@medusajs/framework/types"
|
} from "@medusajs/framework/types"
|
||||||
import {
|
import {
|
||||||
WorkflowData,
|
WorkflowData,
|
||||||
createWorkflow,
|
createWorkflow,
|
||||||
transform,
|
transform,
|
||||||
} from "@medusajs/framework/workflows-sdk"
|
} from "@medusajs/framework/workflows-sdk"
|
||||||
import {
|
import { useRemoteQueryStep } from "../../common"
|
||||||
getItemTaxLinesStep,
|
import { getItemTaxLinesStep, setTaxLinesForItemsStep } from "../steps"
|
||||||
retrieveCartWithLinksStep,
|
|
||||||
setTaxLinesForItemsStep,
|
|
||||||
} from "../steps"
|
|
||||||
|
|
||||||
const cartFields = [
|
const cartFields = [
|
||||||
"id",
|
"id",
|
||||||
@@ -61,7 +57,7 @@ const cartFields = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export type UpdateTaxLinesWorkflowInput = {
|
export type UpdateTaxLinesWorkflowInput = {
|
||||||
cart_or_cart_id: string | CartWorkflowDTO
|
cart_id: string
|
||||||
items?: CartLineItemDTO[]
|
items?: CartLineItemDTO[]
|
||||||
shipping_methods?: CartShippingMethodDTO[]
|
shipping_methods?: CartShippingMethodDTO[]
|
||||||
force_tax_calculation?: boolean
|
force_tax_calculation?: boolean
|
||||||
@@ -74,17 +70,20 @@ export const updateTaxLinesWorkflowId = "update-tax-lines"
|
|||||||
export const updateTaxLinesWorkflow = createWorkflow(
|
export const updateTaxLinesWorkflow = createWorkflow(
|
||||||
updateTaxLinesWorkflowId,
|
updateTaxLinesWorkflowId,
|
||||||
(input: WorkflowData<UpdateTaxLinesWorkflowInput>): WorkflowData<void> => {
|
(input: WorkflowData<UpdateTaxLinesWorkflowInput>): WorkflowData<void> => {
|
||||||
const cart = retrieveCartWithLinksStep({
|
const cart = useRemoteQueryStep({
|
||||||
cart_or_cart_id: input.cart_or_cart_id,
|
entry_point: "cart",
|
||||||
fields: cartFields,
|
fields: cartFields,
|
||||||
|
variables: {
|
||||||
|
id: input.cart_id,
|
||||||
|
},
|
||||||
|
list: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const taxLineItems = getItemTaxLinesStep(
|
const taxLineItems = getItemTaxLinesStep(
|
||||||
transform({ input, cart }, (data) => ({
|
transform({ input, cart }, (data) => ({
|
||||||
cart: data.cart,
|
cart: data.cart,
|
||||||
items: data.input.items || data.cart.items,
|
items: data.input.items || data.cart.items,
|
||||||
shipping_methods:
|
shipping_methods: data.input.shipping_methods || data.cart.shipping_methods,
|
||||||
data.input.shipping_methods || data.cart.shipping_methods,
|
|
||||||
force_tax_calculation: data.input.force_tax_calculation,
|
force_tax_calculation: data.input.force_tax_calculation,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
import { updateTaxLinesWorkflow } from "@medusajs/core-flows"
|
import { updateTaxLinesWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { HttpTypes } from "@medusajs/framework/types"
|
||||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||||
import { refetchCart } from "../../helpers"
|
import { refetchCart } from "../../helpers"
|
||||||
import { HttpTypes } from "@medusajs/framework/types"
|
|
||||||
|
|
||||||
export const POST = async (
|
export const POST = async (
|
||||||
req: MedusaRequest,
|
req: MedusaRequest,
|
||||||
res: MedusaResponse<HttpTypes.StoreCartResponse>
|
res: MedusaResponse<HttpTypes.StoreCartResponse>
|
||||||
) => {
|
) => {
|
||||||
const workflow = updateTaxLinesWorkflow(req.scope)
|
await updateTaxLinesWorkflow(req.scope).run({
|
||||||
|
|
||||||
await workflow.run({
|
|
||||||
input: {
|
input: {
|
||||||
cart_or_cart_id: req.params.id,
|
cart_id: req.params.id,
|
||||||
force_tax_calculation: true,
|
force_tax_calculation: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in new issue
Block a user