Refactor cost documents following developrs advice

This commit is contained in:
falken10
2025-06-27 13:40:02 +02:00
committed by Massimo Fabbro
parent ccd97c66ae
commit b59bdb585b
4 changed files with 28 additions and 75 deletions
+1 -9
View File
@@ -64,15 +64,7 @@ class CostSchedulesData:
def get_csv_filepaths(cls) -> dict[int, str]:
"""Get CSV filepaths for cost schedules from document references."""
filepaths = {}
ifc_file = tool.Ifc.get()
cost_docs_document = next(
(
document
for document in ifc_file.by_type("IfcDocumentInformation")
if document.Name == "BBIM_Cost_Documents"
),
None,
)
cost_docs_document = tool.Cost.get_or_create_cost_documents()
if cost_docs_document:
references = tool.Document.get_document_references(cost_docs_document)
@@ -606,7 +606,7 @@ class RefreshCostScheduleCsv(bpy.types.Operator, tool.Ifc.Operator):
cls.poll_message_set("No active cost schedule")
return False
file_path = core.get_cost_schedule_csv_filepath(tool.Cost, props.active_cost_schedule_id)
file_path = tool.Cost.get_cost_schedule_csv_filepath(props.active_cost_schedule_id)
if not file_path:
cls.poll_message_set("No CSV file associated with this cost schedule")
return False
@@ -614,10 +614,7 @@ class RefreshCostScheduleCsv(bpy.types.Operator, tool.Ifc.Operator):
return True
def _execute(self, context):
error_message = core.refresh_cost_schedule_csv(tool.Cost)
if error_message:
self.report({"ERROR"}, error_message)
return {"CANCELLED"}
core.refresh_cost_schedule_csv(tool.Cost)
CostSchedulesData.is_loaded = False
return {"FINISHED"}
+5 -22
View File
@@ -18,7 +18,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union, Literal
import bonsai.tool as tool
import os
from bonsai.bim.module.cost.data import CostSchedulesData
@@ -26,6 +25,7 @@ if TYPE_CHECKING:
import bpy
import ifcopenshell
import ifcopenshell.util.cost
import bonsai.tool as tool
def add_cost_schedule(ifc: type[tool.Ifc], name: str, predefined_type: str) -> None:
@@ -342,13 +342,9 @@ def select_cost_schedule_products(
def import_cost_schedule_csv(
cost: type[tool.Cost], file_path: str, is_schedule_of_rates: bool
cost: type[tool.Cost], resolved_path: str, is_schedule_of_rates: bool
) -> ifcopenshell.entity_instance:
resolved_path = tool.Ifc.resolve_uri(file_path)
if not os.path.exists(resolved_path):
print(f"Error: Could not find CSV file at {file_path} (resolved to {resolved_path})")
return None
cost_schedule = cost.import_cost_schedule_csv(resolved_path, is_schedule_of_rates)
return cost_schedule
@@ -364,18 +360,7 @@ def remove_csv_filepath(cost: type[tool.Cost], cost_schedule) -> None:
def refresh_cost_schedule_csv(cost: type[tool.Cost]) -> Optional[str]:
props = cost.get_cost_props()
cost_schedule_id = props.active_cost_schedule_id
file_path = cost.get_cost_schedule_csv_filepath(cost_schedule_id)
if not file_path:
return "No CSV file associated with this cost schedule"
resolved_path = tool.Ifc.resolve_uri(file_path)
if not os.path.exists(resolved_path):
return f"Could not find CSV file at {file_path} (resolved to {resolved_path})"
cost.delete_all_cost_items()
cost.refresh_cost_schedule_csv()
cost.load_cost_schedule_tree()
@@ -487,9 +472,7 @@ def generate_cost_schedule_browser(cost: type[tool.Cost], cost_schedule: ifcopen
return cost.generate_cost_schedule_browser(cost_schedule)
def get_cost_schedule_csv_filepath(cost: type[tool.Cost], cost_schedule_id: int) -> Optional[str]:
return cost.get_cost_schedule_csv_filepath(cost_schedule_id)
def is_schedule_of_rates_csv(cost: type[tool.Cost], cost_schedule_id: int) -> bool:
return cost.is_schedule_of_rates_csv(cost_schedule_id)
+20 -39
View File
@@ -593,10 +593,7 @@ class Cost(bonsai.core.tool.Cost):
return csv2ifc.cost_schedule
@classmethod
def add_csv_filepath(cls, file_path: str, is_schedule_of_rates: bool, cost_schedule) -> None:
if not file_path or not cost_schedule:
return
def get_or_create_cost_documents(cls) -> ifcopenshell.entity_instance:
ifc_file = tool.Ifc.get()
cost_docs_document = next(
(
@@ -606,11 +603,26 @@ class Cost(bonsai.core.tool.Cost):
),
None,
)
if not cost_docs_document:
cost_docs_document = ifcopenshell.api.document.add_information(ifc_file)
cost_docs_document.Name = "BBIM_Cost_Documents"
cost_docs_document.Description = "Bonsai internal document containing references to cost CSV files"
return cost_docs_document
@classmethod
def add_csv_filepath(
cls,
file_path: Optional[str] = None,
is_schedule_of_rates: bool = False,
cost_schedule: ifcopenshell.entity_instance = None,
) -> None:
if not file_path or not cost_schedule:
return
ifc_file = tool.Ifc.get()
cost_docs_document = cls.get_or_create_cost_documents()
reference = ifcopenshell.api.document.add_reference(ifc_file, cost_docs_document)
reference.Location = file_path
@@ -628,14 +640,7 @@ class Cost(bonsai.core.tool.Cost):
return
ifc_file = tool.Ifc.get()
cost_docs_document = next(
(
document
for document in ifc_file.by_type("IfcDocumentInformation")
if document.Name == "BBIM_Cost_Documents"
),
None,
)
cost_docs_document = cls.get_or_create_cost_documents()
if not cost_docs_document:
return
@@ -646,7 +651,6 @@ class Cost(bonsai.core.tool.Cost):
for reference in references:
if reference.Description and f"Cost Schedule ID: {cost_schedule_id}" in reference.Description:
ifcopenshell.api.document.remove_reference(ifc_file, reference)
print(f"Cost schedule id={cost_schedule_id} csv filepath correctly removed")
return
@classmethod
@@ -661,15 +665,7 @@ class Cost(bonsai.core.tool.Cost):
@classmethod
def is_schedule_of_rates_csv(cls, cost_schedule_id: int) -> bool:
"""Check if a cost schedule is a schedule of rates based on document references."""
ifc_file = tool.Ifc.get()
cost_docs_document = next(
(
document
for document in ifc_file.by_type("IfcDocumentInformation")
if document.Name == "BBIM_Cost_Documents"
),
None,
)
cost_docs_document = cls.get_or_create_cost_documents()
if not cost_docs_document:
return False
@@ -684,15 +680,7 @@ class Cost(bonsai.core.tool.Cost):
@classmethod
def get_cost_schedule_csv_filepath(cls, cost_schedule_id: int) -> Optional[str]:
ifc_file = tool.Ifc.get()
cost_docs_document = next(
(
document
for document in ifc_file.by_type("IfcDocumentInformation")
if document.Name == "BBIM_Cost_Documents"
),
None,
)
cost_docs_document = cls.get_or_create_cost_documents()
if not cost_docs_document:
return None
@@ -1110,12 +1098,5 @@ class Cost(bonsai.core.tool.Cost):
results["unit_symbol"] = "U"
return results
@classmethod
def get_cost_schedule_documents(cls) -> Union[ifcopenshell.entity_instance, None]:
"""Get the document information entity that stores CSV references."""
for document in tool.Ifc.get().by_type("IfcDocumentInformation"):
if document.Name == "BBIM_Cost_Documents":
return document
return None