plateforme-tfjm2/apps/tournament/models.py

328 lines
9.4 KiB
Python
Raw Normal View History

2020-04-29 02:06:02 +00:00
import os
2020-05-05 15:12:24 +00:00
from django.core.mail import send_mail
2020-04-29 02:06:02 +00:00
from django.db import models
2020-05-05 15:12:24 +00:00
from django.template.loader import render_to_string
2020-05-04 18:21:53 +00:00
from django.urls import reverse_lazy
2020-05-05 11:54:26 +00:00
from django.utils import timezone
2020-04-29 02:06:02 +00:00
from django.utils.translation import gettext_lazy as _
class Tournament(models.Model):
name = models.CharField(
max_length=255,
verbose_name=_("name"),
)
organizers = models.ManyToManyField(
'member.TFJMUser',
related_name="organized_tournaments",
verbose_name=_("organizers"),
)
size = models.PositiveSmallIntegerField(
verbose_name=_("size"),
)
place = models.CharField(
max_length=255,
verbose_name=_("place"),
)
price = models.PositiveSmallIntegerField(
verbose_name=_("price"),
)
description = models.TextField(
verbose_name=_("description"),
)
date_start = models.DateField(
2020-05-05 11:57:19 +00:00
default=timezone.now,
2020-04-29 02:06:02 +00:00
verbose_name=_("date start"),
)
date_end = models.DateField(
2020-05-05 11:57:19 +00:00
default=timezone.now,
2020-04-29 14:59:59 +00:00
verbose_name=_("date end"),
2020-04-29 02:06:02 +00:00
)
date_inscription = models.DateTimeField(
2020-05-05 11:51:47 +00:00
default=timezone.now,
2020-04-29 02:06:02 +00:00
verbose_name=_("date of registration closing"),
)
date_solutions = models.DateTimeField(
2020-05-05 11:51:47 +00:00
default=timezone.now,
2020-04-29 02:06:02 +00:00
verbose_name=_("date of maximal solution submission"),
)
date_syntheses = models.DateTimeField(
2020-05-05 11:51:47 +00:00
default=timezone.now,
2020-05-05 00:20:45 +00:00
verbose_name=_("date of maximal syntheses submission for the first round"),
)
date_solutions_2 = models.DateTimeField(
2020-05-05 11:51:47 +00:00
default=timezone.now,
2020-05-05 00:20:45 +00:00
verbose_name=_("date when solutions of round 2 are available"),
)
date_syntheses_2 = models.DateTimeField(
2020-05-05 11:51:47 +00:00
default=timezone.now,
2020-05-05 00:20:45 +00:00
verbose_name=_("date of maximal syntheses submission for the second round"),
2020-04-29 02:06:02 +00:00
)
final = models.BooleanField(
verbose_name=_("final tournament"),
)
year = models.PositiveIntegerField(
2020-05-05 11:54:26 +00:00
default=os.getenv("TFJM_YEAR", timezone.now().year),
2020-04-29 13:29:01 +00:00
verbose_name=_("year"),
2020-04-29 02:06:02 +00:00
)
2020-05-05 12:17:06 +00:00
@property
def teams(self):
return self._teams if not self.final else Team.objects.filter(selected_for_final=True)
2020-05-04 22:11:38 +00:00
@property
def linked_organizers(self):
return ['<a href="{url}">'.format(url=reverse_lazy("member:information", args=(user.pk,))) + str(user) + '</a>'
for user in self.organizers.all()]
2020-04-30 18:11:03 +00:00
@property
def solutions(self):
from member.models import Solution
2020-05-04 22:11:38 +00:00
return Solution.objects.filter(final=self.final) if self.final \
else Solution.objects.filter(team__tournament=self)
@property
def syntheses(self):
from member.models import Synthesis
return Synthesis.objects.filter(final=self.final) if self.final \
else Synthesis.objects.filter(team__tournament=self)
2020-04-30 18:11:03 +00:00
2020-04-29 02:06:02 +00:00
@classmethod
def get_final(cls):
return cls.objects.get(year=os.getenv("TFJM_YEAR"), final=True)
class Meta:
verbose_name = _("tournament")
verbose_name_plural = _("tournaments")
2020-05-05 15:23:33 +00:00
def send_mail_to_organizers(self, template_name, subject="Contact TFJM²", **kwargs):
context = kwargs
context["tournament"] = self
for user in self.organizers.all():
context["user"] = user
message = render_to_string("mail_templates/" + template_name + ".txt", context=context)
message_html = render_to_string("mail_templates/" + template_name + ".html", context=context)
send_mail(subject, message, "contact@tfjm.org", [user.email], html_message=message_html)
from member.models import TFJMUser
for user in TFJMUser.objects.get(is_superuser=True).all():
context["user"] = user
message = render_to_string("mail_templates/" + template_name + ".txt", context=context)
message_html = render_to_string("mail_templates/" + template_name + ".html", context=context)
send_mail(subject, message, "contact@tfjm.org", [user.email], html_message=message_html)
2020-04-29 04:52:39 +00:00
def __str__(self):
return self.name
2020-04-29 02:06:02 +00:00
class Team(models.Model):
name = models.CharField(
max_length=255,
verbose_name=_("name"),
)
trigram = models.CharField(
max_length=3,
verbose_name=_("trigram"),
)
tournament = models.ForeignKey(
Tournament,
on_delete=models.PROTECT,
2020-05-05 12:17:06 +00:00
related_name="_teams",
2020-04-29 02:06:02 +00:00
verbose_name=_("tournament"),
)
inscription_date = models.DateTimeField(
auto_now_add=True,
verbose_name=_("inscription date"),
)
validation_status = models.CharField(
max_length=8,
choices=[
2020-04-29 14:26:52 +00:00
("0invalid", _("Registration not validated")),
("1waiting", _("Waiting for validation")),
2020-04-29 14:59:59 +00:00
("2valid", _("Registration validated")),
2020-04-29 02:06:02 +00:00
],
verbose_name=_("validation status"),
)
selected_for_final = models.BooleanField(
default=False,
verbose_name=_("selected for final"),
)
access_code = models.CharField(
max_length=6,
unique=True,
verbose_name=_("access code"),
)
year = models.PositiveIntegerField(
2020-05-05 11:54:26 +00:00
default=os.getenv("TFJM_YEAR", timezone.now().year),
2020-04-29 02:06:02 +00:00
verbose_name=_("year"),
)
2020-04-29 05:39:52 +00:00
@property
def valid(self):
2020-04-29 15:58:11 +00:00
return self.validation_status == "2valid"
2020-04-29 05:39:52 +00:00
@property
def waiting(self):
2020-04-29 15:58:11 +00:00
return self.validation_status == "1waiting"
2020-04-29 05:39:52 +00:00
@property
def invalid(self):
2020-04-29 15:58:11 +00:00
return self.validation_status == "0invalid"
2020-04-29 05:39:52 +00:00
2020-04-29 02:06:02 +00:00
@property
def encadrants(self):
2020-04-29 15:58:11 +00:00
return self.users.all().filter(role="2coach")
2020-04-29 02:06:02 +00:00
2020-05-04 18:21:53 +00:00
@property
def linked_encadrants(self):
return ['<a href="{url}">'.format(url=reverse_lazy("member:information", args=(user.pk,))) + str(user) + '</a>'
for user in self.encadrants]
2020-04-29 02:06:02 +00:00
@property
def participants(self):
2020-04-29 15:58:11 +00:00
return self.users.all().filter(role="3participant")
2020-04-29 02:06:02 +00:00
2020-05-04 18:21:53 +00:00
@property
def linked_participants(self):
return ['<a href="{url}">'.format(url=reverse_lazy("member:information", args=(user.pk,))) + str(user) + '</a>'
for user in self.participants]
2020-05-05 21:19:18 +00:00
@property
def future_tournament(self):
return Tournament.get_final() if self.selected_for_final else self.tournament
2020-05-05 00:20:45 +00:00
@property
def can_validate(self):
# TODO In a normal time, team needs a motivation letter and authorizations.
return self.encadrants.exists() and self.participants.count() >= 4
2020-04-29 02:06:02 +00:00
class Meta:
verbose_name = _("team")
verbose_name_plural = _("teams")
unique_together = (('name', 'year',), ('trigram', 'year',),)
2020-05-05 15:12:24 +00:00
def send_mail(self, template_name, subject="Contact TFJM²", **kwargs):
context = kwargs
context["team"] = self
for user in self.users.all():
context["user"] = user
message = render_to_string("mail_templates/" + template_name + ".txt", context=context)
message_html = render_to_string("mail_templates/" + template_name + ".html", context=context)
send_mail(subject, message, "contact@tfjm.org", [user.email], html_message=message_html)
2020-04-29 04:52:39 +00:00
def __str__(self):
2020-05-05 02:45:38 +00:00
return self.trigram + " -- " + self.name
class Pool(models.Model):
teams = models.ManyToManyField(
Team,
related_name="pools",
verbose_name=_("teams"),
)
solutions = models.ManyToManyField(
"member.Solution",
related_name="pools",
verbose_name=_("solutions"),
)
round = models.PositiveIntegerField(
choices=[
(1, _("Round 1")),
(2, _("Round 2")),
],
verbose_name=_("round"),
)
juries = models.ManyToManyField(
"member.TFJMUser",
related_name="pools",
verbose_name=_("juries"),
)
@property
def problems(self):
return list(d["problem"] for d in self.solutions.values("problem").all())
@property
def tournament(self):
return self.solutions.first().tournament
@property
def syntheses(self):
from member.models import Synthesis
return Synthesis.objects.filter(team__in=self.teams.all(), round=self.round, final=self.tournament.final)
class Meta:
verbose_name = _("pool")
verbose_name_plural = _("pools")
2020-04-29 04:52:39 +00:00
2020-04-29 02:06:02 +00:00
class Payment(models.Model):
user = models.OneToOneField(
'member.TFJMUser',
on_delete=models.CASCADE,
related_name="payment",
verbose_name=_("user"),
)
team = models.ForeignKey(
Team,
on_delete=models.CASCADE,
related_name="payments",
verbose_name=_("team"),
)
method = models.CharField(
max_length=16,
choices=[
("not_paid", _("Not paid")),
("credit_card", _("Credit card")),
("check", _("Bank check")),
("transfer", _("Bank transfer")),
("cash", _("Cash")),
("scholarship", _("Scholarship")),
],
default="not_paid",
verbose_name=_("payment method"),
)
validation_status = models.CharField(
max_length=8,
choices=[
2020-04-29 14:26:52 +00:00
("0invalid", _("Registration not validated")),
("1waiting", _("Waiting for validation")),
("2valid", _("Registration validated")),
2020-04-29 02:06:02 +00:00
],
verbose_name=_("validation status"),
)
2020-04-29 02:51:25 +00:00
class Meta:
verbose_name = _("payment")
verbose_name_plural = _("payments")
2020-04-29 04:52:39 +00:00
def __str__(self):
return _("Payment of {user}").format(str(self.user))