From 4f0c493a7f6044506beb26a46efa18ae0c3e1267 Mon Sep 17 00:00:00 2001 From: DaTweety <129504390+DaTweety@users.noreply.github.com> Date: Sun, 18 Oct 2026 11:05:16 +0200 Subject: [PATCH] Nomenclature: an element is where its folio is element_nomenclature_view gave an element's own plant and location only, which are empty unless typed into every element. A project structured by its folios (=plant +location on the title block, %M / %LM) therefore showed no place in the BOM, nomenclature tables and queries, although the folio says where each device is -- the way EPLAN builds the device tag from the page structure. The view now falls back to the folio's plant and location when the element has none of its own. Co-Authored-By: Claude Opus 5.5 --- misc/qet-mcp/test_qet_mcp.py | 19 +++++++++++++++++++ sources/dataBase/projectdatabase.cpp | 13 +++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/misc/qet-mcp/test_qet_mcp.py b/misc/qet-mcp/test_qet_mcp.py index 8358ef5b7..d3ecccfc7 100644 --- a/misc/qet-mcp/test_qet_mcp.py +++ b/misc/qet-mcp/test_qet_mcp.py @@ -4602,6 +4602,25 @@ class Integration(unittest.TestCase): self.assertEqual(len(styles), 1, styles) self.assertIn("dash", styles.pop()) + def test_nomenclature_takes_the_place_of_the_folio(self): + """An element without its own plant / location is where its folio + is: element_nomenclature_view (BOM, nomenclature tables) shows the + folio's =plant +location; an element's own value still wins.""" + base = self.sb.new() + ops = [{"op": "add_folio", "id": "f"}, + {"op": "set_folio", "folio": "$f", "property": "plant", "value": "HAUS"}, + {"op": "set_folio", "folio": "$f", "property": "locmach", "value": "UV1"}, + {"op": "add_element", "id": "a", "folio": "$f", "path": COIL, "x": 100, "y": 100}, + {"op": "set_label", "folio": "$f", "element": "$a", "label": "KA1"}, + {"op": "add_element", "id": "b", "folio": "$f", "path": COIL, "x": 300, "y": 100}, + {"op": "set_label", "folio": "$f", "element": "$b", "label": "KA2"}, + {"op": "set_info", "folio": "$f", "element": "$b", "key": "location", "value": "UV2"}] + r = self.ok(self.sb.edit(base, ops)) + q = m.tool_query(BINARY, r["output"], "SELECT label, plant, location FROM " + "element_nomenclature_view ORDER BY label") + self.assertEqual(q["rows"], [{"label": "KA1", "plant": "HAUS", "location": "UV1"}, + {"label": "KA2", "plant": "HAUS", "location": "UV2"}]) + # ---- conductor manual routing ---- def test_move_conductor_segment_reroutes_the_path(self): diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index b2b9d3da3..28e04971b 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -2804,10 +2804,15 @@ bool projectDataBase::createDataBase() */ void projectDataBase::createElementNomenclatureView() { + //plant and location: the element's own, else its folio's. An + //installation is structured by its folios (=plant +location, the + //%M / %LM of the folio), as EPLAN builds the device tag from the + //page structure: an element drawn on a +UV1 folio is in +UV1 + //without the information being typed into every element. QString create_view ("CREATE VIEW element_nomenclature_view AS SELECT " "ei.label AS label," - "ei.plant AS plant," - "ei.location AS location," + "COALESCE(NULLIF(ei.plant, ''), di.plant) AS plant," + "COALESCE(NULLIF(ei.location, ''), di.locmach) AS location," "ei.comment AS comment," "ei.function AS function," "ei.description AS description," @@ -2908,6 +2913,10 @@ void projectDataBase::createElementNomenclatureView() columns_.replace(QStringLiteral("e.sub_type AS element_sub_type"), QStringLiteral("NULL AS element_sub_type")); columns_.replace(QStringLiteral("di.title AS title"), QStringLiteral("st.title AS title")); columns_.replace(QStringLiteral("di.folio AS folio"), QStringLiteral("st.folio AS folio")); + //A spare terminal is on no folio: no folio plant or location + //to fall back to, its own value as before + columns_.replace(QStringLiteral("di.plant"), QStringLiteral("''")); + columns_.replace(QStringLiteral("di.locmach"), QStringLiteral("''")); columns_.replace(QStringLiteral("e.pos AS position"), QStringLiteral("st.position AS position")); create_view += QStringLiteral(" UNION ALL SELECT ") + columns_ + QStringLiteral(" FROM spare_terminal st"