From 46454c5c94685302ea7f90b98a5b42a2415c40c7 Mon Sep 17 00:00:00 2001 From: "Sigma Dimensions (Yass)" <79010126+myoualid@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:18:55 +0100 Subject: [PATCH] consider unit basis for calculating resource costs #4122 --- .../calculate_cost_item_resource_value.py | 7 ++++--- .../ifcopenshell/util/resource.py | 21 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py b/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py index e947654b3a..bace1c6d12 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py +++ b/src/ifcopenshell-python/ifcopenshell/api/cost/calculate_cost_item_resource_value.py @@ -106,14 +106,15 @@ class Usecase: total_cost = 0 for resource in resources: - cost = ifcopenshell.util.resource.get_cost(resource) - quantity = ifcopenshell.util.resource.get_quantity(resource) + cost, unit = ifcopenshell.util.resource.get_cost(resource) 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. + quantity = ifcopenshell.util.resource.get_quantity(resource) if not cost or not quantity: continue + if unit and "day" in unit: + quantity = quantity / 8 # Assume 8 hour working day - TODO implement resource calendar 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) diff --git a/src/ifcopenshell-python/ifcopenshell/util/resource.py b/src/ifcopenshell-python/ifcopenshell/util/resource.py index f3ce2082e0..f4397ea349 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/resource.py +++ b/src/ifcopenshell-python/ifcopenshell/util/resource.py @@ -119,22 +119,25 @@ def get_nested_resources(resource): def get_cost(resource): - total = 0 - for cost_value in resource.BaseCosts or []: - total += cost_value.AppliedValue.wrappedValue if cost_value.AppliedValue else 0 - return total - + costs = [ + ifcopenshell.util.cost.calculate_applied_value(resource, cost_value) + for cost_value in getattr(resource, "BaseCosts", []) + ] + 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): 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 + return duration.total_seconds() / 3600 def get_parent_cost(resource): if not resource.Nests: