Map to dataclasses from Peabody objects 🟥

This commit is contained in:
Daniel Roth 2026-01-23 12:09:19 +00:00
parent 949c9f684d
commit d480339ba6
8 changed files with 169 additions and 234 deletions

View file

@ -1,131 +0,0 @@
from enum import StrEnum
class LbwfElement(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"

View file

@ -0,0 +1,12 @@
from dataclasses import dataclass
from typing import Optional
from xml.dom.minidom import Element
from backend.condition.domain.aspect_type import AspectType
@dataclass(frozen=True)
class ElementMapping:
element: Element
aspect_type: AspectType
element_instance: Optional[int] = None

View file

@ -1,179 +1,170 @@
from dataclasses import dataclass
from typing import Optional
from backend.condition.domain.element import Element
from backend.condition.domain.aspect_type import AspectType
from backend.condition.domain.mapping.element_mapping import ElementMapping
@dataclass(frozen=True)
class LbwfElementMapping:
element: Element
aspect_type: AspectType
element_instance: Optional[int] = None
LBWF_ELEMENT_MAP: dict[str, LbwfElementMapping] = {
LBWF_ELEMENT_MAP: dict[str, ElementMapping] = {
# ==========================================================
# PROPERTY / GENERAL
# ==========================================================
"AHR_CAT": LbwfElementMapping(
"AHR_CAT": ElementMapping(
element=Element.ACCESSIBLE_HOUSING_REGISTER,
aspect_type=AspectType.CATEGORY,
),
"ASSETSAREA": LbwfElementMapping(
"ASSETSAREA": ElementMapping(
element=Element.PROPERTY,
aspect_type=AspectType.AREA,
),
# "DECNTHMINC": LbwfElementMapping(
# "DECNTHMINC": ElementMapping(
# element=Element.DECENT_HOMES,
# aspect_type=AspectType.INCLUSION,
# ), # Ignore this one
"QUALITYSTD": LbwfElementMapping(
"QUALITYSTD": ElementMapping(
element=Element.QUALITY_STANDARD,
aspect_type=AspectType.TYPE,
),
"EXTSTOREY": LbwfElementMapping(
"EXTSTOREY": ElementMapping(
element=Element.PROPERTY,
aspect_type=AspectType.CONFIGURATION,
),
"FLVL": LbwfElementMapping(
"FLVL": ElementMapping(
element=Element.FLOOR_LEVEL_FRONT_DOOR,
aspect_type=AspectType.LOCATION,
),
# ==========================================================
# ASBESTOS (NON-HHSRS RECORD)
# ==========================================================
"ASBESTOS": LbwfElementMapping(
"ASBESTOS": ElementMapping(
element=Element.ASBESTOS,
aspect_type=AspectType.PRESENCE,
),
# ==========================================================
# INTERNAL BATHROOMS & KITCHENS
# ==========================================================
"INTBTHRLOC": LbwfElementMapping(
"INTBTHRLOC": ElementMapping(
element=Element.BATHROOM,
aspect_type=AspectType.LOCATION,
),
"INTBTHADEQ": LbwfElementMapping(
"INTBTHADEQ": ElementMapping(
element=Element.BATHROOM,
aspect_type=AspectType.ADEQUACY,
),
"INTKITADEQ": LbwfElementMapping(
"INTKITADEQ": ElementMapping(
element=Element.KITCHEN,
aspect_type=AspectType.ADEQUACY,
),
"INTCKRLOC": LbwfElementMapping(
"INTCKRLOC": ElementMapping(
element=Element.KITCHEN,
aspect_type=AspectType.LOCATION,
),
# ==========================================================
# INTERNAL HEATING
# ==========================================================
"INTCHEXTNT": LbwfElementMapping(
"INTCHEXTNT": ElementMapping(
element=Element.HEATING_EXTENT,
aspect_type=AspectType.CONFIGURATION,
),
"INTCHDIST": LbwfElementMapping(
"INTCHDIST": ElementMapping(
element=Element.HEATING_DISTRIBUTION,
aspect_type=AspectType.TYPE,
),
"INTCHBLR": LbwfElementMapping(
"INTCHBLR": ElementMapping(
element=Element.HEATING_BOILER,
aspect_type=AspectType.TYPE,
),
# ==========================================================
# INTERNAL FIRE
# ==========================================================
"FRARISKRTG": LbwfElementMapping(
"FRARISKRTG": ElementMapping(
element=Element.FIRE_RISK_ASSESSMENT,
aspect_type=AspectType.RATING,
),
"FRATYPE": LbwfElementMapping(
"FRATYPE": ElementMapping(
element=Element.FIRE_RISK_ASSESSMENT,
aspect_type=AspectType.TYPE,
),
"FRAEVACSTR": LbwfElementMapping(
"FRAEVACSTR": ElementMapping(
element=Element.FIRE_RISK_ASSESSMENT,
aspect_type=AspectType.STRATEGY,
),
"INTSMKDET": LbwfElementMapping(
"INTSMKDET": ElementMapping(
element=Element.SMOKE_DETECTION,
aspect_type=AspectType.PRESENCE,
),
"INTCHEXTNT": LbwfElementMapping(
"INTCHEXTNT": ElementMapping(
element=Element.HEATING_SYSTEM,
aspect_type=AspectType.EXTENT,
),
# ==========================================================
# HEATING & SERVICES
# ==========================================================
"INTBOILERF": LbwfElementMapping(
"INTBOILERF": ElementMapping(
element=Element.BOILER_FUEL,
aspect_type=AspectType.TYPE,
),
"INTHTDISYS": LbwfElementMapping(
"INTHTDISYS": ElementMapping(
element=Element.HEATING_SYSTEM,
aspect_type=AspectType.DISTRIBUTION,
),
"INTWTRHTNG": LbwfElementMapping(
"INTWTRHTNG": ElementMapping(
element=Element.WATER_HEATING,
aspect_type=AspectType.TYPE,
),
# ==========================================================
# EXTERNAL WALLS (INSTANCED)
# ==========================================================
"EXTWALLSTR": LbwfElementMapping(
"EXTWALLSTR": ElementMapping(
element=Element.EXTERNAL_WALL,
aspect_type=AspectType.STRUCTURE,
element_instance=1,
),
"EXTWALLFN1": LbwfElementMapping(
"EXTWALLFN1": ElementMapping(
element=Element.EXTERNAL_WALL,
aspect_type=AspectType.FINISH,
element_instance=1,
),
"EXTWALLFN2": LbwfElementMapping(
"EXTWALLFN2": ElementMapping(
element=Element.EXTERNAL_WALL,
aspect_type=AspectType.FINISH,
element_instance=2,
),
"EXTWALLINS": LbwfElementMapping(
"EXTWALLINS": ElementMapping(
element=Element.EXTERNAL_WALL,
aspect_type=AspectType.INSULATION,
),
"EXTWALLSPL": LbwfElementMapping(
"EXTWALLSPL": ElementMapping(
element=Element.EXTERNAL_WALL,
aspect_type=AspectType.CONDITION,
),
# ==========================================================
# EXTERNAL ROOFS (INSTANCED)
# ==========================================================
"EXTRFSTR1": LbwfElementMapping(
"EXTRFSTR1": ElementMapping(
element=Element.ROOF,
aspect_type=AspectType.STRUCTURE,
element_instance=1,
),
"EXTRFSTR2": LbwfElementMapping(
"EXTRFSTR2": ElementMapping(
element=Element.ROOF,
aspect_type=AspectType.STRUCTURE,
element_instance=2,
),
"EXTRFSTR3": LbwfElementMapping(
"EXTRFSTR3": ElementMapping(
element=Element.ROOF,
aspect_type=AspectType.STRUCTURE,
element_instance=3,
),
"EXTROOF1": LbwfElementMapping(
"EXTROOF1": ElementMapping(
element=Element.ROOF,
aspect_type=AspectType.COVERING,
element_instance=1,
),
"EXTROOF2": LbwfElementMapping(
"EXTROOF2": ElementMapping(
element=Element.ROOF,
aspect_type=AspectType.COVERING,
element_instance=2,
),
"EXTROOF3": LbwfElementMapping(
"EXTROOF3": ElementMapping(
element=Element.ROOF,
aspect_type=AspectType.COVERING,
element_instance=3,
@ -181,34 +172,34 @@ LBWF_ELEMENT_MAP: dict[str, LbwfElementMapping] = {
# ==========================================================
# EXTERNAL DOORS & WINDOWS
# ==========================================================
"INTFRDOOR": LbwfElementMapping(
"INTFRDOOR": ElementMapping(
element=Element.EXTERNAL_DOOR,
aspect_type=AspectType.TYPE,
),
"INTFRDRFRR": LbwfElementMapping(
"INTFRDRFRR": ElementMapping(
element=Element.EXTERNAL_DOOR,
aspect_type=AspectType.FIRE_RATING,
),
"EXTBKSDDR1": LbwfElementMapping(
"EXTBKSDDR1": ElementMapping(
element=Element.EXTERNAL_DOOR,
aspect_type=AspectType.TYPE,
element_instance=1,
),
"EXTBKSDDR2": LbwfElementMapping(
"EXTBKSDDR2": ElementMapping(
element=Element.EXTERNAL_DOOR,
aspect_type=AspectType.TYPE,
element_instance=2,
),
"INTWDWTYPE": LbwfElementMapping(
"INTWDWTYPE": ElementMapping(
element=Element.EXTERNAL_WINDOWS,
aspect_type=AspectType.TYPE,
),
"EXTWNDWS1": LbwfElementMapping(
"EXTWNDWS1": ElementMapping(
element=Element.EXTERNAL_WINDOWS,
aspect_type=AspectType.TYPE,
element_instance=1,
),
"EXTWNDWS2": LbwfElementMapping(
"EXTWNDWS2": ElementMapping(
element=Element.EXTERNAL_WINDOWS,
aspect_type=AspectType.TYPE,
element_instance=2,
@ -216,121 +207,121 @@ LBWF_ELEMENT_MAP: dict[str, LbwfElementMapping] = {
# ==========================================================
# HHSRS
# ==========================================================
"HHSRSDAMP": LbwfElementMapping(
"HHSRSDAMP": ElementMapping(
element=Element.HHSRS_DAMP_AND_MOULD,
aspect_type=AspectType.RISK,
),
"HHSRSCOLD": LbwfElementMapping(
"HHSRSCOLD": ElementMapping(
element=Element.HHSRS_EXCESS_COLD,
aspect_type=AspectType.RISK,
),
"HHSRSHEAT": LbwfElementMapping(
"HHSRSHEAT": ElementMapping(
element=Element.HHSRS_EXCESS_HEAT,
aspect_type=AspectType.RISK,
),
"HHSRSASB": LbwfElementMapping(
"HHSRSASB": ElementMapping(
element=Element.HHSRS_ASBESTOS_AND_MMF,
aspect_type=AspectType.RISK,
),
"HHSRSBIOCIDES": LbwfElementMapping(
"HHSRSBIOCIDES": ElementMapping(
element=Element.HHSRS_BIOCIDES,
aspect_type=AspectType.RISK,
),
"HHSRSCO": LbwfElementMapping(
"HHSRSCO": ElementMapping(
element=Element.HHSRS_CARBON_MONOXIDE,
aspect_type=AspectType.RISK,
),
"HHSRSLEAD": LbwfElementMapping(
"HHSRSLEAD": ElementMapping(
element=Element.HHSRS_LEAD,
aspect_type=AspectType.RISK,
),
"HHSRSRADIA": LbwfElementMapping(
"HHSRSRADIA": ElementMapping(
element=Element.HHSRS_RADIATION,
aspect_type=AspectType.RISK,
),
"HHSRSFUEL": LbwfElementMapping(
"HHSRSFUEL": ElementMapping(
element=Element.HHSRS_UNCOMBUSTED_FUEL_GAS,
aspect_type=AspectType.RISK,
),
"HHSRSORGAN": LbwfElementMapping(
"HHSRSORGAN": ElementMapping(
element=Element.HHSRS_VOLATILE_ORGANIC_COMPOUNDS, aspect_type=AspectType.RISK
),
"HHSRSCROWD": LbwfElementMapping(
"HHSRSCROWD": ElementMapping(
element=Element.HHSRS_CROWDING_AND_SPACE,
aspect_type=AspectType.RISK,
),
"HHSRSENTRY": LbwfElementMapping(
"HHSRSENTRY": ElementMapping(
element=Element.HHSRS_ENTRY_BY_INTRUDERS,
aspect_type=AspectType.RISK,
),
"HHSRSLIGHT": LbwfElementMapping(
"HHSRSLIGHT": ElementMapping(
element=Element.HHSRS_LIGHTING,
aspect_type=AspectType.RISK,
),
"HHSRSNOISE": LbwfElementMapping(
"HHSRSNOISE": ElementMapping(
element=Element.HHSRS_NOISE,
aspect_type=AspectType.RISK,
),
"HHSRSDOMES": LbwfElementMapping(
"HHSRSDOMES": ElementMapping(
element=Element.HHSRS_DOMESTIC_HYGIENE_PESTS_REFUSE,
aspect_type=AspectType.RISK,
),
"HHSRSFOOD": LbwfElementMapping(
"HHSRSFOOD": ElementMapping(
element=Element.HHSRS_FOOD_SAFETY,
aspect_type=AspectType.RISK,
),
"HHSRSPERS": LbwfElementMapping(
"HHSRSPERS": ElementMapping(
element=Element.HHSRS_PERSONAL_HYGIENE_SANITATION,
aspect_type=AspectType.RISK,
),
"HHSRSWATER": LbwfElementMapping(
"HHSRSWATER": ElementMapping(
element=Element.HHSRS_WATER_SUPPLY,
aspect_type=AspectType.RISK,
),
"HHSRSFBATH": LbwfElementMapping(
"HHSRSFBATH": ElementMapping(
element=Element.HHSRS_FALLS_ASSOCIATED_WITH_BATHS,
aspect_type=AspectType.RISK,
),
"HHSRSFLEVE": LbwfElementMapping(
"HHSRSFLEVE": ElementMapping(
element=Element.HHSRS_FALLS_ON_LEVEL_SURFACES,
aspect_type=AspectType.RISK,
),
"HHSRSFSTAI": LbwfElementMapping(
"HHSRSFSTAI": ElementMapping(
element=Element.HHSRS_FALLS_ON_STAIRS,
aspect_type=AspectType.RISK,
),
"HHSRSFBETW": LbwfElementMapping(
"HHSRSFBETW": ElementMapping(
element=Element.HHSRS_FALLS_BETWEEN_LEVELS,
aspect_type=AspectType.RISK,
),
"HHSRSELEC": LbwfElementMapping(
"HHSRSELEC": ElementMapping(
element=Element.HHSRS_ELECTRICAL_HAZARDS,
aspect_type=AspectType.RISK,
),
"HHSRSFIRE": LbwfElementMapping(
"HHSRSFIRE": ElementMapping(
element=Element.HHSRS_FIRE,
aspect_type=AspectType.RISK,
),
"HHSRSFLAME": LbwfElementMapping(
"HHSRSFLAME": ElementMapping(
element=Element.HHSRS_FLAMES_HOT_SURFACES,
aspect_type=AspectType.RISK,
),
"HHSRSENTRP": LbwfElementMapping(
"HHSRSENTRP": ElementMapping(
element=Element.HHSRS_COLLISION_AND_ENTRAPMENT,
aspect_type=AspectType.RISK,
),
"HHSRSEXPLO": LbwfElementMapping(
"HHSRSEXPLO": ElementMapping(
element=Element.HHSRS_EXPLOSIONS,
aspect_type=AspectType.RISK,
),
"HHSRSSTRUC": LbwfElementMapping(
"HHSRSSTRUC": ElementMapping(
element=Element.HHSRS_STRUCTURAL_COLLAPSE,
aspect_type=AspectType.RISK,
),
"HHSRSCLOW": LbwfElementMapping(
"HHSRSCLOW": ElementMapping(
element=Element.HHSRS_COLLISION_AND_ENTRAPMENT, aspect_type=AspectType.RISK
),
"HHSRSPOSI": LbwfElementMapping(
"HHSRSPOSI": ElementMapping(
element=Element.HHSRS_AMENITIES,
aspect_type=AspectType.RISK,
),

View file

@ -2,10 +2,8 @@ from typing import Any, List, Optional
from backend.condition.domain.asset_condition import AssetCondition
from backend.condition.domain.element import Element
from backend.condition.domain.mapping.lbwf.lbwf_element_map import (
LbwfElementMapping,
LBWF_ELEMENT_MAP,
)
from backend.condition.domain.mapping.element_mapping import ElementMapping
from backend.condition.domain.mapping.lbwf.lbwf_element_map import LBWF_ELEMENT_MAP
from backend.condition.domain.mapping.mapper import Mapper
from backend.condition.parsing.records.lbwf.lbwf_asset_condition import (
LbwfAssetCondition,
@ -19,7 +17,7 @@ logger = setup_logger()
class LbwfMapper(Mapper):
def map_asset_conditions_for_property(
self, client_data: Any, survey_year: Optional[int]
self, client_data: Any, survey_year: Optional[int] = None
) -> List[AssetCondition]:
assert isinstance(
client_data, LbwfHouse
@ -30,7 +28,7 @@ class LbwfMapper(Mapper):
uprn: int = client_data.uprn
for raw_asset in client_data.assets:
try:
element_mapping: LbwfElementMapping = LbwfMapper._map_element(
element_mapping: ElementMapping = LbwfMapper._map_element(
raw_asset.element_code
)
except:
@ -59,7 +57,7 @@ class LbwfMapper(Mapper):
return mapped_assets
@staticmethod
def _map_element(lbwf_element_code: str) -> LbwfElementMapping:
def _map_element(lbwf_element_code: str) -> ElementMapping:
return LBWF_ELEMENT_MAP[lbwf_element_code]
@staticmethod

View file

@ -3,9 +3,12 @@ from typing import Any, List, Optional
from backend.condition.domain.asset_condition import AssetCondition
class Mapper(ABC):
@abstractmethod
def map_asset_conditions_for_property(self, client_data: Any, survey_year: Optional[int]) -> List[AssetCondition]:
#TODO: client_data should be properly typed
pass
def map_asset_conditions_for_property(
self, client_data: Any, survey_year: Optional[int] = None
) -> List[AssetCondition]:
# TODO: client_data should be properly typed
pass

View file

@ -0,0 +1,40 @@
from backend.condition.domain.mapping.element_mapping import ElementMapping
PEABODY_ELEMENT_MAP = {
# --------------------
# GENERAL
# --------------------
("100", "1"): ElementMapping(element="property", aspect="type"),
("100", "3"): ElementMapping(element="property", aspect="age_band"),
("100", "14"): ElementMapping(element="property", aspect="construction_type"),
# --------------------
# EXTERNALS
# --------------------
("120", "1"): ElementMapping(element="external_wall", aspect="structure"),
("120", "2"): ElementMapping(element="external_wall", aspect="finish"),
("110", "1"): ElementMapping(element="roof", aspect="covering"),
# --------------------
# INTERNALS
# --------------------
("160", "1"): ElementMapping(element="kitchen", aspect="condition"),
("190", "1"): ElementMapping(element="bathroom", aspect="condition"),
# --------------------
# HHSRS (PEABODY)
# --------------------
("54", "1"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=1
),
("54", "2"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=2
),
("54", "4"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=4
),
("54", "24"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=24
),
("54", "29"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=29
),
}

View file

@ -13,6 +13,6 @@ logger = setup_logger()
class PeabodyMapper(Mapper):
def map_asset_conditions_for_property(
self, client_data: Any, survey_year: Optional[int]
self, client_data: Any, survey_year: Optional[int] = None
) -> List[AssetCondition]:
raise NotImplementedError

View file

@ -1,5 +1,8 @@
from datetime import datetime
from typing import List
from backend.condition.domain.aspect_type import AspectType
from backend.condition.domain.element import Element
from backend.condition.domain.mapping.peabody.peabody_mapper import PeabodyMapper
from backend.condition.parsing.records.peabody.peabody_asset_condition import (
PeabodyAssetCondition,
@ -18,23 +21,42 @@ def test_peabody_mapper_maps_property():
full_address="FLAT 1 RANDOM SQUARE FAKE STREET LONDON E1 1EE",
location_type_code=1,
parent_lo_reference="RAND1000",
element_code=50,
element="Internal",
sub_element_code=3,
sub_element="CCU",
material_code=2,
material_or_answer="RCD/MCB CCU",
renewal_quantity=1,
renewal_year=2038,
renewal_cost=500,
element_code=130,
element="WINDOWS",
sub_element_code=1,
sub_element="Windows",
material_code=1,
material_or_answer="UPVC Double Glazed",
renewal_quantity=8,
renewal_year=2036,
renewal_cost=4800,
cloned="N",
lo_type_code=1,
condition_survey_date=datetime(2024, 2, 15, 0, 0, 0),
condition_survey_date=datetime(2024, 2, 15, 12, 47, 0),
)
],
)
mapper = PeabodyMapper()
expected_assets: List[AssetCondition] = [
AssetCondition(
uprn=1,
element=Element.EXTERNAL_WINDOWS,
aspect_type=AspectType.MATERIAL,
value="UPVC Double Glazed",
quantity=8,
install_date=None,
renewal_year=2036,
element_instance=None,
source_system=None,
comments=None,
)
]
# act
actual_assets = mapper.map_asset_conditions_for_property(peabody_property)
# assert
assert False # temp
assert len(actual_assets) == len(expected_assets)
for i, (actual, expected) in enumerate(zip(actual_assets, expected_assets)):
assert actual == expected, f"Mismatch at index {i}"