diff --git a/backend/app/db/functions/recommendations_functions.py b/backend/app/db/functions/recommendations_functions.py new file mode 100644 index 00000000..11001a7f --- /dev/null +++ b/backend/app/db/functions/recommendations_functions.py @@ -0,0 +1,18 @@ +from sqlalchemy.orm import sessionmaker +from backend.app.db.connection import db_engine +from backend.app.db.models.recommendations import Plan + + +def create_plan(plan): + """ + This function will create a record for the plan in the database if it does not exist. + :param plan: dictionary of data representing a plan to be created + """ + + Session = sessionmaker(bind=db_engine) + with Session() as session: + new_plan = Plan(**plan) + session.add(new_plan) + session.commit() + + return new_plan.id diff --git a/backend/app/db/models/recommendations.py b/backend/app/db/models/recommendations.py new file mode 100644 index 00000000..435c07dd --- /dev/null +++ b/backend/app/db/models/recommendations.py @@ -0,0 +1,60 @@ +from sqlalchemy import Column, BigInteger, String, Float, Boolean, TIMESTAMP, ForeignKey +from sqlalchemy.orm import declarative_base, relationship +from sqlalchemy.sql import func +from backend.app.db.models.portfolio import Portfolio + +Base = declarative_base() + + +class Recommendation(Base): + __tablename__ = 'recommendation' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + property_id = Column(BigInteger, ForeignKey('property.id'), nullable=False) + created_at = Column(TIMESTAMP, nullable=False, server_default=func.now()) + type = Column(String, nullable=False) + description = Column(String, nullable=False) + estimated_cost = Column(Float) + default = Column(Boolean, nullable=False) + starting_u_value = Column(Float) + new_u_value = Column(Float) + sap_points = Column(Float) + heat_demand = Column(Float) + co2_equivalent_savings = Column(Float) + energy_savings = Column(Float) + energy_cost_savings = Column(Float) + property_valuation_increase = Column(Float) + rental_yield_increase = Column(Float) + total_work_hours = Column(Float) + + +class RecommendationMaterials(Base): + __tablename__ = 'recommendation_materials' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + recommendation_id = Column(BigInteger, ForeignKey('recommendation.id'), nullable=False) + material_id = Column(BigInteger, ForeignKey('material.id'), nullable=False) + created_at = Column(TIMESTAMP, nullable=False, server_default=func.now()) + + # recommendation = relationship('Recommendation') + # material = relationship('Material') + + +class Plan(Base): + __tablename__ = 'plan' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + portfolio_id = Column(BigInteger, ForeignKey(Portfolio.id), nullable=False) + created_at = Column(TIMESTAMP, nullable=False, server_default=func.now()) + is_default = Column(Boolean, nullable=False) + + +class PlanRecommendations(Base): + __tablename__ = 'plan_recommendations' + + id = Column(BigInteger, primary_key=True, autoincrement=True) + plan_id = Column(BigInteger, ForeignKey('plan.id'), nullable=False) + recommendation_id = Column(BigInteger, ForeignKey('recommendation.id'), nullable=False) + + plan = relationship('Plan') + recommendation = relationship('Recommendation') diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index 5fbc5f1a..e1ee5dea 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -19,6 +19,7 @@ from backend.app.db.functions.property_functions import ( create_property, create_property_targets, update_property_data, create_property_details_epc ) from backend.app.db.functions.materials_functions import get_materials +from backend.app.db.functions.recommendations_functions import create_plan # TODO: This is placeholder until data is stored in DB from backend.app.plan.uvalue_estimates_walls import uvalue_estimates_walls @@ -253,5 +254,15 @@ async def trigger_plan(body: PlanTriggerRequest): if not recommendations: continue # Create a plan + new_plan_id = create_plan( + { + "portfolio_id": body.portfolio_id, + "is_default": True + } + ) + + # upload recommendations + + # create the bridging between the plan and the recommendation return Response(status_code=200)