""" Park submission service for ThrillWiki. Handles Park entity creation and updates through the Sacred Pipeline. """ import logging from decimal import Decimal from django.core.exceptions import ValidationError from apps.entities.models import Park from apps.entities.services import BaseEntitySubmissionService logger = logging.getLogger(__name__) class ParkSubmissionService(BaseEntitySubmissionService): """ Service for creating Park submissions through the Sacred Pipeline. Parks require special handling for: - Geographic coordinates (latitude/longitude) - Location point (PostGIS in production) - Park type and status fields Required fields: - name: Park name - park_type: Type of park (theme_park, amusement_park, etc.) Example: from apps.entities.services.park_submission import ParkSubmissionService submission, park = ParkSubmissionService.create_entity_submission( user=request.user, data={ 'name': 'Cedar Point', 'park_type': 'theme_park', 'status': 'operating', 'latitude': Decimal('41.4792'), 'longitude': Decimal('-82.6839'), 'description': 'Legendary amusement park...', }, source='api', ip_address=request.META.get('REMOTE_ADDR') ) """ entity_model = Park entity_type_name = 'Park' required_fields = ['name', 'park_type'] @classmethod def create_entity_submission(cls, user, data, **kwargs): """ Create a Park submission with special coordinate handling. Coordinates (latitude/longitude) are processed using the Park model's set_location() method which handles both SQLite and PostGIS modes. Args: user: User creating the park data: Park field data (must include name and park_type) **kwargs: Additional metadata (source, ip_address, user_agent) Returns: tuple: (ContentSubmission, Park or None) """ # Extract coordinates for special handling latitude = data.get('latitude') longitude = data.get('longitude') # Create submission through base class submission, park = super().create_entity_submission(user, data, **kwargs) # If park was created (moderator bypass), set location using helper method if park and latitude is not None and longitude is not None: try: park.set_location(float(longitude), float(latitude)) park.save() logger.info( f"Park {park.id} location set: " f"({latitude}, {longitude})" ) except Exception as e: logger.warning( f"Failed to set location for Park {park.id}: {str(e)}" ) return submission, park @classmethod def update_entity_submission(cls, entity, user, update_data, **kwargs): """ Update a Park with special coordinate handling. Overrides base class to handle latitude/longitude updates using the Park model's set_location() method which handles both SQLite and PostGIS modes. Args: entity: Existing Park instance to update user: User making the update update_data: Park field data to update **kwargs: Additional parameters - latitude: New latitude coordinate (optional) - longitude: New longitude coordinate (optional) - source: Submission source ('api', 'web', etc.) - ip_address: User's IP address (optional) - user_agent: User's user agent string (optional) Returns: tuple: (ContentSubmission, Park or None) """ # Extract coordinates for special handling latitude = kwargs.pop('latitude', None) longitude = kwargs.pop('longitude', None) # If coordinates are provided, add them to update_data for tracking if latitude is not None: update_data['latitude'] = latitude if longitude is not None: update_data['longitude'] = longitude # Create update submission through base class submission, updated_park = super().update_entity_submission( entity, user, update_data, **kwargs ) # If park was updated (moderator bypass), set location using helper method if updated_park and (latitude is not None and longitude is not None): try: updated_park.set_location(float(longitude), float(latitude)) updated_park.save() logger.info( f"Park {updated_park.id} location updated: " f"({latitude}, {longitude})" ) except Exception as e: logger.warning( f"Failed to update location for Park {updated_park.id}: {str(e)}" ) return submission, updated_park