Model/backend/condition/domain/mapping/peabody/peabody_mapper.py
2026-01-27 16:08:20 +00:00

107 lines
3.9 KiB
Python

from typing import Any, Dict, Optional, Tuple
from datetime import date
from backend.condition.domain.aspect_condition import AspectCondition
from backend.condition.domain.element import Element
from backend.condition.domain.element_type import ElementType
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.domain.property_condition_survey import PropertyConditionSurvey
from backend.condition.parsing.records.peabody.peabody_asset_condition import (
PeabodyAssetCondition,
)
from backend.condition.parsing.records.peabody.peabody_property import PeabodyProperty
from utils.logger import setup_logger
logger = setup_logger()
class PeabodyMapper(Mapper):
def map_asset_conditions_for_property(
self, client_property_data: Any, survey_year: Optional[int] = None
) -> PropertyConditionSurvey:
assert isinstance(
client_property_data, PeabodyProperty
) # TODO: think of a better way to do this
elements_by_key: dict[tuple[ElementType, int], Element] = {}
for raw_asset in client_property_data.assets:
element_mapping = PeabodyMapper._safe_map_element(raw_asset)
aspect_condition = PeabodyMapper._build_aspect_condition(
raw_asset, element_mapping
)
element_key = (
element_mapping.elementType,
element_mapping.element_instance or 1,
)
PeabodyMapper._attach_aspect_condition_to_element(
elements_by_key,
element_key,
aspect_condition,
)
return PropertyConditionSurvey(
uprn=client_property_data.uprn,
elements=list(elements_by_key.values()),
date=date(2000, 1, 1), # Temp - not sure how to get this
source="Peabody", # TODO: Make this the system, not the client
)
@staticmethod
def _safe_map_element(raw_asset: PeabodyAssetCondition) -> Optional[ElementMapping]:
try:
return PeabodyMapper._map_element(
raw_asset.element_code,
raw_asset.sub_element_code,
)
except KeyError:
logger.warning(
f"Unrecognised Peabody Asset Element: "
f"{raw_asset.element} ({raw_asset.element_code}), "
f"Sub-Element: {raw_asset.sub_element} ({raw_asset.sub_element_code}). "
"Skipping record"
)
return None
@staticmethod
def _map_element(element_code: int, sub_element_code: int) -> ElementMapping:
return PEABODY_ELEMENT_MAP[(element_code, sub_element_code)]
@staticmethod
def _attach_aspect_condition_to_element(
elements_by_key: Dict[Tuple[ElementType, int], Element],
element_key: Tuple[ElementType, int],
aspect_condition: AspectCondition,
) -> None:
element = elements_by_key.get(element_key)
if element is None:
element = Element(
element_type=element_key[0],
element_instance=element_key[1],
aspect_conditions=[],
)
elements_by_key[element_key] = element
element.aspect_conditions.append(aspect_condition)
@staticmethod
def _build_aspect_condition(
raw_asset, element_mapping: ElementMapping
) -> AspectCondition:
return AspectCondition(
aspect_type=element_mapping.aspect_type,
aspect_instance=element_mapping.aspect_instance or 1,
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,
comments=None,
)