Added unit tests for costs

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-23 16:30:38 +00:00
parent 11ba4c64d0
commit ee698c40b5
2 changed files with 254 additions and 184 deletions

View file

@ -150,7 +150,8 @@ class Costs:
"preliminaries": preliminaries_cost,
"material": base_material_cost,
"profit": profit_cost,
"labour_hours": labour_hours
"labour_hours": labour_hours,
"labour_cost": labour_cost
}
def loft_insulation(self, floor_area, material):
@ -187,7 +188,8 @@ class Costs:
"preliminaries": preliminaries_cost,
"material": base_material_cost,
"profit": profit_cost,
"labour_hours": labour_hours
"labour_hours": labour_hours,
"labour_cost": labour_cost
}
def internal_wall_insulation(self, wall_area, material, non_insulation_materials):
@ -280,7 +282,8 @@ class Costs:
"material": materials_costs,
"profit": profit_cost,
"labour_hours": labour_hours,
"labour_days": labour_days
"labour_days": labour_days,
"labour_cost": labour_costs
}
def suspended_floor_insulation(self, insulation_floor_area, material, non_insulation_materials):
@ -297,45 +300,6 @@ class Costs:
:return:
"""
# material = {'type': 'suspended_floor_insulation', 'description': 'Thermafleece CosyWool Roll', 'depth': 140.0,
# 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.039,
# 'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
# 'material_cost': 11.68, 'labour_cost': 1.78, 'labour_hours_per_unit': 0.1, 'plant_cost': 0,
# 'total_cost': 13.46, 'link': 'SPONs',
# 'Notes': 'Spons did not contain labour costs so we use values for similar insulations. We use
# the '
# 'same values as in Crown loft roll 44, since it is also an insulation roll'}
#
# non_insulation_materials = [
# {'type': 'suspended_floor_demolition', 'description': 'Removal of carpet and underfelt', 'depth': 0,
# 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 3.32, 'labour_hours_per_unit': 0.11,
# 'plant_cost': 0, 'total_cost': 3.32, 'link': 'SPONs',
# 'Notes': 'We ignore the plant cost that is in SPONs because we assume the carpet is not scrapped and '
# 'therefore there is no need for a skip'},
# {'type': 'suspended_floor_demolition',
# 'description': 'Remove boarding; withdraw nails; set aside for reuse; ground level', 'depth': 0,
# 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 9.34, 'labour_hours_per_unit': 0.3,
# 'plant_cost': 0, 'total_cost': 9.34, 'link': 'SPONs', 'Notes': 0},
# {'type': 'suspended_floor_vapour_barrier', 'description': 'Visqueen High Performance Vapour Barrier',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0, 'prime_material_cost': 0.58, 'material_cost': 1.21, 'labour_cost': 0.48,
# 'labour_hours_per_unit': 0.02, 'plant_cost': 0, 'total_cost': 1.69, 'link': 'SPONs', 'Notes': 0},
# {'type': 'suspended_floor_redecoration', 'description': 'refix floorboards previously set aside',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0, 'prime_material_cost': 0, 'material_cost': 1.54, 'labour_cost': 24.98,
# 'labour_hours_per_unit': 0.74, 'plant_cost': 0, 'total_cost': 26.52, 'link': 'SPONs', 'Notes': 0},
# {'type': 'suspended_floor_redecoration', 'description': 'Fitting carpet', 'depth': 0, 'depth_unit': 0,
# 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.59, 'labour_hours_per_unit': 0.37,
# 'plant_cost': 0, 'total_cost': 6.59, 'link': 'SPONs',
# 'Notes': 'SPONs does not have data on re-fitting the carpet so we use the data in Fitted carpeting; '
# 'Gradus woven polypropylene tufted loop\n\n as a baseline. We assume re-use of carpets, '
# 'therefore we need just labour rates'}]
# insulation_floor_area = self.property.floor_area / self.property.number_of_floors
demolition_data = [x for x in non_insulation_materials if x["type"] == "suspended_floor_demolition"]
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "suspended_floor_vapour_barrier"]
redecoration_data = [x for x in non_insulation_materials if x["type"] == "suspended_floor_redecoration"]
@ -394,7 +358,8 @@ class Costs:
"material": materials_costs,
"profit": profit_cost,
"labour_hours": labour_hours,
"labour_days": labour_days
"labour_days": labour_days,
"labour_cost": labour_costs
}
def solid_floor_insulation(self, insulation_floor_area, material, non_insulation_materials):
@ -428,78 +393,13 @@ class Costs:
7) Considerations for Doors and Fixtures: It's important to note that raising the floor level can affect door
thresholds and other fixtures. Doors may need to be trimmed, and fixtures might need adjustments.
:param material:
:param non_insulation_materials:
:param insulation_floor_area: Area of the floor to be insulated
:param material: Selected insulation material
:param non_insulation_materials: Non-insulation materials required for the job
:return:
"""
# material = {
# 'type': 'solid_floor_insulation', 'description': 'Kay-Cel Expanded Polystyrene Board',
# 'depth': 100.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.033,
# 'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
# 'material_cost': 12.02, 'labour_cost': 4.4, 'labour_hours_per_unit': 0.19, 'plant_cost': 0,
# 'total_cost': 16.42, 'link': 'SPONs', 'Notes': 0
# }
#
# non_insulation_materials = [
# {'type': 'solid_floor_demolition', 'description': 'Removal of carpet and underfelt', 'depth': 0,
# 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 3.32, 'labour_hours_per_unit': 0.11,
# 'plant_cost': 0, 'total_cost': 3.32, 'link': 'SPONs',
# 'Notes': 'We ignore the plant cost that is in SPONs because we assume the carpet is not scrapped and '
# 'therefore there is no need for a skip'},
# {'type': 'solid_floor_preparation',
# 'description': 'clean surface of concrete to receive new damp-proof membrane', 'depth': 0,
# 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 4.36, 'labour_hours_per_unit': 0.14,
# 'plant_cost': 0, 'total_cost': 4.36, 'link': 0, 'Notes': 0}, {'type': 'solid_floor_preparation',
# 'description': 'Clean out crack to '
# 'form a 20mm×20mm '
# 'groove and fill with '
# 'cement: mortar mixed '
# 'with bonding agent',
# 'depth': 0, 'depth_unit': 0,
# 'cost_unit': 0,
# 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0,
# 'material_cost': 6.91,
# 'labour_cost': 18.99,
# 'labour_hours_per_unit': 0.61,
# 'plant_cost': 0.16,
# 'total_cost': 26.06, 'link': 0,
# 'Notes': 'This step is the '
# 'assessment and repair of '
# 'any damage to the concrete '
# 'floor such as filling '
# 'cracks or levelling uneven '
# 'areas'},
# {'type': 'solid_floor_vapour_barrier', 'description': 'Visqueen High Performance Vapour Barrier',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0, 'prime_material_cost': 0.58, 'material_cost': 1.21, 'labour_cost': 0.48,
# 'labour_hours_per_unit': 0.02, 'plant_cost': 0, 'total_cost': 1.69, 'link': 'SPONs', 'Notes': 0},
# {'type': 'solid_floor_redecoration',
# 'description': 'Screeded beds; protection to compressible formwork exceeding 600mm wide', 'depth': 0,
# 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 9.6, 'material_cost': 9.89, 'labour_cost': 2.67, 'labour_hours_per_unit': 0.15,
# 'plant_cost': 0, 'total_cost': 12.56, 'link': 'SPONs',
# 'Notes': 'This is the screed layer, placed on top of the insulation'},
# {'type': 'solid_floor_redecoration', 'description': 'Fitting carpet', 'depth': 0, 'depth_unit': 0,
# 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.59, 'labour_hours_per_unit': 0.37,
# 'plant_cost': 0, 'total_cost': 6.59, 'link': 'SPONs',
# 'Notes': 'SPONs does not have data on re-fitting the carpet so we use the data in Fitted carpeting; '
# 'Gradus woven polypropylene tufted loop\n\n as a baseline. We assume re-use of carpets, '
# 'therefore we need just labour rates'},
# {'type': 'solid_floor_redecoration',
# 'description': 'Fitting existing softwood skirting or architrave to new frames; 150mm high', 'depth': 0,
# 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0.01, 'labour_cost': 4.87, 'labour_hours_per_unit': 0.12,
# 'plant_cost': 0, 'total_cost': 4.88, 'link': 'SPONs', 'Notes': 0}
# ]
# insulation_floor_area = self.property.floor_area / self.property.number_of_floors
demolition_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_demolition"]
preparation_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_preparation"]
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "solid_floor_vapour_barrier"]
@ -564,7 +464,8 @@ class Costs:
"material": materials_cost,
"profit": profit_cost,
"labour_hours": labour_hours,
"labour_days": labour_days
"labour_days": labour_days,
"labour_cost": labour_costs
}
def external_wall_insulation(self, wall_area, material, non_insulation_materials):
@ -632,73 +533,6 @@ class Costs:
else:
raise ValueError("Unsupported property type - haven't handled flats")
# non_insulation_materials = [x for x in df if x["type"] != "external_wall_insulation"]
# insulation_materials = [x for x in df if x["type"] == "external_wall_insulation"]
# material = {'type': 'external_wall_insulation', 'description': 'Ecotherm Eco-Versal PIR Insulation Board',
# 'depth': 150.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.022,
# 'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 23.53,
# 'material_cost': 34.62, 'labour_cost': 33.06, 'labour_hours_per_unit': 1.4, 'plant_cost': 0,
# 'total_cost': 67.68, 'link': 'SPONs', 'Notes': 0}
# non_insulation_materials = [
# {'type': 'ewi_wall_demolition',
# 'description': 'Solid & Dry Lined walls: Hack of wall finishes with chipping '
# 'hammer; plaster to walls.',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 'gbp_per_m2',
# 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 10.27,
# 'labour_hours_per_unit': 0.33, 'plant_cost': 1.28, 'total_cost': 11.55,
# 'link': 'SPONs', 'Notes': 0}, {'type': 'ewi_wall_demolition',
# 'description': 'Stud walls: Remove wall linings '
# 'including battening behind; '
# 'plasterboard and skim',
# 'depth': 0, 'depth_unit': 0,
# 'cost_unit': 'gbp_per_m2',
# 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0,
# 'labour_cost': 6.23, 'labour_hours_per_unit': 0.2,
# 'plant_cost': 1.25, 'total_cost': 7.48,
# 'link': 'SPONs', 'Notes': 0},
# {'type': 'ewi_wall_demolition',
# 'description': 'Lathe and Plaster walls: Remove wall linings including battening '
# 'behind; wood lath and plaster',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 'gbp_per_m2',
# 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.85,
# 'labour_hours_per_unit': 0.22, 'plant_cost': 2.09, 'total_cost': 8.94,
# 'link': 'SPONs', 'Notes': 0}, {'type': 'ewi_wall_preparation',
# 'description': 'Clean and prepare surfaces, '
# 'one coat Keim dilution, '
# 'one coat primer and two coats '
# 'of Keim Ecosil paint; Brick or '
# 'block walls; over 300 mm girth',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 0,
# 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0,
# 'prime_material_cost': 0, 'material_cost': 7.3,
# 'labour_cost': 5.62, 'labour_hours_per_unit': 0.3,
# 'plant_cost': 0, 'total_cost': 12.92,
# 'link': 'SPONs',
# 'Notes': 'This work covers the preparation and '
# 'priming of the wall before insulating'},
# {'type': 'ewi_wall_redecoration',
# 'description': 'EPS insulation fixed with adhesive to SFS structure (measured '
# 'separately) with horizontal PVC intermediate track and vertical '
# 'T-spines; with glassfibre mesh reinforcement embedded in Sto '
# 'Armat Classic Basecoat Render and Stolit K 1.5 Decorative '
# 'Topcoat Render (white)',
# 'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
# 'thermal_conductivity_unit': 0, 'prime_material_cost': 0, 'material_cost': 0,
# 'labour_cost': 0, 'labour_hours_per_unit': 0, 'plant_cost': 0,
# 'total_cost': 69.94, 'link': 'SPONs',
# 'Notes': 'This material in SPONs is for 70mm EPS insulation, which comes in at a '
# 'cost of 99.17 per meter square. This includes the cost of insulation. '
# 'To get the costing for just the works and not the insulation, '
# 'we subtract the cost of EPS insulation, using Ravathem 75mm insulation '
# 'as an example, which costs £29.23 per meter square, giving us the cost '
# 'of the remaining works without insulation. This material gives us a '
# 'cost for basecoat, mesh application and a render finish'}]
demolition_data = [x for x in non_insulation_materials if x["type"] == "ewi_wall_demolition"]
preparation_data = [x for x in non_insulation_materials if x["type"] == "ewi_wall_preparation"]
redecoration_data = [x for x in non_insulation_materials if x["type"] == "ewi_wall_redecoration"]
@ -759,5 +593,6 @@ class Costs:
"material": materials_costs,
"profit": profit_cost,
"labour_hours": labour_hours,
"labour_days": labour_days
"labour_days": labour_days,
"labour_cost": labour_costs
}

View file

@ -30,7 +30,7 @@ class TestCosts:
assert cwi_results == {'total': 1027.0280465530302, 'subtotal': 855.8567054608585, 'vat': 171.1713410921717,
'contingency': 63.396792997100626, 'preliminaries': 63.396792997100626,
'material': 539.0166061175574, 'profit': 95.09518949565093,
'labour_hours': 6.234177828761786}
'labour_hours': 6.234177828761786, 'labour_cost': 94.95132385344874}
def test_loft_insulation(self):
mock_property = Mock()
@ -56,7 +56,8 @@ class TestCosts:
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}
'material': 198.29923000000002, 'profit': 38.4120045, 'labour_hours': 3.685,
'labour_cost': 57.7808}
def test_internal_wall_insulation(self):
mock_property = Mock()
@ -173,4 +174,238 @@ class TestCosts:
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}
'labour_hours': 88.23759388401297, 'labour_days': 2.757424808875405,
'labour_cost': 1927.1602026551818}
def test_suspended_floor_insulation(self):
mock_property = Mock()
mock_property.data = {
"county": "Northamptonshire"
}
costs = Costs(mock_property)
sus_floor_material = {'type': 'suspended_floor_insulation', 'description': 'Thermafleece CosyWool Roll',
'depth': 140.0,
'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.039,
'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
'material_cost': 11.68, 'labour_cost': 1.78, 'labour_hours_per_unit': 0.1,
'plant_cost': 0,
'total_cost': 13.46, 'link': 'SPONs',
'Notes': 'Spons did not contain labour costs so we use values for similar insulations. '
'We use the '
'same values as in Crown loft roll 44, since it is also an insulation roll'}
sus_floor_non_insulation_materials = [
{'type': 'suspended_floor_demolition', 'description': 'Removal of carpet and underfelt', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 3.32, 'labour_hours_per_unit': 0.11,
'plant_cost': 0, 'total_cost': 3.32, 'link': 'SPONs',
'Notes': 'We ignore the plant cost that is in SPONs because we assume the carpet is not scrapped and '
'therefore there is no need for a skip'},
{'type': 'suspended_floor_demolition',
'description': 'Remove boarding; withdraw nails; set aside for reuse; ground level', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 9.34, 'labour_hours_per_unit': 0.3,
'plant_cost': 0, 'total_cost': 9.34, 'link': 'SPONs', 'Notes': 0},
{'type': 'suspended_floor_vapour_barrier', 'description': 'Visqueen High Performance Vapour Barrier',
'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
'thermal_conductivity_unit': 0, 'prime_material_cost': 0.58, 'material_cost': 1.21, 'labour_cost': 0.48,
'labour_hours_per_unit': 0.02, 'plant_cost': 0, 'total_cost': 1.69, 'link': 'SPONs', 'Notes': 0},
{'type': 'suspended_floor_redecoration', 'description': 'refix floorboards previously set aside',
'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
'thermal_conductivity_unit': 0, 'prime_material_cost': 0, 'material_cost': 1.54, 'labour_cost': 24.98,
'labour_hours_per_unit': 0.74, 'plant_cost': 0, 'total_cost': 26.52, 'link': 'SPONs', 'Notes': 0},
{'type': 'suspended_floor_redecoration', 'description': 'Fitting carpet', 'depth': 0, 'depth_unit': 0,
'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.59, 'labour_hours_per_unit': 0.37,
'plant_cost': 0, 'total_cost': 6.59, 'link': 'SPONs',
'Notes': 'SPONs does not have data on re-fitting the carpet so we use the data in Fitted carpeting; '
'Gradus woven polypropylene tufted loop\n\n as a baseline. We assume re-use of carpets, '
'therefore we need just labour rates'}]
sus_floor_results = costs.suspended_floor_insulation(
insulation_floor_area=33.5,
material=sus_floor_material,
non_insulation_materials=sus_floor_non_insulation_materials
)
assert sus_floor_results == {
'total': 3003.366924, 'subtotal': 2502.80577, 'vat': 500.561154,
'contingency': 185.39302, 'preliminaries': 185.39302, 'material': 483.405,
'profit': 278.08952999999997, 'labour_hours': 54.940000000000005,
'labour_days': 2.289166666666667, 'labour_cost': 1370.5252
}
def test_solid_floor_insulation(self):
mock_property = Mock()
mock_property.data = {
"county": "Northamptonshire"
}
costs = Costs(mock_property)
sol_floor_material = {
'type': 'solid_floor_insulation', 'description': 'Kay-Cel Expanded Polystyrene Board',
'depth': 100.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.033,
'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
'material_cost': 12.02, 'labour_cost': 4.4, 'labour_hours_per_unit': 0.19, 'plant_cost': 0,
'total_cost': 16.42, 'link': 'SPONs', 'Notes': 0
}
sol_floor_non_insulation_materials = [
{'type': 'solid_floor_demolition', 'description': 'Removal of carpet and underfelt', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 3.32, 'labour_hours_per_unit': 0.11,
'plant_cost': 0, 'total_cost': 3.32, 'link': 'SPONs',
'Notes': 'We ignore the plant cost that is in SPONs because we assume the carpet is not scrapped and '
'therefore there is no need for a skip'},
{'type': 'solid_floor_preparation',
'description': 'clean surface of concrete to receive new damp-proof membrane', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 4.36, 'labour_hours_per_unit': 0.14,
'plant_cost': 0, 'total_cost': 4.36, 'link': 0, 'Notes': 0}, {'type': 'solid_floor_preparation',
'description': 'Clean out crack to '
'form a 20mm×20mm '
'groove and fill with '
'cement: mortar mixed '
'with bonding agent',
'depth': 0, 'depth_unit': 0,
'cost_unit': 0,
'thermal_conductivity': 0,
'thermal_conductivity_unit': 0,
'prime_material_cost': 0,
'material_cost': 6.91,
'labour_cost': 18.99,
'labour_hours_per_unit': 0.61,
'plant_cost': 0.16,
'total_cost': 26.06, 'link': 0,
'Notes': 'This step is the '
'assessment and repair of '
'any damage to the concrete '
'floor such as filling '
'cracks or levelling uneven '
'areas'},
{'type': 'solid_floor_vapour_barrier', 'description': 'Visqueen High Performance Vapour Barrier',
'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
'thermal_conductivity_unit': 0, 'prime_material_cost': 0.58, 'material_cost': 1.21, 'labour_cost': 0.48,
'labour_hours_per_unit': 0.02, 'plant_cost': 0, 'total_cost': 1.69, 'link': 'SPONs', 'Notes': 0},
{'type': 'solid_floor_redecoration',
'description': 'Screeded beds; protection to compressible formwork exceeding 600mm wide', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 9.6, 'material_cost': 9.89, 'labour_cost': 2.67, 'labour_hours_per_unit': 0.15,
'plant_cost': 0, 'total_cost': 12.56, 'link': 'SPONs',
'Notes': 'This is the screed layer, placed on top of the insulation'},
{'type': 'solid_floor_redecoration', 'description': 'Fitting carpet', 'depth': 0, 'depth_unit': 0,
'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.59, 'labour_hours_per_unit': 0.37,
'plant_cost': 0, 'total_cost': 6.59, 'link': 'SPONs',
'Notes': 'SPONs does not have data on re-fitting the carpet so we use the data in Fitted carpeting; '
'Gradus woven polypropylene tufted loop\n\n as a baseline. We assume re-use of carpets, '
'therefore we need just labour rates'},
{'type': 'solid_floor_redecoration',
'description': 'Fitting existing softwood skirting or architrave to new frames; 150mm high', 'depth': 0,
'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0.01, 'labour_cost': 4.87, 'labour_hours_per_unit': 0.12,
'plant_cost': 0, 'total_cost': 4.88, 'link': 'SPONs', 'Notes': 0}
]
sol_floor_results = costs.solid_floor_insulation(
insulation_floor_area=33.5,
material=sol_floor_material,
non_insulation_materials=sol_floor_non_insulation_materials
)
assert sol_floor_results == {
'total': 3962.021952, 'subtotal': 3301.68496, 'vat': 660.336992, 'contingency': 353.75196,
'preliminaries': 235.83464, 'material': 1006.3399999999999, 'profit': 353.75196, 'labour_hours': 57.285,
'labour_days': 2.386875, 'labour_cost': 1346.6464
}
def test_external_wall_insulation(self):
mock_property = Mock()
mock_property.data = {
"county": "Northamptonshire",
"property-type": "House",
"built-form": 'End-Terrace'
}
costs = Costs(mock_property)
ewi_material = {'type': 'external_wall_insulation', 'description': 'Ecotherm Eco-Versal PIR Insulation Board',
'depth': 150.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.022,
'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 23.53,
'material_cost': 34.62, 'labour_cost': 33.06, 'labour_hours_per_unit': 1.4, 'plant_cost': 0,
'total_cost': 67.68, 'link': 'SPONs', 'Notes': 0}
ewi_non_insulation_materials = [
{'type': 'ewi_wall_demolition',
'description': 'Solid & Dry Lined walls: Hack of wall finishes with chipping '
'hammer; plaster to walls.',
'depth': 0, 'depth_unit': 0, 'cost_unit': 'gbp_per_m2',
'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 10.27,
'labour_hours_per_unit': 0.33, 'plant_cost': 1.28, 'total_cost': 11.55,
'link': 'SPONs', 'Notes': 0}, {'type': 'ewi_wall_demolition',
'description': 'Stud walls: Remove wall linings '
'including battening behind; '
'plasterboard and skim',
'depth': 0, 'depth_unit': 0,
'cost_unit': 'gbp_per_m2',
'thermal_conductivity': 0,
'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0,
'labour_cost': 6.23, 'labour_hours_per_unit': 0.2,
'plant_cost': 1.25, 'total_cost': 7.48,
'link': 'SPONs', 'Notes': 0},
{'type': 'ewi_wall_demolition',
'description': 'Lathe and Plaster walls: Remove wall linings including battening '
'behind; wood lath and plaster',
'depth': 0, 'depth_unit': 0, 'cost_unit': 'gbp_per_m2',
'thermal_conductivity': 0, 'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 0, 'labour_cost': 6.85,
'labour_hours_per_unit': 0.22, 'plant_cost': 2.09, 'total_cost': 8.94,
'link': 'SPONs', 'Notes': 0}, {'type': 'ewi_wall_preparation',
'description': 'Clean and prepare surfaces, '
'one coat Keim dilution, '
'one coat primer and two coats '
'of Keim Ecosil paint; Brick or '
'block walls; over 300 mm girth',
'depth': 0, 'depth_unit': 0, 'cost_unit': 0,
'thermal_conductivity': 0,
'thermal_conductivity_unit': 0,
'prime_material_cost': 0, 'material_cost': 7.3,
'labour_cost': 5.62, 'labour_hours_per_unit': 0.3,
'plant_cost': 0, 'total_cost': 12.92,
'link': 'SPONs',
'Notes': 'This work covers the preparation and '
'priming of the wall before insulating'},
{'type': 'ewi_wall_redecoration',
'description': 'EPS insulation fixed with adhesive to SFS structure (measured '
'separately) with horizontal PVC intermediate track and vertical '
'T-spines; with glassfibre mesh reinforcement embedded in Sto '
'Armat Classic Basecoat Render and Stolit K 1.5 Decorative '
'Topcoat Render (white)',
'depth': 0, 'depth_unit': 0, 'cost_unit': 0, 'thermal_conductivity': 0,
'thermal_conductivity_unit': 0, 'prime_material_cost': 0, 'material_cost': 0,
'labour_cost': 0, 'labour_hours_per_unit': 0, 'plant_cost': 0,
'total_cost': 69.94, 'link': 'SPONs',
'Notes': 'This material in SPONs is for 70mm EPS insulation, which comes in at a '
'cost of 99.17 per meter square. This includes the cost of insulation. '
'To get the costing for just the works and not the insulation, '
'we subtract the cost of EPS insulation, using Ravathem 75mm insulation '
'as an example, which costs £29.23 per meter square, giving us the cost '
'of the remaining works without insulation. This material gives us a '
'cost for basecoat, mesh application and a render finish'}]
ewi_results = costs.external_wall_insulation(
wall_area=95.9104281347967,
material=ewi_material,
non_insulation_materials=ewi_non_insulation_materials
)
assert ewi_results == {
'total': 13590.909723215433, 'subtotal': 11325.758102679527, 'vat': 2265.1516205359053,
'contingency': 808.9827216199662, 'preliminaries': 1213.4740824299492,
'material': 4020.565147410677, 'profit': 1213.4740824299492,
'labour_hours': 187.02533486285358, 'labour_days': 5.8445417144641745,
'labour_cost': 3921.5600094613983
}