Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ticket drop time UI support, unapproved club event visibility changes #750

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

julianweng
Copy link
Member

@julianweng julianweng commented Nov 23, 2024

  • Add UI support for ticket drop times
  • Add ticket_drop_time validation in event serializer based on event end time
  • Prevent retroactive editing of ticket drop time after tickets have been sold (plus handling of edge case where ticket has been added to cart but not bought before ticket drop time is pushed back)
  • Prevent unapproved clubs from selling tickets (add_to_cart)
  • Prevent clubs which have been archived from selling existing tickets
  • Allow leaders of unapproved clubs to create and view events (with the warning that such events are not visible to the public until the club is approved), allowing for "draft" functionality (also currently, the event just disappears after submission on the frontend for unapproved clubs...)
  • Standardize spelling of "publicly" in the codebase (alternative being "publically")
  • Add button to view public event page within event editing page
  • Show all clubs in /directory which have been approved at some point

Event page with unreleased tickets

Unapproved club event (displayed to officers only)

Note for events without a ticket_drop_time

User viewport after clicking on link to ticket_drop_time field within note

…ing details for non-dropped events, add ticket_drop_time serializer validation, make events belonging to unapproved clubs visible to club leaders specifically, standardize spelling of "publicly"
…ged following a ticket being added to a user's cart
@julianweng julianweng linked an issue Nov 23, 2024 that may be closed by this pull request
Copy link

codecov bot commented Nov 23, 2024

Codecov Report

Attention: Patch coverage is 83.33333% with 3 lines in your changes missing coverage. Please review.

Project coverage is 71.99%. Comparing base (b280dc0) to head (194cebe).
Report is 16 commits behind head on master.

Files with missing lines Patch % Lines
backend/clubs/views.py 80.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #750      +/-   ##
==========================================
+ Coverage   71.95%   71.99%   +0.04%     
==========================================
  Files          32       32              
  Lines        6953     6967      +14     
==========================================
+ Hits         5003     5016      +13     
- Misses       1950     1951       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@aviupadhyayula aviupadhyayula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up (and sorry for getting to this so late). Left some comments on the backend changes. Frontend changes LGTM!

backend/clubs/serializers.py Outdated Show resolved Hide resolved
{"detail": "Related club does not exist", "success": False},
status=status.HTTP_404_NOT_FOUND,
)
elif not club.approved and not club.ghost:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not None evaluates to true in Python. Is it possible for club.approved = None and club.ghost = None (and if so, do we want this condition evaluating to true)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, if a club has no approved value, then it's either new, in which case ghost would also be none and the condition should evaluate to true (e.g. the club shouldn't be able to sell tickets), or approved previously but recently changed, in which case the club should be able to sell tickets, ghost would be true, and this condition would be false.

Comment on lines +3217 to +3224
if (
"ticket_drop_time" in request.data
and Ticket.objects.filter(event=event, owner__isnull=False).exists()
):
raise DRFValidationError(
detail="""Ticket drop times cannot be edited
after tickets have been sold."""
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will there ever be a case where tickets have been issued to people, and then the drop time is changed? I think yes (imagine a club leader who's issued tickets to their members, before they're generally available to the public).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this condition can only be triggered if ticket drop time has also already elapsed? I think I was mostly just uncomfortable with the idea of ticket drop times being pushed back retroactively after people have bought tickets, but didn't consider the ticket issuance case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thinking only checking this once the ticket drop time has elapsed makes sense.

Comment on lines 5255 to +5263
tickets_to_replace = cart.tickets.filter(
Q(owner__isnull=False)
| Q(event__club__archived=True)
| Q(holder__isnull=False)
| Q(event__end_time__lt=now)
| (
Q(event__ticket_drop_time__gt=timezone.now())
& Q(event__ticket_drop_time__isnull=False)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is needed. Users shouldn't be able to add tickets to their cart if the ticket drop time hasn't elapsed yet. (The logic's in ClubEventViewSet.add_to_cart().)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is handling the edge case where people have added tickets to their cart under a certain ticket drop time, but the drop time has since been updated (assuming that existing cartholders shouldn't be "grandfathered" into the old ticket drop time).

Comment on lines +5396 to +5398
Q(event__ticket_drop_time__lt=timezone.now())
| Q(event__ticket_drop_time__isnull=True),
event__club__archived=False,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note as above here. Will there ever be a case where a ticket is in a user's cart, but the drop time hasn't elapsed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Responded above.

@julianweng julianweng force-pushed the 698-support-ticket-drop-times-on-frontend branch from af5e57c to 8d0adca Compare January 30, 2025 04:29
@julianweng julianweng self-assigned this Feb 5, 2025
@julianweng julianweng requested review from aviupadhyayula and removed request for rm03 February 5, 2025 14:18
Copy link
Member

@aviupadhyayula aviupadhyayula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Julian! Left some comments, thanks for picking this PR back up.

Comment on lines +468 to +471
if ticket_drop_time is not None and ticket_drop_time >= end_time:
raise serializers.ValidationError(
"Your ticket drop time must be before the event ends!"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this again: would it make more sense for the ticket drop time to be before the event's start time? I can't think of a scenario where the event would start but tickets would drop midway through it.

Comment on lines +3217 to +3224
if (
"ticket_drop_time" in request.data
and Ticket.objects.filter(event=event, owner__isnull=False).exists()
):
raise DRFValidationError(
detail="""Ticket drop times cannot be edited
after tickets have been sold."""
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thinking only checking this once the ticket drop time has elapsed makes sense.

@@ -5241,6 +5297,8 @@ def cart(self, request, *args, **kwargs):
continue

available_tickets = Ticket.objects.filter(
Q(event__ticket_drop_time__lt=timezone.now())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: should be less than or equal to.

@@ -605,6 +647,50 @@ def test_add_to_cart_before_ticket_drop(self):
# Tickets should not be added to cart before drop time
self.assertEqual(resp.status_code, 403, resp.content)

def test_add_to_cart_unapproved_club(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice to test the case where a user adds a ticket that's dropped, the ticket drop time gets pushed back, and the user attempts to check out. But maybe it's extra, feel free to skip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support ticket drop times on frontend
2 participants