mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
172 lines
5.9 KiB
Python
172 lines
5.9 KiB
Python
###
|
|
# This script contains methods for interacting with the property table in the database
|
|
###
|
|
import datetime
|
|
import pytz
|
|
from sqlalchemy.orm import Session
|
|
from backend.app.db.models.portfolio import (
|
|
PropertyModel, PropertyCreationStatus, PortfolioStatus, PropertyTargetsModel, PropertyDetailsEpcModel,
|
|
PropertyDetailsSpatial
|
|
)
|
|
from sqlalchemy.orm.exc import NoResultFound
|
|
|
|
|
|
def create_property(session: Session, portfolio_id: int, address: str, postcode: str, uprn: str) -> (int, bool):
|
|
"""
|
|
This function will create a record for the property in the database if it does not exist.
|
|
If it does exist, it will just update the updated_at field.
|
|
:param session: The database session
|
|
:param portfolio_id: The ID of the portfolio the property belongs to
|
|
:param address: The address of the property
|
|
:param postcode: The postcode of the property
|
|
:return: The ID of the property and a boolean indicating whether it was created or not
|
|
"""
|
|
|
|
try:
|
|
# Attempt to fetch the existing property
|
|
existing_property = session.query(PropertyModel).filter_by(
|
|
uprn=uprn, portfolio_id=portfolio_id
|
|
).one()
|
|
|
|
# Update the 'updated_at' field
|
|
existing_property.updated_at = datetime.datetime.now(pytz.utc)
|
|
|
|
# Merge the updated property back into the session
|
|
session.merge(existing_property)
|
|
session.flush()
|
|
|
|
return existing_property.id, False
|
|
|
|
except NoResultFound:
|
|
# Property doesn't exist, create a new one
|
|
new_property = PropertyModel(
|
|
address=address,
|
|
postcode=postcode,
|
|
portfolio_id=portfolio_id,
|
|
uprn=uprn,
|
|
creation_status=PropertyCreationStatus.LOADING,
|
|
status=PortfolioStatus.ASSESSMENT.value,
|
|
has_pre_condition_report=False,
|
|
has_recommendations=False
|
|
)
|
|
|
|
# Add the new property to the session
|
|
session.add(new_property)
|
|
|
|
session.flush()
|
|
|
|
return new_property.id, True
|
|
|
|
|
|
def create_property_targets(
|
|
session: Session, property_id: int, portfolio_id: int, epc_target=None, heat_demand_target=None
|
|
):
|
|
"""
|
|
This function will create a record for the property targets in the database if it does not exist.
|
|
:param session: The database session
|
|
:param property_id: The ID of the property the targets belong to
|
|
:param portfolio_id: The ID of the portfolio the property belongs to
|
|
:param epc_target: Goal EPC value for the property
|
|
:param heat_demand_target: Heat demand target for the property in kwh/m^2/year
|
|
:return:
|
|
"""
|
|
|
|
new_target = PropertyTargetsModel(
|
|
property_id=property_id,
|
|
portfolio_id=portfolio_id,
|
|
epc=epc_target,
|
|
heat_demand=heat_demand_target
|
|
)
|
|
session.add(new_target)
|
|
session.flush()
|
|
|
|
return True
|
|
|
|
|
|
def update_property_data(
|
|
session: Session, property_id: int, portfolio_id: int, property_data: dict
|
|
):
|
|
now = datetime.datetime.now(pytz.utc)
|
|
|
|
try:
|
|
# Attempt to fetch the existing property
|
|
existing_property = session.query(PropertyModel).filter_by(
|
|
id=property_id, portfolio_id=portfolio_id
|
|
).one()
|
|
|
|
# Update the fields with the data in property_data
|
|
for key, value in property_data.items():
|
|
setattr(existing_property, key, value)
|
|
|
|
existing_property.updated_at = now
|
|
|
|
# Merge the updated property back into the session and flush
|
|
session.merge(existing_property)
|
|
session.flush()
|
|
|
|
except NoResultFound:
|
|
raise Exception(f"Property with property_id {property_id} and portfolio_id {portfolio_id} not found")
|
|
|
|
return True
|
|
|
|
|
|
def create_property_details_epc(
|
|
session: Session, property_details_epc: dict
|
|
):
|
|
"""
|
|
This function will create or update a record for the property details EPC in the database.
|
|
:param session: The database session
|
|
:param property_details_epc: A dictionary containing details about the property EPC.
|
|
:return: True if successful, False otherwise.
|
|
"""
|
|
|
|
existing_record = session.query(PropertyDetailsEpcModel).filter_by(
|
|
portfolio_id=property_details_epc["portfolio_id"],
|
|
property_id=property_details_epc["property_id"]
|
|
).first()
|
|
|
|
if existing_record:
|
|
# If the record exists, update its fields
|
|
for key, value in property_details_epc.items():
|
|
setattr(existing_record, key, value)
|
|
else:
|
|
# If the record doesn't exist, create a new one
|
|
new_property_details_epc = PropertyDetailsEpcModel(**property_details_epc)
|
|
session.add(new_property_details_epc)
|
|
|
|
session.flush()
|
|
|
|
return True
|
|
|
|
|
|
def update_or_create_property_spatial_details(session: Session, uprn: int, property_details_spatial: dict):
|
|
"""
|
|
Update an existing property details record or create a new one based on the UPRN.
|
|
|
|
:param session: The SQLAlchemy session for database interaction.
|
|
:param uprn: The unique property reference number (UPRN) of the property.
|
|
:param property_details_spatial: A dictionary containing the spatial property details to store or update.
|
|
:return: True if the operation is successful, otherwise raises an exception.
|
|
"""
|
|
|
|
try:
|
|
# Attempt to fetch the existing property details
|
|
existing_property_details = session.query(PropertyDetailsSpatial).filter_by(
|
|
uprn=uprn
|
|
).one()
|
|
|
|
# Update the fields with the data in property_details
|
|
for key, value in property_details_spatial.items():
|
|
setattr(existing_property_details, key, value)
|
|
|
|
# Merge the updated property details back into the session and flush
|
|
session.merge(existing_property_details)
|
|
session.flush()
|
|
|
|
except NoResultFound:
|
|
# Create a new record if not found
|
|
new_property_details = PropertyDetailsSpatial(uprn=uprn, **property_details_spatial)
|
|
session.add(new_property_details)
|
|
session.flush()
|
|
|
|
return True
|