kers/events/models.py
redfast00 52b2c31c10
Round amount of interested/admitted people in events
We round this number to avoid people not registering for an event
because the event is at max capacity and they would bump it to an
online event. We don't hide the number entirely in order to not
put off people when there aren't a lot of people interested/admitted.
2021-05-09 02:50:50 +02:00

108 lines
3.1 KiB
Python

from django.db import models
from users.models import CustomUser
class Event(models.Model):
date = models.DateField()
capacity = models.IntegerField(default=6)
note = models.TextField(max_length=1024, default="")
responsible_person = models.ForeignKey(CustomUser, null=True, on_delete=models.SET_NULL)
def __str__(self):
return f"{self.date}"
class TimeSlot(models.Model):
MORNING, AFTERNOON, EVENING = range(3)
TIME_SLOTS = {
MORNING: "voormiddag",
AFTERNOON: "namiddag",
EVENING: "avond",
}
time = models.IntegerField(choices=TIME_SLOTS.items(), default=MORNING)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["time", "event"], name="no_duplicate_timeslots"
),
]
def __str__(self):
return f"{self.event.date} {self.TIME_SLOTS[self.time]}"
def time_str(self):
return TimeSlot.TIME_SLOTS[self.time]
def count_with_status(self, status):
return self.eventregistration_set.filter(state=status).count()
def count_interested(self):
return self.count_with_status(EventRegistration.INTERESTED)
def count_admitted(self):
return self.count_with_status(EventRegistration.ADMITTED)
def precision(self):
# TODO put this in a database field?
return 10
def lower_round(self, n):
return (n // self.precision()) * self.precision()
def upper_round(self, n):
return ((n + self.precision()) // self.precision()) * self.precision()
# Unfortunately, Django doesn't support arguments in templates
def lower_interested(self):
return self.lower_round(self.count_interested())
def upper_interested(self):
return self.upper_round(self.count_interested())
def lower_admitted(self):
return self.lower_round(self.count_admitted())
def upper_admitted(self):
return self.upper_round(self.count_admitted())
def registration_of(self, user):
if not user.is_authenticated:
return None
registrations = self.eventregistration_set.filter(user=user).all()
if not registrations:
return None
assert len(registrations) == 1, "Registrations should be unique per user and timeslot"
return registrations[0]
class EventRegistration(models.Model):
INTERESTED = "I"
ADMITTED = "A"
REGISTRATION_STATE = {
INTERESTED: "op wachtlijst",
ADMITTED: "bevestigd",
}
time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
state = models.CharField(max_length=1, choices=REGISTRATION_STATE.items())
class Meta:
constraints = [
models.UniqueConstraint(
fields=["time_slot", "user"], name="register_only_once_per_timeslot"
),
]
def __str__(self):
return f"Reservation[{self.user.username}:{self.time_slot.event.date}:{self.state}]"
def state_str(self):
return EventRegistration.REGISTRATION_STATE[self.state]