mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-24 12:23:11 +00:00
Premier draft d'une app de controle
This commit is contained in:
parent
38e096b5df
commit
d90ebbe6e6
11 changed files with 288 additions and 8 deletions
|
@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
{% load logs_extra %}
|
{% load logs_extra %}
|
||||||
|
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -28,6 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% block title %}Statistiques{% endblock %}
|
{% block title %}Statistiques{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<h2>Centre de contrôle</h2>
|
||||||
|
Aucune jauge objet
|
||||||
|
|
||||||
<h2>Actions effectuées</h2>
|
<h2>Actions effectuées</h2>
|
||||||
{% include "logs/aff_summary.html" with versions_list=versions_list %}
|
{% include "logs/aff_summary.html" with versions_list=versions_list %}
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% if is_cableur %}
|
{% if is_cableur %}
|
||||||
<a class="list-group-item list-group-item-info" href="{% url "logs:index" %}">
|
<a class="list-group-item list-group-item-info" href="{% url "logs:index" %}">
|
||||||
<i class="glyphicon glyphicon-stats"></i>
|
<i class="glyphicon glyphicon-stats"></i>
|
||||||
Résumé
|
Centre de contrôle
|
||||||
</a>
|
</a>
|
||||||
<a class="list-group-item list-group-item-info" href="{% url "logs:stats-logs" %}">
|
<a class="list-group-item list-group-item-info" href="{% url "logs:stats-logs" %}">
|
||||||
<i class="glyphicon glyphicon-stats"></i>
|
<i class="glyphicon glyphicon-stats"></i>
|
||||||
|
|
|
@ -28,8 +28,13 @@ from __future__ import unicode_literals
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from django import forms
|
from django import forms
|
||||||
from .models import OptionalUser, OptionalMachine, OptionalTopologie
|
from .models import OptionalUser, OptionalMachine, OptionalTopologie
|
||||||
from .models import GeneralOption, AssoOption, MailMessageOption, Service
|
from .models import (
|
||||||
|
GeneralOption,
|
||||||
|
AssoOption,
|
||||||
|
MailMessageOption,
|
||||||
|
Service,
|
||||||
|
Jauge
|
||||||
|
)
|
||||||
|
|
||||||
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..)"""
|
||||||
|
@ -177,3 +182,23 @@ class DelServiceForm(Form):
|
||||||
label="Enregistrements service actuels",
|
label="Enregistrements service actuels",
|
||||||
widget=forms.CheckboxSelectMultiple
|
widget=forms.CheckboxSelectMultiple
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class JaugeForm(ModelForm):
|
||||||
|
"""Edition, ajout de jauges"""
|
||||||
|
class Meta:
|
||||||
|
model = Jauge
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||||
|
super(JaugeForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class DelJaugeForm(Form):
|
||||||
|
"""Suppression de services sur la page d'accueil"""
|
||||||
|
services = forms.ModelMultipleChoiceField(
|
||||||
|
queryset=Jauge.objects.all(),
|
||||||
|
label="Enregistrements jauges actuels",
|
||||||
|
widget=forms.CheckboxSelectMultiple
|
||||||
|
)
|
||||||
|
|
28
preferences/migrations/0027_jauge.py
Normal file
28
preferences/migrations/0027_jauge.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-12-16 04:33
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
('preferences', '0026_auto_20171216_0401'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Jauge',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('level_value', models.IntegerField(blank=True, null=True)),
|
||||||
|
('level_percentage', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(100)])),
|
||||||
|
('comment', models.CharField(max_length=255)),
|
||||||
|
('objet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
20
preferences/migrations/0028_jauge_direction.py
Normal file
20
preferences/migrations/0028_jauge_direction.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-12-16 05:06
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('preferences', '0027_jauge'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='jauge',
|
||||||
|
name='direction',
|
||||||
|
field=models.CharField(choices=[('croissant', 'croissant'), ('decroissant', 'decroissant')], default='croissant', max_length=32),
|
||||||
|
),
|
||||||
|
]
|
|
@ -24,8 +24,13 @@
|
||||||
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 django.apps
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.core.validators import MaxValueValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.functional import cached_property
|
||||||
|
from django.apps import apps
|
||||||
|
|
||||||
from cotisations.models import Paiement
|
from cotisations.models import Paiement
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,3 +155,44 @@ class MailMessageOption(models.Model):
|
||||||
|
|
||||||
welcome_mail_fr = models.TextField(default="")
|
welcome_mail_fr = models.TextField(default="")
|
||||||
welcome_mail_en = models.TextField(default="")
|
welcome_mail_en = models.TextField(default="")
|
||||||
|
|
||||||
|
|
||||||
|
class Jauge(models.Model):
|
||||||
|
"""Jauge de contrôle
|
||||||
|
Possibilité de classer en pourcentage ou valeur brute /
|
||||||
|
croissant ou décroissant
|
||||||
|
Exemple : nombre de facture non controlées"""
|
||||||
|
|
||||||
|
DIRECTION_CHOICES = (
|
||||||
|
('croissant', 'croissant'),
|
||||||
|
('decroissant', 'decroissant'),
|
||||||
|
)
|
||||||
|
|
||||||
|
objet = models.ForeignKey(ContentType)
|
||||||
|
level_value = models.IntegerField(blank=True, null=True)
|
||||||
|
level_percentage = models.IntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[MaxValueValidator(100)]
|
||||||
|
)
|
||||||
|
direction = models.CharField(
|
||||||
|
max_length=32,
|
||||||
|
choices=DIRECTION_CHOICES,
|
||||||
|
default='croissant'
|
||||||
|
)
|
||||||
|
comment = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def jauge_state(self):
|
||||||
|
all_object = apps.get_model(self.objet.app_label, self.objet.name).objects.all().count()
|
||||||
|
if self.direction == "croissant":
|
||||||
|
if self.level_value:
|
||||||
|
if all_object > self.level_value:
|
||||||
|
return False
|
||||||
|
#if self.level_percentage:
|
||||||
|
# if all_objet
|
||||||
|
else:
|
||||||
|
if self.level_value:
|
||||||
|
if all_object < self.level_value:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
54
preferences/templates/preferences/aff_jauge.html
Normal file
54
preferences/templates/preferences/aff_jauge.html
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{% 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 %}
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Objet</th>
|
||||||
|
<th>Jauge en pourcentage</th>
|
||||||
|
<th>Jauge en valeur</th>
|
||||||
|
<th>Sens</th>
|
||||||
|
<th>Valeur recherchée</th>
|
||||||
|
<th>Etat</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for jauge in jauge_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ jauge.objet }}</td>
|
||||||
|
<td>{{ jauge.level_percentage }}%</td>
|
||||||
|
<td>{{ jauge.level_value }}</td>
|
||||||
|
<td>{{ jauge.direction }}<td>
|
||||||
|
<td>{{ jauge.comment }}</td>
|
||||||
|
<td>{{ jauge.jauge_state }}<td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% if is_admin %}
|
||||||
|
{% include 'buttons/edit.html' with href='preferences:edit-jauge' id=jauge.id %}
|
||||||
|
{% endif %}
|
||||||
|
{% include 'buttons/history.html' with href='preferences:history' name='jauge' id=jauge.id %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
|
@ -191,6 +191,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-services' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un ou plusieurs service</a>
|
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-services' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer un ou plusieurs service</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "preferences/aff_service.html" with service_list=service_list %}
|
{% include "preferences/aff_service.html" with service_list=service_list %}
|
||||||
|
<h2>Gestion des jauges</h2>
|
||||||
|
{% if is_infra %}
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-jauge' %}"><i class="glyphicon glyphicon-plus"></i> Ajouter une jauge</a>
|
||||||
|
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-jauge' %}"><i class="glyphicon glyphicon-trash"></i> Supprimer une jauge</a>
|
||||||
|
{% endif %}
|
||||||
|
{% include "preferences/aff_jauge.html" with jauge_list=jauge_list %}
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -73,5 +73,17 @@ urlpatterns = [
|
||||||
views.history,
|
views.history,
|
||||||
name='history'
|
name='history'
|
||||||
),
|
),
|
||||||
|
url(r'^add_jauge/$', views.add_jauge, name='add-jauge'),
|
||||||
|
url(
|
||||||
|
r'^edit_jauge/(?P<jaugeid>[0-9]+)$',
|
||||||
|
views.edit_jauge,
|
||||||
|
name='edit-jauge'
|
||||||
|
),
|
||||||
|
url(r'^del_jauge/$', views.del_jauge, name='del-jauge'),
|
||||||
|
url(
|
||||||
|
r'^history/(?P<object_name>jauge)/(?P<object_id>[0-9]+)$',
|
||||||
|
views.history,
|
||||||
|
name='history'
|
||||||
|
),
|
||||||
url(r'^$', views.display_options, name='display-options'),
|
url(r'^$', views.display_options, name='display-options'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -42,9 +42,22 @@ from reversion.models import Version
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
|
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
from .forms import ServiceForm, DelServiceForm
|
from .forms import (
|
||||||
from .models import Service, OptionalUser, OptionalMachine, AssoOption
|
ServiceForm,
|
||||||
from .models import MailMessageOption, GeneralOption, OptionalTopologie
|
DelServiceForm,
|
||||||
|
JaugeForm,
|
||||||
|
DelJaugeForm
|
||||||
|
)
|
||||||
|
from .models import (
|
||||||
|
Service,
|
||||||
|
OptionalUser,
|
||||||
|
OptionalMachine,
|
||||||
|
AssoOption,
|
||||||
|
MailMessageOption,
|
||||||
|
GeneralOption,
|
||||||
|
OptionalTopologie,
|
||||||
|
Jauge
|
||||||
|
)
|
||||||
from . import models
|
from . import models
|
||||||
from . import forms
|
from . import forms
|
||||||
|
|
||||||
|
@ -61,6 +74,7 @@ def display_options(request):
|
||||||
assooptions, _created = AssoOption.objects.get_or_create()
|
assooptions, _created = AssoOption.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()
|
||||||
|
jauge_list = Jauge.objects.all()
|
||||||
return form({
|
return form({
|
||||||
'useroptions': useroptions,
|
'useroptions': useroptions,
|
||||||
'machineoptions': machineoptions,
|
'machineoptions': machineoptions,
|
||||||
|
@ -68,7 +82,8 @@ def display_options(request):
|
||||||
'generaloptions': generaloptions,
|
'generaloptions': generaloptions,
|
||||||
'assooptions': assooptions,
|
'assooptions': assooptions,
|
||||||
'mailmessageoptions': mailmessageoptions,
|
'mailmessageoptions': mailmessageoptions,
|
||||||
'service_list': service_list
|
'service_list': service_list,
|
||||||
|
'jauge_list': jauge_list,
|
||||||
}, 'preferences/display_preferences.html', request)
|
}, 'preferences/display_preferences.html', request)
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,6 +190,76 @@ def del_services(request):
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('admin')
|
||||||
|
def add_jauge(request):
|
||||||
|
"""Ajout d'un service de la page d'accueil"""
|
||||||
|
jauge = JaugeForm(request.POST or None)
|
||||||
|
if jauge.is_valid():
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
jauge.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Création")
|
||||||
|
messages.success(request, "Cette jauge a été ajoutée")
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
return form(
|
||||||
|
{'preferenceform': jauge},
|
||||||
|
'preferences/preferences.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('admin')
|
||||||
|
def edit_jauge(request, jaugeid):
|
||||||
|
"""Edition des jauge affichés sur la page d'accueil"""
|
||||||
|
try:
|
||||||
|
jauge_instance = Jauge.objects.get(pk=jaugeid)
|
||||||
|
except Jauge.DoesNotExist:
|
||||||
|
messages.error(request, u"Entrée inexistante")
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
jauge = JaugeForm(request.POST or None, instance=jauge_instance)
|
||||||
|
if jauge.is_valid():
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
jauge.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment(
|
||||||
|
"Champs modifié(s) : %s" % ', '.join(
|
||||||
|
field for field in jauge.changed_data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
messages.success(request, "Jauge modifié")
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
return form(
|
||||||
|
{'preferenceform': jauge},
|
||||||
|
'preferences/preferences.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('admin')
|
||||||
|
def del_jauge(request):
|
||||||
|
"""Suppression d'un service de la page d'accueil"""
|
||||||
|
jauge = DelJaugeForm(request.POST or None)
|
||||||
|
if jauge.is_valid():
|
||||||
|
jauge_dels = jauge.cleaned_data['jauge']
|
||||||
|
for jauge_del in jauge_dels:
|
||||||
|
try:
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
jauge_del.delete()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
messages.success(request, "Le jauge a été supprimée")
|
||||||
|
except ProtectedError:
|
||||||
|
messages.error(request, "Erreur la jauge\
|
||||||
|
suivant %s ne peut être supprimé" % jauge_del)
|
||||||
|
return redirect(reverse('preferences:display-options'))
|
||||||
|
return form(
|
||||||
|
{'preferenceform': jauge},
|
||||||
|
'preferences/preferences.html',
|
||||||
|
request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('cableur')
|
@permission_required('cableur')
|
||||||
|
|
Loading…
Reference in a new issue