From bb80cdf5a6157ca1f3a276e12e9faae9a4739cb7 Mon Sep 17 00:00:00 2001
From: dh_ackergaul <dh_ackergaul@dh-software.de>
Date: Di, 23 Jun 2026 11:16:18 +0200
Subject: [PATCH] Update emvheya - 23.6.2026, 11:16:10 [JD]

---
 manufacturer/_furnview/_global/html/h/generic-katatree/js/classes/article-list-builder.js |  250 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 155 insertions(+), 95 deletions(-)

diff --git a/manufacturer/_furnview/_global/html/h/generic-katatree/js/classes/article-list-builder.js b/manufacturer/_furnview/_global/html/h/generic-katatree/js/classes/article-list-builder.js
index 6a83406..a9b4eda 100644
--- a/manufacturer/_furnview/_global/html/h/generic-katatree/js/classes/article-list-builder.js
+++ b/manufacturer/_furnview/_global/html/h/generic-katatree/js/classes/article-list-builder.js
@@ -6,6 +6,27 @@
 /* JM [2023|January|26] ein cache in dem die generierten Merkmal-Container je nach context abgespeichert werden, damit diese nicht geloescht werden. Da die Ausfuehrungssteuerung kein dynamisches erstellen / loeschen von Merkmal-UIs unterstuetzt! */
 var artPropMerkmalCache = {};
 
+
+function getArtPropByArtCached(manu, prog, artNr) {
+    var key = manu + "\x1f" + prog + "\x1f" + artNr;
+    if (artPropByArtCache.hasOwnProperty(key)) {
+        return artPropByArtCache[key];
+    }
+    var result = FurnplanCommunicationService.GetArtPropByArt(manu, prog, [artNr]);
+    artPropByArtCache[key] = result;
+    return result;
+}
+
+function getDynEquipmentCached(manu, prog, artNr, manuCat) {
+    var key = manu + "\x1f" + prog + "\x1f" + artNr + "\x1f" + manuCat;
+    if (dynEquipmentCache.hasOwnProperty(key)) {
+        return dynEquipmentCache[key];
+    }
+    var result = FurnplanCommunicationService.GetDynEquipment(manu, prog, [artNr], manuCat);
+    dynEquipmentCache[key] = result;
+    return result;
+}
+
 // 0 = nichts
 // &1 = simple search -> hat zubehoer: ja/nein
 // &2 = detail search -> json infos je zuboeher
@@ -119,13 +140,13 @@
                 dhToDoParams[+artPropVar.key.replace("v", "")] = artPropVar.value.toString();
             }
         });
-        var vSelect = $("#artPropVarList_" + article.id.replace("/","")).find("select[data-vkey]");
+        var vSelect = $("#artPropVarList_" + article.id.replace("/", "")).find("select[data-vkey]");
         vSelect.each(function (index, input) {
             var input_value = parseFloat($(input).val().replace(",", "."));
             var input_vKey = +$(input).attr("data-vkey");
             dhToDoParams[input_vKey] = input_value.toString();
         });
-        var vInputs = $("#artPropVarList_" + article.id.replace("/","")).find("input[data-vkey]");
+        var vInputs = $("#artPropVarList_" + article.id.replace("/", "")).find("input[data-vkey]");
         vInputs.each(function (index, input) {
             var input_value = parseFloat($(input).val().replace(",", "."));
             var input_vKey = +$(input).attr("data-vkey");
@@ -169,10 +190,10 @@
             dhToDoParams[input_vKey] = input_value.toString();
         });
         if (doDhTodo) {
-            
+
             dhToDoParams[10] = article.manufacturerName;
             dhToDoParams[4] = article.programName;
-            dh_todo.apply(null, dhToDoParams);        
+            dh_todo.apply(null, dhToDoParams);
             dh_todo("3", "1", "0", "12028", "S", article.modName);
         }
     }
@@ -195,7 +216,7 @@
         }
         dhToDoParams[0] = "0";
         dhToDoParams[1] = artNo;
-        var id = "artPropVarList_" + artNo.replace("/","");
+        var id = "artPropVarList_" + artNo.replace("/", "");
         if (parentPoArtNr !== undefined) {
             id += "_" + parentPoArtNr;
         }
@@ -308,8 +329,8 @@
 }
 
 
-
 ArticleListBuilder.buildEquipment = function buildEquipment(article, cfg, container, toggleButton) {
+    var now = Date.now();
     var previouseActiveGroups = [];
     {
         container.find('.dhPtmButton.active').each(function (i, el) {
@@ -323,19 +344,19 @@
     if (useDynZub) {
         article.artPropTrans = [];
         article.artFittings = [];
-
         var dynamicEquipment = getArticleDynZub(article);
         if (typeof dynamicEquipment === "object") {
+            var fittingInfoByArtNr = buildIndexMap(fittingInfo, "artNr"); // O(1)-Lookup statt fittingInfo.find() je Fitting
+            var propTransInfoById = buildIndexMap(propTransInfo, "id"); // O(1)-Lookup statt propTransInfo.find() je PropTrans
             dynamicEquipment.fittings.forEach(function (fittingId) {
                 if (Article.checkFittingsByCfg(fittingId, cfg["ArtPropsToHide"], cfg["ArtPropsToShow"])) {
                     var f = new ArticleFitting(fittingId);
-                    var fittingArtPropData = FurnplanCommunicationService.GetArtPropByArt(currentManu, currentProg, [f.artNoFitting]);
+                    var fittingArtPropData = getArtPropByArtCached(currentManu, currentProg, f.artNoFitting);
+                    //var fittingArtPropData = FurnplanCommunicationService.GetArtPropByArt(currentManu, currentProg, f.artNoFitting);
                     if (fittingArtPropData.length > 0) {
                         f.controls = new ArticleFittingControl(fittingArtPropData[0].Vars, fittingId, article.artNo);
                     }
-                    var foundF = fittingInfo.find(function (fi) {
-                        return f.artNoFitting === fi.artNr;
-                    });
+                    var foundF = fittingInfoByArtNr["$" + f.artNoFitting];
                     if (foundF) {
                         f.jsAN = foundF.jsAN;
                         f.hideInsert = foundF.hideInsert;
@@ -351,9 +372,7 @@
             dynamicEquipment.propTransfer.forEach(function (propTransferId) {
                 if (Article.checkPropTransByCfg(propTransferId, cfg["ArtPropsToHide"], cfg["ArtPropsToShow"])) {
                     var p = new ArticlePropertyTrans(propTransferId);
-                    var foundP = propTransInfo.find(function (pti) {
-                        return p.id === pti.id;
-                    });
+                    var foundP = propTransInfoById["$" + p.id];
                     if (foundP) {
                         p.img = foundP.img;
                         p.text = foundP.text;
@@ -396,61 +415,12 @@
     var sortedGroups = [];
     var groupedArticles = { "unCatageorized": [] };
 
-    function pushInKeyArray(equipment) {
-        if (groupedArticles.hasOwnProperty(equipment.Cat)) {
-            groupedArticles[equipment.Cat].push(equipment);
-        } else {
-            groupedArticles[equipment.Cat] = [];
-            pushInKeyArray(equipment);
-        }
-    }
+    var artInfoTextCatById = buildIndexMap(definedArtInfoTextCategories, "id"); // O(1)-Lookup statt .find() je Equipment-Eintrag
 
-    //Zuebör in einer Kategorie sortieren, unabhängig davon ob es sich um dynamisches oder statisches Zubehör handelt
-    function sortEquipment(a, b) {
-        return a.orderIndex - b.orderIndex;
-    }
-
-    function renderGroup(key, containerElement) {
-        var group = false;
-        var groupElements = [];
-        if (cfg["useComboBoxForArtPropCategory"].indexOf(key) > -1) {
-            group = true;
-        }
-        groupedArticles[key].sort(sortEquipment);
-        groupedArticles[key].forEach(function (equipment, index) {
-            var isLast = false;
-            if (groupedArticles[key].length === index + 1) {
-                isLast = true;
-            }
-            if (group) {
-                groupElements.push(equipment);
-            }
-            else {
-                if (equipment instanceof ArticlePoEquipment) {
-                    containerElement.append(ArticleListBuilder.renderPoEquipmentContainer(equipment, equipment.artInfoTexts, cfg, true, isLast));
-                }
-                if (equipment instanceof ArticleShoppingCart) {
-                    containerElement.append(ArticleListBuilder.renderShoppingCartContainer(equipment, equipment.artInfoTexts, cfg, true, isLast));
-                }
-                if (equipment instanceof ArticleFitting) {
-                    containerElement.append(ArticleListBuilder.renderFittingContainer(equipment.imgURL(), equipment.artInfoTexts, equipment.artNoFitting, equipment.getText(), isLast, index === 0, cfg, equipment.hideDelete, equipment.hideInsert, equipment.hideFront, equipment.hideRefresh, equipment.hideMove, true, equipment.controls));
-                }
-                if (equipment instanceof ArticlePropertyTrans) {
-                    if (!equipment.ptm) {
-                        containerElement.append(ArticleListBuilder.renderProptransContainer(equipment.imgURL(), equipment.artInfoTexts, equipment.img, equipment.id, equipment.getText(), equipment.controls, equipment.hideDelete, equipment.hideFront, true, equipment.artNo, isLast));
-                    }
-                }
-            }
-        })
-        if (group) {
-            containerElement.append(ArticleListBuilder.getArtPropComboBoxContainer(groupElements, cfg));
-        }
-    }
-
-
+    timeline(Date.now(), "1111");
     article.artFittings.forEach(function (f, index) {
         if (!f.hideFittingbyAN) {
-            var fiInfo = FurnplanCommunicationService.GetDynEquipment(getCurrentManu(), f.prog, f.artNoFitting, article.selectedProgGroup);
+            var fiInfo = getDynEquipmentCached(getCurrentManu(), f.prog, f.artNoFitting, article.selectedProgGroup);
             if (fiInfo.rows) {
                 fiInfo.rows.forEach(function (fi) {
                     if (fi) {
@@ -476,6 +446,36 @@
                     }
                 })
             }
+            //var fiInfo = getDynEquipmentCached(getCurrentManu(), f.prog, f.artNoFitting, article.selectedProgGroup);
+            //var key = getCurrentManu() + "\x1f" + f.prog + "\x1f" + f.artNoFitting + "\x1f" + article.selectedProgGroup;
+            // var key = "KEY" + f.artNoFitting;
+            // var fiInfo = article.mod.dynEquipmentCache[key];
+            // if (fiInfo) {
+            //     fiInfo.forEach(function (fi) {
+            //         if (fi) {
+            //             f.orderIndex = fi.id;
+            //             if (fi.Cat.startsWith("dhartinfo_")) {
+            //                 var foundCategory = artInfoTextCatById["$" + fi.Cat];
+            //                 if (foundCategory) {
+            //                     f.artInfoTexts.push(foundCategory);
+            //                 }
+            //                 if (fiInfo.length === 1) {
+            //                         groupedArticles["unCatageorized"].push(pt);
+            //                     }
+            //             }
+            //             else {
+            //                 if (fi.Cat !== "" && !fi.Cat.startsWith("dhartinfo_")) {
+            //                     // In kategorisiert reinpacken
+            //                     f.Cat = fi.Cat;
+            //                     pushInKeyArray(f);
+            //                 } else {
+            //                     // In nicht kategorisiert reinpacken
+            //                     groupedArticles["unCatageorized"].push(f);
+            //                 }
+            //             }
+            //         }
+            //     })
+            // }
         }
     });
 
@@ -486,17 +486,20 @@
                 // In nicht kategorisiert reinpacken wenn in Spalte B nichts eingetragen weil die Eigenschaftsübertragung dann nicht kategorisiert sei kann
                 groupedArticles["unCatageorized"].push(pt);
             } else {
-                var piInfo = FurnplanCommunicationService.GetDynEquipment(getCurrentManu(), pt.prog, pt.artNo, article.selectedProgGroup);
-                if (piInfo.rows) {
+                var piInfo = getDynEquipmentCached(getCurrentManu(), pt.prog, pt.artNo, article.selectedProgGroup);
+                // var key = "KEY" + pt.artNo;
+                // var piInfo = article.mod.dynEquipmentCache[key];
+                if (piInfo) {
                     piInfo.rows.forEach(function (pi) {
                         if (pi) {
                             pt.orderIndex = pi.id;
                             if (pi.Cat.startsWith("dhartinfo_")) {
-                                var foundCategory = definedArtInfoTextCategories.find(function (cat) {
-                                    return cat.id === pi.Cat;
-                                });
+                                var foundCategory = artInfoTextCatById["$" + pi.Cat];
                                 if (foundCategory) {
                                     pt.artInfoTexts.push(foundCategory);
+                                }
+                                if (piInfo.length === 1) {
+                                    groupedArticles["unCatageorized"].push(pt);
                                 }
                             } else {
                                 if (pi.Cat !== "" && !pi.Cat.startsWith("dhartinfo_")) {
@@ -519,8 +522,10 @@
         } else {
             pt.hasNoCategory = true;
             if (pt.artNo !== "") {
-                var piInfo = FurnplanCommunicationService.GetDynEquipment(getCurrentManu(), pt.prog, pt.artNo, article.selectedProgGroup);
-                if (piInfo.rows) {
+                var piInfo = getDynEquipmentCached(getCurrentManu(), pt.prog, pt.artNo, article.selectedProgGroup);
+                // var key = "KEY" + pt.artNo;
+                // var piInfo = article.mod.dynEquipmentCache[key];
+                if (piInfo) {
                     piInfo.rows.forEach(function (pi) {
                         if (pi) {
                             if (pi.Cat !== "" && !pi.Cat.startsWith("dhartinfo_")) {
@@ -537,19 +542,17 @@
         }
     });
 
-
-
     article.artShoppingCartArticles.forEach(function (sc, index) {
-        var siInfo = FurnplanCommunicationService.GetDynEquipment(getCurrentManu(), sc.prog, sc.artNo, article.selectedProgGroup);
-        if (siInfo.rows) {
-            siInfo.rows.forEach(function (si) {
+        // var siInfo = getDynEquipmentCached(getCurrentManu(), sc.prog, sc.artNo, article.selectedProgGroup);
+        var key = "KEY" + sc.artNo;
+        var siInfo = article.mod.dynEquipmentCache[key];
+        if (siInfo) {
+            siInfo.forEach(function (si) {
                 if (si) {
                     sc.orderIndex = si.id;
                     //ArtInfotexte abfangen
                     if (si.Cat.startsWith("dhartinfo_")) {
-                        var foundCategory = definedArtInfoTextCategories.find(function (cat) {
-                            return cat.id === si.Cat;
-                        });
+                        var foundCategory = artInfoTextCatById["$" + si.Cat];
                         if (foundCategory) {
                             sc.artInfoTexts.push(foundCategory);
                         }
@@ -568,18 +571,19 @@
         }
 
     });
+
     article.artPoEquipment.forEach(function (poe, index) {
         var isAdded = false;
-        var poInfo = FurnplanCommunicationService.GetDynEquipment(getCurrentManu(), poe.prog, poe.artNo, article.selectedProgGroup);
-        if (poInfo.rows) {
-            poInfo.rows.forEach(function (poi) {
+        //var poInfo = getDynEquipmentCached(getCurrentManu(), poe.prog, poe.artNo, article.selectedProgGroup);
+        var key = "KEY" + poe.artNo;
+        var poInfo = article.mod.dynEquipmentCache[key];
+        if (poInfo) {
+            poInfo.forEach(function (poi) {
                 if (poi) {
                     poe.orderIndex = poi.id;
                     //ArtInfotexte abfangen
                     if (poi.Cat.startsWith("dhartinfo_")) {
-                        var foundCategory = definedArtInfoTextCategories.find(function (cat) {
-                            return cat.id === poi.Cat;
-                        });
+                        var foundCategory = artInfoTextCatById["$" + poi.Cat];
                         if (foundCategory) {
                             poe.artInfoTexts.push(foundCategory);
                         }
@@ -612,6 +616,9 @@
             })
         }
     });
+    timeline(Date.now(), "2222");
+
+
 
 
     Object.keys(groupedArticles).forEach(function (key, index) {
@@ -688,11 +695,6 @@
         }
     });
 
-
-
-
-
-
     var closeEquipment = $('<div class="dhEquipmentClose"></div>');
     closeEquipment.click(function () {
         var scrollPos = $(window).scrollTop();
@@ -701,6 +703,60 @@
         toggleButton.trigger("click", {});
     });
     container.append(closeEquipment);
+
+
+    function pushInKeyArray(equipment) {
+        if (groupedArticles.hasOwnProperty(equipment.Cat)) {
+            groupedArticles[equipment.Cat].push(equipment);
+        } else {
+            groupedArticles[equipment.Cat] = [];
+            pushInKeyArray(equipment);
+        }
+    }
+
+    //Zuebör in einer Kategorie sortieren, unabhängig davon ob es sich um dynamisches oder statisches Zubehör handelt
+    function sortEquipment(a, b) {
+        return a.orderIndex - b.orderIndex;
+    }
+
+    function renderGroup(key, containerElement) {
+        var group = false;
+        var groupElements = [];
+        if (cfg["useComboBoxForArtPropCategory"].indexOf(key) > -1) {
+            group = true;
+        }
+        groupedArticles[key].sort(sortEquipment);
+        groupedArticles[key].forEach(function (equipment, index) {
+            var isLast = false;
+            if (groupedArticles[key].length === index + 1) {
+                isLast = true;
+            }
+            if (group) {
+                groupElements.push(equipment);
+            }
+            else {
+                if (equipment instanceof ArticlePoEquipment) {
+                    containerElement.append(ArticleListBuilder.renderPoEquipmentContainer(equipment, equipment.artInfoTexts, cfg, true, isLast));
+                }
+                if (equipment instanceof ArticleShoppingCart) {
+                    containerElement.append(ArticleListBuilder.renderShoppingCartContainer(equipment, equipment.artInfoTexts, cfg, true, isLast));
+                }
+                if (equipment instanceof ArticleFitting) {
+                    containerElement.append(ArticleListBuilder.renderFittingContainer(equipment.imgURL(), equipment.artInfoTexts, equipment.artNoFitting, equipment.getText(), isLast, index === 0, cfg, equipment.hideDelete, equipment.hideInsert, equipment.hideFront, equipment.hideRefresh, equipment.hideMove, true, equipment.controls));
+                }
+                if (equipment instanceof ArticlePropertyTrans) {
+                    if (!equipment.ptm) {
+                        containerElement.append(ArticleListBuilder.renderProptransContainer(equipment.imgURL(), equipment.artInfoTexts, equipment.img, equipment.id, equipment.getText(), equipment.controls, equipment.hideDelete, equipment.hideFront, true, equipment.artNo, isLast));
+                    }
+                }
+            }
+        })
+        if (group) {
+            containerElement.append(ArticleListBuilder.getArtPropComboBoxContainer(groupElements, cfg));
+        }
+    }
+
+
 };
 
 
@@ -1054,8 +1110,12 @@
 
                     console.log("click on:", window.currentEquipmentMap, articleModes);
                 }
-
+                timeline(Date.now(), "Start buildEquipment");
                 ArticleListBuilder.buildEquipment(article, cfg, container, toggleArtProps);
+                timeline(Date.now(), "Stop buildEquipment");
+                genKataTreeTimeLine.forEach(function (params) {
+                    console.log("date: " + params.date + " Text: " + params.text);
+                })
                 if (useDynZub) {
                     onEquipmentChangeListeners[article.artNo] = ArticleListBuilder.buildEquipment.bind(this, article, cfg, container, toggleArtProps);
                 }
@@ -1123,7 +1183,7 @@
 
     if (showArtPropVars) {
         var artPropVarList = $("<div class='artPropVarList'></div>");
-        artPropVarList.attr("id", "artPropVarList_" + article.id.replace("/",""));
+        artPropVarList.attr("id", "artPropVarList_" + article.id.replace("/", ""));
         article.artPropVars.forEach(function (artProp) {
             var artPropVarItem = $('<div class="artPropVarItem"></div>');
             var artPropCellHeader = $('<div class="artPropCellHeader"></div>');
@@ -1185,7 +1245,7 @@
             if (article.subHingeArticle.artPropVars.length > 0) {
                 fourthRow.addClass("hasHinge");
                 var artPropVarList = $("<div class='artPropVarList'></div>");
-                artPropVarList.attr("id", "artPropVarList_" + article.subHingeArticle.id.replace("/",""));
+                artPropVarList.attr("id", "artPropVarList_" + article.subHingeArticle.id.replace("/", ""));
                 article.subHingeArticle.artPropVars.forEach(function (artProp) {
                     var artPropVarItem = $('<div class="artPropVarItem"></div>');
                     var artPropCellHeader = $('<div class="artPropCellHeader" ></div>');

--
Gitblit v1.9.3