"""The Secondary Heating Removal Recommendation Generator (ADR-0028). Offers to strip a dwelling's lodged secondary heating system so the main system serves 100% of space heating. A **standalone, co-selectable** Recommendation — not an Option in the Heating & Hot Water rec — because removing a secondary heater is independent of (and combinable with) a tune-up or boiler upgrade. Eligibility is purely physical: offered **iff a secondary is lodged** (`sap_heating.secondary_heating_type` is set). RdSAP only records a secondary when a *fixed* emitter is present (portable plug-in heaters are ignored), so a lodged secondary is by definition a fixed unit worth removing. There is no effectiveness gate — on an electric-storage main RdSAP §A.2.2 forces a default secondary back, making removal a no-op, but that is the Optimiser's call (it owns the economics), not eligibility's. Detection + pricing only; impact is produced later by scoring (ADR-0016). Priced at a flat per-dwelling decommission cost (one electrician visit to disconnect a fixed/hard-wired heater + localised making-good), not scaled by room count — the EPC lodges one secondary system with no heater count (ADR-0028). """ from typing import Final, Optional from datatypes.epc.domain.epc_property_data import EpcPropertyData from domain.modelling.measure_type import MeasureType from domain.modelling.recommendation import Cost, MeasureOption, Recommendation from domain.modelling.simulation import EpcSimulation, SecondaryHeatingOverlay from repositories.product.product_repository import ProductRepository _SECONDARY_HEATING_REMOVAL_MEASURE_TYPE: Final[MeasureType] = ( MeasureType.SECONDARY_HEATING_REMOVAL ) def recommend_secondary_heating_removal( epc: EpcPropertyData, products: ProductRepository ) -> Optional[Recommendation]: """Return a Secondary Heating Removal Recommendation — its single Option clears the lodged secondary system — else None when no secondary is lodged (nothing physical to remove).""" if epc.sap_heating.secondary_heating_type is None: return None product = products.get(_SECONDARY_HEATING_REMOVAL_MEASURE_TYPE) overlay = EpcSimulation(secondary_heating=SecondaryHeatingOverlay()) cost = Cost( total=product.unit_cost_per_m2, contingency_rate=product.contingency_rate, ) option = MeasureOption( measure_type=_SECONDARY_HEATING_REMOVAL_MEASURE_TYPE, description="Remove the secondary heating system", overlay=overlay, cost=cost, material_id=product.id, ) return Recommendation(surface="Secondary Heating", options=(option,))