mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Implemented cost framework
This commit is contained in:
parent
3426629418
commit
0b52dc8097
4 changed files with 63 additions and 22 deletions
|
|
@ -771,19 +771,38 @@ class Costs:
|
|||
:return:
|
||||
"""
|
||||
|
||||
number_of_windows = 7
|
||||
windows_cost = 345
|
||||
material_cost = material["material_cost"] * number_of_windows * self.SASH_WINDOW_INFLATION_FACTOR
|
||||
labour_cost = (
|
||||
material["labour_cost"] * number_of_windows * self.SASH_WINDOW_INFLATION_FACTOR *
|
||||
self.labour_adjustment_factor
|
||||
)
|
||||
|
||||
material_cost = windows_cost * number_of_windows * self.SASH_WINDOW_INFLATION_FACTOR
|
||||
subtotal = material_cost + labour_cost
|
||||
|
||||
subtotal = material_cost
|
||||
|
||||
contingency_cost = subtotal * 0.2
|
||||
preliminaries_cost = subtotal * 0.2
|
||||
profit_cost = subtotal * 0.2
|
||||
contingency_cost = subtotal * self.CONTINGENCY
|
||||
preliminaries_cost = subtotal * self.PRELIMINARIES
|
||||
profit_cost = subtotal * self.PROFIT_MARGIN
|
||||
|
||||
subtotal_before_vat = subtotal + contingency_cost + preliminaries_cost + profit_cost
|
||||
|
||||
vat_cost = subtotal_before_vat * 0.2
|
||||
vat_cost = subtotal_before_vat * self.VAT_RATE
|
||||
|
||||
total_cost = subtotal_before_vat + vat_cost
|
||||
|
||||
labour_hours = material["labour_hours_per_unit"] * number_of_windows
|
||||
|
||||
# Assume a team of 2
|
||||
labour_days = (labour_hours / 8) / 2
|
||||
|
||||
return {
|
||||
"total": total_cost,
|
||||
"subtotal": subtotal_before_vat,
|
||||
"vat": vat_cost,
|
||||
"contingency": contingency_cost,
|
||||
"preliminaries": preliminaries_cost,
|
||||
"material": material_cost,
|
||||
"profit": profit_cost,
|
||||
"labour_hours": labour_hours,
|
||||
"labour_cost": labour_cost,
|
||||
"labour_days": labour_days
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@ class WindowsRecommendations:
|
|||
|
||||
self.recommendation = []
|
||||
|
||||
self.glazing_materials = [
|
||||
material for material in materials if material["type"] == "window_glazing"
|
||||
self.glazing_material = [
|
||||
material for material in materials if material["type"] == "windows_glazing"
|
||||
]
|
||||
|
||||
# TODO: This will be populated with the works associated to upgrading glazing. This will involve removal of
|
||||
# previous glazing and installation of new glazing. This will not include the cost of the windows material
|
||||
# themselfs
|
||||
self.glazing_works_materials = []
|
||||
if len(self.glazing_material) != 1:
|
||||
raise ValueError("There should only be one window glazing material")
|
||||
self.glazing_material = self.glazing_material[0]
|
||||
|
||||
def recommend(self):
|
||||
"""
|
||||
|
|
@ -34,12 +33,14 @@ class WindowsRecommendations:
|
|||
if not number_of_windows:
|
||||
raise ValueError("Number of windows not specified")
|
||||
|
||||
if self.property.windows["has_glazing"] & self.property.windows["glazing_coverage"] == "full":
|
||||
if self.property.windows["has_glazing"] & (self.property.windows["glazing_coverage"] == "full"):
|
||||
return
|
||||
|
||||
# We then price the job based on the number of windows that there are
|
||||
|
||||
cost_result = {}
|
||||
cost_result = self.costs.window_glazing(
|
||||
number_of_windows=number_of_windows,
|
||||
material=self.glazing_material,
|
||||
)
|
||||
|
||||
description = None
|
||||
|
||||
|
|
|
|||
|
|
@ -942,8 +942,24 @@ materials = [
|
|||
'https://www.hamuch.com/cost/led-spot-light#:~:text=It%20costs%20an%20average%20of,'
|
||||
'will%20drive%20up%20the%20cost.',
|
||||
'created_at': datetime.datetime(2023, 11, 28, 22, 49, 12, 244907), 'is_active': True, 'prime_material_cost': None,
|
||||
'material_cost': 20.0, 'labour_cost': 46.0, 'labour_hours_per_unit': 0.8, 'plant_cost': 0.0, 'total_cost': 66.0,
|
||||
'material_cost': 20.0, 'labour_cost': 15.0, 'labour_hours_per_unit': 0.8, 'plant_cost': 0.0, 'total_cost': 66.0,
|
||||
'notes': 'We estimate the unit economics from the checkatrade article. We assume that the average job consists '
|
||||
'of installing 6 lights based on the hamuch article. We use the median value of 400 for a job of 6 '
|
||||
'lights'}
|
||||
'lights'},
|
||||
{'id': 1235, 'type': 'windows_glazing',
|
||||
'description': 'uPVC windows; Profile 22 or other equal and approved; reinforced where appropriate with '
|
||||
'aluminium alloy; in refurbishment work, including standard ironmongery; sills and factory glazed '
|
||||
'with low-e 24 mm double glazing; removing existing windows and fixing new in position; including '
|
||||
'lugs plugged and screwed to brickwork or blockwork; Casement/fixed light; including vents; '
|
||||
'e.p.d.m. glazing gaskets and weather seals; 1770 mm × 1200 mm; ref P312WW',
|
||||
'depth': 0.0, 'depth_unit': None, 'cost': None, 'cost_unit': 'gbp_per_unit', 'r_value_per_mm': None,
|
||||
'r_value_unit': 'square_meter_kelvin_per_watt', 'thermal_conductivity': None, 'thermal_conductivity_unit': None,
|
||||
'link': 'SPONs',
|
||||
'created_at': datetime.datetime(2023, 11, 28, 22, 49, 12, 244907),
|
||||
'is_active': True, 'prime_material_cost': 176.55,
|
||||
'material_cost': 182.25, 'labour_cost': 163.36, 'labour_hours_per_unit': 6.5, 'plant_cost': 0.0,
|
||||
'total_cost': 345.61,
|
||||
'notes': 'This is the cost of removal of existing windows and installation of new windows. This is a casement '
|
||||
'style window, which is the most common but also the cheapest style. In the cost estimation framework, '
|
||||
'we can inflate prices for different finishes, to be conservative on price.'}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from recommendations.WindowsRecommendations import WindowsRecommendations
|
||||
from backend.Property import Property
|
||||
from unittest.mock import Mock
|
||||
from recommendations.tests.test_data.materials import materials
|
||||
|
||||
|
||||
class TestWindowRecommendations:
|
||||
|
|
@ -25,6 +26,10 @@ class TestWindowRecommendations:
|
|||
'glazing_type': 'single',
|
||||
'no_data': False
|
||||
}
|
||||
property_1.number_of_windows = 5
|
||||
property_1.number_of_windows = 7
|
||||
|
||||
recommender = WindowsRecommendations(property_instance=property_1, materials=[])
|
||||
recommender = WindowsRecommendations(property_instance=property_1, materials=materials)
|
||||
|
||||
assert not recommender.recommendation
|
||||
|
||||
recommender.recommend()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue