diff --git a/domain/modelling/floor_recommendation.py b/domain/modelling/floor_recommendation.py index a6992a85..f2360677 100644 --- a/domain/modelling/floor_recommendation.py +++ b/domain/modelling/floor_recommendation.py @@ -21,6 +21,12 @@ from repositories.product.product_repository import ProductRepository # Recommended ground-floor insulation depth (mm). _RECOMMENDED_FLOOR_THICKNESS_MM = 100 +# Insulating an as-built floor re-lodges its insulation as retro-fitted. The +# calculator keys on this for a suspended timber floor's sealed/unsealed +# determination (cert_to_inputs: "retro" + no U-value → sealed), so the +# overlay must set it or the suspended-floor cascade leaves a ~1.4 SAP gap +# (see test_elmhurst_cascade_pins). +_RETROFITTED_INSULATION = "Retro-fitted" def _is_uninsulated(thickness: Optional[Union[str, int]]) -> bool: @@ -75,7 +81,8 @@ def recommend_floor_insulation( overlay=EpcSimulation( building_parts={ BuildingPartIdentifier.MAIN: BuildingPartOverlay( - floor_insulation_thickness=_RECOMMENDED_FLOOR_THICKNESS_MM + floor_insulation_thickness=_RECOMMENDED_FLOOR_THICKNESS_MM, + floor_insulation_type_str=_RETROFITTED_INSULATION, ) } ), diff --git a/domain/modelling/simulation.py b/domain/modelling/simulation.py index 5b2ba8a6..7f9b7469 100644 --- a/domain/modelling/simulation.py +++ b/domain/modelling/simulation.py @@ -24,6 +24,7 @@ class BuildingPartOverlay: wall_insulation_type: Optional[int] = None roof_insulation_thickness: Optional[int] = None floor_insulation_thickness: Optional[int] = None + floor_insulation_type_str: Optional[str] = None def _no_building_parts() -> dict[BuildingPartIdentifier, BuildingPartOverlay]: diff --git a/tests/domain/modelling/fixtures/solid_floor_001431_after.pdf b/tests/domain/modelling/fixtures/solid_floor_001431_after.pdf new file mode 100644 index 00000000..ea3ffbfa Binary files /dev/null and b/tests/domain/modelling/fixtures/solid_floor_001431_after.pdf differ diff --git a/tests/domain/modelling/fixtures/solid_floor_001431_before.pdf b/tests/domain/modelling/fixtures/solid_floor_001431_before.pdf new file mode 100644 index 00000000..187140c0 Binary files /dev/null and b/tests/domain/modelling/fixtures/solid_floor_001431_before.pdf differ diff --git a/tests/domain/modelling/fixtures/suspended_floor_001431_after.pdf b/tests/domain/modelling/fixtures/suspended_floor_001431_after.pdf new file mode 100644 index 00000000..3cc53118 Binary files /dev/null and b/tests/domain/modelling/fixtures/suspended_floor_001431_after.pdf differ diff --git a/tests/domain/modelling/fixtures/suspended_floor_001431_before.pdf b/tests/domain/modelling/fixtures/suspended_floor_001431_before.pdf new file mode 100644 index 00000000..49a82bc0 Binary files /dev/null and b/tests/domain/modelling/fixtures/suspended_floor_001431_before.pdf differ diff --git a/tests/domain/modelling/test_elmhurst_cascade_pins.py b/tests/domain/modelling/test_elmhurst_cascade_pins.py index bc2d6f32..16202022 100644 --- a/tests/domain/modelling/test_elmhurst_cascade_pins.py +++ b/tests/domain/modelling/test_elmhurst_cascade_pins.py @@ -20,6 +20,7 @@ from datatypes.epc.domain.epc_property_data import EpcPropertyData from domain.modelling.package_scorer import PackageScorer, Score from domain.modelling.product import Product from domain.modelling.recommendation import Recommendation +from domain.modelling.floor_recommendation import recommend_floor_insulation from domain.modelling.roof_recommendation import recommend_loft_insulation from domain.modelling.simulation import EpcSimulation from domain.modelling.wall_recommendation import recommend_cavity_wall @@ -99,3 +100,41 @@ def test_loft_overlay_reproduces_the_relodged_after() -> None: _assert_overlay_reproduces_after( before, after, recommendation.options[0].overlay ) + + +def test_solid_floor_overlay_reproduces_the_relodged_after() -> None: + # Arrange + before: EpcPropertyData = parse_recommendation_summary( + "solid_floor_001431_before.pdf" + ) + after: EpcPropertyData = parse_recommendation_summary( + "solid_floor_001431_after.pdf" + ) + recommendation: Recommendation | None = recommend_floor_insulation( + before, _AnyProduct() + ) + assert recommendation is not None + + # Act / Assert + _assert_overlay_reproduces_after( + before, after, recommendation.options[0].overlay + ) + + +def test_suspended_floor_overlay_reproduces_the_relodged_after() -> None: + # Arrange + before: EpcPropertyData = parse_recommendation_summary( + "suspended_floor_001431_before.pdf" + ) + after: EpcPropertyData = parse_recommendation_summary( + "suspended_floor_001431_after.pdf" + ) + recommendation: Recommendation | None = recommend_floor_insulation( + before, _AnyProduct() + ) + assert recommendation is not None + + # Act / Assert + _assert_overlay_reproduces_after( + before, after, recommendation.options[0].overlay + )