mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Map LbwfHouse to AssetCondition list 🟥
This commit is contained in:
parent
694bb0b569
commit
c8abc19e59
5 changed files with 375 additions and 8 deletions
|
|
@ -6,6 +6,9 @@ from backend.condition.domain.element import Element
|
||||||
@dataclass
|
@dataclass
|
||||||
class AssetCondition:
|
class AssetCondition:
|
||||||
uprn: int
|
uprn: int
|
||||||
element: Element
|
element: Element # TODO: should HHSRS elements be handled differently?
|
||||||
condition_description: str
|
condition_description: str # TODO: this probably needs to be some sort of enum so it's searchable/filterable on the frontend
|
||||||
|
quantity: int
|
||||||
renewal_year: Optional[int] = None
|
renewal_year: Optional[int] = None
|
||||||
|
source: Optional[str] = None
|
||||||
|
# TODO: add install_date
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,123 @@
|
||||||
from enum import Enum
|
from enum import StrEnum
|
||||||
|
|
||||||
class Element(Enum):
|
|
||||||
pass
|
class Element(StrEnum):
|
||||||
|
AHR_CAT = "Accessible Housing Register Category"
|
||||||
|
ASBESTOS = "Asbestos Present"
|
||||||
|
ASSETSAREA = "Assets Area for Decent Homes and Investment"
|
||||||
|
DECNTHMINC = "Include for Decent Homes Reporting - LBWF Stock"
|
||||||
|
EICINSFREQ = "EICR - Elec Install Conditions Report Inspection Frequency"
|
||||||
|
EXTBALCONY = "Private Balconies in External Area"
|
||||||
|
EXTBKSDDR1 = "Back and Side Doors 1 in External Area"
|
||||||
|
EXTBKSDDR2 = "Back and Side Doors 2 in External Area"
|
||||||
|
EXTBPOINTG = "Brickwork Pointing in External Area"
|
||||||
|
EXTCHIMNEY = "Chimneys in External Area"
|
||||||
|
EXTDWNPTYP = "Downpipes in External Area"
|
||||||
|
EXTDRPKERB = "Drop Kerb in External Area"
|
||||||
|
EXTEXTDECS = "External Decorations in External Area"
|
||||||
|
EXTFASOFBR = "Fascia / Soffit / Bargeboard in External Area"
|
||||||
|
EXTGARDOOR = "Garage Door in External Area"
|
||||||
|
EXTGARROOF = "Garage Roof in External Area"
|
||||||
|
EXTGARSTDR = "Garage and Store Doors in External Area"
|
||||||
|
EXTGARSTRF = "Garage and Store Roofs in External Area"
|
||||||
|
EXTGARSTWD = "Garage and Store Windows in External Area"
|
||||||
|
EXTGARWDWS = "Garage Windows in External Area"
|
||||||
|
EXTGUTRTYP = "Gutters in External Area"
|
||||||
|
EXTHARDSTD = "Hardstanding in External Area"
|
||||||
|
EXTINTDWNP = "Internal Downpipes in External Area"
|
||||||
|
EXTLINTELS = "Lintels in External Area"
|
||||||
|
EXTOUTBOH = "Overhaul of Outbuilding in External Area"
|
||||||
|
EXTPARKING = "Parking in External Area"
|
||||||
|
EXTPCHCNPY = "Porch and / or Canopy in External Area"
|
||||||
|
EXTPTFRDR1 = "Patio and French Doors 1 in External Area"
|
||||||
|
EXTROOF1 = "Roof Covering 1 in External Area"
|
||||||
|
EXTROOF2 = "Roof Covering 2 in External Area"
|
||||||
|
EXTROOF3 = "Roof Covering 3 in External Area"
|
||||||
|
EXTRFSTR1 = "Roof Structure 1 in External Area"
|
||||||
|
EXTRFSTR2 = "Roof Structure 2 in External Area"
|
||||||
|
EXTRFSTR3 = "Roof Structure 3 in External Area"
|
||||||
|
EXTSTOREY = "Number of Storeys within the Property or Block"
|
||||||
|
EXTSTRDOOR = "Store Door in External Area"
|
||||||
|
EXTSTRINSP = "Structural Defects in External Area"
|
||||||
|
EXTSTRROOF = "Store Roof in External Area"
|
||||||
|
EXTSTRWDWS = "Store Windows in External Area"
|
||||||
|
EXTWALLFN1 = "Wall Finish 1 in External Area"
|
||||||
|
EXTWALLFN2 = "Wall Finish 2 in External Area"
|
||||||
|
EXTWALLINS = "Wall Insulation Improvement in External Area"
|
||||||
|
EXTWALLSPL = "Wall Spalling in External Area"
|
||||||
|
EXTWALLSTR = "Wall Structure in External Area"
|
||||||
|
EXTWNDWS1 = "Windows 1 in External Area"
|
||||||
|
EXTWNDWS2 = "Windows 2 in External Area"
|
||||||
|
FFHHDAMP = "Fitness for Human Habitation - Serious problem with damp"
|
||||||
|
FFHHDRNWC = "Fitness for Human Habitation - Problems with the drainage or the lavatories"
|
||||||
|
FFHHHCWAT = "Fitness for Human Habitation - Problem with the supply of hot and cold water"
|
||||||
|
FFHHNEGLC = "Fitness for Human Habitation - Building neglected and is in a bad condition"
|
||||||
|
FFHHNONAT = "Fitness for Human Habitation - Not enough natural light"
|
||||||
|
FFHHNOVEN = "Fitness for Human Habitation - Not enough ventilation"
|
||||||
|
FFHHPRPCK = "Fitness for Human Habitation - Difficult to prepare and cook food or wash up"
|
||||||
|
FFHHUNLAY = "Fitness for Human Habitation - Unsafe layout"
|
||||||
|
FFHHUNSTA = "Fitness for Human Habitation - Building is unstable"
|
||||||
|
FRARISKRTG = "Fire Risk Assessment Rating"
|
||||||
|
FRAEVACSTR = "Fire Risk Assessment Evacuation Strategy"
|
||||||
|
FRATYPE = "Fire Risk Assessment Type"
|
||||||
|
FLVL = "Floor Level of Front Door"
|
||||||
|
HHSRSASB = "Asbestos (and MMF)"
|
||||||
|
HHSRSBIOC = "Biocides"
|
||||||
|
HHSRSCO = "Carbon monoxide"
|
||||||
|
HHSRSCOLD = "Excess cold"
|
||||||
|
HHSRSCLOW = "Collision hazards and low headroom"
|
||||||
|
HHSRSCROWD = "Crowding and space"
|
||||||
|
HHSRSDAMP = "Damp and mould growth"
|
||||||
|
HHSRSDOMES = "Domestic hygeine, Pests and Refuse"
|
||||||
|
HHSRSELEC = "Electrical hazards"
|
||||||
|
HHSRSENTRP = "Collision and entrapment"
|
||||||
|
HHSRSENTRY = "Entry by intruders"
|
||||||
|
HHSRSEXPLO = "Explosions"
|
||||||
|
HHSRSFBATH = "Falls associated with baths etc"
|
||||||
|
HHSRSFBETW = "Falling between levels"
|
||||||
|
HHSRSFIRE = "Fire"
|
||||||
|
HHSRSFLAME = "Flames, hot surfaces etc"
|
||||||
|
HHSRSFLEVE = "Falling on level surfaces etc"
|
||||||
|
HHSRSFOOD = "Food safety"
|
||||||
|
HHSRSFSTAI = "Falling on stairs etc"
|
||||||
|
HHSRSFUEL = "Uncombusted fuel gas"
|
||||||
|
HHSRSHEAT = "Excess heat"
|
||||||
|
HHSRSLEAD = "Lead"
|
||||||
|
HHSRSLIGHT = "Lighting"
|
||||||
|
HHSRSNO2 = "Nitrogen dioxide"
|
||||||
|
HHSRSNOISE = "Noise"
|
||||||
|
HHSRSORGAN = "Volatile organic compounds"
|
||||||
|
HHSRSPERS = "Personal hygeine, Sanitation and Drainage"
|
||||||
|
HHSRSPOSI = "Position and operability of amenities etc"
|
||||||
|
HHSRSRADIA = "Radiation"
|
||||||
|
HHSRSSO2 = "Sulphur dioxide and smoke"
|
||||||
|
HHSRSSTRUC = "Structural collapse and falling elements"
|
||||||
|
HHSRSWATER = "Water supply"
|
||||||
|
INTACCRAMP = "Access Ramp 1:12 Gradient to Property"
|
||||||
|
INTADDWCW = "Additional WCs and / or WHBs in Property"
|
||||||
|
INTBTHADEQ = "Adequacy of Bathroom Location in Property"
|
||||||
|
INTBTHREML = "Source of Bathroom Remaining Life in Property"
|
||||||
|
INTBTHRLOC = "Location of Bathroom in Property"
|
||||||
|
INTBOILERF = "Boiler Fuel in Property"
|
||||||
|
INTCHEXTNT = "Extent of Central Heating in Property"
|
||||||
|
INTCKRLOC = "Adequacy of Cooker Location in Property"
|
||||||
|
INTCOMHTG = "Community Heating in Property"
|
||||||
|
INTELECTRC = "Electrics Required in Property"
|
||||||
|
INTFLRLVL = "Floor Level Location for Property"
|
||||||
|
INTFRDOOR = "Type and Location of Front Door in Property"
|
||||||
|
INTFRDRFRR = "Front Door Fire Rating in Property"
|
||||||
|
INTGASAVAI = "Gas Available in Property"
|
||||||
|
INTHEATREC = "Heat Recovery Units in Property"
|
||||||
|
INTHTDISYS = "Heating Distribution System in Property"
|
||||||
|
INTHTIMP = "Heating Improvement Required in Property"
|
||||||
|
INTKITADEQ = "Adequacy of Kitchen and Type in Property"
|
||||||
|
INTKITREML = "Source of Kitchen Remaining Life in Property"
|
||||||
|
INTLOFTINS = "Size in mm of Loft Insulation Thickness in Property"
|
||||||
|
INTNSEINSL = "Adequacy of Noise Insulation in Property"
|
||||||
|
INTPROGHTG = "Programmable Heating in Property"
|
||||||
|
INTSMKDET = "Smoke Detectors in Property"
|
||||||
|
INTSTEPSFD = "Number of Steps to Front Door for Property"
|
||||||
|
INTTNTINST = "Tenant Installed Kitchen in Property"
|
||||||
|
INTWDWTYPE = "Windows in Property"
|
||||||
|
INTWTRHTNG = "Type of Water Heating in Property"
|
||||||
|
QUALITYSTD = "Quality standard"
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
from typing import Any, List
|
from typing import Any, List, Optional
|
||||||
from backend.condition.domain.asset_condition import AssetCondition
|
from backend.condition.domain.asset_condition import AssetCondition
|
||||||
|
from backend.condition.domain.element import Element
|
||||||
from backend.condition.domain.mapping.mapper import Mapper
|
from backend.condition.domain.mapping.mapper import Mapper
|
||||||
|
from backend.condition.parsing.records.lbwf.lbwf_asset_condition import LbwfAssetCondition
|
||||||
|
|
||||||
|
|
||||||
class LbwfMapper(Mapper):
|
class LbwfMapper(Mapper):
|
||||||
|
|
||||||
def map_asset_conditions(self, client_data: List[Any]) -> List[AssetCondition]:
|
def map_asset_conditions(self, client_data: List[Any]) -> List[AssetCondition]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _map_element(lbwf_asset: LbwfAssetCondition) -> Optional[Element]:
|
||||||
|
raise NotImplementedError
|
||||||
239
backend/condition/tests/mapping/test_lbwf_mapper.py
Normal file
239
backend/condition/tests/mapping/test_lbwf_mapper.py
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
from typing import List
|
||||||
|
import pytest
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from backend.condition.domain.mapping.lbwf_mapper import LbwfMapper
|
||||||
|
from backend.condition.parsing.records.lbwf.lbwf_house import LbwfHouse
|
||||||
|
from backend.condition.parsing.records.lbwf.lbwf_asset_condition import LbwfAssetCondition
|
||||||
|
from backend.condition.domain.element import Element
|
||||||
|
from backend.condition.domain.asset_condition import AssetCondition
|
||||||
|
|
||||||
|
def test_lbwf_mapper_maps_house():
|
||||||
|
# arrange
|
||||||
|
lbwf_house = LbwfHouse(
|
||||||
|
uprn=1,
|
||||||
|
reference=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
epc="F",
|
||||||
|
shdf="NO",
|
||||||
|
house="HOUSE",
|
||||||
|
fail_decency=2025,
|
||||||
|
assets=[
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="AHR_CAT",
|
||||||
|
element_code_description="Accessible Housing Register Category",
|
||||||
|
attribute_code="F",
|
||||||
|
attribute_code_description="General Needs",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=1,
|
||||||
|
install_date=None,
|
||||||
|
remaining_life=None,
|
||||||
|
element_comments=None,
|
||||||
|
),
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="FLVL",
|
||||||
|
element_code_description="Floor Level of Front Door",
|
||||||
|
attribute_code="0G",
|
||||||
|
attribute_code_description="Ground Floor",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=1,
|
||||||
|
install_date=None,
|
||||||
|
remaining_life=None,
|
||||||
|
element_comments=None,
|
||||||
|
),
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="ASBESTOS",
|
||||||
|
element_code_description="Asbestos Present",
|
||||||
|
attribute_code="YES",
|
||||||
|
attribute_code_description="Yes",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=None,
|
||||||
|
install_date=None,
|
||||||
|
remaining_life=None,
|
||||||
|
element_comments="Source of Data = ACT",
|
||||||
|
),
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="INTBTHRLOC",
|
||||||
|
element_code_description="Location of Bathroom in Property",
|
||||||
|
attribute_code="ENTRANCE",
|
||||||
|
attribute_code_description="Bathroom on Entrance Level in Property",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=1,
|
||||||
|
install_date=None,
|
||||||
|
remaining_life=None,
|
||||||
|
element_comments="Source of Data = Codeman",
|
||||||
|
),
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="INTCHEXTNT",
|
||||||
|
element_code_description="Extent of Central Heating in Property",
|
||||||
|
attribute_code="NONE",
|
||||||
|
attribute_code_description="No Central Heating in Property",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=1,
|
||||||
|
install_date=None,
|
||||||
|
remaining_life=None,
|
||||||
|
element_comments="Source of Data = Codeman",
|
||||||
|
),
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="HHSRSFIRE",
|
||||||
|
element_code_description="Fire",
|
||||||
|
attribute_code="TYPRISK",
|
||||||
|
attribute_code_description="Category 4 - Typical Risk",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=1,
|
||||||
|
install_date=None,
|
||||||
|
remaining_life=None,
|
||||||
|
element_comments="Source of Data = Morgan Sindall",
|
||||||
|
),
|
||||||
|
LbwfAssetCondition(
|
||||||
|
prop_ref=100,
|
||||||
|
domna=100,
|
||||||
|
address="123 Fake Street, London, A10 1AB",
|
||||||
|
ownership="LBWF_OWNED",
|
||||||
|
prop_status="OCCP",
|
||||||
|
prop_type="HOU",
|
||||||
|
prop_sub_type="TERRACED",
|
||||||
|
element_group="ASSETS",
|
||||||
|
element_code="EXTWALLFN1",
|
||||||
|
element_code_description="Wall Finish 1 in External Area",
|
||||||
|
attribute_code="RENDERPBBL",
|
||||||
|
attribute_code_description="Render or Pebbledash Wall Finish 1 in External Area",
|
||||||
|
element_date_value=None,
|
||||||
|
element_numerical_value=None,
|
||||||
|
element_text_value=None,
|
||||||
|
quantity=1,
|
||||||
|
install_date=date(2009,4,1),
|
||||||
|
remaining_life=26,
|
||||||
|
element_comments="Source of Data = Codeman",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
mapper = LbwfMapper()
|
||||||
|
|
||||||
|
current_year = 2026
|
||||||
|
|
||||||
|
expected_assets: List[AssetCondition] = [
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.AHR_CAT,
|
||||||
|
condition_description="General Needs",
|
||||||
|
quantity=1,
|
||||||
|
renewal_year=None,
|
||||||
|
source=None
|
||||||
|
),
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.FLVL,
|
||||||
|
condition_description="Ground Floor",
|
||||||
|
quantity=1,
|
||||||
|
renewal_year=None,
|
||||||
|
source=None
|
||||||
|
),
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.ASBESTOS,
|
||||||
|
condition_description="Yes",
|
||||||
|
quantity=None,
|
||||||
|
renewal_year=None,
|
||||||
|
source="Source of Data = ACT"
|
||||||
|
),
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.INTBTHRLOC,
|
||||||
|
condition_description="Bathroom on Entrance Level in Property",
|
||||||
|
quantity=1,
|
||||||
|
renewal_year=None,
|
||||||
|
source="Source of Data = Codeman"
|
||||||
|
),
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.INTCHEXTNT,
|
||||||
|
condition_description="No Central Heating in Property",
|
||||||
|
quantity=1,
|
||||||
|
renewal_year=None,
|
||||||
|
source="Source of Data = Codeman"
|
||||||
|
),
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.HHSRSFIRE,
|
||||||
|
condition_description="Category 4 - Typical Risk",
|
||||||
|
quantity=1,
|
||||||
|
renewal_year=None,
|
||||||
|
source="Source of Data = Morgan Sindall"
|
||||||
|
),
|
||||||
|
AssetCondition(
|
||||||
|
uprn=1,
|
||||||
|
element=Element.EXTWALLFN1,
|
||||||
|
condition_description="Render or Pebbledash Wall Finish 1 in External Area",
|
||||||
|
quantity=1,
|
||||||
|
renewal_year=2052,
|
||||||
|
source="Source of Data = Codeman"
|
||||||
|
),
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
# act
|
||||||
|
actual_assets: List[AssetCondition] = mapper.map_asset_conditions(lbwf_house)
|
||||||
|
|
||||||
|
# assert
|
||||||
|
assert actual_assets == expected_assets
|
||||||
|
|
@ -112,7 +112,7 @@ def lbwf_homes_xlsx_bytes() -> BytesIO:
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
def test_lbwf_parser_passes_houses(lbwf_homes_xlsx_bytes):
|
def test_lbwf_parser_parses_houses(lbwf_homes_xlsx_bytes):
|
||||||
# arrange
|
# arrange
|
||||||
parser = LbwfParser()
|
parser = LbwfParser()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue