Add documentation for cost module

This commit is contained in:
Dion Moult
2022-11-21 12:05:30 +09:00
parent 412cf7c6cb
commit 11f772b5a3
19 changed files with 621 additions and 74 deletions
@@ -18,7 +18,7 @@
class Usecase:
def __init__(self, file, classifcation=None):
def __init__(self, file, classification=None):
"""Removes an IfcClassification from the project and all references
The classification and all of its relationships, children references,
@@ -36,7 +36,6 @@ class Usecase:
ifcopenshell.api.run("classification.remove_classification", model,
classification=classification)
"""
self.file = file
self.settings = {"classification": classification}
@@ -20,11 +20,36 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_schedule=None, cost_item=None):
"""Add a new cost item
A cost item represents a single line item in a cost schedule. Cost items
may then be broken down into cost subitems.
:param cost_schedule: If the cost item is to be added as a root or top
level cost item to a cost schedule, the IfcCostSchedule may be
specified. This is mutually exlclusive to the cost_item parameter.
:type cost_schedule: ifcopenshell.entity_instance.entity_instance
:param cost_item: If the cost item is to be added as a subitem to an
existing cost item, the parent IfcCostItem may be specified. This is
mutually exclusive to the cost_schedule parameter.
:type cost_item: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcCostItem
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# The very first cost item must be in a cost schedule
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
# You may add cost items as top level item in the schedule
item1 = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# Alternatively you may add them as subitems
item2 = ifcopenshell.api.run("cost.add_cost_item", model, cost_item=item1)
"""
self.file = file
self.settings = {"cost_schedule": None, "cost_item": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_schedule": cost_schedule, "cost_item": cost_item}
def execute(self):
cost_item = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcCostItem")
@@ -20,11 +20,58 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None, ifc_class="IfcQuantityCount"):
"""Adds a new quantity associated with a cost item
Cost items calculate their subtotal by multiplying the sum of the cost
item's "values" by the sum of the cost item's "quantities". The
quantities may be either parametrically linked to quantities measured on
physical product, or manually specified.
The quantity must be of a particular type, common examples are:
- IfcQuantityCount: to count the total occurrences of a product, useful
for things like doors, windows, and furniture
- IfcQuantityNumber: any other generic numeric quantity
- IfcQuantityLength
- IfcQuantityArea
- IfcQuantityVolume
- IfcQuantityWeight
- IfcQuantityTime
A cost item must not mix quantities of different types.
If an IfcQuantityCount is used, then this API will automatically count
all products that this cost item controls (see
ifcopenshell.api.controls.assign_control) and prefill that quantity.
For all other quantity types, the quantity is left as zero and the user
must either manually specify the quantity or parametrically link it
using another API call.
:param cost_item: The IfcCostItem to add the quantity to
:type cost_item: ifcopenshell.entity_instance.entity_instance
:param ifc_class: The type of quantity to add
:type ifc_class: str, optional
:return: The newly created quantity entity, chosen from the ifc_class
parameter
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
chair = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcFurniture")
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
ifcopenshell.api.run("control.assign_control", model,
relating_control=cost_item, related_object=chair)
# Let's assume we want to count the amount of chairs to calculate our cost item
# Because this is an IfcQuantityCount the count will be automatically set to "1" chair
ifcopenshell.api.run("cost.add_cost_item_quantity", model,
cost_item=item, ifc_class="IfcQuantityCount")
"""
self.file = file
self.settings = {"cost_item": None, "ifc_class": "IfcQuantityCount"}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item, "ifc_class": ifc_class}
def execute(self):
quantity = self.file.create_entity(self.settings["ifc_class"], Name="Unnamed")
@@ -22,11 +22,37 @@ from datetime import datetime
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, name=None, predefined_type="NOTDEFINED"):
"""Add a new cost schedule
A cost schedule is a group of cost items which typically represent a
cost plan or breakdown of the project. This may be used as an estimate,
bid, or actual cost.
Alternatively, a cost schedule may also represent a schedule of rates,
which include cost items which capture unit rates for different elements
or processes.
As such, creating a cost schedule is necessary prior to creating and
managing any cost items.
:param name: The name of the cost schedule.
:type name: str, optional
:param predefined_type: The predefined type of the cost schedule, chosen
from a valid type in the IFC documentation for
IfcCostScheduleTypeEnum
:type predefined_type: str, optional
:return: The newly created IfcCostSchedule entity
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
# Now that we have a cost schedule, we may add cost items to it
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
"""
self.file = file
self.settings = {"name": None, "predefined_type": "NOTDEFINED", "start_time": datetime.now()}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"name": name, "predefined_type": predefined_type}
def execute(self):
cost_schedule = ifcopenshell.api.run(
@@ -18,11 +18,79 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, parent=None):
"""Adds a new value or subvalue to a cost item
A cost item's subtotal can be specified in two ways.
Option 1 is by simply manually specifying the subtotal value, which
represents the full cost of that cost item. This option occurs when a
cost item has no quantities associated with it.
Option 2 is by specifying a unit cost value of the cost item, which is
then multiplied by the associated quantity of the cost item, to give us
the subtotal. This option occurs when a cost item has quantities
associated with it.
For either option 1 (full cost value) or option 2 (unit cost value), the
cost value may be specified as a single number, or as a sum of
subcomponents or formulas (e.g. multiplication by wastage factor, or
adding taxes or other adjustments).
This function lets you add a single top level unit value to a cost item,
or alternatively price subcomponents by using the "parent" parameter.
More advanced usage, which involves summing, subcategory-filtered costs,
and formulas are possible but not yet documented.
:param parent: A parent IfcCostItem, if specifying a price directly to a
cost item, or a top-level price component. Alternatively, this can
be set to a IfcCostValue, if specifying price subcomponents.
:type parent: ifcopenshell.entity_instance.entity_instance
:return: The newly created IfcCostValue
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
# We always need a schedule first prior to adding any cost items
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
# Option 1: This cost item will have a full cost of 42.0
item1 = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item1)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 42.0})
# Option 2: This cost item will have a unit cost of 5.0 per unit
# area, multiplied by the quantity of area specified explicitly as
# 3.0, giving us a subtotal cost of 15.0.
item2 = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item2)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5.0})
quantity = ifcopenshell.api.run("cost.add_cost_item_quantity", model,
cost_item=item2, ifc_class="IfcQuantityVolume")
ifcopenshell.api.run("cost.edit_cost_item_quantity", model,
physical_quantity=quantity, "attributes": {"VolumeValue": 3.0})
# A cost value may also be specified in terms of the sum of its
# subcomponents. In this case, it's broken down into 2 subvalues.
item1 = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item1)
subvalue1 = ifcopenshell.api.run("cost.add_cost_value", model, parent=value)
subvalue2 = ifcopenshell.api.run("cost.add_cost_value", model, parent=value)
# This specifies that the value is the sum of all subitems
# regardless of their cost category. The first subvalue is 2.0 and
# the second is 3.0, giving a total value of 5.0.
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value, attributes={"Category": "*"})
ifcopenshell.api.run("cost.edit_cost_value", model,
cost_value=subvalue1, attributes={"AppliedValue": 2.0})
ifcopenshell.api.run("cost.edit_cost_value", model,
cost_value=subvalue2, attributes={"AppliedValue": 3.0})
"""
self.file = file
self.settings = {"parent": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"parent": parent}
def execute(self):
value = self.file.create_entity("IfcCostValue")
@@ -20,11 +20,62 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None, products=None, prop_name=""):
"""Adds a cost item quantity that is parametrically connected to a product
A cost item may have its subtotal calculated by multiplying a unit value
by a quantity associated with the cost item. That quantity may be either
manually specified or parametrically connected to a quantity on a
product. This API function lets you create that parametric connection.
For example, you may wish to have a cost item linked to the "NetVolume"
quantity on all IfcSlabs. Each quantity has a name which you can
specify. If the quantity is updated in-place (which should occur for
Native IFC applications) then the quantity for the cost item will
automatically update as well. If the quantity is deleted and then
re-added, then the parametric relationship is also lost.
This API also automatically assigns a control relationship between the
cost item and the product, so it is not necessary to use
ifcopenshell.api.control.assign_control.
:param cost_item: The IfcCostItem to assign parametric quantities to
:type cost_item: ifcopenshell.entity_instance.entity_instance
:param products: The IfcObjects to assign parametric quantities to
:type products: list[ifcopenshell.entity_instance.entity_instance]
:param prop_name: The name of the quantity. If this is not specified,
then it is assumed that there is no calculated quantity, and the
number of objects are counted instead.
:type prop_name: str, optional
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# Let's imagine a unit cost of 5.0 per unit volume
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5.0})
slab = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSlab")
# Usually the quantity would be automatically calculated via a
# graphical authoring application but let's assign a manual quantity
# for now.
qto = ifcopenshell.api.run("pset.add_qto", model, product=slab, name="Qto_SlabBaseQuantities")
ifcopenshell.api.run("pset.edit_qto", model, qto=qto, properties={"NetVolume": 42.0})
# Now let's parametrically link the slab's quantity to the cost
# item. If the slab is edited in the future and 42.0 changes, then
# the updated value will also automatically be applied to the cost
# item.
ifcopenshell.api.run("cost.assign_cost_item_quantity", model,
cost_item=item, products=[slab], prop_name="NetVolume")
"""
self.file = file
self.settings = {"cost_item": None, "products": [], "prop_name": ""}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item, "products": products or [], "prop_name": prop_name}
def execute(self):
if self.settings["prop_name"]:
@@ -20,11 +20,46 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None, cost_rate=None):
"""Assigns a cost value to a cost item from a schedule of rates
Instead of assigning cost values from scratch for each cost item in a
cost schedule, the cost values may instead be assigned from a schedule
of rates.
A schedule of rates is just another cost schedule which have cost values
but no quantities. This API will allow you to "copy" the values from a
cost item in the schedule of rates into another cost item in your own
cost schedule. When the schedule of rates value is updated, then your
cost item values will also be updated. You can think of the schedule of
rates as a "template" to quickly populate your rates from.
:param cost_item: The IfcCostItem that you want to copy the values to
:type cost_item: ifcopenshell.entity_instance.entity_instance
:param cost_rate: The IfcCostItem that you want to copy the values from
:type cost_rate: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Let's create a schedule of rates with a single rate in it of 5.0
rate_tables = ifcopenshell.api.run("cost.add_cost_schedule", model,
predefined_type="SCHEDULEOFRATES")
rate = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5.0})
# And this schedule will be for our actual cost plan / estimate / etc
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# Now the cost item has the same rate as the one from the schedule of rate's item
ifcopenshell.api.run("cost.assign_cost_value", model, cost_item=item, cost_rate=rate)
"""
self.file = file
self.settings = {"cost_item": None, "cost_rate": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item, "cost_rate": cost_rate}
def execute(self):
for cost_value in self.settings["cost_item"].CostValues:
@@ -21,11 +21,68 @@ import ifcopenshell.util.date
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None):
"""Calculates the total cost of all resources associated with a cost item
A cost item may have construction resources (e.g. equipment, material,
etc) assigned to it. Construction resources may be assigned directly to
the cost item, or assigned first to a task, and the task is then
assigned to the cost item.
The cost of a resource is calculated by the total sum of all of its base
costs. If no quantity is provided, that sum is considered to be the
total cost. Otherwise, it is considered to be a unit cost, and is then
multiplied by the resource quantity. The quantity is either stored as a
base quantity (such as a volume) for a things like material resources,
or as a duration as a daily rate for labour resources.
The final calculated cost is set as the cost item's value. Any
previously existing values are removed.
:param cost_item: The IfcCostItem to calculate
:type cost_item: ifccopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# First, we need a cost schedule and item
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# Let's imagine we have our own formworking crew
crew = ifcopenshell.api.run("resource.add_resource", model, ifc_class="IfcCrewResource")
# ... and they need concrete
concrete = ifcopenshell.api.run("resource.add_resource", model,
ifc_class="IfcConstructionMaterialResource", parent_resource=crew)
ifcopenshell.api.run("control.assign_control", model,
relating_control=item, related_object=concrete)
# ... which has a unit price of 42.0 per m3
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=concrete)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 42.0})
# ... and a volume of 200m3
quantity = ifcopenshell.api.run("resource.add_resource_quantity", model,
resource=concrete, ifc_class="IfcQuantityVolume")
ifcopenshell.api.run("resource.edit_resource_quantity", model,
physical_quantity=quantity, "attributes": {"VolumeValue": 200.0})
# Let's say they also need some equipment
equipment = ifcopenshell.api.run("resource.add_resource", model,
ifc_class="IfcConstructionEquipmentResource", parent_resource=crew)
ifcopenshell.api.run("control.assign_control", model,
relating_control=item, related_object=equipment)
# ... with a fixed price of 50,000
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=concrete)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 42.0})
# (42 * 200) + 50000 = 58400 is our calculated cost
ifcopenshell.api.run("cost.calculate_cost_item_resource_value", model, cost_item=item)
"""
self.file = file
self.settings = {"cost_item": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item}
def execute(self):
for cost_value in self.settings["cost_item"].CostValues or []:
@@ -20,11 +20,37 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, source=None, destination=None):
"""Copies all cost values from one cost item to another
Any previously existing values will be removed. The entire value is
copied, including all components and formulas. However they are not
parametrically linked, so if one value changes, the other will not.
:param source: The IfcCostItem to copy cost values from
:type source: ifcopenshell.entity_instance.entity_instance
:param destination: The IfcCostItem to copy cost values from
:type destination: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
# Assume we have a schedule with multiple items in it
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item1 = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
item2 = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# One of the items has a value
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5000.0})
# Let's copy the value from one item to another
ifcopenshell.api.run("cost.copy_cost_item_values", model, source=item1, destination=item2)
"""
self.file = file
self.settings = {"source": None, "destination": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"source": source, "destination": destination}
def execute(self):
for cost_value in self.settings["destination"].CostValues or []:
@@ -18,11 +18,27 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None, attributes=None):
"""Edits the attributes of an IfcCostItem
For more information about the attributes and data types of an
IfcCostItem, consult the IFC documentation.
:param cost_item: The IfcCostItem entity you want to edit
:type cost_item: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
ifcopenshell.api.run("cost.edit_cost_item", model, cost_item=item, attributes={"Name": "Foo"})
"""
self.file = file
self.settings = {"cost_item": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,35 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, physical_quantity=None, attributes=None):
"""Edits the attributes of an IfcPhysicalQuantity
For more information about the attributes and data types of an
IfcPhysicalQuantity, consult the IFC documentation.
:param physical_quantity: The IfcPhysicalQuantity entity you want to edit
:type physical_quantity: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# This cost item will have a unit cost of 5 and a volume of 3
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5.0})
quantity = ifcopenshell.api.run("cost.add_cost_item_quantity", model,
cost_item=item, ifc_class="IfcQuantityVolume")
ifcopenshell.api.run("cost.edit_cost_item_quantity", model,
physical_quantity=quantity, "attributes": {"VolumeValue": 3.0})
"""
self.file = file
self.settings = {"physical_quantity": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"physical_quantity": physical_quantity, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -18,11 +18,28 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_schedule=None, attributes=None):
"""Edits the attributes of an IfcCostSchedule
For more information about the attributes and data types of an
IfcCostSchedule, consult the IFC documentation.
:param cost_schedule: The IfcCostSchedule entity you want to edit
:type cost_schedule: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
ifcopenshell.api.run("cost.edit_cost_schedule", model,
cost_schedule=schedule, attributes={"Name": "Foo"})
"""
self.file = file
self.settings = {"cost_schedule": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_schedule": cost_schedule, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -22,11 +22,31 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_value=None, attributes=None):
"""Edits the attributes of an IfcCostValue
For more information about the attributes and data types of an
IfcCostValue, consult the IFC documentation.
:param cost_value: The IfcCostValue entity you want to edit
:type cost_value: ifcopenshell.entity_instance.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# This cost item will have a total cost of 42
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 42.0})
"""
self.file = file
self.settings = {"cost_value": None, "attributes": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_value": cost_value, "attributes": attributes or {}}
def execute(self):
for name, value in self.settings["attributes"].items():
@@ -23,11 +23,33 @@ import ifcopenshell.util.element
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_value=None, formula=None):
"""Sets a cost value based on a formula, similar to formulas in spreadsheets
Costs may be made up of many components (e.g. labour, material, waste
factor, taxes, etc). This can be easily represented in the form of a
formula similar thta would be used in spreadsheet applications.
For more information, see ifcopenshell.util.cost
:param cost_value: The IfcCostValue to set the values of
:type cost_value: ifcopenshell.entity_instance.entity_instance
:param formula: The formula following the language of ifcopenshell.util.cost
:type formula: str
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value_formula", model, cost_value=value,
formula="5000 * 1.19")
"""
self.file = file
self.settings = {"cost_value": None, "formula": {}}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_value": cost_value, "formula": formula or {}}
def execute(self):
try:
@@ -20,11 +20,26 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None):
"""Removes a cost item
All associated relationships with the cost item are also removed,
however the related resources, products, and tasks themselves are
retained.
:param cost_item: The IfcCostItem entity you want to remove
:type cost_item: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
ifcopenshell.api.run("cost.remove_cost_item", model, cost_item=item)
"""
self.file = file
self.settings = {"cost_item": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item}
def execute(self):
# TODO: do a deep purge
@@ -18,11 +18,32 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None, physical_quantity=None):
"""Removes a quantity assigned to a cost item
If the quantity is part of a product (e.g. wall), then the quantity will
still exist and merely the relationship to the cost item will be
removed.
:param cost_item: The IfcCostItem that the quantity is assigned to
:type cost_item: ifcopenshell.entity_instance.entity_instance
:param physical_quantity: The IfcPhysicalQuantity to remove
:type physical_quantity: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
quantity = ifcopenshell.api.run("cost.add_cost_item_quantity", model,
cost_item=item, ifc_class="IfcQuantityVolume")
# Let's change our mind and delete it
ifcopenshell.api.run("cost.remove_cost_item", model,
cost_item=item, physical_quantity=quantity)
"""
self.file = file
self.settings = {"cost_item": None, "physical_quantity": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item, "physical_quantity": physical_quantity}
def execute(self):
if len(self.file.get_inverse(self.settings["physical_quantity"])) == 1:
@@ -18,11 +18,25 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_schedule=None):
"""Removes a cost schedule
All associated relationships with the cost schedule are also removed,
including all cost items.
:param cost_schedule: The IfcCostSchedule entity you want to remove
:type cost_schedule: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
ifcopenshell.api.run("cost.remove_cost_schedule", model, cost_schedule=schedule)
"""
self.file = file
self.settings = {"cost_schedule": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_schedule": cost_schedule}
def execute(self):
# TODO: do a deep purge
@@ -18,11 +18,34 @@
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, parent=None, cost_value=None):
"""Removes a cost value
The cost value may be assigned either to a cost item, a construction
resource, or another cost value (i.e. it is a subcomponent of a cost)
:param parent: The IfcCostItem, IfcConstructionResource, or IfcCostValue
that the IfcCostValue is assigned to.
:type parent: ifcopenshell.entity_instance.entity_instance
:param cost_value: The IfcCostValue that you want to remove
:type parent: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# This cost item will have a unit cost of 5 and a volume of 3
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5.0})
ifcopenshell.api.run("cost.remove_cost_value", model, parent=item, cost_value=value)
"""
self.file = file
self.settings = {"parent": None, "cost_value": None}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"parent": parent, "cost_value": cost_value}
def execute(self):
if len(self.file.get_inverse(self.settings["cost_value"])) == 1:
@@ -20,11 +20,52 @@ import ifcopenshell.api
class Usecase:
def __init__(self, file, **settings):
def __init__(self, file, cost_item=None, products=None):
"""Removes quantities of a cost item that are calculated on products
A cost item may have quantities that are parametrically calculated on
physical products. This lets you remove those quantities. This means
that any future changes in the physical product's dimensions will not
have any impact on the cost item.
:param cost_item: The IfcCostItem to remove quantities from
:type cost_item: ifcopenshell.entity_instance.entity_instance
:param products: A list of IfcProducts that may have parametrically
connected quantities to the cost item
:type products: list[ifcopenshell.entity_instance.entity_instance]
:return: None
:rtype: None
Example::
schedule = ifcopenshell.api.run("cost.add_cost_schedule", model)
item = ifcopenshell.api.run("cost.add_cost_item", model, cost_schedule=schedule)
# Let's imagine a unit cost of 5.0 per unit volume
value = ifcopenshell.api.run("cost.add_cost_value", model, parent=item)
ifcopenshell.api.run("cost.edit_cost_value", model, cost_value=value,
attributes={"AppliedValue": 5.0})
slab = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcSlab")
# Usually the quantity would be automatically calculated via a
# graphical authoring application but let's assign a manual quantity
# for now.
qto = ifcopenshell.api.run("pset.add_qto", model, product=slab, name="Qto_SlabBaseQuantities")
ifcopenshell.api.run("pset.edit_qto", model, qto=qto, properties={"NetVolume": 42.0})
# Now let's parametrically link the slab's quantity to the cost
# item. If the slab is edited in the future and 42.0 changes, then
# the updated value will also automatically be applied to the cost
# item.
ifcopenshell.api.run("cost.assign_cost_item_quantity", model,
cost_item=item, products=[slab], prop_name="NetVolume")
# Let's change our mind and remove the parametric connection
ifcopenshell.api.run("cost.unassign_cost_item_quantity", model,
cost_item=item, products=[slab])
"""
self.file = file
self.settings = {"cost_item": None, "products": []}
for key, value in settings.items():
self.settings[key] = value
self.settings = {"cost_item": cost_item, "products": products or []}
def execute(self):
self.quantities = set(self.settings["cost_item"].CostQuantities or [])