# models/property_specs.py from datetime import datetime from .logging_config import logger def verify_property_specs(data): """ Verify property specifications for reasonableness and consistency. This function checks if the provided property details are within reasonable ranges for the Indian real estate market. """ specs_verification = { 'is_valid': True, 'bedrooms_reasonable': True, 'bathrooms_reasonable': True, 'total_rooms_reasonable': True, 'year_built_reasonable': True, 'parking_reasonable': True, 'sq_ft_reasonable': True, 'market_value_reasonable': True, 'issues': [] } try: # Helper function to safely convert values def safe_float_convert(value, default=0.0): try: if isinstance(value, (int, float)): return float(value) if isinstance(value, str): return float(value.replace(',', '').replace('₹', '').strip()) return default except (ValueError, TypeError): return default def safe_int_convert(value, default=0): try: if isinstance(value, (int, float)): return int(value) if isinstance(value, str): return int(float(value.replace(',', '').strip())) return default except (ValueError, TypeError): return default # Validate property type valid_property_types = [ 'Apartment', 'House', 'Villa', 'Independent House', 'Independent Villa', 'Studio', 'Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial' ] if 'property_type' not in data or data['property_type'] not in valid_property_types: specs_verification['is_valid'] = False specs_verification['issues'].append(f"Invalid property type: {data.get('property_type', 'Not specified')}") # Validate bedrooms if 'bedrooms' in data: bedrooms = safe_int_convert(data['bedrooms']) if data['property_type'] in ['Apartment', 'Studio']: if bedrooms > 5 or bedrooms < 0: specs_verification['bedrooms_reasonable'] = False specs_verification['issues'].append(f"Invalid number of bedrooms for {data['property_type']}: {bedrooms}. Should be between 0 and 5.") elif data['property_type'] in ['House', 'Villa', 'Independent House', 'Independent Villa']: if bedrooms > 8 or bedrooms < 0: specs_verification['bedrooms_reasonable'] = False specs_verification['issues'].append(f"Invalid number of bedrooms for {data['property_type']}: {bedrooms}. Should be between 0 and 8.") elif data['property_type'] in ['Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial']: if bedrooms > 0: specs_verification['bedrooms_reasonable'] = False specs_verification['issues'].append(f"Commercial properties typically don't have bedrooms: {bedrooms}") # Validate bathrooms if 'bathrooms' in data: bathrooms = safe_float_convert(data['bathrooms']) if data['property_type'] in ['Apartment', 'Studio']: if bathrooms > 4 or bathrooms < 0: specs_verification['bathrooms_reasonable'] = False specs_verification['issues'].append(f"Invalid number of bathrooms for {data['property_type']}: {bathrooms}. Should be between 0 and 4.") elif data['property_type'] in ['House', 'Villa', 'Independent House', 'Independent Villa']: if bathrooms > 6 or bathrooms < 0: specs_verification['bathrooms_reasonable'] = False specs_verification['issues'].append(f"Invalid number of bathrooms for {data['property_type']}: {bathrooms}. Should be between 0 and 6.") elif data['property_type'] in ['Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial']: if bathrooms > 0: specs_verification['bathrooms_reasonable'] = False specs_verification['issues'].append(f"Commercial properties typically don't have bathrooms: {bathrooms}") # Validate total rooms if 'total_rooms' in data: try: total_rooms = int(data['total_rooms']) if total_rooms < 0: specs_verification['total_rooms_reasonable'] = False specs_verification['issues'].append(f"Invalid total rooms: {total_rooms}. Cannot be negative.") elif 'bedrooms' in data and 'bathrooms' in data: try: bedrooms = int(data['bedrooms']) bathrooms = int(float(data['bathrooms'])) if total_rooms < (bedrooms + bathrooms): specs_verification['total_rooms_reasonable'] = False specs_verification['issues'].append(f"Total rooms ({total_rooms}) is less than bedrooms + bathrooms ({bedrooms + bathrooms})") except ValueError: pass except ValueError: specs_verification['total_rooms_reasonable'] = False specs_verification['issues'].append("Invalid total rooms data: must be a number") # Validate parking if 'parking' in data: try: parking = int(data['parking']) if data['property_type'] in ['Apartment', 'Studio']: if parking > 2 or parking < 0: specs_verification['parking_reasonable'] = False specs_verification['issues'].append(f"Invalid parking spaces for {data['property_type']}: {parking}. Should be between 0 and 2.") elif data['property_type'] in ['House', 'Villa', 'Independent House', 'Independent Villa']: if parking > 4 or parking < 0: specs_verification['parking_reasonable'] = False specs_verification['issues'].append(f"Invalid parking spaces for {data['property_type']}: {parking}. Should be between 0 and 4.") elif data['property_type'] in ['Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial']: if parking < 0: specs_verification['parking_reasonable'] = False specs_verification['issues'].append(f"Invalid parking spaces: {parking}. Cannot be negative.") except ValueError: specs_verification['parking_reasonable'] = False specs_verification['issues'].append("Invalid parking data: must be a number") # Validate square footage if 'sq_ft' in data: try: sq_ft = float(data['sq_ft'].replace(',', '')) if sq_ft <= 0: specs_verification['sq_ft_reasonable'] = False specs_verification['issues'].append(f"Invalid square footage: {sq_ft}. Must be greater than 0.") else: if data['property_type'] in ['Apartment', 'Studio']: if sq_ft > 5000: specs_verification['sq_ft_reasonable'] = False specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably high for {data['property_type']}") elif sq_ft < 200: specs_verification['sq_ft_reasonable'] = False specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably low for {data['property_type']}") elif data['property_type'] in ['House', 'Villa', 'Independent House', 'Independent Villa']: if sq_ft > 10000: specs_verification['sq_ft_reasonable'] = False specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably high for {data['property_type']}") elif sq_ft < 500: specs_verification['sq_ft_reasonable'] = False specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably low for {data['property_type']}") except ValueError: specs_verification['sq_ft_reasonable'] = False specs_verification['issues'].append("Invalid square footage data: must be a number") # Validate market value if 'market_value' in data: try: market_value = float(data['market_value'].replace(',', '').replace('₹', '').strip()) if market_value <= 0: specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Invalid market value: {market_value}. Must be greater than 0.") else: if data['property_type'] in ['Apartment', 'Studio']: if market_value > 500000000: # 5 crore limit for apartments specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably high for {data['property_type']}") elif market_value < 500000: # 5 lakh minimum specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {data['property_type']}") elif data['property_type'] in ['House', 'Villa', 'Independent House', 'Independent Villa']: if market_value > 2000000000: # 20 crore limit for houses specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably high for {data['property_type']}") elif market_value < 1000000: # 10 lakh minimum specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {data['property_type']}") elif data['property_type'] in ['Commercial', 'Office', 'Shop']: if market_value < 2000000: # 20 lakh minimum specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {data['property_type']}") elif data['property_type'] in ['Warehouse', 'Industrial']: if market_value < 5000000: # 50 lakh minimum specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {data['property_type']}") # Check price per square foot if 'sq_ft' in data and float(data['sq_ft'].replace(',', '')) > 0: try: sq_ft = float(data['sq_ft'].replace(',', '')) price_per_sqft = market_value / sq_ft if data['property_type'] in ['Apartment', 'Studio']: if price_per_sqft < 1000: # Less than ₹1000 per sq ft specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably low for {data['property_type']}") elif price_per_sqft > 50000: # More than ₹50k per sq ft specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably high for {data['property_type']}") elif data['property_type'] in ['House', 'Villa', 'Independent House', 'Independent Villa']: if price_per_sqft < 500: # Less than ₹500 per sq ft specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably low for {data['property_type']}") elif price_per_sqft > 100000: # More than ₹1 lakh per sq ft specs_verification['market_value_reasonable'] = False specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably high for {data['property_type']}") except ValueError: pass except ValueError: specs_verification['market_value_reasonable'] = False specs_verification['issues'].append("Invalid market value data: must be a number") # Calculate verification score valid_checks = sum([ specs_verification['bedrooms_reasonable'], specs_verification['bathrooms_reasonable'], specs_verification['total_rooms_reasonable'], specs_verification['year_built_reasonable'], specs_verification['parking_reasonable'], specs_verification['sq_ft_reasonable'], specs_verification['market_value_reasonable'] ]) total_checks = 7 specs_verification['verification_score'] = (valid_checks / total_checks) * 100 # Overall validity specs_verification['is_valid'] = all([ specs_verification['bedrooms_reasonable'], specs_verification['bathrooms_reasonable'], specs_verification['total_rooms_reasonable'], specs_verification['year_built_reasonable'], specs_verification['parking_reasonable'], specs_verification['sq_ft_reasonable'], specs_verification['market_value_reasonable'] ]) except Exception as e: logger.error(f"Error in property specs verification: {str(e)}") specs_verification['is_valid'] = False specs_verification['issues'].append(f"Error in verification: {str(e)}") return specs_verification