UI: Implement Web Assets' theme system, and add 'dark' theme #103972
@ -428,7 +428,7 @@ ACTIVE_PAYMENT_BACKEND = os.getenv('ACTIVE_PAYMENT_METHOD', 'stripe')
|
||||
# An indicator for the maximum amount of tickets that can be sold
|
||||
TICKET_SALES_CAP = int(os.getenv('TICKET_SALES_CAP', 760))
|
||||
|
||||
# Backgroun tasks settings
|
||||
# Background tasks settings
|
||||
MAX_ATTEMPTS = 3
|
||||
|
||||
if os.environ.get('ADMINS') is not None:
|
||||
|
@ -13,7 +13,7 @@ from django.contrib.flatpages.models import FlatPage
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from django.db import models as django_models
|
||||
from django.db.models import QuerySet, Sum, F, Value, Count, OuterRef, Subquery
|
||||
from django.db.models import QuerySet, Sum, F, Value, Count, OuterRef, Subquery, Q
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.http import HttpRequest
|
||||
from django.http.response import HttpResponse, HttpResponseBadRequest, JsonResponse
|
||||
@ -218,7 +218,7 @@ class IsScheduledFilter(PreFilteredListFilter):
|
||||
if value == 'Yes':
|
||||
return queryset.filter(day__isnull=False, time__isnull=False)
|
||||
elif value == 'No':
|
||||
return queryset.filter(day__isnull=True, time__isnull=True)
|
||||
return queryset.filter(Q(day__isnull=True) | Q(time__isnull=True))
|
||||
return queryset
|
||||
|
||||
|
||||
|
@ -256,7 +256,7 @@ class TicketAdmin(_CSVReportMixin, admin.ModelAdmin):
|
||||
'user__profile__title',
|
||||
)
|
||||
date_hierarchy = 'created_at'
|
||||
actions = ['send_mail_unclaimed_reminder', 'send_mail_unpaid_reminder']
|
||||
actions = ['send_mail_unclaimed_reminder', 'send_mail_unpaid_reminder', 'mark_as_unpaid']
|
||||
|
||||
def get_fieldsets(self, *args, **kwargs):
|
||||
"""Hide checkout data into a collapsible section."""
|
||||
@ -399,6 +399,16 @@ class TicketAdmin(_CSVReportMixin, admin.ModelAdmin):
|
||||
msg = f'{count} emails queued for sending'
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
||||
def mark_as_unpaid(self, request, queryset):
|
||||
"""Set tickets as not paid."""
|
||||
count = 0
|
||||
for ticket in queryset:
|
||||
ticket.is_paid = False
|
||||
ticket.save()
|
||||
count += 1
|
||||
msg = f'{count} tickets set as unpaid'
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
||||
|
||||
@admin.register(tickets.models.TicketClaim)
|
||||
class TicketClaimAdmin(_CSVReportMixin, admin.ModelAdmin):
|
||||
|
@ -177,6 +177,7 @@ def _upsert_ticket_from_payment_intent(user_id, sku, quantity, payment_intent, p
|
||||
def process_charge_refunded(payload):
|
||||
"""Clear attendees from matching ticket, if it's been fully refunded.
|
||||
|
||||
Also, set ticket as not paid (used to restore availability quota).
|
||||
Also, update stored checkout session data.
|
||||
"""
|
||||
charge = payload.get('data', {}).get('object', {})
|
||||
@ -193,6 +194,9 @@ def process_charge_refunded(payload):
|
||||
if is_full_refund:
|
||||
logger.info('Removing all attendees from a fully refunded ticket pk=%s', ticket.pk)
|
||||
ticket.attendees.clear()
|
||||
# Mark tickets as unpaid when fully refunded
|
||||
ticket.is_paid = False
|
||||
ticket.save()
|
||||
|
||||
_update_checkout_data(ticket, session)
|
||||
|
||||
|
@ -550,6 +550,8 @@ class TestStripeWebhook(TestCase):
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(ticket.attendees.count(), 0)
|
||||
ticket = Ticket.objects.get(id=ticket.id)
|
||||
self.assertEqual(ticket.is_paid, False)
|
||||
|
||||
# Check that invoice PDF includes refund date and updated total
|
||||
invoice_url = reverse('tickets:invoice-pdf', kwargs={'ticket_token': ticket.token})
|
||||
|
Loading…
Reference in New Issue
Block a user