consider unit basis for calculating resource costs #4122

This commit is contained in:
Sigma Dimensions (Yass)
2023-12-20 14:18:55 +01:00
parent 73aeafb063
commit 46454c5c94
2 changed files with 16 additions and 12 deletions
@@ -106,14 +106,15 @@ class Usecase:
total_cost = 0 total_cost = 0
for resource in resources: for resource in resources:
cost = ifcopenshell.util.resource.get_cost(resource) cost, unit = ifcopenshell.util.resource.get_cost(resource)
quantity = ifcopenshell.util.resource.get_quantity(resource)
if not cost: if not cost:
cost = ifcopenshell.util.resource.get_parent_cost(resource) # Concept to standardise - Not defined in schema, but this makes manual scheduling of resources 10x faster and less duplicate data. cost = ifcopenshell.util.resource.get_parent_cost(resource) # Concept to standardise - Not defined in schema, but this makes manual scheduling of resources 10x faster and less duplicate data.
quantity = ifcopenshell.util.resource.get_quantity(resource)
if not cost or not quantity: if not cost or not quantity:
continue continue
if unit and "day" in unit:
quantity = quantity / 8 # Assume 8 hour working day - TODO implement resource calendar
total_cost += cost * quantity total_cost += cost * quantity
if total_cost: if total_cost:
cost_value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=self.settings["cost_item"]) cost_value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=self.settings["cost_item"])
cost_value.AppliedValue = self.file.createIfcMonetaryMeasure(total_cost) cost_value.AppliedValue = self.file.createIfcMonetaryMeasure(total_cost)
@@ -119,22 +119,25 @@ def get_nested_resources(resource):
def get_cost(resource): def get_cost(resource):
total = 0 costs = [
for cost_value in resource.BaseCosts or []: ifcopenshell.util.cost.calculate_applied_value(resource, cost_value)
total += cost_value.AppliedValue.wrappedValue if cost_value.AppliedValue else 0 for cost_value in getattr(resource, "BaseCosts", [])
return total ]
cost = costs[0] if costs else None
unit_basis = next(
(cost_value.UnitBasis for cost_value in getattr(resource, "BaseCosts", []) if cost_value.UnitBasis),
None
)
unit = unit_basis.UnitComponent.Name if unit_basis and unit_basis.UnitComponent.is_a("IfcConversionBasedUnit") else None
return cost, unit
def get_quantity(resource): def get_quantity(resource):
total = 0 total = 0
if resource.BaseQuantity: if resource.BaseQuantity:
return resource.BaseQuantity[3] return resource.BaseQuantity[3]
if resource.Usage and resource.Usage.ScheduleWork: 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) duration = ifcopenshell.util.date.ifc2datetime(resource.Usage.ScheduleWork)
if duration.days: return duration.total_seconds() / 3600
return duration.days
return duration.seconds / 60 / 60
def get_parent_cost(resource): def get_parent_cost(resource):
if not resource.Nests: if not resource.Nests: