diff --git a/domain/epc/property_overlays/construction_age_band_overlay.py b/domain/epc/property_overlays/construction_age_band_overlay.py new file mode 100644 index 00000000..d4cc6eae --- /dev/null +++ b/domain/epc/property_overlays/construction_age_band_overlay.py @@ -0,0 +1,22 @@ +"""Map a Landlord-Override construction-age-band value to a fabric Simulation +Overlay. + +A construction-age-band value is the RdSAP England-&-Wales letter code (A..M) +the calculator's U-value cascades key on (`SapBuildingPart.construction_age_band`, +read via `.strip().upper()` against the letter-code bands). The overlay targets +the override's building part and sets the band; an unrecognised code produces no +overlay. Re-dating a part re-derives its construction-default U-values, so this +is the highest-leverage fabric override. +""" + +from __future__ import annotations + +from typing import Optional + +from domain.modelling.simulation import EpcSimulation + + +def age_band_overlay_for( + age_band_value: str, building_part: int +) -> Optional[EpcSimulation]: + raise NotImplementedError diff --git a/domain/modelling/simulation.py b/domain/modelling/simulation.py index 217d446b..caee5fb5 100644 --- a/domain/modelling/simulation.py +++ b/domain/modelling/simulation.py @@ -28,6 +28,12 @@ class BuildingPartOverlay: # The wall material (RdSAP `wall_construction` code). Left `None` by Measures # — insulating a wall doesn't change its material — but set by a Landlord # Override that corrects the construction itself (ADR-0032). + # RdSAP England-&-Wales construction age band — the letter code A..M the + # calculator's U-value cascades key on (`SapBuildingPart.construction_age_band`). + # Left `None` by Measures (retrofits don't change build era); set by a Landlord + # Override that corrects the lodged age band, which re-derives this part's + # fabric U-value defaults. Folds onto the part via the generic field loop. + construction_age_band: Optional[str] = None wall_construction: Optional[int] = None wall_insulation_type: Optional[int] = None # Added solid-wall insulation depth (mm) — drives the calculator's Table 6 diff --git a/tests/domain/epc/test_construction_age_band_overlay.py b/tests/domain/epc/test_construction_age_band_overlay.py new file mode 100644 index 00000000..066244a6 --- /dev/null +++ b/tests/domain/epc/test_construction_age_band_overlay.py @@ -0,0 +1,23 @@ +"""The Landlord-Override construction-age-band → fabric Simulation Overlay. + +An age-band value resolves to the RdSAP letter code the calculator's U-value +cascades read from `SapBuildingPart.construction_age_band`; the overlay targets +the override's building part. +""" + +from __future__ import annotations + +from datatypes.epc.domain.epc_property_data import BuildingPartIdentifier +from domain.epc.property_overlays.construction_age_band_overlay import ( + age_band_overlay_for, +) + + +def test_age_band_overlays_the_main_building_part() -> None: + # Act — band B (1900-1929) on the main building part. + simulation = age_band_overlay_for("B", 0) + + # Assert + assert simulation is not None + overlay = simulation.building_parts[BuildingPartIdentifier.MAIN] + assert overlay.construction_age_band == "B"