tested iwi costs

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-23 16:19:22 +00:00
parent 824b92fedd
commit 11ba4c64d0
5 changed files with 153 additions and 121 deletions

View file

@ -82,6 +82,7 @@ class Property(Definitions):
self.insulation_wall_area = None
self.floor_area = None
self.pitched_roof_area = None
self.insulation_floor_area = None
if epc_client:
self.epc_client = epc_client
@ -619,8 +620,10 @@ class Property(Definitions):
built_form=self.data["built-form"],
)
self.insulation_floor_area = self.floor_area / self.number_of_floors
self.pitched_roof_area = esimtate_pitched_roof_area(
floor_area=self.floor_area / self.number_of_floors, floor_height=self.floor_height
floor_area=self.insulation_floor_area, floor_height=self.floor_height
)
def set_wall_type(self):

View file

@ -160,19 +160,7 @@ class Costs:
:return: A dictionary containing detailed cost breakdown.
"""
# Cost per m2
# material = {
# "description": "Crown Loft Roll 44 glass fibre roll",
# "depth": 270,
# "thermal_conductivity": 0.044,
# "prime_cost": None,
# "material_cost": 5.91938,
# "labour_cost": 1.96,
# "labour_hours": 0.11
# }
material_cost_per_m2 = material["material_cost"]
# floor_area = self.property.floor_area
base_material_cost = material_cost_per_m2 * floor_area
labour_cost = material["labour_cost"] * floor_area * self.labour_adjustment_factor
@ -225,110 +213,6 @@ class Costs:
:return:
"""
# Parsing the provided table into a list of dictionaries
# non_insulation_materials = [
# {'type': 'iwi_wall_demolition',
# 'description': 'Solid & Dry Lined walls: Hack of wall finishes with chipping hammer; plaster to walls.',
# 'depth': 0.0, 'depth_unit': 0.0, 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.0,
# 'thermal_conductivity_unit': 0.0, 'prime_material_cost': 0.0, 'material_cost': 0.0, 'labour_cost': 10.27,
# 'labour_hours_per_unit': 0.33, 'plant_cost': 1.28, 'total_cost': 11.55, 'link': 'SPONs', 'Notes': 0.0},
# {'type': 'iwi_wall_demolition',
# 'description': 'Stud walls: Remove wall linings including battening behind; plasterboard and skim',
# 'depth': 0.0, 'depth_unit': 0.0, 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.0,
# 'thermal_conductivity_unit': 0.0, 'prime_material_cost': 0.0, 'material_cost': 0.0, 'labour_cost': 6.23,
# 'labour_hours_per_unit': 0.2, 'plant_cost': 1.25, 'total_cost': 7.48, 'link': 'SPONs', 'Notes': 0.0},
# {'type': 'iwi_wall_demolition',
# 'description': 'Lathe and Plaster walls: Remove wall linings including battening behind; wood lath and '
# 'plaster',
# 'depth': 0.0, 'depth_unit': 0.0, 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.0,
# 'thermal_conductivity_unit': 0.0, 'prime_material_cost': 0.0, 'material_cost': 0.0, 'labour_cost': 6.85,
# 'labour_hours_per_unit': 0.22, 'plant_cost': 2.09, 'total_cost': 8.94, 'link': 'SPONs', 'Notes': 0.0},
# {'Notes': "",
# 'cost_unit': "",
# 'depth': "",
# 'depth_unit': "",
# 'description': 'Visqueen High Performance Vapour Barrier',
# 'labour_cost': 0.48,
# 'labour_hours_per_unit': 0.02,
# 'link': 'SPONs',
# 'material_cost': 1.21,
# 'plant_cost': 0,
# 'prime_material_cost': 0.58,
# 'thermal_conductivity': "",
# 'thermal_conductivity_unit': "",
# 'total_cost': 1.69,
# 'type': 'iwi_vapour_barrier'},
# {'Notes': "",
# 'cost_unit': "",
# 'depth': "",
# 'depth_unit': "",
# 'description': 'Plaster; one coat Thistle board finish or other equal; steel trowelled; 3 mm thick work '
# 'to walls or ceilings; one coat; to plasterboard base; over 600mm wide',
# 'labour_cost': 6.58,
# 'labour_hours_per_unit': 0.25,
# 'link': "",
# 'material_cost': 0.06,
# 'plant_cost': 0,
# 'prime_material_cost': 0.0,
# 'thermal_conductivity': "",
# 'thermal_conductivity_unit': "",
# 'total_cost': 6.64,
# 'type': 'iwi_redecoration'},
# {'Notes': "",
# 'cost_unit': "",
# 'depth': "",
# 'depth_unit': "",
# 'description': 'Two coats emulsion paint on plaster, over 40mm girth; 3.5m - '
# '5m high',
# 'labour_cost': 0.0,
# 'labour_hours_per_unit': 0.21,
# 'link': "",
# 'material_cost': 0.41,
# 'plant_cost': 0,
# 'prime_material_cost': "",
# 'thermal_conductivity': "",
# 'thermal_conductivity_unit': "",
# 'total_cost': 4.34,
# 'type': 'iwi_redecoration'},
# {'Notes': "",
# 'cost_unit': "",
# 'depth': "",
# 'depth_unit': "",
# 'description': 'Fitting existing softwood skirting or architrave to new '
# 'frames; 150mm high',
# 'labour_cost': 4.87,
# 'labour_hours_per_unit': 0.01,
# 'link': "",
# 'material_cost': 4.86,
# 'plant_cost': 0,
# 'prime_material_cost': "",
# 'thermal_conductivity': "",
# 'thermal_conductivity_unit': "",
# 'total_cost': 4.88,
# 'type': 'iwi_redecoration'}
# ]
#
# material = {
# "type": "internal_wall_insulation",
# "description": "Ecotherm Eco-Versal PIR Insulation Board",
# "depth": 150,
# "depth_unit": "mm",
# "cost_unit": "gbp_per_m2",
# "thermal_conductivity": 0.022,
# "thermal_conductivity_unit": "watt_per_meter_kelvin",
# "prime_material_cost": "",
# "material_cost": 11.68,
# "labour_cost": 3.12,
# "labour_hours_per_unit": 0.18,
# "plant_cost": "",
# "total_cost": 14.8,
# "link": "SPONs"
# }
# Cost per m2
# wall_area = self.property.insulation_wall_area
# Extract and check the different types of data we'll need
demolition_data = [x for x in non_insulation_materials if x["type"] == "iwi_wall_demolition"]
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "iwi_vapour_barrier"]
@ -365,7 +249,8 @@ class Costs:
subtotal_before_profit = labour_costs + materials_costs + demolition_plant_costs
contingency_cost = subtotal_before_profit * self.CONTINGENCY
# We use high risk contingency for iwi
contingency_cost = subtotal_before_profit * self.HIGH_RISK_CONTINGENCY
preliminaries_cost = subtotal_before_profit * self.PRELIMINARIES
profit_cost = subtotal_before_profit * self.PROFIT_MARGIN
@ -384,7 +269,7 @@ class Costs:
redecoration_labour_hours)
# To install internal wall insulation, a small to medium size project might be conducted by a team of 3-5 people
labour_days = (labour_hours / 8) / 5
labour_days = (labour_hours / 8) / 4
return {
"total": total_cost,

View file

@ -58,7 +58,7 @@ class FloorRecommendations(Definitions):
)
property_type = self.property.data["property-type"]
floor_area = self.property.floor_area / self.property.number_of_floors
floor_area = self.property.insulation_floor_area
year_built = self.property.year_built
if self.property.floor["another_property_below"] | (self.property.floor["insulation_thickness"] in [
@ -137,7 +137,7 @@ class FloorRecommendations(Definitions):
if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
quantity = self.property.floor_area / self.property.number_of_floors
quantity = self.property.insulation_floor_area
estimated_cost = cost_per_unit * quantity

View file

@ -161,6 +161,7 @@ class RoofRecommendations:
if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
# TODO: We should use the floor area divided by the number of floors to get the area of the roof
estimated_cost = cost_per_unit * self.property.floor_area
if roof["is_pitched"]:

View file

@ -31,3 +31,146 @@ class TestCosts:
'contingency': 63.396792997100626, 'preliminaries': 63.396792997100626,
'material': 539.0166061175574, 'profit': 95.09518949565093,
'labour_hours': 6.234177828761786}
def test_loft_insulation(self):
mock_property = Mock()
mock_property.data = {
"county": "Northamptonshire"
}
costs = Costs(mock_property)
loft_material = {
"description": "Crown Loft Roll 44 glass fibre roll",
"depth": 270,
"thermal_conductivity": 0.044,
"prime_cost": None,
"material_cost": 5.91938,
"labour_cost": 1.96,
"labour_hours": 0.11
}
loft_results = costs.loft_insulation(
floor_area=33.5,
material=loft_material,
)
assert loft_results == {'total': 414.8496486, 'subtotal': 345.70804050000004, 'vat': 69.14160810000001,
'contingency': 25.608003000000004, 'preliminaries': 25.608003000000004,
'material': 198.29923000000002, 'profit': 38.4120045, 'labour_hours': 3.685}
def test_internal_wall_insulation(self):
mock_property = Mock()
mock_property.data = {
"county": "Northamptonshire"
}
costs = Costs(mock_property)
iwi_non_insulation_materials = [
{'type': 'iwi_wall_demolition',
'description': 'Solid & Dry Lined walls: Hack of wall finishes with chipping hammer; plaster to walls.',
'depth': 0.0, 'depth_unit': 0.0, 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.0,
'thermal_conductivity_unit': 0.0, 'prime_material_cost': 0.0, 'material_cost': 0.0, 'labour_cost': 10.27,
'labour_hours_per_unit': 0.33, 'plant_cost': 1.28, 'total_cost': 11.55, 'link': 'SPONs', 'Notes': 0.0},
{'type': 'iwi_wall_demolition',
'description': 'Stud walls: Remove wall linings including battening behind; plasterboard and skim',
'depth': 0.0, 'depth_unit': 0.0, 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.0,
'thermal_conductivity_unit': 0.0, 'prime_material_cost': 0.0, 'material_cost': 0.0, 'labour_cost': 6.23,
'labour_hours_per_unit': 0.2, 'plant_cost': 1.25, 'total_cost': 7.48, 'link': 'SPONs', 'Notes': 0.0},
{'type': 'iwi_wall_demolition',
'description': 'Lathe and Plaster walls: Remove wall linings including battening behind; wood lath and '
'plaster',
'depth': 0.0, 'depth_unit': 0.0, 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.0,
'thermal_conductivity_unit': 0.0, 'prime_material_cost': 0.0, 'material_cost': 0.0, 'labour_cost': 6.85,
'labour_hours_per_unit': 0.22, 'plant_cost': 2.09, 'total_cost': 8.94, 'link': 'SPONs', 'Notes': 0.0},
{'Notes': "",
'cost_unit': "",
'depth': "",
'depth_unit': "",
'description': 'Visqueen High Performance Vapour Barrier',
'labour_cost': 0.48,
'labour_hours_per_unit': 0.02,
'link': 'SPONs',
'material_cost': 1.21,
'plant_cost': 0,
'prime_material_cost': 0.58,
'thermal_conductivity': "",
'thermal_conductivity_unit': "",
'total_cost': 1.69,
'type': 'iwi_vapour_barrier'},
{'Notes': "",
'cost_unit': "",
'depth': "",
'depth_unit': "",
'description': 'Plaster; one coat Thistle board finish or other equal; steel trowelled; 3 mm thick work '
'to walls or ceilings; one coat; to plasterboard base; over 600mm wide',
'labour_cost': 6.58,
'labour_hours_per_unit': 0.25,
'link': "",
'material_cost': 0.06,
'plant_cost': 0,
'prime_material_cost': 0.0,
'thermal_conductivity': "",
'thermal_conductivity_unit': "",
'total_cost': 6.64,
'type': 'iwi_redecoration'},
{'Notes': "",
'cost_unit': "",
'depth': "",
'depth_unit': "",
'description': 'Two coats emulsion paint on plaster, over 40mm girth; 3.5m - '
'5m high',
'labour_cost': 0.0,
'labour_hours_per_unit': 0.21,
'link': "",
'material_cost': 0.41,
'plant_cost': 0,
'prime_material_cost': "",
'thermal_conductivity': "",
'thermal_conductivity_unit': "",
'total_cost': 4.34,
'type': 'iwi_redecoration'},
{'Notes': "",
'cost_unit': "",
'depth': "",
'depth_unit': "",
'description': 'Fitting existing softwood skirting or architrave to new '
'frames; 150mm high',
'labour_cost': 4.87,
'labour_hours_per_unit': 0.01,
'link': "",
'material_cost': 4.86,
'plant_cost': 0,
'prime_material_cost': "",
'thermal_conductivity': "",
'thermal_conductivity_unit': "",
'total_cost': 4.88,
'type': 'iwi_redecoration'}
]
iwi_material = {
"type": "internal_wall_insulation",
"description": "Ecotherm Eco-Versal PIR Insulation Board",
"depth": 150,
"depth_unit": "mm",
"cost_unit": "gbp_per_m2",
"thermal_conductivity": 0.022,
"thermal_conductivity_unit": "watt_per_meter_kelvin",
"prime_material_cost": "",
"material_cost": 11.68,
"labour_cost": 3.12,
"labour_hours_per_unit": 0.18,
"plant_cost": "",
"total_cost": 14.8,
"link": "SPONs"
}
iwi_results = costs.internal_wall_insulation(
wall_area=95.9104281347967,
material=iwi_material,
non_insulation_materials=iwi_non_insulation_materials
)
assert iwi_results == {'total': 6421.5484411659245, 'subtotal': 5351.29036763827, 'vat': 1070.258073527654,
'contingency': 573.3525393898148, 'preliminaries': 382.2350262598765,
'material': 1747.488000615996, 'profit': 573.3525393898148,
'labour_hours': 88.23759388401297, 'labour_days': 2.757424808875405}