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:
Oliver Windall Juhl
2023-05-04 09:29:13 +02:00
committed by GitHub
parent 0e488e71b1
commit 284f1eed9a
5 changed files with 100 additions and 40 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
fix(medusa): Only set product availability if variants are requested

View File

@@ -59,7 +59,16 @@ export default async (req, res) => {
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 })
}

View File

@@ -6,11 +6,11 @@ import {
SalesChannelService,
} from "../../../../services"
import { FilterableProductProps } from "../../../../types/product"
import { IInventoryService } from "@medusajs/types"
import { PricedProduct } from "../../../../types/pricing"
import { Product } from "../../../../models"
import { Type } from "class-transformer"
import { Product } from "../../../../models"
import { PricedProduct } from "../../../../types/pricing"
import { FilterableProductProps } from "../../../../types/product"
/**
* @oas [get] /admin/products
@@ -241,16 +241,21 @@ export default async (req, res) => {
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)
)
if (includesPricing) {
if (shouldSetPricing) {
products = await pricingService
.withTransaction(transactionManager)
.setProductPrices(rawProducts)
}
if (inventoryService) {
// We only set availability if variants are requested
const shouldSetAvailability = relations?.includes("variants")
if (inventoryService && shouldSetAvailability) {
const [salesChannelsIds] = await salesChannelService
.withTransaction(transactionManager)
.listAndCount({}, { select: ["id"] })

View File

@@ -101,24 +101,46 @@ export default async (req, res) => {
currencyCode = region.currency_code
}
const pricedProductArray = await pricingService.setProductPrices(
[rawProduct],
{
cart_id: validated.cart_id,
customer_id: customer_id,
region_id: regionId,
currency_code: currencyCode,
include_discount_prices: true,
}
const decoratedProduct = rawProduct
// We only set prices if variants.prices are requested
const shouldSetPricing = ["variants", "variants.prices"].every((relation) =>
req.retrieveConfig.relations?.includes(relation)
)
const [product] = await productVariantInventoryService.setProductAvailability(
pricedProductArray,
sales_channel_id
)
// We only set availability if variants are requested
const shouldSetAvailability =
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({
product: cleanResponseData(product, req.allowedProperties || []),
product: cleanResponseData(decoratedProduct, req.allowedProperties || []),
})
}

View File

@@ -7,19 +7,19 @@ import {
IsString,
ValidateNested,
} from "class-validator"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import {
CartService,
ProductService,
ProductVariantInventoryService,
} from "../../../../services"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import PricingService from "../../../../services/pricing"
import { DateComparisonOperator } from "../../../../types/common"
import { PriceSelectionParams } from "../../../../types/price-selection"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
import { IsType } from "../../../../utils/validators/is-type"
import { cleanResponseData } from "../../../../utils/clean-response-data"
import { defaultStoreCategoryScope } from "../product-categories"
/**
@@ -249,25 +249,44 @@ export default async (req, res) => {
// Create a new reference just for naming purpose
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
// of the appropriate entity
await Promise.all([
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
),
])
await Promise.all(decoratePromises)
return [computedProducts, count]
}