feat(medusa, inventory): Search inventory items by title and description (#4154)
* initial filtering based on query * add changeset * add expect clause to ensure other items are not inluded
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/inventory": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Feat(medusa,inventory): search inventory items based on title and description
|
||||||
@@ -538,6 +538,49 @@ describe("Inventory Items endpoints", () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("Lists inventory items searching by title, description and sku", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const inventoryService = appContainer.resolve("inventoryService")
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
inventoryService.createInventoryItem({
|
||||||
|
title: "Test Item",
|
||||||
|
}),
|
||||||
|
inventoryService.createInventoryItem({
|
||||||
|
description: "Test Desc",
|
||||||
|
}),
|
||||||
|
inventoryService.createInventoryItem({
|
||||||
|
sku: "Test Sku",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
|
||||||
|
const response = await api.get(
|
||||||
|
`/admin/inventory-items?q=test`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.data.inventory_items).not.toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
sku: "MY_SKU",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
expect(response.data.inventory_items).toHaveLength(3)
|
||||||
|
expect(response.data.inventory_items).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
sku: "Test Sku",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
description: "Test Desc",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
title: "Test Item",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("When deleting an inventory item it removes associated levels and reservations", async () => {
|
it("When deleting an inventory item it removes associated levels and reservations", async () => {
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ export default class InventoryItemService {
|
|||||||
selector,
|
selector,
|
||||||
config
|
config
|
||||||
)
|
)
|
||||||
|
|
||||||
return await queryBuilder.getManyAndCount()
|
return await queryBuilder.getManyAndCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { EntityManager, FindOptionsWhere, ILike } from "typeorm"
|
import { Brackets, EntityManager, FindOptionsWhere } from "typeorm"
|
||||||
import {
|
import {
|
||||||
ExtendedFindConfig,
|
ExtendedFindConfig,
|
||||||
FilterableInventoryItemProps,
|
FilterableInventoryItemProps,
|
||||||
FindConfig,
|
FindConfig,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { InventoryItem, ReservationItem } from "../models"
|
|
||||||
import { buildQuery, objectToStringPath } from "@medusajs/utils"
|
import { buildQuery, objectToStringPath } from "@medusajs/utils"
|
||||||
|
|
||||||
|
import { InventoryItem } from "../models"
|
||||||
|
|
||||||
export function getListQuery(
|
export function getListQuery(
|
||||||
manager: EntityManager,
|
manager: EntityManager,
|
||||||
selector: FilterableInventoryItemProps = {},
|
selector: FilterableInventoryItemProps = {},
|
||||||
@@ -28,10 +29,6 @@ export function getListQuery(
|
|||||||
|
|
||||||
const queryBuilder = inventoryItemRepository.createQueryBuilder("inv_item")
|
const queryBuilder = inventoryItemRepository.createQueryBuilder("inv_item")
|
||||||
|
|
||||||
if (q) {
|
|
||||||
query.where.sku = ILike(`%${q}%`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("location_id" in query.where) {
|
if ("location_id" in query.where) {
|
||||||
const locationIds = Array.isArray(selector.location_id)
|
const locationIds = Array.isArray(selector.location_id)
|
||||||
? selector.location_id
|
? selector.location_id
|
||||||
@@ -47,6 +44,18 @@ export function getListQuery(
|
|||||||
delete query.where.location_id
|
delete query.where.location_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (q) {
|
||||||
|
queryBuilder.where(query.where).andWhere(
|
||||||
|
new Brackets((qb) => {
|
||||||
|
qb.where("inv_item.sku ILike :q", { q: `%${q}%` })
|
||||||
|
.orWhere("inv_item.description ILike :q", { q: `%${q}%` })
|
||||||
|
.orWhere("inv_item.title ILike :q", { q: `%${q}%` })
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
queryBuilder.where(query.where)
|
||||||
|
}
|
||||||
|
|
||||||
if (query.take) {
|
if (query.take) {
|
||||||
queryBuilder.take(query.take)
|
queryBuilder.take(query.take)
|
||||||
}
|
}
|
||||||
@@ -55,10 +64,6 @@ export function getListQuery(
|
|||||||
queryBuilder.skip(query.skip)
|
queryBuilder.skip(query.skip)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.where) {
|
|
||||||
queryBuilder.where(query.where)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.select) {
|
if (query.select) {
|
||||||
const legacySelect = objectToStringPath(query.select)
|
const legacySelect = objectToStringPath(query.select)
|
||||||
queryBuilder.select(legacySelect.map((s) => "inv_item." + s))
|
queryBuilder.select(legacySelect.map((s) => "inv_item." + s))
|
||||||
|
|||||||
@@ -132,6 +132,9 @@ export default (app) => {
|
|||||||
export const defaultAdminInventoryItemFields: (keyof InventoryItemDTO)[] = [
|
export const defaultAdminInventoryItemFields: (keyof InventoryItemDTO)[] = [
|
||||||
"id",
|
"id",
|
||||||
"sku",
|
"sku",
|
||||||
|
"title",
|
||||||
|
"description",
|
||||||
|
"thumbnail",
|
||||||
"origin_country",
|
"origin_country",
|
||||||
"hs_code",
|
"hs_code",
|
||||||
"requires_shipping",
|
"requires_shipping",
|
||||||
|
|||||||
Reference in New Issue
Block a user