Normalize PasHub main-heating Mains gas to SAP fuel code 26 🟩

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-14 14:29:26 +00:00
parent 52c5826afc
commit 02ad8701d3
2 changed files with 24 additions and 2 deletions

View file

@ -6027,7 +6027,7 @@ def _map_sap_heating(
main_heating_details=[
MainHeatingDetail(
has_fghrs=main.flue_gas_heat_recovery_system,
main_fuel_type=fuel_type,
main_fuel_type=_pashub_main_fuel_code(fuel_type),
heat_emitter_type=main.emitter,
emitter_temperature=main.emitter_temperature,
fan_flue_present=main.fan_assist,
@ -7030,6 +7030,28 @@ def _elmhurst_main_fuel_int(fuel_type: str) -> Optional[int]:
return _ELMHURST_MAIN_FUEL_TO_SAP10.get(fuel_type)
# PasHub Site-Notes surveyed main-heating "Fuel" labels mapped to SAP10 fuel
# codes (the epc-codes `main_fuel` enum the calculator's resolver routes via
# its API→Table-12/32 translation). Seeded only with labels confirmed from
# live PasHub fixtures; a dedicated lookup rather than reuse of the Elmhurst
# map, which carries legacy label oddities PasHub must not inherit. New labels
# are a one-line addition — until then they strict-raise at the boundary
# (ADR-0015) rather than being silently mis-billed downstream.
_PASHUB_MAIN_FUEL_TO_SAP10: Dict[str, int] = {
"Mains gas": 26, # matches the Elmhurst mapper's mains-gas code
"Electricity": 30, # the standard-electricity fuel code
}
def _pashub_main_fuel_code(fuel_label: str) -> Union[int, str]:
"""Resolve a PasHub surveyed main-heating Fuel label to a SAP10 fuel code
at the mapper boundary (ADR-0015). A genuinely blank label is the "no main
heating" shape and passes through unchanged."""
if not fuel_label:
return fuel_label
return _PASHUB_MAIN_FUEL_TO_SAP10.get(fuel_label, fuel_label)
def _resolve_elmhurst_underfloor_subtype(
main_floor: ElmhurstFloorDetails,
main_age_band: str,

View file

@ -379,7 +379,7 @@ class TestFromSiteNotesExample1:
main_heating_details=[
MainHeatingDetail(
has_fghrs=False,
main_fuel_type="Mains gas",
main_fuel_type=26,
heat_emitter_type="Radiators",
emitter_temperature="Unknown",
fan_flue_present=True,