The new updates of partners and user

Made-with: Cursor
This commit is contained in:
Vivek P Prakash
2026-03-15 00:29:17 +05:30
parent 88b3aafb0b
commit c04395afc9
65 changed files with 5242 additions and 341 deletions

246
events/api.py Normal file
View File

@@ -0,0 +1,246 @@
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)

View File

@@ -0,0 +1,33 @@
# Generated by Django 4.2.27 on 2026-03-13 16:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0006_alter_event_source'),
]
operations = [
migrations.AddField(
model_name='event',
name='gst_percentage_1',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='event',
name='gst_percentage_2',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='event',
name='include_gst',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='event',
name='event_status',
field=models.CharField(choices=[('created', 'Created'), ('cancelled', 'Cancelled'), ('pending', 'Pending'), ('completed', 'Completed'), ('postponed', 'Postponed'), ('published', 'Published'), ('live', 'Live'), ('flagged', 'Flagged')], default='pending', max_length=250),
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 4.2.27 on 2026-03-14 15:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('partner', '0001_initial'),
('events', '0007_event_gst_percentage_1_event_gst_percentage_2_and_more'),
]
operations = [
migrations.AddField(
model_name='event',
name='is_partner_event',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='event',
name='partner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='partner.partner'),
),
]

View File

@@ -1,6 +1,7 @@
from random import choices
from django.db import models
from master_data.models import EventType
from partner.models import Partner
class Event(models.Model):
@@ -21,10 +22,16 @@ class Event(models.Model):
place = models.CharField(max_length=200)
is_bookable = models.BooleanField(default=False)
include_gst = models.BooleanField(default=False)
gst_percentage_1 = models.IntegerField(default=0)
gst_percentage_2 = models.IntegerField(default=0)
is_eventify_event = models.BooleanField(default=True)
outside_event_url = models.URLField(default='NA')
is_partner_event = models.BooleanField(default=False)
partner = models.ForeignKey(Partner, on_delete=models.CASCADE, blank=True, null=True)
event_type = models.ForeignKey(EventType, on_delete=models.CASCADE)
event_status = models.CharField(max_length=250, choices=[
('created', 'Created'),
@@ -32,6 +39,9 @@ class Event(models.Model):
('pending', 'Pending'),
('completed', 'Completed'),
('postponed', 'Postponed'),
('published', 'Published'),
('live', 'Live'),
('flagged', 'Flagged'),
], default='pending')
cancelled_reason = models.TextField(default='NA')

View File

@@ -1,5 +1,6 @@
from django.urls import path
from . import views
from . import api
app_name = 'events'
@@ -14,3 +15,8 @@ urlpatterns = [
path('<int:pk>/images/<int:img_id>/delete/', views.delete_event_image, name='delete_event_image'),
path('<int:pk>/images/<int:img_id>/primary/', views.set_primary_image, name='set_primary_image'),
]
# Event API URLs
urlpatterns += [
path('api/create/', api.EventCreateAPI.as_view(), name='event_api_create'),
]

View File

@@ -10,8 +10,6 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from .models import Event
class EventListView(LoginRequiredMixin, generic.ListView):