Map to dataclasses from Peabody objects 🟩

This commit is contained in:
Daniel Roth 2026-01-23 12:50:48 +00:00
parent d480339ba6
commit 42f9821f1b
2 changed files with 85 additions and 29 deletions

View file

@ -1,40 +1,54 @@
from backend.condition.domain.aspect_type import AspectType
from backend.condition.domain.element import Element
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"),
# ==========================================================
# PROPERTY / GENERAL
# ==========================================================
(100, 1): ElementMapping(element=Element.PROPERTY, aspect_type=AspectType.TYPE),
# (100, 3): ElementMapping(element=Element.PROPERTY, aspect_type=AspectType.AGE),
# (100, 14): ElementMapping(element="property", aspect_type="construction_type"),
# ==========================================================
# EXTERNAL WALLS
# ==========================================================
(120, 1): ElementMapping(
element=Element.EXTERNAL_WALL, aspect_type=AspectType.STRUCTURE
),
(120, 2): ElementMapping(
element=Element.EXTERNAL_WALL, aspect_type=AspectType.FINISH
),
# ==========================================================
# EXTERNAL ROOFS
# ==========================================================
(110, 1): ElementMapping(element=Element.ROOF, aspect_type=AspectType.COVERING),
# ==========================================================
# EXTERNAL DOORS & WINDOWS
# ==========================================================
(130, 1): ElementMapping(
element=Element.EXTERNAL_WINDOWS, aspect_type=AspectType.MATERIAL
),
# ==========================================================
# INTERNAL BATHROOMS & KITCHENS
# ==========================================================
(160, 1): ElementMapping(element=Element.KITCHEN, aspect_type=AspectType.CONDITION),
(190, 1): ElementMapping(
element=Element.BATHROOM, aspect_type=AspectType.CONDITION
),
# --------------------
# HHSRS (PEABODY)
# --------------------
("54", "1"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=1
(54, 1): ElementMapping(
element=Element.HHSRS_DAMP_AND_MOULD, aspect_type=AspectType.RISK
),
("54", "2"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=2
(54, 4): ElementMapping(
element=Element.HHSRS_ASBESTOS_AND_MMF, aspect_type=AspectType.RISK
),
("54", "4"): ElementMapping(
element="hhsrs", aspect="risk", is_hhsrs=True, hhsrs_hazard_id=4
(54, 15): ElementMapping(
element=Element.HHSRS_DOMESTIC_HYGIENE_PESTS_REFUSE, aspect_type=AspectType.RISK
),
("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
(54, 29): ElementMapping(
element=Element.HHSRS_STRUCTURAL_COLLAPSE, aspect_type=AspectType.RISK
),
}

View file

@ -1,6 +1,10 @@
from typing import Any, List, Optional
from backend.condition.domain.asset_condition import AssetCondition
from backend.condition.domain.mapping.element_mapping import ElementMapping
from backend.condition.domain.mapping.peabody.peabody_element_map import (
PEABODY_ELEMENT_MAP,
)
from backend.condition.domain.mapping.mapper import Mapper
from backend.condition.parsing.records.peabody.peabody_asset_condition import (
PeabodyAssetCondition,
@ -15,4 +19,42 @@ class PeabodyMapper(Mapper):
def map_asset_conditions_for_property(
self, client_data: Any, survey_year: Optional[int] = None
) -> List[AssetCondition]:
raise NotImplementedError
assert isinstance(
client_data, PeabodyProperty
) # TODO: think of a better way to do this
mapped_assets: List[AssetCondition] = []
uprn: int = client_data.uprn
for raw_asset in client_data.assets:
try:
element_mapping: ElementMapping = PeabodyMapper._map_element(
raw_asset.element_code, raw_asset.sub_element_code
)
except:
logger.warning(
f"""Unrecognised Peabody Asset Element: {raw_asset.element} ({raw_asset.element_code}),
Sub-Element: {raw_asset.sub_element} ({raw_asset.sub_element_code}). Skipping record"""
)
continue
mapped_assets.append(
AssetCondition(
uprn=uprn,
element=element_mapping.element,
aspect_type=element_mapping.aspect_type,
value=raw_asset.material_or_answer,
quantity=raw_asset.renewal_quantity,
install_date=None, # Not available in peabody data
renewal_year=raw_asset.renewal_year,
element_instance=element_mapping.element_instance,
source_system=None, # Once we know the system name we'll set it here
comments=None, # Not available in peabody data
)
)
return mapped_assets
@staticmethod
def _map_element(element_code: int, sub_element_code: int) -> ElementMapping:
return PEABODY_ELEMENT_MAP[(element_code, sub_element_code)]