search
This commit is contained in:
@@ -13,7 +13,7 @@ export function register(app, basePath = '') {
|
|||||||
* @query {string} [filter] - Optional comma-separated category filter IDs (empty = all)
|
* @query {string} [filter] - Optional comma-separated category filter IDs (empty = all)
|
||||||
* @query {number} [offset=0] - Number of results to skip
|
* @query {number} [offset=0] - Number of results to skip
|
||||||
* @query {number} [maxCount=10] - Maximum number of results to return
|
* @query {number} [maxCount=10] - Maximum number of results to return
|
||||||
* @returns {Object} 200 - `{ katagg, length, recordset }`
|
* @returns {Object} 200 - `{ categories, length, recordset }`
|
||||||
* @returns {Object} 400 - `{ error }` when target is missing
|
* @returns {Object} 400 - `{ error }` when target is missing
|
||||||
*/
|
*/
|
||||||
app.get(`${basePath}/article/search`, async (req, res) => {
|
app.get(`${basePath}/article/search`, async (req, res) => {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { getPool } from '../../db/mssqlClient.js';
|
import { getPool } from '../../db/mssqlClient.js';
|
||||||
import { LOAD_KAT_MAP } from '../../db/mssql/categories.js';
|
import { LOAD_CATEGORIES } from '../../db/mssql/categories.js';
|
||||||
import * as Q from '../../db/mssql/searchArticles.js';
|
import * as Q from '../../db/mssql/searchArticles.js';
|
||||||
import { bruttoFromNetto, loadSteuersatz } from '../misc/getSteuer.js';
|
import { bruttoFromNetto, loadSteuersatz } from '../misc/getSteuer.js';
|
||||||
|
|
||||||
let katMapCache;
|
let categoryCache;
|
||||||
|
|
||||||
export function parseFilter(raw) {
|
export function parseFilter(raw) {
|
||||||
if (raw === undefined || raw === null || raw === '') {
|
if (raw === undefined || raw === null || raw === '') {
|
||||||
@@ -13,47 +13,68 @@ export function parseFilter(raw) {
|
|||||||
return parts.length ? parts : [''];
|
return parts.length ? parts : [''];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUpPath(kat, katMap) {
|
function getUpPath(kat, parentMap) {
|
||||||
const list = [kat];
|
const list = [kat];
|
||||||
if (katMap[kat]) {
|
if (parentMap[kat]) {
|
||||||
for (const item of getUpPath(katMap[kat], katMap)) {
|
for (const item of getUpPath(parentMap[kat], parentMap)) {
|
||||||
list.push(item);
|
list.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadKatMap(pool) {
|
async function loadCategoryCache(pool) {
|
||||||
if (katMapCache) {
|
if (categoryCache) {
|
||||||
return katMapCache;
|
return categoryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await pool.request().query(LOAD_KAT_MAP);
|
const result = await pool.request().query(LOAD_CATEGORIES);
|
||||||
katMapCache = {};
|
const byId = {};
|
||||||
|
const parentMap = {};
|
||||||
for (const item of result.recordset) {
|
for (const item of result.recordset) {
|
||||||
katMapCache[item.kKategorie] = item.kOberKategorie;
|
byId[item.kKategorie] = {
|
||||||
|
name: item.cName ?? null,
|
||||||
|
parent: item.kOberKategorie,
|
||||||
|
};
|
||||||
|
parentMap[item.kKategorie] = item.kOberKategorie;
|
||||||
}
|
}
|
||||||
return katMapCache;
|
categoryCache = { byId, parentMap };
|
||||||
|
return categoryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildKatAgg(recordset, katMap) {
|
function buildKatAgg(recordset, parentMap) {
|
||||||
const katagg = {};
|
const counts = {};
|
||||||
|
|
||||||
for (const item of recordset) {
|
for (const item of recordset) {
|
||||||
if (!item.katList) {
|
if (!item.katList) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (const kat of item.katList.split(',')) {
|
for (const kat of item.katList.split(',')) {
|
||||||
for (const katpart of getUpPath(kat, katMap)) {
|
for (const katpart of getUpPath(kat, parentMap)) {
|
||||||
if (!katagg[katpart]) {
|
if (!counts[katpart]) {
|
||||||
katagg[katpart] = 0;
|
counts[katpart] = 0;
|
||||||
}
|
}
|
||||||
katagg[katpart]++;
|
counts[katpart]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return katagg;
|
return counts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function shapeCategories(counts, byId) {
|
||||||
|
const categories = {};
|
||||||
|
|
||||||
|
for (const [id, count] of Object.entries(counts)) {
|
||||||
|
const meta = byId[id] ?? {};
|
||||||
|
categories[id] = {
|
||||||
|
count,
|
||||||
|
name: meta.name ?? null,
|
||||||
|
parent: meta.parent ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
function shapeArticle(row, steuersaetze) {
|
function shapeArticle(row, steuersaetze) {
|
||||||
@@ -61,7 +82,7 @@ function shapeArticle(row, steuersaetze) {
|
|||||||
const brutto = bruttoFromNetto(row.fVKNEtto, row.kSteuerklasse, steuersaetze);
|
const brutto = bruttoFromNetto(row.fVKNEtto, row.kSteuerklasse, steuersaetze);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
katList: row.katList,
|
categories: row.katList,
|
||||||
available: row.fVerfuegbar,
|
available: row.fVerfuegbar,
|
||||||
id: row.kArtikel,
|
id: row.kArtikel,
|
||||||
stock: row.fBestand,
|
stock: row.fBestand,
|
||||||
@@ -140,7 +161,7 @@ function buildQuery(filter, categoryFilter) {
|
|||||||
export async function searchArticles(target, filter = [''], offset = 0, maxCount = 10) {
|
export async function searchArticles(target, filter = [''], offset = 0, maxCount = 10) {
|
||||||
const trimmed = target?.toString().trim();
|
const trimmed = target?.toString().trim();
|
||||||
if (!trimmed) {
|
if (!trimmed) {
|
||||||
return { katagg: {}, length: 0, recordset: [] };
|
return { categories: {}, length: 0, recordset: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
const start = Math.max(0, Number(offset) || 0);
|
const start = Math.max(0, Number(offset) || 0);
|
||||||
@@ -159,17 +180,20 @@ export async function searchArticles(target, filter = [''], offset = 0, maxCount
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await request.query(sql);
|
const result = await request.query(sql);
|
||||||
const [katMap, steuersaetze] = await Promise.all([
|
const [categoryData, steuersaetze] = await Promise.all([
|
||||||
loadKatMap(pool),
|
loadCategoryCache(pool),
|
||||||
loadSteuersatz(),
|
loadSteuersatz(),
|
||||||
]);
|
]);
|
||||||
const katagg = buildKatAgg(result.recordset, katMap);
|
const categories = shapeCategories(
|
||||||
|
buildKatAgg(result.recordset, categoryData.parentMap),
|
||||||
|
categoryData.byId
|
||||||
|
);
|
||||||
const length = result.recordset.length;
|
const length = result.recordset.length;
|
||||||
const recordset = result.recordset
|
const recordset = result.recordset
|
||||||
.slice(start, start + count)
|
.slice(start, start + count)
|
||||||
.map((row) => shapeArticle(row, steuersaetze));
|
.map((row) => shapeArticle(row, steuersaetze));
|
||||||
|
|
||||||
console.dir({ katagg, length, recordset }, { depth: null });
|
console.dir({ categories, length, recordset }, { depth: null });
|
||||||
|
|
||||||
return { katagg, length, recordset };
|
return { categories, length, recordset };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user