import enum from datetime import datetime from backend.app.db.base import Base from sqlalchemy import Column, Integer, BigInteger, Text, Float, DateTime, Boolean, Date, ForeignKey from sqlalchemy.dialects.postgresql import ENUM as PgEnum class EnergyAssessment(Base): __tablename__ = 'energy_assessments' id = Column(BigInteger, primary_key=True, autoincrement=True) uprn = Column(BigInteger, nullable=False) uprn_source = Column(Text, nullable=False) property_type = Column(Text, nullable=False) building_reference_number = Column(Text) current_energy_efficiency = Column(Text, nullable=False) current_energy_rating = Column(Text, nullable=False) address1 = Column(Text, nullable=False) address2 = Column(Text, nullable=False) address3 = Column(Text) posttown = Column(Text, nullable=False) postcode = Column(Text, nullable=False) address = Column(Text, nullable=False) county = Column(Text) constituency = Column(Text) constituency_label = Column(Text) low_energy_fixed_light_count = Column(Text, nullable=False) construction_age_band = Column(Text, nullable=False) mainheat_energy_eff = Column(Text, nullable=False) windows_env_eff = Column(Text, nullable=False) lighting_energy_eff = Column(Text, nullable=False) environment_impact_potential = Column(Text, nullable=False) mainheatcont_description = Column(Text, nullable=False) sheating_energy_eff = Column(Text, nullable=False) local_authority = Column(Text, nullable=False) local_authority_label = Column(Text, nullable=False) fixed_lighting_outlets_count = Column(Text, nullable=False) energy_tariff = Column(Text, nullable=False) mechanical_ventilation = Column(Text, nullable=False) solar_water_heating_flag = Column(Text, nullable=False) co2_emissions_potential = Column(Text, nullable=False) number_heated_rooms = Column(Text, nullable=False) floor_description = Column(Text, nullable=False) energy_consumption_potential = Column(Text, nullable=False) built_form = Column(Text, nullable=False) number_open_fireplaces = Column(Text, nullable=False) windows_description = Column(Text, nullable=False) glazed_area = Column(Text, nullable=False) inspection_date = Column(DateTime(timezone=True), nullable=False) mains_gas_flag = Column(Text, nullable=False) co2_emiss_curr_per_floor_area = Column(Text, nullable=False) heat_loss_corridor = Column(Text, nullable=False) unheated_corridor_length = Column(Text) flat_storey_count = Column(Text) roof_energy_eff = Column(Text, nullable=False) total_floor_area = Column(Text, nullable=False) environment_impact_current = Column(Text, nullable=False) roof_description = Column(Text, nullable=False) floor_energy_eff = Column(Text, nullable=False) number_habitable_rooms = Column(Text, nullable=False) hot_water_env_eff = Column(Text, nullable=False) mainheatc_energy_eff = Column(Text, nullable=False) main_fuel = Column(Text, nullable=False) lighting_env_eff = Column(Text, nullable=False) windows_energy_eff = Column(Text, nullable=False) floor_env_eff = Column(Text, nullable=False) sheating_env_eff = Column(Text, nullable=False) lighting_description = Column(Text, nullable=False) roof_env_eff = Column(Text, nullable=False) walls_energy_eff = Column(Text, nullable=False) photo_supply = Column(Text, nullable=False) lighting_cost_potential = Column(Text, nullable=False) mainheat_env_eff = Column(Text, nullable=False) multi_glaze_proportion = Column(Text, nullable=False) main_heating_controls = Column(Text, nullable=False) flat_top_storey = Column(Text) secondheat_description = Column(Text, nullable=False) walls_env_eff = Column(Text, nullable=False) transaction_type = Column(Text, nullable=False) extension_count = Column(Text, nullable=False) mainheatc_env_eff = Column(Text, nullable=False) lmk_key = Column(Text) wind_turbine_count = Column(Text, nullable=False) tenure = Column(Text, nullable=False) floor_level = Column(Text, nullable=False) potential_energy_efficiency = Column(Text, nullable=False) potential_energy_rating = Column(Text, nullable=False) hot_water_energy_eff = Column(Text, nullable=False) low_energy_lighting = Column(Text, nullable=False) walls_description = Column(Text, nullable=False) hotwater_description = Column(Text, nullable=False) co2_emissions_current = Column(Text, nullable=False) heating_cost_current = Column(Text, nullable=False) heating_cost_potential = Column(Text, nullable=False) hot_water_cost_current = Column(Text, nullable=False) hot_water_cost_potential = Column(Text, nullable=False) lighting_cost_current = Column(Text, nullable=False) energy_consumption_current = Column(Text, nullable=False) lodgement_date = Column(Date, nullable=False) lodgement_datetime = Column(DateTime(timezone=False), nullable=False) mainheat_description = Column(Text, nullable=False) floor_height = Column(Float, nullable=False) glazed_type = Column(Text, nullable=False) file_location = Column(Text, nullable=False) surveyor_name = Column(Text, nullable=False) surveyor_company = Column(Text, nullable=False) space_heating_kwh = Column(Text, nullable=False) water_heating_kwh = Column(Text, nullable=False) number_of_doors = Column(Integer, nullable=False) number_of_insulated_doors = Column(Integer, nullable=False) number_of_floors = Column(Integer, nullable=False) insulation_wall_area = Column(Float, nullable=False) heat_loss_perimeter = Column(Float, nullable=False) party_wall_length = Column(Float, nullable=False) perimeter = Column(Float, nullable=False) rooms_with_bath_and_or_shower = Column(Integer) rooms_with_mixer_shower_no_bath = Column(Integer) room_with_bath_and_mixer_shower = Column(Integer) percent_draftproofed = Column(Integer) has_hot_water_cylinder = Column(Boolean) cylinder_insulation_type = Column(Text) cylinder_insulation_thickness = Column(Integer) cylinder_thermostat = Column(Boolean) main_dwelling_ground_floor_area = Column(Float) number_of_windows = Column(Integer) windows_area = Column(Float) EPC_KEYS = [ 'low_energy_fixed_light_count', 'address', 'uprn_source', 'floor_height', 'heating_cost_potential', 'unheated_corridor_length', 'hot_water_cost_potential', 'construction_age_band', 'potential_energy_rating', 'mainheat_energy_eff', 'windows_env_eff', 'lighting_energy_eff', 'environment_impact_potential', 'glazed_type', 'heating_cost_current', 'address3', 'mainheatcont_description', 'sheating_energy_eff', 'property_type', 'local_authority_label', 'fixed_lighting_outlets_count', 'energy_tariff', 'mechanical_ventilation', 'hot_water_cost_current', 'county', 'postcode', 'solar_water_heating_flag', 'constituency', 'co2_emissions_potential', 'number_heated_rooms', 'floor_description', 'energy_consumption_potential', 'local_authority', 'built_form', 'number_open_fireplaces', 'windows_description', 'glazed_area', 'inspection_date', 'mains_gas_flag', 'co2_emiss_curr_per_floor_area', 'address1', 'heat_loss_corridor', 'flat_storey_count', 'constituency_label', 'roof_energy_eff', 'total_floor_area', 'building_reference_number', 'environment_impact_current', 'co2_emissions_current', 'roof_description', 'floor_energy_eff', 'number_habitable_rooms', 'address2', 'hot_water_env_eff', 'posttown', 'mainheatc_energy_eff', 'main_fuel', 'lighting_env_eff', 'windows_energy_eff', 'floor_env_eff', 'sheating_env_eff', 'lighting_description', 'roof_env_eff', 'walls_energy_eff', 'photo_supply', 'lighting_cost_potential', 'mainheat_env_eff', 'multi_glaze_proportion', 'main_heating_controls', 'lodgement_datetime', 'flat_top_storey', 'current_energy_rating', 'secondheat_description', 'walls_env_eff', 'transaction_type', 'uprn', 'current_energy_efficiency', 'energy_consumption_current', 'mainheat_description', 'lighting_cost_current', 'lodgement_date', 'extension_count', 'mainheatc_env_eff', 'lmk_key', 'wind_turbine_count', 'tenure', 'floor_level', 'potential_energy_efficiency', 'hot_water_energy_eff', 'low_energy_lighting', 'walls_description', 'hotwater_description' ] def to_dict(self): """ Convert the SQLAlchemy object to a dictionary. """ epc = {key.replace("_", "-"): getattr(self, key) for key in self.EPC_KEYS} # Get everything else condition = { column.name: getattr(self, column.name) for column in self.__table__.columns if column.name not in self.EPC_KEYS } return {"epc": epc, "condition": condition} @staticmethod def empty_response(): return {"epc": {}, "condition": {}} class EnergyAssessmentScenarios(Base): __tablename__ = 'energy_assessment_scenarios' id = Column(BigInteger, primary_key=True, autoincrement=True) scenario_name = Column(Text, nullable=False) energy_assessment_id = Column(BigInteger, ForeignKey('energy_assessments.id'), nullable=False) class DocumentTypeEnum(enum.Enum): EPR = "EPR" ConditionReport = "Condition Report" EvidenceReport = "Evidence Report" SummaryInformation = "Summary Information" FloorPlan = "Floor Plan" ScenarioDraftEPC = "Scenario Draft EPC" ScenarioSiteNotes = "Scenario Site Notes" class EnergyAssessmentDocuments(Base): __tablename__ = 'energy_assessment_documents' id = Column(BigInteger, primary_key=True, autoincrement=True) uprn = Column(BigInteger, nullable=False) energy_assessment_id = Column(BigInteger, ForeignKey('energy_assessments.id'), nullable=False) document_type = Column(PgEnum(DocumentTypeEnum, name="document_type"), nullable=False) document_location = Column(Text, nullable=False) uploaded_at = Column(DateTime(timezone=True), nullable=False, default=datetime.utcnow) scenario_id = Column(BigInteger, ForeignKey('energy_assessment_scenarios.id'), nullable=True) @staticmethod def empty_response(): return { "id": None, "uprn": None, "document_type": None, "document_location": None, "uploaded_at": None, "scenario_id": None }