From 23e111cb81cdf7cc3cf68c8d17dd19aae578b24d Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 29 Aug 2025 22:49:52 +0800 Subject: [PATCH] fixe bug with violates min insulation constraints --- .../optimiser/funding_optimiser.py | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/recommendations/optimiser/funding_optimiser.py b/recommendations/optimiser/funding_optimiser.py index 84ad4dbc..03824ea0 100644 --- a/recommendations/optimiser/funding_optimiser.py +++ b/recommendations/optimiser/funding_optimiser.py @@ -77,8 +77,12 @@ def _sum_cost_gain_with_scheme(items, scheme): return total_cost, total_gain -def violates_min_insulation(fixed): - """Return True if fixed selection includes a heating/PV measure but no required insulation.""" +def violates_min_insulation(fixed, optimisation_input_measures): + """ + Return True if fixed selection includes a heating/PV measure but no required insulation. + It should *only* violate min insulation if the fixed selection excldes insulation but the + property needs insulation + """ picked_types = {opt["type"] for (_, _, opt) in fixed} def has_any(substrs): @@ -106,7 +110,22 @@ def violates_min_insulation(fixed): "room_roof_insulation", ]) - return is_heating and not has_insul + def _needs_insulation(measures, t): + return _find_measure(measures, t) and not has_any({t}) + + needs_insul = any( + _needs_insulation(optimisation_input_measures, t) + for t in [ + "external_wall_insulation", + "internal_wall_insulation", + "cavity_wall_insulation", + "loft_insulation", + "flat_roof_insulation", + "room_roof_insulation", + ] + ) + + return is_heating and not has_insul and needs_insul # Treat "type" like "external_wall_insulation+mechanical_ventilation" → "external_wall_insulation" @@ -278,10 +297,11 @@ def optimise_with_funding_paths(p, input_measures, housing_type, funding: Fundin for fixed in fixed_selections: - if violates_min_insulation(fixed): + if violates_min_insulation(fixed, optimisation_input_measures): # We log an error and skip this - we should not see any errors but we can probably get a reasonable # outcome for the end user without a complete termination of the process logger.error("Skipping fixed selection due to minimum insulation violation: %s", fixed) + blah continue scheme = _path_scheme(path_spec)