Skip to content

Commit

Permalink
Update views to use ticket settings
Browse files Browse the repository at this point in the history
  • Loading branch information
aviupadhyayula committed Jan 2, 2025
1 parent 0311a34 commit d7f8054
Showing 1 changed file with 85 additions and 51 deletions.
136 changes: 85 additions & 51 deletions backend/clubs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
Tag,
Testimonial,
Ticket,
TicketSettings,
TicketTransactionRecord,
TicketTransferRecord,
Year,
Expand Down Expand Up @@ -2464,6 +2465,14 @@ def add_to_cart(self, request, *args, **kwargs):
---
"""
event = self.get_object()

# Check if event has any tickets
if not event.has_tickets:
return Response(
{"detail": "This event does not have any tickets", "success": False},
status=status.HTTP_403_FORBIDDEN,
)

cart, _ = Cart.objects.get_or_create(owner=self.request.user)

# Check if the event has already ended
Expand All @@ -2474,7 +2483,10 @@ def add_to_cart(self, request, *args, **kwargs):
)

# Cannot add tickets that haven't dropped yet
if event.ticket_drop_time and timezone.now() < event.ticket_drop_time:
if (
event.ticket_settings.drop_time
and timezone.now() < event.ticket_settings.drop_time
):
return Response(
{"detail": "Ticket drop time has not yet elapsed", "success": False},
status=status.HTTP_403_FORBIDDEN,
Expand All @@ -2490,11 +2502,14 @@ def add_to_cart(self, request, *args, **kwargs):
num_requested = sum(item["count"] for item in quantities)
num_carted = cart.tickets.filter(event=event).count()

if num_requested + num_carted > event.ticket_order_limit:
if (
event.ticket_settings.order_limit
and num_requested + num_carted > event.ticket_settings.order_limit
):
return Response(
{
"detail": f"Order exceeds the maximum ticket limit of "
f"{event.ticket_order_limit}.",
f"{event.ticket_settings.order_limit}.",
"success": False,
},
status=status.HTTP_403_FORBIDDEN,
Expand Down Expand Up @@ -2680,20 +2695,22 @@ def tickets(self, request, *args, **kwargs):
---
"""
event = self.get_object()
tickets = Ticket.objects.filter(event=event)

if event.ticket_drop_time and timezone.now() < event.ticket_drop_time:
if not event.has_tickets or (
event.ticket_settings.drop_time
and timezone.now() < event.ticket_settings.drop_time
):
return Response({"totals": [], "available": []})

# Take price of first ticket of given type for now
totals = (
tickets.values("type")
event.tickets.values("type")
.annotate(price=Max("price"))
.annotate(count=Count("type"))
.order_by("type")
)
available = (
tickets.filter(owner__isnull=True, holder__isnull=True, buyable=True)
event.tickets.filter(owner__isnull=True, holder__isnull=True, buyable=True)
.values("type")
.annotate(price=Max("price"))
.annotate(count=Count("type"))
Expand All @@ -2705,7 +2722,11 @@ def tickets(self, request, *args, **kwargs):
@transaction.atomic
def create_tickets(self, request, *args, **kwargs):
"""
Create ticket offerings for event
Create or update ticket offerings for an event.
This endpoint allows configuring ticket types, quantities, prices, and settings.
Tickets cannot be modified after they have been dropped or sold.
---
requestBody:
content:
Expand All @@ -2717,6 +2738,11 @@ def create_tickets(self, request, *args, **kwargs):
type: array
items:
type: object
required:
- type
- count
- price
- transferable
properties:
type:
type: string
Expand All @@ -2725,26 +2751,24 @@ def create_tickets(self, request, *args, **kwargs):
price:
type: number
group_size:
type: number
required: false
type: integer
group_discount:
type: number
format: float
required: false
transferable:
type: boolean
buyable:
type: boolean
required: false
order_limit:
type: int
required: false
type: integer
drop_time:
type: string
format: date-time
required: false
fee_charged_to_buyer:
type: boolean
responses:
"200":
description: Tickets created successfully
content:
application/json:
schema:
Expand All @@ -2753,6 +2777,7 @@ def create_tickets(self, request, *args, **kwargs):
detail:
type: string
"400":
description: Invalid request parameters
content:
application/json:
schema:
Expand All @@ -2761,6 +2786,7 @@ def create_tickets(self, request, *args, **kwargs):
detail:
type: string
"403":
description: Tickets cannot be modified
content:
application/json:
schema:
Expand All @@ -2772,27 +2798,59 @@ def create_tickets(self, request, *args, **kwargs):
"""
event = self.get_object()

# Tickets can't be edited after they've dropped
if event.ticket_drop_time and timezone.now() > event.ticket_drop_time:
# Tickets can't be edited after they've been sold or checked out
if event.tickets.filter(
Q(owner__isnull=False) | Q(holder__isnull=False)
).exists():
return Response(
{"detail": "Tickets cannot be edited after they have dropped"},
{
"detail": "Tickets cannot be edited after they have been "
"sold or checked out"
},
status=status.HTTP_403_FORBIDDEN,
)

# Tickets can't be edited after they've been sold or held
ticket_settings, _ = TicketSettings.objects.get_or_create(event=event)

# Tickets can't be edited after they've dropped
if (
Ticket.objects.filter(event=event)
.filter(Q(owner__isnull=False) | Q(holder__isnull=False))
.exists()
event.ticket_settings.drop_time
and timezone.now() > event.ticket_settings.drop_time
):
return Response(
{
"detail": "Tickets cannot be edited after they have been "
"sold or checked out"
},
{"detail": "Tickets cannot be edited after they have dropped"},
status=status.HTTP_403_FORBIDDEN,
)

order_limit = request.data.get("order_limit", None)
if order_limit is not None:
ticket_settings.order_limit = order_limit
ticket_settings.save()

drop_time = request.data.get("drop_time", None)
if drop_time is not None:
try:
drop_time = datetime.datetime.strptime(drop_time, "%Y-%m-%dT%H:%M:%S%z")
except ValueError as e:
return Response(
{"detail": f"Invalid drop time: {str(e)}"},
status=status.HTTP_400_BAD_REQUEST,
)

if drop_time < timezone.now():
return Response(
{"detail": "Specified drop time has already elapsed"},
status=status.HTTP_400_BAD_REQUEST,
)

ticket_settings.drop_time = drop_time
ticket_settings.save()

fee_charged_to_buyer = request.data.get("fee_charged_to_buyer", None)
if fee_charged_to_buyer is not None:
ticket_settings.fee_charged_to_buyer = fee_charged_to_buyer
ticket_settings.save()

quantities = request.data.get("quantities", [])
if not quantities:
return Response(
Expand Down Expand Up @@ -2855,35 +2913,11 @@ def create_tickets(self, request, *args, **kwargs):
for item in quantities
for _ in range(item["count"])
]

Ticket.objects.bulk_create(tickets)

order_limit = request.data.get("order_limit", None)
if order_limit is not None:
event.ticket_order_limit = order_limit
event.save()

drop_time = request.data.get("drop_time", None)
if drop_time is not None:
try:
drop_time = datetime.datetime.strptime(drop_time, "%Y-%m-%dT%H:%M:%S%z")
except ValueError as e:
return Response(
{"detail": f"Invalid drop time: {str(e)}"},
status=status.HTTP_400_BAD_REQUEST,
)

if drop_time < timezone.now():
return Response(
{"detail": "Specified drop time has already elapsed"},
status=status.HTTP_400_BAD_REQUEST,
)

event.ticket_drop_time = drop_time
event.save()

cache.delete(f"clubs:{event.club.id}-authed")
cache.delete(f"clubs:{event.club.id}-anon")

return Response({"detail": "Successfully created tickets"})

@action(detail=True, methods=["post"])
Expand Down

0 comments on commit d7f8054

Please sign in to comment.