From 5b0f25847ceb3fc7ff3f8320271b717f06b5d38c Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 14 Jul 2026 15:17:06 +0000 Subject: [PATCH] =?UTF-8?q?Normalize=20PasHub=20site-notes=20emitter=20lab?= =?UTF-8?q?el=20to=20its=20SAP10=20code=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _map_sap_heating resolves the raw emitter label (e.g. Radiators) to its SAP10 emitter code via _pashub_heat_emitter_code, reusing the Elmhurst emitter map. Blank passes through; an unrecognised label strict-raises UnmappedPasHubLabel at the mapper boundary (ADR-0015) instead of resurfacing as the calculator's UnmappedSapCode: heat_emitter_type. Co-Authored-By: Claude Opus 4.8 (1M context) --- datatypes/epc/domain/mapper.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index b3bfdb370..266fa6e71 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -6028,7 +6028,7 @@ def _map_sap_heating( MainHeatingDetail( has_fghrs=main.flue_gas_heat_recovery_system, main_fuel_type=_pashub_main_fuel_code(fuel_type), - heat_emitter_type=main.emitter, + heat_emitter_type=_pashub_heat_emitter_code(main.emitter), emitter_temperature=main.emitter_temperature, fan_flue_present=main.fan_assist, main_heating_control=main.controls, @@ -7081,6 +7081,20 @@ def _pashub_main_fuel_code(fuel_label: str) -> Union[int, str]: return code +def _pashub_heat_emitter_code(emitter_label: str) -> Union[int, str]: + """Resolve a PasHub surveyed main-heating emitter label to its SAP10 emitter + code at the mapper boundary (ADR-0015), reusing the Elmhurst emitter map + (`Radiators -> 1`). A blank label passes through unchanged; a non-empty label + the map does not cover strict-raises `UnmappedPasHubLabel` here rather than + resurfacing downstream as the calculator's `UnmappedSapCode: heat_emitter_type`.""" + if not emitter_label: + return emitter_label + code = _ELMHURST_HEAT_EMITTER_TO_SAP10.get(emitter_label) + if code is None: + raise UnmappedPasHubLabel("heat emitter", emitter_label) + return code + + def _resolve_elmhurst_underfloor_subtype( main_floor: ElmhurstFloorDetails, main_age_band: str,