mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 16:06:27 +00:00
You can now calculate costs from direct resources and indirect task-based resources
This commit is contained in:
@@ -65,6 +65,7 @@ classes = (
|
|||||||
operator.LoadScheduleOfRates,
|
operator.LoadScheduleOfRates,
|
||||||
operator.ExpandCostItemRate,
|
operator.ExpandCostItemRate,
|
||||||
operator.ContractCostItemRate,
|
operator.ContractCostItemRate,
|
||||||
|
operator.CalculateCostItemResourceValue,
|
||||||
prop.CostItem,
|
prop.CostItem,
|
||||||
prop.CostItemQuantity,
|
prop.CostItemQuantity,
|
||||||
prop.CostItemType,
|
prop.CostItemType,
|
||||||
|
|||||||
@@ -1054,3 +1054,21 @@ class ContractCostItemRate(bpy.types.Operator):
|
|||||||
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
|
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
|
||||||
bpy.ops.bim.load_schedule_of_rates(cost_schedule=int(props.schedule_of_rates))
|
bpy.ops.bim.load_schedule_of_rates(cost_schedule=int(props.schedule_of_rates))
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CalculateCostItemResourceValue(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.calculate_cost_item_resource_value"
|
||||||
|
bl_label = "Calculate Cost Item Resource Value"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
cost_item: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
return IfcStore.execute_ifc_operator(self, context)
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
self.file = IfcStore.get_file()
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"cost.calculate_cost_item_resource_value", self.file, cost_item=self.file.by_id(self.cost_item)
|
||||||
|
)
|
||||||
|
Data.load(self.file)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -432,6 +432,9 @@ class BIM_PT_cost_item_quantities(Panel):
|
|||||||
row2 = col.row(align=True)
|
row2 = col.row(align=True)
|
||||||
row2.label(text="Resources")
|
row2.label(text="Resources")
|
||||||
|
|
||||||
|
op = row2.operator("bim.calculate_cost_item_resource_value", text="", icon="DISC")
|
||||||
|
op.cost_item = cost_item.ifc_definition_id
|
||||||
|
|
||||||
rtprops = context.scene.BIMResourceTreeProperties
|
rtprops = context.scene.BIMResourceTreeProperties
|
||||||
rprops = context.scene.BIMResourceProperties
|
rprops = context.scene.BIMResourceProperties
|
||||||
if rtprops.resources and rprops.active_resource_index < len(rtprops.resources):
|
if rtprops.resources and rprops.active_resource_index < len(rtprops.resources):
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import ifcopenshell.api
|
||||||
|
import ifcopenshell.util.date
|
||||||
|
|
||||||
|
|
||||||
|
class Usecase:
|
||||||
|
def __init__(self, file, **settings):
|
||||||
|
self.file = file
|
||||||
|
self.settings = {"cost_item": None}
|
||||||
|
for key, value in settings.items():
|
||||||
|
self.settings[key] = value
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
for cost_value in self.settings["cost_item"].CostValues or []:
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"cost.remove_cost_value", self.file, parent=self.settings["cost_item"], cost_value=cost_value
|
||||||
|
)
|
||||||
|
|
||||||
|
resources = []
|
||||||
|
for rel in self.settings["cost_item"].Controls or []:
|
||||||
|
for related_object in rel.RelatedObjects:
|
||||||
|
if related_object.is_a("IfcConstructionResource"):
|
||||||
|
resources.append(related_object)
|
||||||
|
elif related_object.is_a("IfcTask"):
|
||||||
|
for rel2 in related_object.OperatesOn or []:
|
||||||
|
for related_object2 in rel2.RelatedObjects:
|
||||||
|
if related_object2.is_a("IfcConstructionResource"):
|
||||||
|
resources.append(related_object2)
|
||||||
|
|
||||||
|
total_cost = 0
|
||||||
|
for resource in resources:
|
||||||
|
cost = self.get_cost(resource)
|
||||||
|
quantity = self.get_quantity(resource)
|
||||||
|
if not cost or not quantity:
|
||||||
|
continue
|
||||||
|
total_cost += cost * quantity
|
||||||
|
|
||||||
|
if total_cost:
|
||||||
|
cost_value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=self.settings["cost_item"])
|
||||||
|
cost_value.AppliedValue = self.file.createIfcMonetaryMeasure(total_cost)
|
||||||
|
|
||||||
|
def get_cost(self, resource):
|
||||||
|
total = 0
|
||||||
|
for cost_value in resource.BaseCosts or []:
|
||||||
|
total += cost_value.AppliedValue.wrappedValue if cost_value.AppliedValue else 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
def get_quantity(self, resource):
|
||||||
|
total = 0
|
||||||
|
if resource.BaseQuantity:
|
||||||
|
return resource.BaseQuantity[3]
|
||||||
|
if resource.Usage and resource.Usage.ScheduleWork:
|
||||||
|
# For now we assume either hourly or daily depending on how duration is stored
|
||||||
|
duration = ifcopenshell.util.date.ifc2datetime(resource.Usage.ScheduleWork)
|
||||||
|
if duration.days:
|
||||||
|
return duration.days
|
||||||
|
return duration.seconds / 60 / 60
|
||||||
Reference in New Issue
Block a user