diff --git a/etl/eligibility/ha_15_32/app.py b/etl/eligibility/ha_15_32/app.py index b7f44a43..76aadcc4 100644 --- a/etl/eligibility/ha_15_32/app.py +++ b/etl/eligibility/ha_15_32/app.py @@ -980,6 +980,8 @@ def analyse_ha_15_results(results_df, ha15, no_house_numbers): results_df["warmfront_identified"] ] + warmfront_identified = warmfront_identified + n_identified = (warmfront_identified["gbis_eligible"] | warmfront_identified["eco4_eligible"]).sum() success_rate = n_identified / warmfront_identified.shape[0] @@ -1030,6 +1032,11 @@ def analyse_ha_15_results(results_df, ha15, no_house_numbers): (results_df["eco4_eligible"] == True) ].copy() + new_possibilities_gbis = results_df[ + (~results_df["warmfront_identified"]) & + (results_df["eco4_eligible"] == False) & (results_df["gbis_eligible"] == True) + ].copy() + # These are future possibilityies future_possibilities_eco = results_df[ (~results_df["warmfront_identified"]) & diff --git a/etl/eligibility/ha_15_32/ha16_app.py b/etl/eligibility/ha_15_32/ha16_app.py index b7f076b1..0d67e0b4 100644 --- a/etl/eligibility/ha_15_32/ha16_app.py +++ b/etl/eligibility/ha_15_32/ha16_app.py @@ -478,7 +478,7 @@ def get_epc_data(data, cleaned, cleaning_data, created_at, photo_supply_lookup, def analyse_results(results_df, data, survey_list): - analysis_data = data[["row_id", "survey_key", "warmfront_identified"]].merge( + analysis_data = data[["row_id", "survey_key", "warmfront_identified", "row_colour_name"]].merge( results_df, how="left", on="row_id" ).merge( survey_list[["survey_key", survey_list.columns[0]]].rename(columns={survey_list.columns[0]: "funding_scheme"}), diff --git a/etl/eligibility/ha_15_32/ha25_app.py b/etl/eligibility/ha_15_32/ha25_app.py index c67c6b6b..7dd36726 100644 --- a/etl/eligibility/ha_15_32/ha25_app.py +++ b/etl/eligibility/ha_15_32/ha25_app.py @@ -787,6 +787,11 @@ def analyse_results(results_df, data, eco4_prospects_survey_list): results_df, how="left", on="row_id" ) + analysis_data = analysis_data.merge( + eco4_prospects_survey_list[["survey_key", "ADDRESS 1", "NO", "POSTCODE"]], + how="left", on="survey_key" + ) + # NEW analysis_data["roof_insulation_thickness"] = np.where( pd.isnull(analysis_data["roof_insulation_thickness"]), None, analysis_data["roof_insulation_thickness"] diff --git a/etl/eligibility/ha_15_32/ha7_app.py b/etl/eligibility/ha_15_32/ha7_app.py index 54d0dbb0..c6486159 100644 --- a/etl/eligibility/ha_15_32/ha7_app.py +++ b/etl/eligibility/ha_15_32/ha7_app.py @@ -272,6 +272,8 @@ def analyse_ha_7(results_df, data): data[["row_id", "row_code", "Property Type", "Construction Year Band"]], how="left", on="row_id" ) + analysis_data["row_code"].value_counts() + # NEW analysis_data["roof_insulation_thickness"] = np.where( @@ -304,6 +306,10 @@ def analyse_ha_7(results_df, data): ) ] + wf_identified = analysis_data[ + (analysis_data["row_code"] == "potential ECO4") + ] + # END NEW warmfront_identification = analysis_data["row_code"].value_counts() diff --git a/recommendations/SolarPvRecommendations.py b/recommendations/SolarPvRecommendations.py index 5163c1cb..01cd4f17 100644 --- a/recommendations/SolarPvRecommendations.py +++ b/recommendations/SolarPvRecommendations.py @@ -31,7 +31,8 @@ class SolarPvRecommendations: is_valid_roof_type = ( self.property.roof["is_flat"] or self.property.roof["is_pitched"] or self.property.roof["is_roof_room"] ) - has_no_existing_solar_pv = not self.property.data["photo-supply"] in [ + # If there is no existing solar PV, the photo-supply field will be None or a missing value + has_no_existing_solar_pv = self.property.data["photo-supply"] in [ None, 0, self.property.DATA_ANOMALY_MATCHES ] diff --git a/recommendations/tests/test_solar_pv_recommendations.py b/recommendations/tests/test_solar_pv_recommendations.py index e69de29b..f2436cb1 100644 --- a/recommendations/tests/test_solar_pv_recommendations.py +++ b/recommendations/tests/test_solar_pv_recommendations.py @@ -0,0 +1,79 @@ +import pytest +from recommendations.SolarPvRecommendations import SolarPvRecommendations +from backend.Property import Property + + +class TestSolarPvRecommendations: + @pytest.fixture + def property_instance_invalid_type(self): + # Setup the property_instance with an invalid property type + property_instance_invalid_type = Property(id=1, address="", postcode="") + property_instance_invalid_type.data = { + "property-type": "InvalidType", "county": "Broxbourne", "photo-supply": None + } + property_instance_invalid_type.roof = {"is_flat": False, "is_pitched": False, "is_roof_room": False} + return property_instance_invalid_type + + @pytest.fixture + def property_instance_invalid_roof(self): + # Setup the property_instance with invalid roof type + property_instance_invalid_roof = Property(id=1, address="", postcode="") + property_instance_invalid_roof.data = { + "county": "Huntingdonshire", "property-type": "House", "photo-supply": None + } + property_instance_invalid_roof.roof = {"is_flat": False, "is_pitched": False, "is_roof_room": False} + return property_instance_invalid_roof + + @pytest.fixture + def property_instance_has_solar_pv(self): + # Setup the property_instance without existing solar pv + property_instance_has_solar_pv = Property(id=1, address="", postcode="") + property_instance_has_solar_pv.data = {"photo-supply": "40", "county": "Huntingdonshire", + "property-type": "House"} + property_instance_has_solar_pv.roof = {"is_flat": True} + return property_instance_has_solar_pv + + @pytest.fixture + def property_instance_valid_all(self): + # Setup a valid property_instance that passes all conditions + property_instance_valid_all = Property(id=1, address="", postcode="") + property_instance_valid_all.solar_pv_roof_area = 20 + property_instance_valid_all.solar_pv_percentage = 40 + property_instance_valid_all.data = {"property-type": "House", "photo-supply": None, "county": "Huntingdonshire"} + property_instance_valid_all.roof = {"is_flat": True} + return property_instance_valid_all + + def test_invalid_property_type(self, property_instance_invalid_type): + solar_pv = SolarPvRecommendations(property_instance_invalid_type) + solar_pv.recommend() + assert not solar_pv.recommendation + + def test_invalid_roof_type(self, property_instance_invalid_roof): + solar_pv = SolarPvRecommendations(property_instance_invalid_roof) + solar_pv.recommend() + assert not solar_pv.recommendation + + def test_existing_solar_pv(self, property_instance_has_solar_pv): + solar_pv = SolarPvRecommendations(property_instance_has_solar_pv) + solar_pv.recommend() + assert not solar_pv.recommendation + + def test_valid_all_conditions(self, property_instance_valid_all): + solar_pv = SolarPvRecommendations(property_instance_valid_all) + solar_pv.recommend() + assert solar_pv.recommendation == [ + { + 'parts': [], + 'type': 'solar_pv', + 'description': 'Install a 4 kilowatt-peak (kWp) solar photovoltaic (PV) panel system on the roof', + 'starting_u_value': None, + 'new_u_value': None, + 'sap_points': None, + 'total': 8527.0752, + 'subtotal': 7105.896, + 'vat': 1421.1791999999996, + 'labour_hours': 72, + 'labour_days': 2, + 'photo_supply': 4000 + } + ]