u
This commit is contained in:
@@ -171,7 +171,7 @@ const articles = await store.category.getCategoryArticles(42, 5);
|
|||||||
|
|
||||||
*Source: `src/store/category/getTreeForCompany.js`*
|
*Source: `src/store/category/getTreeForCompany.js`*
|
||||||
|
|
||||||
Returns the full category tree for the user's selected company together with its articles and the posterminal ids assigned to each category.
|
Returns the full category tree for the user's selected company together with the article count and the posterminal ids assigned to each category.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
@@ -182,13 +182,13 @@ Returns the full category tree for the user's selected company together with its
|
|||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<{languageId: number, tree: Array<object>, articles: Array<object>}>` — The category tree, articles and language.
|
`Promise<{languageId: number, tree: Array<{id: number, parentId: number|null, sort: number, name: string|null, slug: string|null, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null, articleCount: number, posterminalIds: number[]}>, articleCount: number}>` — The category tree and article count.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const tree = await store.category.getTreeForCompany(42);
|
const tree = await store.category.getTreeForCompany(42);
|
||||||
// => { languageId, tree: [{ id, posterminalIds, ... }], articles: [...] }
|
// => { languageId, tree: [{ id, articleCount, posterminalIds, ... }], articleCount: 25 }
|
||||||
```
|
```
|
||||||
|
|
||||||
## `category.move`
|
## `category.move`
|
||||||
|
|||||||
@@ -186,13 +186,13 @@ Lists the companies accessible to the given Google auth user.
|
|||||||
|
|
||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
`Promise<Array<object>>` — The accessible company rows.
|
`Promise<Array<{id: number, name: string, rootCategoryId: number, languageId: number, iso639: string|null, taxrate: number, reducedtaxrate: number, taxfreerate: number}>>` — The accessible company rows.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const companies = await store.company.list(42);
|
const companies = await store.company.list(42);
|
||||||
// => [{ id, name, ... }]
|
// => [{ id, name, rootCategoryId, languageId, iso639, taxrate, reducedtaxrate, taxfreerate }]
|
||||||
```
|
```
|
||||||
|
|
||||||
## `company.update`
|
## `company.update`
|
||||||
|
|||||||
4
API.md
4
API.md
@@ -72,7 +72,7 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met
|
|||||||
- `getById(id: number, tx?: object): Promise<object|undefined>`
|
- `getById(id: number, tx?: object): Promise<object|undefined>`
|
||||||
- `getByName(name: string, tx?: object): Promise<object|undefined>`
|
- `getByName(name: string, tx?: object): Promise<object|undefined>`
|
||||||
- `getHistory(googleAuthId: number, opts?: {limit?: number}, tx?: object): Promise<Array<{id: number, companyuserId: number|null, date: string, text: string}>>`
|
- `getHistory(googleAuthId: number, opts?: {limit?: number}, tx?: object): Promise<Array<{id: number, companyuserId: number|null, date: string, text: string}>>`
|
||||||
- `list(googleAuthId: number, tx?: object): Promise<Array<object>>`
|
- `list(googleAuthId: number, tx?: object): Promise<Array<{id: number, name: string, rootCategoryId: number, languageId: number, iso639: string|null, taxrate: number, reducedtaxrate: number, taxfreerate: number}>>`
|
||||||
- `update(id: number, input: {iso639: string, name: string, taxrate: number, reducedtaxrate: number}, tx?: object): Promise<{id: number, rootCategoryId: number, languageId: number, taxrateId: number, reducedtaxrateId: number, taxfreerateId: number}>`
|
- `update(id: number, input: {iso639: string, name: string, taxrate: number, reducedtaxrate: number}, tx?: object): Promise<{id: number, rootCategoryId: number, languageId: number, taxrateId: number, reducedtaxrateId: number, taxfreerateId: number}>`
|
||||||
- [category](API.category.md)
|
- [category](API.category.md)
|
||||||
- `addImage(googleAuthId: number, categoryId: number, image: Buffer, tx?: object): Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number}>`
|
- `addImage(googleAuthId: number, categoryId: number, image: Buffer, tx?: object): Promise<{id: number, fullHash: string, thumbW: number, thumbH: number, thumbHash: string, smallThumbW: number, smallThumbH: number}>`
|
||||||
@@ -81,7 +81,7 @@ The store is exposed as a `LibDashStore` instance (see `src/index.js`). Each met
|
|||||||
- `deleteImage(googleAuthId: number, categoryId: number, tx?: object): Promise<{id: number, thumbW: null, thumbH: null, thumbHash: null}>`
|
- `deleteImage(googleAuthId: number, categoryId: number, tx?: object): Promise<{id: number, thumbW: null, thumbH: null, thumbHash: null}>`
|
||||||
- `ensureByPath(input: {googleAuthId: number, parentId: number, path: string}, tx?: object): Promise<number>`
|
- `ensureByPath(input: {googleAuthId: number, parentId: number, path: string}, tx?: object): Promise<number>`
|
||||||
- `getCategoryArticles(googleAuthId: number, categoryId: number, tx?: object): Promise<Array<{id: number, sku: string, name: string, slug: string, net: number|null, taxRate: number|null, optionsCount: number, articleListCount: number, childCount: number, parentArticleId: number|null, parentSku: string|null, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null, brand: {id: number|null, name: string, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null}|null}>>`
|
- `getCategoryArticles(googleAuthId: number, categoryId: number, tx?: object): Promise<Array<{id: number, sku: string, name: string, slug: string, net: number|null, taxRate: number|null, optionsCount: number, articleListCount: number, childCount: number, parentArticleId: number|null, parentSku: string|null, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null, brand: {id: number|null, name: string, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null}|null}>>`
|
||||||
- `getTreeForCompany(googleAuthId: number, tx?: object): Promise<{languageId: number, tree: Array<object>, articles: Array<object>}>`
|
- `getTreeForCompany(googleAuthId: number, tx?: object): Promise<{languageId: number, tree: Array<{id: number, parentId: number|null, sort: number, name: string|null, slug: string|null, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null, articleCount: number, posterminalIds: number[]}>, articleCount: number}>`
|
||||||
- `move(input: {googleAuthId: number, id: number, parentId: number}, tx?: object): Promise<{id: number, parentId: number, sort: number}>`
|
- `move(input: {googleAuthId: number, id: number, parentId: number}, tx?: object): Promise<{id: number, parentId: number, sort: number}>`
|
||||||
- `order(input: {googleAuthId: number, parentId: number, categoryIds: Array<number>}, tx?: object): Promise<{categoryIds: Array<number>}>`
|
- `order(input: {googleAuthId: number, parentId: number, categoryIds: Array<number>}, tx?: object): Promise<{categoryIds: Array<number>}>`
|
||||||
- `rename(input: {googleAuthId: number, id: number, name: string}, tx?: object): Promise<{id: number, name: string, slug: string}>`
|
- `rename(input: {googleAuthId: number, id: number, name: string}, tx?: object): Promise<{id: number, name: string, slug: string}>`
|
||||||
|
|||||||
@@ -19,7 +19,13 @@ SELECT
|
|||||||
p.hash AS fullHash,
|
p.hash AS fullHash,
|
||||||
p.thumbw AS thumbW,
|
p.thumbw AS thumbW,
|
||||||
p.thumbh AS thumbH,
|
p.thumbh AS thumbH,
|
||||||
p.thumbhash AS thumbHash
|
p.thumbhash AS thumbHash,
|
||||||
|
(
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM categoryarticle ca
|
||||||
|
INNER JOIN article a ON a.id = ca.article_id
|
||||||
|
WHERE ca.category_id = t.id AND a.parentarticle_id IS NULL
|
||||||
|
) AS articleCount
|
||||||
FROM tree t
|
FROM tree t
|
||||||
LEFT JOIN categorytext ct
|
LEFT JOIN categorytext ct
|
||||||
ON ct.category_id = t.id AND ct.language_id = @languageId
|
ON ct.category_id = t.id AND ct.language_id = @languageId
|
||||||
@@ -33,6 +39,19 @@ LEFT JOIN pic p ON p.id = first_pic.pic_id
|
|||||||
ORDER BY t.sort, t.id
|
ORDER BY t.sort, t.id
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const COUNT_ARTICLES_IN_TREE = `
|
||||||
|
WITH tree AS (
|
||||||
|
SELECT id FROM category WHERE id = @rootId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN tree t ON c.parent_id = t.id
|
||||||
|
)
|
||||||
|
SELECT COUNT(DISTINCT ca.article_id) AS total
|
||||||
|
FROM categoryarticle ca
|
||||||
|
INNER JOIN article a ON a.id = ca.article_id
|
||||||
|
WHERE ca.category_id IN (SELECT id FROM tree)
|
||||||
|
AND a.parentarticle_id IS NULL
|
||||||
|
`;
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ARTICLE_LIST_COLUMNS,
|
ARTICLE_LIST_COLUMNS,
|
||||||
ARTICLE_LIST_JOINS,
|
ARTICLE_LIST_JOINS,
|
||||||
|
|||||||
@@ -52,11 +52,13 @@ SELECT
|
|||||||
c.name,
|
c.name,
|
||||||
c.root_category_id AS rootCategoryId,
|
c.root_category_id AS rootCategoryId,
|
||||||
c.default_language_id AS languageId,
|
c.default_language_id AS languageId,
|
||||||
|
l.iso639,
|
||||||
tr.rate AS taxrate,
|
tr.rate AS taxrate,
|
||||||
rtr.rate AS reducedtaxrate,
|
rtr.rate AS reducedtaxrate,
|
||||||
tfr.rate AS taxfreerate
|
tfr.rate AS taxfreerate
|
||||||
FROM company c
|
FROM company c
|
||||||
INNER JOIN companyuser cu ON cu.company_id = c.id
|
INNER JOIN companyuser cu ON cu.company_id = c.id
|
||||||
|
LEFT JOIN language l ON l.id = c.default_language_id
|
||||||
LEFT JOIN tax tr ON tr.id = c.taxrate
|
LEFT JOIN tax tr ON tr.id = c.taxrate
|
||||||
LEFT JOIN tax rtr ON rtr.id = c.reducedtaxrate
|
LEFT JOIN tax rtr ON rtr.id = c.reducedtaxrate
|
||||||
LEFT JOIN tax tfr ON tfr.id = c.taxfreerate
|
LEFT JOIN tax tfr ON tfr.id = c.taxfreerate
|
||||||
|
|||||||
@@ -79,7 +79,13 @@ WITH RECURSIVE tree AS (
|
|||||||
SELECT
|
SELECT
|
||||||
t.id, t.parent_id AS parentId, t.sort, ct.name, ct.slug,
|
t.id, t.parent_id AS parentId, t.sort, ct.name, ct.slug,
|
||||||
p.hash AS fullHash, p.thumbw AS thumbW, p.thumbh AS thumbH,
|
p.hash AS fullHash, p.thumbw AS thumbW, p.thumbh AS thumbH,
|
||||||
p.thumbhash AS thumbHash
|
p.thumbhash AS thumbHash,
|
||||||
|
(
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM categoryarticle ca
|
||||||
|
INNER JOIN article a ON a.id = ca.article_id
|
||||||
|
WHERE ca.category_id = t.id AND a.parentarticle_id IS NULL
|
||||||
|
) AS articleCount
|
||||||
FROM tree t
|
FROM tree t
|
||||||
LEFT JOIN categorytext ct
|
LEFT JOIN categorytext ct
|
||||||
ON ct.category_id = t.id AND ct.language_id = @languageId
|
ON ct.category_id = t.id AND ct.language_id = @languageId
|
||||||
@@ -89,4 +95,17 @@ LEFT JOIN pic p ON p.id = (
|
|||||||
ORDER BY cp.sort, cp.id LIMIT 1
|
ORDER BY cp.sort, cp.id LIMIT 1
|
||||||
)
|
)
|
||||||
ORDER BY t.sort, t.id
|
ORDER BY t.sort, t.id
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const COUNT_ARTICLES_IN_TREE = `
|
||||||
|
WITH RECURSIVE tree AS (
|
||||||
|
SELECT id FROM category WHERE id = @rootId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN tree t ON c.parent_id = t.id
|
||||||
|
)
|
||||||
|
SELECT COUNT(DISTINCT ca.article_id) AS total
|
||||||
|
FROM categoryarticle ca
|
||||||
|
INNER JOIN article a ON a.id = ca.article_id
|
||||||
|
WHERE ca.category_id IN (SELECT id FROM tree)
|
||||||
|
AND a.parentarticle_id IS NULL
|
||||||
`;
|
`;
|
||||||
@@ -1,52 +1,60 @@
|
|||||||
import { GET_TREE_FOR_COMPANY as MSSQL_GET_TREE } from '../../providers/mssql/queries/category.js';
|
import {
|
||||||
import { GET_TREE_FOR_COMPANY as SQLITE_GET_TREE } from '../../providers/sqlite3/queries/category.js';
|
GET_TREE_FOR_COMPANY as MSSQL_GET_TREE,
|
||||||
|
COUNT_ARTICLES_IN_TREE as MSSQL_COUNT_ARTICLES,
|
||||||
|
} from '../../providers/mssql/queries/category.js';
|
||||||
|
import {
|
||||||
|
GET_TREE_FOR_COMPANY as SQLITE_GET_TREE,
|
||||||
|
COUNT_ARTICLES_IN_TREE as SQLITE_COUNT_ARTICLES,
|
||||||
|
} from '../../providers/sqlite3/queries/category.js';
|
||||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||||
import queryCategoryArticles from './queryCategoryArticles.js';
|
|
||||||
import getCategoryPosterminalIds from '../posterminal/getCategoryPosterminalIds.js';
|
import getCategoryPosterminalIds from '../posterminal/getCategoryPosterminalIds.js';
|
||||||
import makeRunner from '../runner.js';
|
import makeRunner from '../runner.js';
|
||||||
|
|
||||||
export default function getTreeForCompany(provider) {
|
export default function getTreeForCompany(provider) {
|
||||||
const access = resolveSelectedCompanyAccess(provider);
|
const access = resolveSelectedCompanyAccess(provider);
|
||||||
const articles = queryCategoryArticles(provider);
|
|
||||||
const posterminalIds = getCategoryPosterminalIds(provider);
|
const posterminalIds = getCategoryPosterminalIds(provider);
|
||||||
const sql =
|
const isSqlite = provider?.dialect === 'sqlite3';
|
||||||
provider?.dialect === 'sqlite3' ? SQLITE_GET_TREE : MSSQL_GET_TREE;
|
const sql = isSqlite ? SQLITE_GET_TREE : MSSQL_GET_TREE;
|
||||||
|
const countSql = isSqlite ? SQLITE_COUNT_ARTICLES : MSSQL_COUNT_ARTICLES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full category tree for the user's selected company together
|
* Returns the full category tree for the user's selected company together
|
||||||
* with its articles and the posterminal ids assigned to each category.
|
* with the article count and the posterminal ids assigned to each category.
|
||||||
*
|
*
|
||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<{languageId: number, tree: Array<object>, articles: Array<object>}>} The category tree, articles and language.
|
* @returns {Promise<{languageId: number, tree: Array<{id: number, parentId: number|null, sort: number, name: string|null, slug: string|null, fullHash: string|null, thumbW: number|null, thumbH: number|null, thumbHash: string|null, articleCount: number, posterminalIds: number[]}>, articleCount: number}>} The category tree and article count.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const tree = await store.category.getTreeForCompany(42);
|
* const tree = await store.category.getTreeForCompany(42);
|
||||||
* // => { languageId, tree: [{ id, posterminalIds, ... }], articles: [...] }
|
* // => { languageId, tree: [{ id, articleCount, posterminalIds, ... }], articleCount: 25 }
|
||||||
*/
|
*/
|
||||||
return async (googleAuthId, tx) => {
|
return async (googleAuthId, tx) => {
|
||||||
const { companyId, rootCategoryId, languageId, posCustomerGroupId } =
|
const { companyId, rootCategoryId, languageId } =
|
||||||
await access(googleAuthId, tx);
|
await access(googleAuthId, tx);
|
||||||
|
|
||||||
const runner = makeRunner(provider, tx);
|
const runner = makeRunner(provider, tx);
|
||||||
const [treeResult, articleRows, ptMap] = await Promise.all([
|
const [treeResult, countResult, ptMap] = await Promise.all([
|
||||||
runner.query(sql, {
|
runner.query(sql, {
|
||||||
rootId: rootCategoryId,
|
rootId: rootCategoryId,
|
||||||
languageId,
|
languageId,
|
||||||
}),
|
}),
|
||||||
articles({ categoryId: rootCategoryId, languageId, posCustomerGroupId }, tx),
|
runner.query(countSql, {
|
||||||
|
rootId: rootCategoryId,
|
||||||
|
}),
|
||||||
posterminalIds(companyId, tx),
|
posterminalIds(companyId, tx),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const tree = treeResult.rows.map((row) => ({
|
const tree = treeResult.rows.map((row) => ({
|
||||||
...row,
|
...row,
|
||||||
|
articleCount: Number(row.articleCount ?? 0),
|
||||||
posterminalIds: ptMap[row.id] ?? [],
|
posterminalIds: ptMap[row.id] ?? [],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
languageId,
|
languageId,
|
||||||
tree,
|
tree,
|
||||||
articles: articleRows,
|
articleCount: Number(countResult.rows[0]?.total ?? 0),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ export default function list(provider) {
|
|||||||
*
|
*
|
||||||
* @param {number} googleAuthId - The id of the Google auth user.
|
* @param {number} googleAuthId - The id of the Google auth user.
|
||||||
* @param {object} [tx] - Optional transaction to run within.
|
* @param {object} [tx] - Optional transaction to run within.
|
||||||
* @returns {Promise<Array<object>>} The accessible company rows.
|
* @returns {Promise<Array<{id: number, name: string, rootCategoryId: number, languageId: number, iso639: string|null, taxrate: number, reducedtaxrate: number, taxfreerate: number}>>} The accessible company rows.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* const companies = await store.company.list(42);
|
* const companies = await store.company.list(42);
|
||||||
* // => [{ id, name, ... }]
|
* // => [{ id, name, rootCategoryId, languageId, iso639, taxrate, reducedtaxrate, taxfreerate }]
|
||||||
*/
|
*/
|
||||||
return async (googleAuthId, tx) => {
|
return async (googleAuthId, tx) => {
|
||||||
const result = await makeRunner(provider, tx).query(sql, { googleAuthId });
|
const result = await makeRunner(provider, tx).query(sql, { googleAuthId });
|
||||||
|
|||||||
Reference in New Issue
Block a user