From 1fbe972af755b0243d474ad9e9e44297bb2bcdbd Mon Sep 17 00:00:00 2001 From: Niklas Fondberg Date: Mon, 11 Oct 2021 19:28:15 +0200 Subject: [PATCH] Add search for products in all sub categories (#68) --- src/datasources/product-api.ts | 14 +++++++++-- src/datasources/sql/products-sql.ts | 36 ++++++++++++++++++++++++---- src/resolvers/categories-resolver.ts | 11 +++++++-- src/schema.graphql | 5 +++- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/datasources/product-api.ts b/src/datasources/product-api.ts index 3a4c506..d57deb1 100644 --- a/src/datasources/product-api.ts +++ b/src/datasources/product-api.ts @@ -88,8 +88,8 @@ export class ProductAPI extends BaseSQLDataSource { return mem; }, {}); - fields['artNo'] = fields['artNo']; - fields['name'] = fields['name']; + fields['artNo'] = fields['artNo'] ?? ''; // some actually exists without artNo + fields['name'] = fields['name'] ?? ''; // some actually exists without name fields['copyright'] = fields['copyright'] ?? ''; fields['comments'] = fields['comments'] ?? ''; fields['batch'] = fields['batch'] ?? ''; @@ -196,6 +196,16 @@ export class ProductAPI extends BaseSQLDataSource { .then((data) => data.rows.map((row) => this.createProductFromRow(row))); } + async getCategoryWithSubCategoriesProducts( + categoryId: number, + ): Promise> { + const query = sql.categoryWithAllSubCategoriesProducts(categoryId); + + return this.knex + .raw(query) + .then((data) => data.rows.map((row) => this.createProductFromRow(row))); + } + async getKeywordProducts(keywordId: number): Promise> { const query = sql.keywordProducts(keywordId); diff --git a/src/datasources/sql/products-sql.ts b/src/datasources/sql/products-sql.ts index 8325618..6bf0fde 100644 --- a/src/datasources/sql/products-sql.ts +++ b/src/datasources/sql/products-sql.ts @@ -121,7 +121,32 @@ export function categoryProducts(categoryId: number) { return ( baseQuery + /* sql */ ` - WHERE products.productid IN (SELECT product_id FROM product_category WHERE category_id = ${categoryId}); + WHERE products.productid IN (SELECT product_id FROM product_category WHERE category_id = ${categoryId}) + ORDER BY products.inserted DESC +` + ); +} + +export function categoryWithAllSubCategoriesProducts(categoryId: number) { + return ( + baseQuery + + /* sql */ ` + WHERE products.productid IN ( + SELECT product_id + FROM product_category + WHERE category_id IN ( + SELECT cat.id + FROM categories cat + JOIN ( + SELECT id, lft, rgt + FROM categories + WHERE id = ${categoryId} + ) tree + ON cat.lft >= tree.lft AND cat.rgt <= tree.rgt + ) + ORDER BY product_id + ) + ORDER BY products.inserted DESC ` ); } @@ -130,7 +155,8 @@ export function designerProducts() { return ( baseQuery + /* sql */ ` - WHERE products.designerid = ?; + WHERE products.designerid = ? + ORDER BY products.inserted DESC ` ); } @@ -139,7 +165,8 @@ export function keywordProducts(keywordId: number) { return ( baseQuery + /* sql */ ` - WHERE products.productid IN (SELECT product_id FROM product_keyword WHERE keyword_id = ${keywordId}); + WHERE products.productid IN (SELECT product_id FROM product_keyword WHERE keyword_id = ${keywordId}) + ORDER BY products.inserted DESC ` ); } @@ -148,7 +175,8 @@ export function searchByFieldValue(fieldid: number) { return ( baseQuery + /* sql */ ` - WHERE products.productid IN (SELECT productid FROM "product-products_fields" WHERE fieldid = ${fieldid} AND LOWER(value) LIKE ? LIMIT 5000); -- limit to 5000 results + WHERE products.productid IN (SELECT productid FROM "product-products_fields" WHERE fieldid = ${fieldid} AND LOWER(value) LIKE ? LIMIT 5000) -- limit to 5000 results + ORDER BY products.inserted DESC ` ); } diff --git a/src/resolvers/categories-resolver.ts b/src/resolvers/categories-resolver.ts index 2d4a091..e0011ef 100644 --- a/src/resolvers/categories-resolver.ts +++ b/src/resolvers/categories-resolver.ts @@ -3,9 +3,16 @@ import { CategoryAPI } from '../datasources/category-api'; import { ProductAPI } from '../datasources/product-api'; const Category = { - async products({ id }, _args, { dataSources, auth }) { + async products({ id }, { includeAllSubCategories }, { dataSources, auth }) { + console.log('includeAllSubCategories:', includeAllSubCategories); checkAccess(['products.read'], auth); - return (dataSources.productApi).getCategoryProducts(id); + if (includeAllSubCategories === true) { + return (( + dataSources.productApi + )).getCategoryWithSubCategoriesProducts(id); + } else { + return (dataSources.productApi).getCategoryProducts(id); + } }, }; diff --git a/src/schema.graphql b/src/schema.graphql index 59095c1..0e6bfb2 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -256,7 +256,10 @@ type Category { childCount: Int lft: Int rgt: Int - products: [Product] + """ + Default to false + """ + products(includeAllSubCategories: Boolean): [Product] } type Batch {