mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
working on funding
This commit is contained in:
parent
41f3998c1d
commit
a6daeab889
4 changed files with 129 additions and 72 deletions
2
.idea/Model.iml
generated
2
.idea/Model.iml
generated
|
|
@ -7,7 +7,7 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/recommendations" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Stonewater-wave-3" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Fastapi-backend" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyNamespacePackagesService">
|
||||
|
|
|
|||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -3,7 +3,7 @@
|
|||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.10 (backend)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Stonewater-wave-3" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Fastapi-backend" project-jdk-type="Python SDK" />
|
||||
<component name="PyCharmProfessionalAdvertiser">
|
||||
<option name="shown" value="true" />
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -98,11 +98,14 @@ class Funding:
|
|||
self,
|
||||
scheme: str,
|
||||
eligible: bool,
|
||||
types: List[str],
|
||||
measure_types: List[str],
|
||||
project_score: float,
|
||||
estimated_funding: float,
|
||||
notify_tenant_benefits_requirements: bool,
|
||||
notify_council_tax_band_requirements: bool,
|
||||
notify_tenant_low_income_requirements: bool,
|
||||
innovation_required: bool,
|
||||
):
|
||||
""""
|
||||
"""
|
||||
|
|
@ -113,11 +116,14 @@ class Funding:
|
|||
return {
|
||||
"scheme": scheme,
|
||||
"eligible": eligible,
|
||||
"type": types,
|
||||
"measure_types": measure_types,
|
||||
"project_score": project_score,
|
||||
"estimated_funding": estimated_funding,
|
||||
"requires_benefits": notify_tenant_benefits_requirements,
|
||||
"requires_council_tax_band": notify_council_tax_band_requirements,
|
||||
"requires_low_income": notify_tenant_low_income_requirements
|
||||
"requires_low_income": notify_tenant_low_income_requirements,
|
||||
"innovation_required": innovation_required,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -140,7 +146,7 @@ class Funding:
|
|||
"""
|
||||
pass
|
||||
|
||||
def find_best_gbis_measure(self, measures):
|
||||
def find_gbis_measures(self, measures):
|
||||
"""
|
||||
The best measure is one that:
|
||||
1) Creates some SAP movement, therefore enables eligiblity
|
||||
|
|
@ -247,21 +253,26 @@ class Funding:
|
|||
) and
|
||||
(self.council_tax_band in [None, "A", "B", "C", "D"])
|
||||
):
|
||||
# We find the best measure for GBIS
|
||||
recommended_measure = self.find_best_gbis_measure(
|
||||
# This function pulls out the various measures that can provide funding under GBIS
|
||||
recommended_measures = self.find_gbis_measures(
|
||||
measures=[m for m in valid_measures if m not in ["cavity_wall_insulation", "loft_insulation"]]
|
||||
)
|
||||
# If the council tax band is missing, we nofify the customer that this is a requirement that
|
||||
# should be checked
|
||||
return self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
measure_types=[recommended_measure["measure_type"]],
|
||||
estimated_funding=recommended_measure["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=self.council_tax_band is None,
|
||||
notify_tenant_low_income_requirements=False,
|
||||
)
|
||||
return [
|
||||
self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
types=[m["type"]], # This is single measure so we only have one type
|
||||
measure_types=[m["measure_type"]],
|
||||
project_score=m["project_score"],
|
||||
estimated_funding=m["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=self.council_tax_band is None,
|
||||
notify_tenant_low_income_requirements=False,
|
||||
innovation_required=False
|
||||
) for m in recommended_measures
|
||||
]
|
||||
|
||||
# Low income/flex
|
||||
if (
|
||||
|
|
@ -271,28 +282,83 @@ class Funding:
|
|||
# Find the best measure, and can also include CWI/LI but requires the tenant to be
|
||||
# low inome or on benefits
|
||||
# We find the best measure for GBIS
|
||||
recommended_measure = self.find_best_gbis_measure(measures=valid_measures)
|
||||
return self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
measure_types=[recommended_measure["measure_type"]],
|
||||
estimated_funding=recommended_measure["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=True,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=True,
|
||||
)
|
||||
recommended_measures = self.find_gbis_measures(measures=valid_measures)
|
||||
return [
|
||||
self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
types=[m["type"]], # This is single measure so we only have one type
|
||||
measure_types=[m["measure_type"]],
|
||||
project_score=m["project_score"],
|
||||
estimated_funding=m["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=True,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=True,
|
||||
innovation_required=False
|
||||
) for m in recommended_measures
|
||||
]
|
||||
|
||||
# Otherwise, no funding availability
|
||||
return self.output(
|
||||
scheme="gbis",
|
||||
eligible=False,
|
||||
measure_types=[],
|
||||
estimated_funding=0,
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=False
|
||||
return []
|
||||
|
||||
def gbis_social(self):
|
||||
"""
|
||||
Because this is social housing, we have two typical means for eligibility
|
||||
1) EPC D, where an innovation measure is required
|
||||
2) EPC G-E, where an innovation measure isn't required
|
||||
:return:
|
||||
"""
|
||||
valid_measures = [
|
||||
"internal_wall_insulation",
|
||||
"external_wall_insulation",
|
||||
"flat_roof_insulation",
|
||||
"suspended_floor_insulation",
|
||||
"room_roof_insulation",
|
||||
# Not available for every eligiblity type
|
||||
"cavity_wall_insulation",
|
||||
"loft_insulation",
|
||||
"heating_control"
|
||||
]
|
||||
|
||||
recommended_measures = self.find_gbis_measures(
|
||||
measures=valid_measures
|
||||
)
|
||||
|
||||
# All measures are available
|
||||
if self.starting_sap == "D":
|
||||
return [
|
||||
self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
types=[m["type"]], # This is single measure so we only have one type
|
||||
measure_types=[m["measure_type"]],
|
||||
project_score=m["project_score"],
|
||||
estimated_funding=m["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=False,
|
||||
innovation_required=True
|
||||
) for m in recommended_measures
|
||||
]
|
||||
|
||||
if self.starting_sap in ["G", "F", "E"]:
|
||||
return [
|
||||
self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
types=[m["type"]], # This is single measure so we only have one type
|
||||
measure_types=[m["measure_type"]],
|
||||
project_score=m["project_score"],
|
||||
estimated_funding=m["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=False,
|
||||
innovation_required=False
|
||||
) for m in recommended_measures
|
||||
]
|
||||
|
||||
return []
|
||||
|
||||
def gbis(self):
|
||||
"""
|
||||
Check if a property is eligible for GBIS
|
||||
|
|
@ -303,24 +369,33 @@ class Funding:
|
|||
self.gbis_eligibiltiy = self.gbis_prs()
|
||||
return
|
||||
|
||||
if self.tenure == "Social":
|
||||
self.gbis_eligibiltiy = self.gbis_social()
|
||||
|
||||
raise NotImplementedError("Implement social/oo")
|
||||
|
||||
def whlg(self):
|
||||
if self.tenure == "Social":
|
||||
# We can't do anything for social housing
|
||||
self.whlg_eligibility = self.output(
|
||||
scheme="whlg",
|
||||
eligible=False,
|
||||
measure_types=[],
|
||||
estimated_funding=0,
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=False
|
||||
)
|
||||
self.whlg_eligibility = []
|
||||
return
|
||||
|
||||
if not self.whlg_eligible_postcodes.empty:
|
||||
print("Eligible implement me!")
|
||||
raise Exception("Implement me")
|
||||
# self.whlg_eligibility = [
|
||||
# self.output(
|
||||
# scheme,
|
||||
# eligible,
|
||||
# types,
|
||||
# measure_types,
|
||||
# project_score: float,
|
||||
# estimated_funding: float,
|
||||
# notify_tenant_benefits_requirements: bool,
|
||||
# notify_council_tax_band_requirements: bool,
|
||||
# notify_tenant_low_income_requirements: bool,
|
||||
# innovation_required: bool,
|
||||
# )
|
||||
# ]
|
||||
|
||||
def eco4(self):
|
||||
if self.tenure == "Private":
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from dotenv import load_dotenv
|
|||
from utils.s3 import save_csv_to_s3
|
||||
from etl.find_my_epc.AssetListEpcData import AssetListEpcData
|
||||
|
||||
PORTFOLIO_ID = 134
|
||||
PORTFOLIO_ID = 138
|
||||
USER_ID = 8
|
||||
|
||||
load_dotenv(dotenv_path="backend/.env")
|
||||
|
|
@ -19,25 +19,15 @@ def app():
|
|||
|
||||
asset_list = [
|
||||
{
|
||||
"address": "Flat 2, 42 Malden Road, London NW5 3HG",
|
||||
"postcode": "NW5 3HG",
|
||||
"uprn": 5117165,
|
||||
"address": "42 Rippolson Road",
|
||||
"postcode": "SE18 1NS",
|
||||
"uprn": 100020999275,
|
||||
},
|
||||
{
|
||||
"address": "15 Bournville Lane",
|
||||
"postcode": "B30 2JY",
|
||||
"uprn": 100070301128
|
||||
"address": "66 Riverdale Road",
|
||||
"postcode": "DA8 1PX",
|
||||
"uprn": 100020235516
|
||||
},
|
||||
{
|
||||
"address": "34 Bournville Lane",
|
||||
"postcode": "B30 2LN",
|
||||
"uprn": 100070301140
|
||||
},
|
||||
{
|
||||
"address": "36 Bournville Lane",
|
||||
"postcode": "B30 2LN",
|
||||
"uprn": 100070301142
|
||||
}
|
||||
]
|
||||
asset_list = pd.DataFrame(asset_list)
|
||||
|
||||
|
|
@ -67,20 +57,12 @@ def app():
|
|||
|
||||
valuation_data = [
|
||||
{
|
||||
"uprn": 5117165,
|
||||
"valuation": 467_000
|
||||
"valuation": 469_000,
|
||||
"uprn": 100020999275,
|
||||
},
|
||||
{
|
||||
"uprn": 100070301128,
|
||||
"valuation": 335_000
|
||||
},
|
||||
{
|
||||
"uprn": 100070301140,
|
||||
"valuation": 276_000
|
||||
},
|
||||
{
|
||||
"uprn": 100070301142,
|
||||
"valuation": 276_000
|
||||
"valuation": 382_000,
|
||||
"uprn": 100020235516
|
||||
},
|
||||
]
|
||||
# Store valuation data to s3
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue