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"),)