From c76785e02cccc598668af5bf46405a749dd91a4d Mon Sep 17 00:00:00 2001 From: Andrej Date: Fri, 6 Jun 2025 17:58:52 +0500 Subject: [PATCH] tool.cost - refactor expand/contract rates methods So they will be more similar --- src/bonsai/bonsai/bim/module/cost/operator.py | 4 +-- src/bonsai/bonsai/core/cost.py | 22 +++++++++----- src/bonsai/bonsai/core/tool.py | 4 +-- src/bonsai/bonsai/tool/cost.py | 29 ++++++++++--------- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/cost/operator.py b/src/bonsai/bonsai/bim/module/cost/operator.py index 963d33e0e9..c6dd73598a 100644 --- a/src/bonsai/bonsai/bim/module/cost/operator.py +++ b/src/bonsai/bonsai/bim/module/cost/operator.py @@ -154,7 +154,7 @@ class ExpandCostItem(bpy.types.Operator, tool.Ifc.Operator): cost_item: int def _execute(self, context): - core.expand_cost_item(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item)) + core.expand_cost_item(tool.Cost, cost_item_id=self.cost_item) class ExpandCostItems(bpy.types.Operator, tool.Ifc.Operator): @@ -179,7 +179,7 @@ class ContractCostItem(bpy.types.Operator, tool.Ifc.Operator): cost_item: int def _execute(self, context): - core.contract_cost_item(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item)) + core.contract_cost_item(tool.Cost, cost_item_id=self.cost_item) class ContractCostItems(bpy.types.Operator, tool.Ifc.Operator): diff --git a/src/bonsai/bonsai/core/cost.py b/src/bonsai/bonsai/core/cost.py index b0ede21948..5da4a826ac 100644 --- a/src/bonsai/bonsai/core/cost.py +++ b/src/bonsai/bonsai/core/cost.py @@ -76,8 +76,8 @@ def add_cost_item(ifc: type[tool.Ifc], cost: type[tool.Cost], cost_item: ifcopen # cost.enable_editing_cost_schedule_attributes(cost_schedule) -def expand_cost_item(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None: - cost.expand_cost_item(cost_item) +def expand_cost_item(cost: type[tool.Cost], cost_item_id: int) -> None: + cost.expand_cost_item(cost_item_id) cost.load_cost_schedule_tree() @@ -86,8 +86,8 @@ def expand_cost_items(cost: type[tool.Cost]) -> None: cost.load_cost_schedule_tree() -def contract_cost_item(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None: - cost.contract_cost_item(cost_item) +def contract_cost_item(cost: type[tool.Cost], cost_item_id: int) -> None: + cost.contract_cost_item(cost_item_id) cost.load_cost_schedule_tree() @@ -368,12 +368,18 @@ def remove_cost_column(cost: type[tool.Cost], name: str) -> None: cost.remove_cost_column(name) -def expand_cost_item_rate(cost: type[tool.Cost], cost_item: int) -> None: - cost.expand_cost_item_rate(cost_item) +def expand_cost_item_rate(cost: type[tool.Cost], cost_item_id: int) -> None: + cost.expand_cost_item_rate(cost_item_id) + schedule_of_rates = cost.get_active_schedule_of_rates() + assert schedule_of_rates + cost.load_schedule_of_rates_tree(schedule_of_rates) -def contract_cost_item_rate(cost: type[tool.Cost], cost_item: int) -> None: - cost.contract_cost_item_rate(cost_item) +def contract_cost_item_rate(cost: type[tool.Cost], cost_item_id: int) -> None: + cost.contract_cost_item_rate(cost_item_id) + schedule_of_rates = cost.get_active_schedule_of_rates() + assert schedule_of_rates + cost.load_schedule_of_rates_tree(schedule_of_rates) def calculate_cost_item_resource_value(ifc: type[tool.Ifc], cost_item: ifcopenshell.entity_instance) -> None: diff --git a/src/bonsai/bonsai/core/tool.py b/src/bonsai/bonsai/core/tool.py index d8ccba3c28..ea149f0ff6 100644 --- a/src/bonsai/bonsai/core/tool.py +++ b/src/bonsai/bonsai/core/tool.py @@ -203,7 +203,7 @@ class Cost: def change_parent_cost_item(cls, cost_item, new_parent): pass def clean_up_cost_item_tree(cls, cost_item): pass def contract_cost_item_rate(cls, cost_item): pass - def contract_cost_item(cls, cost_item): pass + def contract_cost_item(cls, cost_item_id): pass def contract_cost_items(cls): pass def create_new_cost_item_li(props_collection, cost_item, level_index, type): pass def disable_editing_cost_item_parent(cls): pass @@ -220,7 +220,7 @@ class Cost: def enable_editing_cost_items(cls, cost_schedule): pass def enable_editing_cost_schedule_attributes(cls, cost_schedule): pass def expand_cost_item_rate(cls, cost_item): pass - def expand_cost_item(cls, cost_item): pass + def expand_cost_item(cls, cost_item_id): pass def expand_cost_items(cls): pass def export_cost_schedules(cls, filepath, format, cost_schedule): pass def format_unit(cls, unit): pass diff --git a/src/bonsai/bonsai/tool/cost.py b/src/bonsai/bonsai/tool/cost.py index 0e80a44630..a41f57b24d 100644 --- a/src/bonsai/bonsai/tool/cost.py +++ b/src/bonsai/bonsai/tool/cost.py @@ -38,6 +38,8 @@ if TYPE_CHECKING: class Cost(bonsai.core.tool.Cost): RELATED_OBJECT_TYPE = Literal["PRODUCT", "PROCESS", "RESOURCE"] + + # TODO: Do we really need them cached as class attributes? contracted_cost_items: list[int] """List of contracted cost item ids.""" @@ -169,12 +171,12 @@ class Cost(bonsai.core.tool.Cost): props.is_cost_update_enabled = True @classmethod - def expand_cost_item(cls, cost_item: ifcopenshell.entity_instance) -> None: + def expand_cost_item(cls, cost_item_id: int) -> None: props = cls.get_cost_props() if not hasattr(cls, "contracted_cost_items"): cls.contracted_cost_items = json.loads(props.contracted_cost_items) - if cost_item.id() in cls.contracted_cost_items: - cls.contracted_cost_items.remove(cost_item.id()) + if cost_item_id in cls.contracted_cost_items: + cls.contracted_cost_items.remove(cost_item_id) props.contracted_cost_items = json.dumps(cls.contracted_cost_items) @classmethod @@ -187,11 +189,11 @@ class Cost(bonsai.core.tool.Cost): props.contracted_cost_items = json.dumps(cls.contracted_cost_items) @classmethod - def contract_cost_item(cls, cost_item: ifcopenshell.entity_instance) -> None: + def contract_cost_item(cls, cost_item_id: int) -> None: props = cls.get_cost_props() if not hasattr(cls, "contracted_cost_items"): cls.contracted_cost_items = json.loads(props.contracted_cost_items) - cls.contracted_cost_items.append(cost_item.id()) + cls.contracted_cost_items.append(cost_item_id) props.contracted_cost_items = json.dumps(cls.contracted_cost_items) @classmethod @@ -669,18 +671,19 @@ class Cost(bonsai.core.tool.Cost): @classmethod def expand_cost_item_rate(cls, cost_item_id: int) -> None: props = cls.get_cost_props() - contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates) - contracted_cost_item_rates.remove(cost_item_id) - props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates) - cls.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates))) + if not hasattr(cls, "contracted_cost_item_rates"): + cls.contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates) + if cost_item_id in cls.contracted_cost_item_rates: + cls.contracted_cost_item_rates.remove(cost_item_id) + props.contracted_cost_item_rates = json.dumps(cls.contracted_cost_item_rates) @classmethod def contract_cost_item_rate(cls, cost_item_id: int) -> None: props = cls.get_cost_props() - contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates) - contracted_cost_item_rates.append(cost_item_id) - props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates) - cls.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates))) + if not hasattr(cls, "contracted_cost_item_rates"): + cls.contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates) + cls.contracted_cost_item_rates.append(cost_item_id) + props.contracted_cost_item_rates = json.dumps(cls.contracted_cost_item_rates) @classmethod def create_new_cost_item_li(