forked from DGNum/gestioCOF
Merge branch 'Aufinal/rip-custommail' into 'master'
Supprime `custommail` de gestioCOF Closes #227 See merge request klub-dev-ens/gestioCOF!459
This commit is contained in:
commit
600927b21c
29 changed files with 327 additions and 755 deletions
21
bda/admin.py
21
bda/admin.py
|
@ -1,10 +1,11 @@
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from custommail.shortcuts import send_mass_custom_mail
|
|
||||||
from dal.autocomplete import ModelSelect2
|
from dal.autocomplete import ModelSelect2
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.core.mail import send_mass_mail
|
||||||
from django.db.models import Count, Q, Sum
|
from django.db.models import Count, Q, Sum
|
||||||
|
from django.template import loader
|
||||||
from django.template.defaultfilters import pluralize
|
from django.template.defaultfilters import pluralize
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
@ -169,19 +170,23 @@ class ParticipantAdmin(ReadOnlyMixin, admin.ModelAdmin):
|
||||||
form = ParticipantAdminForm
|
form = ParticipantAdminForm
|
||||||
|
|
||||||
def send_attribs(self, request, queryset):
|
def send_attribs(self, request, queryset):
|
||||||
datatuple = []
|
emails = []
|
||||||
for member in queryset.all():
|
for member in queryset.all():
|
||||||
|
subject = "Résultats du tirage au sort"
|
||||||
attribs = member.attributions.all()
|
attribs = member.attributions.all()
|
||||||
context = {"member": member.user}
|
context = {"member": member.user}
|
||||||
shortname = ""
|
|
||||||
|
template_name = ""
|
||||||
if len(attribs) == 0:
|
if len(attribs) == 0:
|
||||||
shortname = "bda-attributions-decus"
|
template_name = "bda/mails/attributions-decus.txt"
|
||||||
else:
|
else:
|
||||||
shortname = "bda-attributions"
|
template_name = "bda/mails/attributions.txt"
|
||||||
context["places"] = attribs
|
context["places"] = attribs
|
||||||
print(context)
|
|
||||||
datatuple.append((shortname, context, "bda@ens.fr", [member.user.email]))
|
message = loader.render_to_string(template_name, context)
|
||||||
send_mass_custom_mail(datatuple)
|
emails.append((subject, message, "bda@ens.fr", [member.user.email]))
|
||||||
|
|
||||||
|
send_mass_mail(emails)
|
||||||
count = len(queryset.all())
|
count = len(queryset.all())
|
||||||
if count == 1:
|
if count == 1:
|
||||||
message_bit = "1 membre a"
|
message_bit = "1 membre a"
|
||||||
|
|
|
@ -2,14 +2,14 @@ import calendar
|
||||||
import random
|
import random
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from custommail.models import CustomMail
|
|
||||||
from custommail.shortcuts import send_mass_custom_mail
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
|
from django.core.mail import EmailMessage, send_mass_mail
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Count, Exists
|
from django.db.models import Count, Exists
|
||||||
|
from django.template import loader
|
||||||
from django.utils import formats, timezone
|
from django.utils import formats, timezone
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,16 +116,19 @@ class Spectacle(models.Model):
|
||||||
bda_generic.nb_attr = 1
|
bda_generic.nb_attr = 1
|
||||||
members.append(bda_generic)
|
members.append(bda_generic)
|
||||||
# On écrit un mail personnalisé à chaque participant
|
# On écrit un mail personnalisé à chaque participant
|
||||||
datatuple = [
|
mails = [
|
||||||
(
|
(
|
||||||
"bda-rappel",
|
str(self),
|
||||||
{"member": member, "nb_attr": member.nb_attr, "show": self},
|
loader.render_to_string(
|
||||||
|
"bda/mails/rappel.txt",
|
||||||
|
context={"member": member, "nb_attr": member.nb_attr, "show": self},
|
||||||
|
),
|
||||||
settings.MAIL_DATA["rappels"]["FROM"],
|
settings.MAIL_DATA["rappels"]["FROM"],
|
||||||
[member.email],
|
[member.email],
|
||||||
)
|
)
|
||||||
for member in members
|
for member in members
|
||||||
]
|
]
|
||||||
send_mass_custom_mail(datatuple)
|
send_mass_mail(mails)
|
||||||
# On enregistre le fait que l'envoi a bien eu lieu
|
# On enregistre le fait que l'envoi a bien eu lieu
|
||||||
self.rappel_sent = timezone.now()
|
self.rappel_sent = timezone.now()
|
||||||
self.save()
|
self.save()
|
||||||
|
@ -348,21 +351,24 @@ class SpectacleRevente(models.Model):
|
||||||
BdA-Revente à tous les intéressés.
|
BdA-Revente à tous les intéressés.
|
||||||
"""
|
"""
|
||||||
inscrits = self.attribution.spectacle.subscribed.select_related("user")
|
inscrits = self.attribution.spectacle.subscribed.select_related("user")
|
||||||
datatuple = [
|
mails = [
|
||||||
(
|
(
|
||||||
"bda-revente",
|
"BdA-Revente : {}".format(self.attribution.spectacle.title),
|
||||||
{
|
loader.render_to_string(
|
||||||
"member": participant.user,
|
"bda/mails/revente-new.txt",
|
||||||
"show": self.attribution.spectacle,
|
context={
|
||||||
"revente": self,
|
"member": participant.user,
|
||||||
"site": Site.objects.get_current(),
|
"show": self.attribution.spectacle,
|
||||||
},
|
"revente": self,
|
||||||
|
"site": Site.objects.get_current(),
|
||||||
|
},
|
||||||
|
),
|
||||||
settings.MAIL_DATA["revente"]["FROM"],
|
settings.MAIL_DATA["revente"]["FROM"],
|
||||||
[participant.user.email],
|
[participant.user.email],
|
||||||
)
|
)
|
||||||
for participant in inscrits
|
for participant in inscrits
|
||||||
]
|
]
|
||||||
send_mass_custom_mail(datatuple)
|
send_mass_mail(mails)
|
||||||
self.notif_sent = True
|
self.notif_sent = True
|
||||||
self.notif_time = timezone.now()
|
self.notif_time = timezone.now()
|
||||||
self.save()
|
self.save()
|
||||||
|
@ -373,20 +379,23 @@ class SpectacleRevente(models.Model):
|
||||||
leur indiquer qu'il est désormais disponible au shotgun.
|
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")
|
||||||
datatuple = [
|
mails = [
|
||||||
(
|
(
|
||||||
"bda-shotgun",
|
"BdA-Revente : {}".format(self.attribution.spectacle.title),
|
||||||
{
|
loader.render_to_string(
|
||||||
"member": participant.user,
|
"bda/mails/revente-shotgun.txt",
|
||||||
"show": self.attribution.spectacle,
|
context={
|
||||||
"site": Site.objects.get_current(),
|
"member": participant.user,
|
||||||
},
|
"show": self.attribution.spectacle,
|
||||||
|
"site": Site.objects.get_current(),
|
||||||
|
},
|
||||||
|
),
|
||||||
settings.MAIL_DATA["revente"]["FROM"],
|
settings.MAIL_DATA["revente"]["FROM"],
|
||||||
[participant.user.email],
|
[participant.user.email],
|
||||||
)
|
)
|
||||||
for participant in inscrits
|
for participant in inscrits
|
||||||
]
|
]
|
||||||
send_mass_custom_mail(datatuple)
|
send_mass_mail(mails)
|
||||||
self.notif_sent = True
|
self.notif_sent = True
|
||||||
self.notif_time = timezone.now()
|
self.notif_time = timezone.now()
|
||||||
# Flag inutile, sauf si l'horloge interne merde
|
# Flag inutile, sauf si l'horloge interne merde
|
||||||
|
@ -418,31 +427,30 @@ class SpectacleRevente(models.Model):
|
||||||
"show": spectacle,
|
"show": spectacle,
|
||||||
}
|
}
|
||||||
|
|
||||||
c_mails_qs = CustomMail.objects.filter(
|
subject = "BdA-Revente : {}".format(spectacle.title)
|
||||||
shortname__in=[
|
|
||||||
"bda-revente-winner",
|
|
||||||
"bda-revente-loser",
|
|
||||||
"bda-revente-seller",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
c_mails = {cm.shortname: cm for cm in c_mails_qs}
|
|
||||||
|
|
||||||
mails.append(
|
mails.append(
|
||||||
c_mails["bda-revente-winner"].get_message(
|
EmailMessage(
|
||||||
context,
|
subject=subject,
|
||||||
|
body=loader.render_to_string(
|
||||||
|
"bda/mails/revente-tirage-winner.txt",
|
||||||
|
context=context,
|
||||||
|
),
|
||||||
from_email=settings.MAIL_DATA["revente"]["FROM"],
|
from_email=settings.MAIL_DATA["revente"]["FROM"],
|
||||||
to=[winner.user.email],
|
to=[winner.user.email],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
mails.append(
|
mails.append(
|
||||||
c_mails["bda-revente-seller"].get_message(
|
EmailMessage(
|
||||||
context,
|
subject=subject,
|
||||||
|
body=loader.render_to_string(
|
||||||
|
"bda/mails/revente-tirage-seller.txt",
|
||||||
|
context=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],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Envoie un mail aux perdants
|
# Envoie un mail aux perdants
|
||||||
|
@ -452,11 +460,15 @@ class SpectacleRevente(models.Model):
|
||||||
new_context["acheteur"] = inscrit.user
|
new_context["acheteur"] = inscrit.user
|
||||||
|
|
||||||
mails.append(
|
mails.append(
|
||||||
c_mails["bda-revente-loser"].get_message(
|
EmailMessage(
|
||||||
new_context,
|
subject=subject,
|
||||||
|
body=loader.render_to_string(
|
||||||
|
"bda/mails/revente-tirage-loser.txt",
|
||||||
|
context=new_context,
|
||||||
|
),
|
||||||
from_email=settings.MAIL_DATA["revente"]["FROM"],
|
from_email=settings.MAIL_DATA["revente"]["FROM"],
|
||||||
to=[inscrit.user.email],
|
to=[inscrit.user.email],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
mail_conn = mail.get_connection()
|
mail_conn = mail.get_connection()
|
||||||
|
|
|
@ -26,13 +26,6 @@
|
||||||
|
|
||||||
<hr \>
|
<hr \>
|
||||||
|
|
||||||
<p>
|
|
||||||
<em>Note :</em> le template de ce mail peut être modifié à
|
|
||||||
<a href="{% url 'admin:custommail_custommail_change' custommail.pk %}">cette adresse</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr \>
|
|
||||||
|
|
||||||
<h3>Forme des mails</h3>
|
<h3>Forme des mails</h3>
|
||||||
|
|
||||||
<h4>Une seule place</h4>
|
<h4>Une seule place</h4>
|
||||||
|
|
10
bda/templates/bda/mails/attributions-decus.txt
Normal file
10
bda/templates/bda/mails/attributions-decus.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Cher-e {{ member.first_name }},
|
||||||
|
|
||||||
|
Tu t'es inscrit-e pour le tirage au sort du BdA. Malheureusement, tu n'as
|
||||||
|
obtenu aucune place.
|
||||||
|
|
||||||
|
Nous proposons cependant de nombreuses offres hors-tirage tout au long de
|
||||||
|
l'année, et nous t'invitons à nous contacter si l'une d'entre elles
|
||||||
|
t'intéresse !
|
||||||
|
--
|
||||||
|
Le Bureau des Arts
|
31
bda/templates/bda/mails/attributions.txt
Normal file
31
bda/templates/bda/mails/attributions.txt
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
Cher-e {{ member.first_name }},
|
||||||
|
|
||||||
|
Tu t'es inscrit-e pour le tirage au sort du BdA. Tu as été sélectionné-e
|
||||||
|
pour les spectacles suivants :
|
||||||
|
{% for place in places %}
|
||||||
|
- 1 place pour {{ place }}{% endfor %}
|
||||||
|
|
||||||
|
*Paiement*
|
||||||
|
L'intégralité de ces places de spectacles est à régler dès maintenant et AVANT
|
||||||
|
vendredi prochain, au bureau du COF pendant les heures de permanences (du lundi au vendredi
|
||||||
|
entre 12h et 14h, et entre 18h et 20h). Des facilités de paiement sont bien
|
||||||
|
évidemment possibles : nous pouvons ne pas encaisser le chèque immédiatement,
|
||||||
|
ou bien découper votre paiement en deux fois. Pour ceux qui ne pourraient pas
|
||||||
|
venir payer au bureau, merci de nous contacter par mail.
|
||||||
|
|
||||||
|
*Mode de retrait des places*
|
||||||
|
Au moment du paiement, certaines places vous seront remises directement,
|
||||||
|
d'autres seront à récupérer au cours de l'année, d'autres encore seront
|
||||||
|
nominatives et à retirer le soir même dans les théâtres correspondants.
|
||||||
|
Pour chaque spectacle, vous recevrez un mail quelques jours avant la
|
||||||
|
représentation vous indiquant le mode de retrait.
|
||||||
|
|
||||||
|
Nous vous rappelons que l'obtention de places du BdA vous engage à
|
||||||
|
respecter les règles de fonctionnement :
|
||||||
|
https://bda.ens.fr/lequipe/charte-bda/
|
||||||
|
Un système de revente des places via les mails BdA-revente est disponible
|
||||||
|
directement sur votre compte GestioCOF.
|
||||||
|
|
||||||
|
En vous souhaitant de très beaux spectacles tout au long de l'année,
|
||||||
|
--
|
||||||
|
Le Bureau des Arts
|
23
bda/templates/bda/mails/rappel.txt
Normal file
23
bda/templates/bda/mails/rappel.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Bonjour {{ member.first_name }},
|
||||||
|
|
||||||
|
Nous te rappellons que tu as eu la chance d'obtenir {{ nb_attr|pluralize:"une place,deux places" }}
|
||||||
|
pour {{ show.title }}, le {{ show.date }} au {{ show.location }}. N'oublie pas de t'y rendre !
|
||||||
|
{% if nb_attr == 2 %}
|
||||||
|
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.
|
||||||
|
{% endif %}
|
||||||
|
{% if show.listing %}Pour ce spectacle, tu as reçu {{ nb_attr|pluralize:"une place,des places" }} sur
|
||||||
|
listing. Il te faudra donc te rendre 15 minutes en avance sur les lieux de la représentation
|
||||||
|
pour {{ nb_attr|pluralize:"la,les" }} retirer.
|
||||||
|
{% else %}Pour assister à ce spectacle, tu dois présenter les billets qui ont
|
||||||
|
été distribués au burô.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Si tu ne peux plus assister à cette représentation, tu peux
|
||||||
|
revendre ta place via BdA-revente, accessible directement sur
|
||||||
|
GestioCOF (lien "revendre une place du premier tirage" sur la page
|
||||||
|
d'accueil https://www.cof.ens.fr/gestion/).
|
||||||
|
|
||||||
|
En te souhaitant un excellent spectacle,
|
||||||
|
--
|
||||||
|
Le Bureau des Arts
|
12
bda/templates/bda/mails/revente-new.txt
Normal file
12
bda/templates/bda/mails/revente-new.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Bonjour {{ member.first_name }}
|
||||||
|
|
||||||
|
Une place pour le spectacle {{ show.title }} ({{ show.date }})
|
||||||
|
a été postée sur BdA-Revente.
|
||||||
|
|
||||||
|
Si ce spectacle t'intéresse toujours, merci de nous le signaler en cliquant
|
||||||
|
sur ce lien : https://{{ site }}{% url "bda-revente-confirm" revente.id %}.
|
||||||
|
Dans le cas où plusieurs personnes seraient intéressées, nous procèderons à
|
||||||
|
un tirage au sort le {{ revente.date_tirage|date:"DATE_FORMAT" }}.
|
||||||
|
|
||||||
|
Chaleureusement,
|
||||||
|
Le BdA
|
13
bda/templates/bda/mails/revente-seller.txt
Normal file
13
bda/templates/bda/mails/revente-seller.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Bonjour {{ vendeur.first_name }},
|
||||||
|
|
||||||
|
Tu t’es bien inscrit·e pour revendre une place pour {{ show.title }}.
|
||||||
|
|
||||||
|
{% with revente.date_tirage as time %}
|
||||||
|
Le tirage au sort entre tout·e·s les racheteuse·eur·s potentiel·le·s aura lieu
|
||||||
|
le {{ time|date:"DATE_FORMAT" }} à {{ time|time:"TIME_FORMAT" }} (dans {{time|timeuntil }}).
|
||||||
|
Si personne ne s’est inscrit pour racheter la place, celle-ci apparaîtra parmi
|
||||||
|
les « Places disponibles immédiatement à la revente » sur GestioCOF.
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
Bonne revente !
|
||||||
|
Le Bureau des Arts
|
6
bda/templates/bda/mails/revente-shotgun-seller.txt
Normal file
6
bda/templates/bda/mails/revente-shotgun-seller.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Bonjour {{ vendeur.first_name }} !
|
||||||
|
|
||||||
|
Je souhaiterais racheter ta place pour {{ show.title }} le {{ show.date }} ({{ show.location }}) à {{ show.price|floatformat:2 }}€.
|
||||||
|
Contacte-moi si tu es toujours intéressé·e !
|
||||||
|
|
||||||
|
{{ acheteur.get_full_name }} ({{ acheteur.email }})
|
11
bda/templates/bda/mails/revente-shotgun.txt
Normal file
11
bda/templates/bda/mails/revente-shotgun.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Bonjour {{ member.first_name }}
|
||||||
|
|
||||||
|
Une place pour le spectacle {{ show.title }} ({{ show.date }})
|
||||||
|
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
|
||||||
|
cette place : elle est disponible immédiatement à l'adresse
|
||||||
|
https://{{ site }}{% url "bda-revente-buy" show.id %}, à la disposition de tous.
|
||||||
|
|
||||||
|
Chaleureusement,
|
||||||
|
Le BdA
|
9
bda/templates/bda/mails/revente-tirage-loser.txt
Normal file
9
bda/templates/bda/mails/revente-tirage-loser.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Bonjour {{ acheteur.first_name }},
|
||||||
|
|
||||||
|
Tu t'étais inscrit·e pour la revente de la place de {{ vendeur.get_full_name }}
|
||||||
|
pour {{ show.title }}.
|
||||||
|
Malheureusement, une autre personne a été tirée au sort pour racheter la place.
|
||||||
|
Tu pourras certainement retenter ta chance pour une autre revente !
|
||||||
|
|
||||||
|
À très bientôt,
|
||||||
|
Le Bureau des Arts
|
7
bda/templates/bda/mails/revente-tirage-seller.txt
Normal file
7
bda/templates/bda/mails/revente-tirage-seller.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Bonjour {{ vendeur.first_name }},
|
||||||
|
|
||||||
|
La personne tirée au sort pour racheter ta place pour {{ show.title }} est {{ acheteur.get_full_name }}.
|
||||||
|
Tu peux le/la contacter à l'adresse {{ acheteur.email }}, ou en répondant à ce mail.
|
||||||
|
|
||||||
|
Chaleureusement,
|
||||||
|
Le BdA
|
7
bda/templates/bda/mails/revente-tirage-winner.txt
Normal file
7
bda/templates/bda/mails/revente-tirage-winner.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Bonjour {{ acheteur.first_name }},
|
||||||
|
|
||||||
|
Tu as été tiré·e au sort pour racheter une place pour {{ show.title }} le {{ show.date }} ({{ show.location }}) à {{ show.price|floatformat:2 }}€.
|
||||||
|
Tu peux contacter le/la vendeur·se à l'adresse {{ vendeur.email }}.
|
||||||
|
|
||||||
|
Chaleureusement,
|
||||||
|
Le BdA
|
|
@ -1,7 +1,3 @@
|
||||||
import os
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.management import call_command
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from shared.tests.mixins import ViewTestCaseMixin
|
from shared.tests.mixins import ViewTestCaseMixin
|
||||||
|
@ -28,12 +24,6 @@ class BdATestHelpers:
|
||||||
if self.bda_testdata:
|
if self.bda_testdata:
|
||||||
self.load_bda_testdata()
|
self.load_bda_testdata()
|
||||||
|
|
||||||
def require_custommails(self):
|
|
||||||
data_file = os.path.join(
|
|
||||||
settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json"
|
|
||||||
)
|
|
||||||
call_command("syncmails", data_file, verbosity=0)
|
|
||||||
|
|
||||||
def load_bda_testdata(self):
|
def load_bda_testdata(self):
|
||||||
self.tirage = Tirage.objects.create(
|
self.tirage = Tirage.objects.create(
|
||||||
title="Test tirage",
|
title="Test tirage",
|
||||||
|
|
|
@ -19,8 +19,6 @@ User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
class SpectacleReventeTests(TestCase):
|
class SpectacleReventeTests(TestCase):
|
||||||
fixtures = ["gestioncof/management/data/custommail.json"]
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,6 @@ class SendRemindersViewTestCase(BdATestHelpers, BdAViewTestCaseMixin, TestCase):
|
||||||
return "/gestion/bda/mails-rappel/{}".format(self.show1.id)
|
return "/gestion/bda/mails-rappel/{}".format(self.show1.id)
|
||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
self.require_custommails()
|
|
||||||
resp = self.client.post(self.url)
|
resp = self.client.post(self.url)
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
# TODO: check that emails are sent
|
# TODO: check that emails are sent
|
||||||
|
|
47
bda/views.py
47
bda/views.py
|
@ -4,17 +4,17 @@ import random
|
||||||
import time
|
import time
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from custommail.models import CustomMail
|
|
||||||
from custommail.shortcuts import send_custom_mail, send_mass_custom_mail
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core import serializers
|
from django.core import serializers
|
||||||
from django.core.exceptions import NON_FIELD_ERRORS
|
from django.core.exceptions import NON_FIELD_ERRORS
|
||||||
|
from django.core.mail import send_mail, send_mass_mail
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Count, Prefetch
|
from django.db.models import Count, Prefetch
|
||||||
from django.forms.models import inlineformset_factory
|
from django.forms.models import inlineformset_factory
|
||||||
from django.http import HttpResponseBadRequest, HttpResponseRedirect, JsonResponse
|
from django.http import HttpResponseBadRequest, HttpResponseRedirect, JsonResponse
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
from django.template import loader
|
||||||
from django.template.defaultfilters import pluralize
|
from django.template.defaultfilters import pluralize
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import formats, timezone
|
from django.utils import formats, timezone
|
||||||
|
@ -400,7 +400,7 @@ def revente_manage(request, tirage_id):
|
||||||
if "resell" in request.POST:
|
if "resell" in request.POST:
|
||||||
resellform = ResellForm(participant, request.POST, prefix="resell")
|
resellform = ResellForm(participant, request.POST, prefix="resell")
|
||||||
if resellform.is_valid():
|
if resellform.is_valid():
|
||||||
datatuple = []
|
mails = []
|
||||||
attributions = resellform.cleaned_data["attributions"]
|
attributions = resellform.cleaned_data["attributions"]
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
for attribution in attributions:
|
for attribution in attributions:
|
||||||
|
@ -415,16 +415,17 @@ def revente_manage(request, tirage_id):
|
||||||
"show": attribution.spectacle,
|
"show": attribution.spectacle,
|
||||||
"revente": revente,
|
"revente": revente,
|
||||||
}
|
}
|
||||||
datatuple.append(
|
mails.append(
|
||||||
(
|
(
|
||||||
"bda-revente-new",
|
"BdA-Revente : {}".format(attribution.spectacle),
|
||||||
context,
|
loader.render_to_string(
|
||||||
|
"bda/mails/revente-seller.txt", context=context
|
||||||
|
),
|
||||||
settings.MAIL_DATA["revente"]["FROM"],
|
settings.MAIL_DATA["revente"]["FROM"],
|
||||||
[participant.user.email],
|
[participant.user.email],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
revente.save()
|
send_mass_mail(mails)
|
||||||
send_mass_custom_mail(datatuple)
|
|
||||||
# On annule une revente
|
# On annule une revente
|
||||||
elif "annul" in request.POST:
|
elif "annul" in request.POST:
|
||||||
annulform = AnnulForm(participant, request.POST, prefix="annul")
|
annulform = AnnulForm(participant, request.POST, prefix="annul")
|
||||||
|
@ -643,12 +644,16 @@ def revente_buy(request, spectacle_id):
|
||||||
"acheteur": request.user,
|
"acheteur": request.user,
|
||||||
"vendeur": revente.seller.user,
|
"vendeur": revente.seller.user,
|
||||||
}
|
}
|
||||||
send_custom_mail(
|
|
||||||
"bda-buy-shotgun",
|
send_mail(
|
||||||
"bda@ens.fr",
|
"BdA-Revente : {}".format(spectacle.title),
|
||||||
|
loader.render_to_string(
|
||||||
|
"bda/mails/revente-shotgun-seller.txt", context=context
|
||||||
|
),
|
||||||
|
request.user.email,
|
||||||
[revente.seller.user.email],
|
[revente.seller.user.email],
|
||||||
context=context,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"bda/revente/mail-success.html",
|
"bda/revente/mail-success.html",
|
||||||
|
@ -751,19 +756,21 @@ class UnpaidParticipants(BuroRequiredMixin, ListView):
|
||||||
def send_rappel(request, spectacle_id):
|
def send_rappel(request, spectacle_id):
|
||||||
show = get_object_or_404(Spectacle, id=spectacle_id)
|
show = get_object_or_404(Spectacle, id=spectacle_id)
|
||||||
# Mails d'exemples
|
# Mails d'exemples
|
||||||
custommail = CustomMail.objects.get(shortname="bda-rappel")
|
subject = show.title
|
||||||
exemple_mail_1place = custommail.render(
|
body_mail_1place = loader.render_to_string(
|
||||||
{"member": request.user, "show": show, "nb_attr": 1}
|
"bda/mails/rappel.txt",
|
||||||
|
context={"member": request.user, "show": show, "nb_attr": 1},
|
||||||
)
|
)
|
||||||
exemple_mail_2places = custommail.render(
|
body_mail_2places = loader.render_to_string(
|
||||||
{"member": request.user, "show": show, "nb_attr": 2}
|
"bda/mails/rappel.txt",
|
||||||
|
context={"member": request.user, "show": show, "nb_attr": 2},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Contexte
|
# Contexte
|
||||||
ctxt = {
|
ctxt = {
|
||||||
"show": show,
|
"show": show,
|
||||||
"exemple_mail_1place": exemple_mail_1place,
|
"exemple_mail_1place": (subject, body_mail_1place),
|
||||||
"exemple_mail_2places": exemple_mail_2places,
|
"exemple_mail_2places": (subject, body_mail_2places),
|
||||||
"custommail": custommail,
|
|
||||||
}
|
}
|
||||||
# Envoi confirmé
|
# Envoi confirmé
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
|
|
@ -51,7 +51,6 @@ INSTALLED_APPS = (
|
||||||
"kfet",
|
"kfet",
|
||||||
"kfet.open",
|
"kfet.open",
|
||||||
"channels",
|
"channels",
|
||||||
"custommail",
|
|
||||||
"djconfig",
|
"djconfig",
|
||||||
"wagtail.contrib.forms",
|
"wagtail.contrib.forms",
|
||||||
"wagtail.contrib.redirects",
|
"wagtail.contrib.redirects",
|
||||||
|
|
|
@ -1,600 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "model",
|
|
||||||
"content_type": [
|
|
||||||
"auth",
|
|
||||||
"user"
|
|
||||||
],
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "int",
|
|
||||||
"content_type": null,
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "model",
|
|
||||||
"content_type": [
|
|
||||||
"bda",
|
|
||||||
"spectacle"
|
|
||||||
],
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "model",
|
|
||||||
"content_type": [
|
|
||||||
"bda",
|
|
||||||
"spectaclerevente"
|
|
||||||
],
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "model",
|
|
||||||
"content_type": [
|
|
||||||
"sites",
|
|
||||||
"site"
|
|
||||||
],
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "model",
|
|
||||||
"content_type": [
|
|
||||||
"gestioncof",
|
|
||||||
"petitcoursdemande"
|
|
||||||
],
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "list",
|
|
||||||
"content_type": null,
|
|
||||||
"inner1": 12,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "list",
|
|
||||||
"content_type": null,
|
|
||||||
"inner1": 1,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "pair",
|
|
||||||
"content_type": null,
|
|
||||||
"inner1": 12,
|
|
||||||
"inner2": 8
|
|
||||||
},
|
|
||||||
"pk": 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "list",
|
|
||||||
"content_type": null,
|
|
||||||
"inner1": 9,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "list",
|
|
||||||
"content_type": null,
|
|
||||||
"inner1": 3,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 11
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.type",
|
|
||||||
"fields": {
|
|
||||||
"kind": "model",
|
|
||||||
"content_type": [
|
|
||||||
"gestioncof",
|
|
||||||
"petitcourssubject"
|
|
||||||
],
|
|
||||||
"inner1": null,
|
|
||||||
"inner2": null
|
|
||||||
},
|
|
||||||
"pk": 12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "welcome",
|
|
||||||
"subject": "Bienvenue au COF",
|
|
||||||
"body": "Bonjour {{ member.first_name }} et bienvenue au COF !\r\n\r\nTu trouveras plein de trucs cool sur le site du COF : https://www.cof.ens.fr/ et notre page Facebook : https://www.facebook.com/cof.ulm\r\nEt n'oublie pas d'aller d\u00e9couvrir GestioCOF, la plateforme de gestion du COF !\r\nSi tu as des questions, tu peux nous envoyer un mail \u00e0 cof@ens.fr (on aime le spam), ou passer nous voir au Bur\u00f4 pr\u00e8s de la Cour\u00f4 du lundi au vendredi de 12h \u00e0 14h et de 18h \u00e0 20h.\r\n\r\nRetrouvez les \u00e9v\u00e8nements de rentr\u00e9e pour les conscrit.e.s et les vieux/vieilles organis\u00e9s par le COF et ses clubs ici : http://www.cof.ens.fr/depot/Rentree.pdf \r\n\r\nAmicalement,\r\n\r\nTon COF qui t'aime.",
|
|
||||||
"description": "Mail de bienvenue au COF envoy\u00e9 automatiquement \u00e0 l'inscription d'un nouveau membre"
|
|
||||||
},
|
|
||||||
"pk": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-rappel",
|
|
||||||
"subject": "{{ show }}",
|
|
||||||
"body": "Bonjour {{ member.first_name }},\r\n\r\nNous te rappellons que tu as eu la chance d'obtenir {{ nb_attr|pluralize:\"une place,deux places\" }}\r\npour {{ show.title }}, le {{ show.date }} au {{ show.location }}. N'oublie pas de t'y rendre !\r\n{% if nb_attr == 2 %}\r\nTu as obtenu deux places pour ce spectacle. Nous te rappelons que\r\nces places sont strictement r\u00e9serv\u00e9es aux personnes de moins de 28 ans.\r\n{% endif %}\r\n{% if show.listing %}Pour ce spectacle, tu as re\u00e7u des places sur\r\nlisting. Il te faudra donc te rendre 15 minutes en avance sur les lieux de la repr\u00e9sentation\r\npour retirer {{ nb_attr|pluralize:\"ta place,tes places\" }}.\r\n{% else %}Pour assister \u00e0 ce spectacle, tu dois pr\u00e9senter les billets qui ont\r\n\u00e9t\u00e9 distribu\u00e9s au bur\u00f4.\r\n{% endif %}\r\n\r\nSi tu ne peux plus assister \u00e0 cette repr\u00e9sentation, tu peux\r\nrevendre ta place via BdA-revente, accessible directement sur\r\nGestioCOF (lien \"revendre une place du premier tirage\" sur la page\r\nd'accueil https://www.cof.ens.fr/gestion/).\r\n\r\nEn te souhaitant un excellent spectacle,\r\n\r\nLe Bureau des Arts",
|
|
||||||
"description": "Mail de rappel pour les spectacles BdA"
|
|
||||||
},
|
|
||||||
"pk": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"pk": 3,
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-revente",
|
|
||||||
"subject": "{{ show }}",
|
|
||||||
"description": "Notification envoy\u00e9e \u00e0 toutes les personnes int\u00e9ress\u00e9es par un spectacle pour leur signaler qu'une place vient d'\u00eatre mise en vente.",
|
|
||||||
"body": "Bonjour {{ member.first_name }}\r\n\r\nUne place pour le spectacle {{ show.title }} ({{ show.date }})\r\na \u00e9t\u00e9 post\u00e9e sur BdA-Revente.\r\n\r\nSi ce spectacle t'int\u00e9resse toujours, merci de nous le signaler en cliquant\r\nsur ce lien : http://{{ site }}{% url \"bda-revente-confirm\" revente.id %}.\r\nDans le cas o\u00f9 plusieurs personnes seraient int\u00e9ress\u00e9es, nous proc\u00e8derons \u00e0\r\nun tirage au sort le {{ revente.date_tirage|date:\"DATE_FORMAT\" }}.\r\n\r\nChaleureusement,\r\nLe BdA"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"pk": 4,
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-shotgun",
|
|
||||||
"subject": "{{ show }}",
|
|
||||||
"description": "Notification signalant qu'une place est au shotgun aux personnes int\u00e9ress\u00e9es.",
|
|
||||||
"body": "Bonjour {{ member.first_name }}\r\n\r\nUne place pour le spectacle {{ show.title }} ({{ show.date }})\r\na \u00e9t\u00e9 post\u00e9e sur BdA-Revente.\r\n\r\nPuisque ce spectacle a lieu dans moins de 24h, il n'y a pas de tirage au sort pour\r\ncette place : elle est disponible imm\u00e9diatement \u00e0 l'adresse\r\nhttp://{{ site }}{% url \"bda-revente-buy\" show.id %}, \u00e0 la disposition de tous.\r\n\r\nChaleureusement,\r\nLe BdA"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-revente-winner",
|
|
||||||
"subject": "BdA-Revente : {{ show.title }}",
|
|
||||||
"body": "Bonjour {{ acheteur.first_name }},\r\n\r\nTu as \u00e9t\u00e9 tir\u00e9-e au sort pour racheter une place pour {{ show.title }} le {{ show.date }} ({{ show.location }}) \u00e0 {{ show.price|floatformat:2 }}\u20ac.\r\nTu peux contacter le/la vendeur-se \u00e0 l'adresse {{ vendeur.email }}.\r\n\r\nChaleureusement,\r\nLe BdA",
|
|
||||||
"description": "Mail envoy\u00e9 au gagnant d'un tirage BdA-Revente"
|
|
||||||
},
|
|
||||||
"pk": 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-revente-loser",
|
|
||||||
"subject": "BdA-Revente : {{ show.title }}",
|
|
||||||
"body": "Bonjour {{ acheteur.first_name }},\r\n\r\nTu t'\u00e9tais inscrit-e pour la revente de la place de {{ vendeur.get_full_name }}\r\npour {{ show.title }}.\r\nMalheureusement, une autre personne a \u00e9t\u00e9 tir\u00e9e au sort pour racheter la place.\r\nTu pourras certainement retenter ta chance pour une autre revente !\r\n\r\n\u00c0 tr\u00e8s bient\u00f4t,\r\nLe Bureau des Arts",
|
|
||||||
"description": "Notification envoy\u00e9e aux perdants d'un tirage de revente."
|
|
||||||
},
|
|
||||||
"pk": 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-revente-seller",
|
|
||||||
"subject": "BdA-Revente : {{ show.title }}",
|
|
||||||
"body": "Bonjour {{ vendeur.first_name }},\r\n\r\nLa personne tir\u00e9e au sort pour racheter ta place pour {{ show.title }} est {{ acheteur.get_full_name }}.\r\nTu peux le/la contacter \u00e0 l'adresse {{ acheteur.email }}, ou en r\u00e9pondant \u00e0 ce mail.\r\n\r\nChaleureusement,\r\nLe BdA",
|
|
||||||
"description": "Notification envoy\u00e9e au vendeur d'une place pour lui indiquer qu'elle vient d'\u00eatre attribu\u00e9e"
|
|
||||||
},
|
|
||||||
"pk": 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-revente-new",
|
|
||||||
"subject": "BdA-Revente : {{ show.title }}",
|
|
||||||
"body": "Bonjour {{ vendeur.first_name }},\r\n\r\nTu t\u2019es bien inscrit-e pour la revente de {{ show.title }}.\r\n\r\n{% with revente.date_tirage as time %}\r\nLe tirage au sort entre tout-e-s les racheteuse-eur-s potentiel-le-s aura lieu\r\nle {{ time|date:\"DATE_FORMAT\" }} \u00e0 {{ time|time:\"TIME_FORMAT\" }} (dans {{time|timeuntil }}).\r\nSi personne ne s\u2019est inscrit pour racheter la place, celle-ci apparaitra parmi\r\nles \u00ab Places disponibles imm\u00e9diatement \u00e0 la revente \u00bb sur GestioCOF.\r\n{% endwith %}\r\n\r\nBonne revente !\r\nLe Bureau des Arts",
|
|
||||||
"description": "Notification signalant au vendeur d'une place que sa mise en vente a bien eu lieu et lui donnant quelques informations compl\u00e9mentaires."
|
|
||||||
},
|
|
||||||
"pk": 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-buy-shotgun",
|
|
||||||
"subject": "BdA-Revente : {{ show.title }}",
|
|
||||||
"body": "Bonjour {{ vendeur.first_name }} !\r\n\r\nJe souhaiterais racheter ta place pour {{ show.title }} le {{ show.date }} ({{ show.location }}) \u00e0 {{ show.price|floatformat:2 }}\u20ac.\r\nContacte-moi si tu es toujours int\u00e9ress\u00e9\u00b7e !\r\n\r\n{{ acheteur.get_full_name }} ({{ acheteur.email }})",
|
|
||||||
"description": "Mail envoy\u00e9 au revendeur lors d'un achat au shotgun."
|
|
||||||
},
|
|
||||||
"pk": 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "petit-cours-mail-eleve",
|
|
||||||
"subject": "Petits cours ENS par le COF",
|
|
||||||
"body": "Salut,\r\n\r\nLe COF a re\u00e7u une demande de petit cours qui te correspond. Tu es en haut de la liste d'attente donc on a transmis tes coordonn\u00e9es, ainsi que celles de 2 autres qui correspondaient aussi (c'est la vie, on donne les num\u00e9ros 3 par 3 pour que ce soit plus souple). Voici quelques infos sur l'annonce en question :\r\n\r\n\u00a4 Nom : {{ demande.name }}\r\n\r\n\u00a4 P\u00e9riode : {{ demande.quand }}\r\n\r\n\u00a4 Fr\u00e9quence : {{ demande.freq }}\r\n\r\n\u00a4 Lieu (si pr\u00e9f\u00e9r\u00e9) : {{ demande.lieu }}\r\n\r\n\u00a4 Niveau : {{ demande.get_niveau_display }}\r\n\r\n\u00a4 Remarques diverses (d\u00e9sol\u00e9 pour les balises HTML) : {{ demande.remarques }}\r\n\r\n{% if matieres|length > 1 %}\u00a4 Mati\u00e8res :\r\n{% for matiere in matieres %} \u00a4 {{ matiere }}\r\n{% endfor %}{% else %}\u00a4 Mati\u00e8re : {% for matiere in matieres %}{{ matiere }}\r\n{% endfor %}{% endif %}\r\nVoil\u00e0, cette personne te contactera peut-\u00eatre sous peu, tu pourras voir les d\u00e9tails directement avec elle (prix, modalit\u00e9s, ...). Pour indication, 30 Euro/h semble \u00eatre la moyenne.\r\n\r\nSi tu te rends compte qu'en fait tu ne peux pas/plus donner de cours en ce moment, \u00e7a serait cool que tu d\u00e9coches la case \"Recevoir des propositions de petits cours\" sur GestioCOF. Ensuite d\u00e8s que tu voudras r\u00e9appara\u00eetre tu pourras recocher la case et tu seras \u00e0 nouveau sur la liste.\r\n\r\n\u00c0 bient\u00f4t,\r\n\r\n--\r\nLe COF, pour les petits cours",
|
|
||||||
"description": "Mail envoy\u00e9 aux personnes dont ont a donn\u00e9 les contacts \u00e0 des demandeurs de petits cours"
|
|
||||||
},
|
|
||||||
"pk": 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "petits-cours-mail-demandeur",
|
|
||||||
"subject": "Cours particuliers ENS",
|
|
||||||
"body": "Bonjour,\r\n\r\nJe vous contacte au sujet de votre annonce pass\u00e9e sur le site du COF pour rentrer en contact avec un \u00e9l\u00e8ve normalien pour des cours particuliers. Voici les coordonn\u00e9es d'\u00e9l\u00e8ves qui sont motiv\u00e9s par de tels cours et correspondent aux crit\u00e8res que vous nous aviez transmis :\r\n\r\n{% for matiere, proposed in proposals %}\u00a4 {{ matiere }} :{% for user in proposed %}\r\n \u00a4 {{ user.get_full_name }}{% if user.profile.phone %}, {{ user.profile.phone }}{% endif %}{% if user.email %}, {{ user.email }}{% endif %}{% endfor %}\r\n\r\n{% endfor %}{% if unsatisfied %}Nous n'avons cependant pas pu trouver d'\u00e9l\u00e8ve disponible pour des cours de {% for matiere in unsatisfied %}{% if forloop.counter0 > 0 %}, {% endif %}{{ matiere }}{% endfor %}.\r\n\r\n{% endif %}Si pour une raison ou une autre ces num\u00e9ros ne suffisaient pas, n'h\u00e9sitez pas \u00e0 r\u00e9pondre \u00e0 cet e-mail et je vous en ferai parvenir d'autres sans probl\u00e8me.\r\n{% if extra|length > 0 %}\r\n{{ extra|safe }}\r\n{% endif %}\r\nCordialement,\r\n\r\n--\r\nLe COF, BdE de l'ENS",
|
|
||||||
"description": "Mail envoy\u00e9 aux personnes qui demandent des petits cours lorsque leur demande est trait\u00e9e.\r\n\r\n(Ne pas toucher \u00e0 {{ extra|safe }})"
|
|
||||||
},
|
|
||||||
"pk": 11
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-attributions",
|
|
||||||
"subject": "R\u00e9sultats du tirage au sort",
|
|
||||||
"body": "Cher-e {{ member.first_name }},\r\n\r\nTu t'es inscrit-e pour le tirage au sort du BdA. Tu as \u00e9t\u00e9 s\u00e9lectionn\u00e9-e\r\npour les spectacles suivants :\r\n{% for place in places %}\r\n- 1 place pour {{ place }}{% endfor %}\r\n\r\n*Paiement*\r\nL'int\u00e9gralit\u00e9 de ces places de spectacles est \u00e0 r\u00e9gler d\u00e8s maintenant et AVANT\r\nvendredi prochain, au bureau du COF pendant les heures de permanences (du lundi au vendredi\r\nentre 12h et 14h, et entre 18h et 20h). Des facilit\u00e9s de paiement sont bien\r\n\u00e9videmment possibles : nous pouvons ne pas encaisser le ch\u00e8que imm\u00e9diatement,\r\nou bien d\u00e9couper votre paiement en deux fois. Pour ceux qui ne pourraient pas\r\nvenir payer au bureau, merci de nous contacter par mail.\r\n\r\n*Mode de retrait des places*\r\nAu moment du paiement, certaines places vous seront remises directement,\r\nd'autres seront \u00e0 r\u00e9cup\u00e9rer au cours de l'ann\u00e9e, d'autres encore seront\r\nnominatives et \u00e0 retirer le soir m\u00eame dans les the\u00e2tres correspondants.\r\nPour chaque spectacle, vous recevrez un mail quelques jours avant la\r\nrepr\u00e9sentation vous indiquant le mode de retrait.\r\n\r\nNous vous rappelons que l'obtention de places du BdA vous engage \u00e0\r\nrespecter les r\u00e8gles de fonctionnement :\r\nhttp://www.cof.ens.fr/bda/?page_id=1370\r\nUn syst\u00e8me de revente des places via les mails BdA-revente disponible\r\ndirectement sur votre compte GestioCOF.\r\n\r\nEn vous souhaitant de tr\u00e8s beaux spectacles tout au long de l'ann\u00e9e,\r\n--\r\nLe Bureau des Arts",
|
|
||||||
"description": "Mail annon\u00e7ant les r\u00e9sultats du tirage au sort du BdA aux gagnants d'une ou plusieurs places"
|
|
||||||
},
|
|
||||||
"pk": 12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.custommail",
|
|
||||||
"fields": {
|
|
||||||
"shortname": "bda-attributions-decus",
|
|
||||||
"subject": "R\u00e9sultats du tirage au sort",
|
|
||||||
"body": "Cher-e {{ member.first_name }},\r\n\r\nTu t'es inscrit-e pour le tirage au sort du BdA. Malheureusement, tu n'as\r\nobtenu aucune place.\r\n\r\nNous proposons cependant de nombreuses offres hors-tirage tout au long de\r\nl'ann\u00e9e, et nous t'invitons \u00e0 nous contacter si l'une d'entre elles\r\nt'int\u00e9resse !\r\n--\r\nLe Bureau des Arts",
|
|
||||||
"description": "Mail annon\u00e7ant les r\u00e9sultats du tirage au sort du BdA aux personnes n'ayant pas obtenu de place"
|
|
||||||
},
|
|
||||||
"pk": 13
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 1,
|
|
||||||
"type": 1,
|
|
||||||
"name": "member",
|
|
||||||
"description": "Utilisateur de GestioCOF"
|
|
||||||
},
|
|
||||||
"pk": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 2,
|
|
||||||
"type": 1,
|
|
||||||
"name": "member",
|
|
||||||
"description": "Utilisateur ayant eu une place pour ce spectacle"
|
|
||||||
},
|
|
||||||
"pk": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 2,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 2,
|
|
||||||
"type": 2,
|
|
||||||
"name": "nb_attr",
|
|
||||||
"description": "Nombre de places obtenues"
|
|
||||||
},
|
|
||||||
"pk": 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 3,
|
|
||||||
"type": 4,
|
|
||||||
"name": "revente",
|
|
||||||
"description": "Revente mentionn\u00e9e dans le mail"
|
|
||||||
},
|
|
||||||
"pk": 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 3,
|
|
||||||
"type": 1,
|
|
||||||
"name": "member",
|
|
||||||
"description": "Personne int\u00e9ress\u00e9e par la place"
|
|
||||||
},
|
|
||||||
"pk": 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 3,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 3,
|
|
||||||
"type": 5,
|
|
||||||
"name": "site",
|
|
||||||
"description": "Site web (gestioCOF)"
|
|
||||||
},
|
|
||||||
"pk": 8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 4,
|
|
||||||
"type": 5,
|
|
||||||
"name": "site",
|
|
||||||
"description": "Site web (gestioCOF)"
|
|
||||||
},
|
|
||||||
"pk": 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 4,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 4,
|
|
||||||
"type": 1,
|
|
||||||
"name": "member",
|
|
||||||
"description": "Personne int\u00e9ress\u00e9e par la place"
|
|
||||||
},
|
|
||||||
"pk": 11
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 5,
|
|
||||||
"type": 1,
|
|
||||||
"name": "acheteur",
|
|
||||||
"description": "Gagnant-e du tirage"
|
|
||||||
},
|
|
||||||
"pk": 12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 5,
|
|
||||||
"type": 1,
|
|
||||||
"name": "vendeur",
|
|
||||||
"description": "Personne qui vend une place"
|
|
||||||
},
|
|
||||||
"pk": 13
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 5,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 14
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 6,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 6,
|
|
||||||
"type": 1,
|
|
||||||
"name": "vendeur",
|
|
||||||
"description": "Personne qui vend une place"
|
|
||||||
},
|
|
||||||
"pk": 16
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 6,
|
|
||||||
"type": 1,
|
|
||||||
"name": "acheteur",
|
|
||||||
"description": "Personne inscrite au tirage qui n'a pas eu la place"
|
|
||||||
},
|
|
||||||
"pk": 17
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 7,
|
|
||||||
"type": 1,
|
|
||||||
"name": "acheteur",
|
|
||||||
"description": "Gagnant-e du tirage"
|
|
||||||
},
|
|
||||||
"pk": 18
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 7,
|
|
||||||
"type": 1,
|
|
||||||
"name": "vendeur",
|
|
||||||
"description": "Personne qui vend une place"
|
|
||||||
},
|
|
||||||
"pk": 19
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 7,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 20
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 8,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 21
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 8,
|
|
||||||
"type": 1,
|
|
||||||
"name": "vendeur",
|
|
||||||
"description": "Personne qui vend la place"
|
|
||||||
},
|
|
||||||
"pk": 22
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 8,
|
|
||||||
"type": 4,
|
|
||||||
"name": "revente",
|
|
||||||
"description": "Revente mentionn\u00e9e dans le mail"
|
|
||||||
},
|
|
||||||
"pk": 23
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 9,
|
|
||||||
"type": 1,
|
|
||||||
"name": "vendeur",
|
|
||||||
"description": "Personne qui vend la place"
|
|
||||||
},
|
|
||||||
"pk": 24
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 9,
|
|
||||||
"type": 3,
|
|
||||||
"name": "show",
|
|
||||||
"description": "Spectacle"
|
|
||||||
},
|
|
||||||
"pk": 25
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 9,
|
|
||||||
"type": 1,
|
|
||||||
"name": "acheteur",
|
|
||||||
"description": "Personne qui prend la place au shotgun"
|
|
||||||
},
|
|
||||||
"pk": 26
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 10,
|
|
||||||
"type": 6,
|
|
||||||
"name": "demande",
|
|
||||||
"description": "Demande de petit cours"
|
|
||||||
},
|
|
||||||
"pk": 27
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 10,
|
|
||||||
"type": 7,
|
|
||||||
"name": "matieres",
|
|
||||||
"description": "Liste des mati\u00e8res concern\u00e9es par la demande"
|
|
||||||
},
|
|
||||||
"pk": 28
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 11,
|
|
||||||
"type": 10,
|
|
||||||
"name": "proposals",
|
|
||||||
"description": "Liste associant une liste d'enseignants \u00e0 chaque mati\u00e8re"
|
|
||||||
},
|
|
||||||
"pk": 29
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 11,
|
|
||||||
"type": 7,
|
|
||||||
"name": "unsatisfied",
|
|
||||||
"description": "Liste des mati\u00e8res pour lesquelles on n'a pas d'enseigant \u00e0 proposer"
|
|
||||||
},
|
|
||||||
"pk": 30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 12,
|
|
||||||
"type": 11,
|
|
||||||
"name": "places",
|
|
||||||
"description": "Places de spectacle du participant"
|
|
||||||
},
|
|
||||||
"pk": 31
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 12,
|
|
||||||
"type": 1,
|
|
||||||
"name": "member",
|
|
||||||
"description": "Participant du tirage au sort"
|
|
||||||
},
|
|
||||||
"pk": 32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "custommail.variable",
|
|
||||||
"fields": {
|
|
||||||
"custommail": 13,
|
|
||||||
"type": 1,
|
|
||||||
"name": "member",
|
|
||||||
"description": "Participant du tirage au sort"
|
|
||||||
},
|
|
||||||
"pk": 33
|
|
||||||
}
|
|
||||||
]
|
|
11
gestioncof/templates/gestioncof/mails/welcome.txt
Normal file
11
gestioncof/templates/gestioncof/mails/welcome.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Bonjour {{ member.first_name }} et bienvenue au COF !
|
||||||
|
|
||||||
|
Tu trouveras plein de trucs cool sur le site du COF : https://cof.ens.fr/ et notre page Facebook : https://www.facebook.com/cof.ulm
|
||||||
|
Et n'oublie pas d'aller découvrir GestioCOF, la plateforme de gestion du COF !
|
||||||
|
Si tu as des questions, tu peux nous envoyer un mail à cof@ens.fr (on aime le spam), ou passer nous voir au Burô près de la Courô du lundi au vendredi de 12h à 14h et de 18h à 20h.
|
||||||
|
|
||||||
|
Retrouvez les évènements de rentrée pour les conscrit.e.s et les vieux/vieilles organisés par le COF et ses clubs ici : https://cof.ens.fr/planningrentree.
|
||||||
|
|
||||||
|
Amicalement,
|
||||||
|
|
||||||
|
Ton COF qui t'aime.
|
|
@ -1,15 +1,13 @@
|
||||||
import os
|
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from custommail.models import CustomMail
|
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.messages.api import get_messages
|
from django.contrib.messages.api import get_messages
|
||||||
from django.contrib.messages.storage.base import Message
|
from django.contrib.messages.storage.base import Message
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.management import call_command
|
from django.core.mail import EmailMessage
|
||||||
|
from django.template import loader
|
||||||
from django.test import Client, TestCase, override_settings
|
from django.test import Client, TestCase, override_settings
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
@ -33,12 +31,6 @@ class RegistrationViewTests(ViewTestCaseMixin, TestCase):
|
||||||
auth_user = "staff"
|
auth_user = "staff"
|
||||||
auth_forbidden = [None, "user", "member"]
|
auth_forbidden = [None, "user", "member"]
|
||||||
|
|
||||||
def requires_mails(self):
|
|
||||||
data_file = os.path.join(
|
|
||||||
settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json"
|
|
||||||
)
|
|
||||||
call_command("syncmails", data_file, verbosity=0)
|
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
r = self.client.get(self.url)
|
r = self.client.get(self.url)
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
|
@ -64,8 +56,6 @@ class RegistrationViewTests(ViewTestCaseMixin, TestCase):
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_post_new(self):
|
def test_post_new(self):
|
||||||
self.requires_mails()
|
|
||||||
|
|
||||||
r = self.client.post(
|
r = self.client.post(
|
||||||
self.url,
|
self.url,
|
||||||
dict(
|
dict(
|
||||||
|
@ -97,7 +87,6 @@ class RegistrationViewTests(ViewTestCaseMixin, TestCase):
|
||||||
self.assertEqual(u.email, "username@mail.net")
|
self.assertEqual(u.email, "username@mail.net")
|
||||||
|
|
||||||
def test_post_edit(self):
|
def test_post_edit(self):
|
||||||
self.requires_mails()
|
|
||||||
u = self.users["user"]
|
u = self.users["user"]
|
||||||
|
|
||||||
r = self.client.post(
|
r = self.client.post(
|
||||||
|
@ -132,7 +121,6 @@ class RegistrationViewTests(ViewTestCaseMixin, TestCase):
|
||||||
self.assertEqual(u.email, "user@mail.net")
|
self.assertEqual(u.email, "user@mail.net")
|
||||||
|
|
||||||
def _test_mail_welcome(self, was_cof, is_cof, expect_mail):
|
def _test_mail_welcome(self, was_cof, is_cof, expect_mail):
|
||||||
self.requires_mails()
|
|
||||||
u = self.users["member"] if was_cof else self.users["user"]
|
u = self.users["member"] if was_cof else self.users["user"]
|
||||||
|
|
||||||
data = dict(
|
data = dict(
|
||||||
|
@ -146,8 +134,12 @@ class RegistrationViewTests(ViewTestCaseMixin, TestCase):
|
||||||
u.refresh_from_db()
|
u.refresh_from_db()
|
||||||
|
|
||||||
def _is_sent():
|
def _is_sent():
|
||||||
cm = CustomMail.objects.get(shortname="welcome")
|
welcome_msg = EmailMessage(
|
||||||
welcome_msg = cm.get_message({"member": u})
|
subject="Bienvenue au COF",
|
||||||
|
body=loader.render_to_string(
|
||||||
|
"gestioncof/mails/welcome.txt", context={"member": "u"}
|
||||||
|
),
|
||||||
|
)
|
||||||
for m in mail.outbox:
|
for m in mail.outbox:
|
||||||
if m.subject == welcome_msg.subject:
|
if m.subject == welcome_msg.subject:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -4,7 +4,6 @@ from datetime import timedelta
|
||||||
from smtplib import SMTPRecipientsRefused
|
from smtplib import SMTPRecipientsRefused
|
||||||
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
|
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
|
||||||
|
|
||||||
from custommail.shortcuts import send_custom_mail
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
@ -15,8 +14,10 @@ from django.contrib.auth.views import (
|
||||||
redirect_to_login,
|
redirect_to_login,
|
||||||
)
|
)
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
from django.core.mail import send_mail
|
||||||
from django.http import Http404, HttpResponse, HttpResponseForbidden
|
from django.http import Http404, HttpResponse, HttpResponseForbidden
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
|
from django.template import loader
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
@ -489,8 +490,13 @@ def notify_new_member(request, member: User):
|
||||||
|
|
||||||
# Try to send a welcome email and report SMTP errors
|
# Try to send a welcome email and report SMTP errors
|
||||||
try:
|
try:
|
||||||
send_custom_mail(
|
send_mail(
|
||||||
"welcome", "cof@ens.fr", [member.email], context={"member": member}
|
"Bienvenue au COF",
|
||||||
|
loader.render_to_string(
|
||||||
|
"gestioncof/mails/welcome.txt", context={"member": member}
|
||||||
|
),
|
||||||
|
"cof@ens.fr",
|
||||||
|
[member.email],
|
||||||
)
|
)
|
||||||
except SMTPRecipientsRefused:
|
except SMTPRecipientsRefused:
|
||||||
messages.error(
|
messages.error(
|
||||||
|
|
17
petitscours/templates/petitscours/mails/demandeur.txt
Normal file
17
petitscours/templates/petitscours/mails/demandeur.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
Bonjour,
|
||||||
|
|
||||||
|
Je vous contacte au sujet de votre annonce passée sur le site du COF pour rentrer en contact avec un élève normalien pour des cours particuliers. Voici les coordonnées d'élèves qui sont motivés par de tels cours et correspondent aux critères que vous nous aviez transmis :
|
||||||
|
|
||||||
|
{% for matiere, proposed in proposals %}¤ {{ matiere }} :{% for user in proposed %}
|
||||||
|
¤ {{ user.get_full_name }}{% if user.profile.phone %}, {{ user.profile.phone }}{% endif %}{% if user.email %}, {{ user.email }}{% endif %}{% endfor %}
|
||||||
|
|
||||||
|
{% endfor %}{% if unsatisfied %}Nous n'avons cependant pas pu trouver d'élève disponible pour des cours de {% for matiere in unsatisfied %}{% if forloop.counter0 > 0 %}, {% endif %}{{ matiere }}{% endfor %}.
|
||||||
|
|
||||||
|
{% endif %}Si pour une raison ou une autre ces numéros ne suffisaient pas, n'hésitez pas à répondre à cet e-mail et je vous en ferai parvenir d'autres sans problème.
|
||||||
|
{% if extra|length > 0 %}
|
||||||
|
{{ extra|safe }}
|
||||||
|
{% endif %}
|
||||||
|
Cordialement,
|
||||||
|
|
||||||
|
--
|
||||||
|
Le COF, BdE de l'ENS
|
28
petitscours/templates/petitscours/mails/eleve.txt
Normal file
28
petitscours/templates/petitscours/mails/eleve.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
Salut,
|
||||||
|
|
||||||
|
Le COF a reçu une demande de petit cours qui te correspond. Tu es en haut de la liste d'attente donc on a transmis tes coordonnées, ainsi que celles de 2 autres qui correspondaient aussi (c'est la vie, on donne les numéros 3 par 3 pour que ce soit plus souple). Voici quelques infos sur l'annonce en question :
|
||||||
|
|
||||||
|
¤ Nom : {{ demande.name }}
|
||||||
|
|
||||||
|
¤ Période : {{ demande.quand }}
|
||||||
|
|
||||||
|
¤ Fréquence : {{ demande.freq }}
|
||||||
|
|
||||||
|
¤ Lieu (si préféré) : {{ demande.lieu }}
|
||||||
|
|
||||||
|
¤ Niveau : {{ demande.get_niveau_display }}
|
||||||
|
|
||||||
|
¤ Remarques diverses (désolé pour les balises HTML) : {{ demande.remarques }}
|
||||||
|
|
||||||
|
{% if matieres|length > 1 %}¤ Matières :
|
||||||
|
{% for matiere in matieres %} ¤ {{ matiere }}
|
||||||
|
{% endfor %}{% else %}¤ Matière : {% for matiere in matieres %}{{ matiere }}
|
||||||
|
{% endfor %}{% endif %}
|
||||||
|
Voilà, cette personne te contactera peut-être sous peu, tu pourras voir les détails directement avec elle (prix, modalités, ...). Pour indication, 30 Euro/h semble être la moyenne.
|
||||||
|
|
||||||
|
Si tu te rends compte qu'en fait tu ne peux pas/plus donner de cours en ce moment, ça serait cool que tu décoches la case "Recevoir des propositions de petits cours" sur GestioCOF. Ensuite dès que tu voudras réapparaître tu pourras recocher la case et tu seras à nouveau sur la liste.
|
||||||
|
|
||||||
|
À bientôt,
|
||||||
|
|
||||||
|
--
|
||||||
|
Le COF, pour les petits cours
|
|
@ -8,7 +8,6 @@ from django.urls import reverse
|
||||||
from gestioncof.tests.mixins import ViewTestCaseMixin
|
from gestioncof.tests.mixins import ViewTestCaseMixin
|
||||||
|
|
||||||
from .utils import (
|
from .utils import (
|
||||||
PetitCoursTestHelpers,
|
|
||||||
create_petitcours_ability,
|
create_petitcours_ability,
|
||||||
create_petitcours_demande,
|
create_petitcours_demande,
|
||||||
create_petitcours_subject,
|
create_petitcours_subject,
|
||||||
|
@ -160,9 +159,7 @@ class PetitCoursInscriptionViewTestCase(ViewTestCaseMixin, TestCase):
|
||||||
self.assertFalse(self.user.petitcoursability_set.all())
|
self.assertFalse(self.user.petitcoursability_set.all())
|
||||||
|
|
||||||
|
|
||||||
class PetitCoursTraitementViewTestCase(
|
class PetitCoursTraitementViewTestCase(ViewTestCaseMixin, TestCase):
|
||||||
ViewTestCaseMixin, PetitCoursTestHelpers, TestCase
|
|
||||||
):
|
|
||||||
url_name = "petits-cours-demande-traitement"
|
url_name = "petits-cours-demande-traitement"
|
||||||
|
|
||||||
http_methods = ["GET", "POST"]
|
http_methods = ["GET", "POST"]
|
||||||
|
@ -188,14 +185,10 @@ class PetitCoursTraitementViewTestCase(
|
||||||
self.demande.matieres.add(self.subject)
|
self.demande.matieres.add(self.subject)
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
self.require_custommails()
|
|
||||||
|
|
||||||
resp = self.client.get(self.url)
|
resp = self.client.get(self.url)
|
||||||
self.assertEqual(resp.status_code, 200)
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
|
||||||
def test_get_with_match(self):
|
def test_get_with_match(self):
|
||||||
self.require_custommails()
|
|
||||||
|
|
||||||
create_petitcours_ability(
|
create_petitcours_ability(
|
||||||
user=self.user, matiere=self.subject, niveau="college"
|
user=self.user, matiere=self.subject, niveau="college"
|
||||||
)
|
)
|
||||||
|
@ -211,8 +204,6 @@ class PetitCoursTraitementViewTestCase(
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_post_with_match(self):
|
def test_post_with_match(self):
|
||||||
self.require_custommails()
|
|
||||||
|
|
||||||
create_petitcours_ability(
|
create_petitcours_ability(
|
||||||
user=self.user, matiere=self.subject, niveau="college"
|
user=self.user, matiere=self.subject, niveau="college"
|
||||||
)
|
)
|
||||||
|
@ -230,9 +221,7 @@ class PetitCoursTraitementViewTestCase(
|
||||||
self.assertIsNotNone(self.demande.processed)
|
self.assertIsNotNone(self.demande.processed)
|
||||||
|
|
||||||
|
|
||||||
class PetitCoursRetraitementViewTestCase(
|
class PetitCoursRetraitementViewTestCase(ViewTestCaseMixin, TestCase):
|
||||||
ViewTestCaseMixin, PetitCoursTestHelpers, TestCase
|
|
||||||
):
|
|
||||||
url_name = "petits-cours-demande-retraitement"
|
url_name = "petits-cours-demande-retraitement"
|
||||||
|
|
||||||
http_methods = ["GET", "POST"]
|
http_methods = ["GET", "POST"]
|
||||||
|
@ -253,8 +242,6 @@ class PetitCoursRetraitementViewTestCase(
|
||||||
self.demande = create_petitcours_demande()
|
self.demande = create_petitcours_demande()
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
self.require_custommails()
|
|
||||||
|
|
||||||
resp = self.client.get(self.url)
|
resp = self.client.get(self.url)
|
||||||
self.assertEqual(resp.status_code, 200)
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import os
|
from gestioncof.tests.utils import create_user
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.management import call_command
|
|
||||||
|
|
||||||
from petitscours.models import (
|
from petitscours.models import (
|
||||||
PetitCoursAbility,
|
PetitCoursAbility,
|
||||||
PetitCoursAttributionCounter,
|
PetitCoursAttributionCounter,
|
||||||
|
@ -13,7 +9,7 @@ from petitscours.models import (
|
||||||
|
|
||||||
def create_petitcours_ability(**kwargs):
|
def create_petitcours_ability(**kwargs):
|
||||||
if "user" not in kwargs:
|
if "user" not in kwargs:
|
||||||
kwargs["user"] = create_user()
|
kwargs["user"] = create_user("toto")
|
||||||
if "matiere" not in kwargs:
|
if "matiere" not in kwargs:
|
||||||
kwargs["matiere"] = create_petitcours_subject()
|
kwargs["matiere"] = create_petitcours_subject()
|
||||||
if "niveau" not in kwargs:
|
if "niveau" not in kwargs:
|
||||||
|
@ -29,11 +25,3 @@ def create_petitcours_demande(**kwargs):
|
||||||
|
|
||||||
def create_petitcours_subject(**kwargs):
|
def create_petitcours_subject(**kwargs):
|
||||||
return PetitCoursSubject.objects.create(**kwargs)
|
return PetitCoursSubject.objects.create(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class PetitCoursTestHelpers:
|
|
||||||
def require_custommails(self):
|
|
||||||
data_file = os.path.join(
|
|
||||||
settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json"
|
|
||||||
)
|
|
||||||
call_command("syncmails", data_file, verbosity=0)
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from custommail.shortcuts import render_custom_mail
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
@ -8,6 +7,7 @@ from django.contrib.auth.models import User
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
|
from django.template import loader
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
|
@ -70,15 +70,18 @@ def _finalize_traitement(
|
||||||
proposed_for.setdefault(user, []).append(matiere)
|
proposed_for.setdefault(user, []).append(matiere)
|
||||||
|
|
||||||
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
||||||
mainmail = render_custom_mail(
|
mainmail = (
|
||||||
"petits-cours-mail-demandeur",
|
"Cours particuliers ENS",
|
||||||
{
|
loader.render_to_string(
|
||||||
"proposals": proposals.items(),
|
"petitscours/mails/demandeur.txt",
|
||||||
"unsatisfied": unsatisfied,
|
context={
|
||||||
"extra": '<textarea name="extra" '
|
"proposals": proposals.items(),
|
||||||
'style="width:99%; height: 90px;">'
|
"unsatisfied": unsatisfied,
|
||||||
"</textarea>",
|
"extra": '<textarea name="extra" '
|
||||||
},
|
'style="width:99%; height: 90px;">'
|
||||||
|
"</textarea>",
|
||||||
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if errors is not None:
|
if errors is not None:
|
||||||
for error in errors:
|
for error in errors:
|
||||||
|
@ -100,11 +103,16 @@ def _finalize_traitement(
|
||||||
|
|
||||||
|
|
||||||
def _generate_eleve_email(demande, proposed_for):
|
def _generate_eleve_email(demande, proposed_for):
|
||||||
|
subject = "Petits cours ENS par le COF"
|
||||||
return [
|
return [
|
||||||
(
|
(
|
||||||
user,
|
user,
|
||||||
render_custom_mail(
|
(
|
||||||
"petit-cours-mail-eleve", {"demande": demande, "matieres": matieres}
|
subject,
|
||||||
|
loader.render_to_string(
|
||||||
|
"petitscours/mails/eleve.txt",
|
||||||
|
context={"demande": demande, "matieres": matieres},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
for user, matieres in proposed_for.items()
|
for user, matieres in proposed_for.items()
|
||||||
|
@ -197,9 +205,14 @@ def _traitement_post(request, demande):
|
||||||
else:
|
else:
|
||||||
proposed_for[user].append(matiere)
|
proposed_for[user].append(matiere)
|
||||||
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
proposed_mails = _generate_eleve_email(demande, proposed_for)
|
||||||
mainmail_object, mainmail_body = render_custom_mail(
|
mainmail_object = "Cours particuliers ENS"
|
||||||
"petits-cours-mail-demandeur",
|
mainmail_body = loader.render_to_string(
|
||||||
{"proposals": proposals.items(), "unsatisfied": unsatisfied, "extra": extra},
|
"petitscours/mails/demandeur.txt",
|
||||||
|
context={
|
||||||
|
"proposals": proposals.items(),
|
||||||
|
"unsatisfied": unsatisfied,
|
||||||
|
"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"]
|
||||||
|
|
|
@ -8,4 +8,3 @@ python manage.py sync_page_translation_fields
|
||||||
python manage.py update_translation_fields
|
python manage.py update_translation_fields
|
||||||
python manage.py loaddata gestion sites articles
|
python manage.py loaddata gestion sites articles
|
||||||
python manage.py loaddevdata
|
python manage.py loaddevdata
|
||||||
python manage.py syncmails gestioncof/management/data/custommail.json
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ Pillow
|
||||||
django-bootstrap-form==3.3
|
django-bootstrap-form==3.3
|
||||||
statistics==1.0.3.5
|
statistics==1.0.3.5
|
||||||
django-widget-tweaks==1.4.1
|
django-widget-tweaks==1.4.1
|
||||||
git+https://git.eleves.ens.fr/cof-geek/django_custommail.git#egg=django_custommail
|
|
||||||
channels==1.1.*
|
channels==1.1.*
|
||||||
python-dateutil
|
python-dateutil
|
||||||
wagtail==2.7.*
|
wagtail==2.7.*
|
||||||
|
|
Loading…
Reference in a new issue