chore(core-flows): only allow published products in addToCartWorkflow (#13182)

Closes #13163 

I have a few questions about expected behaviour, since this currently breaks some tests:

- Many tests use the productModule to create products, with default status == "draft", and use the addToCart workflow which now throws. Should I change all breaking tests to specify status == "published" whne creating the product? The alternative would be to check the status in the store API route before the workflow but 1. it would be an extra query and 2. the addToCart workflow is only used in the store currently, and even if it was to be used admin-side, it still doesn't make sense to add a draft product to cart

- After this PR an unpublished product would give the same error as a variant that doesn't exist. While imho this is correct, the thrown error (for both) is "Items  do not have a price" which doesn't make much sense(i believe the workflows goes through with an empty variants list and then errors at the price check point). Should I throw a different error when a variant doesn't exists/isn't published?


---

> [!NOTE]
> Enforces that only variants from published products can be added to carts, adds status fetching, refines errors, and updates tests to use ProductStatus.PUBLISHED.
> 
> - **Core Flows**:
>   - addToCart: Validate variants exist and belong to `product.status = PUBLISHED`; throw clear `INVALID_DATA` when not found/unpublished.
>   - Data fetching: Include `product.status` in `cart` and `order` variant field selections.
> - **Tests/Fixtures**:
>   - Update integration tests to set `status: ProductStatus.PUBLISHED` when creating products and import `ProductStatus` where needed.
>   - Add cases for unpublished products and non-existent variants producing the new error message.
> 
> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ca72532e957964d2d8e6bcecbb0905054c677ded. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>
This commit is contained in:
Leonardo Benini
2025-10-02 14:31:53 +02:00
committed by GitHub
parent bb08edd41f
commit 9c957e1da0
20 changed files with 243 additions and 4 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/core-flows": patch
---
chore(core-flows): only allow published products in addToCartWorkflow

View File

@@ -2036,6 +2036,7 @@ medusaIntegrationTestRunner({
{
title: "Product without inventory management",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -2229,6 +2230,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Test fixture ${shippingProfile.id}`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [
{ title: "pack", values: ["1-pack", "2-pack", "3-pack"] },
@@ -2548,6 +2550,7 @@ medusaIntegrationTestRunner({
`/admin/products`,
{
title: "test product",
status: ProductStatus.PUBLISHED,
description: "test",
options: [
{
@@ -2893,6 +2896,7 @@ medusaIntegrationTestRunner({
{
title: "Gift Card",
description: "test",
status: ProductStatus.PUBLISHED,
is_giftcard: true,
options: [
{
@@ -3452,6 +3456,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Medusa T-Shirt not discountable",
status: ProductStatus.PUBLISHED,
handle: "t-shirt-not-discountable",
discountable: false,
options: [
@@ -3628,6 +3633,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -3744,6 +3750,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -3862,6 +3869,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -3980,6 +3988,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -4117,6 +4126,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -4233,6 +4243,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -4370,6 +4381,7 @@ medusaIntegrationTestRunner({
{
title: "Product for free",
description: "test",
status: ProductStatus.PUBLISHED,
options: [
{
title: "Size",
@@ -4464,6 +4476,7 @@ medusaIntegrationTestRunner({
`/admin/products`,
{
title: "Product for free",
status: ProductStatus.PUBLISHED,
description: "test",
options: [
{

View File

@@ -4,6 +4,7 @@ import {
ClaimType,
ContainerRegistrationKeys,
Modules,
ProductStatus,
RuleOperator,
} from "@medusajs/utils"
import {
@@ -82,6 +83,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Test product",
status: ProductStatus.PUBLISHED,
options: [{ title: "size", values: ["large", "small"] }],
shipping_profile_id: shippingProfile.id,
variants: [
@@ -107,6 +109,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Extra product",
status: ProductStatus.PUBLISHED,
options: [{ title: "size", values: ["large", "small"] }],
shipping_profile_id: shippingProfile.id,
variants: [

View File

@@ -1,6 +1,6 @@
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { HttpTypes } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/utils"
import { ModuleRegistrationName, ProductStatus } from "@medusajs/utils"
import { adminHeaders, createAdminUser, } from "../../../../helpers/create-admin-user"
import { setupTaxStructure } from "../../../../modules/__tests__/fixtures"
@@ -312,6 +312,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Shirt",
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "medium", "small"] },
],
@@ -537,6 +538,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Shirt",
status: ProductStatus.PUBLISHED,
options: [{ title: "size", values: ["large", "small"] }],
variants: [
{

View File

@@ -2,6 +2,7 @@ import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import {
ContainerRegistrationKeys,
Modules,
ProductStatus,
RuleOperator,
} from "@medusajs/utils"
import {
@@ -80,6 +81,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Test product",
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "size", values: ["large", "small"] }],
variants: [
@@ -105,6 +107,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Extra product",
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "size", values: ["large", "small"] }],
variants: [
@@ -130,6 +133,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Extra product 2, same price",
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "size", values: ["large", "small"] }],
variants: [

View File

@@ -6,7 +6,7 @@ import {
AdminStockLocation,
MedusaContainer,
} from "@medusajs/types"
import { ContainerRegistrationKeys, Modules } from "@medusajs/utils"
import { ContainerRegistrationKeys, Modules, ProductStatus } from "@medusajs/utils"
import {
adminHeaders,
generatePublishableKey,
@@ -116,6 +116,7 @@ export async function createOrderSeeder({
"/admin/products",
{
title: `Test fixture ${shippingProfile.id}`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: withoutShipping ? undefined : shippingProfile.id,
options: [
{ title: "size", values: ["large", "small"] },

View File

@@ -3,6 +3,7 @@ import {
ContainerRegistrationKeys,
Modules,
OrderChangeStatus,
ProductStatus,
RuleOperator,
} from "@medusajs/utils"
import {
@@ -109,6 +110,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Test product",
status: ProductStatus.PUBLISHED,
options: [{ title: "size", values: ["large", "small"] }],
shipping_profile_id: shippingProfile.id,
variants: [
@@ -134,6 +136,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Extra product",
status: ProductStatus.PUBLISHED,
options: [{ title: "size", values: ["large", "small"] }],
shipping_profile_id: shippingProfile.id,
variants: [
@@ -607,6 +610,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Shirt",
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "medium", "small"] },
],

View File

@@ -1,6 +1,6 @@
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { AdminShippingOption } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/utils"
import { ModuleRegistrationName, ProductStatus } from "@medusajs/utils"
import {
adminHeaders,
createAdminUser,
@@ -705,6 +705,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Test fixture`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [
{ title: "size", values: ["large", "small"] },
@@ -793,6 +794,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Test fixture 2`,
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },
@@ -829,6 +831,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Test fixture 3`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [
{ title: "size", values: ["large", "small"] },
@@ -883,6 +886,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Test override 4`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "size", values: ["large"] }],
variants: [
@@ -924,6 +928,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Test fixture 4`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfileOverride.id,
options: [
{ title: "size", values: ["large", "small"] },
@@ -1310,6 +1315,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Wooden table`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "color", values: ["green"] }],
variants: [
@@ -1474,6 +1480,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Tablet`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "color", values: ["green"] }],
variants: [
@@ -1697,6 +1704,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Tablet`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "color", values: ["green"] }],
variants: [
@@ -2101,6 +2109,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Bottle Packs`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "packs", values: ["one", "two", "three"] }],
variants: [
@@ -2907,6 +2916,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: `Wooden table`,
status: ProductStatus.PUBLISHED,
shipping_profile_id: shippingProfile.id,
options: [{ title: "color", values: ["green"] }],
variants: [

View File

@@ -1,5 +1,5 @@
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { Modules, PromotionStatus, PromotionType } from "@medusajs/utils"
import { Modules, ProductStatus, PromotionStatus, PromotionType } from "@medusajs/utils"
import {
createAdminUser,
generatePublishableKey,
@@ -1724,6 +1724,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Discounted Medusa T-Shirt",
status: ProductStatus.PUBLISHED,
handle: "discounted-medusa-t-shirt",
options: [
{

View File

@@ -4,6 +4,7 @@ import {
generatePublishableKey,
generateStoreHeaders,
} from "../../../../helpers/create-admin-user"
import { ProductStatus } from "@medusajs/utils"
jest.setTimeout(50000)
@@ -80,6 +81,7 @@ medusaIntegrationTestRunner({
{
title: "Test fixture",
shipping_profile_id: shippingProfile.id,
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },

View File

@@ -4,6 +4,7 @@ import {
generatePublishableKey,
generateStoreHeaders,
} from "../../../../helpers/create-admin-user"
import { ProductStatus } from "@medusajs/utils"
jest.setTimeout(50000)
@@ -78,6 +79,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Test fixture",
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },
@@ -634,6 +636,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Test prod",
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },

View File

@@ -26,6 +26,7 @@ import {
import {
ContainerRegistrationKeys,
Modules,
ProductStatus,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import {
@@ -316,6 +317,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -472,6 +474,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -605,6 +608,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -764,6 +768,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",

View File

@@ -36,6 +36,7 @@ import {
Modules,
PriceListStatus,
PriceListType,
ProductStatus,
RuleOperator,
} from "@medusajs/utils"
import {
@@ -184,6 +185,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -422,6 +424,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -538,6 +541,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -687,6 +691,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -855,6 +860,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -1263,6 +1269,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -1456,6 +1463,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -1691,6 +1699,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -1809,6 +1818,153 @@ medusaIntegrationTestRunner({
)
})
it("should throw if product is not published", async () => {
const salesChannel = await scModuleService.createSalesChannels({
name: "Webshop",
})
const location = await stockLocationModule.createStockLocations({
name: "Warehouse",
})
let cart = await cartModuleService.createCarts({
currency_code: "usd",
sales_channel_id: salesChannel.id,
})
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.DRAFT,
variants: [
{
title: "Test variant",
},
],
},
])
const inventoryItem = await inventoryModule.createInventoryItems({
sku: "inv-1234",
})
await inventoryModule.createInventoryLevels([
{
inventory_item_id: inventoryItem.id,
location_id: location.id,
stocked_quantity: 2,
reserved_quantity: 0,
},
])
const priceSet = await pricingModule.createPriceSets({
prices: [
{
amount: 3000,
currency_code: "usd",
},
],
})
await pricingModule.createPricePreferences({
attribute: "currency_code",
value: "usd",
is_tax_inclusive: true,
})
await remoteLink.create([
{
[Modules.PRODUCT]: {
variant_id: product.variants[0].id,
},
[Modules.PRICING]: {
price_set_id: priceSet.id,
},
},
{
[Modules.SALES_CHANNEL]: {
sales_channel_id: salesChannel.id,
},
[Modules.STOCK_LOCATION]: {
stock_location_id: location.id,
},
},
{
[Modules.PRODUCT]: {
variant_id: product.variants[0].id,
},
[Modules.INVENTORY]: {
inventory_item_id: inventoryItem.id,
},
},
])
cart = await cartModuleService.retrieveCart(cart.id, {
select: ["id", "region_id", "currency_code", "sales_channel_id"],
})
const { errors } = await addToCartWorkflow(appContainer).run({
input: {
items: [
{
variant_id: product.variants[0].id,
quantity: 1,
},
],
cart_id: cart.id,
},
throwOnError: false,
})
expect(errors).toEqual([
{
action: "get-variant-items-with-prices-workflow-as-step",
handlerType: "invoke",
error: expect.objectContaining({
message: expect.stringContaining(
`Variants ${product.variants[0].id} do not exist or belong to a product that is not published`
),
}),
},
])
})
it("should throw if variant doesn't exist", async () => {
const salesChannel = await scModuleService.createSalesChannels({
name: "Webshop",
})
let cart = await cartModuleService.createCarts({
currency_code: "usd",
sales_channel_id: salesChannel.id,
})
const { errors } = await addToCartWorkflow(appContainer).run({
input: {
items: [
{
variant_id: "var_1234",
quantity: 1,
},
],
cart_id: cart.id,
},
throwOnError: false,
})
expect(errors).toEqual([
{
action: "get-variant-items-with-prices-workflow-as-step",
handlerType: "invoke",
error: expect.objectContaining({
message: expect.stringContaining(
`Variants var_1234 do not exist or belong to a product that is not published`
),
}),
},
])
})
it("should throw if no price sets for variant exist", async () => {
const salesChannel = await scModuleService.createSalesChannels({
name: "Webshop",
@@ -1910,6 +2066,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -2062,6 +2219,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",

View File

@@ -109,6 +109,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
manage_inventory: false,
@@ -215,6 +216,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product default tax",
status: ProductStatus.PUBLISHED,
variants: [
{ title: "Test variant default tax", manage_inventory: false },
],
@@ -1334,6 +1336,7 @@ medusaIntegrationTestRunner({
"/admin/products",
{
title: "Test fixture",
status: ProductStatus.PUBLISHED,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },

View File

@@ -11,6 +11,7 @@ import {
import {
ContainerRegistrationKeys,
Modules,
ProductStatus,
PromotionStatus,
PromotionType,
} from "@medusajs/utils"
@@ -71,6 +72,7 @@ medusaIntegrationTestRunner({
const [product, product_2] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -79,6 +81,7 @@ medusaIntegrationTestRunner({
},
{
title: "Another product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Variant variable",
@@ -401,6 +404,7 @@ medusaIntegrationTestRunner({
const [product, product_2] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",
@@ -409,6 +413,7 @@ medusaIntegrationTestRunner({
},
{
title: "Another product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Variant variable",
@@ -815,6 +820,7 @@ medusaIntegrationTestRunner({
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
type_id: productType.id,
variants: [
{

View File

@@ -9,6 +9,7 @@ import {
import {
ContainerRegistrationKeys,
Modules,
ProductStatus,
remoteQueryObjectFromString,
} from "@medusajs/utils"
@@ -94,6 +95,7 @@ export async function prepareDataFixtures({ container }) {
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",

View File

@@ -19,6 +19,7 @@ import {
import {
ContainerRegistrationKeys,
Modules,
ProductStatus,
RuleOperator,
remoteQueryObjectFromString,
} from "@medusajs/utils"
@@ -108,6 +109,7 @@ async function prepareDataFixtures({ container }) {
const [product] = await productModule.createProducts([
{
title: "Test product",
status: ProductStatus.PUBLISHED,
variants: [
{
title: "Test variant",

View File

@@ -157,6 +157,7 @@ export const productVariantsFields = [
"product.id",
"product.title",
"product.description",
"product.status",
"product.subtitle",
"product.thumbnail",
"product.type.value",

View File

@@ -13,6 +13,7 @@ import {
filterObjectByKeys,
isDefined,
MedusaError,
ProductStatus,
simpleHash,
} from "@medusajs/framework/utils"
import {
@@ -167,6 +168,7 @@ export const getVariantsAndItemsWithPrices = createWorkflow(
calculatedPriceSets,
}): GetVariantsAndItemsWithPricesWorkflowOutput => {
const priceNotFound: string[] = []
const variantNotFoundOrPublished: string[] = []
const items = (inputItems ?? cart.items ?? []).map((item) => {
const item_ = item as any
@@ -182,6 +184,11 @@ export const getVariantsAndItemsWithPrices = createWorkflow(
}
const variant = variantsData.find((v) => v.id === item.variant_id)
if ((item.variant_id && !variant) || // variant specified but doesn't exist
(variant && (!variant?.product?.status || variant.product.status !== ProductStatus.PUBLISHED)) // variant exists but product is not published
) {
variantNotFoundOrPublished.push(item_.variant_id)
}
if (variant) {
variant.calculated_price = calculatedPriceSet
@@ -215,6 +222,12 @@ export const getVariantsAndItemsWithPrices = createWorkflow(
}
})
if (variantNotFoundOrPublished.length > 0) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Variants ${variantNotFoundOrPublished.join(", ")} do not exist or belong to a product that is not published`
)
}
if (priceNotFound.length > 0) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,

View File

@@ -8,6 +8,7 @@ export const productVariantsFields = [
"product.id",
"product.title",
"product.description",
"product.status",
"product.subtitle",
"product.thumbnail",
"product.type.value",