8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-23 11:53:12 +00:00

Déplace les templates dans préférences.

This commit is contained in:
Hugo LEVY-FALK 2019-01-21 00:54:02 +01:00
parent f4b6f10d1e
commit 4fef4a6057
20 changed files with 294 additions and 395 deletions

View file

@ -30,7 +30,7 @@ from django.contrib import admin
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from .models import Facture, Article, Banque, Paiement, Cotisation, Vente from .models import Facture, Article, Banque, Paiement, Cotisation, Vente
from .models import CustomInvoice, CostEstimate, DocumentTemplate from .models import CustomInvoice, CostEstimate
class FactureAdmin(VersionAdmin): class FactureAdmin(VersionAdmin):
@ -74,11 +74,6 @@ class CotisationAdmin(VersionAdmin):
pass pass
class DocumentTemplateAdmin(VersionAdmin):
"""Admin class for DocumentTemplate"""
pass
admin.site.register(Facture, FactureAdmin) admin.site.register(Facture, FactureAdmin)
admin.site.register(Article, ArticleAdmin) admin.site.register(Article, ArticleAdmin)
admin.site.register(Banque, BanqueAdmin) admin.site.register(Banque, BanqueAdmin)
@ -87,4 +82,3 @@ admin.site.register(Vente, VenteAdmin)
admin.site.register(Cotisation, CotisationAdmin) admin.site.register(Cotisation, CotisationAdmin)
admin.site.register(CustomInvoice, CustomInvoiceAdmin) admin.site.register(CustomInvoice, CustomInvoiceAdmin)
admin.site.register(CostEstimate, CostEstimateAdmin) admin.site.register(CostEstimate, CostEstimateAdmin)
admin.site.register(DocumentTemplate, DocumentTemplateAdmin)

View file

@ -48,7 +48,7 @@ from re2o.field_permissions import FieldPermissionFormMixin
from re2o.mixins import FormRevMixin from re2o.mixins import FormRevMixin
from .models import ( from .models import (
Article, Paiement, Facture, Banque, Article, Paiement, Facture, Banque,
CustomInvoice, Vente, CostEstimate, DocumentTemplate CustomInvoice, Vente, CostEstimate,
) )
from .payment_methods import balance from .payment_methods import balance
@ -316,37 +316,3 @@ class RechargeForm(FormRevMixin, Form):
} }
) )
return self.cleaned_data return self.cleaned_data
class DocumentTemplateForm(FormRevMixin, ModelForm):
"""
Form used to create a document template.
"""
class Meta:
model = DocumentTemplate
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(DocumentTemplateForm, self).__init__(
*args, prefix=prefix, **kwargs)
class DelDocumentTemplateForm(FormRevMixin, Form):
"""
Form used to delete one or more document templatess.
The use must choose the one to delete by checking the boxes.
"""
document_templates = forms.ModelMultipleChoiceField(
queryset=DocumentTemplate.objects.none(),
label=_("Available document templates"),
widget=forms.CheckboxSelectMultiple
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop('instances', None)
super(DelDocumentTemplateForm, self).__init__(*args, **kwargs)
if instances:
self.fields['document_templates'].queryset = instances
else:
self.fields['document_templates'].queryset = Banque.objects.all()

View file

@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-03 16:48
from __future__ import unicode_literals
from django.db import migrations, models
import re2o.mixins
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0038_auto_20181231_1657'),
]
operations = [
migrations.CreateModel(
name='DocumentTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template', models.FileField(upload_to='templates/', verbose_name='template')),
('name', models.CharField(max_length=255, verbose_name='name')),
],
options={
'verbose_name_plural': 'document templates',
'verbose_name': 'document template',
},
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
),
]

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-20 23:08
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0039_documenttemplate'),
]
operations = [
migrations.AlterField(
model_name='documenttemplate',
name='name',
field=models.CharField(max_length=125, unique=True, verbose_name='name'),
),
]

View file

@ -33,7 +33,6 @@ each.
from __future__ import unicode_literals from __future__ import unicode_literals
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
import os
from django.db import models from django.db import models
from django.db.models import Q, Max from django.db.models import Q, Max
@ -956,56 +955,3 @@ def cotisation_post_delete(**_kwargs):
""" """
regen('mac_ip_list') regen('mac_ip_list')
regen('mailing') regen('mailing')
class DocumentTemplate(RevMixin, AclMixin, models.Model):
"""Represent a template in order to create documents such as invoice or
subscription voucher.
"""
template = models.FileField(
upload_to='templates/',
verbose_name=_('template')
)
name = models.CharField(
max_length=125,
verbose_name=_('name'),
unique=True
)
class Meta:
verbose_name = _("document template")
verbose_name_plural = _("document templates")
def __str__(self):
return str(self.name)
@receiver(models.signals.post_delete, sender=DocumentTemplate)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""
Deletes file from filesystem
when corresponding `DocumentTemplate` object is deleted.
"""
if instance.template:
if os.path.isfile(instance.template.path):
os.remove(instance.template.path)
@receiver(models.signals.pre_save, sender=DocumentTemplate)
def auto_delete_file_on_change(sender, instance, **kwargs):
"""
Deletes old file from filesystem
when corresponding `DocumentTemplate` object is updated
with new file.
"""
if not instance.pk:
return False
try:
old_file = DocumentTemplate.objects.get(pk=instance.pk).template
except DocumentTemplate.DoesNotExist:
return False
new_file = instance.template
if not old_file == new_file:
if os.path.isfile(old_file.path):
os.remove(old_file.path)

View file

@ -51,7 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% bootstrap_form_errors discount_form %} {% bootstrap_form_errors discount_form %}
{% endif %} {% endif %}
<form class="form" method="post" enctype="multipart/form-data"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form factureform %} {% bootstrap_form factureform %}
{% if payment_method %} {% if payment_method %}

View file

@ -1,42 +0,0 @@
{% extends "cotisations/sidebar.html" %}
{% 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 © 2019 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 bootstrap3 %}
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Document Templates" %}{% endblock %}
{% block content %}
<h2>{% trans "Document templates list" %}</h2>
{% can_create Banque %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-document-template' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add a document template" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-document-template' %}">
<i class="fa fa-trash"></i> {% trans "Delete one or several document templates" %}
</a>
{% include 'cotisations/aff_document_template.html' %}
{% endblock %}

View file

@ -181,25 +181,5 @@ urlpatterns = [
views.control, views.control,
name='control' name='control'
), ),
url(
r'^add_document_template/$',
views.add_document_template,
name='add-document-template'
),
url(
r'^edit_document_template/(?P<documenttemplateid>[0-9]+)$',
views.edit_document_template,
name='edit-document-template'
),
url(
r'^del_document_template/$',
views.del_document_template,
name='del-document-template'
),
url(
r'^index_document_template/$',
views.index_document_template,
name='index-document-template'
),
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
] + payment_methods.urls.urlpatterns ] + payment_methods.urls.urlpatterns

View file

@ -70,7 +70,6 @@ from .models import (
CustomInvoice, CustomInvoice,
BaseInvoice, BaseInvoice,
CostEstimate, CostEstimate,
DocumentTemplate
) )
from .forms import ( from .forms import (
FactureForm, FactureForm,
@ -85,8 +84,6 @@ from .forms import (
CustomInvoiceForm, CustomInvoiceForm,
DiscountForm, DiscountForm,
CostEstimateForm, CostEstimateForm,
DocumentTemplateForm,
DelDocumentTemplateForm
) )
from .tex import render_invoice, render_voucher, escape_chars from .tex import render_invoice, render_voucher, escape_chars
from .payment_methods.forms import payment_method_factory from .payment_methods.forms import payment_method_factory
@ -1056,102 +1053,6 @@ def credit_solde(request, user, **_kwargs):
}, 'cotisations/facture.html', request) }, 'cotisations/facture.html', request)
@login_required
@can_create(DocumentTemplate)
def add_document_template(request):
"""
View used to add a document template.
"""
document_template = DocumentTemplateForm(
request.POST or None,
request.FILES or None,
)
if document_template.is_valid():
document_template.save()
messages.success(
request,
_("The document template was created.")
)
return redirect(reverse('cotisations:index-document-template'))
return form({
'factureform': document_template,
'action_name': _("Add"),
'title': _("New document template")
}, 'cotisations/facture.html', request)
@login_required
@can_edit(DocumentTemplate)
def edit_document_template(request, document_template_instance, **_kwargs):
"""
View used to edit a document_template.
"""
document_template = DocumentTemplateForm(
request.POST or None,
request.FILES or None,
instance=document_template_instance)
if document_template.is_valid():
if document_template.changed_data:
document_template.save()
messages.success(
request,
_("The document template was edited.")
)
return redirect(reverse('cotisations:index-document-template'))
return form({
'factureform': document_template,
'action_name': _("Edit"),
'title': _("Edit document template")
}, 'cotisations/facture.html', request)
@login_required
@can_delete_set(DocumentTemplate)
def del_document_template(request, instances):
"""
View used to delete a set of document template.
"""
document_template = DelDocumentTemplateForm(
request.POST or None, instances=instances)
if document_template.is_valid():
document_template_del = document_template.cleaned_data['document_templates']
for document_template in document_template_del:
try:
document_template.delete()
messages.success(
request,
_("The document template %(document_template)s was deleted.") % {
'document_template': document_template
}
)
except ProtectedError:
messages.error(
request,
_("The document template %(document_template)s can't be deleted \
because it is currently being used.") % {
'document_template': document_template
}
)
return redirect(reverse('cotisations:index-document-template'))
return form({
'factureform': document_template,
'action_name': _("Delete"),
'title': _("Delete document template")
}, 'cotisations/facture.html', request)
@login_required
@can_view_all(DocumentTemplate)
def index_document_template(request):
"""
View used to display the list of all available document templates.
"""
document_template_list = DocumentTemplate.objects.order_by('name')
return render(request, 'cotisations/index_document_template.html', {
'document_template_list': document_template_list
})
@login_required @login_required
@can_view(Facture) @can_view(Facture)
def voucher_pdf(request, invoice, **_kwargs): def voucher_pdf(request, invoice, **_kwargs):

View file

@ -40,7 +40,8 @@ from .models import (
HomeOption, HomeOption,
RadiusKey, RadiusKey,
SwitchManagementCred, SwitchManagementCred,
Reminder Reminder,
DocumentTemplate
) )
@ -101,6 +102,12 @@ class ReminderAdmin(VersionAdmin):
"""Class reminder for switch""" """Class reminder for switch"""
pass pass
class DocumentTemplateAdmin(VersionAdmin):
"""Admin class for DocumentTemplate"""
pass
admin.site.register(OptionalUser, OptionalUserAdmin) admin.site.register(OptionalUser, OptionalUserAdmin)
admin.site.register(OptionalMachine, OptionalMachineAdmin) admin.site.register(OptionalMachine, OptionalMachineAdmin)
admin.site.register(OptionalTopologie, OptionalTopologieAdmin) admin.site.register(OptionalTopologie, OptionalTopologieAdmin)
@ -113,3 +120,4 @@ admin.site.register(RadiusKey, RadiusKeyAdmin)
admin.site.register(SwitchManagementCred, SwitchManagementCredAdmin) admin.site.register(SwitchManagementCred, SwitchManagementCredAdmin)
admin.site.register(AssoOption, AssoOptionAdmin) admin.site.register(AssoOption, AssoOptionAdmin)
admin.site.register(MailMessageOption, MailMessageOptionAdmin) admin.site.register(MailMessageOption, MailMessageOptionAdmin)
admin.site.register(DocumentTemplate, DocumentTemplateAdmin)

View file

@ -43,10 +43,12 @@ from .models import (
RadiusKey, RadiusKey,
SwitchManagementCred, SwitchManagementCred,
RadiusOption, RadiusOption,
CotisationsOption CotisationsOption,
DocumentTemplate
) )
from topologie.models import Switch from topologie.models import Switch
class EditOptionalUserForm(ModelForm): class EditOptionalUserForm(ModelForm):
"""Formulaire d'édition des options de l'user. (solde, telephone..)""" """Formulaire d'édition des options de l'user. (solde, telephone..)"""
class Meta: class Meta:
@ -376,3 +378,36 @@ class DelMailContactForm(Form):
else: else:
self.fields['mailcontacts'].queryset = MailContact.objects.all() self.fields['mailcontacts'].queryset = MailContact.objects.all()
class DocumentTemplateForm(FormRevMixin, ModelForm):
"""
Form used to create a document template.
"""
class Meta:
model = DocumentTemplate
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(DocumentTemplateForm, self).__init__(
*args, prefix=prefix, **kwargs)
class DelDocumentTemplateForm(FormRevMixin, Form):
"""
Form used to delete one or more document templatess.
The use must choose the one to delete by checking the boxes.
"""
document_templates = forms.ModelMultipleChoiceField(
queryset=DocumentTemplate.objects.none(),
label=_("Available document templates"),
widget=forms.CheckboxSelectMultiple
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop('instances', None)
super(DelDocumentTemplateForm, self).__init__(*args, **kwargs)
if instances:
self.fields['document_templates'].queryset = instances
else:
self.fields['document_templates'].queryset = Banque.objects.all()

View file

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-20 23:39
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import preferences.models
import re2o.mixins
def create_defaults(apps, schema_editor):
CotisationsOption = apps.get_model('preferences', 'CotisationsOption')
CotisationsOption.objects.get_or_create()
class Migration(migrations.Migration):
dependencies = [
('preferences', '0058_auto_20190108_1650'),
]
operations = [
migrations.CreateModel(
name='CotisationsOption',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('send_voucher_mail', models.BooleanField(default=False, verbose_name='Send voucher by email when the invoice is controlled.')),
],
options={
'verbose_name': 'cotisations options',
},
bases=(re2o.mixins.AclMixin, models.Model),
),
migrations.CreateModel(
name='DocumentTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template', models.FileField(upload_to='templates/', verbose_name='template')),
('name', models.CharField(max_length=125, unique=True, verbose_name='name')),
],
options={
'verbose_name': 'document template',
'verbose_name_plural': 'document templates',
},
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
),
migrations.AddField(
model_name='assooption',
name='pres_name',
field=models.CharField(default='', help_text='Displayed on subscription vouchers', max_length=255, verbose_name='President of the association'),
),
migrations.AddField(
model_name='cotisationsoption',
name='invoice_template',
field=models.OneToOneField(default=preferences.models.default_invoice, on_delete=django.db.models.deletion.PROTECT, related_name='invoice_template', to='preferences.DocumentTemplate', verbose_name='Template for invoices'),
),
migrations.AddField(
model_name='cotisationsoption',
name='voucher_template',
field=models.OneToOneField(default=preferences.models.default_voucher, on_delete=django.db.models.deletion.PROTECT, related_name='voucher_template', to='preferences.DocumentTemplate', verbose_name='Template for subscription voucher'),
),
migrations.RunPython(create_defaults),
]

View file

@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-03 19:56
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import re2o.mixins
import preferences.models
def initialize_invoice_template(apps, schema_editor):
CotisationsOption = apps.get_model('preferences', 'CotisationsOption')
CotisationsOption.objects.get_or_create()
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0039_documenttemplate'),
('preferences', '0058_auto_20190108_1650'),
]
operations = [
migrations.CreateModel(
name='CotisationsOption',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('invoice_template', models.OneToOneField(default=preferences.models.default_invoice,on_delete=django.db.models.deletion.PROTECT, related_name='invoice_template', to='cotisations.DocumentTemplate', verbose_name='Template for invoices')),
('voucher_template', models.OneToOneField(default=preferences.models.default_voucher, on_delete=django.db.models.deletion.PROTECT, related_name='voucher_template', to='cotisations.DocumentTemplate', verbose_name='Template for subscription voucher')),
],
options={
'verbose_name': 'cotisations options',
},
bases=(re2o.mixins.AclMixin, models.Model),
),
migrations.RunPython(initialize_invoice_template),
]

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-10 22:13
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0059_cotisationsoption'),
]
operations = [
migrations.AddField(
model_name='assooption',
name='pres_name',
field=models.CharField(default='', help_text='Displayed on subscription vouchers', max_length=255, verbose_name='President of the association'),
),
]

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-20 18:03
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0060_assooption_pres_name'),
]
operations = [
migrations.AddField(
model_name='cotisationsoption',
name='send_voucher_mail',
field=models.BooleanField(default=False, verbose_name='Send voucher by email when the invoice is controlled.'),
),
]

View file

@ -24,6 +24,7 @@
Reglages généraux, machines, utilisateurs, mail, general pour l'application. Reglages généraux, machines, utilisateurs, mail, general pour l'application.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
import os
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils import timezone from django.utils import timezone
@ -35,9 +36,8 @@ from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import machines.models import machines.models
import cotisations.models
from re2o.mixins import AclMixin from re2o.mixins import AclMixin, RevMixin
from re2o.aes_field import AESEncryptedField from re2o.aes_field import AESEncryptedField
from datetime import timedelta from datetime import timedelta
@ -696,7 +696,7 @@ class RadiusOption(AclMixin, PreferencesModel):
def default_invoice(): def default_invoice():
tpl, _ = cotisations.models.DocumentTemplate.objects.get_or_create( tpl, _ = DocumentTemplate.objects.get_or_create(
name="Re2o default invoice", name="Re2o default invoice",
template="templates/default_invoice.tex" template="templates/default_invoice.tex"
) )
@ -704,7 +704,7 @@ def default_invoice():
def default_voucher(): def default_voucher():
tpl, _ = cotisations.models.DocumentTemplate.objects.get_or_create( tpl, _ = DocumentTemplate.objects.get_or_create(
name="Re2o default voucher", name="Re2o default voucher",
template="templates/default_voucher.tex" template="templates/default_voucher.tex"
) )
@ -716,14 +716,14 @@ class CotisationsOption(AclMixin, PreferencesModel):
verbose_name = _("cotisations options") verbose_name = _("cotisations options")
invoice_template = models.OneToOneField( invoice_template = models.OneToOneField(
'cotisations.DocumentTemplate', 'preferences.DocumentTemplate',
verbose_name=_("Template for invoices"), verbose_name=_("Template for invoices"),
related_name="invoice_template", related_name="invoice_template",
on_delete=models.PROTECT, on_delete=models.PROTECT,
default=default_invoice, default=default_invoice,
) )
voucher_template = models.OneToOneField( voucher_template = models.OneToOneField(
'cotisations.DocumentTemplate', 'preferences.DocumentTemplate',
verbose_name=_("Template for subscription voucher"), verbose_name=_("Template for subscription voucher"),
related_name="voucher_template", related_name="voucher_template",
on_delete=models.PROTECT, on_delete=models.PROTECT,
@ -733,3 +733,56 @@ class CotisationsOption(AclMixin, PreferencesModel):
verbose_name=_("Send voucher by email when the invoice is controlled."), verbose_name=_("Send voucher by email when the invoice is controlled."),
default=False, default=False,
) )
class DocumentTemplate(RevMixin, AclMixin, models.Model):
"""Represent a template in order to create documents such as invoice or
subscription voucher.
"""
template = models.FileField(
upload_to='templates/',
verbose_name=_('template')
)
name = models.CharField(
max_length=125,
verbose_name=_('name'),
unique=True
)
class Meta:
verbose_name = _("document template")
verbose_name_plural = _("document templates")
def __str__(self):
return str(self.name)
@receiver(models.signals.post_delete, sender=DocumentTemplate)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""
Deletes file from filesystem
when corresponding `DocumentTemplate` object is deleted.
"""
if instance.template:
if os.path.isfile(instance.template.path):
os.remove(instance.template.path)
@receiver(models.signals.pre_save, sender=DocumentTemplate)
def auto_delete_file_on_change(sender, instance, **kwargs):
"""
Deletes old file from filesystem
when corresponding `DocumentTemplate` object is updated
with new file.
"""
if not instance.pk:
return False
try:
old_file = DocumentTemplate.objects.get(pk=instance.pk).template
except DocumentTemplate.DoesNotExist:
return False
new_file = instance.template
if not old_file == new_file:
if os.path.isfile(old_file.path):
os.remove(old_file.path)

View file

@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td><a href="{{template.template.url}}">{{template.template}}</a></td> <td><a href="{{template.template.url}}">{{template.template}}</a></td>
<td class="text-right"> <td class="text-right">
{% can_edit template %} {% can_edit template %}
{% include 'buttons/edit.html' with href='cotisations:edit-document-template' id=template.id %} {% include 'buttons/edit.html' with href='preferences:edit-document-template' id=template.id %}
{% acl_end %} {% acl_end %}
{% history_button template %} {% history_button template %}
</td> </td>

View file

@ -350,6 +350,25 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</table> </table>
</div> </div>
</div> </div>
<div class="panel panel-default" id="templates">
<div class="panel-heading" data-toggle="collapse" href="#collapse_templates">
<h4 class="panel-title">
<a><i class="fa fa-edit"></i> {% trans "Document templates" %}</a>
</h4>
</div>
<div id="collapse_templates" class="panel-collapse panel-body collapse">
{% can_create DocumentTemplate %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-document-template' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add a document template" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-document-template' %}">
<i class="fa fa-trash"></i> {% trans "Delete one or several document templates" %}
</a>
{% include 'preferences/aff_document_template.html' %}
</div>
</div>
<div class="panel panel-default" id="cotisation"> <div class="panel panel-default" id="cotisation">
<div class="panel-heading" data-toggle="collapse" href="#collapse_cotisation"> <div class="panel-heading" data-toggle="collapse" href="#collapse_cotisation">
<h4 class="panel-title"> <h4 class="panel-title">

View file

@ -111,5 +111,20 @@ urlpatterns = [
name='edit-switchmanagementcred' name='edit-switchmanagementcred'
), ),
url(r'^del_switchmanagementcred/(?P<switchmanagementcredid>[0-9]+)$', views.del_switchmanagementcred, name='del-switchmanagementcred'), url(r'^del_switchmanagementcred/(?P<switchmanagementcredid>[0-9]+)$', views.del_switchmanagementcred, name='del-switchmanagementcred'),
url(
r'^add_document_template/$',
views.add_document_template,
name='add-document-template'
),
url(
r'^edit_document_template/(?P<documenttemplateid>[0-9]+)$',
views.edit_document_template,
name='edit-document-template'
),
url(
r'^del_document_template/$',
views.del_document_template,
name='del-document-template'
),
url(r'^$', views.display_options, name='display-options'), url(r'^$', views.display_options, name='display-options'),
] ]

View file

@ -48,7 +48,9 @@ from .forms import (
ServiceForm, ServiceForm,
ReminderForm, ReminderForm,
RadiusKeyForm, RadiusKeyForm,
SwitchManagementCredForm SwitchManagementCredForm,
DocumentTemplateForm,
DelDocumentTemplateForm
) )
from .models import ( from .models import (
Service, Service,
@ -65,6 +67,7 @@ from .models import (
SwitchManagementCred, SwitchManagementCred,
RadiusOption, RadiusOption,
CotisationsOption, CotisationsOption,
DocumentTemplate
) )
from . import models from . import models
from . import forms from . import forms
@ -90,6 +93,7 @@ def display_options(request):
switchmanagementcred_list = SwitchManagementCred.objects.all() switchmanagementcred_list = SwitchManagementCred.objects.all()
radiusoptions, _ = RadiusOption.objects.get_or_create() radiusoptions, _ = RadiusOption.objects.get_or_create()
cotisationsoptions, _created = CotisationsOption.objects.get_or_create() cotisationsoptions, _created = CotisationsOption.objects.get_or_create()
document_template_list = DocumentTemplate.objects.order_by('name')
return form({ return form({
'useroptions': useroptions, 'useroptions': useroptions,
'machineoptions': machineoptions, 'machineoptions': machineoptions,
@ -105,6 +109,7 @@ def display_options(request):
'switchmanagementcred_list': switchmanagementcred_list, 'switchmanagementcred_list': switchmanagementcred_list,
'radiusoptions' : radiusoptions, 'radiusoptions' : radiusoptions,
'cotisationsoptions': cotisationsoptions, 'cotisationsoptions': cotisationsoptions,
'document_template_list': document_template_list,
}, 'preferences/display_preferences.html', request) }, 'preferences/display_preferences.html', request)
@ -408,3 +413,86 @@ def del_mailcontact(request, instances):
request request
) )
@login_required
@can_create(DocumentTemplate)
def add_document_template(request):
"""
View used to add a document template.
"""
document_template = DocumentTemplateForm(
request.POST or None,
request.FILES or None,
)
if document_template.is_valid():
document_template.save()
messages.success(
request,
_("The document template was created.")
)
return redirect(reverse('preferences:display-options'))
return form({
'preferenceform': document_template,
'action_name': _("Add"),
'title': _("New document template")
}, 'preferences/preferences.html', request)
@login_required
@can_edit(DocumentTemplate)
def edit_document_template(request, document_template_instance, **_kwargs):
"""
View used to edit a document_template.
"""
document_template = DocumentTemplateForm(
request.POST or None,
request.FILES or None,
instance=document_template_instance)
if document_template.is_valid():
if document_template.changed_data:
document_template.save()
messages.success(
request,
_("The document template was edited.")
)
return redirect(reverse('preferences:display-options'))
return form({
'preferenceform': document_template,
'action_name': _("Edit"),
'title': _("Edit document template")
}, 'preferences/preferences.html', request)
@login_required
@can_delete_set(DocumentTemplate)
def del_document_template(request, instances):
"""
View used to delete a set of document template.
"""
document_template = DelDocumentTemplateForm(
request.POST or None, instances=instances)
if document_template.is_valid():
document_template_del = document_template.cleaned_data['document_templates']
for document_template in document_template_del:
try:
document_template.delete()
messages.success(
request,
_("The document template %(document_template)s was deleted.") % {
'document_template': document_template
}
)
except ProtectedError:
messages.error(
request,
_("The document template %(document_template)s can't be deleted \
because it is currently being used.") % {
'document_template': document_template
}
)
return redirect(reverse('preferences:display-options'))
return form({
'preferenceform': document_template,
'action_name': _("Delete"),
'title': _("Delete document template")
}, 'preferences/preferences.html', request)