fix(medusa): Only set product availability + prices if requested (#4010)
* fix(medusa): Only set product availability if variants are requested * Add checks to get products as well * Create nasty-fans-suffer.md
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(medusa): Only set product availability if variants are requested
|
||||||
@@ -59,7 +59,16 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const rawProduct = await productService.retrieve(id, req.retrieveConfig)
|
const rawProduct = await productService.retrieve(id, req.retrieveConfig)
|
||||||
|
|
||||||
const [product] = await pricingService.setProductPrices([rawProduct])
|
// We only set prices if variants.prices are requested
|
||||||
|
const shouldSetPricing = ["variants", "variants.prices"].every((relation) =>
|
||||||
|
req.retrieveConfig.relations?.includes(relation)
|
||||||
|
)
|
||||||
|
|
||||||
|
const product = rawProduct
|
||||||
|
|
||||||
|
if (!shouldSetPricing) {
|
||||||
|
await pricingService.setProductPrices([product])
|
||||||
|
}
|
||||||
|
|
||||||
res.json({ product })
|
res.json({ product })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import {
|
|||||||
SalesChannelService,
|
SalesChannelService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
|
||||||
import { FilterableProductProps } from "../../../../types/product"
|
|
||||||
import { IInventoryService } from "@medusajs/types"
|
import { IInventoryService } from "@medusajs/types"
|
||||||
import { PricedProduct } from "../../../../types/pricing"
|
|
||||||
import { Product } from "../../../../models"
|
|
||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
|
import { Product } from "../../../../models"
|
||||||
|
import { PricedProduct } from "../../../../types/pricing"
|
||||||
|
import { FilterableProductProps } from "../../../../types/product"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /admin/products
|
* @oas [get] /admin/products
|
||||||
@@ -241,16 +241,21 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
let products: (Product | PricedProduct)[] = rawProducts
|
let products: (Product | PricedProduct)[] = rawProducts
|
||||||
|
|
||||||
const includesPricing = ["variants", "variants.prices"].every(
|
// We only set prices if variants.prices are requested
|
||||||
|
const shouldSetPricing = ["variants", "variants.prices"].every(
|
||||||
(relation) => relations?.includes(relation)
|
(relation) => relations?.includes(relation)
|
||||||
)
|
)
|
||||||
if (includesPricing) {
|
|
||||||
|
if (shouldSetPricing) {
|
||||||
products = await pricingService
|
products = await pricingService
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.setProductPrices(rawProducts)
|
.setProductPrices(rawProducts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inventoryService) {
|
// We only set availability if variants are requested
|
||||||
|
const shouldSetAvailability = relations?.includes("variants")
|
||||||
|
|
||||||
|
if (inventoryService && shouldSetAvailability) {
|
||||||
const [salesChannelsIds] = await salesChannelService
|
const [salesChannelsIds] = await salesChannelService
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.listAndCount({}, { select: ["id"] })
|
.listAndCount({}, { select: ["id"] })
|
||||||
|
|||||||
@@ -101,24 +101,46 @@ export default async (req, res) => {
|
|||||||
currencyCode = region.currency_code
|
currencyCode = region.currency_code
|
||||||
}
|
}
|
||||||
|
|
||||||
const pricedProductArray = await pricingService.setProductPrices(
|
const decoratedProduct = rawProduct
|
||||||
[rawProduct],
|
|
||||||
{
|
// We only set prices if variants.prices are requested
|
||||||
cart_id: validated.cart_id,
|
const shouldSetPricing = ["variants", "variants.prices"].every((relation) =>
|
||||||
customer_id: customer_id,
|
req.retrieveConfig.relations?.includes(relation)
|
||||||
region_id: regionId,
|
|
||||||
currency_code: currencyCode,
|
|
||||||
include_discount_prices: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const [product] = await productVariantInventoryService.setProductAvailability(
|
// We only set availability if variants are requested
|
||||||
pricedProductArray,
|
const shouldSetAvailability =
|
||||||
sales_channel_id
|
req.retrieveConfig.relations?.includes("variants")
|
||||||
)
|
|
||||||
|
const decoratePromises: Promise<any>[] = []
|
||||||
|
|
||||||
|
if (shouldSetPricing) {
|
||||||
|
decoratePromises.push(
|
||||||
|
pricingService.setProductPrices([decoratedProduct], {
|
||||||
|
cart_id: validated.cart_id,
|
||||||
|
customer_id: customer_id,
|
||||||
|
region_id: regionId,
|
||||||
|
currency_code: currencyCode,
|
||||||
|
include_discount_prices: true,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSetAvailability) {
|
||||||
|
decoratePromises.push(
|
||||||
|
productVariantInventoryService.setProductAvailability(
|
||||||
|
[decoratedProduct],
|
||||||
|
sales_channel_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can run them concurrently as the new properties are assigned to the references
|
||||||
|
// of the appropriate entity
|
||||||
|
await Promise.all(decoratePromises)
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
product: cleanResponseData(product, req.allowedProperties || []),
|
product: cleanResponseData(decoratedProduct, req.allowedProperties || []),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ import {
|
|||||||
IsString,
|
IsString,
|
||||||
ValidateNested,
|
ValidateNested,
|
||||||
} from "class-validator"
|
} from "class-validator"
|
||||||
|
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
||||||
import {
|
import {
|
||||||
CartService,
|
CartService,
|
||||||
ProductService,
|
ProductService,
|
||||||
ProductVariantInventoryService,
|
ProductVariantInventoryService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
|
||||||
import PricingService from "../../../../services/pricing"
|
import PricingService from "../../../../services/pricing"
|
||||||
import { DateComparisonOperator } from "../../../../types/common"
|
import { DateComparisonOperator } from "../../../../types/common"
|
||||||
import { PriceSelectionParams } from "../../../../types/price-selection"
|
import { PriceSelectionParams } from "../../../../types/price-selection"
|
||||||
|
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
||||||
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
||||||
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
|
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
|
||||||
import { IsType } from "../../../../utils/validators/is-type"
|
import { IsType } from "../../../../utils/validators/is-type"
|
||||||
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
|
||||||
import { defaultStoreCategoryScope } from "../product-categories"
|
import { defaultStoreCategoryScope } from "../product-categories"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,25 +249,44 @@ export default async (req, res) => {
|
|||||||
// Create a new reference just for naming purpose
|
// Create a new reference just for naming purpose
|
||||||
const computedProducts = rawProducts
|
const computedProducts = rawProducts
|
||||||
|
|
||||||
|
// We only set prices if variants.prices are requested
|
||||||
|
const shouldSetPricing = ["variants", "variants.prices"].every(
|
||||||
|
(relation) => listConfig.relations?.includes(relation)
|
||||||
|
)
|
||||||
|
|
||||||
|
// We only set availability if variants are requested
|
||||||
|
const shouldSetAvailability = listConfig.relations?.includes("variants")
|
||||||
|
|
||||||
|
const decoratePromises: Promise<any>[] = []
|
||||||
|
|
||||||
|
if (shouldSetPricing) {
|
||||||
|
decoratePromises.push(
|
||||||
|
pricingService
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.setProductPrices(computedProducts, {
|
||||||
|
cart_id: cart_id,
|
||||||
|
region_id: regionId,
|
||||||
|
currency_code: currencyCode,
|
||||||
|
customer_id: req.user?.customer_id,
|
||||||
|
include_discount_prices: true,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSetAvailability) {
|
||||||
|
decoratePromises.push(
|
||||||
|
productVariantInventoryService
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.setProductAvailability(
|
||||||
|
computedProducts,
|
||||||
|
filterableFields.sales_channel_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// We can run them concurrently as the new properties are assigned to the references
|
// We can run them concurrently as the new properties are assigned to the references
|
||||||
// of the appropriate entity
|
// of the appropriate entity
|
||||||
await Promise.all([
|
await Promise.all(decoratePromises)
|
||||||
pricingService
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.setProductPrices(computedProducts, {
|
|
||||||
cart_id: cart_id,
|
|
||||||
region_id: regionId,
|
|
||||||
currency_code: currencyCode,
|
|
||||||
customer_id: req.user?.customer_id,
|
|
||||||
include_discount_prices: true,
|
|
||||||
}),
|
|
||||||
productVariantInventoryService
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.setProductAvailability(
|
|
||||||
computedProducts,
|
|
||||||
filterableFields.sales_channel_id
|
|
||||||
),
|
|
||||||
])
|
|
||||||
|
|
||||||
return [computedProducts, count]
|
return [computedProducts, count]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user