from typing import List, Dict, Optional, Union, Any from datetime import datetime from decimal import Decimal from sqlalchemy.orm import Session from models.house import House from schemas.house import HouseCreate, HouseUpdate def validate_property_type(property_type: str) -> bool: """ Validate that property type is one of the accepted values. Args: property_type: The property type to validate Returns: bool: True if valid property type, False otherwise """ valid_types = ['single_family', 'townhouse', 'condo', 'multi_family', 'apartment'] return property_type.lower() in valid_types def calculate_price_per_sqft(price: float, square_footage: float) -> float: """ Calculate price per square foot of the property. Args: price: Total price of the property square_footage: Total square footage Returns: float: Price per square foot """ if square_footage <= 0: raise ValueError("Square footage must be greater than 0") return round(price / square_footage, 2) def search_available_houses( db: Session, min_price: Optional[float] = None, max_price: Optional[float] = None, min_beds: Optional[int] = None, min_baths: Optional[float] = None, property_type: Optional[str] = None ) -> List[House]: """ Search for available houses matching given criteria. Args: db: Database session min_price: Minimum price max_price: Maximum price min_beds: Minimum number of bedrooms min_baths: Minimum number of bathrooms property_type: Type of property Returns: List of matching House objects """ query = db.query(House).filter(House.is_available == True) if min_price: query = query.filter(House.price >= min_price) if max_price: query = query.filter(House.price <= max_price) if min_beds: query = query.filter(House.bedrooms >= min_beds) if min_baths: query = query.filter(House.bathrooms >= min_baths) if property_type: query = query.filter(House.property_type == property_type) return query.all() def update_house_status( db: Session, house_id: int, new_status: str ) -> Union[House, Dict[str, str]]: """ Update the status of a house listing. Args: db: Database session house_id: ID of house to update new_status: New status value Returns: Updated House object or error dict """ valid_statuses = ['available', 'pending', 'sold', 'off_market'] if new_status not in valid_statuses: return {"error": f"Invalid status. Must be one of: {', '.join(valid_statuses)}"} house = db.query(House).filter(House.id == house_id).first() if not house: return {"error": "House not found"} house.status = new_status if new_status != 'available': house.is_available = False db.commit() db.refresh(house) return house def validate_house_data(house_data: Dict[str, Any]) -> Dict[str, str]: """ Validate house data before creation/update. Args: house_data: Dictionary containing house data Returns: Dictionary with error messages if validation fails, empty dict if valid """ errors = {} if house_data.get('square_footage', 0) <= 0: errors['square_footage'] = "Square footage must be greater than 0" if house_data.get('price', 0) <= 0: errors['price'] = "Price must be greater than 0" if house_data.get('bedrooms', 0) < 0: errors['bedrooms'] = "Bedrooms cannot be negative" if house_data.get('bathrooms', 0) < 0: errors['bathrooms'] = "Bathrooms cannot be negative" if house_data.get('year_built', 0) > datetime.now().year: errors['year_built'] = "Year built cannot be in the future" if not validate_property_type(house_data.get('property_type', '')): errors['property_type'] = "Invalid property type" return errors