mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 16:22:53 +00:00
BBIM D: Copy cost items, export Cost Schedules individually, start improving Cost Schedule UI
This commit is contained in:
@@ -76,6 +76,7 @@ classes = (
|
||||
operator.LoadCostItemTaskQuantities,
|
||||
operator.LoadCostItemResourceQuantities,
|
||||
operator.ChangeParentCostItem,
|
||||
operator.CopyCostItem,
|
||||
prop.CostItem,
|
||||
prop.CostItemQuantity,
|
||||
prop.CostItemType,
|
||||
|
||||
@@ -97,10 +97,9 @@ class AddSummaryCostItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_label = "Add Cost Item"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Add a summary cost item"
|
||||
cost_schedule: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
core.add_summary_cost_item(tool.Ifc, tool.Cost, cost_schedule=tool.Ifc.get().by_id(self.cost_schedule))
|
||||
core.add_summary_cost_item(tool.Ifc, tool.Cost, cost_schedule=tool.Cost.get_active_cost_schedule())
|
||||
|
||||
|
||||
class AddCostItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -114,6 +113,16 @@ class AddCostItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
core.add_cost_item(tool.Ifc, tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item))
|
||||
|
||||
|
||||
class CopyCostItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.copy_cost_item"
|
||||
bl_label = "Copy Cost Item"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Copy a cost item"
|
||||
|
||||
def _execute(self, context):
|
||||
core.copy_cost_item(tool.Ifc, tool.Cost)
|
||||
|
||||
|
||||
class ExpandCostItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.expand_cost_item"
|
||||
bl_label = "Expand Cost Item"
|
||||
@@ -214,8 +223,9 @@ class UnassignCostItemType(bpy.types.Operator, tool.Ifc.Operator):
|
||||
core.unassign_cost_item_type(
|
||||
tool.Ifc,
|
||||
tool.Cost,
|
||||
self.cost_item,
|
||||
products=[tool.Ifc.get().by_id(self.related_object)] if self.related_object else [],
|
||||
tool.Spatial,
|
||||
cost_item=tool.Ifc.get().by_id(self.cost_item),
|
||||
product_types=[tool.Ifc.get().by_id(self.related_object)] if self.related_object else [],
|
||||
)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -491,7 +501,7 @@ class AddCostColumn(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
name: bpy.props.StringProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
def execute(self, context):
|
||||
core.add_cost_column(tool.Cost, self.name)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -619,10 +629,12 @@ class ExportCostSchedules(bpy.types.Operator):
|
||||
bl_label = "Export Cost Schedule"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Export a cost schedule to a CSV, XSLX OR ODS file"
|
||||
cost_schedule: bpy.props.IntProperty()
|
||||
format: bpy.props.EnumProperty("Format", items=(("CSV", "CSV", ""), ("XLSX", "XLSX", ""), ("ODS", "ODS", "")))
|
||||
|
||||
def execute(self, context):
|
||||
core.export_cost_schedules(tool.Cost, format=self.format)
|
||||
cost_schedule = tool.Ifc.get().by_id(self.cost_schedule) if self.cost_schedule else None
|
||||
core.export_cost_schedules(tool.Cost, format=self.format, cost_schedule=cost_schedule)
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
@@ -667,7 +679,9 @@ class LoadProductCostItems(bpy.types.Operator):
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
core.load_product_cost_items(tool.Cost, product=tool.Ifc.get().by_id(context.active_object.BIMObjectProperties.ifc_definition_id))
|
||||
core.load_product_cost_items(
|
||||
tool.Cost, product=tool.Ifc.get().by_id(context.active_object.BIMObjectProperties.ifc_definition_id)
|
||||
)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -213,3 +213,4 @@ class BIMCostProperties(PropertyGroup):
|
||||
name="Show Nested Tasks", default=False, update=update_active_cost_item_resources
|
||||
)
|
||||
change_cost_item_parent: BoolProperty(name="Change Cost Item Parent", default=False, update=update_cost_item_parent)
|
||||
show_cost_item_operators: BoolProperty(name="Show Cost Item Operators", default=False)
|
||||
|
||||
@@ -43,43 +43,54 @@ class BIM_PT_cost_schedules(Panel):
|
||||
|
||||
self.props = context.scene.BIMCostProperties
|
||||
row = self.layout.row()
|
||||
if CostSchedulesData.data["total_cost_schedules"]:
|
||||
row.label(text=f"{CostSchedulesData.data['total_cost_schedules']} Cost Schedules Found", icon="TEXT")
|
||||
row.operator("bim.export_cost_schedules", text="Export as spreadsheet", icon="EXPORT")
|
||||
else:
|
||||
row.label(text="No Cost Schedules Found found.", icon="COMMUNITY")
|
||||
|
||||
row = self.layout.row()
|
||||
row.prop(self.props, "cost_schedule_predefined_types")
|
||||
row.operator("bim.add_cost_schedule", icon="ADD", text="Add")
|
||||
if not self.props.active_cost_schedule_id:
|
||||
if CostSchedulesData.data["total_cost_schedules"]:
|
||||
row.label(text=f"{CostSchedulesData.data['total_cost_schedules']} Cost Schedules Found", icon="TEXT")
|
||||
row.operator("bim.export_cost_schedules", text="Export as spreadsheet", icon="EXPORT")
|
||||
else:
|
||||
row.label(text="No Cost Schedules Found found.", icon="COMMUNITY")
|
||||
row = self.layout.row()
|
||||
row.prop(self.props, "cost_schedule_predefined_types")
|
||||
row.operator("bim.add_cost_schedule", icon="ADD", text="Add")
|
||||
|
||||
for schedule in CostSchedulesData.data["schedules"]:
|
||||
self.draw_cost_schedule_ui(schedule)
|
||||
|
||||
def draw_cost_schedule_ui(self, cost_schedule):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=cost_schedule["name"], icon="LINENUMBERS_ON")
|
||||
|
||||
if self.props.active_cost_schedule_id and self.props.active_cost_schedule_id == cost_schedule["id"]:
|
||||
op = row.operator("bim.select_cost_schedule_products", icon="RESTRICT_SELECT_OFF", text="Assigned")
|
||||
row.label(text="Currently editing: {}".format(cost_schedule["name"]), icon="LINENUMBERS_ON")
|
||||
grid = self.layout.grid_flow(columns=2, even_columns=True)
|
||||
col = grid.column()
|
||||
row1 = col.row(align=True)
|
||||
row1.alignment = "LEFT"
|
||||
row1.label(text="Schedule tools")
|
||||
row1 = col.row(align=True)
|
||||
row1.alignment = "RIGHT"
|
||||
row1.operator("bim.export_cost_schedules", text="Export", icon="EXPORT").cost_schedule = cost_schedule["id"]
|
||||
row2 = col.row(align=True)
|
||||
row2.alignment = "RIGHT"
|
||||
op = row2.operator("bim.select_cost_schedule_products", icon="RESTRICT_SELECT_OFF", text="Assigned")
|
||||
op.cost_schedule = cost_schedule["id"]
|
||||
row.operator("bim.select_unassigned_products", icon="RESTRICT_SELECT_OFF", text="Unassigned")
|
||||
row2.operator("bim.select_unassigned_products", icon="RESTRICT_SELECT_OFF", text="Unassigned")
|
||||
|
||||
row.prop(self.props, "should_show_column_ui", text="", icon="SHORTDISPLAY")
|
||||
col = grid.column()
|
||||
row1 = col.row(align=True)
|
||||
row1.alignment = "LEFT"
|
||||
row1.label(text="Settings")
|
||||
row1 = col.row(align=True)
|
||||
row1.alignment = "RIGHT"
|
||||
row1.prop(self.props, "should_show_column_ui", text="Schedule Columns", icon="SHORTDISPLAY")
|
||||
if self.props.is_editing == "COST_SCHEDULE_ATTRIBUTES":
|
||||
row.operator("bim.edit_cost_schedule", text="", icon="CHECKMARK")
|
||||
elif self.props.is_editing == "COST_ITEMS":
|
||||
row.operator("bim.add_summary_cost_item", text="", icon="ADD").cost_schedule = cost_schedule["id"]
|
||||
row.operator("bim.disable_editing_cost_schedule", text="", icon="CANCEL")
|
||||
elif self.props.active_cost_schedule_id:
|
||||
row.operator("bim.remove_cost_schedule", text="", icon="X").cost_schedule = cost_schedule["id"]
|
||||
row.operator("bim.disable_editing_cost_schedule", text="Disable Editing", icon="CANCEL")
|
||||
else:
|
||||
row.label(text=cost_schedule["name"], icon="LINENUMBERS_ON")
|
||||
row.operator("bim.enable_editing_cost_items", text="", icon="OUTLINER").cost_schedule = cost_schedule["id"]
|
||||
row.operator(
|
||||
"bim.enable_editing_cost_schedule_attributes", text="", icon="GREASEPENCIL"
|
||||
).cost_schedule = cost_schedule["id"]
|
||||
row.operator("bim.remove_cost_schedule", text="", icon="X").cost_schedule = cost_schedule["id"]
|
||||
|
||||
if self.props.active_cost_schedule_id == cost_schedule["id"]:
|
||||
if self.props.is_editing == "COST_SCHEDULE_ATTRIBUTES":
|
||||
self.draw_editable_cost_schedule_ui()
|
||||
@@ -101,30 +112,39 @@ class BIM_PT_cost_schedules(Panel):
|
||||
row = self.layout.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
ifc_definition_id = None
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="Cost Item Tools")
|
||||
row = self.layout.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
row.operator("bim.add_summary_cost_item", text="Add Summary Cost", icon="ADD")
|
||||
row.operator("bim.expand_all_tasks", text="Expand All")
|
||||
row.operator("bim.contract_all_tasks", text="Contract All")
|
||||
row = self.layout.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
if self.props.cost_items and self.props.active_cost_item_index < len(self.props.cost_items):
|
||||
ifc_definition_id = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
|
||||
if ifc_definition_id:
|
||||
row.prop(self.props, "change_cost_item_parent", text="", icon="LINKED")
|
||||
row.prop(self.props, "enable_reorder", text="", icon="SORTALPHA")
|
||||
if not CostSchedulesData.data["is_editing_rates"]:
|
||||
op = row.operator("bim.enable_editing_cost_item_quantities", text="", icon="PROPERTIES")
|
||||
row.prop(self.props, "show_cost_item_operators", text="Edit", icon="DOWNARROW_HLT")
|
||||
row.operator("bim.add_cost_item", text="Add", icon="ADD").cost_item = ifc_definition_id
|
||||
row.operator("bim.copy_cost_item", text="Copy", icon="ADD")
|
||||
row.operator("bim.remove_cost_item", text="Delete", icon="X").cost_item = ifc_definition_id
|
||||
if self.props.show_cost_item_operators:
|
||||
row = self.layout.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
row.prop(self.props, "change_cost_item_parent", text="", icon="LINKED")
|
||||
row.prop(self.props, "enable_reorder", text="", icon="SORTALPHA")
|
||||
if not CostSchedulesData.data["is_editing_rates"]:
|
||||
op = row.operator("bim.enable_editing_cost_item_quantities", text="", icon="PROPERTIES")
|
||||
op.cost_item = ifc_definition_id
|
||||
op = row.operator("bim.enable_editing_cost_item_values", text="", icon="DISC")
|
||||
op.cost_item = ifc_definition_id
|
||||
|
||||
op = row.operator("bim.enable_editing_cost_item_values", text="", icon="DISC")
|
||||
op.cost_item = ifc_definition_id
|
||||
|
||||
row.operator("bim.add_cost_item", text="", icon="ADD").cost_item = ifc_definition_id
|
||||
|
||||
if self.props.active_cost_item_id == ifc_definition_id:
|
||||
if self.props.cost_item_editing_type == "ATTRIBUTES":
|
||||
row.operator("bim.edit_cost_item", text="", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_cost_item", text="", icon="CANCEL")
|
||||
else:
|
||||
op = row.operator("bim.enable_editing_cost_item_attributes", text="", icon="GREASEPENCIL")
|
||||
op.cost_item = ifc_definition_id
|
||||
|
||||
row.operator("bim.remove_cost_item", text="", icon="X").cost_item = ifc_definition_id
|
||||
|
||||
if self.props.active_cost_item_id == ifc_definition_id:
|
||||
if self.props.cost_item_editing_type == "ATTRIBUTES":
|
||||
row.operator("bim.edit_cost_item", text="", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_cost_item", text="", icon="CANCEL")
|
||||
else:
|
||||
op = row.operator("bim.enable_editing_cost_item_attributes", text="", icon="GREASEPENCIL")
|
||||
op.cost_item = ifc_definition_id
|
||||
self.layout.template_list(
|
||||
"BIM_UL_cost_items",
|
||||
"",
|
||||
@@ -698,9 +718,7 @@ class BIM_PT_Costing_Tools(Panel):
|
||||
def draw(self, context):
|
||||
self.props = context.scene.BIMCostProperties
|
||||
row = self.layout.row()
|
||||
row.operator(
|
||||
"bim.load_product_cost_items", icon="FILE_REFRESH"
|
||||
)
|
||||
row.operator("bim.load_product_cost_items", icon="FILE_REFRESH")
|
||||
row = self.layout.row()
|
||||
row.template_list(
|
||||
"BIM_UL_product_cost_items",
|
||||
|
||||
@@ -236,8 +236,8 @@ def calculate_cost_item_resource_value(ifc, cost_item):
|
||||
ifc.run("cost.calculate_cost_item_resource_value", cost_item=cost_item)
|
||||
|
||||
|
||||
def export_cost_schedules(cost, format):
|
||||
cost.export_cost_schedules(format)
|
||||
def export_cost_schedules(cost, format, cost_schedule=None):
|
||||
cost.export_cost_schedules(format, cost_schedule)
|
||||
|
||||
|
||||
def clear_cost_item_assignments(ifc, cost, cost_item, related_object_type):
|
||||
@@ -276,4 +276,11 @@ def change_parent_cost_item(ifc, cost, new_parent):
|
||||
if cost_item :
|
||||
ifc.run("nest.change_nest", item=cost_item, new_parent=new_parent)
|
||||
cost.disable_editing_cost_item_parent()
|
||||
cost.load_cost_schedule_tree()
|
||||
cost.load_cost_schedule_tree()
|
||||
|
||||
def copy_cost_item(ifc, cost):
|
||||
cost_item = cost.get_highlighted_cost_item()
|
||||
if cost_item:
|
||||
cost_item = ifc.run("cost.copy_cost_item", cost_item=cost_item)
|
||||
cost.disable_editing_cost_item_parent()
|
||||
cost.load_cost_schedule_tree()
|
||||
|
||||
@@ -498,24 +498,23 @@ class Cost(blenderbim.core.tool.Cost):
|
||||
props.is_cost_update_enabled = True
|
||||
|
||||
@classmethod
|
||||
def export_cost_schedules(cls, format=None):
|
||||
def export_cost_schedules(cls, format=None, cost_schedule=None):
|
||||
path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "build", "cost_schedules")
|
||||
if format == "CSV":
|
||||
from ifc5d.ifc5Dspreadsheet import Ifc5DCsvWriter
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
writer = Ifc5DCsvWriter(file=tool.Ifc.get(), output=path)
|
||||
writer = Ifc5DCsvWriter(file=tool.Ifc.get(), output=path, cost_schedule=cost_schedule)
|
||||
writer.write()
|
||||
elif format == "ODS":
|
||||
from ifc5d.ifc5Dspreadsheet import Ifc5DOdsWriter
|
||||
|
||||
writer = Ifc5DOdsWriter(file=tool.Ifc.get(), output=path)
|
||||
writer = Ifc5DOdsWriter(file=tool.Ifc.get(), output=path, cost_schedule=cost_schedule)
|
||||
writer.write()
|
||||
elif format == "XLSX":
|
||||
from ifc5d.ifc5Dspreadsheet import Ifc5DXlsxWriter
|
||||
|
||||
writer = Ifc5DXlsxWriter(file=tool.Ifc.get(), output=path)
|
||||
writer = Ifc5DXlsxWriter(file=tool.Ifc.get(), output=path, cost_schedule=cost_schedule )
|
||||
writer.write()
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user