diff --git a/backend/grants/admin.py b/backend/grants/admin.py index 5cba23db4d..6615e8bd06 100644 --- a/backend/grants/admin.py +++ b/backend/grants/admin.py @@ -1,3 +1,4 @@ +import logging from django.db import transaction from custom_admin.audit import ( create_addition_admin_log_entry, @@ -31,12 +32,15 @@ from submissions.models import Submission from .models import Grant, GrantConfirmPendingStatusProxy from django.db.models import Exists, OuterRef, F +from pretix import user_has_admission_ticket from django.contrib.admin import SimpleListFilter from participants.models import Participant from django.urls import reverse from django.utils.safestring import mark_safe +logger = logging.getLogger(__name__) + EXPORT_GRANTS_FIELDS = ( "name", "full_name", @@ -407,10 +411,10 @@ class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin): "accommodation_amount", "total_amount", "country_type", + "user_has_ticket", + "has_voucher", "applicant_reply_sent_at", "applicant_reply_deadline", - "voucher_code", - "voucher_email_sent_at", "created", ) list_filter = ( @@ -461,9 +465,6 @@ class GrantAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin): "total_amount", "applicant_reply_sent_at", "applicant_reply_deadline", - "pretix_voucher_id", - "voucher_code", - "voucher_email_sent_at", "internal_notes", ) }, @@ -560,6 +561,29 @@ def emoji_gender(self, obj): } return emoji[gender] + @admin.display( + boolean=True, + ) + def user_has_ticket(self, obj: Grant) -> bool: + if not obj.user_id: + return None + + try: + return user_has_admission_ticket( + email=obj.user.email, + event_organizer=obj.conference.pretix_organizer_id, + event_slug=obj.conference.pretix_event_id, + ) + except Exception as e: + logger.error(e) + return None + + @admin.display( + boolean=True, + ) + def has_voucher(self, obj: Grant) -> bool: + return obj.has_voucher + def get_queryset(self, request): qs = ( super() @@ -577,8 +601,16 @@ def get_queryset(self, request): submission__speaker_id=OuterRef("user_id"), ) ), + has_voucher=Exists( + ConferenceVoucher.objects.for_conference( + OuterRef("conference_id"), + ).filter( + user_id=OuterRef("user_id"), + ) + ), ) ) + return qs class Media: diff --git a/backend/grants/migrations/0028_remove_grant_pretix_voucher_id_and_more.py b/backend/grants/migrations/0028_remove_grant_pretix_voucher_id_and_more.py new file mode 100644 index 0000000000..a5223817a9 --- /dev/null +++ b/backend/grants/migrations/0028_remove_grant_pretix_voucher_id_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 5.1.4 on 2025-01-28 16:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('grants', '0027_grantconfirmpendingstatusproxy'), + ] + + operations = [ + migrations.RemoveField( + model_name='grant', + name='pretix_voucher_id', + ), + migrations.RemoveField( + model_name='grant', + name='voucher_code', + ), + migrations.RemoveField( + model_name='grant', + name='voucher_email_sent_at', + ), + ] diff --git a/backend/grants/models.py b/backend/grants/models.py index adfcce6e76..a7bb447af8 100644 --- a/backend/grants/models.py +++ b/backend/grants/models.py @@ -207,19 +207,6 @@ class ApprovedType(models.TextChoices): ) # Voucher Management - voucher_code = models.TextField( - help_text=_("Voucher code generated for this grant."), - blank=True, - null=True, - ) - pretix_voucher_id = models.IntegerField( - help_text=_("ID of the voucher in the Pretix database"), - blank=True, - null=True, - ) - voucher_email_sent_at = models.DateTimeField( - help_text=_("When the email was last sent"), blank=True, null=True - ) internal_notes = models.TextField( _("Internal Notes"), help_text=_("Internal notes only available to the Financial Aid Commettie"),