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"