from django.http import JsonResponse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.forms.models import model_to_dict from rest_framework.views import APIView from datetime import datetime from events.models import Event from master_data.models import EventType from mobile_api.utils import validate_token_and_get_user from eventify_logger.services import log def _event_to_dict(event, request=None): """Serialize Event for JSON.""" data = model_to_dict( event, fields=[ "id", "name", "description", "start_date", "end_date", "start_time", "end_time", "all_year_event", "latitude", "longitude", "pincode", "district", "state", "place", "venue_name", "event_status", "cancelled_reason", "important_information", "source", "created_date", ], ) # Add event_type info data["event_type"] = { "id": event.event_type.id, "event_type": event.event_type.event_type, } if event.event_type.event_type_icon: if request: data["event_type"]["event_type_icon"] = request.build_absolute_uri(event.event_type.event_type_icon.url) else: data["event_type"]["event_type_icon"] = event.event_type.event_type_icon.url else: data["event_type"]["event_type_icon"] = None return data @method_decorator(csrf_exempt, name="dispatch") class EventCreateAPI(APIView): """ Create Event API. Body: token, username (required); name, description, latitude, longitude, pincode, place, event_type_id (required); start_date, end_date, start_time, end_time, all_year_event, venue_name, event_status, cancelled_reason, important_information, source, district, state (optional). Returns: created event data. """ def post(self, request): try: user, token, data, error_response = validate_token_and_get_user(request, error_status_code=True) if error_response: return error_response # Extract required fields name = data.get("name") description = data.get("description") latitude = data.get("latitude") longitude = data.get("longitude") pincode = data.get("pincode") place = data.get("place") event_type_id = data.get("event_type_id") or data.get("event_type") # Validate required fields if not all([name, description, latitude, longitude, pincode, place, event_type_id]): return JsonResponse( { "status": "error", "message": "name, description, latitude, longitude, pincode, place, and event_type_id are required.", }, status=400, ) # Validate event_type exists try: event_type = EventType.objects.get(id=event_type_id) except EventType.DoesNotExist: return JsonResponse( {"status": "error", "message": "EventType not found."}, status=404, ) # Validate latitude and longitude try: latitude = float(latitude) if latitude < -90 or latitude > 90: return JsonResponse( {"status": "error", "message": "latitude must be between -90 and 90."}, status=400, ) except (TypeError, ValueError): return JsonResponse( {"status": "error", "message": "latitude must be numeric."}, status=400, ) try: longitude = float(longitude) if longitude < -180 or longitude > 180: return JsonResponse( {"status": "error", "message": "longitude must be between -180 and 180."}, status=400, ) except (TypeError, ValueError): return JsonResponse( {"status": "error", "message": "longitude must be numeric."}, status=400, ) # Handle all_year_event all_year_event = data.get("all_year_event", False) if isinstance(all_year_event, str): all_year_event = all_year_event.lower() in ['true', '1', 'yes', 'on'] # Handle dates and times - clear if all_year_event is True start_date = None end_date = None start_time = None end_time = None if not all_year_event: # Parse start_date if data.get("start_date"): try: start_date = datetime.strptime(data["start_date"], "%Y-%m-%d").date() except ValueError: return JsonResponse( {"status": "error", "message": "Invalid start_date format. Expected YYYY-MM-DD."}, status=400, ) # Parse end_date if data.get("end_date"): try: end_date = datetime.strptime(data["end_date"], "%Y-%m-%d").date() except ValueError: return JsonResponse( {"status": "error", "message": "Invalid end_date format. Expected YYYY-MM-DD."}, status=400, ) # Parse start_time if data.get("start_time"): try: start_time = datetime.strptime(data["start_time"], "%H:%M:%S").time() except ValueError: try: start_time = datetime.strptime(data["start_time"], "%H:%M").time() except ValueError: return JsonResponse( {"status": "error", "message": "Invalid start_time format. Expected HH:MM or HH:MM:SS."}, status=400, ) # Parse end_time if data.get("end_time"): try: end_time = datetime.strptime(data["end_time"], "%H:%M:%S").time() except ValueError: try: end_time = datetime.strptime(data["end_time"], "%H:%M").time() except ValueError: return JsonResponse( {"status": "error", "message": "Invalid end_time format. Expected HH:MM or HH:MM:SS."}, status=400, ) # Validate event_status if provided event_status = data.get("event_status", "pending") valid_statuses = ['created', 'cancelled', 'pending', 'completed', 'postponed'] if event_status not in valid_statuses: return JsonResponse( { "status": "error", "message": f"Invalid event_status. Must be one of: {', '.join(valid_statuses)}", }, status=400, ) # Validate source if provided source = data.get("source", "official") valid_sources = ['official', 'community'] if source not in valid_sources: return JsonResponse( { "status": "error", "message": f"Invalid source. Must be one of: {', '.join(valid_sources)}", }, status=400, ) # Create event event = Event.objects.create( name=name, description=description, start_date=start_date, end_date=end_date, start_time=start_time, end_time=end_time, all_year_event=all_year_event, latitude=latitude, longitude=longitude, pincode=pincode, district=data.get("district", ""), state=data.get("state", ""), place=place, venue_name=data.get("venue_name", ""), event_type=event_type, event_status=event_status, cancelled_reason=data.get("cancelled_reason", "NA"), important_information=data.get("important_information", ""), source=source, ) log("info", "Event created", request=request, user=user, logger_data={"event_id": event.id, "event_name": name}) return JsonResponse( { "status": "success", "message": "Event created successfully.", "event": _event_to_dict(event, request), }, status=201, ) except Exception as e: log("error", "Event create exception", request=request, logger_data={"error": str(e)}) return JsonResponse({"status": "error", "message": str(e)}, status=500)