diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index 9d9a7802..e2c295c2 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -830,7 +830,29 @@ class EpcPropertyDataMapper: secondary_heating_type=schema.sap_heating.secondary_heating_type, cylinder_insulation_thickness_mm=schema.sap_heating.cylinder_insulation_thickness, ), - sap_windows=[], + # ADR-0028: 990/1000 omit sap_windows -> synthesised from the + # glazed_area band + TFA (added in a later slice). The 10 rich + # certs keep their lodged per-window geometry. + sap_windows=[ + SapWindow( + frame_material=None, + glazing_gap=0, + orientation=w.orientation, + window_type=w.window_type, + glazing_type=w.glazing_type, + # ADR-0028: the 10 rich certs lodge a real per-window + # window_area (Measurement) -- use it directly as geometry + # (width = area, height = 1.0) rather than the placeholder + # windowless 0x0. + window_width=_measurement_value(w.window_area), + window_height=1.0, + draught_proofed=False, + window_location=w.window_location, + window_wall_type=0, + permanent_shutters_present=False, + ) + for w in schema.sap_windows + ], sap_energy_source=SapEnergySource( mains_gas=es.mains_gas == "Y", meter_type=str(es.meter_type), diff --git a/datatypes/epc/schema/rdsap_schema_18_0.py b/datatypes/epc/schema/rdsap_schema_18_0.py index 4289aef7..08e008db 100644 --- a/datatypes/epc/schema/rdsap_schema_18_0.py +++ b/datatypes/epc/schema/rdsap_schema_18_0.py @@ -170,6 +170,19 @@ class RenewableHeatIncentive: impact_of_solid_wall_insulation: Optional[int] = None +@dataclass +class SapWindow: + """Per-window geometry. ADR-0028: only 10/1000 18.0 certs lodge this array + (all band-4); window_area arrives as a Measurement and is read via + `_measurement_value`. Mirrors the 20.0.0 SapWindow shape.""" + + orientation: int + window_area: float + window_type: int + glazing_type: int + window_location: int + + @dataclass(kw_only=True) class RdSapSchema18_0: uprn: int @@ -258,3 +271,8 @@ class RdSapSchema18_0: sap_flat_details: Optional[SapFlatDetails] = None address_line_2: Optional[str] = None alternative_improvements: Optional[List[AlternativeImprovement]] = None + # ADR-0028: additive — the placeholder schema omitted sap_windows entirely, + # silently dropping the 10 rich certs' lodged per-window geometry. Capture it + # so the mapper can use lodged window_area directly (default [] = windowless, + # synthesised from the glazed_area band). + sap_windows: List[SapWindow] = field(default_factory=list)