Parcourir la source

Permet à un admin de déclencher un renvoi du lien de gestion

Assorti d'un message personalisé.
Jocelyn Delalande il y a 6 ans
Parent
commit
791eff76ed

+ 97 - 3
wifiwithme/apps/contribmap/admin.py

@@ -1,17 +1,36 @@
 # -*- coding: utf-8 -*-
-
-from django.contrib import admin
+from django.conf.urls import url
+from django.contrib import admin, messages
+from django.http import HttpResponseNotAllowed
+from django.core.urlresolvers import reverse
+from django.shortcuts import redirect, render
+from django.template.loader import get_template
+from django.template import engines as template_engines
 from django.utils.html import format_html
 
-# Register your models here.
+from .emails import send_contributor_email
+from .forms import ReminderForm
+from .tokens import ContribTokenManager
 from .models import Contrib
 
 
+django_templates = template_engines['django']
+
+
 # Kinda hackish to do that here
 admin.site.site_header = "Administration − Wifi with me"
 admin.site.site_title = "Wifi with me"
 
 
+def send_reminder_action(modeladmin, request, queryset):
+    selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
+    return redirect(reverse(
+        "admin:send_contrib_reminder",
+        args=[",".join(selected)],
+    ))
+send_reminder_action.short_description = "Renvoyer le lien de gestion par mail"
+
+
 @admin.register(Contrib)
 class ContribAdmin(admin.ModelAdmin):
     search_fields = ["name", "email", "phone"]
@@ -45,6 +64,8 @@ class ContribAdmin(admin.ModelAdmin):
         }]
     ]
 
+    actions = [send_reminder_action]
+
     def expired_string(self, obj):
         if obj.is_expired():
             return format_html('<strong style="color: red; cursor: help;" title="Cette entrée excède la durée de rétention et aurait dû être supprimée automatiquement.">expiré</strong>')
@@ -52,3 +73,76 @@ class ContribAdmin(admin.ModelAdmin):
             return 'non expiré'
 
     expired_string.short_description = 'Expiration'
+
+    def send_reminder(self, request, pks):
+        contribs = Contrib.objects.filter(pk__in=pks.split(','))
+        contribs_with_email = contribs.exclude(email='')
+        contribs_without_email = contribs.filter(email='')
+
+        if request.method not in ('GET', 'POST'):
+            return HttpResponseNotAllowed()
+
+        if request.method == 'POST':
+            form = ReminderForm(request.POST)
+            if form.is_valid():
+                for contrib in contribs:
+                    send_contributor_email(
+                        contrib,
+                        django_templates.from_string(form.cleaned_data['mail_subject']),
+                        django_templates.from_string(form.cleaned_data['mail_body']),
+                        ContribTokenManager().mk_token(contrib),
+                        request,
+                    )
+
+                messages.add_message(
+                    request, messages.INFO,
+                    'Mail de rappel bien envoyé à {} destinataires.'.format(
+                        contribs_with_email.count()
+                    )
+                )
+                return redirect('admin:contribmap_contrib_changelist')
+
+        elif request.method == 'GET':
+            form = ReminderForm(initial={
+                'mail_subject': get_template(
+                    'contribmap/mails/link_reminder.subject'
+                ).template.source,
+                'mail_body': get_template(
+                    'contribmap/mails/link_reminder.txt'
+                ).template.source,
+            })
+
+        if contribs_with_email.exists():
+            if contribs_without_email.exists():
+
+                messages.add_message(
+                    request, messages.WARNING,
+                    "Certaines contributions ne mentionnent"
+                    + " pas d'email : {}.".format(
+                        ', '.join(['« {} »'.format(i) for i in contribs_without_email]))
+                    + " Astuce : il doit y avoir un n° de téléphone …"
+                )
+
+            # case of form display or re-display (errors)
+            return render(
+                request, 'admin/contribmap/contrib/send_reminder.html', {
+                    'contribs': contribs_with_email,
+                    'form': form,
+                }
+            )
+        else:
+            messages.add_message(
+                request, messages.ERROR,
+                "Aucune des contributions sélectionnées ne mentionne une adresse"
+                " mail ; impossible d'envoyer un email de rappel."
+            )
+            return redirect('admin:contribmap_contrib_changelist')
+
+    def get_urls(self):
+        return super().get_urls() + [
+            url(
+                r'^remind/(?P<pks>(\d+,?)+)',
+                self.admin_site.admin_view(self.send_reminder),
+                name='send_contrib_reminder',
+            ),
+        ]

+ 15 - 0
wifiwithme/apps/contribmap/forms.py

@@ -106,3 +106,18 @@ class ManageActionForm(forms.Form):
             (ACTION_DELETE, ACTION_DELETE),
             (ACTION_RENEW, ACTION_RENEW),
     ))
+
+
+class ReminderForm(forms.Form):
+    """To send by hand reminder email from admin
+
+    Is meant for exceptional cases, regular cases should be handled by cron
+    jobs.
+    """
+    mail_subject = forms.CharField(label="Sujet de l'email")
+    mail_body = forms.CharField(
+        label='Corps du message',
+        widget=forms.Textarea,
+        help_text="Les noms entre {{}} sont des variables qui "
+        "seront substituées au moment de l'envoi.",
+    )

+ 39 - 0
wifiwithme/apps/contribmap/templates/admin/contribmap/contrib/send_reminder.html

@@ -0,0 +1,39 @@
+
+{% extends "admin/base_site.html" %}
+
+{% block content %}
+<style>
+ label {
+     display: inline-block;
+     width: 10rem;
+ }
+
+ input[type=text], textarea {
+     width: 30rem;
+ }
+ span.helptext {
+     display: block;
+ }
+</style>
+
+Ce message sera envoyé aux destinataires suivants
+<ul>
+{% for contrib in contribs %}
+    <li>{{ contrib.email }} ({{ contrib }})</li>
+    {% endfor %}
+</ul>
+
+<p>
+    Le contenu ci-dessous est proposé comme base, mais vous pouvez tout à fait
+    le modifier.
+</p>
+
+<form action="" method="post">
+    {% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" value="Envoyer les emails" />
+</form>
+
+
+
+{% endblock %}

+ 1 - 0
wifiwithme/apps/contribmap/templates/contribmap/mails/link_reminder.subject

@@ -0,0 +1 @@
+[wifi-with-me] Lien de gestion pour votre demande #{{ contrib.id }}

+ 18 - 0
wifiwithme/apps/contribmap/templates/contribmap/mails/link_reminder.txt

@@ -0,0 +1,18 @@
+Chèr·e {{ contrib.name }},
+
+Vous aviez déposé le {{ contrib.date|date:'j F o' }} une demande de raccordement.
+
+Ceci est un rappel du lien qui vous permet de gérer votre demande (supprimer ou
+prolonger d'un an).
+
+<{{ management_link }}>
+
+Sans intervention de votre part, votre demande, ainsi que les informations
+personelles associées seront supprimés de nos serveurs dans {{ ndays }} jours :
+le **{{contrib.expiration_date|date }}**{% if isp.CNIL.LINK %}, conformément à notre déclaration CNIL¹{% endif %}.
+
+Bien à vous,
+
+Les bénévoles de {{ isp.NAME }}
+
+{% if isp.CNIL.LINK %}¹ {{ isp.CNIL.LINK }}{% endif %}