mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
Merge branch 'better-vouchers' into 'dev'
Better vouchers See merge request federez/re2o!444
This commit is contained in:
commit
80328199c8
10 changed files with 320 additions and 18 deletions
|
@ -25,7 +25,9 @@ from django.template.loader import get_template
|
||||||
from django.core.mail import EmailMessage
|
from django.core.mail import EmailMessage
|
||||||
|
|
||||||
from .tex import create_pdf
|
from .tex import create_pdf
|
||||||
from preferences.models import AssoOption, GeneralOption, CotisationsOption
|
from preferences.models import (
|
||||||
|
AssoOption, GeneralOption, CotisationsOption, Mandate
|
||||||
|
)
|
||||||
from re2o.settings import LOGO_PATH
|
from re2o.settings import LOGO_PATH
|
||||||
from re2o import settings
|
from re2o import settings
|
||||||
|
|
||||||
|
@ -97,9 +99,10 @@ def send_mail_invoice(invoice):
|
||||||
|
|
||||||
def send_mail_voucher(invoice):
|
def send_mail_voucher(invoice):
|
||||||
"""Creates a voucher from an invoice and sends it by email to the client"""
|
"""Creates a voucher from an invoice and sends it by email to the client"""
|
||||||
|
president = Mandate.get_mandate(invoice.date).president
|
||||||
ctx = {
|
ctx = {
|
||||||
'asso_name': AssoOption.get_cached_value('name'),
|
'asso_name': AssoOption.get_cached_value('name'),
|
||||||
'pres_name': AssoOption.get_cached_value('pres_name'),
|
'pres_name': ' '.join([president.name, president.surname]),
|
||||||
'firstname': invoice.user.name,
|
'firstname': invoice.user.name,
|
||||||
'lastname': invoice.user.surname,
|
'lastname': invoice.user.surname,
|
||||||
'email': invoice.user.email,
|
'email': invoice.user.email,
|
||||||
|
|
|
@ -60,7 +60,7 @@ from re2o.acl import (
|
||||||
can_delete_set,
|
can_delete_set,
|
||||||
can_change,
|
can_change,
|
||||||
)
|
)
|
||||||
from preferences.models import AssoOption, GeneralOption
|
from preferences.models import AssoOption, GeneralOption, Mandate
|
||||||
from .models import (
|
from .models import (
|
||||||
Facture,
|
Facture,
|
||||||
Article,
|
Article,
|
||||||
|
@ -1068,9 +1068,10 @@ def voucher_pdf(request, invoice, **_kwargs):
|
||||||
_("Could not find a voucher for that invoice.")
|
_("Could not find a voucher for that invoice.")
|
||||||
)
|
)
|
||||||
return redirect(reverse('cotisations:index'))
|
return redirect(reverse('cotisations:index'))
|
||||||
|
president = Mandate.get_mandate(invoice.date).president
|
||||||
return render_voucher(request, {
|
return render_voucher(request, {
|
||||||
'asso_name': AssoOption.get_cached_value('name'),
|
'asso_name': AssoOption.get_cached_value('name'),
|
||||||
'pres_name': AssoOption.get_cached_value('pres_name'),
|
'pres_name': ' '.join([president.name, president.surname]),
|
||||||
'firstname': invoice.user.name,
|
'firstname': invoice.user.name,
|
||||||
'lastname': invoice.user.surname,
|
'lastname': invoice.user.surname,
|
||||||
'email': invoice.user.email,
|
'email': invoice.user.email,
|
||||||
|
|
|
@ -26,6 +26,7 @@ Formulaire d'edition des réglages : user, machine, topologie, asso...
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
|
from django.db.models import Q
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from re2o.mixins import FormRevMixin
|
from re2o.mixins import FormRevMixin
|
||||||
|
@ -45,7 +46,8 @@ from .models import (
|
||||||
RadiusOption,
|
RadiusOption,
|
||||||
CotisationsOption,
|
CotisationsOption,
|
||||||
DocumentTemplate,
|
DocumentTemplate,
|
||||||
RadiusAttribute
|
RadiusAttribute,
|
||||||
|
Mandate
|
||||||
)
|
)
|
||||||
from topologie.models import Switch
|
from topologie.models import Switch
|
||||||
|
|
||||||
|
@ -261,6 +263,72 @@ class EditCotisationsOptionForm(ModelForm):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class MandateForm(ModelForm):
|
||||||
|
"""Edit Mandates"""
|
||||||
|
class Meta:
|
||||||
|
model = Mandate
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||||
|
super(MandateForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
def clean_start_date(self):
|
||||||
|
date = self.cleaned_data.get('start_date')
|
||||||
|
existing_mandates = Mandate.objects.filter(
|
||||||
|
start_date__gte=date, end_date__lt=date
|
||||||
|
)
|
||||||
|
if existing_mandates:
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("There is already a mandate taking place at the specified start date.")
|
||||||
|
)
|
||||||
|
return date
|
||||||
|
|
||||||
|
def clean_end_date(self):
|
||||||
|
date = self.cleaned_data.get('end_date')
|
||||||
|
if date is None:
|
||||||
|
return None
|
||||||
|
existing_mandates = Mandate.objects.filter(
|
||||||
|
start_date__gte=date, end_date__lt=date
|
||||||
|
)
|
||||||
|
if existing_mandates:
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("There is already a mandate taking place at the specified end date.")
|
||||||
|
)
|
||||||
|
return date
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(MandateForm, self).clean()
|
||||||
|
start_date, end_date = cleaned_data['start_date'], cleaned_data['end_date']
|
||||||
|
if end_date:
|
||||||
|
included_mandates = Mandate.objects.filter(
|
||||||
|
Q(start_date__gte=start_date, start_date__lt=end_date)
|
||||||
|
| Q(end_date__gt=start_date, end_date__lte=end_date)
|
||||||
|
)
|
||||||
|
if included_mandates:
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("The specified dates overlap with an existing mandate."),
|
||||||
|
code='invalid'
|
||||||
|
)
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
"""Warning, side effect : if a mandate with a null end_date
|
||||||
|
exists, its end_date will be set to instance.start_date, no matter the
|
||||||
|
value of commit."""
|
||||||
|
instance = super(MandateForm, self).save(commit=False)
|
||||||
|
if instance.end_date is None:
|
||||||
|
try:
|
||||||
|
previous_mandate = Mandate.objects.get(end_date__isnull=True)
|
||||||
|
previous_mandate.end_date = instance.start_date
|
||||||
|
previous_mandate.save()
|
||||||
|
except Mandate.DoesNotExist:
|
||||||
|
pass
|
||||||
|
if commit:
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class ServiceForm(ModelForm):
|
class ServiceForm(ModelForm):
|
||||||
"""Edition, ajout de services sur la page d'accueil"""
|
"""Edition, ajout de services sur la page d'accueil"""
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
68
preferences/migrations/0063_mandate.py
Normal file
68
preferences/migrations/0063_mandate.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.23 on 2019-09-21 18:23
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.utils import timezone
|
||||||
|
import re2o.mixins
|
||||||
|
|
||||||
|
|
||||||
|
def create_current_mandate(apps, schema_editor):
|
||||||
|
AssoOption = apps.get_model('preferences', 'AssoOption')
|
||||||
|
Mandate = apps.get_model('preferences', 'Mandate')
|
||||||
|
Adherent = apps.get_model('users', 'Adherent')
|
||||||
|
assooption = AssoOption.objects.get_or_create()[0]
|
||||||
|
pres_name = assooption.pres_name
|
||||||
|
l = pres_name.split(' ')
|
||||||
|
try:
|
||||||
|
name, surname = l[0], l[1]
|
||||||
|
president = Adherent.objects.get(name__icontains=name, surname__icontains=surname)
|
||||||
|
Mandate.objects.create(
|
||||||
|
president=president,
|
||||||
|
start_date=timezone.now(),
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print("Warning : I was unable to find an adherent corresponding to %s. You might want to edit your preferences afterward. I will disable the sending of vouchers by email." % pres_name)
|
||||||
|
CotisationsOption = apps.get_model('preferences', 'CotisationsOption')
|
||||||
|
cotisoption = CotisationsOption.objects.get_or_create()[0]
|
||||||
|
cotisoption.send_voucher_mail = False
|
||||||
|
cotisoption.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('preferences', '0062_auto_20190910_1909'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Mandate',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('start_date', models.DateTimeField(verbose_name='start date')),
|
||||||
|
('end_date', models.DateTimeField(blank=True, null=True, verbose_name='end date')),
|
||||||
|
('president', models.ForeignKey(blank=True, help_text='Displayed on subscription vouchers', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='President of the association')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Mandate',
|
||||||
|
'verbose_name_plural': 'Mandates',
|
||||||
|
'permissions': (('view_mandate', 'Can view a mandate'),),
|
||||||
|
},
|
||||||
|
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
|
||||||
|
),
|
||||||
|
migrations.RunPython(create_current_mandate),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='cotisationsoption',
|
||||||
|
name='send_voucher_mail',
|
||||||
|
field=models.BooleanField(default=False, help_text='Be carefull, if no mandate is defined on the preferences page, errors will be triggered when generating vouchers.', verbose_name='Send voucher by email when the invoice is controlled.'),
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='assooption',
|
||||||
|
name='pres_name',
|
||||||
|
),
|
||||||
|
]
|
|
@ -501,6 +501,48 @@ class MailContact(AclMixin, models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return(self.address)
|
return(self.address)
|
||||||
|
|
||||||
|
class Mandate(RevMixin, AclMixin, models.Model):
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Mandate")
|
||||||
|
verbose_name_plural = _("Mandates")
|
||||||
|
permissions = (
|
||||||
|
("view_mandate", _("Can view a mandate")),
|
||||||
|
)
|
||||||
|
|
||||||
|
president = models.ForeignKey(
|
||||||
|
'users.User',
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("President of the association"),
|
||||||
|
help_text=_("Displayed on subscription vouchers")
|
||||||
|
)
|
||||||
|
start_date = models.DateTimeField(
|
||||||
|
verbose_name=_("start date")
|
||||||
|
)
|
||||||
|
end_date = models.DateTimeField(
|
||||||
|
verbose_name=_("end date"),
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_mandate(cls, date=timezone.now):
|
||||||
|
""""Find the mandate taking place at the given date."""
|
||||||
|
if callable(date):
|
||||||
|
date = date()
|
||||||
|
mandate = cls.objects.exclude(end_date__lte=date).order_by('start_date').first() or cls.objects.order_by('start_date').last()
|
||||||
|
if not mandate:
|
||||||
|
raise cls.DoesNotExist("No mandate have been created. Please go to the preferences page to create one.")
|
||||||
|
return mandate
|
||||||
|
|
||||||
|
|
||||||
|
def is_over(self):
|
||||||
|
return self.end_date is None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.president) + ' ' + str(self.start_date.year)
|
||||||
|
|
||||||
|
|
||||||
class AssoOption(AclMixin, PreferencesModel):
|
class AssoOption(AclMixin, PreferencesModel):
|
||||||
"""Options générales de l'asso : siret, addresse, nom, etc"""
|
"""Options générales de l'asso : siret, addresse, nom, etc"""
|
||||||
|
@ -525,12 +567,6 @@ class AssoOption(AclMixin, PreferencesModel):
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
pres_name = models.CharField(
|
|
||||||
max_length=255,
|
|
||||||
default="",
|
|
||||||
verbose_name=_("President of the association"),
|
|
||||||
help_text=_("Displayed on subscription vouchers")
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
|
@ -812,6 +848,7 @@ class CotisationsOption(AclMixin, PreferencesModel):
|
||||||
)
|
)
|
||||||
send_voucher_mail = models.BooleanField(
|
send_voucher_mail = models.BooleanField(
|
||||||
verbose_name=_("Send voucher by email when the invoice is controlled."),
|
verbose_name=_("Send voucher by email when the invoice is controlled."),
|
||||||
|
help_text=_("Be carefull, if no mandate is defined on the preferences page, errors will be triggered when generating vouchers."),
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
52
preferences/templates/preferences/aff_mandate.html
Normal file
52
preferences/templates/preferences/aff_mandate.html
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{% 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 © 2018 Hugo Levy-Falk
|
||||||
|
|
||||||
|
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 i18n %}
|
||||||
|
{% load acl %}
|
||||||
|
{% load logs_extra %}
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Start date" %}</th>
|
||||||
|
<th>{% trans "End date" %}</th>
|
||||||
|
<th>{% trans "President" %}</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for mandate in mandate_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{mandate.start_date|date:"d/m/Y"}}</td>
|
||||||
|
<td>{% if mandate.end_date %}{{mandate.end_date|date:"d/m/Y"}}{% else %}{% trans "In progress." %}{% endif %}</td>
|
||||||
|
<td><a href="{% url 'users:profil' userid=mandate.president.id %}">{{mandate.president.name}} {{mandate.president.surname}}</a></td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% can_edit mandate%}
|
||||||
|
{% include 'buttons/edit.html' with href='preferences:edit-mandate' id=mandate.id %}
|
||||||
|
{% acl_end %}
|
||||||
|
{% can_delete mandate %}
|
||||||
|
{% include 'buttons/suppr.html' with href='preferences:del-mandate' id=mandate.id %}
|
||||||
|
{% acl_end %}
|
||||||
|
{% history_button mandate %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
|
@ -325,11 +325,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<th>{% trans "Description of the organisation" %}</th>
|
<th>{% trans "Description of the organisation" %}</th>
|
||||||
<td>{{ assooptions.description|safe }}</td>
|
<td>{{ assooptions.description|safe }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<th>{% trans "President of the association"%}</th>
|
|
||||||
<td>{{ assooptions.pres_name }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
|
<h5>{% trans "Mandates" %}</h5>
|
||||||
|
{% can_create Mandate %}
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-mandate' %}">
|
||||||
|
<i class="fa fa-plus"></i> {% trans "Add a mandate" %}
|
||||||
|
</a>
|
||||||
|
{% acl_end %}
|
||||||
|
{% include 'preferences/aff_mandate.html' with mandate_list=mandate_list %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default" id="templates">
|
<div class="panel panel-default" id="templates">
|
||||||
|
|
|
@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<form class="form" method="post" enctype="multipart/form-data">
|
<form class="form" method="post" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if preferenceform %}
|
{% if preferenceform %}
|
||||||
{% massive_bootstrap_form preferenceform 'members' %}
|
{% massive_bootstrap_form preferenceform 'members,president' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% bootstrap_button action_name button_type="submit" icon='ok' button_class='btn-success' %}
|
{% bootstrap_button action_name button_type="submit" icon='ok' button_class='btn-success' %}
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -126,6 +126,21 @@ urlpatterns = [
|
||||||
views.del_document_template,
|
views.del_document_template,
|
||||||
name='del-document-template'
|
name='del-document-template'
|
||||||
),
|
),
|
||||||
|
url(
|
||||||
|
r'^add_mandate/$',
|
||||||
|
views.add_mandate,
|
||||||
|
name='add-mandate'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
r'^edit_mandate/(?P<mandateid>[0-9]+)$',
|
||||||
|
views.edit_mandate,
|
||||||
|
name='edit-mandate'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
r'^del_mandate/(?P<mandateid>[0-9]+)$',
|
||||||
|
views.del_mandate,
|
||||||
|
name='del-mandate'
|
||||||
|
),
|
||||||
url(r'^add_radiusattribute/$', views.add_radiusattribute, name='add-radiusattribute'),
|
url(r'^add_radiusattribute/$', views.add_radiusattribute, name='add-radiusattribute'),
|
||||||
url(
|
url(
|
||||||
r'^edit_radiusattribute/(?P<radiusattributeid>[0-9]+)$',
|
r'^edit_radiusattribute/(?P<radiusattributeid>[0-9]+)$',
|
||||||
|
|
|
@ -54,7 +54,8 @@ from .forms import (
|
||||||
DocumentTemplateForm,
|
DocumentTemplateForm,
|
||||||
DelDocumentTemplateForm,
|
DelDocumentTemplateForm,
|
||||||
RadiusAttributeForm,
|
RadiusAttributeForm,
|
||||||
DelRadiusAttributeForm
|
DelRadiusAttributeForm,
|
||||||
|
MandateForm
|
||||||
)
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
Service,
|
Service,
|
||||||
|
@ -72,7 +73,8 @@ from .models import (
|
||||||
RadiusOption,
|
RadiusOption,
|
||||||
CotisationsOption,
|
CotisationsOption,
|
||||||
DocumentTemplate,
|
DocumentTemplate,
|
||||||
RadiusAttribute
|
RadiusAttribute,
|
||||||
|
Mandate
|
||||||
)
|
)
|
||||||
from . import models
|
from . import models
|
||||||
from . import forms
|
from . import forms
|
||||||
|
@ -89,6 +91,7 @@ def display_options(request):
|
||||||
topologieoptions, _created = OptionalTopologie.objects.get_or_create()
|
topologieoptions, _created = OptionalTopologie.objects.get_or_create()
|
||||||
generaloptions, _created = GeneralOption.objects.get_or_create()
|
generaloptions, _created = GeneralOption.objects.get_or_create()
|
||||||
assooptions, _created = AssoOption.objects.get_or_create()
|
assooptions, _created = AssoOption.objects.get_or_create()
|
||||||
|
mandate_list = Mandate.objects.order_by('start_date')
|
||||||
homeoptions, _created = HomeOption.objects.get_or_create()
|
homeoptions, _created = HomeOption.objects.get_or_create()
|
||||||
mailmessageoptions, _created = MailMessageOption.objects.get_or_create()
|
mailmessageoptions, _created = MailMessageOption.objects.get_or_create()
|
||||||
service_list = Service.objects.all()
|
service_list = Service.objects.all()
|
||||||
|
@ -110,6 +113,7 @@ def display_options(request):
|
||||||
'topologieoptions': topologieoptions,
|
'topologieoptions': topologieoptions,
|
||||||
'generaloptions': generaloptions,
|
'generaloptions': generaloptions,
|
||||||
'assooptions': assooptions,
|
'assooptions': assooptions,
|
||||||
|
'mandate_list': mandate_list,
|
||||||
'homeoptions': homeoptions,
|
'homeoptions': homeoptions,
|
||||||
'mailmessageoptions': mailmessageoptions,
|
'mailmessageoptions': mailmessageoptions,
|
||||||
'service_list': service_list,
|
'service_list': service_list,
|
||||||
|
@ -558,3 +562,54 @@ def del_radiusattribute(request, radiusattribute_instance, **_kwargs):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_create(Mandate)
|
||||||
|
def add_mandate(request):
|
||||||
|
"""Create a mandate."""
|
||||||
|
mandate = MandateForm(request.POST or None)
|
||||||
|
if mandate.is_valid():
|
||||||
|
mandate.save()
|
||||||
|
messages.success(request, _("The mandate was added."))
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
return form(
|
||||||
|
{'preferenceform': mandate, 'action_name': _("Add a mandate")},
|
||||||
|
'preferences/preferences.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_edit(Mandate)
|
||||||
|
def edit_mandate(request, mandate_instance, **_kwargs):
|
||||||
|
"""Edit a mandate."""
|
||||||
|
mandate = MandateForm(
|
||||||
|
request.POST or None,
|
||||||
|
instance=mandate_instance
|
||||||
|
)
|
||||||
|
if mandate.is_valid():
|
||||||
|
mandate.save()
|
||||||
|
messages.success(request, _("The mandate was edited."))
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
return form(
|
||||||
|
{'preferenceform': mandate, 'action_name': _("Edit")},
|
||||||
|
'preferences/preferences.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@can_delete(Mandate)
|
||||||
|
def del_mandate(request, mandate_instance, **_kwargs):
|
||||||
|
"""Delete a mandate."""
|
||||||
|
if request.method == "POST":
|
||||||
|
mandate_instance.delete()
|
||||||
|
messages.success(request, _("The mandate was deleted."))
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
return form(
|
||||||
|
{'objet': mandate_instance, 'objet_name': 'attribute'},
|
||||||
|
'preferences/delete.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue