fix: Product type tax overrides (#9951)
* fix: Make product type tax override work * fix: Make product type tax override work
This commit is contained in:
@@ -1,142 +0,0 @@
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
CartShippingMethodDTO,
|
||||
CartWorkflowDTO,
|
||||
ITaxModuleService,
|
||||
ItemTaxLineDTO,
|
||||
ShippingTaxLineDTO,
|
||||
TaxCalculationContext,
|
||||
TaxableItemDTO,
|
||||
TaxableShippingDTO,
|
||||
} from "@medusajs/framework/types"
|
||||
import { MedusaError, Modules } from "@medusajs/framework/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
export interface GetItemTaxLinesStepInput {
|
||||
cart: CartWorkflowDTO
|
||||
items: CartLineItemDTO[]
|
||||
shipping_methods: CartShippingMethodDTO[]
|
||||
force_tax_calculation?: boolean
|
||||
is_return?: boolean
|
||||
}
|
||||
|
||||
function normalizeTaxModuleContext(
|
||||
cart: CartWorkflowDTO,
|
||||
forceTaxCalculation: boolean,
|
||||
isReturn?: boolean
|
||||
): TaxCalculationContext | null {
|
||||
const address = cart.shipping_address
|
||||
const shouldCalculateTax = forceTaxCalculation || cart.region?.automatic_taxes
|
||||
|
||||
if (!shouldCalculateTax) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (forceTaxCalculation && !address?.country_code) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`country code is required to calculate taxes`
|
||||
)
|
||||
}
|
||||
|
||||
if (!address?.country_code) {
|
||||
return null
|
||||
}
|
||||
|
||||
const customer = cart.customer
|
||||
? {
|
||||
id: cart.customer.id,
|
||||
email: cart.customer.email,
|
||||
customer_groups: cart.customer.groups?.map((g) => g.id) || [],
|
||||
}
|
||||
: undefined
|
||||
|
||||
return {
|
||||
address: {
|
||||
country_code: address.country_code,
|
||||
province_code: address.province,
|
||||
address_1: address.address_1,
|
||||
address_2: address.address_2,
|
||||
city: address.city,
|
||||
postal_code: address.postal_code,
|
||||
},
|
||||
customer,
|
||||
is_return: isReturn ?? false,
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeLineItemsForTax(
|
||||
cart: CartWorkflowDTO,
|
||||
items: CartLineItemDTO[]
|
||||
): TaxableItemDTO[] {
|
||||
return items.map((item) => ({
|
||||
id: item.id,
|
||||
product_id: item.product_id!,
|
||||
product_name: item.variant_title,
|
||||
product_sku: item.variant_sku,
|
||||
product_type: item.product_type,
|
||||
product_type_id: item.product_type,
|
||||
quantity: item.quantity,
|
||||
unit_price: item.unit_price,
|
||||
currency_code: cart.currency_code,
|
||||
}))
|
||||
}
|
||||
|
||||
function normalizeLineItemsForShipping(
|
||||
cart: CartWorkflowDTO,
|
||||
shippingMethods: CartShippingMethodDTO[]
|
||||
): TaxableShippingDTO[] {
|
||||
return shippingMethods.map((shippingMethod) => ({
|
||||
id: shippingMethod.id,
|
||||
shipping_option_id: shippingMethod.shipping_option_id!,
|
||||
unit_price: shippingMethod.amount,
|
||||
currency_code: cart.currency_code,
|
||||
}))
|
||||
}
|
||||
|
||||
export const getItemTaxLinesStepId = "get-item-tax-lines"
|
||||
/**
|
||||
* This step retrieves the tax lines of the specified line items in a cart.
|
||||
*/
|
||||
export const getItemTaxLinesStep = createStep(
|
||||
getItemTaxLinesStepId,
|
||||
async (data: GetItemTaxLinesStepInput, { container }) => {
|
||||
const {
|
||||
cart,
|
||||
items,
|
||||
shipping_methods: shippingMethods,
|
||||
force_tax_calculation: forceTaxCalculation = false,
|
||||
is_return: isReturn = false,
|
||||
} = data
|
||||
|
||||
const taxService = container.resolve<ITaxModuleService>(Modules.TAX)
|
||||
|
||||
const taxContext = normalizeTaxModuleContext(
|
||||
cart,
|
||||
forceTaxCalculation,
|
||||
isReturn
|
||||
)
|
||||
|
||||
if (!taxContext) {
|
||||
return new StepResponse({
|
||||
lineItemTaxLines: [],
|
||||
shippingMethodsTaxLines: [],
|
||||
})
|
||||
}
|
||||
|
||||
const lineItemTaxLines = (await taxService.getTaxLines(
|
||||
normalizeLineItemsForTax(cart, items),
|
||||
taxContext
|
||||
)) as ItemTaxLineDTO[]
|
||||
|
||||
const shippingMethodsTaxLines = (await taxService.getTaxLines(
|
||||
normalizeLineItemsForShipping(cart, shippingMethods),
|
||||
taxContext
|
||||
)) as ShippingTaxLineDTO[]
|
||||
|
||||
return new StepResponse({
|
||||
lineItemTaxLines,
|
||||
shippingMethodsTaxLines,
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -9,7 +9,6 @@ export * from "./find-one-or-any-region"
|
||||
export * from "./find-or-create-customer"
|
||||
export * from "./find-sales-channel"
|
||||
export * from "./get-actions-to-compute-from-promotions"
|
||||
export * from "./get-item-tax-lines"
|
||||
export * from "./get-line-item-actions"
|
||||
export * from "./get-promotion-codes-to-apply"
|
||||
export * from "./get-variant-price-sets"
|
||||
@@ -28,3 +27,4 @@ export * from "./update-line-items"
|
||||
export * from "./validate-cart-payments"
|
||||
export * from "./validate-cart-shipping-options"
|
||||
export * from "./validate-variant-prices"
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ export const productVariantsFields = [
|
||||
"product.subtitle",
|
||||
"product.thumbnail",
|
||||
"product.type.value",
|
||||
"product.type.id",
|
||||
"product.collection.title",
|
||||
"product.handle",
|
||||
"product.discountable",
|
||||
|
||||
@@ -86,6 +86,7 @@ export function prepareLineItemData(data: Input) {
|
||||
variant.product.description ?? item?.product_description,
|
||||
product_subtitle: variant.product.subtitle ?? item?.product_subtitle,
|
||||
product_type: variant.product.type?.value ?? item?.product_type ?? null,
|
||||
product_type_id: variant.product.type?.id ?? item?.product_type_id ?? null,
|
||||
product_collection:
|
||||
variant.product.collection?.title ?? item?.product_collection ?? null,
|
||||
product_handle: variant.product.handle ?? item?.product_handle,
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
transform,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import { getItemTaxLinesStep, setTaxLinesForItemsStep } from "../steps"
|
||||
import { getItemTaxLinesStep } from "../../tax/steps/get-item-tax-lines"
|
||||
import { setTaxLinesForItemsStep } from "../steps"
|
||||
|
||||
const cartFields = [
|
||||
"id",
|
||||
@@ -23,6 +24,7 @@ const cartFields = [
|
||||
"items.product_description",
|
||||
"items.product_subtitle",
|
||||
"items.product_type",
|
||||
"items.product_type_id",
|
||||
"items.product_collection",
|
||||
"items.product_handle",
|
||||
"items.variant_sku",
|
||||
@@ -81,7 +83,7 @@ export const updateTaxLinesWorkflow = createWorkflow(
|
||||
|
||||
const taxLineItems = getItemTaxLinesStep(
|
||||
transform({ input, cart }, (data) => ({
|
||||
cart: data.cart,
|
||||
orderOrCart: data.cart,
|
||||
items: data.input.items || data.cart.items,
|
||||
shipping_methods:
|
||||
data.input.shipping_methods || data.cart.shipping_methods,
|
||||
|
||||
@@ -20,7 +20,6 @@ export * from "./exchange/cancel-exchange"
|
||||
export * from "./exchange/create-exchange"
|
||||
export * from "./exchange/create-exchange-items-from-actions"
|
||||
export * from "./exchange/delete-exchanges"
|
||||
export * from "./get-item-tax-lines"
|
||||
export * from "./preview-order-change"
|
||||
export * from "./register-fulfillment"
|
||||
export * from "./register-shipment"
|
||||
@@ -35,3 +34,4 @@ export * from "./update-order-change-actions"
|
||||
export * from "./update-order-changes"
|
||||
export * from "./update-order-exchanges"
|
||||
export * from "./update-shipping-methods"
|
||||
|
||||
|
||||
@@ -6,10 +6,8 @@ import {
|
||||
when,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import {
|
||||
getOrderItemTaxLinesStep,
|
||||
setOrderTaxLinesForItemsStep,
|
||||
} from "../steps"
|
||||
import { getItemTaxLinesStep } from "../../tax/steps/get-item-tax-lines"
|
||||
import { setOrderTaxLinesForItemsStep } from "../steps"
|
||||
|
||||
const completeOrderFields = [
|
||||
"id",
|
||||
@@ -174,7 +172,7 @@ export const updateOrderTaxLinesWorkflow = createWorkflow(
|
||||
}).config({ name: "query-order-shipping-methods" })
|
||||
})
|
||||
|
||||
const taxLineItems = getOrderItemTaxLinesStep(
|
||||
const taxLineItems = getItemTaxLinesStep(
|
||||
transform(
|
||||
{ input, order, items, shippingMethods, isFullOrder },
|
||||
(data) => {
|
||||
@@ -187,7 +185,7 @@ export const updateOrderTaxLinesWorkflow = createWorkflow(
|
||||
: data.items ?? []
|
||||
|
||||
return {
|
||||
order: data.order,
|
||||
orderOrCart: data.order,
|
||||
items: lineItems,
|
||||
shipping_methods: shippingMethods,
|
||||
force_tax_calculation: data.input.force_tax_calculation,
|
||||
|
||||
+29
-29
@@ -1,4 +1,7 @@
|
||||
import {
|
||||
CartLineItemDTO,
|
||||
CartShippingMethodDTO,
|
||||
CartWorkflowDTO,
|
||||
ITaxModuleService,
|
||||
ItemTaxLineDTO,
|
||||
OrderLineItemDTO,
|
||||
@@ -12,24 +15,24 @@ import {
|
||||
import { MedusaError, Modules } from "@medusajs/framework/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
export interface GetOrderItemTaxLinesStepInput {
|
||||
order: OrderWorkflowDTO
|
||||
items: OrderLineItemDTO[]
|
||||
shipping_methods: OrderShippingMethodDTO[]
|
||||
export interface GetItemTaxLinesStepInput {
|
||||
orderOrCart: OrderWorkflowDTO | CartWorkflowDTO
|
||||
items: OrderLineItemDTO[] | CartLineItemDTO[]
|
||||
shipping_methods: OrderShippingMethodDTO[] | CartShippingMethodDTO[]
|
||||
force_tax_calculation?: boolean
|
||||
is_return?: boolean
|
||||
shipping_address?: OrderWorkflowDTO["shipping_address"]
|
||||
}
|
||||
|
||||
function normalizeTaxModuleContext(
|
||||
order: OrderWorkflowDTO,
|
||||
orderOrCart: OrderWorkflowDTO | CartWorkflowDTO,
|
||||
forceTaxCalculation: boolean,
|
||||
isReturn?: boolean,
|
||||
shippingAddress?: OrderWorkflowDTO["shipping_address"]
|
||||
): TaxCalculationContext | null {
|
||||
const address = shippingAddress ?? order.shipping_address
|
||||
const address = shippingAddress ?? orderOrCart.shipping_address
|
||||
const shouldCalculateTax =
|
||||
forceTaxCalculation || order.region?.automatic_taxes
|
||||
forceTaxCalculation || orderOrCart.region?.automatic_taxes
|
||||
|
||||
if (!shouldCalculateTax) {
|
||||
return null
|
||||
@@ -46,10 +49,10 @@ function normalizeTaxModuleContext(
|
||||
return null
|
||||
}
|
||||
|
||||
const customer = order.customer && {
|
||||
id: order.customer.id,
|
||||
email: order.customer.email,
|
||||
customer_groups: order.customer.groups?.map((g) => g.id) || [],
|
||||
const customer = orderOrCart.customer && {
|
||||
id: orderOrCart.customer.id,
|
||||
email: orderOrCart.customer.email,
|
||||
customer_groups: orderOrCart.customer.groups?.map((g) => g.id) || [],
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -67,28 +70,25 @@ function normalizeTaxModuleContext(
|
||||
}
|
||||
|
||||
function normalizeLineItemsForTax(
|
||||
order: OrderWorkflowDTO,
|
||||
items: OrderLineItemDTO[]
|
||||
orderOrCart: OrderWorkflowDTO | CartWorkflowDTO,
|
||||
items: OrderLineItemDTO[] | CartLineItemDTO[]
|
||||
): TaxableItemDTO[] {
|
||||
return items.map(
|
||||
(item) =>
|
||||
({
|
||||
id: item.id,
|
||||
product_id: item.product_id!,
|
||||
product_name: item.variant_title,
|
||||
product_sku: item.variant_sku,
|
||||
product_type: item.product_type,
|
||||
product_type_id: item.product_type,
|
||||
product_type_id: item.product_type_id,
|
||||
quantity: item.quantity,
|
||||
unit_price: item.unit_price,
|
||||
currency_code: order.currency_code,
|
||||
currency_code: orderOrCart.currency_code,
|
||||
} as TaxableItemDTO)
|
||||
)
|
||||
}
|
||||
|
||||
function normalizeLineItemsForShipping(
|
||||
order: OrderWorkflowDTO,
|
||||
shippingMethods: OrderShippingMethodDTO[]
|
||||
orderOrCart: OrderWorkflowDTO | CartWorkflowDTO,
|
||||
shippingMethods: OrderShippingMethodDTO[] | CartShippingMethodDTO[]
|
||||
): TaxableShippingDTO[] {
|
||||
return shippingMethods.map(
|
||||
(shippingMethod) =>
|
||||
@@ -96,20 +96,20 @@ function normalizeLineItemsForShipping(
|
||||
id: shippingMethod.id,
|
||||
shipping_option_id: shippingMethod.shipping_option_id!,
|
||||
unit_price: shippingMethod.amount,
|
||||
currency_code: order.currency_code,
|
||||
currency_code: orderOrCart.currency_code,
|
||||
} as TaxableShippingDTO)
|
||||
)
|
||||
}
|
||||
|
||||
export const getOrderItemTaxLinesStepId = "get-order-item-tax-lines"
|
||||
export const getItemTaxLinesStepId = "get-item-tax-lines"
|
||||
/**
|
||||
* This step retrieves the tax lines for an order's line items and shipping methods.
|
||||
*/
|
||||
export const getOrderItemTaxLinesStep = createStep(
|
||||
getOrderItemTaxLinesStepId,
|
||||
async (data: GetOrderItemTaxLinesStepInput, { container }) => {
|
||||
export const getItemTaxLinesStep = createStep(
|
||||
getItemTaxLinesStepId,
|
||||
async (data: GetItemTaxLinesStepInput, { container }) => {
|
||||
const {
|
||||
order,
|
||||
orderOrCart,
|
||||
items = [],
|
||||
shipping_methods: shippingMethods = [],
|
||||
force_tax_calculation: forceTaxCalculation = false,
|
||||
@@ -119,7 +119,7 @@ export const getOrderItemTaxLinesStep = createStep(
|
||||
const taxService = container.resolve<ITaxModuleService>(Modules.TAX)
|
||||
|
||||
const taxContext = normalizeTaxModuleContext(
|
||||
order,
|
||||
orderOrCart,
|
||||
forceTaxCalculation,
|
||||
isReturn,
|
||||
shippingAddress
|
||||
@@ -136,14 +136,14 @@ export const getOrderItemTaxLinesStep = createStep(
|
||||
|
||||
if (items.length) {
|
||||
stepResponseData.lineItemTaxLines = (await taxService.getTaxLines(
|
||||
normalizeLineItemsForTax(order, items),
|
||||
normalizeLineItemsForTax(orderOrCart, items),
|
||||
taxContext
|
||||
)) as ItemTaxLineDTO[]
|
||||
}
|
||||
|
||||
if (shippingMethods.length) {
|
||||
stepResponseData.shippingMethodsTaxLines = (await taxService.getTaxLines(
|
||||
normalizeLineItemsForShipping(order, shippingMethods),
|
||||
normalizeLineItemsForShipping(orderOrCart, shippingMethods),
|
||||
taxContext
|
||||
)) as ShippingTaxLineDTO[]
|
||||
}
|
||||
Reference in New Issue
Block a user