Resolve a landlord age-band override onto the main building part 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jun-te Kim 2026-06-19 13:41:20 +00:00
parent 5a6d9a4e5d
commit 0135f0f27b
3 changed files with 51 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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"