From 5a8888231d9fc175aae3aa294f6e57f257483f26 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 6 May 2018 19:11:12 +0200 Subject: [PATCH] =?UTF-8?q?Ajoute=20le=20r=C3=A9glage=20reminder=20et=20fa?= =?UTF-8?q?ctorise=20la=20liste=20des=20services?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preferences/admin.py | 5 ++ preferences/forms.py | 40 +++------ preferences/migrations/0035_reminder.py | 28 ++++++ preferences/models.py | 26 ++++++ .../templates/preferences/aff_reminder.html | 47 ++++++++++ .../preferences/display_preferences.html | 27 +++--- preferences/urls.py | 9 +- preferences/views.py | 88 ++++++++++++------- re2o/templatetags/acl.py | 1 + re2o/views.py | 1 + 10 files changed, 201 insertions(+), 71 deletions(-) create mode 100644 preferences/migrations/0035_reminder.py create mode 100644 preferences/templates/preferences/aff_reminder.html diff --git a/preferences/admin.py b/preferences/admin.py index 296dc57c..109fb936 100644 --- a/preferences/admin.py +++ b/preferences/admin.py @@ -34,6 +34,7 @@ from .models import ( OptionalTopologie, GeneralOption, Service, + Reminder, AssoOption, MailMessageOption, HomeOption @@ -79,6 +80,9 @@ class HomeOptionAdmin(VersionAdmin): """Class admin options home""" pass +class ReminderAdmin(VersionAdmin): + """Class reminder""" + pass admin.site.register(OptionalUser, OptionalUserAdmin) admin.site.register(OptionalMachine, OptionalMachineAdmin) @@ -86,5 +90,6 @@ admin.site.register(OptionalTopologie, OptionalTopologieAdmin) admin.site.register(GeneralOption, GeneralOptionAdmin) admin.site.register(HomeOption, HomeOptionAdmin) admin.site.register(Service, ServiceAdmin) +admin.site.register(Reminder, ReminderAdmin) admin.site.register(AssoOption, AssoOptionAdmin) admin.site.register(MailMessageOption, MailMessageOptionAdmin) diff --git a/preferences/forms.py b/preferences/forms.py index afe111a2..a95b8ef6 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -24,6 +24,7 @@ Formulaire d'edition des réglages : user, machine, topologie, asso... """ from __future__ import unicode_literals +from re2o.mixins import FormRevMixin from django.forms import ModelForm, Form from django import forms @@ -35,7 +36,8 @@ from .models import ( AssoOption, MailMessageOption, HomeOption, - Service + Service, + Reminder ) class EditOptionalUserForm(ModelForm): @@ -51,18 +53,6 @@ class EditOptionalUserForm(ModelForm): prefix=prefix, **kwargs ) - self.fields['is_tel_mandatory'].label = ( - 'Exiger un numéro de téléphone' - ) - self.fields['user_solde'].label = ( - 'Activation du solde pour les utilisateurs' - ) - self.fields['max_solde'].label = 'Solde maximum' - self.fields['min_online_payment'].label = ( - 'Montant de rechargement minimum en ligne' - ) - self.fields['self_adhesion'].label = 'Auto inscription' - class EditOptionalMachineForm(ModelForm): """Options machines (max de machines, etc)""" @@ -207,7 +197,7 @@ class EditHomeOptionForm(ModelForm): ) -class ServiceForm(ModelForm): +class ServiceForm(FormRevMixin, ModelForm): """Edition, ajout de services sur la page d'accueil""" class Meta: model = Service @@ -217,19 +207,13 @@ class ServiceForm(ModelForm): prefix = kwargs.pop('prefix', self.Meta.model.__name__) super(ServiceForm, self).__init__(*args, prefix=prefix, **kwargs) - -class DelServiceForm(Form): - """Suppression de services sur la page d'accueil""" - services = forms.ModelMultipleChoiceField( - queryset=Service.objects.none(), - label="Enregistrements service actuels", - widget=forms.CheckboxSelectMultiple - ) +class ReminderForm(FormRevMixin, ModelForm): + """Edition, ajout de rappel""" + class Meta: + model = Reminder + fields = '__all__' def __init__(self, *args, **kwargs): - instances = kwargs.pop('instances', None) - super(DelServiceForm, self).__init__(*args, **kwargs) - if instances: - self.fields['services'].queryset = instances - else: - self.fields['services'].queryset = Service.objects.all() + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(ReminderForm, self).__init__(*args, prefix=prefix, **kwargs) + diff --git a/preferences/migrations/0035_reminder.py b/preferences/migrations/0035_reminder.py new file mode 100644 index 00000000..eaba7753 --- /dev/null +++ b/preferences/migrations/0035_reminder.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-05-05 10:53 +from __future__ import unicode_literals + +from django.db import migrations, models +import re2o.mixins + + +class Migration(migrations.Migration): + + dependencies = [ + ('preferences', '0034_auto_20180416_1120'), + ] + + operations = [ + migrations.CreateModel( + name='Reminder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('days', models.IntegerField(default=7, help_text="Délais entre le mail et la fin d'adhésion", unique=True)), + ('message', models.CharField(blank=True, default='', max_length=255, null=True)), + ], + options={ + 'permissions': (('view_reminder', 'Peut voir un objet reminder'),), + }, + bases=(re2o.mixins.AclMixin, models.Model), + ), + ] diff --git a/preferences/models.py b/preferences/models.py index b5031e4d..2fe34932 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -239,6 +239,32 @@ def optionaltopologie_post_save(**kwargs): topologie_pref.set_in_cache() +class Reminder(AclMixin, models.Model): + """Options pour les mails de notification de fin d'adhésion. + Days: liste des nombres de jours pour lesquells un mail est envoyé + optionalMessage: message additionel pour le mail + """ + PRETTY_NAME="Options pour le mail de fin d'adhésion" + + days = models.IntegerField( + default=7, + unique=True, + help_text="Délais entre le mail et la fin d'adhésion" + ) + message = models.CharField( + max_length=255, + default="", + null=True, + blank=True, + help_text="Message affiché spécifiquement pour ce rappel" + ) + + class Meta: + permissions = ( + ("view_reminder", "Peut voir un objet reminder"), + ) + + class GeneralOption(AclMixin, PreferencesModel): """Options générales : nombre de resultats par page, nom du site, temps où les liens sont valides""" diff --git a/preferences/templates/preferences/aff_reminder.html b/preferences/templates/preferences/aff_reminder.html new file mode 100644 index 00000000..4bcaacce --- /dev/null +++ b/preferences/templates/preferences/aff_reminder.html @@ -0,0 +1,47 @@ +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2017 Gabriel Détraz +Copyright © 2017 Goulven Kermarec +Copyright © 2017 Augustin Lemesle + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} +{% load acl %} + + + + + + + + + + {% for reminder in reminder_list %} + + + + + + {% endfor %} +
Nombre de jours avant le rappelMessage custom pour ce rappel
{{ reminder.days }}{{ reminder.message }} + {% can_edit reminder %} + {% include 'buttons/edit.html' with href='preferences:edit-reminder' id=reminder.id %} + {% acl_end %} + {% include 'buttons/history.html' with href='preferences:history' name='reminder' id=reminder.id %} +
+ diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index d1aca6a6..ec9231ad 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -146,19 +146,24 @@ with this program; if not, write to the Free Software Foundation, Inc., Editer

- - - - - - - - - - - + {% for line in assooptions %} + + {% for text, field in line %} + + + {% endfor %} + + {% endfor %}
Url du compte twitter{{ homeoptions.twitter_url }}Nom utilisé pour afficher le compte{{ homeoptions.twitter_account_name }}
Url du compte facebook{{ homeoptions.facebook_url }}
{{ field }}{{ text }}
+ + +

Options pour le mail de fin d'adhésion

+ {% can_create preferences.Reminder%} + Ajouter un rappel + {% acl_end %} + {% include "preferences/aff_reminder.html" with reminder_list=reminder_list %} +


diff --git a/preferences/urls.py b/preferences/urls.py index bca7bb1e..686c1888 100644 --- a/preferences/urls.py +++ b/preferences/urls.py @@ -73,7 +73,14 @@ urlpatterns = [ views.edit_service, name='edit-service' ), - url(r'^del_services/$', views.del_services, name='del-services'), + url(r'^del_service/$', views.del_service, name='del-service'), + url(r'^add_reminder/$', views.add_reminder, name='add-reminder'), + url( + r'^edit_reminder/(?P[0-9]+)$', + views.edit_reminder, + name='edit-reminder' + ), + url(r'^del_reminder/$', views.del_reminder, name='del-reminder'), url( r'^history/(?P\w+)/(?P[0-9]+)$', re2o.views.history, diff --git a/preferences/views.py b/preferences/views.py index 4606b787..cc826827 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -40,9 +40,9 @@ from django.db import transaction from reversion import revisions as reversion from re2o.views import form -from re2o.acl import can_create, can_edit, can_delete_set, can_view_all +from re2o.acl import can_create, can_edit, can_delete, can_view_all -from .forms import ServiceForm, DelServiceForm +from .forms import ServiceForm, ReminderForm from .models import ( Service, OptionalUser, @@ -145,10 +145,7 @@ def add_service(request): """Ajout d'un service de la page d'accueil""" service = ServiceForm(request.POST or None, request.FILES or None) if service.is_valid(): - with transaction.atomic(), reversion.create_revision(): - service.save() - reversion.set_user(request.user) - reversion.set_comment("Création") + service.save() messages.success(request, "Ce service a été ajouté") return redirect(reverse('preferences:display-options')) return form( @@ -164,14 +161,7 @@ def edit_service(request, service_instance, **_kwargs): """Edition des services affichés sur la page d'accueil""" service = ServiceForm(request.POST or None, request.FILES or None,instance=service_instance) if service.is_valid(): - with transaction.atomic(), reversion.create_revision(): - service.save() - reversion.set_user(request.user) - reversion.set_comment( - "Champs modifié(s) : %s" % ', '.join( - field for field in service.changed_data - ) - ) + service.save() messages.success(request, "Service modifié") return redirect(reverse('preferences:display-options')) return form( @@ -180,26 +170,62 @@ def edit_service(request, service_instance, **_kwargs): request ) - @login_required -@can_delete_set(Service) -def del_services(request, instances): - """Suppression d'un service de la page d'accueil""" - services = DelServiceForm(request.POST or None, instances=instances) - if services.is_valid(): - services_dels = services.cleaned_data['services'] - for services_del in services_dels: - try: - with transaction.atomic(), reversion.create_revision(): - services_del.delete() - reversion.set_user(request.user) - messages.success(request, "Le service a été supprimée") - except ProtectedError: - messages.error(request, "Erreur le service\ - suivant %s ne peut être supprimé" % services_del) +@can_delete(Service) +def del_service(request, service_instance, **_kwargs): + """Destruction d'un service""" + if request.method == "POST": + service_instance.delete() + messages.success(request, "Le service a été détruit") return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': services, 'action_name': 'Supprimer'}, + {'objet': service_instance, 'objet_name': 'service'}, + 'preferences/delete.html', + request + ) + +@login_required +@can_create(Reminder) +def add_reminder(request): + """Ajout d'un rappel""" + reminder = ReminderForm(request.POST or None) + if reminder.is_valid(): + reminder.save() + messages.success(request, "Ce rappel a été ajouté") + return redirect(reverse('preferences:display-options')) + return form( + {'preferenceform': reminder, 'action_name': 'Ajouter'}, + 'preferences/preferences.html', + request + ) + +@login_required +@can_edit(Reminder) +def edit_reminder(request, reminder_instance, **_kwargs): + """Edition des rappels""" + reminder = ReminderForm(request.POST or None, instance=reminder_instance) + if reminder.is_valid(): + reminder.save() + messages.success(request, "Service modifié") + return redirect(reverse('preferences:display-options')) + return form( + {'preferenceform': reminder, 'action_name': 'Editer'}, 'preferences/preferences.html', request ) + +@login_required +@can_delete(Reminder) +def del_reminder(request, reminder_instance, **_kwargs): + """Destruction d'un reminder""" + if request.method == "POST": + reminder_instance.delete() + messages.success(request, "Le reminder a été détruit") + return redirect(reverse('preferences:display-options')) + return form( + {'objet': reminder_instance, 'objet_name': 'reminder'}, + 'preferences/delete.html', + request + ) + + diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py index fccbea1d..46ba73c1 100644 --- a/re2o/templatetags/acl.py +++ b/re2o/templatetags/acl.py @@ -117,6 +117,7 @@ MODEL_NAME = { 'OptionalTopologie': preferences.models.OptionalTopologie, 'GeneralOption': preferences.models.GeneralOption, 'preferences.Service': preferences.models.Service, + 'preferences.Reminder': preferences.models.Reminder, 'AssoOption': preferences.models.AssoOption, 'MailMessageOption': preferences.models.MailMessageOption, # topologie diff --git a/re2o/views.py b/re2o/views.py index 3c5cde09..51ef2137 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -94,6 +94,7 @@ HISTORY_BIND = { }, 'preferences': { 'service': preferences.models.Service, + 'reminder': preferences.models.Reminder, }, 'cotisations': { 'facture': cotisations.models.Facture,