mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Fixing bug with gbis remaining counts
This commit is contained in:
parent
f8948ff60f
commit
abe0e627db
1 changed files with 184 additions and 82 deletions
|
|
@ -424,6 +424,12 @@ class DataLoader:
|
|||
def load_asset_list(self, filepath, ha_name):
|
||||
workbook = openpyxl.load_workbook(filepath)
|
||||
asset_sheetname = self.get_asset_sheetname(workbook)
|
||||
|
||||
# TODO: TEMP
|
||||
sheetnames_lower = [x.lower() for x in workbook.sheetnames]
|
||||
if any("eco3" in x for x in sheetnames_lower):
|
||||
raise Exception("REMOVE ME")
|
||||
|
||||
asset_sheet = workbook[asset_sheetname]
|
||||
asset_sheet_colnames = [cell.value for cell in asset_sheet[1]]
|
||||
if ha_name == "HA25":
|
||||
|
|
@ -569,6 +575,34 @@ class DataLoader:
|
|||
)
|
||||
return asset_list
|
||||
|
||||
@staticmethod
|
||||
def correct_ha38_asset_list(asset_list):
|
||||
# For Kingsford court, the house number is at the end of the address
|
||||
def rearrange_address_if_flat(address):
|
||||
if '/flat' in address.lower():
|
||||
parts = address.split('/flat', 1)
|
||||
return f"FLAT{parts[1]}, {parts[0]}"
|
||||
return address
|
||||
|
||||
def extract_house_no_if_flat(address):
|
||||
if '/flat' in address.lower():
|
||||
# Attempt to extract the house number following "/flat"
|
||||
try:
|
||||
house_no = address.split('/flat ')[1].split(' ')[0]
|
||||
# Remove trailing comma
|
||||
house_no = house_no.replace(",", "")
|
||||
except IndexError:
|
||||
house_no = None
|
||||
return house_no
|
||||
return None
|
||||
|
||||
asset_list['ExtractedHouseNo'] = asset_list['matching_address'].apply(extract_house_no_if_flat)
|
||||
asset_list.loc[asset_list['ExtractedHouseNo'].notnull(), 'HouseNo'] = asset_list['ExtractedHouseNo']
|
||||
asset_list['matching_address'] = asset_list['matching_address'].apply(rearrange_address_if_flat)
|
||||
# We then need to
|
||||
|
||||
return asset_list
|
||||
|
||||
@staticmethod
|
||||
def correct_ha6_survey_list(survey_list):
|
||||
|
||||
|
|
@ -925,6 +959,11 @@ class DataLoader:
|
|||
def correct_ha38_survey_list(survey_list):
|
||||
# Rename the "No" column to "No." to align with the other survey sheets
|
||||
survey_list = survey_list.rename(columns={"NO ": "NO."})
|
||||
|
||||
survey_list["Street / Block Name"] = survey_list["Street / Block Name"].str.replace(
|
||||
'Kingsford Court, Coombe Valley Road', 'Kingsford Court'
|
||||
)
|
||||
|
||||
return survey_list
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -1345,6 +1384,7 @@ class DataLoader:
|
|||
"eco4 (subject to ciga/archetype check": "eco4 (subject to ciga)",
|
||||
"eco4 (subject to archetype check)": "eco4",
|
||||
"eco4 (subject to ciga/archetype)": "eco4 (subject to ciga)",
|
||||
"eco4 (subject to ciga)": "eco4 (subject to ciga)"
|
||||
}
|
||||
|
||||
ha_facts_and_figures = []
|
||||
|
|
@ -2943,8 +2983,8 @@ def forecast_remaining_sales(loader):
|
|||
median_ciga_success_rate = ciga_passrates["# CIGA passed"].sum() / ciga_passrates["# CIGA dependent"].sum()
|
||||
|
||||
# 3) Calculate the conversion rate of an ECO4 and a GBISjob, that doesn't need ciga, to install
|
||||
eco4_ciga_independent_passrates = []
|
||||
gbis_ciga_independent_passrates = []
|
||||
eco4_ciga_independent_to_install = []
|
||||
gbis_to_install = []
|
||||
for ha_name, input_data in loader.data.items():
|
||||
asset_list = input_data["asset_list"].copy()
|
||||
survey_list = input_data["survey_list"].copy()
|
||||
|
|
@ -2973,7 +3013,7 @@ def forecast_remaining_sales(loader):
|
|||
)
|
||||
]
|
||||
|
||||
eco4_ciga_independent_passrates.append(
|
||||
eco4_ciga_independent_to_install.append(
|
||||
{
|
||||
"Ha Name": ha_name,
|
||||
"# ECO4 at install stage": typical_eco4_installed.shape[0],
|
||||
|
|
@ -2993,7 +3033,7 @@ def forecast_remaining_sales(loader):
|
|||
)
|
||||
]
|
||||
|
||||
gbis_ciga_independent_passrates.append(
|
||||
gbis_to_install.append(
|
||||
{
|
||||
"Ha Name": ha_name,
|
||||
"# GBIS at install stage": typical_gbis_installed.shape[0],
|
||||
|
|
@ -3001,33 +3041,33 @@ def forecast_remaining_sales(loader):
|
|||
}
|
||||
)
|
||||
|
||||
eco4_ciga_independent_passrates = pd.DataFrame(eco4_ciga_independent_passrates)
|
||||
gbis_ciga_independent_passrates = pd.DataFrame(gbis_ciga_independent_passrates)
|
||||
eco4_ciga_independent_to_install = pd.DataFrame(eco4_ciga_independent_to_install)
|
||||
gbis_to_install = pd.DataFrame(gbis_to_install)
|
||||
|
||||
eco4_ciga_independent_passrates["conversion"] = (
|
||||
eco4_ciga_independent_passrates["# ECO4 successfully installed"] /
|
||||
eco4_ciga_independent_passrates["# ECO4 at install stage"]
|
||||
eco4_ciga_independent_to_install["conversion"] = (
|
||||
eco4_ciga_independent_to_install["# ECO4 successfully installed"] /
|
||||
eco4_ciga_independent_to_install["# ECO4 at install stage"]
|
||||
)
|
||||
eco4_ciga_independent_passrates_clipped = eco4_ciga_independent_passrates[
|
||||
eco4_ciga_independent_passrates["conversion"] >= sales_conversion_lower_bound
|
||||
eco4_ciga_independent_to_install_clipped = eco4_ciga_independent_to_install[
|
||||
eco4_ciga_independent_to_install["conversion"] >= sales_conversion_lower_bound
|
||||
]
|
||||
|
||||
gbis_ciga_independent_passrates["conversion"] = (
|
||||
gbis_ciga_independent_passrates["# GBIS successfully installed"] /
|
||||
gbis_ciga_independent_passrates["# GBIS at install stage"]
|
||||
gbis_to_install["conversion"] = (
|
||||
gbis_to_install["# GBIS successfully installed"] /
|
||||
gbis_to_install["# GBIS at install stage"]
|
||||
)
|
||||
gbis_ciga_independent_passrates_clipped = gbis_ciga_independent_passrates[
|
||||
gbis_ciga_independent_passrates["conversion"] >= sales_conversion_lower_bound
|
||||
gbis_to_install_clipped = gbis_to_install[
|
||||
gbis_to_install["conversion"] >= sales_conversion_lower_bound
|
||||
]
|
||||
|
||||
median_eco4_to_install = (
|
||||
eco4_ciga_independent_passrates_clipped["# ECO4 successfully installed"].sum() /
|
||||
eco4_ciga_independent_passrates_clipped["# ECO4 at install stage"].sum()
|
||||
eco4_ciga_independent_to_install_clipped["# ECO4 successfully installed"].sum() /
|
||||
eco4_ciga_independent_to_install_clipped["# ECO4 at install stage"].sum()
|
||||
)
|
||||
|
||||
median_gbis_to_install = (
|
||||
gbis_ciga_independent_passrates_clipped["# GBIS successfully installed"].sum() /
|
||||
gbis_ciga_independent_passrates_clipped["# GBIS at install stage"].sum()
|
||||
gbis_to_install_clipped["# GBIS successfully installed"].sum() /
|
||||
gbis_to_install_clipped["# GBIS at install stage"].sum()
|
||||
)
|
||||
|
||||
# Produce the final output
|
||||
|
|
@ -3044,29 +3084,26 @@ def forecast_remaining_sales(loader):
|
|||
|
||||
results = []
|
||||
for ha_name, input_data in loader.data.items():
|
||||
|
||||
# Original warmfront figures - ECO4
|
||||
original_warmfront_estimates = december_figures[december_figures["HA Name"] == ha_name]
|
||||
|
||||
original_warmfront_eco4 = original_warmfront_estimates["ECO4"].values[0]
|
||||
original_warmfront_remaining_eco4 = original_warmfront_estimates["ECO4 remaining"].values[0]
|
||||
original_warmfront_sold_eco4 = (
|
||||
original_warmfront_estimates["No. of Tech surveys complete - Eco 4"].values[0] * eco4_rate
|
||||
)
|
||||
|
||||
# original_warmfront_eco4_revenue = (
|
||||
# original_warmfront_remaining_eco4 * eco4_rate +
|
||||
# (original_warmfront_eco4 - original_warmfront_remaining_eco4) * old_eco4_rate
|
||||
# )
|
||||
original_warmfront_eco4_revenue = original_warmfront_eco4 * eco4_rate
|
||||
original_warmfront_remaining_eco4_revenue = original_warmfront_remaining_eco4 * eco4_rate
|
||||
original_warmfront_sold_gbis = (
|
||||
original_warmfront_estimates["No. of Tech surveys complete - GBIS"].values[0] * gbis_rate
|
||||
)
|
||||
|
||||
# Original warmfront figures - GBIS
|
||||
|
||||
original_warmfront_gbis = original_warmfront_estimates["GBIS"].values[0]
|
||||
original_warmfront_remaining_gbis = original_warmfront_estimates["GBIS remaining"].values[0]
|
||||
|
||||
# original_warmfront_gbis_revenue = (
|
||||
# original_warmfront_remaining_gbis * gbis_rate +
|
||||
# (original_warmfront_gbis - original_warmfront_remaining_gbis) * old_gbis_rate
|
||||
# )
|
||||
original_warmfront_gbis_revenue = (
|
||||
original_warmfront_gbis * gbis_rate
|
||||
)
|
||||
|
|
@ -3123,7 +3160,7 @@ def forecast_remaining_sales(loader):
|
|||
|
||||
# We also need the ha ciga passed to install success rate
|
||||
ha_ciga_pass_to_sale = converted_ciga_jobs[converted_ciga_jobs["HA Name"] == ha_name]
|
||||
if not ha_ciga_pass_to_sale.empty:
|
||||
if not ha_ciga_pass_to_sale.empty and ha_ciga_pass_to_sale["# Ciga dependent at installation"].values[0] != 0:
|
||||
ha_ciga_pass_to_sale_rate = (
|
||||
ha_ciga_pass_to_sale["# Ciga dependent successfully installed"].values[0] /
|
||||
ha_ciga_pass_to_sale["# Ciga dependent at installation"].values[0]
|
||||
|
|
@ -3131,7 +3168,9 @@ def forecast_remaining_sales(loader):
|
|||
else:
|
||||
ha_ciga_pass_to_sale_rate = median_ciga_pass_to_install
|
||||
|
||||
ha_eco4_to_sale = eco4_ciga_independent_passrates[eco4_ciga_independent_passrates["Ha Name"] == ha_name]
|
||||
ha_eco4_to_sale = eco4_ciga_independent_to_install_clipped[
|
||||
eco4_ciga_independent_to_install_clipped["Ha Name"] == ha_name
|
||||
]
|
||||
if not ha_eco4_to_sale.empty:
|
||||
ha_eco4_to_sale_rate = (
|
||||
ha_eco4_to_sale['# ECO4 successfully installed'].values[0] /
|
||||
|
|
@ -3149,12 +3188,6 @@ def forecast_remaining_sales(loader):
|
|||
eco4_rate=eco4_rate
|
||||
)
|
||||
|
||||
# Calculate the delta compared to Warmfront's original estimate
|
||||
eco4_delta_vs_original_estimate = (
|
||||
eco4_post_ciga_total_results[
|
||||
"ECO4 - post CIGA - #"] - original_warmfront_eco4
|
||||
) / original_warmfront_eco4
|
||||
|
||||
eco4_post_ciga_remaining_results = calculate_eco4_post_ciga(
|
||||
eligiblity_counts=eligiblity_counts_remaining,
|
||||
input_data=input_data,
|
||||
|
|
@ -3164,10 +3197,18 @@ def forecast_remaining_sales(loader):
|
|||
eco4_rate=eco4_rate
|
||||
)
|
||||
|
||||
# Calculate the delta compared to Warmfront's original remaining
|
||||
if original_warmfront_remaining_eco4 == 0:
|
||||
eco4_delta_vs_original_estimate_remaining = eco4_post_ciga_remaining_results["ECO4 - post CIGA - #"]
|
||||
else:
|
||||
eco4_delta_vs_original_estimate_remaining = ((eco4_post_ciga_remaining_results["ECO4 - post CIGA - #"] -
|
||||
original_warmfront_remaining_eco4) /
|
||||
original_warmfront_remaining_eco4)
|
||||
|
||||
# GBIS Figures
|
||||
# Estimate the GBIS conversion rate
|
||||
ha_gbis_sale_conversion = gbis_ciga_independent_passrates[
|
||||
gbis_ciga_independent_passrates["Ha Name"] == ha_name
|
||||
ha_gbis_sale_conversion = gbis_to_install_clipped[
|
||||
gbis_to_install_clipped["Ha Name"] == ha_name
|
||||
]
|
||||
|
||||
if not ha_gbis_sale_conversion.empty:
|
||||
|
|
@ -3178,6 +3219,9 @@ def forecast_remaining_sales(loader):
|
|||
else:
|
||||
ha_gbis_sale_conversion = median_gbis_to_install
|
||||
|
||||
asset_list["ECO Eligibility"].value_counts()
|
||||
asset_list_remaining["ECO Eligibility"].value_counts()
|
||||
|
||||
gbis_total = eligiblity_counts[
|
||||
eligiblity_counts["ECO Eligibility"] == "gbis"
|
||||
]["count"].sum()
|
||||
|
|
@ -3185,18 +3229,59 @@ def forecast_remaining_sales(loader):
|
|||
gbis_total_revenue = int(gbis_total * gbis_rate)
|
||||
|
||||
gbis_remaining = eligiblity_counts_remaining[
|
||||
eligiblity_counts["ECO Eligibility"] == "gbis"
|
||||
eligiblity_counts_remaining["ECO Eligibility"] == "gbis"
|
||||
]["count"].sum()
|
||||
gbis_remaining = int(np.round(gbis_remaining * ha_gbis_sale_conversion))
|
||||
gbis_remaining_revenue = int(gbis_remaining * gbis_rate)
|
||||
|
||||
# GBIS delta
|
||||
if original_warmfront_gbis == 0:
|
||||
gbis_delta_vs_original_estimate = gbis_total
|
||||
if original_warmfront_remaining_gbis == 0:
|
||||
gbis_delta_vs_original_estimate_remaining = gbis_remaining
|
||||
else:
|
||||
gbis_delta_vs_original_estimate = (
|
||||
gbis_total - original_warmfront_gbis
|
||||
) / original_warmfront_gbis
|
||||
gbis_delta_vs_original_estimate_remaining = (
|
||||
(gbis_remaining - original_warmfront_remaining_gbis) / original_warmfront_remaining_gbis
|
||||
)
|
||||
|
||||
# Current sales figures
|
||||
# For any sales surveys that are complete, that could still cancel, we apply a conversion rate
|
||||
eco4_actually_sold = 0
|
||||
gbis_actually_sold = 0
|
||||
if not survey_list.empty:
|
||||
surveys_with_eligibility = survey_list.merge(
|
||||
asset_list[["asset_list_row_id", "ECO Eligibility"]],
|
||||
how="left", on="asset_list_row_id"
|
||||
)
|
||||
completed_eco4_sales = surveys_with_eligibility[
|
||||
surveys_with_eligibility["installation_status"] == "ECO4 - installed"
|
||||
]
|
||||
incomplete_eco4_sales = surveys_with_eligibility[
|
||||
(surveys_with_eligibility["installation_status"] == "ECO4 - in progress") &
|
||||
(~surveys_with_eligibility["ECO Eligibility"].isin(
|
||||
["eco4 - passed ciga"])
|
||||
)
|
||||
]
|
||||
incomplete_eco4_sales_ciga = surveys_with_eligibility[
|
||||
(surveys_with_eligibility["installation_status"] == "ECO4 - in progress") &
|
||||
(surveys_with_eligibility["ECO Eligibility"].isin(
|
||||
["eco4 - passed ciga"])
|
||||
)
|
||||
]
|
||||
|
||||
eco4_actually_sold = (completed_eco4_sales.shape[0] * eco4_rate) + (
|
||||
incomplete_eco4_sales.shape[0] * ha_eco4_to_sale_rate +
|
||||
incomplete_eco4_sales_ciga.shape[0] * ha_ciga_pass_to_sale_rate
|
||||
) * eco4_rate
|
||||
|
||||
completed_gbis_sales = surveys_with_eligibility[
|
||||
surveys_with_eligibility["installation_status"] == "GBIS - installed"
|
||||
]
|
||||
incomplete_gbis_sales = surveys_with_eligibility[
|
||||
(surveys_with_eligibility["installation_status"] == "GBIS - in progress")
|
||||
]
|
||||
|
||||
gbis_actually_sold = completed_gbis_sales.shape[0] * gbis_rate + (
|
||||
incomplete_gbis_sales.shape[0] * ha_gbis_sale_conversion * gbis_rate
|
||||
)
|
||||
|
||||
to_append = {
|
||||
("", "", "", "HA Name"): ha_name,
|
||||
|
|
@ -3204,29 +3289,33 @@ def forecast_remaining_sales(loader):
|
|||
("", "Original Warmfront estimate", "Total - #", "ECO4 - November"): original_warmfront_eco4,
|
||||
("ECO4 original", "", "Remaining - #", ""): original_warmfront_remaining_eco4,
|
||||
("ECO4 original", "", "Total - £", ""): original_warmfront_eco4_revenue,
|
||||
("ECO4 original", "", "Sold - £", ""): original_warmfront_sold_eco4,
|
||||
("ECO4 original", "", "Remaining - £", ""): original_warmfront_remaining_eco4_revenue,
|
||||
# GBIS - original warmfront figures
|
||||
("", "Original Warmfront estimate", "Total - #", "GBIS - November"): original_warmfront_gbis,
|
||||
("GBIS original", "", "Remaining - #", ""): original_warmfront_gbis,
|
||||
("GBIS original", "", "Total - £", ""): original_warmfront_gbis_revenue,
|
||||
("GBIS original", "", "Sold - £", ""): original_warmfront_sold_gbis,
|
||||
("GBIS original", "", "Remaining - £", ""): original_warmfront_remaining_gbis_revenue,
|
||||
# ECO4 - asset list, pre-ciga
|
||||
("", "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", "", "Sold - £", ""): eco4_actually_sold,
|
||||
("ECO4 pre-ciga", "", "Remaining - £", ""): eco4_pre_ciga_remaining_revenue,
|
||||
# ECO4 - asset list, post ciga, total
|
||||
("ECO4 post-ciga", "", "Estimated total eligible - #", "ECO4 total (post-ciga)"):
|
||||
("ECO4 post-ciga", "", "Estimated total eligible - #", "ECO4 total"):
|
||||
eco4_post_ciga_total_results[
|
||||
"ECO4 - post CIGA - #"],
|
||||
("ECO4 post-ciga", "", "Estimated total eligible - £", ""): eco4_post_ciga_total_results[
|
||||
"ECO4 - post CIGA - £"],
|
||||
("ECO4 post-ciga", "", "Delta vs original estimate - %", ""): eco4_delta_vs_original_estimate,
|
||||
# ECO4 - asset list, post ciga, remaining
|
||||
("ECO4 post-ciga", "", "Estimated remaining eligible - #", ""): eco4_post_ciga_remaining_results[
|
||||
"ECO4 - post CIGA - #"],
|
||||
("ECO4 post-ciga", "", "Estimated remaining eligible - £", ""): eco4_post_ciga_remaining_results[
|
||||
"ECO4 - post CIGA - £"],
|
||||
("ECO4 post-ciga", "", "Delta vs original estimate, remaining - %",
|
||||
""): eco4_delta_vs_original_estimate_remaining,
|
||||
("ECO4 post-ciga", "", "Of which - confirmed (post CIGA or no CIGA required) - #", ""):
|
||||
eco4_post_ciga_remaining_results["Of which confirmed - #"],
|
||||
("ECO4 post-ciga", "", "Of which - confirmed (post CIGA or no CIGA required) - £", ""):
|
||||
|
|
@ -3257,13 +3346,15 @@ def forecast_remaining_sales(loader):
|
|||
# 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,
|
||||
("GBIS Postcode list", "", "Delta vs original estimate - %", ""): gbis_delta_vs_original_estimate,
|
||||
("GBIS Postcode list", "Warmfront post code list", "Sold - £", "GBIS total"): gbis_actually_sold,
|
||||
("GBIS Postcode list", "Warmfront post code list", "Remaining - #", "GBIS total"): gbis_remaining,
|
||||
("GBIS Postcode list", "Warmfront post code list", "Remaining - £", "GBIS total"): gbis_remaining_revenue,
|
||||
("GBIS Postcode list", "", "Delta vs original estimate, remaining - %", ""):
|
||||
gbis_delta_vs_original_estimate_remaining,
|
||||
}
|
||||
|
||||
# Make sure nothing is forgotten due to duplicate multi-index keys
|
||||
if len(to_append) != 33:
|
||||
if len(to_append) != 37:
|
||||
raise ValueError("Something went wrong")
|
||||
|
||||
results.append(to_append)
|
||||
|
|
@ -3275,26 +3366,26 @@ def forecast_remaining_sales(loader):
|
|||
if col == ('', '', '', 'HA Name'):
|
||||
totals_row[col] = "Total"
|
||||
elif col in [
|
||||
("ECO4 post-ciga", "", "Delta vs original estimate - %", ""),
|
||||
("GBIS Postcode list", "", "Delta vs original estimate - %", "")
|
||||
("ECO4 post-ciga", "", "Delta vs original estimate, remaining - %", ""),
|
||||
("GBIS Postcode list", "", "Delta vs original estimate, remaining - %", "")
|
||||
]:
|
||||
totals_row[col] = None
|
||||
else:
|
||||
totals_row[col] = results[col].sum()
|
||||
|
||||
# For the delta columns, we calculate the delta on the totals
|
||||
totals_row[("ECO4 post-ciga", "", "Delta vs original estimate - %", "")] = (
|
||||
totals_row[("ECO4 post-ciga", "", "Delta vs original estimate, remaining - %", "")] = (
|
||||
(
|
||||
totals_row[("ECO4 post-ciga", "", "Estimated total eligible - #", "ECO4 total (post-ciga)")] -
|
||||
totals_row[("", "Original Warmfront estimate", "Total - #", "ECO4 - November")]
|
||||
) / totals_row[("", "Original Warmfront estimate", "Total - #", "ECO4 - November")]
|
||||
totals_row[("ECO4 post-ciga", "", "Estimated remaining eligible - #", "")] -
|
||||
totals_row[("ECO4 original", "", "Remaining - #", "")]
|
||||
) / totals_row[("ECO4 original", "", "Remaining - #", "")]
|
||||
)
|
||||
|
||||
totals_row[("GBIS Postcode list", "", "Delta vs original estimate - %", "")] = (
|
||||
totals_row[("GBIS Postcode list", "", "Delta vs original estimate, remaining - %", "")] = (
|
||||
(
|
||||
totals_row[("GBIS Postcode list", "Warmfront post code list", "Total - #", "GBIS total")] -
|
||||
totals_row[("", "Original Warmfront estimate", "Total - #", "GBIS - November")]
|
||||
) / totals_row[("", "Original Warmfront estimate", "Total - #", "GBIS - November")]
|
||||
totals_row[("GBIS Postcode list", "Warmfront post code list", "Remaining - #", "GBIS total")] -
|
||||
totals_row[("GBIS original", "", "Remaining - #", "")]
|
||||
) / totals_row[("GBIS original", "", "Remaining - #", "")]
|
||||
)
|
||||
|
||||
blank_row = pd.DataFrame([{col: "" for col in results.columns}])
|
||||
|
|
@ -3342,6 +3433,15 @@ def forecast_remaining_sales(loader):
|
|||
)
|
||||
headline_total_delta = round(headline_total_delta, 1)
|
||||
|
||||
headline_eco4_sold_since_november = (
|
||||
totals_row[('ECO4 pre-ciga', '', 'Sold - £', '')] - totals_row[('ECO4 original', '', 'Sold - £', '')]
|
||||
)
|
||||
|
||||
headline_gbis_sold_since_november = (
|
||||
totals_row[("GBIS Postcode list", "Warmfront post code list", "Sold - £", "GBIS total")] -
|
||||
totals_row[('GBIS original', '', 'Sold - £', '')]
|
||||
)
|
||||
|
||||
headlines = [
|
||||
{
|
||||
("", "", "", "HA Name"): "Headlines",
|
||||
|
|
@ -3358,16 +3458,22 @@ def forecast_remaining_sales(loader):
|
|||
"ECO4 - November"): headline_eco4_original_remaining_revenue
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "ECO4 Remaining - postcode list - #",
|
||||
("", "", "", "HA Name"): "ECO4 Sold since November - £",
|
||||
(
|
||||
"", "Original Warmfront estimate", "Total - #",
|
||||
"ECO4 - November"): headline_eco4_sold_since_november
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "ECO4 Remaining - postcode list (post CIGA) - #",
|
||||
("", "Original Warmfront estimate", "Total - #", "ECO4 - November"): headline_eco4_postcode_list_remaining
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "ECO4 Remaining - postcode list - £",
|
||||
("", "", "", "HA Name"): "ECO4 Remaining - postcode list (post CIGA) - £",
|
||||
("", "Original Warmfront estimate", "Total - #",
|
||||
"ECO4 - November"): headline_eco4_postcode_list_remaining_revenue
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "ECO4 delta %",
|
||||
("", "", "", "HA Name"): "ECO4 £ remaining delta - %",
|
||||
("", "Original Warmfront estimate", "Total - #", "ECO4 - November"): str(headline_eco4_delta) + "%"
|
||||
},
|
||||
{
|
||||
|
|
@ -3380,6 +3486,12 @@ def forecast_remaining_sales(loader):
|
|||
"", "Original Warmfront estimate", "Total - #",
|
||||
"ECO4 - November"): headline_gbis_original_remaining_revenue
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "GBIS Sold since November - £",
|
||||
(
|
||||
"", "Original Warmfront estimate", "Total - #",
|
||||
"ECO4 - November"): headline_gbis_sold_since_november
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "GBIS Remaining - post code list - #",
|
||||
("", "Original Warmfront estimate", "Total - #", "ECO4 - November"): headline_gbis_postcode_list_remaining
|
||||
|
|
@ -3400,7 +3512,7 @@ def forecast_remaining_sales(loader):
|
|||
"ECO4 - November"): headline_original_total_revenue_remaining
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "Total Remaining - post code list - £",
|
||||
("", "", "", "HA Name"): "Total Remaining - post code list (post CIGA) - £",
|
||||
("", "Original Warmfront estimate", "Total - #",
|
||||
"ECO4 - November"): headline_postcode_list_total_revenue_remaining
|
||||
},
|
||||
|
|
@ -3440,14 +3552,16 @@ def forecast_remaining_sales(loader):
|
|||
("", "Original Warmfront estimate", "Total - #", "ECO4 - November"): str(
|
||||
round(median_eco4_to_install * 100, 1)) + "%",
|
||||
("ECO4 original", "", "Remaining - #",
|
||||
""): " - Sales conversion rate for a ECO4 property that didn't need a CIGA check. Job must not cancel"
|
||||
""): " - Sales conversion rate for a ECO4 property that didn't need a CIGA check. Surveys that resulted "
|
||||
"in cancelled install are excluded."
|
||||
},
|
||||
{
|
||||
("", "", "", "HA Name"): "Median ECO4 (subect to CIGA) sales conversion rate",
|
||||
("", "Original Warmfront estimate", "Total - #", "ECO4 - November"): str(
|
||||
round(median_ciga_pass_to_install * 100, 1)) + "%",
|
||||
("ECO4 original", "", "Remaining - #",
|
||||
""): " - Sales conversion rate for a ECO4 property that passed a CIGA check. Job must not cancel"
|
||||
""): " - Sales conversion rate for a ECO4 property that passed a CIGA check. Surveys that resulted in "
|
||||
"cancelled installs are excluded."
|
||||
}
|
||||
]
|
||||
|
||||
|
|
@ -3462,23 +3576,7 @@ def forecast_remaining_sales(loader):
|
|||
pd.DataFrame(assumptions)
|
||||
]
|
||||
)
|
||||
|
||||
# header_rows = [
|
||||
# [name[0] for name in results.columns.values],
|
||||
# [name[1] for name in results.columns.values],
|
||||
# [name[2] for name in results.columns.values],
|
||||
# [name[3] for name in results.columns.values]
|
||||
# ]
|
||||
|
||||
# Step 2: Write the transformed header and DataFrame data to CSV.
|
||||
# Open the file in write mode.
|
||||
import csv
|
||||
with open("HA Remaining Analysis.csv", "w", newline="") as file:
|
||||
# writer = csv.writer(file)
|
||||
|
||||
# Write the header rows.
|
||||
# writer.writerows(header_rows)
|
||||
|
||||
# Write the DataFrame data without the index (adjust if you want the index).
|
||||
results.to_csv(file, header=True, index=False)
|
||||
|
||||
|
|
@ -3504,8 +3602,12 @@ def app():
|
|||
# Grab the December HA figures filepath
|
||||
december_figures_filepath = "local_data/ha_data/HA_December_figures.csv"
|
||||
|
||||
# priority_has = [
|
||||
# "HA1", "HA6", "HA7", "HA14", "HA15", "HA16", "HA24", "HA25", "HA28", "HA32", "HA38", "HA39", "HA107",
|
||||
# ]
|
||||
# TODO: Remove ECO3 sales from HA25
|
||||
priority_has = [
|
||||
"HA1", "HA6", "HA7", "HA14", "HA15", "HA16", "HA24", "HA25", "HA28", "HA32", "HA38", "HA39", "HA107",
|
||||
"HA1", "HA6", "HA7", "HA14", "HA15", "HA16", "HA24", "HA28", "HA32", "HA39", "HA107",
|
||||
]
|
||||
# Next HAs to do: 15[DONE], 32 [DONE], 33 [Input format is 4 parts and no eco4 jobs identified - come back on this],
|
||||
# Then: 28 [DONE],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue