From 60b2a6cd9d56201bfbb6533a6cac39e95e442da4 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 6 May 2018 19:08:35 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Refactor=20l'affichage=20des=20r=C3=A9glage?= =?UTF-8?q?s,=20factorisation=20et=20utilisation=20help=5Ftext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preferences/models.py | 131 +++++++++++--- .../preferences/display_preferences.html | 171 +++++------------- preferences/views.py | 31 +++- 3 files changed, 170 insertions(+), 163 deletions(-) diff --git a/preferences/models.py b/preferences/models.py index 560fa30f..b5031e4d 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -66,24 +66,35 @@ class OptionalUser(AclMixin, PreferencesModel): activation ou non du solde, autorisation du negatif, fingerprint etc""" PRETTY_NAME = "Options utilisateur" - is_tel_mandatory = models.BooleanField(default=True) - user_solde = models.BooleanField(default=False) + is_tel_mandatory = models.BooleanField( + default=True, + help_text="Obligation de renseigner le téléphone" + ) + user_solde = models.BooleanField( + default=False, + help_text="Solde pour les users" + ) solde_negatif = models.DecimalField( max_digits=5, decimal_places=2, - default=0 + default=0, + help_text="Maximum de négatif autorisé" ) max_solde = models.DecimalField( max_digits=5, decimal_places=2, - default=50 + default=50, + help_text="Valeur maximum du solde" ) min_online_payment = models.DecimalField( max_digits=5, decimal_places=2, - default=10 + default=10, + help_text="Montant minimum pour le rechargement online" ) - gpg_fingerprint = models.BooleanField(default=True) + gpg_fingerprint = models.BooleanField( + default=True, + help_text="Gpg fingerprint activée") all_can_create_club = models.BooleanField( default=False, help_text="Les users peuvent créer un club" @@ -100,7 +111,8 @@ class OptionalUser(AclMixin, PreferencesModel): 'users.ListShell', on_delete=models.PROTECT, blank=True, - null=True + null=True, + help_text="Shell par default" ) class Meta: @@ -138,13 +150,20 @@ class OptionalMachine(AclMixin, PreferencesModel): (DISABLED, 'Désactivé'), ) - password_machine = models.BooleanField(default=False) - max_lambdauser_interfaces = models.IntegerField(default=10) - max_lambdauser_aliases = models.IntegerField(default=10) + password_machine = models.BooleanField( + default=False, + help_text="Un mot de passe par machine activé") + max_lambdauser_interfaces = models.IntegerField( + default=10, + help_text="Maximum d'interface pour un user sans droits") + max_lambdauser_aliases = models.IntegerField( + default=10, + help_text="Maximum de cname pour un user sans droits") ipv6_mode = models.CharField( max_length=32, choices=CHOICE_IPV6, - default='DISABLED' + default='DISABLED', + help_text="Mode ipv6" ) create_machine = models.BooleanField( default=True, @@ -187,21 +206,24 @@ class OptionalTopologie(AclMixin, PreferencesModel): radius_general_policy = models.CharField( max_length=32, choices=CHOICE_RADIUS, - default='DEFINED' + default='DEFINED', + help_text="Politique par defaut de placement de vlan avec radius" ) vlan_decision_ok = models.OneToOneField( 'machines.Vlan', on_delete=models.PROTECT, related_name='decision_ok', blank=True, - null=True + null=True, + help_text="Placement sur ce vlan par default en cas d'accès OK" ) vlan_decision_nok = models.OneToOneField( 'machines.Vlan', on_delete=models.PROTECT, related_name='decision_nok', blank=True, - null=True + null=True, + help_text="Placement par defaut sur ce vlan en cas de rejet" ) class Meta: @@ -225,23 +247,44 @@ class GeneralOption(AclMixin, PreferencesModel): general_message = models.TextField( default="", blank=True, - help_text="Message général affiché sur le site (maintenance, etc" + help_text="Message général affiché sur le site (maintenance, etc)" + ) + search_display_page = models.IntegerField( + default=15, + help_text="Nombre de résultats affichés dans une recherche" + ) + pagination_number = models.IntegerField( + default=25, + help_text="Nombre d'item par page paginée" + ) + pagination_large_number = models.IntegerField( + default=8, + help_text="Nombre d'item par page paginée, items larges" + ) + req_expire_hrs = models.IntegerField( + default=48, + help_text="Delais d'expiration des token changement de mdp, en heure" + ) + site_name = models.CharField( + max_length=32, + default="Re2o", + help_text="Nom du site web, par defaut re2o" + ) + email_from = models.EmailField( + default="www-data@example.com", + help_text="From des mails envoyés par re2o" ) - search_display_page = models.IntegerField(default=15) - pagination_number = models.IntegerField(default=25) - pagination_large_number = models.IntegerField(default=8) - req_expire_hrs = models.IntegerField(default=48) - site_name = models.CharField(max_length=32, default="Re2o") - email_from = models.EmailField(default="www-data@example.com") GTU_sum_up = models.TextField( default="", blank=True, + help_text="Résumé des CGU à l'inscription" ) GTU = models.FileField( upload_to='', default="", null=True, blank=True, + help_text="CGU et documents réglementaires à l'inscription" ) class Meta: @@ -280,19 +323,43 @@ class AssoOption(AclMixin, PreferencesModel): name = models.CharField( default="Association réseau école machin", - max_length=256 + max_length=256, + help_text="Nom complet de l'asso" + ) + siret = models.CharField( + default="00000000000000", + max_length=32, + help_text="Numero SIRET" + ) + adresse1 = models.CharField( + default="1 Rue de exemple", + max_length=128, + help_text="Adresse" + ) + adresse2 = models.CharField( + default="94230 Cachan", + max_length=128 + ) + contact = models.EmailField( + default="contact@example.org", + help_text="Mail de contact" + ) + telephone = models.CharField( + max_length=15, + default="0000000000", + help_text="Téléphone de contact" + ) + pseudo = models.CharField( + default="Asso", + max_length=32, + help_text="Pseudo de l'asso" ) - siret = models.CharField(default="00000000000000", max_length=32) - adresse1 = models.CharField(default="1 Rue de exemple", max_length=128) - adresse2 = models.CharField(default="94230 Cachan", max_length=128) - contact = models.EmailField(default="contact@example.org") - telephone = models.CharField(max_length=15, default="0000000000") - pseudo = models.CharField(default="Asso", max_length=32) utilisateur_asso = models.OneToOneField( 'users.User', on_delete=models.PROTECT, blank=True, - null=True + null=True, + help_text="Utilisateur dans la db correspondant à l'asso" ) PAYMENT = ( ('NONE', 'NONE'), @@ -302,20 +369,24 @@ class AssoOption(AclMixin, PreferencesModel): max_length=255, choices=PAYMENT, default='NONE', + help_text="Mode de paiement en ligne" ) payment_id = models.CharField( max_length=255, default='', - blank=True + blank=True, + help_text="Id de paiement en ligne" ) payment_pass = AESEncryptedField( max_length=255, null=True, blank=True, + help_text="Clef de paiement en ligne" ) description = models.TextField( null=True, blank=True, + help_text="Description de l'asso" ) class Meta: diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index 99e3e14f..d1aca6a6 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -37,40 +37,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,

- - - - - - - - - - {% if useroptions.user_solde %} - - - {% endif %} - - - - - - - - {% if useroptions.user_solde %} + {% for line in useroptions %} - - - - - - {% endif %} - - - - - + {% for text, field in line %} + + + {% endfor %} + {% endfor %}
Téléphone obligatoirement requis{{ useroptions.is_tel_mandatory }}Activation du solde pour les utilisateurs{{ useroptions.user_solde }}
Champ gpg fingerprint{{ useroptions.gpg_fingerprint }}Solde négatif{{ useroptions.solde_negatif }}
Creations d'adhérents par tous{{ useroptions.all_can_create_adherent }}Creations de clubs par tous{{ useroptions.all_can_create_club }}
Solde maximum{{ useroptions.max_solde }}Montant minimal de rechargement en ligne{{ useroptions.min_online_payment }}
Auto inscription{{ useroptions.self_adhesion }}Shell par défaut des utilisateurs{{ useroptions.shell_default }}{{ field }}{{ text }}

Préférences machines

@@ -79,23 +53,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,

- - - - - - - - - - - - - +
Mot de passe par machine{{ machineoptions.password_machine }}Machines/interfaces autorisées par utilisateurs{{ machineoptions.max_lambdauser_interfaces }}
Alias dns autorisé par utilisateur{{ machineoptions.max_lambdauser_aliases }}Support de l'ipv6{{ machineoptions.ipv6_mode }}
+ {% for line in machineoptions %} - - + {% for text, field in line %} + + + {% endfor %} + {% endfor %}
Creation de machines{{ machineoptions.create_machine }}{{ field }}{{ text }}

Préférences topologie

@@ -105,19 +71,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,

- - - - - - - - - - - - + {% for line in topologieoptions %} + + {% for text, field in line %} + + + {% endfor %} + + {% endfor %}
Politique générale de placement de vlan{{ topologieoptions.radius_general_policy }} Ce réglage défini la politique vlan après acceptation radius : soit sur le vlan de la plage d'ip de la machine, soit sur un vlan prédéfini dans "Vlan où placer les machines après acceptation RADIUS"
Vlan où placer les machines après acceptation RADIUS{{ topologieoptions.vlan_decision_ok }}Vlan où placer les machines après rejet RADIUS{{ topologieoptions.vlan_decision_nok }}
{{ field }}{{ text }}
+

Préférences generales

@@ -126,35 +89,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,

- - - - - - - - - - - - - - - - - - + {% for line in generaloptions %} - - - - - - - - + {% for text, field in line %} + + + {% endfor %} + + {% endfor %}
Nom du site web{{ generaloptions.site_name }}Adresse mail d'expedition automatique{{ generaloptions.email_from }}
Affichage de résultats dans le champ de recherche{{ generaloptions.search_display_page }}Nombre d'items affichés en liste (taille normale){{ generaloptions.pagination_number }}
Nombre d'items affichés en liste (taille élevée){{ generaloptions.pagination_large_number }}Temps avant expiration du lien de reinitialisation de mot de passe (en heures){{ generaloptions.req_expire_hrs }}
Message global affiché sur le site{{ generaloptions.general_message }}Résumé des CGU{{ generaloptions.GTU_sum_up }}
CGU{{generaloptions.GTU}} -
{{ field }}{{ text }}
+

Données de l'association

@@ -163,37 +107,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {% for line in assooptions %} + + {% for text, field in line %} + + + {% endfor %} + + {% endfor %}
Nom{{ assooptions.name }}SIRET{{ assooptions.siret }}
Adresse{{ assooptions.adresse1 }}
- {{ assooptions.adresse2 }}
Contact mail{{ assooptions.contact }}
Telephone{{ assooptions.telephone }}Pseudo d'usage{{ assooptions.pseudo }}
Objet utilisateur de l'association{{ assooptions.utilisateur_asso }}Moyen de paiement automatique{{ assooptions.payment }}
Description de l'association{{ assooptions.description | safe }}
{{ field }}{{ text }}
+

Messages personalisé dans les mails

@@ -202,20 +125,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,

- - - + {% for line in assooptions %} + + {% for text, field in line %} + + + {% endfor %} - - - - + {% endfor %}
Mail de bienvenue (Français){{ mailmessageoptions.welcome_mail_fr | safe }}
{{ field }}{{ text }}
Mail de bienvenue (Anglais){{ mailmessageoptions.welcome_mail_en | safe }}
+

Liste des services et préférences page d'accueil

{% can_create preferences.Service%}
Ajouter un service {% acl_end %} - Supprimer un ou plusieurs service {% include "preferences/aff_service.html" with service_list=service_list %} diff --git a/preferences/views.py b/preferences/views.py index b2a6ba4c..4606b787 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -51,12 +51,23 @@ from .models import ( MailMessageOption, GeneralOption, OptionalTopologie, - HomeOption + HomeOption, + Reminder ) from . import models from . import forms +def format_options(model): + """Return a list of tuple for display of settings""" + model_formated = [] + for field in model._meta.get_fields()[1::2]: + model_formated.append([(getattr(model, field.name), model._meta.get_field(field.name).help_text)]) + for rank, field in enumerate(model._meta.get_fields()[2::2]): + model_formated[rank].append((getattr(model, field.name), model._meta.get_field(field.name).help_text)) + return model_formated + + @login_required @can_view_all(OptionalUser) @can_view_all(OptionalMachine) @@ -76,15 +87,17 @@ def display_options(request): homeoptions, _created = HomeOption.objects.get_or_create() mailmessageoptions, _created = MailMessageOption.objects.get_or_create() service_list = Service.objects.all() + reminder_list = Reminder.objects.all() return form({ - 'useroptions': useroptions, - 'machineoptions': machineoptions, - 'topologieoptions': topologieoptions, - 'generaloptions': generaloptions, - 'assooptions': assooptions, - 'homeoptions': homeoptions, - 'mailmessageoptions': mailmessageoptions, - 'service_list': service_list + 'useroptions': format_options(useroptions), + 'machineoptions': format_options(machineoptions), + 'topologieoptions': format_options(topologieoptions), + 'generaloptions': format_options(generaloptions), + 'assooptions': format_options(assooptions), + 'homeoptions': format_options(homeoptions), + 'mailmessageoptions': format_options(mailmessageoptions), + 'service_list': service_list, + 'reminder_list':reminder_list }, 'preferences/display_preferences.html', request) From 5a8888231d9fc175aae3aa294f6e57f257483f26 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 6 May 2018 19:11:12 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Ajoute=20le=20r=C3=A9glage=20reminder=20et?= =?UTF-8?q?=20factorise=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, From f34d0a9a3f53875dde749fc7e95deb44edc19514 Mon Sep 17 00:00:00 2001 From: Grizzly Date: Sun, 1 Jul 2018 16:37:56 +0000 Subject: [PATCH 3/3] oubli du fichier urls --- re2o/urls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/re2o/urls.py b/re2o/urls.py index b1a1037c..52b685ff 100644 --- a/re2o/urls.py +++ b/re2o/urls.py @@ -47,13 +47,14 @@ from django.conf.urls import include, url from django.contrib import admin from django.contrib.auth import views as auth_views -from .views import index, about_page +from .views import index, about_page, contact_page handler500 = 're2o.views.handler500' urlpatterns = [ url(r'^$', index, name='index'), url(r'^about/$', about_page, name='about'), + url(r'^contact/$', contact_page, name='contact'), url('^logout/', auth_views.logout, {'next_page': '/'}), url('^', include('django.contrib.auth.urls')), url(r'^i18n/', include('django.conf.urls.i18n')),