from django.contrib.auth.models import User, Group from django.db import models from django.dispatch import receiver from django.db.models.signals import post_save, post_delete from django.utils.translation import ugettext_lazy as _ from cof.petits_cours_models import choices_length # --- # User management # --- OCCUPATION_CHOICES = ( ('exterieur', _("Extérieur")), ('1A', _("1A")), ('2A', _("2A")), ('3A', _("3A")), ('4A', _("4A")), ('archicube', _("Archicube")), ('doctorant', _("Doctorant")), ('CST', _("CST")), ) class Profile(models.Model): user = models.OneToOneField( User, on_delete=models.CASCADE, related_name="profile", verbose_name=_("utilisateur"), ) login_clipper = models.CharField( _("login clipper"), max_length=8, blank=True, ) phone = models.CharField(_("téléphone"), max_length=20, blank=True) occupation = models.CharField(_("occupation"), default="1A", choices=OCCUPATION_CHOICES, max_length=choices_length( OCCUPATION_CHOICES)) departement = models.CharField(_("département"), max_length=50, blank=True) comments = models.TextField( _("commentaires visibles par l'utilisateur"), blank=True ) class Meta: verbose_name = _("profil") verbose_name_plural = _("profils") def __str__(self): return self.user.username @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.get_or_create(user=instance) @receiver(post_delete, sender=Profile) def post_delete_user(sender, instance, *args, **kwargs): instance.user.delete() class AssociationManager(models.Manager): def get_by_natural_key(self, name): return self.get(name=name) class Association(models.Model): objects = AssociationManager() name = models.CharField( _("nom de l'association"), unique=True, max_length=30 ) staff_group = models.ForeignKey( Group, on_delete=models.PROTECT, related_name="staff_group_of", blank=True, null=True, verbose_name=_("groupe des membres du bureau"), ) members_group = models.ForeignKey( Group, on_delete=models.PROTECT, related_name="member_group_of", blank=True, null=True, verbose_name=_("groupe des membres"), ) def natural_key(self): return self.name class Meta: verbose_name = _("association") verbose_name_plural = _("associations") def __str__(self): return self.name # --- # Clubs # --- class Club(models.Model): ANNUAL = "ANN" SEMESTER = "SEM" COURSE = "COU" COTISATION_FREQUENCY_CHOICES = [ (ANNUAL, _("Annuel")), (SEMESTER, _("Semestriel")), (COURSE, _("Au cours")) ] association = models.ForeignKey( Association, on_delete=models.PROTECT, related_name="clubs", verbose_name=_("association"), ) name = models.CharField(_("nom"), max_length=200, unique=True) description = models.TextField(_("description"), blank=True) members = models.ManyToManyField( User, through="ClubUser", related_name="in_clubs", blank=True, verbose_name=_("membres du club"), ) price = models.DecimalField( _("cotisation (€)"), decimal_places=2, max_digits=5, blank=True, default=0 ) cotisation_frequency = models.CharField( _("fréquence de la cotisation"), default=ANNUAL, choices=COTISATION_FREQUENCY_CHOICES, max_length=3, blank=True ) def __str__(self): template = ( self.price and _("%(name)s (%(price).2f€ / %(cotisation_frequency)s)") or _("%(name)s") ) return template % vars(self) class ClubUser(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) club = models.ForeignKey(Club, on_delete=models.CASCADE) is_respo = models.BooleanField(_("est responsable du club")) has_paid = models.BooleanField(_("a payé sa cotisation")) # --- # Events # --- class Location(models.Model): name = models.CharField(_("nom du lieu"), max_length=200) class Meta: verbose_name = _("lieu") verbose_name_plural = _("lieux") def __str__(self): return self.name class Event(models.Model): associations = models.ManyToManyField( Association, related_name="events", verbose_name=_("associations"), ) title = models.CharField(_("titre"), max_length=200) location = models.ForeignKey( Location, blank=True, null=True, on_delete=models.PROTECT, verbose_name=_("lieux"), ) start_date = models.DateTimeField( _("début de l'événement"), blank=True, null=True, ) end_date = models.DateTimeField( _("fin de l'événement"), blank=True, null=True, ) description = models.TextField(_("description"), blank=True) image = models.ImageField( _("image"), blank=True, null=True, upload_to="public/imgs/events/", ) registration_open = models.NullBooleanField( _("les inscriptions sont ouvertes"), help_text=_("Indéfini signifie « l'inscription n'est pas requise »"), default=True, ) old = models.BooleanField(_("archiver (événement fini)"), default=False) class Meta: verbose_name = _("événement") verbose_name_plural = _("événements") def __str__(self): title, location = self.title, self.location start = self.start_date.date() end = self.end_date.date() if not self.start_date.date(): return "{} @ {}".format(title, location) elif start == end: return "{} @ {} ({})".format(title, location, start) else: return "{} @ {} ({} → {})".format(title, location, start, end) class EventCommentField(models.Model): TEXT = "text" CHAR = "char" FIELD_TYPE = [ (TEXT, _("Texte long")), (CHAR, _("Texte court")), ] event = models.ForeignKey( Event, on_delete=models.CASCADE, related_name="commentfields", verbose_name=_("événement"), ) name = models.CharField(_("nom du champ"), max_length=200) fieldtype = models.CharField( _("type de champ"), max_length=10, choices=FIELD_TYPE, default=TEXT, ) default = models.TextField(_("valeur par défaut"), blank=True) ordering = models.IntegerField( _("ordre des champs"), default=0, help_text=_( "plus petit en premier, ordre alphabétique sur le nom si " "ambiguïté" ), ) class Meta: verbose_name = _("champ") verbose_name_plural = _("champs") def __str__(self): return self.name class EventCommentValue(models.Model): commentfield = models.ForeignKey( EventCommentField, on_delete=models.CASCADE, related_name="values" ) registration = models.ForeignKey( "EventRegistration", on_delete=models.CASCADE, related_name="comments" ) content = models.TextField(_("contenu"), blank=True) class Meta: unique_together = ("commentfield", "registration") def __str__(self): return ( _("Commentaire de %(field_name)s") % {"field_name": self.commentfield} ) class EventOption(models.Model): event = models.ForeignKey( Event, on_delete=models.CASCADE, related_name="options", verbose_name=_("événement"), ) name = models.CharField(_("option"), max_length=200) multi_choices = models.BooleanField(_("choix multiples"), default=False) class Meta: verbose_name = _("option des événements") verbose_name_plural = _("options des événements") def __str__(self): return self.name class EventOptionChoice(models.Model): event_option = models.ForeignKey( EventOption, on_delete=models.CASCADE, related_name="choices", verbose_name=_("événement"), ) value = models.CharField("Valeur", max_length=200) class Meta: verbose_name = _("choix") verbose_name_plural = _("choix") def __str__(self): return self.value class EventRegistration(models.Model): user = models.ForeignKey( User, on_delete=models.SET_NULL, null=True, verbose_name=_("utilisateur"), ) event = models.ForeignKey( Event, on_delete=models.CASCADE, verbose_name=_("événement"), ) options = models.ManyToManyField( EventOptionChoice, verbose_name=_("choix"), ) filledcomments = models.ManyToManyField( EventCommentField, through=EventCommentValue, verbose_name=_("commentaires"), ) paid = models.BooleanField(_("a payé"), default=False) class Meta: verbose_name = _("inscription") verbose_name_plural = _("inscriptions") unique_together = ("user", "event") def __str__(self): return ( _("Inscription de %(user)s à %(event)s") % {"user": self.user, "event": self.event} )