fix(medusa): Include inventory quantity when listing products (#3586)
* initial inclusion of quantities when listing admin prices * add changeset * rename variable * add inventory service check when listing products * update changeset version bump
This commit is contained in:
5
.changeset/olive-days-jog.md
Normal file
5
.changeset/olive-days-jog.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/medusa": minor
|
||||
---
|
||||
|
||||
Fix(medusa): include quantities when listing admin products with an inventory module installed
|
||||
@@ -1,10 +1,16 @@
|
||||
import { IsNumber, IsOptional, IsString } from "class-validator"
|
||||
import { PricingService, ProductService } from "../../../../services"
|
||||
import {
|
||||
PricingService,
|
||||
ProductService,
|
||||
ProductVariantInventoryService,
|
||||
SalesChannelService,
|
||||
} from "../../../../services"
|
||||
|
||||
import { Type } from "class-transformer"
|
||||
import { Product } from "../../../../models"
|
||||
import { PricedProduct } from "../../../../types/pricing"
|
||||
import { FilterableProductProps } from "../../../../types/product"
|
||||
import { PricedProduct } from "../../../../types/pricing"
|
||||
import { Product } from "../../../../models"
|
||||
import { Type } from "class-transformer"
|
||||
import { IInventoryService } from "@medusajs/types"
|
||||
|
||||
/**
|
||||
* @oas [get] /admin/products
|
||||
@@ -214,6 +220,13 @@ import { FilterableProductProps } from "../../../../types/product"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const productService: ProductService = req.scope.resolve("productService")
|
||||
const inventoryService: IInventoryService | undefined =
|
||||
req.scope.resolve("inventoryService")
|
||||
const productVariantInventoryService: ProductVariantInventoryService =
|
||||
req.scope.resolve("productVariantInventoryService")
|
||||
const salesChannelService: SalesChannelService = req.scope.resolve(
|
||||
"salesChannelService"
|
||||
)
|
||||
const pricingService: PricingService = req.scope.resolve("pricingService")
|
||||
|
||||
const { skip, take, relations } = req.listConfig
|
||||
@@ -232,6 +245,18 @@ export default async (req, res) => {
|
||||
products = await pricingService.setProductPrices(rawProducts)
|
||||
}
|
||||
|
||||
if (inventoryService) {
|
||||
const [salesChannelsIds] = await salesChannelService.listAndCount(
|
||||
{},
|
||||
{ select: ["id"] }
|
||||
)
|
||||
|
||||
products = await productVariantInventoryService.setProductAvailability(
|
||||
products,
|
||||
salesChannelsIds.map((salesChannel) => salesChannel.id)
|
||||
)
|
||||
}
|
||||
|
||||
res.json({
|
||||
products,
|
||||
count,
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { EntityManager, In } from "typeorm"
|
||||
import {
|
||||
ICacheService,
|
||||
IInventoryService,
|
||||
InventoryItemDTO,
|
||||
IStockLocationService,
|
||||
InventoryItemDTO,
|
||||
ReservationItemDTO,
|
||||
ReserveQuantityContext,
|
||||
} from "@medusajs/types"
|
||||
import { isDefined, MedusaError, TransactionBaseService } from "@medusajs/utils"
|
||||
import { EntityManager, In } from "typeorm"
|
||||
import { LineItem, Product, ProductVariant } from "../models"
|
||||
import { ProductVariantInventoryItem } from "../models/product-variant-inventory-item"
|
||||
import { MedusaError, TransactionBaseService, isDefined } from "@medusajs/utils"
|
||||
import { PricedProduct, PricedVariant } from "../types/pricing"
|
||||
|
||||
import { ProductVariantInventoryItem } from "../models/product-variant-inventory-item"
|
||||
import ProductVariantService from "./product-variant"
|
||||
import SalesChannelInventoryService from "./sales-channel-inventory"
|
||||
import SalesChannelLocationService from "./sales-channel-location"
|
||||
@@ -629,7 +630,7 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
|
||||
async setVariantAvailability(
|
||||
variants: ProductVariant[] | PricedVariant[],
|
||||
salesChannelId: string | undefined
|
||||
salesChannelId: string | string[] | undefined
|
||||
): Promise<ProductVariant[] | PricedVariant[]> {
|
||||
if (!this.inventoryService_) {
|
||||
return variants
|
||||
@@ -649,11 +650,23 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
// first get all inventory items required for a variant
|
||||
const variantInventory = await this.listByVariant(variant.id)
|
||||
|
||||
variant.inventory_quantity =
|
||||
await this.getVariantQuantityFromVariantInventoryItems(
|
||||
variantInventory,
|
||||
salesChannelId
|
||||
)
|
||||
const salesChannelArray = Array.isArray(salesChannelId)
|
||||
? salesChannelId
|
||||
: [salesChannelId]
|
||||
|
||||
const quantities = await Promise.all(
|
||||
salesChannelArray.map(async (salesChannel) => {
|
||||
return await this.getVariantQuantityFromVariantInventoryItems(
|
||||
variantInventory,
|
||||
salesChannel
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
variant.inventory_quantity = quantities.reduce(
|
||||
(acc, next) => acc + (next || 0),
|
||||
0
|
||||
)
|
||||
|
||||
return variant
|
||||
})
|
||||
@@ -662,7 +675,7 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
|
||||
async setProductAvailability(
|
||||
products: (Product | PricedProduct)[],
|
||||
salesChannelId: string | undefined
|
||||
salesChannelId: string | string[] | undefined
|
||||
): Promise<(Product | PricedProduct)[]> {
|
||||
return await Promise.all(
|
||||
products.map(async (product) => {
|
||||
|
||||
Reference in New Issue
Block a user