8
0
Fork 0
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:
Gabriel Detraz 2017-12-19 21:11:18 +01:00 committed by root
parent 38e096b5df
commit d90ebbe6e6
11 changed files with 288 additions and 8 deletions

View file

@ -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>

View file

@ -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 />

View file

@ -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>

View file

@ -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
)

View 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')),
],
),
]

View 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),
),
]

View file

@ -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

View 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>

View file

@ -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 />

View file

@ -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'),
] ]

View file

@ -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')