diff --git a/etl/eligibility/ha_15_32/ha_analysis_batch_3.py b/etl/eligibility/ha_15_32/ha_analysis_batch_3.py index 1e2c5d92..d4c3f74f 100644 --- a/etl/eligibility/ha_15_32/ha_analysis_batch_3.py +++ b/etl/eligibility/ha_15_32/ha_analysis_batch_3.py @@ -2859,21 +2859,30 @@ def calculate_eco4_post_ciga( eligiblity_counts["ECO Eligibility"] == "failed ciga" ]["count"].sum() + eco4_no_ciga_needed_or_ciga_passed = eco4_no_ciga_needed + eco4_ciga_passed + eco4_confirmed = (eco4_no_ciga_needed * ha_eco4_to_sale_rate) + (eco4_ciga_passed * ha_ciga_pass_to_sale_rate) eco4_confirmed = np.round(eco4_confirmed) + eco4_no_ciga_needed_cancellations = int(eco4_no_ciga_needed_or_ciga_passed - eco4_confirmed) + if remaining_needing_ciga_check > 0: # We update the eco4 post ciga with the converted remaining eco4_ciga_expected_remaining_to_pass = np.round(remaining_needing_ciga_check * ha_ciga_conversion_rate) + eco4_remaining_forecast = np.round( eco4_ciga_expected_remaining_to_pass * ha_ciga_pass_to_sale_rate ) + eco4_ciga_needed_cancellations = eco4_ciga_expected_remaining_to_pass - eco4_remaining_forecast eco4_estimated_ciga_failures = remaining_needing_ciga_check - eco4_ciga_expected_remaining_to_pass eco4_post_ciga = eco4_confirmed + eco4_remaining_forecast else: eco4_remaining_forecast = 0 eco4_estimated_ciga_failures = 0 + eco4_ciga_needed_cancellations = 0 eco4_post_ciga = eco4_confirmed + + eco4_expected_cancellations = eco4_no_ciga_needed_cancellations + eco4_ciga_needed_cancellations else: eco4_no_ciga_needed = eligiblity_counts[ eligiblity_counts["ECO Eligibility"] == "eco4" @@ -2881,14 +2890,18 @@ def calculate_eco4_post_ciga( eco4_confirmed_ciga_failures = 0 # Multiply by sale conversion eco4_confirmed = np.round(eco4_no_ciga_needed * ha_eco4_to_sale_rate) + eco4_no_ciga_cancellations = int(eco4_no_ciga_needed - eco4_confirmed) eco4_ciga_expected_remaining_to_pass = np.round(remaining_needing_ciga_check * ha_ciga_conversion_rate) eco4_estimated_ciga_failures = remaining_needing_ciga_check - eco4_ciga_expected_remaining_to_pass eco4_remaining_forecast = np.round( eco4_ciga_expected_remaining_to_pass * ha_ciga_pass_to_sale_rate ) + eco4_ciga_cancellations = int(eco4_ciga_expected_remaining_to_pass - eco4_remaining_forecast) eco4_post_ciga = eco4_confirmed + eco4_remaining_forecast + eco4_expected_cancellations = eco4_no_ciga_cancellations + eco4_ciga_cancellations + eco4_post_ciga = int(eco4_post_ciga) eco4_remaining_forecast = int(eco4_remaining_forecast) eco4_confirmed = int(eco4_confirmed) @@ -2912,6 +2925,9 @@ def calculate_eco4_post_ciga( ), "Confirmed CIGA failures - £": int(eco4_confirmed_ciga_failures * eco4_rate), "Estimated CIGA failures - £": int(eco4_estimated_ciga_failures * eco4_rate), + # Expected cencellations + "Expected cancellations - #": eco4_expected_cancellations, + "Expected cancellations - £": eco4_expected_cancellations * eco4_rate } return results @@ -3322,6 +3338,28 @@ def forecast_remaining_sales(loader): incomplete_gbis_sales.shape[0] * ha_gbis_sale_conversion * gbis_rate ) + # Add in the variance: + # We should expect that the pre-ciga total is: + # 1) The number of post CIGA successes + + # 2) the number of CIGA failures + + # 3) The number of cancellations + variance_total = eco4_pre_ciga - ( + eco4_post_ciga_total_results["ECO4 - post CIGA - #"] + + eco4_post_ciga_total_results['Estimated total - failed CIGA'] + + eco4_post_ciga_total_results["Expected cancellations - #"] + ) + if variance_total != 0: + raise ValueError("Something went wrong in variance total") + + variance_remaining = eco4_pre_ciga_remaining - ( + eco4_post_ciga_remaining_results["ECO4 - post CIGA - #"] + + eco4_post_ciga_remaining_results['Estimated total - failed CIGA'] + + eco4_post_ciga_remaining_results["Expected cancellations - #"] + ) + + if variance_remaining != 0: + raise ValueError("Something went wrong in variance remaining") + to_append = { ("", "", "", "HA Name"): ha_name, # ECO4 - original warmfront figures @@ -3340,6 +3378,8 @@ def forecast_remaining_sales(loader): ("", "Warmfront post code list", "Total #", "ECO4 total (pre-ciga)"): eco4_pre_ciga, ("ECO4 pre-ciga", "", "Remaining - #", ""): eco4_pre_ciga_remaining, ("ECO4 pre-ciga", "", "Total - £", ""): eco4_pre_ciga_revenue, + ("ECO4 pre-ciga", "", "VARIANCE - TOTAL", ""): variance_total, + ("ECO4 pre-ciga", "", "VARIANCE - REMAINING", ""): variance_remaining, ("ECO4 pre-ciga", "", "Sold - £", ""): eco4_actually_sold, ("ECO4 pre-ciga", "", "Remaining - £", ""): eco4_pre_ciga_remaining_revenue, # ECO4 - asset list, post ciga, total @@ -3382,6 +3422,13 @@ def forecast_remaining_sales(loader): ("ECO4 CIGA failures", "", "Estimated failures - £", ""): eco4_post_ciga_remaining_results[ "Estimated CIGA failures - £" ], + # Expected ECO4 cancellations + ("ECO4 Cancellations", "", "Expected cancellations - #", ""): eco4_post_ciga_remaining_results[ + "Expected cancellations - #" + ], + ("ECO4 Cancellations", "", "Expected cancellations - £", ""): eco4_post_ciga_remaining_results[ + "Expected cancellations - £" + ], # GBIS postcode list ("GBIS Postcode list", "Warmfront post code list", "Total - #", "GBIS total"): gbis_total, ("GBIS Postcode list", "Warmfront post code list", "Total - £", "GBIS total"): gbis_total_revenue, @@ -3393,7 +3440,7 @@ def forecast_remaining_sales(loader): } # Make sure nothing is forgotten due to duplicate multi-index keys - if len(to_append) != 37: + if len(to_append) != 41: raise ValueError("Something went wrong") results.append(to_append)