Files

247 lines
9.4 KiB
Python
Raw Permalink Normal View History

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"] = 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)