From 0a35f21af7ac8b6cdc1af12a403e95f9bf6142fe Mon Sep 17 00:00:00 2001 From: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com> Date: Wed, 24 May 2023 11:52:25 +0100 Subject: [PATCH] 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 --- .changeset/bright-carrots-look.md | 6 +++ .../inventory/inventory-items/index.js | 43 +++++++++++++++++++ .../inventory/src/services/inventory-item.ts | 1 + packages/inventory/src/utils/query.ts | 25 ++++++----- .../api/routes/admin/inventory-items/index.ts | 3 ++ 5 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 .changeset/bright-carrots-look.md diff --git a/.changeset/bright-carrots-look.md b/.changeset/bright-carrots-look.md new file mode 100644 index 0000000000..f81d29b1a5 --- /dev/null +++ b/.changeset/bright-carrots-look.md @@ -0,0 +1,6 @@ +--- +"@medusajs/inventory": patch +"@medusajs/medusa": patch +--- + +Feat(medusa,inventory): search inventory items based on title and description diff --git a/integration-tests/plugins/__tests__/inventory/inventory-items/index.js b/integration-tests/plugins/__tests__/inventory/inventory-items/index.js index db0c1ef3b2..755c2e01e4 100644 --- a/integration-tests/plugins/__tests__/inventory/inventory-items/index.js +++ b/integration-tests/plugins/__tests__/inventory/inventory-items/index.js @@ -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 () => { diff --git a/packages/inventory/src/services/inventory-item.ts b/packages/inventory/src/services/inventory-item.ts index 0324523037..46a76dcd0c 100644 --- a/packages/inventory/src/services/inventory-item.ts +++ b/packages/inventory/src/services/inventory-item.ts @@ -72,6 +72,7 @@ export default class InventoryItemService { selector, config ) + return await queryBuilder.getManyAndCount() } diff --git a/packages/inventory/src/utils/query.ts b/packages/inventory/src/utils/query.ts index 6793c1fcfd..be26d5b1e8 100644 --- a/packages/inventory/src/utils/query.ts +++ b/packages/inventory/src/utils/query.ts @@ -1,12 +1,13 @@ -import { EntityManager, FindOptionsWhere, ILike } from "typeorm" +import { Brackets, EntityManager, FindOptionsWhere } from "typeorm" import { ExtendedFindConfig, FilterableInventoryItemProps, FindConfig, } from "@medusajs/types" -import { InventoryItem, ReservationItem } from "../models" import { buildQuery, objectToStringPath } from "@medusajs/utils" +import { InventoryItem } from "../models" + export function getListQuery( manager: EntityManager, selector: FilterableInventoryItemProps = {}, @@ -28,10 +29,6 @@ export function getListQuery( const queryBuilder = inventoryItemRepository.createQueryBuilder("inv_item") - if (q) { - query.where.sku = ILike(`%${q}%`) - } - if ("location_id" in query.where) { const locationIds = Array.isArray(selector.location_id) ? selector.location_id @@ -47,6 +44,18 @@ export function getListQuery( 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) { queryBuilder.take(query.take) } @@ -55,10 +64,6 @@ export function getListQuery( queryBuilder.skip(query.skip) } - if (query.where) { - queryBuilder.where(query.where) - } - if (query.select) { const legacySelect = objectToStringPath(query.select) queryBuilder.select(legacySelect.map((s) => "inv_item." + s)) diff --git a/packages/medusa/src/api/routes/admin/inventory-items/index.ts b/packages/medusa/src/api/routes/admin/inventory-items/index.ts index 13701b1f5f..66f97e308b 100644 --- a/packages/medusa/src/api/routes/admin/inventory-items/index.ts +++ b/packages/medusa/src/api/routes/admin/inventory-items/index.ts @@ -132,6 +132,9 @@ export default (app) => { export const defaultAdminInventoryItemFields: (keyof InventoryItemDTO)[] = [ "id", "sku", + "title", + "description", + "thumbnail", "origin_country", "hs_code", "requires_shipping",