fix(core-flows): Avoid throwing if no prices found for variant when adding to cart custom price item (#14528)
* Avoid throwing prices not found error when line item is custom unit price * Add changeset * Avoid throwing upo variant price validation for custom priced item variants
This commit is contained in:
1 parent
d4173478f4
commit
28fae96cee
4 files changed
+116
-8
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/core-flows": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(core-flows): Avoid throwing if no prices found for variant when adding to cart custom price item
|
||||||
@@ -2474,6 +2474,103 @@ medusaIntegrationTestRunner({
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should add item to cart with unit_price when variant has no price set", 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.PUBLISHED,
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
await remoteLink.create([
|
||||||
|
{
|
||||||
|
[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"],
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add item with unit_price specified even though variant has no price set
|
||||||
|
await addToCartWorkflow(appContainer).run({
|
||||||
|
input: {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
variant_id: product.variants[0].id,
|
||||||
|
quantity: 1,
|
||||||
|
unit_price: 5000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cart_id: cart.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
cart = await cartModuleService.retrieveCart(cart.id, {
|
||||||
|
relations: ["items"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(cart).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: cart.id,
|
||||||
|
currency_code: "usd",
|
||||||
|
items: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
unit_price: 5000,
|
||||||
|
is_custom_price: true,
|
||||||
|
quantity: 1,
|
||||||
|
title: "Test product",
|
||||||
|
subtitle: "Test variant",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
describe("setPricingContext hook", () => {
|
describe("setPricingContext hook", () => {
|
||||||
it("should use context provided by the hook", async () => {
|
it("should use context provided by the hook", async () => {
|
||||||
const salesChannel = await scModuleService.createSalesChannels({
|
const salesChannel = await scModuleService.createSalesChannels({
|
||||||
|
|||||||
@@ -91,13 +91,15 @@ async function fetchVariantPriceSets(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates that all variants have price sets and throws error for missing ones
|
* Validates that all variants without a custom price have price sets and throws error for missing ones
|
||||||
*/
|
*/
|
||||||
function validateVariantPriceSets(
|
function validateVariantPriceSets(
|
||||||
variantPriceSets: VariantPriceSetData[]
|
variantPriceSets: VariantPriceSetData[],
|
||||||
|
variantsWithCustomPrice: string[] = []
|
||||||
): void {
|
): void {
|
||||||
|
const variantsWithCustomPriceSet = new Set(variantsWithCustomPrice)
|
||||||
const notFound = variantPriceSets
|
const notFound = variantPriceSets
|
||||||
.filter((v) => !v.price_set?.id)
|
.filter((v) => !v.price_set?.id && !variantsWithCustomPriceSet.has(v.id))
|
||||||
.map((v) => v.id)
|
.map((v) => v.id)
|
||||||
|
|
||||||
if (notFound.length) {
|
if (notFound.length) {
|
||||||
@@ -287,7 +289,10 @@ export const getVariantPriceSetsStep = createStep(
|
|||||||
const variantIds = bulkData.map((item) => item.variantId)
|
const variantIds = bulkData.map((item) => item.variantId)
|
||||||
const variantPriceSets = await fetchVariantPriceSets(query, variantIds)
|
const variantPriceSets = await fetchVariantPriceSets(query, variantIds)
|
||||||
|
|
||||||
validateVariantPriceSets(variantPriceSets)
|
const variantsWithCustomPrice = bulkData
|
||||||
|
.filter((item) => !!item.context?.is_custom_price)
|
||||||
|
.map((item) => item.variantId)
|
||||||
|
validateVariantPriceSets(variantPriceSets, variantsWithCustomPrice)
|
||||||
|
|
||||||
// Map variant IDs to price set IDs
|
// Map variant IDs to price set IDs
|
||||||
const variantToPriceSetId = new Map<string, string>()
|
const variantToPriceSetId = new Map<string, string>()
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ export const getVariantsAndItemsWithPrices = createWorkflow(
|
|||||||
context: {
|
context: {
|
||||||
...baseContext,
|
...baseContext,
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
|
is_custom_price: !!item.unit_price,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -180,7 +181,10 @@ export const getVariantsAndItemsWithPrices = createWorkflow(
|
|||||||
calculatedPriceSet = calculatedPriceSets[item_.variant_id!]
|
calculatedPriceSet = calculatedPriceSets[item_.variant_id!]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!calculatedPriceSet && item_.variant_id) {
|
const isCustomPrice =
|
||||||
|
item_.is_custom_price ?? isDefined(item?.unit_price)
|
||||||
|
|
||||||
|
if (!calculatedPriceSet && item_.variant_id && !isCustomPrice) {
|
||||||
priceNotFound.push(item_.variant_id)
|
priceNotFound.push(item_.variant_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,9 +202,6 @@ export const getVariantsAndItemsWithPrices = createWorkflow(
|
|||||||
variant.calculated_price = calculatedPriceSet
|
variant.calculated_price = calculatedPriceSet
|
||||||
}
|
}
|
||||||
|
|
||||||
const isCustomPrice =
|
|
||||||
item_.is_custom_price ?? isDefined(item?.unit_price)
|
|
||||||
|
|
||||||
const input: PrepareLineItemDataInput = {
|
const input: PrepareLineItemDataInput = {
|
||||||
item: item_,
|
item: item_,
|
||||||
variant: variant,
|
variant: variant,
|
||||||
|
|||||||
Reference in new issue
Block a user