Merge branch 'Elarnon/mail_bda' into 'master'
Améliore les mails automatiques du BdA Les mails du BdA sont maintenant tous chargés depuis des templates gérés par le système de templates de Django, et plus par de l'interpolation de chaîne de caractères. Ceci permet en particulier d'utiliser (et de configurer) la localisation de Django afin d'afficher les dates de façon uniforme (et sans "hack" à la `date_no_seconds`) dans un format comportant un "à" entre le jour et l'heure. See merge request !113
This commit is contained in:
commit
d6dd7b346c
21 changed files with 133 additions and 104 deletions
|
@ -1,16 +1,21 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Gestion en ligne de commande des reventes.
|
||||||
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
from django.core.management import BaseCommand
|
from django.core.management import BaseCommand
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from datetime import timedelta
|
|
||||||
from bda.models import SpectacleRevente
|
from bda.models import SpectacleRevente
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Envoie les mails de notification et effectue " \
|
help = "Envoie les mails de notification et effectue " \
|
||||||
"les tirages au sort des reventes"
|
"les tirages au sort des reventes"
|
||||||
|
leave_locale_alone = True
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
@ -18,21 +23,21 @@ class Command(BaseCommand):
|
||||||
for revente in reventes:
|
for revente in reventes:
|
||||||
# Check si < 24h
|
# Check si < 24h
|
||||||
if (revente.attribution.spectacle.date <=
|
if (revente.attribution.spectacle.date <=
|
||||||
revente.date + timedelta(days=1)) and \
|
revente.date + timedelta(days=1)) and \
|
||||||
now >= revente.date + timedelta(minutes=15) and \
|
now >= revente.date + timedelta(minutes=15) and \
|
||||||
not revente.notif_sent:
|
not revente.notif_sent:
|
||||||
self.stdout.write(str(now))
|
self.stdout.write(str(now))
|
||||||
revente.mail_shotgun()
|
revente.mail_shotgun()
|
||||||
self.stdout.write("Mail de disponibilité immédiate envoyé")
|
self.stdout.write("Mail de disponibilité immédiate envoyé")
|
||||||
# Check si délai de retrait dépassé
|
# Check si délai de retrait dépassé
|
||||||
elif (now >= revente.date + timedelta(hours=1) and
|
elif (now >= revente.date + timedelta(hours=1) and
|
||||||
not revente.notif_sent):
|
not revente.notif_sent):
|
||||||
self.stdout.write(str(now))
|
self.stdout.write(str(now))
|
||||||
revente.send_notif()
|
revente.send_notif()
|
||||||
self.stdout.write("Mail d'inscription à une revente envoyé")
|
self.stdout.write("Mail d'inscription à une revente envoyé")
|
||||||
# Check si tirage à faire
|
# Check si tirage à faire
|
||||||
elif (now >= revente.expiration_time and
|
elif (now >= revente.expiration_time and
|
||||||
not revente.tirage_done):
|
not revente.tirage_done):
|
||||||
self.stdout.write(str(now))
|
self.stdout.write(str(now))
|
||||||
revente.tirage()
|
revente.tirage()
|
||||||
self.stdout.write("Tirage effectué, mails envoyés")
|
self.stdout.write("Tirage effectué, mails envoyés")
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Gestion en ligne de commande des mails de rappel.
|
||||||
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from datetime import timedelta
|
|
||||||
from bda.models import Spectacle
|
from bda.models import Spectacle
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Envoie les mails de rappel des spectacles dont la date ' \
|
help = 'Envoie les mails de rappel des spectacles dont la date ' \
|
||||||
'approche.\nNe renvoie pas les mails déjà envoyés.'
|
'approche.\nNe renvoie pas les mails déjà envoyés.'
|
||||||
|
leave_locale_alone = True
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
|
120
bda/models.py
120
bda/models.py
|
@ -11,19 +11,13 @@ from datetime import timedelta
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.template import loader, Context
|
from django.template import loader
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone, formats
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
|
||||||
|
|
||||||
def render_template(template_name, data):
|
|
||||||
tmpl = loader.get_template(template_name)
|
|
||||||
ctxt = Context(data)
|
|
||||||
return tmpl.render(ctxt)
|
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Tirage(models.Model):
|
class Tirage(models.Model):
|
||||||
title = models.CharField("Titre", max_length=300)
|
title = models.CharField("Titre", max_length=300)
|
||||||
|
@ -34,12 +28,9 @@ class Tirage(models.Model):
|
||||||
enable_do_tirage = models.BooleanField("Le tirage peut être lancé",
|
enable_do_tirage = models.BooleanField("Le tirage peut être lancé",
|
||||||
default=False)
|
default=False)
|
||||||
|
|
||||||
def date_no_seconds(self):
|
|
||||||
return self.fermeture.astimezone(timezone.get_current_timezone()) \
|
|
||||||
.strftime('%d %b %Y %H:%M')
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s" % (self.title, self.date_no_seconds())
|
return "%s - %s" % (self.title, formats.localize(
|
||||||
|
timezone.template_localtime(self.fermeture)))
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
|
@ -89,15 +80,19 @@ class Spectacle(models.Model):
|
||||||
def timestamp(self):
|
def timestamp(self):
|
||||||
return "%d" % calendar.timegm(self.date.utctimetuple())
|
return "%d" % calendar.timegm(self.date.utctimetuple())
|
||||||
|
|
||||||
def date_no_seconds(self):
|
|
||||||
return self.date.astimezone(timezone.get_current_timezone()) \
|
|
||||||
.strftime('%d %b %Y %H:%M')
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(),
|
return "%s - %s, %s, %.02f€" % (
|
||||||
self.location, self.price)
|
self.title,
|
||||||
|
formats.localize(timezone.template_localtime(self.date)),
|
||||||
|
self.location,
|
||||||
|
self.price
|
||||||
|
)
|
||||||
|
|
||||||
def send_rappel(self):
|
def send_rappel(self):
|
||||||
|
"""
|
||||||
|
Envoie un mail de rappel à toutes les personnes qui ont une place pour
|
||||||
|
ce spectacle.
|
||||||
|
"""
|
||||||
# On récupère la liste des participants
|
# On récupère la liste des participants
|
||||||
members = {}
|
members = {}
|
||||||
for attr in Attribution.objects.filter(spectacle=self).all():
|
for attr in Attribution.objects.filter(spectacle=self).all():
|
||||||
|
@ -111,18 +106,17 @@ class Spectacle(models.Model):
|
||||||
members[-1] = ['BdA', 2, 'bda@ens.fr']
|
members[-1] = ['BdA', 2, 'bda@ens.fr']
|
||||||
# On écrit un mail personnalisé à chaque participant
|
# On écrit un mail personnalisé à chaque participant
|
||||||
mails_to_send = []
|
mails_to_send = []
|
||||||
mail_object = "%s - %s - %s" % (self.title, self.date_no_seconds(),
|
mail_object = str(self)
|
||||||
self.location)
|
|
||||||
for member in members.values():
|
for member in members.values():
|
||||||
mail_body = render_template('mail-rappel.txt', {
|
mail_body = loader.render_to_string('bda/mails/rappel.txt', {
|
||||||
'name': member[0],
|
'name': member[0],
|
||||||
'nb_attr': member[1],
|
'nb_attr': member[1],
|
||||||
'show': self})
|
'show': self})
|
||||||
mail_tot = mail.EmailMessage(
|
mail_tot = mail.EmailMessage(
|
||||||
mail_object, mail_body,
|
mail_object, mail_body,
|
||||||
settings.MAIL_DATA['rappels']['FROM'], [member[2]],
|
settings.MAIL_DATA['rappels']['FROM'], [member[2]],
|
||||||
[], headers={
|
[], headers={
|
||||||
'Reply-To': settings.MAIL_DATA['rappels']['REPLYTO']})
|
'Reply-To': settings.MAIL_DATA['rappels']['REPLYTO']})
|
||||||
mails_to_send.append(mail_tot)
|
mails_to_send.append(mail_tot)
|
||||||
# On envoie les mails
|
# On envoie les mails
|
||||||
connection = mail.get_connection()
|
connection = mail.get_connection()
|
||||||
|
@ -274,17 +268,17 @@ class SpectacleRevente(models.Model):
|
||||||
mails_to_send = []
|
mails_to_send = []
|
||||||
mail_object = "%s" % (self.attribution.spectacle)
|
mail_object = "%s" % (self.attribution.spectacle)
|
||||||
for participant in inscrits:
|
for participant in inscrits:
|
||||||
mail_body = render_template('mail-revente.txt', {
|
mail_body = loader.render_to_string('bda/mails/revente.txt', {
|
||||||
'user': participant.user,
|
'user': participant.user,
|
||||||
'spectacle': self.attribution.spectacle,
|
'spectacle': self.attribution.spectacle,
|
||||||
'revente': self,
|
'revente': self,
|
||||||
'domain': Site.objects.get_current().domain})
|
'domain': Site.objects.get_current().domain})
|
||||||
mail_tot = mail.EmailMessage(
|
mail_tot = mail.EmailMessage(
|
||||||
mail_object, mail_body,
|
mail_object, mail_body,
|
||||||
settings.MAIL_DATA['revente']['FROM'],
|
settings.MAIL_DATA['revente']['FROM'],
|
||||||
[participant.user.email],
|
[participant.user.email],
|
||||||
[], headers={
|
[], headers={
|
||||||
'Reply-To': settings.MAIL_DATA['revente']['REPLYTO']})
|
'Reply-To': settings.MAIL_DATA['revente']['REPLYTO']})
|
||||||
mails_to_send.append(mail_tot)
|
mails_to_send.append(mail_tot)
|
||||||
|
|
||||||
connection = mail.get_connection()
|
connection = mail.get_connection()
|
||||||
|
@ -293,22 +287,26 @@ class SpectacleRevente(models.Model):
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def mail_shotgun(self):
|
def mail_shotgun(self):
|
||||||
|
"""
|
||||||
|
Envoie un mail à toutes les personnes intéréssées par le spectacle pour
|
||||||
|
leur indiquer qu'il est désormais disponible au shotgun.
|
||||||
|
"""
|
||||||
inscrits = self.attribution.spectacle.subscribed.select_related('user')
|
inscrits = self.attribution.spectacle.subscribed.select_related('user')
|
||||||
|
|
||||||
mails_to_send = []
|
mails_to_send = []
|
||||||
mail_object = "%s" % (self.attribution.spectacle)
|
mail_object = "%s" % (self.attribution.spectacle)
|
||||||
for participant in inscrits:
|
for participant in inscrits:
|
||||||
mail_body = render_template('mail-shotgun.txt', {
|
mail_body = loader.render_to_string('bda/mails/shotgun.txt', {
|
||||||
'user': participant.user,
|
'user': participant.user,
|
||||||
'spectacle': self.attribution.spectacle,
|
'spectacle': self.attribution.spectacle,
|
||||||
'domain': Site.objects.get_current(),
|
'domain': Site.objects.get_current(),
|
||||||
'mail': self.attribution.participant.user.email})
|
'mail': self.attribution.participant.user.email})
|
||||||
mail_tot = mail.EmailMessage(
|
mail_tot = mail.EmailMessage(
|
||||||
mail_object, mail_body,
|
mail_object, mail_body,
|
||||||
settings.MAIL_DATA['revente']['FROM'],
|
settings.MAIL_DATA['revente']['FROM'],
|
||||||
[participant.user.email],
|
[participant.user.email],
|
||||||
[], headers={
|
[], headers={
|
||||||
'Reply-To': settings.MAIL_DATA['revente']['REPLYTO']})
|
'Reply-To': settings.MAIL_DATA['revente']['REPLYTO']})
|
||||||
mails_to_send.append(mail_tot)
|
mails_to_send.append(mail_tot)
|
||||||
|
|
||||||
connection = mail.get_connection()
|
connection = mail.get_connection()
|
||||||
|
@ -317,6 +315,11 @@ class SpectacleRevente(models.Model):
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def tirage(self):
|
def tirage(self):
|
||||||
|
"""
|
||||||
|
Lance le tirage au sort associé à la revente. Un gagnant est choisi
|
||||||
|
parmis les personnes intéressées par le spectacle. Les personnes sont
|
||||||
|
ensuites prévenues par mail du résultat du tirage.
|
||||||
|
"""
|
||||||
inscrits = list(self.answered_mail.all())
|
inscrits = list(self.answered_mail.all())
|
||||||
spectacle = self.attribution.spectacle
|
spectacle = self.attribution.spectacle
|
||||||
seller = self.seller
|
seller = self.seller
|
||||||
|
@ -334,13 +337,17 @@ class SpectacleRevente(models.Model):
|
||||||
'spectacle': spectacle,
|
'spectacle': spectacle,
|
||||||
}
|
}
|
||||||
mails.append(mail.EmailMessage(
|
mails.append(mail.EmailMessage(
|
||||||
mail_subject, loader.render_to_string('mail-revente-winner.txt', context),
|
mail_subject,
|
||||||
|
loader.render_to_string('bda/mails/revente-winner.txt',
|
||||||
|
context),
|
||||||
from_email=settings.MAIL_DATA['revente']['FROM'],
|
from_email=settings.MAIL_DATA['revente']['FROM'],
|
||||||
to=[winner.user.email],
|
to=[winner.user.email],
|
||||||
reply_to=[seller.user.email],
|
reply_to=[seller.user.email],
|
||||||
))
|
))
|
||||||
mails.append(mail.EmailMessage(
|
mails.append(mail.EmailMessage(
|
||||||
mail_subject, loader.render_to_string('mail-revente-seller.txt', context),
|
mail_subject,
|
||||||
|
loader.render_to_string('bda/mails/revente-seller.txt',
|
||||||
|
context),
|
||||||
from_email=settings.MAIL_DATA['revente']['FROM'],
|
from_email=settings.MAIL_DATA['revente']['FROM'],
|
||||||
to=[seller.user.email],
|
to=[seller.user.email],
|
||||||
reply_to=[winner.user.email],
|
reply_to=[winner.user.email],
|
||||||
|
@ -351,11 +358,12 @@ class SpectacleRevente(models.Model):
|
||||||
if inscrit == winner:
|
if inscrit == winner:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
mail_body = loader.render_to_string('mail-revente-loser.txt', {
|
mail_body = loader.render_to_string(
|
||||||
'acheteur': inscrit.user,
|
'bda/mails/revente-loser.txt',
|
||||||
'vendeur': seller.user,
|
{'acheteur': inscrit.user,
|
||||||
'spectacle': spectacle,
|
'vendeur': seller.user,
|
||||||
})
|
'spectacle': spectacle}
|
||||||
|
)
|
||||||
mails.append(mail.EmailMessage(
|
mails.append(mail.EmailMessage(
|
||||||
mail_subject, mail_body,
|
mail_subject, mail_body,
|
||||||
from_email=settings.MAIL_DATA['revente']['FROM'],
|
from_email=settings.MAIL_DATA['revente']['FROM'],
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
{% for show, members, losers in results %}
|
{% for show, members, losers in results %}
|
||||||
<div class="attribresult">
|
<div class="attribresult">
|
||||||
<h3 class="horizontal-title">{{ show.title }} - {{ show.date_no_seconds }} @ {{ show.location }}</h3>
|
<h3 class="horizontal-title">{{ show.title }} - {{ show.date }} @ {{ show.location }}</h3>
|
||||||
<p>
|
<p>
|
||||||
<strong>{{ show.nrequests }} demandes pour {{ show.slots }} places</strong>
|
<strong>{{ show.nrequests }} demandes pour {{ show.slots }} places</strong>
|
||||||
{{ show.price }}€ par place{% if user.profile.is_buro and show.nrequests < show.slots %}, {{ show.deficit }}€ de déficit{% endif %}
|
{{ show.price }}€ par place{% if user.profile.is_buro and show.nrequests < show.slots %}, {{ show.deficit }}€ de déficit{% endif %}
|
||||||
|
|
6
bda/templates/bda/mails/buy-shotgun.txt
Normal file
6
bda/templates/bda/mails/buy-shotgun.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Bonjour {{ vendeur.first_name }} !
|
||||||
|
|
||||||
|
Je souhaiterais racheter ta place pour {{ spectacle.title }} le {{ spectacle.date }} ({{ spectacle.location }}) à {{ spectacle.price|floatformat:2 }}€.
|
||||||
|
Contacte-moi si tu es toujours intéressé·e !
|
||||||
|
|
||||||
|
{{ acheteur.get_full_name }} ({{ acheteur.email }})
|
|
@ -1,7 +1,7 @@
|
||||||
Bonjour {{ name }},
|
Bonjour {{ name }},
|
||||||
|
|
||||||
Nous te rappellons que tu as eu la chance d'obtenir {{ nb_attr|pluralize:"une place,deux places" }}
|
Nous te rappellons que tu as eu la chance d'obtenir {{ nb_attr|pluralize:"une place,deux places" }}
|
||||||
pour {{ show.title }}, le {{ show.date_no_seconds }} au {{ show.location }}. N'oublie pas de t'y rendre !
|
pour {{ show.title }}, le {{ show.date }} au {{ show.location }}. N'oublie pas de t'y rendre !
|
||||||
{% if nb_attr == 2 %}
|
{% if nb_attr == 2 %}
|
||||||
Tu as obtenu deux places pour ce spectacle. Nous te rappelons que
|
Tu as obtenu deux places pour ce spectacle. Nous te rappelons que
|
||||||
ces places sont strictement réservées aux personnes de moins de 28 ans.
|
ces places sont strictement réservées aux personnes de moins de 28 ans.
|
|
@ -1,6 +1,6 @@
|
||||||
Bonjour {{ acheteur.first_name }},
|
Bonjour {{ acheteur.first_name }},
|
||||||
|
|
||||||
Tu as été tiré-e au sort pour racheter une place pour {{ spectacle.title }} le {{ spectacle.date_no_seconds }} ({{ spectacle.location }}) à {{ spectacle.price|floatformat:2 }}€.
|
Tu as été tiré-e au sort pour racheter une place pour {{ spectacle.title }} le {{ spectacle.date }} ({{ spectacle.location }}) à {{ spectacle.price|floatformat:2 }}€.
|
||||||
Tu peux contacter le/la vendeur-se à l'adresse {{ vendeur.email }}, ou en répondant à ce mail.
|
Tu peux contacter le/la vendeur-se à l'adresse {{ vendeur.email }}, ou en répondant à ce mail.
|
||||||
|
|
||||||
Chaleureusement,
|
Chaleureusement,
|
|
@ -1,6 +1,6 @@
|
||||||
Bonjour {{ user.first_name }}
|
Bonjour {{ user.first_name }}
|
||||||
|
|
||||||
Une place pour le spectacle {{ spectacle.title }} ({{ spectacle.date_no_seconds }})
|
Une place pour le spectacle {{ spectacle.title }} ({{ spectacle.date }})
|
||||||
a été postée sur BdA-Revente.
|
a été postée sur BdA-Revente.
|
||||||
|
|
||||||
Si ce spectacle t'intéresse toujours, merci de nous le signaler en cliquant
|
Si ce spectacle t'intéresse toujours, merci de nous le signaler en cliquant
|
|
@ -1,10 +1,10 @@
|
||||||
Bonjour {{ user.first_name }}
|
Bonjour {{ user.first_name }}
|
||||||
|
|
||||||
Une place pour le spectacle {{ spectacle.title }} ({{ spectacle.date_no_seconds }})
|
Une place pour le spectacle {{ spectacle.title }} ({{ spectacle.date }})
|
||||||
a été postée sur BdA-Revente.
|
a été postée sur BdA-Revente.
|
||||||
|
|
||||||
Puisque ce spectacle a lieu dans moins de 24h, il n'y a pas de tirage au sort pour
|
Puisque ce spectacle a lieu dans moins de 24h, il n'y a pas de tirage au sort pour
|
||||||
cette place : elle est disponible immédiatement à l'addresse
|
cette place : elle est disponible immédiatement à l'adresse
|
||||||
http://{{ domain }}{% url "bda-buy-revente" spectacle.id %}, à la disposition de tous.
|
http://{{ domain }}{% url "bda-buy-revente" spectacle.id %}, à la disposition de tous.
|
||||||
|
|
||||||
Chaleureusement,
|
Chaleureusement,
|
|
@ -18,7 +18,7 @@
|
||||||
{% for spectacle in spectacles %}
|
{% for spectacle in spectacles %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ spectacle.title }}</td>
|
<td>{{ spectacle.title }}</td>
|
||||||
<td data-sort-value="{{ spectacle.timestamp }}">{{ spectacle.date_no_seconds }}</td>
|
<td data-sort-value="{{ spectacle.timestamp }}">{{ spectacle.date }}</td>
|
||||||
<td data-sort-value="{{ spectacle.location }}">{{ spectacle.location }}</td>
|
<td data-sort-value="{{ spectacle.location }}">{{ spectacle.location }}</td>
|
||||||
<td data-sort-value="{{ spectacle.slots }}">{{ spectacle.slots }} places</td>
|
<td data-sort-value="{{ spectacle.slots }}">{{ spectacle.slots }} places</td>
|
||||||
<td data-sort-value="{{ spectacle.total }}">{{ spectacle.total }} demandes</td>
|
<td data-sort-value="{{ spectacle.total }}">{{ spectacle.total }} demandes</td>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{place.spectacle.title}}</td>
|
<td>{{place.spectacle.title}}</td>
|
||||||
<td>{{place.spectacle.location}}</td>
|
<td>{{place.spectacle.location}}</td>
|
||||||
<td>{{place.spectacle.date_no_seconds}}</td>
|
<td>{{place.spectacle.date}}</td>
|
||||||
<td>{% if place.double %}deux places{%else%}une place{% endif %}</td>
|
<td>{% if place.double %}deux places{%else%}une place{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
{% for spectacle in object_list %}
|
{% for spectacle in object_list %}
|
||||||
<tr class="clickable-row" data-href="{% url 'bda-spectacle' tirage_id spectacle.id %}">
|
<tr class="clickable-row" data-href="{% url 'bda-spectacle' tirage_id spectacle.id %}">
|
||||||
<td><a href="{% url 'bda-spectacle' tirage_id spectacle.id %}">{{ spectacle.title }} <span style="font-size:small;" class="glyphicon glyphicon-link" aria-hidden="true"></span></a></td>
|
<td><a href="{% url 'bda-spectacle' tirage_id spectacle.id %}">{{ spectacle.title }} <span style="font-size:small;" class="glyphicon glyphicon-link" aria-hidden="true"></span></a></td>
|
||||||
<td data-sort-value="{{ spectacle.timestamp }}">{{ spectacle.date_no_seconds }}</td>
|
<td data-sort-value="{{ spectacle.timestamp }}">{{ spectacle.date }}</td>
|
||||||
<td data-sort-value="{{ spectacle.location }}">{{ spectacle.location }}</td>
|
<td data-sort-value="{{ spectacle.location }}">{{ spectacle.location }}</td>
|
||||||
<td data-sort-value="{{ spectacle.price |stringformat:".3f" }}">
|
<td data-sort-value="{{ spectacle.price |stringformat:".3f" }}">
|
||||||
{{ spectacle.price |floatformat }}€
|
{{ spectacle.price |floatformat }}€
|
||||||
|
|
21
bda/views.py
21
bda/views.py
|
@ -27,7 +27,7 @@ from datetime import timedelta
|
||||||
|
|
||||||
from gestioncof.decorators import cof_required, buro_required
|
from gestioncof.decorators import cof_required, buro_required
|
||||||
from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\
|
from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\
|
||||||
Tirage, render_template, SpectacleRevente
|
Tirage, SpectacleRevente
|
||||||
from bda.algorithm import Algorithm
|
from bda.algorithm import Algorithm
|
||||||
|
|
||||||
from bda.forms import BaseBdaFormSet, TokenForm, ResellForm, AnnulForm,\
|
from bda.forms import BaseBdaFormSet, TokenForm, ResellForm, AnnulForm,\
|
||||||
|
@ -286,7 +286,7 @@ def revente(request, tirage_id):
|
||||||
revente.seller = participant
|
revente.seller = participant
|
||||||
revente.date = timezone.now()
|
revente.date = timezone.now()
|
||||||
mail_subject = "BdA-Revente : {:s}".format(attribution.spectacle.title)
|
mail_subject = "BdA-Revente : {:s}".format(attribution.spectacle.title)
|
||||||
mail_body = loader.render_to_string('mail-revente-new.txt', {
|
mail_body = loader.render_to_string('bda/mails/revente-new.txt', {
|
||||||
'vendeur': participant.user,
|
'vendeur': participant.user,
|
||||||
'spectacle': attribution.spectacle,
|
'spectacle': attribution.spectacle,
|
||||||
'revente': revente,
|
'revente': revente,
|
||||||
|
@ -453,14 +453,11 @@ def buy_revente(request, spectacle_id):
|
||||||
revente = random.choice(reventes_shotgun)
|
revente = random.choice(reventes_shotgun)
|
||||||
revente.soldTo = participant
|
revente.soldTo = participant
|
||||||
revente.save()
|
revente.save()
|
||||||
mail = """Bonjour !
|
mail = loader.render_to_string('bda/mails/buy-shotgun.txt', {
|
||||||
|
'spectacle': spectacle,
|
||||||
Je souhaiterais racheter ta place pour %s le %s (%s) à %.02f€.
|
'acheteur': request.user,
|
||||||
Contacte-moi si tu es toujours intéressé·e !
|
'vendeur': revente.seller.user,
|
||||||
|
})
|
||||||
%s (%s)""" % (spectacle.title, spectacle.date_no_seconds(),
|
|
||||||
spectacle.location, spectacle.price,
|
|
||||||
request.user.get_full_name(), request.user.email)
|
|
||||||
send_mail("BdA-Revente : %s" % spectacle.title, mail,
|
send_mail("BdA-Revente : %s" % spectacle.title, mail,
|
||||||
request.user.email,
|
request.user.email,
|
||||||
[revente.seller.user.email],
|
[revente.seller.user.email],
|
||||||
|
@ -553,11 +550,11 @@ def send_rappel(request, spectacle_id):
|
||||||
# Mails d'exemples
|
# Mails d'exemples
|
||||||
fake_member = request.user
|
fake_member = request.user
|
||||||
fake_member.nb_attr = 1
|
fake_member.nb_attr = 1
|
||||||
exemple_mail_1place = render_template('mail-rappel.txt', {
|
exemple_mail_1place = loader.render_to_string('bda/mails/rappel.txt', {
|
||||||
'member': fake_member,
|
'member': fake_member,
|
||||||
'show': show})
|
'show': show})
|
||||||
fake_member.nb_attr = 2
|
fake_member.nb_attr = 2
|
||||||
exemple_mail_2places = render_template('mail-rappel.txt', {
|
exemple_mail_2places = loader.render_to_string('bda/mails/rappel.txt', {
|
||||||
'member': fake_member,
|
'member': fake_member,
|
||||||
'show': show})
|
'show': show})
|
||||||
# Contexte
|
# Contexte
|
||||||
|
|
0
cof/locale/__init__.py
Normal file
0
cof/locale/__init__.py
Normal file
0
cof/locale/fr/__init__.py
Normal file
0
cof/locale/fr/__init__.py
Normal file
9
cof/locale/fr/formats.py
Normal file
9
cof/locale/fr/formats.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Formats français.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
DATETIME_FORMAT = r'j F Y \à H:i'
|
|
@ -200,3 +200,5 @@ def show_toolbar(request):
|
||||||
DEBUG_TOOLBAR_CONFIG = {
|
DEBUG_TOOLBAR_CONFIG = {
|
||||||
'SHOW_TOOLBAR_CALLBACK': show_toolbar,
|
'SHOW_TOOLBAR_CALLBACK': show_toolbar,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORMAT_MODULE_PATH = 'cof.locale'
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.contrib.auth.models import User
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.template import loader, Context
|
from django.template import loader
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.db.models import Min
|
from django.db.models import Min
|
||||||
|
@ -33,12 +33,6 @@ import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def render_template(template_path, data):
|
|
||||||
tmpl = loader.get_template(template_path)
|
|
||||||
context = Context(data)
|
|
||||||
return tmpl.render(context)
|
|
||||||
|
|
||||||
|
|
||||||
class DemandeListView(ListView):
|
class DemandeListView(ListView):
|
||||||
model = PetitCoursDemande
|
model = PetitCoursDemande
|
||||||
template_name = "petits_cours_demandes_list.html"
|
template_name = "petits_cours_demandes_list.html"
|
||||||
|
@ -137,14 +131,14 @@ def _finalize_traitement(request, demande, proposals, proposed_for,
|
||||||
proposed_for = proposed_for.items()
|
proposed_for = proposed_for.items()
|
||||||
attribdata = list(attribdata.items())
|
attribdata = list(attribdata.items())
|
||||||
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
||||||
mainmail = render_template("petits-cours-mail-demandeur.txt",
|
mainmail = loader.render_to_string("petits-cours-mail-demandeur.txt", {
|
||||||
{"proposals": proposals,
|
"proposals": proposals,
|
||||||
"unsatisfied": unsatisfied,
|
"unsatisfied": unsatisfied,
|
||||||
"extra":
|
"extra":
|
||||||
'<textarea name="extra" '
|
'<textarea name="extra" '
|
||||||
'style="width:99%; height: 90px;">'
|
'style="width:99%; height: 90px;">'
|
||||||
'</textarea>'
|
'</textarea>'
|
||||||
})
|
})
|
||||||
return render(request, "traitement_demande_petit_cours.html",
|
return render(request, "traitement_demande_petit_cours.html",
|
||||||
{"demande": demande,
|
{"demande": demande,
|
||||||
"unsatisfied": unsatisfied,
|
"unsatisfied": unsatisfied,
|
||||||
|
@ -163,8 +157,10 @@ def _finalize_traitement(request, demande, proposals, proposed_for,
|
||||||
def _generate_eleve_email(demande, proposed_for):
|
def _generate_eleve_email(demande, proposed_for):
|
||||||
proposed_mails = []
|
proposed_mails = []
|
||||||
for user, matieres in proposed_for:
|
for user, matieres in proposed_for:
|
||||||
msg = render_template("petits-cours-mail-eleve.txt",
|
msg = loader.render_to_string("petits-cours-mail-eleve.txt", {
|
||||||
{"demande": demande, "matieres": matieres})
|
"demande": demande,
|
||||||
|
"matieres": matieres
|
||||||
|
})
|
||||||
proposed_mails.append((user, msg))
|
proposed_mails.append((user, msg))
|
||||||
return proposed_mails
|
return proposed_mails
|
||||||
|
|
||||||
|
@ -278,10 +274,11 @@ def _traitement_post(request, demande):
|
||||||
proposals_list = proposals.items()
|
proposals_list = proposals.items()
|
||||||
proposed_for = proposed_for.items()
|
proposed_for = proposed_for.items()
|
||||||
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
||||||
mainmail = render_template("petits-cours-mail-demandeur.txt",
|
mainmail = loader.render_to_string("petits-cours-mail-demandeur.txt", {
|
||||||
{"proposals": proposals_list,
|
"proposals": proposals_list,
|
||||||
"unsatisfied": unsatisfied,
|
"unsatisfied": unsatisfied,
|
||||||
"extra": extra})
|
"extra": extra,
|
||||||
|
})
|
||||||
frommail = settings.MAIL_DATA['petits_cours']['FROM']
|
frommail = settings.MAIL_DATA['petits_cours']['FROM']
|
||||||
bccaddress = settings.MAIL_DATA['petits_cours']['BCC']
|
bccaddress = settings.MAIL_DATA['petits_cours']['BCC']
|
||||||
replyto = settings.MAIL_DATA['petits_cours']['REPLYTO']
|
replyto = settings.MAIL_DATA['petits_cours']['REPLYTO']
|
||||||
|
|
Loading…
Reference in a new issue