From 72cf77690e853d279a37289c1de8c16075ca979f Mon Sep 17 00:00:00 2001 From: Andrej Date: Fri, 6 Jun 2025 14:32:53 +0500 Subject: [PATCH] Prevent removing rel when is still valid after IfcCostItem removal #6769 --- .../ifcopenshell/api/cost/remove_cost_item.py | 2 ++ .../test/api/cost/test_remove_cost_item.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/remove_cost_item.py b/src/ifcopenshell-python/ifcopenshell/api/cost/remove_cost_item.py index b5acaaf1cc..ce1aa5545e 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/cost/remove_cost_item.py +++ b/src/ifcopenshell-python/ifcopenshell/api/cost/remove_cost_item.py @@ -51,6 +51,8 @@ def remove_cost_item(file: ifcopenshell.file, cost_item: ifcopenshell.entity_ins if history: ifcopenshell.util.element.remove_deep2(file, history) elif inverse.is_a("IfcRelAssignsToControl"): + if len(inverse.RelatedObjects) >= 2 or inverse.RelatingControl == cost_item: + continue history = inverse.OwnerHistory file.remove(inverse) if history: diff --git a/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py b/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py index b581afffbc..a987063769 100644 --- a/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py +++ b/src/ifcopenshell-python/test/api/cost/test_remove_cost_item.py @@ -46,6 +46,16 @@ class TestRemoveCostItem(test.bootstrap.IFC4): assert not self.file.by_type("IfcRelAssignsToControl") assert not self.file.by_type("IfcRelNests") + def test_remove_cost_item_keep_rel_for_other_cost_items(self): + schedule = ifcopenshell.api.cost.add_cost_schedule(self.file, name="Foo", predefined_type="BUDGET") + item1 = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule) + item2 = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule) + ifcopenshell.api.cost.remove_cost_item(self.file, cost_item=item1) + assert self.file.by_type("IfcCostItem") == [item2] + rel = next(iter(self.file.by_type("IfcRelAssignsToControl")), None) + assert rel + assert rel.RelatedObjects == (item2,) + class TestRemoveCostItemIFC2X3(test.bootstrap.IFC2X3, TestRemoveCostItem): pass