Source code for events.models.event_registration

from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q
from django.template.defaulttags import date
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from . import Event
from payments.models import Payable


[docs]def registration_member_choices_limit(): """Defines queryset filters to only include current members""" return Q(membership__until__isnull=True) | Q( membership__until__gt=timezone.now().date() )
[docs]class EventRegistration(models.Model, Payable): """Describes a registration for an Event""" event = models.ForeignKey(Event, models.CASCADE) member = models.ForeignKey( "members.Member", models.CASCADE, blank=True, null=True, limit_choices_to=registration_member_choices_limit, ) name = models.CharField( _("name"), max_length=50, help_text=_("Use this for non-members"), null=True, blank=True, ) date = models.DateTimeField(_("registration date"), default=timezone.now) date_cancelled = models.DateTimeField(_("cancellation date"), null=True, blank=True) present = models.BooleanField(_("present"), default=False,) payment = models.OneToOneField( "payments.Payment", related_name="events_registration", on_delete=models.SET_NULL, blank=True, null=True, ) @property def information_fields(self): fields = self.event.registrationinformationfield_set.all() return [ {"field": field, "value": field.get_value_for(self)} for field in fields ] @property def is_registered(self): return self.date_cancelled is None @property def queue_position(self): if self.event.max_participants is not None: try: return list(self.event.queue).index(self) + 1 except ValueError: pass return 0 @property def is_invited(self): return self.is_registered and self.queue_position == 0
[docs] def is_external(self): return bool(self.name)
[docs] def is_late_cancellation(self): # First check whether or not the user cancelled # If the user cancelled then check if this was after the deadline # And if there is a max participants number: # do a complex check to calculate if this user was on # the waiting list at the time of cancellation, since # you shouldn't need to pay the costs of something # you weren't even able to go to. return ( self.date_cancelled and self.event.cancel_deadline and self.date_cancelled > self.event.cancel_deadline and ( self.event.max_participants is None or self.event.eventregistration_set.filter( ( Q(date_cancelled__gte=self.date_cancelled) | Q(date_cancelled=None) ) & Q(date__lte=self.date) ).count() < self.event.max_participants ) )
[docs] def is_paid(self): return self.payment and self.payment.processed
[docs] def would_cancel_after_deadline(self): now = timezone.now() return self.queue_position == 0 and now >= self.event.cancel_deadline
[docs] def clean(self): if (self.member is None and not self.name) or (self.member and self.name): raise ValidationError( { "member": _("Either specify a member or a name"), "name": _("Either specify a member or a name"), } )
[docs] def validate_unique(self, exclude=None): super().validate_unique(exclude)
[docs] def save(self, *args, **kwargs): super().save(*args, **kwargs) if self.event.start_reminder and self.date_cancelled: self.event.start_reminder.users.remove(self.member) elif ( self.event.start_reminder and self.member is not None and not self.event.start_reminder.users.filter(pk=self.member.pk).exists() ): self.event.start_reminder.users.add(self.member)
def __str__(self): if self.member: return "{}: {}".format(self.member.get_full_name(), self.event) else: return "{}: {}".format(self.name, self.event) @property def payment_amount(self): return self.event.price @property def payment_topic(self): return f'{self.event.title_en} [{date(self.event.start, "Y-m-d")}]' @property def payment_notes(self): notes = f"Event registration {self.event.title_en}. " notes += f"{self.event.start}. " f"Registration date: {self.date}." return notes @property def payment_payer(self): return self.member class Meta: verbose_name = _("Registration") verbose_name_plural = _("Registrations") ordering = ("date",) unique_together = (("member", "event"),)