import os from datetime import date from django.contrib.auth.models import AbstractUser from django.db import models from django.utils.translation import gettext_lazy as _ from polymorphic.models import PolymorphicModel from tournament.models import Team, Tournament class TFJMUser(AbstractUser): USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] email = models.EmailField( unique=True, verbose_name=_("email"), ) team = models.ForeignKey( Team, null=True, on_delete=models.SET_NULL, related_name="users", verbose_name=_("team"), ) birth_date = models.DateField( null=True, default=None, verbose_name=_("birth date"), ) gender = models.CharField( max_length=16, null=True, default=None, choices=[ ("male", _("Male")), ("female", _("Female")), ("non-binary", _("Non binary")), ], verbose_name=_("gender"), ) address = models.CharField( max_length=255, null=True, default=None, verbose_name=_("address"), ) postal_code = models.PositiveIntegerField( null=True, default=None, verbose_name=_("postal code"), ) city = models.CharField( max_length=255, null=True, default=None, verbose_name=_("city"), ) country = models.CharField( max_length=255, default="France", null=True, verbose_name=_("country"), ) phone_number = models.CharField( max_length=20, null=True, blank=True, default=None, verbose_name=_("phone number"), ) school = models.CharField( max_length=255, null=True, default=None, verbose_name=_("school"), ) student_class = models.CharField( max_length=16, choices=[ ('seconde', _("Seconde or less")), ('première', _("Première")), ('terminale', _("Terminale")), ], null=True, default=None, verbose_name="class", ) responsible_name = models.CharField( max_length=255, null=True, default=None, verbose_name=_("responsible name"), ) responsible_phone = models.CharField( max_length=20, null=True, default=None, verbose_name=_("responsible phone"), ) responsible_email = models.EmailField( null=True, default=None, verbose_name=_("responsible email"), ) description = models.TextField( null=True, default=None, verbose_name=_("description"), ) role = models.CharField( max_length=16, choices=[ ("0admin", _("Admin")), ("1volunteer", _("Organizer")), ("2coach", _("Coach")), ("3participant", _("Participant")), ] ) year = models.PositiveIntegerField( default=os.getenv("TFJM_YEAR", date.today().year), verbose_name=_("year"), ) @property def participates(self): return self.role == "3participant" or self.role == "2coach" @property def organizes(self): return self.role == "1volunteer" or self.role == "0admin" @property def admin(self): return self.role == "0admin" class Meta: verbose_name = _("user") verbose_name_plural = _("users") def save(self, *args, **kwargs): self.username = self.email super().save(*args, **kwargs) def __str__(self): return self.first_name + " " + self.last_name class Document(PolymorphicModel): file = models.FileField( unique=True, verbose_name=_("file"), ) uploaded_at = models.DateTimeField( auto_now_add=True, verbose_name=_("uploaded at"), ) class Meta: verbose_name = _("document") verbose_name_plural = _("documents") def delete(self, *args, **kwargs): self.file.delete(True) return super().delete(*args, **kwargs) class Authorization(Document): user = models.ForeignKey( TFJMUser, on_delete=models.CASCADE, related_name="authorizations", verbose_name=_("user"), ) type = models.CharField( max_length=32, choices=[ ("parental_consent", _("Parental consent")), ("photo_consent", _("Photo consent")), ("sanitary_plug", _("Sanitary plug")), ("scholarship", _("Scholarship")), ], verbose_name=_("type"), ) class Meta: verbose_name = _("authorization") verbose_name_plural = _("authorizations") def __str__(self): return _("{authorization} for user {user}").format(authorization=self.type, user=str(self.user)) class MotivationLetter(Document): team = models.ForeignKey( Team, on_delete=models.CASCADE, related_name="motivation_letters", verbose_name=_("team"), ) class Meta: verbose_name = _("motivation letter") verbose_name_plural = _("motivation letters") def __str__(self): return _("Motivation letter of team {team} ({trigram})").format(team=self.team.name, trigram=self.team.trigram) class Solution(Document): team = models.ForeignKey( Team, on_delete=models.CASCADE, related_name="solutions", verbose_name=_("team"), ) problem = models.PositiveSmallIntegerField( verbose_name=_("problem"), ) final = models.BooleanField( default=False, verbose_name=_("final solution"), ) @property def tournament(self): return Tournament.get_final() if self.final else self.team.tournament class Meta: verbose_name = _("solution") verbose_name_plural = _("solutions") unique_together = ('team', 'problem', 'final',) def __str__(self): return _("Solution of team {trigram} for problem {problem}")\ .format(trigram=self.team.trigram, problem=self.problem) class Synthesis(Document): team = models.ForeignKey( Team, on_delete=models.CASCADE, related_name="syntheses", verbose_name=_("team"), ) source = models.CharField( max_length=16, choices=[ ("opponent", _("Opponent")), ("rapporteur", _("Rapporteur")), ], verbose_name=_("source"), ) round = models.PositiveSmallIntegerField( choices=[ (1, _("Round 1")), (2, _("Round 2")), ], verbose_name=_("round"), ) final = models.BooleanField( default=False, verbose_name=_("final synthesis"), ) @property def tournament(self): return Tournament.get_final() if self.final else self.team.tournament class Meta: verbose_name = _("synthesis") verbose_name_plural = _("syntheses") unique_together = ('team', 'source', 'round', 'final',) def __str__(self): return _("Synthesis of team {trigram} that is {source} for the round {round} of tournament {tournament}")\ .format(trigram=self.team.trigram, source=self.get_source_display().lower(), tournament=self.tournament) class Config(models.Model): key = models.CharField( max_length=255, primary_key=True, verbose_name=_("key"), ) value = models.TextField( default="", verbose_name=_("value"), ) class Meta: verbose_name = _("configuration") verbose_name_plural = _("configurations")