feat: Implement category and product filtering in UI, add category exclusion, and refine product synchronization with active status and improved rowversion

This commit is contained in:
sebseb7
2025-11-24 09:16:33 +01:00
parent 320bcd4641
commit b743fabc80
4 changed files with 350 additions and 104 deletions

View File

@@ -30,7 +30,9 @@ export function registerImages(app, cacheDir) {
}
}, (err) => {
if (err) {
console.error(`❌ Error serving image ${resolvedPath}:`, err);
if (err.code !== 'ENOENT') {
console.error(`❌ Error serving image ${resolvedPath}:`, err);
}
if (!res.headersSent) {
res.status(404).send('Image not found');
}

View File

@@ -113,10 +113,17 @@ class CategoryProductsSyncer extends EventEmitter {
JOIN tArtikelBeschreibung ab ON ka.kArtikel = ab.kArtikel
JOIN tArtikel a ON ka.kArtikel = a.kArtikel
WHERE ab.kSprache = ${process.env.JTL_SPRACHE_ID}
AND a.cAktiv = 'Y'
AND ab.kPlattform = ${process.env.JTL_PLATTFORM_ID}
AND ab.kShop = ${process.env.JTL_SHOP_ID}
AND ka.kKategorie IN (${list})
ORDER BY (CASE WHEN a.bRowversion > ab.bRowversion THEN a.bRowversion ELSE ab.bRowversion END) DESC
ORDER BY (
CASE
WHEN a.bRowversion >= ab.bRowversion AND a.bRowversion >= ka.bRowversion THEN a.bRowversion
WHEN ab.bRowversion >= a.bRowversion AND ab.bRowversion >= ka.bRowversion THEN ab.bRowversion
ELSE ka.bRowversion
END
) DESC
`);
// Collect all kArtikel IDs to fetch images

View File

@@ -88,6 +88,7 @@ class CategorySyncer extends EventEmitter {
const categoriesResult = await pool.request().query(`
SELECT kKategorie, kOberKategorie, nSort
FROM tkategorie
ORDER BY nSort, kKategorie
`);
// Fetch names
@@ -201,8 +202,19 @@ class CategorySyncer extends EventEmitter {
const rootNodes = [];
// Parse excluded IDs
const excludedIds = new Set(
(process.env.EXCLUDE_CATEGORY_IDS || '')
.split(',')
.map(id => parseInt(id.trim()))
.filter(id => !isNaN(id))
);
// Build hierarchy
categories.forEach(cat => {
// Skip if excluded
if (excludedIds.has(cat.kKategorie)) return;
const node = categoryMap.get(cat.kKategorie);
if (cat.kOberKategorie === 0) {
rootNodes.push(node);
@@ -221,18 +233,22 @@ class CategorySyncer extends EventEmitter {
let resultNodes = rootNodes;
if (rootId && applyRootFilter) {
const specificRoot = categoryMap.get(rootId);
// Return the children of the specified root, not the root itself
resultNodes = specificRoot ? specificRoot.children : [];
if (excludedIds.has(rootId)) {
resultNodes = [];
} else {
const specificRoot = categoryMap.get(rootId);
// Return the children of the specified root, not the root itself
resultNodes = specificRoot ? specificRoot.children : [];
}
}
// Sort children and remove nSort
for (const node of categoryMap.values()) {
node.children.sort((a, b) => a.nSort - b.nSort);
node.children.sort((a, b) => a.nSort - b.nSort || a.kKategorie - b.kKategorie);
}
// Sort root nodes if returning multiple
resultNodes.sort((a, b) => a.nSort - b.nSort);
resultNodes.sort((a, b) => a.nSort - b.nSort || a.kKategorie - b.kKategorie);
// Remove nSort property from all nodes
for (const node of categoryMap.values()) {