# coding: utf-8 import calendar from django.db import models from django.contrib.auth.models import User from django.template import loader, Context from django.core import mail from django.conf import settings from django.utils import timezone def render_template(template_name, data): tmpl = loader.get_template(template_name) ctxt = Context(data) return tmpl.render(ctxt) class Tirage(models.Model): title = models.CharField("Titre", max_length=300) ouverture = models.DateTimeField("Date et heure d'ouverture du tirage") fermeture = models.DateTimeField("Date et heure de fermerture du tirage") token = models.TextField("Graine du tirage", blank=True) active = models.BooleanField("Tirage actif", default=False) def date_no_seconds(self): return self.fermeture.strftime('%d %b %Y %H:%M') def __unicode__(self): return u"%s - %s" % (self.title, self.date_no_seconds()) class Salle(models.Model): name = models.CharField("Nom", max_length=300) address = models.TextField("Adresse") def __unicode__(self): return self.name class Spectacle(models.Model): title = models.CharField("Titre", max_length=300) date = models.DateTimeField("Date & heure") location = models.ForeignKey(Salle) description = models.TextField("Description", blank=True) slots_description = models.TextField("Description des places", blank=True) price = models.FloatField("Prix d'une place") slots = models.IntegerField("Places") priority = models.IntegerField("Priorité", default=1000) tirage = models.ForeignKey(Tirage) listing = models.BooleanField("Les places sont sur listing") rappel_sent = models.DateTimeField("Mail de rappel envoyé", blank=True, null=True) class Meta: verbose_name = "Spectacle" ordering = ("priority", "date", "title",) def __repr__(self): return u"[%s]" % self.__unicode__() def timestamp(self): return "%d" % calendar.timegm(self.date.utctimetuple()) def date_no_seconds(self): return self.date.strftime('%d %b %Y %H:%M') def __unicode__(self): return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price) def send_rappel(self): # On récupère la liste des participants members = {} for attr in Attribution.objects.filter(spectacle=self).all(): member = attr.participant.user if member.id in members: members[member.id].nb_attr = 2 else: member.nb_attr = 1 members[member.id] = member # On écrit un mail personnalisé à chaque participant mails_to_send = [] mail_object = "%s - %s - %s" % (self.title, self.date_no_seconds(), self.location) for member in members.values(): mail_body = render_template('mail-rappel.txt', { 'member': member, 'show': self}) mail_tot = mail.EmailMessage( mail_object, mail_body, settings.RAPPEL_FROM, [member.email], [], headers={'Reply-To': settings.RAPPEL_REPLY_TO}) mails_to_send.append(mail_tot) # On envoie les mails connection = mail.get_connection() connection.send_messages(mails_to_send) # On enregistre le fait que l'envoi a bien eu lieu self.rappel_sent = timezone.now() self.save() # On renvoie la liste des destinataires return members.values() PAYMENT_TYPES = ( ("cash", u"Cash"), ("cb", "CB"), ("cheque", u"Chèque"), ("autre", u"Autre"), ) class Participant(models.Model): user = models.ForeignKey(User) choices = models.ManyToManyField(Spectacle, through="ChoixSpectacle", related_name="chosen_by") attributions = models.ManyToManyField(Spectacle, through="Attribution", related_name="attributed_to") paid = models.BooleanField(u"A payé", default=False) paymenttype = models.CharField(u"Moyen de paiement", max_length=6, choices=PAYMENT_TYPES, blank=True) tirage = models.ForeignKey(Tirage) def __unicode__(self): return u"%s" % (self.user) DOUBLE_CHOICES = ( ("1", "1 place"), ("autoquit", "2 places si possible, 1 sinon"), ("double", "2 places sinon rien"), ) class ChoixSpectacle(models.Model): participant = models.ForeignKey(Participant) spectacle = models.ForeignKey(Spectacle, related_name="participants") priority = models.PositiveIntegerField("Priorité") double_choice = models.CharField("Nombre de places", default="1", choices=DOUBLE_CHOICES, max_length=10) def get_double(self): return self.double_choice != "1" double = property(get_double) def get_autoquit(self): return self.double_choice == "autoquit" autoquit = property(get_autoquit) class Meta: ordering = ("priority",) unique_together = (("participant", "spectacle",),) verbose_name = "voeu" verbose_name_plural = "voeux" class Attribution(models.Model): participant = models.ForeignKey(Participant) spectacle = models.ForeignKey(Spectacle, related_name="attribues") given = models.BooleanField(u"Donnée", default=False) def __unicode__(self): return u"%s -- %s" % (self.participant, self.spectacle)