mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
161 lines
6.6 KiB
Python
161 lines
6.6 KiB
Python
from sqlalchemy import insert, delete
|
|
from sqlalchemy.orm import Session
|
|
from backend.app.db.models.recommendations import Plan, Recommendation, RecommendationMaterials, PlanRecommendations
|
|
from backend.app.db.models.portfolio import PropertyModel, PropertyTargetsModel, PropertyDetailsMeter, \
|
|
PropertyDetailsEpcModel
|
|
|
|
|
|
def create_plan(session: Session, plan):
|
|
"""
|
|
This function will create a record for the plan in the database if it does not exist.
|
|
:param session: The database session
|
|
:param plan: dictionary of data representing a plan to be created
|
|
"""
|
|
|
|
new_plan = Plan(**plan)
|
|
session.add(new_plan)
|
|
session.flush()
|
|
|
|
return new_plan.id
|
|
|
|
|
|
def create_recommendation(session: Session, recommendation):
|
|
"""
|
|
This function will create a record for the recommendation in the database if it does not exist.
|
|
:param session: The database session
|
|
:param recommendation: dictionary of data representing a recommendation to be created
|
|
"""
|
|
|
|
new_recommendation = Recommendation(**recommendation)
|
|
session.add(new_recommendation)
|
|
session.flush()
|
|
|
|
return new_recommendation.id
|
|
|
|
|
|
def create_recommendation_material(session: Session, recommendation_id, material_id, depth):
|
|
"""
|
|
This function will create a record for the recommendation_material in the database if it does not exist.
|
|
:param session: The databse session
|
|
:param recommendation_id: ID of the recommendation
|
|
:param material_id: ID of the material
|
|
:param depth: depth of the material, may be null if a material where depth is not applicable
|
|
"""
|
|
|
|
new_recommendation_material = RecommendationMaterials(
|
|
recommendation_id=recommendation_id,
|
|
material_id=material_id,
|
|
depth=depth
|
|
)
|
|
session.add(new_recommendation_material)
|
|
session.flush()
|
|
|
|
return new_recommendation_material.id
|
|
|
|
|
|
def create_plan_recommendations(session: Session, plan_id, recommendation_ids):
|
|
"""
|
|
This function will create records for the plan_recommendation in the database.
|
|
:param session: The database session
|
|
:param plan_id: ID of the plan
|
|
:param recommendation_ids: list of recommendation IDs
|
|
"""
|
|
|
|
# Prepare a list of dictionaries for bulk insert
|
|
data = [{"plan_id": plan_id, "recommendation_id": rid} for rid in recommendation_ids]
|
|
|
|
# Bulk insert using SQLAlchemy's core API
|
|
session.execute(insert(PlanRecommendations).values(data))
|
|
|
|
|
|
def upload_recommendations(session: Session, recommendations_to_upload, property_id):
|
|
# Prepare data for bulk insert for Recommendation
|
|
recommendations_data = [
|
|
{
|
|
"property_id": property_id,
|
|
"type": rec["type"],
|
|
"description": rec["description"],
|
|
"estimated_cost": rec["total"],
|
|
"default": rec["default"],
|
|
"starting_u_value": rec.get("starting_u_value"),
|
|
"new_u_value": rec.get("new_u_value"),
|
|
"sap_points": rec["sap_points"],
|
|
"heat_demand": rec["heat_demand"],
|
|
"adjusted_heat_demand": rec["adjusted_heat_demand"],
|
|
"co2_equivalent_savings": rec["co2_equivalent_savings"],
|
|
"total_work_hours": rec["labour_hours"],
|
|
"energy_cost_savings": rec["energy_cost_savings"],
|
|
"labour_days": rec["labour_days"]
|
|
}
|
|
for rec in recommendations_to_upload
|
|
]
|
|
|
|
session.bulk_insert_mappings(Recommendation, recommendations_data)
|
|
|
|
# To get the IDs of the newly inserted recommendations, we need to flush the session
|
|
session.flush()
|
|
|
|
# Map the uploaded_recommendation_ids with the original data for reference
|
|
uploaded_recommendation_ids = [rec.id for rec in session.query(Recommendation).filter(
|
|
Recommendation.property_id == property_id,
|
|
Recommendation.description.in_([rec["description"] for rec in recommendations_to_upload])
|
|
)]
|
|
|
|
# Prepare data for bulk insert for RecommendationMaterials
|
|
# We can have multiple materials per recommendation. The aggregation of the materials will total the
|
|
# recommendation figures
|
|
recommendation_materials_data = [
|
|
{
|
|
"recommendation_id": recommendation_id,
|
|
"material_id": part["id"],
|
|
"depth": int(part["depth"]) if part["depth"] else None,
|
|
"quantity": part["quantity"],
|
|
"quantity_unit": part["quantity_unit"],
|
|
"estimated_cost": part["total"],
|
|
}
|
|
for rec, recommendation_id in zip(recommendations_to_upload, uploaded_recommendation_ids)
|
|
for part in rec["parts"]
|
|
]
|
|
|
|
session.bulk_insert_mappings(RecommendationMaterials, recommendation_materials_data)
|
|
|
|
# flush the changes to get the newly created IDs
|
|
session.flush()
|
|
|
|
return uploaded_recommendation_ids
|
|
|
|
|
|
def clear_portfolio(session: Session, portfolio_id: int):
|
|
# Fetch all property IDs associated with the given portfolio
|
|
property_ids = session.query(PropertyModel.id).filter(PropertyModel.portfolio_id == portfolio_id).all()
|
|
property_ids = [p.id for p in property_ids]
|
|
|
|
# Fetch all recommendation IDs associated with the properties
|
|
recommendation_ids = session.query(Recommendation.id).filter(Recommendation.property_id.in_(property_ids)).all()
|
|
recommendation_ids = [r.id for r in recommendation_ids]
|
|
|
|
# Delete all entries from RecommendationMaterials for these recommendations
|
|
session.execute(
|
|
delete(RecommendationMaterials).where(RecommendationMaterials.recommendation_id.in_(recommendation_ids))
|
|
)
|
|
|
|
# Delete all entries from PlanRecommendations that reference plans in the portfolio
|
|
session.execute(delete(PlanRecommendations).where(PlanRecommendations.plan_id.in_(
|
|
session.query(Plan.id).filter(Plan.portfolio_id == portfolio_id).subquery().as_scalar()
|
|
)))
|
|
|
|
# Delete all Plans associated with the portfolio
|
|
session.execute(delete(Plan).where(Plan.portfolio_id == portfolio_id))
|
|
|
|
# Delete all Recommendations associated with the properties
|
|
session.execute(delete(Recommendation).where(Recommendation.property_id.in_(property_ids)))
|
|
|
|
# Now, delete the PropertyModels and related details
|
|
# Delete PropertyTargetsModel, PropertyDetailsMeter, PropertyDetailsEpcModel, and PropertyModel
|
|
session.execute(delete(PropertyTargetsModel).where(PropertyTargetsModel.portfolio_id == portfolio_id))
|
|
# session.execute(delete(PropertyDetailsMeter).where(PropertyDetailsMeter.uprn.in_(property_ids)))
|
|
session.execute(delete(PropertyDetailsEpcModel).where(PropertyDetailsEpcModel.portfolio_id == portfolio_id))
|
|
session.execute(delete(PropertyModel).where(PropertyModel.portfolio_id == portfolio_id))
|
|
|
|
# Commit the changes
|
|
session.commit()
|