import ifcopenshell from ifcopenshell.util import cost as cst import bonsai.tool as tool import pandas as pd def get_task_details(cost_item): """ Checks if a cost item has a task relation and retrieves task details. Parameters: cost_item: The cost item to check. Returns: tuple: Task name, start date, and end date as strings, or empty strings if no task relation exists. """ taskname = "" taskstart = "" taskend = "" if cost_item.Controls and cost_item.Controls[0].RelatedObjects: related_object = cost_item.Controls[0].RelatedObjects[0] if related_object.is_a("IfcTask"): taskname = related_object.Name taskstart = related_object.TaskTime.ScheduleStart[:10] if related_object.TaskTime and related_object.TaskTime.ScheduleStart else "" taskend = related_object.TaskTime.ScheduleFinish[:10] if related_object.TaskTime and related_object.TaskTime.ScheduleFinish else "" return taskname, taskstart, taskend def calculate_total_value(cost_item): """ Calculates the total value of a cost item by summing up all its CostValues. Parameters: cost_item: The cost item to process. Returns: float: The total value of the cost item rounded to two decimal places. """ total_quantity = cst.get_total_quantity(cost_item) # Check for NaN or None if not total_quantity: # Filters out Nan and falsy values return "" total_value = 0.0 if hasattr(cost_item, "CostValues") and cost_item.CostValues: for value in cost_item.CostValues: total_value += cst.calculate_applied_value(cost_item, value) return round(total_value, 2) def calculate_quantity(cost_item): """ Returns the quantity value of a cost item if present """ total_quantity = cst.get_total_quantity(cost_item) if not total_quantity: return "" else: return total_quantity def calculate_summary(cost_item): """ Returns the summary of children cost items' value if present else the product of quantity x value """ total_summary = cst.sum_child_root_elements(cost_item) if total_summary != 0: return round(total_summary,2) else: return multiply_cost_quantity(cost_item) def multiply_cost_quantity(cost_item): """ Returns the product of quantity x value """ if calculate_total_value(cost_item) and calculate_quantity(cost_item): item_product = float(calculate_total_value(cost_item)) * float(calculate_quantity(cost_item)) return item_product else: return "" # Main script model = tool.Ifc.get() schedule_lst = model.by_type("IfcCostSchedule") myschedule = schedule_lst[0] # List all cost items in the schedule costitems_lst = list(cst.get_schedule_cost_items(myschedule)) # Create an empty list for data data = [] # Loop through all cost items for c in costitems_lst: taskname, taskstart, taskend = get_task_details(c) total_value = calculate_total_value(c) total_quantity = calculate_quantity(c) total_summary = calculate_summary(c) item_data = { "ID": c.Identification if hasattr(c, 'Identification') else None, "Name": c.Name if hasattr(c, 'Name') else None, "TaskName": taskname, "Start": taskstart, "End": taskend, "TotalQty": total_quantity, "TotalValue": total_value, "TotalAmount": total_summary, } data.append(item_data) # Create DataFrame df = pd.DataFrame(data) print(df.head(50)) # Export to CSV #output_file = r"C:\Users\path\cost_items_schedule.csv" #df.to_csv(output_file, index=False) #print(f"Data exported to {output_file}")