mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-30 08:32:26 +00:00
Merge branch 'master' of https://gitlab.rezometz.org/rezo/re2o
This commit is contained in:
commit
bfb07c3a24
49 changed files with 840 additions and 139 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
settings.py
|
settings_local.py
|
||||||
settings*
|
|
||||||
*.swp
|
*.swp
|
||||||
*.pyc
|
*.pyc
|
||||||
|
__pycache__
|
||||||
|
|
|
@ -3,10 +3,10 @@ from django.contrib import admin
|
||||||
from .models import Facture, Article, Banque, Paiement, Cotisation
|
from .models import Facture, Article, Banque, Paiement, Cotisation
|
||||||
|
|
||||||
class FactureAdmin(admin.ModelAdmin):
|
class FactureAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user','paiement','name', 'number', 'date')
|
list_display = ('user','paiement','name', 'number','prix', 'date','valid')
|
||||||
|
|
||||||
class ArticleAdmin(admin.ModelAdmin):
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name','prix','cotisation')
|
list_display = ('name','prix','cotisation','duration')
|
||||||
|
|
||||||
class BanqueAdmin(admin.ModelAdmin):
|
class BanqueAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name',)
|
list_display = ('name',)
|
||||||
|
|
88
cotisations/forms.py
Normal file
88
cotisations/forms.py
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
from django import forms
|
||||||
|
from django.forms import ModelForm
|
||||||
|
from .models import Article, Paiement, Facture, Banque
|
||||||
|
|
||||||
|
class NewFactureForm(ModelForm):
|
||||||
|
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article")
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(NewFactureForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['number'].label = 'Quantité'
|
||||||
|
self.fields['cheque'].required = False
|
||||||
|
self.fields['banque'].required = False
|
||||||
|
self.fields['cheque'].label = 'Numero de chèque'
|
||||||
|
self.fields['banque'].empty_label = "Non renseigné"
|
||||||
|
self.fields['paiement'].empty_label = "Séléctionner un moyen de paiement"
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Facture
|
||||||
|
fields = ['paiement','banque','cheque','number']
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data=super(NewFactureForm, self).clean()
|
||||||
|
paiement = cleaned_data.get("paiement")
|
||||||
|
cheque = cleaned_data.get("cheque")
|
||||||
|
banque = cleaned_data.get("banque")
|
||||||
|
if paiement.moyen=="chèque" and not (cheque and banque):
|
||||||
|
raise forms.ValidationError("Le numero de chèque et la banque sont obligatoires")
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
class EditFactureForm(NewFactureForm):
|
||||||
|
class Meta(NewFactureForm.Meta):
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(EditFactureForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['user'].label = 'Adherent'
|
||||||
|
self.fields['name'].label = 'Designation'
|
||||||
|
self.fields['prix'].label = 'Prix unitaire'
|
||||||
|
self.fields['user'].empty_label = "Séléctionner l'adhérent propriétaire"
|
||||||
|
self.fields.pop('article')
|
||||||
|
|
||||||
|
class ArticleForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Article
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ArticleForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['name'].label = "Désignation de l'article"
|
||||||
|
|
||||||
|
class DelArticleForm(ModelForm):
|
||||||
|
articles = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Articles actuels", widget=forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
fields = ['articles']
|
||||||
|
model = Article
|
||||||
|
|
||||||
|
class PaiementForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Paiement
|
||||||
|
fields = ['moyen']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(PaiementForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['moyen'].label = 'Moyen de paiement à ajouter'
|
||||||
|
|
||||||
|
class DelPaiementForm(ModelForm):
|
||||||
|
paiements = forms.ModelMultipleChoiceField(queryset=Paiement.objects.all(), label="Moyens de paiement actuels", widget=forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
exclude = ['moyen']
|
||||||
|
model = Paiement
|
||||||
|
|
||||||
|
class BanqueForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Banque
|
||||||
|
fields = ['name']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(BanqueForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['name'].label = 'Banque à ajouter'
|
||||||
|
|
||||||
|
class DelBanqueForm(ModelForm):
|
||||||
|
banques = forms.ModelMultipleChoiceField(queryset=Banque.objects.all(), label="Banques actuelles", widget=forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
exclude = ['name']
|
||||||
|
model = Banque
|
|
@ -1,8 +1,5 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django import forms
|
|
||||||
from django.forms import ModelForm
|
|
||||||
|
|
||||||
from users.models import User
|
|
||||||
|
|
||||||
class Facture(models.Model):
|
class Facture(models.Model):
|
||||||
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
||||||
|
@ -47,31 +44,3 @@ class Cotisation(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.facture)
|
return str(self.facture)
|
||||||
|
|
||||||
class NewFactureForm(ModelForm):
|
|
||||||
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article")
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(NewFactureForm, self).__init__(*args, **kwargs)
|
|
||||||
self.fields['number'].label = 'Quantité'
|
|
||||||
self.fields['cheque'].required = False
|
|
||||||
self.fields['banque'].required = False
|
|
||||||
self.fields['cheque'].label = 'Numero de chèque'
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Facture
|
|
||||||
exclude = ['user', 'prix', 'name', 'valid']
|
|
||||||
|
|
||||||
class EditFactureForm(ModelForm):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(EditFactureForm, self).__init__(*args, **kwargs)
|
|
||||||
self.fields['user'].label = 'Adherent'
|
|
||||||
self.fields['number'].label = 'Quantité'
|
|
||||||
self.fields['cheque'].required = False
|
|
||||||
self.fields['banque'].required = False
|
|
||||||
self.fields['cheque'].label = 'Numero de chèque'
|
|
||||||
self.fields['name'].label = 'Designation'
|
|
||||||
self.fields['prix'].label = 'Prix unitaire'
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Facture
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<td>{{ facture.prix }}</td>
|
<td>{{ facture.prix }}</td>
|
||||||
<td>{{ facture.paiement }}</td>
|
<td>{{ facture.paiement }}</td>
|
||||||
<td>{{ facture.date }}</td>
|
<td>{{ facture.date }}</td>
|
||||||
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:edit-facture' facture.id %}"><i class="glyphicon glyphicon-tree-conifer"></i> Editer</a></td>
|
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:edit-facture' facture.id %}"><i class="glyphicon glyphicon-bitcoin"></i> Editer</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
<p><a href="{% url "search:search" %}">Créer une facture</a></p>
|
|
||||||
<p><a href="{% url "search:search" %}">Editer une facture</a></p>
|
|
||||||
<p><a href="{% url "cotisations:index" %}">Liste des factures</a></p>
|
<p><a href="{% url "cotisations:index" %}">Liste des factures</a></p>
|
||||||
|
<p><a href="{% url "cotisations:add-article" %}">Ajouter un article</a></p>
|
||||||
|
<p><a href="{% url "cotisations:del-article" %}">Retirer un article</a></p>
|
||||||
|
<p><a href="{% url "cotisations:add-paiement" %}">Ajouter un moyen de paiement</a></p>
|
||||||
|
<p><a href="{% url "cotisations:del-paiement" %}">Retirer un moyen de paiement</a></p>
|
||||||
|
<p><a href="{% url "cotisations:add-banque" %}">Ajouter une banque</a></p>
|
||||||
|
<p><a href="{% url "cotisations:del-banque" %}">Retirer une banque</a></p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -5,6 +5,12 @@ from . import views
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^new_facture/(?P<userid>[0-9]+)$', views.new_facture, name='new-facture'),
|
url(r'^new_facture/(?P<userid>[0-9]+)$', views.new_facture, name='new-facture'),
|
||||||
url(r'^edit_facture/(?P<factureid>[0-9]+)$', views.edit_facture, name='edit-facture'),
|
url(r'^edit_facture/(?P<factureid>[0-9]+)$', views.edit_facture, name='edit-facture'),
|
||||||
|
url(r'^add_article/$', views.add_article, name='add-article'),
|
||||||
|
url(r'^del_article/$', views.del_article, name='del-article'),
|
||||||
|
url(r'^add_paiement/$', views.add_paiement, name='add-paiement'),
|
||||||
|
url(r'^del_paiement/$', views.del_paiement, name='del-paiement'),
|
||||||
|
url(r'^add_banque/$', views.add_banque, name='add-banque'),
|
||||||
|
url(r'^del_banque/$', views.del_banque, name='del-banque'),
|
||||||
url(r'^$', views.index, name='index'),
|
url(r'^$', views.index, name='index'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ from django.shortcuts import render_to_response, get_object_or_404
|
||||||
from django.core.context_processors import csrf
|
from django.core.context_processors import csrf
|
||||||
from django.template import Context, RequestContext, loader
|
from django.template import Context, RequestContext, loader
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db.models import Max
|
from django.db.models import Max, ProtectedError
|
||||||
|
|
||||||
from cotisations.models import NewFactureForm, EditFactureForm, Facture, Article, Cotisation
|
from .models import Facture, Article, Cotisation, Article
|
||||||
|
from .forms import NewFactureForm, EditFactureForm, ArticleForm, DelArticleForm, PaiementForm, DelPaiementForm, BanqueForm, DelBanqueForm
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
@ -34,14 +35,14 @@ def is_adherent(user):
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def create_cotis(facture, user, article):
|
def create_cotis(facture, user, duration):
|
||||||
""" Update et crée l'objet cotisation associé à une facture, prend en argument l'user, la facture pour la quantitéi, et l'article pour la durée"""
|
""" Update et crée l'objet cotisation associé à une facture, prend en argument l'user, la facture pour la quantitéi, et l'article pour la durée"""
|
||||||
cotisation=Cotisation(facture=facture)
|
cotisation=Cotisation(facture=facture)
|
||||||
date_max = end_adhesion(user) or timezone.now()
|
date_max = end_adhesion(user) or timezone.now()
|
||||||
if date_max < timezone.now():
|
if date_max < timezone.now():
|
||||||
datemax = timezone.now()
|
datemax = timezone.now()
|
||||||
cotisation.date_start=date_max
|
cotisation.date_start=date_max
|
||||||
cotisation.date_end = cotisation.date_start + relativedelta(months=article[0].duration*facture.number)
|
cotisation.date_end = cotisation.date_start + relativedelta(months=duration)
|
||||||
cotisation.save()
|
cotisation.save()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -56,11 +57,12 @@ def new_facture(request, userid):
|
||||||
if facture_form.is_valid():
|
if facture_form.is_valid():
|
||||||
new_facture = facture_form.save(commit=False)
|
new_facture = facture_form.save(commit=False)
|
||||||
article = facture_form.cleaned_data['article']
|
article = facture_form.cleaned_data['article']
|
||||||
new_facture.prix = article[0].prix
|
new_facture.prix = sum(art.prix for art in article)
|
||||||
new_facture.name = article[0].name
|
new_facture.name = ' - '.join(art.name for art in article)
|
||||||
new_facture.save()
|
new_facture.save()
|
||||||
if article[0].cotisation == True:
|
if any(art.cotisation for art in article):
|
||||||
create_cotis(new_facture, user, article)
|
duration = sum(art.duration*facture.number for art in article if art.cotisation)
|
||||||
|
create_cotis(new_facture, user, duration)
|
||||||
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s " % user.name )
|
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s " % user.name )
|
||||||
else:
|
else:
|
||||||
messages.success(request, "La facture a été crée")
|
messages.success(request, "La facture a été crée")
|
||||||
|
@ -80,6 +82,65 @@ def edit_facture(request, factureid):
|
||||||
return redirect("/cotisations/")
|
return redirect("/cotisations/")
|
||||||
return form({'factureform': facture_form}, 'cotisations/facture.html', request)
|
return form({'factureform': facture_form}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
|
def add_article(request):
|
||||||
|
article = ArticleForm(request.POST or None)
|
||||||
|
if article.is_valid():
|
||||||
|
article.save()
|
||||||
|
messages.success(request, "L'article a été ajouté")
|
||||||
|
return redirect("/cotisations/")
|
||||||
|
return form({'factureform': article}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
|
def del_article(request):
|
||||||
|
article = DelArticleForm(request.POST or None)
|
||||||
|
if article.is_valid():
|
||||||
|
article_del = article.cleaned_data['articles']
|
||||||
|
article_del.delete()
|
||||||
|
messages.success(request, "Le/les articles ont été supprimé")
|
||||||
|
return redirect("/cotisations/")
|
||||||
|
return form({'factureform': article}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
|
def add_paiement(request):
|
||||||
|
paiement = PaiementForm(request.POST or None)
|
||||||
|
if paiement.is_valid():
|
||||||
|
paiement.save()
|
||||||
|
messages.success(request, "Le moyen de paiement a été ajouté")
|
||||||
|
return redirect("/cotisations/")
|
||||||
|
return form({'factureform': paiement}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
|
def del_paiement(request):
|
||||||
|
paiement = DelPaiementForm(request.POST or None)
|
||||||
|
if paiement.is_valid():
|
||||||
|
paiement_dels = paiement.cleaned_data['paiements']
|
||||||
|
for paiement_del in paiement_dels:
|
||||||
|
try:
|
||||||
|
paiement_del.delete()
|
||||||
|
messages.success(request, "Le moyen de paiement a été supprimé")
|
||||||
|
except ProtectedError:
|
||||||
|
messages.error(request, "Le moyen de paiement %s est affecté à au moins une facture, vous ne pouvez pas le supprimer" % paiement_del)
|
||||||
|
return redirect("/cotisations/")
|
||||||
|
return form({'factureform': paiement}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
|
def add_banque(request):
|
||||||
|
banque = BanqueForm(request.POST or None)
|
||||||
|
if banque.is_valid():
|
||||||
|
banque.save()
|
||||||
|
messages.success(request, "La banque a été ajoutée")
|
||||||
|
return redirect("/cotisations/")
|
||||||
|
return form({'factureform': banque}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
|
def del_banque(request):
|
||||||
|
banque = DelBanqueForm(request.POST or None)
|
||||||
|
if banque.is_valid():
|
||||||
|
banque_dels = banque.cleaned_data['banques']
|
||||||
|
for banque_del in banque_dels:
|
||||||
|
try:
|
||||||
|
banque_del.delete()
|
||||||
|
messages.success(request, "La banque a été supprimée")
|
||||||
|
except ProtectedError:
|
||||||
|
messages.error(request, "La banque %s est affectée à au moins une facture, vous ne pouvez pas la supprimer" % banque_del)
|
||||||
|
return redirect("/cotisations/")
|
||||||
|
return form({'factureform': banque}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
facture_list = Facture.objects.order_by('pk')
|
facture_list = Facture.objects.order_by('date').reverse()
|
||||||
return render(request, 'cotisations/index.html', {'facture_list': facture_list})
|
return render(request, 'cotisations/index.html', {'facture_list': facture_list})
|
||||||
|
|
|
@ -3,7 +3,7 @@ from django.contrib import admin
|
||||||
from .models import Machine, MachineType, IpList, Interface
|
from .models import Machine, MachineType, IpList, Interface
|
||||||
|
|
||||||
class MachineAdmin(admin.ModelAdmin):
|
class MachineAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user','name','type')
|
list_display = ('user','name','type','active')
|
||||||
|
|
||||||
class MachineTypeAdmin(admin.ModelAdmin):
|
class MachineTypeAdmin(admin.ModelAdmin):
|
||||||
list_display = ('type',)
|
list_display = ('type',)
|
||||||
|
|
24
machines/migrations/0013_auto_20160705_1014.py
Normal file
24
machines/migrations/0013_auto_20160705_1014.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('machines', '0012_auto_20160704_0118'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='machine',
|
||||||
|
name='active',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='interface',
|
||||||
|
name='dns',
|
||||||
|
field=models.CharField(max_length=255, unique=True, help_text='Obligatoire et unique, doit se terminer en .rez et ne pas comporter de points'),
|
||||||
|
),
|
||||||
|
]
|
20
machines/migrations/0014_auto_20160706_1220.py
Normal file
20
machines/migrations/0014_auto_20160706_1220.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import machines.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('machines', '0013_auto_20160705_1014'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='interface',
|
||||||
|
name='dns',
|
||||||
|
field=models.CharField(unique=True, validators=[machines.models.full_domain_validator], max_length=255, help_text="Obligatoire et unique, doit se terminer en .rez et ne pas comporter d'autres points"),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,13 +1,38 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form, ValidationError
|
||||||
from macaddress.fields import MACAddressField
|
from macaddress.fields import MACAddressField
|
||||||
|
|
||||||
from users.models import User
|
from django.conf import settings
|
||||||
|
import re
|
||||||
|
|
||||||
|
def full_domain_validator(hostname):
|
||||||
|
""" Validation du nom de domaine, extensions dans settings, prefixe pas plus long que 63 caractères """
|
||||||
|
HOSTNAME_LABEL_PATTERN = re.compile("(?!-)[A-Z\d-]+(?<!-)$", re.IGNORECASE)
|
||||||
|
if not any(ext in hostname for ext in settings.ALLOWED_EXTENSIONS):
|
||||||
|
raise ValidationError(
|
||||||
|
", le nom de domaine '%(label)s' doit comporter une extension valide",
|
||||||
|
params={'label': hostname},
|
||||||
|
)
|
||||||
|
for extension in settings.ALLOWED_EXTENSIONS:
|
||||||
|
if hostname.endswith(extension):
|
||||||
|
hostname=re.sub('%s$' % extension, '', hostname)
|
||||||
|
break
|
||||||
|
if len(hostname) > 63:
|
||||||
|
raise ValidationError(
|
||||||
|
", le nom de domaine '%(label)s' est trop long (maximum de 63 caractères).",
|
||||||
|
params={'label': hostname},
|
||||||
|
)
|
||||||
|
if not HOSTNAME_LABEL_PATTERN.match(hostname):
|
||||||
|
raise ValidationError(
|
||||||
|
", ce nom de domaine '%(label)s' contient des carractères interdits.",
|
||||||
|
params={'label': hostname},
|
||||||
|
)
|
||||||
|
|
||||||
class Machine(models.Model):
|
class Machine(models.Model):
|
||||||
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
||||||
type = models.ForeignKey('MachineType', on_delete=models.PROTECT)
|
type = models.ForeignKey('MachineType', on_delete=models.PROTECT)
|
||||||
name = models.CharField(max_length=255, help_text="Optionnel", blank=True, null=True)
|
name = models.CharField(max_length=255, help_text="Optionnel", blank=True, null=True)
|
||||||
|
active = models.BooleanField(default=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.user) + ' - ' + str(self.id) + ' - ' + str(self.name)
|
return str(self.user) + ' - ' + str(self.id) + ' - ' + str(self.name)
|
||||||
|
@ -25,11 +50,14 @@ class Interface(models.Model):
|
||||||
mac_address = MACAddressField(integer=False, unique=True)
|
mac_address = MACAddressField(integer=False, unique=True)
|
||||||
machine = models.ForeignKey('Machine', on_delete=models.PROTECT)
|
machine = models.ForeignKey('Machine', on_delete=models.PROTECT)
|
||||||
details = models.CharField(max_length=255, blank=True)
|
details = models.CharField(max_length=255, blank=True)
|
||||||
dns = models.CharField(help_text="Obligatoire et unique", max_length=255, unique=True)
|
dns = models.CharField(help_text="Obligatoire et unique, doit se terminer en %s et ne pas comporter d'autres points" % ", ".join(settings.ALLOWED_EXTENSIONS), max_length=255, unique=True, validators=[full_domain_validator])
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.dns
|
return self.dns
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
self.dns=self.dns.lower()
|
||||||
|
|
||||||
class IpList(models.Model):
|
class IpList(models.Model):
|
||||||
ipv4 = models.GenericIPAddressField(protocol='IPv4', unique=True)
|
ipv4 = models.GenericIPAddressField(protocol='IPv4', unique=True)
|
||||||
|
|
||||||
|
@ -45,6 +73,7 @@ class EditMachineForm(ModelForm):
|
||||||
super(EditMachineForm, self).__init__(*args, **kwargs)
|
super(EditMachineForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['name'].label = 'Nom de la machine'
|
self.fields['name'].label = 'Nom de la machine'
|
||||||
self.fields['type'].label = 'Type de machine'
|
self.fields['type'].label = 'Type de machine'
|
||||||
|
self.fields['type'].empty_label = "Séléctionner un type de machine"
|
||||||
|
|
||||||
class NewMachineForm(EditMachineForm):
|
class NewMachineForm(EditMachineForm):
|
||||||
class Meta(EditMachineForm.Meta):
|
class Meta(EditMachineForm.Meta):
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<td>{{ machine.machine.type }}</td>
|
<td>{{ machine.machine.type }}</td>
|
||||||
<td>{{ machine.mac_address }}</td>
|
<td>{{ machine.mac_address }}</td>
|
||||||
<td>{{ machine.ipv4 }}</td>
|
<td>{{ machine.ipv4 }}</td>
|
||||||
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:edit-machine' machine.id %}"><i class="glyphicon glyphicon-tree-conifer"></i> Editer</a></td>
|
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:edit-machine' machine.id %}"><i class="glyphicon glyphicon-hdd"></i> Editer</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
<p><a href="{% url "search:search" %}">Nouvelle machine</a></p>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
108
re2o/settings.py
Normal file
108
re2o/settings.py
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
"""
|
||||||
|
Django settings for re2o project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 1.8.13.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/1.8/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/1.8/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
|
import os
|
||||||
|
from .settings_local import SECRET_KEY, DATABASES, DEBUG, ALLOWED_HOSTS, ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = (
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'bootstrap3',
|
||||||
|
'users',
|
||||||
|
'machines',
|
||||||
|
'cotisations',
|
||||||
|
'topologie',
|
||||||
|
'search',
|
||||||
|
'logs',
|
||||||
|
)
|
||||||
|
|
||||||
|
MIDDLEWARE_CLASSES = (
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
)
|
||||||
|
|
||||||
|
ROOT_URLCONF = 're2o.urls'
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [
|
||||||
|
os.path.join(BASE_DIR, 'templates').replace('\\', '/'),
|
||||||
|
],
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 're2o.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'fr-fr'
|
||||||
|
|
||||||
|
TIME_ZONE = 'Europe/Paris'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
# django-bootstrap3 config dictionnary
|
||||||
|
BOOTSTRAP3 = {
|
||||||
|
'jquery_url': '/static/js/jquery-2.2.4.min.js',
|
||||||
|
'base_url': '/static/bootstrap/',
|
||||||
|
'include_jquery': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOTSTRAP_BASE_URL = '/static/bootstrap/'
|
||||||
|
|
||||||
|
STATICFILES_DIRS = (
|
||||||
|
# Put strings here, like "/home/html/static" or "C:/www/django/static".
|
||||||
|
# Always use forward slashes, even on Windows.
|
||||||
|
# Don't forget to use absolute paths, not relative paths.
|
||||||
|
os.path.join(
|
||||||
|
BASE_DIR,
|
||||||
|
'static',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
STATIC_URL = '/static/'
|
20
re2o/settings_local.example.py
Normal file
20
re2o/settings_local.example.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
SECRET_KEY = 'SUPER_SECRET'
|
||||||
|
|
||||||
|
DB_PASSWORD = 'SUPER_SECRET'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
|
'NAME': 're2o',
|
||||||
|
'USER': 're2o',
|
||||||
|
'PASSWORD': DB_PASSWORD,
|
||||||
|
'HOST': 'localhost',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLOWED_EXTENSIONS = ['.example']
|
|
@ -24,5 +24,6 @@ urlpatterns = [
|
||||||
url(r'^search/', include('search.urls', namespace='search')),
|
url(r'^search/', include('search.urls', namespace='search')),
|
||||||
url(r'^cotisations/', include('cotisations.urls', namespace='cotisations')),
|
url(r'^cotisations/', include('cotisations.urls', namespace='cotisations')),
|
||||||
url(r'^machines/', include('machines.urls', namespace='machines')),
|
url(r'^machines/', include('machines.urls', namespace='machines')),
|
||||||
|
url(r'^topologie/', include('topologie.urls', namespace='topologie')),
|
||||||
#url(r'^logs/', include('logs.urls', namespace='logs')),
|
#url(r'^logs/', include('logs.urls', namespace='logs')),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,9 +3,6 @@ from django import forms
|
||||||
from django.forms import Form
|
from django.forms import Form
|
||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
|
|
||||||
from users.models import User
|
|
||||||
# Create your models here.
|
|
||||||
|
|
||||||
CHOICES = (
|
CHOICES = (
|
||||||
('0', 'Actifs'),
|
('0', 'Actifs'),
|
||||||
('1', 'Désactivés'),
|
('1', 'Désactivés'),
|
||||||
|
|
|
@ -12,6 +12,7 @@ from machines.models import Machine, Interface
|
||||||
from cotisations.models import Facture
|
from cotisations.models import Facture
|
||||||
from search.models import SearchForm, SearchFormPlus
|
from search.models import SearchForm, SearchFormPlus
|
||||||
from users.views import has_access
|
from users.views import has_access
|
||||||
|
from cotisations.views import end_adhesion
|
||||||
|
|
||||||
def form(ctx, template, request):
|
def form(ctx, template, request):
|
||||||
c = ctx
|
c = ctx
|
||||||
|
@ -23,7 +24,7 @@ def search_result(search, type):
|
||||||
date_fin = None
|
date_fin = None
|
||||||
states=[]
|
states=[]
|
||||||
co=[]
|
co=[]
|
||||||
aff=[0,1,2,3,4]
|
aff=['0','1','2','3','4']
|
||||||
if(type):
|
if(type):
|
||||||
aff = search.cleaned_data['affichage']
|
aff = search.cleaned_data['affichage']
|
||||||
co = search.cleaned_data['connexion']
|
co = search.cleaned_data['connexion']
|
||||||
|
@ -32,7 +33,7 @@ def search_result(search, type):
|
||||||
date_fin = search.cleaned_data['date_fin']
|
date_fin = search.cleaned_data['date_fin']
|
||||||
date_query = Q()
|
date_query = Q()
|
||||||
if aff==[]:
|
if aff==[]:
|
||||||
aff = [0,1,2,3,4]
|
aff = ['0','1','2','3','4']
|
||||||
if date_deb != None:
|
if date_deb != None:
|
||||||
date_query = date_query & Q(date__gte=date_deb)
|
date_query = date_query & Q(date__gte=date_deb)
|
||||||
if date_fin != None:
|
if date_fin != None:
|
||||||
|
@ -54,9 +55,13 @@ def search_result(search, type):
|
||||||
users = User.objects.filter((Q(pseudo__icontains = search) | Q(name__icontains = search) | Q(surname__icontains = search)) & query)
|
users = User.objects.filter((Q(pseudo__icontains = search) | Q(name__icontains = search) | Q(surname__icontains = search)) & query)
|
||||||
connexion = []
|
connexion = []
|
||||||
for user in users:
|
for user in users:
|
||||||
|
end=end_adhesion(user)
|
||||||
access=has_access(user)
|
access=has_access(user)
|
||||||
if(len(co)==0 or (len(co)==1 and bool(co[0])==access) or (len(co)==2 and (bool(co[0])==access or bool(co[1])==access))):
|
if(len(co)==0 or (len(co)==1 and bool(co[0])==access) or (len(co)==2 and (bool(co[0])==access or bool(co[1])==access))):
|
||||||
connexion.append([user, access])
|
if(end!=None):
|
||||||
|
connexion.append([user, access, end])
|
||||||
|
else:
|
||||||
|
connexion.append([user, access, "Non adhérent"])
|
||||||
query = Q(user__pseudo__icontains = search) | Q(user__name__icontains = search) | Q(user__surname__icontains = search)
|
query = Q(user__pseudo__icontains = search) | Q(user__name__icontains = search) | Q(user__surname__icontains = search)
|
||||||
if i == '1':
|
if i == '1':
|
||||||
machines = Interface.objects.filter(machine=Machine.objects.filter(query)) | Interface.objects.filter(Q(dns__icontains = search))
|
machines = Interface.objects.filter(machine=Machine.objects.filter(query)) | Interface.objects.filter(Q(dns__icontains = search))
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<li><a href="{% url "users:index" %}">Adhérents</a></li>
|
<li><a href="{% url "users:index" %}">Adhérents</a></li>
|
||||||
<li><a href="{% url "machines:index" %}">Machines</a></li>
|
<li><a href="{% url "machines:index" %}">Machines</a></li>
|
||||||
<li><a href="{% url "cotisations:index" %}">Cotisations</a></li>
|
<li><a href="{% url "cotisations:index" %}">Cotisations</a></li>
|
||||||
<li><a href="#">Topologie</a></li>
|
<li><a href="{% url "topologie:index" %}">Topologie</a></li>
|
||||||
<li><a href="#">Statistiques</a></li>
|
<li><a href="#">Statistiques</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="col-sm-3 col-md-3 navbar-right">
|
<div class="col-sm-3 col-md-3 navbar-right">
|
||||||
|
|
|
@ -7,7 +7,7 @@ class SwitchAdmin(admin.ModelAdmin):
|
||||||
list_display = ('building','number','details')
|
list_display = ('building','number','details')
|
||||||
|
|
||||||
class PortAdmin(admin.ModelAdmin):
|
class PortAdmin(admin.ModelAdmin):
|
||||||
list_display = ('switch', 'port','room','details')
|
list_display = ('switch', 'port','room','machine_interface','details')
|
||||||
|
|
||||||
class RoomAdmin(admin.ModelAdmin):
|
class RoomAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name',)
|
list_display = ('name',)
|
||||||
|
|
11
topologie/forms.py
Normal file
11
topologie/forms.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from .models import Port
|
||||||
|
from django.forms import ModelForm, Form
|
||||||
|
|
||||||
|
class PortForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Port
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class EditPortForm(ModelForm):
|
||||||
|
class Meta(PortForm.Meta):
|
||||||
|
fields = ['room', 'machine_interface', 'related', 'details']
|
21
topologie/migrations/0012_port_machine_interface.py
Normal file
21
topologie/migrations/0012_port_machine_interface.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('machines', '0014_auto_20160706_1220'),
|
||||||
|
('topologie', '0011_auto_20160704_2153'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='port',
|
||||||
|
name='machine_interface',
|
||||||
|
field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, null=True, blank=True, to='machines.Interface'),
|
||||||
|
),
|
||||||
|
]
|
19
topologie/migrations/0013_port_related.py
Normal file
19
topologie/migrations/0013_port_related.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0012_port_machine_interface'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='port',
|
||||||
|
name='related',
|
||||||
|
field=models.OneToOneField(null=True, to='topologie.Port', blank=True, related_name='related_port'),
|
||||||
|
),
|
||||||
|
]
|
26
topologie/migrations/0014_auto_20160706_1238.py
Normal file
26
topologie/migrations/0014_auto_20160706_1238.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0013_port_related'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='port',
|
||||||
|
unique_together=set([('switch', 'port')]),
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='port',
|
||||||
|
name='_content_type',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='port',
|
||||||
|
name='_object_id',
|
||||||
|
),
|
||||||
|
]
|
23
topologie/migrations/0015_auto_20160706_1452.py
Normal file
23
topologie/migrations/0015_auto_20160706_1452.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0014_auto_20160706_1238'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='port',
|
||||||
|
name='related',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='port',
|
||||||
|
name='related',
|
||||||
|
field=models.ManyToManyField(related_name='_port_related_+', to='topologie.Port', blank=True),
|
||||||
|
),
|
||||||
|
]
|
23
topologie/migrations/0016_auto_20160706_1531.py
Normal file
23
topologie/migrations/0016_auto_20160706_1531.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0015_auto_20160706_1452'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='port',
|
||||||
|
name='related',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='port',
|
||||||
|
name='related',
|
||||||
|
field=models.OneToOneField(blank=True, to='topologie.Port', related_name='related_port', null=True),
|
||||||
|
),
|
||||||
|
]
|
Binary file not shown.
|
@ -1,7 +1,18 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.forms import ModelForm, Form
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
def make_port_related(port):
|
||||||
|
related_port = port.related
|
||||||
|
related_port.related = port
|
||||||
|
related_port.save()
|
||||||
|
|
||||||
|
def clean_port_related(port):
|
||||||
|
related_port = port.related_port
|
||||||
|
related_port.related = None
|
||||||
|
related_port.save()
|
||||||
|
|
||||||
class Switch(models.Model):
|
class Switch(models.Model):
|
||||||
building = models.CharField(max_length=10)
|
building = models.CharField(max_length=10)
|
||||||
|
@ -17,25 +28,26 @@ class Switch(models.Model):
|
||||||
class Port(models.Model):
|
class Port(models.Model):
|
||||||
switch = models.ForeignKey(Switch, related_name="ports")
|
switch = models.ForeignKey(Switch, related_name="ports")
|
||||||
port = models.IntegerField()
|
port = models.IntegerField()
|
||||||
details = models.CharField(max_length=255, blank=True)
|
|
||||||
room = models.ForeignKey('Room', on_delete=models.PROTECT, blank=True, null=True)
|
room = models.ForeignKey('Room', on_delete=models.PROTECT, blank=True, null=True)
|
||||||
# machine_interface = models.OneToOneField('machines.Interface', on_delete=models.PROTECT, blank=True, null=True)
|
machine_interface = models.OneToOneField('machines.Interface', on_delete=models.PROTECT, blank=True, null=True)
|
||||||
|
related = models.OneToOneField('self', null=True, blank=True, related_name='related_port')
|
||||||
|
details = models.CharField(max_length=255, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('_content_type', '_object_id')
|
unique_together = ('switch', 'port')
|
||||||
|
|
||||||
_content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True)
|
def clean(self):
|
||||||
_object_id = models.PositiveIntegerField(blank=True, null=True)
|
if self.room and self.machine_interface or self.room and self.related or self.machine_interface and self.related:
|
||||||
goto = GenericForeignKey('_content_type', '_object_id')
|
raise ValidationError("Chambre, interface et related_port sont mutuellement exclusifs")
|
||||||
|
if self.related==self:
|
||||||
@property
|
raise ValidationError("On ne peut relier un port à lui même")
|
||||||
def comefrom(self):
|
if self.related and not self.related.related:
|
||||||
ctype = ContentType.objects.get_for_model(self.__class__)
|
if self.related.machine_interface or self.related.room:
|
||||||
try:
|
raise ValidationError("Le port relié est déjà occupé, veuillez le libérer avant de créer une relation")
|
||||||
event = Port.objects.get(_content_type__pk=ctype.id, _object_id=self.id)
|
else:
|
||||||
except:
|
make_port_related(self)
|
||||||
return None
|
elif hasattr(self, 'related_port'):
|
||||||
return event
|
clean_port_related(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.switch) + " - " + str(self.port)
|
return str(self.switch) + " - " + str(self.port)
|
||||||
|
|
23
topologie/templates/topologie/aff_port.html
Normal file
23
topologie/templates/topologie/aff_port.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<h2>Switch {% if port_list.0 %}{{ port_list.0.switch }}{% endif %}</h2>
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Port</th>
|
||||||
|
<th>Room</th>
|
||||||
|
<th>Interface machine</th>
|
||||||
|
<th>Related</th>
|
||||||
|
<th>Détails</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for port in port_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ port.port }}</td>
|
||||||
|
<td>{{ port.room }}</td>
|
||||||
|
<td>{{ port.machine_interface }}</td>
|
||||||
|
<td>{{ port.related }}</td>
|
||||||
|
<td>{{ port.details }}</td>
|
||||||
|
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:edit-port' port.id %}"><i class="glyphicon glyphicon-random"></i> Editer</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
18
topologie/templates/topologie/aff_switch.html
Normal file
18
topologie/templates/topologie/aff_switch.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Bâtiment</th>
|
||||||
|
<th>Numero</th>
|
||||||
|
<th>Détails</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for switch in switch_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{switch.building}}</td>
|
||||||
|
<td>{{switch.number}}</td>
|
||||||
|
<td>{{switch.details}}</td>
|
||||||
|
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:index-port' switch.pk %}"><i class="glyphicon glyphicon-list-alt"></i> Editer</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
11
topologie/templates/topologie/index.html
Normal file
11
topologie/templates/topologie/index.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends "topologie/sidebar.html" %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}Switchs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% include "topologie/aff_switch.html" with switch_list=switch_list %}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
11
topologie/templates/topologie/index_p.html
Normal file
11
topologie/templates/topologie/index_p.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends "topologie/sidebar.html" %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}Ports du switch{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% include "topologie/aff_port.html" with port_list=port_list %}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
17
topologie/templates/topologie/port.html
Normal file
17
topologie/templates/topologie/port.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "topologie/sidebar.html" %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}Création et modificationd 'utilisateur{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% bootstrap_form_errors topoform %}
|
||||||
|
|
||||||
|
<form class="form" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form topoform %}
|
||||||
|
{%bootstrap_button "Créer ou modifier" button_type="submit" icon="ok" %}
|
||||||
|
</form>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
5
topologie/templates/topologie/sidebar.html
Normal file
5
topologie/templates/topologie/sidebar.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block sidebar %}
|
||||||
|
<p><a href="{% url "topologie:index" %}">Liste des switchs</a></p>
|
||||||
|
{% endblock %}
|
10
topologie/urls.py
Normal file
10
topologie/urls.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', views.index, name='index'),
|
||||||
|
url(r'^switch/(?P<switch_id>[0-9]+)$', views.index_port, name='index-port'),
|
||||||
|
url(r'^edit_port/(?P<port_id>[0-9]+)$', views.edit_port, name='edit-port'),
|
||||||
|
]
|
||||||
|
|
|
@ -1,3 +1,35 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render, redirect
|
||||||
|
from django.contrib import messages
|
||||||
|
|
||||||
# Create your views here.
|
|
||||||
|
from topologie.models import Switch, Port
|
||||||
|
from topologie.forms import EditPortForm
|
||||||
|
from users.views import form
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
switch_list = Switch.objects.order_by('building', 'number')
|
||||||
|
return render(request, 'topologie/index.html', {'switch_list': switch_list})
|
||||||
|
|
||||||
|
def index_port(request, switch_id):
|
||||||
|
try:
|
||||||
|
switch = Switch.objects.get(pk=switch_id)
|
||||||
|
except Switch.DoesNotExist:
|
||||||
|
messages.error(request, u"Switch inexistant")
|
||||||
|
return redirect("/topologie/")
|
||||||
|
port_list = Port.objects.filter(switch = switch).order_by('port')
|
||||||
|
return render(request, 'topologie/index_p.html', {'port_list':port_list})
|
||||||
|
|
||||||
|
def edit_port(request, port_id):
|
||||||
|
try:
|
||||||
|
port = Port.objects.get(pk=port_id)
|
||||||
|
except Port.DoesNotExist:
|
||||||
|
messages.error(request, u"Port inexistant")
|
||||||
|
return redirect("/topologie/")
|
||||||
|
port = EditPortForm(request.POST or None, instance=port)
|
||||||
|
if port.is_valid():
|
||||||
|
port.save()
|
||||||
|
messages.success(request, "Le port a bien été modifié")
|
||||||
|
return redirect("/topologie")
|
||||||
|
return form({'topoform':port}, 'topologie/port.html', request)
|
||||||
|
|
||||||
|
|
30
users/migrations/0016_auto_20160706_1220.py
Normal file
30
users/migrations/0016_auto_20160706_1220.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import users.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0015_whitelist'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ban',
|
||||||
|
name='date_end',
|
||||||
|
field=models.DateTimeField(help_text='%d/%m/%y %H:%M:%S'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='pseudo',
|
||||||
|
field=models.CharField(unique=True, validators=[users.models.linux_user_validator], max_length=32, help_text='Doit contenir uniquement des lettres, chiffres, ou tirets'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='whitelist',
|
||||||
|
name='date_end',
|
||||||
|
field=models.DateTimeField(help_text='%d/%m/%y %H:%M:%S'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from django import forms
|
from django import forms
|
||||||
|
import re
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
@ -15,6 +16,15 @@ def remove_user_room(room):
|
||||||
user.room = None
|
user.room = None
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
|
def linux_user_validator(login):
|
||||||
|
""" Validation du pseudo pour respecter les contraintes unix"""
|
||||||
|
UNIX_LOGIN_PATTERN = re.compile("^[a-z_][a-z0-9_-]*[$]?$")
|
||||||
|
if not UNIX_LOGIN_PATTERN.match(login):
|
||||||
|
raise forms.ValidationError(
|
||||||
|
", ce pseudo ('%(label)s') contient des carractères interdits",
|
||||||
|
params={'label': login},
|
||||||
|
)
|
||||||
|
|
||||||
class User(models.Model):
|
class User(models.Model):
|
||||||
STATE_ACTIVE = 0
|
STATE_ACTIVE = 0
|
||||||
STATE_DEACTIVATED = 1
|
STATE_DEACTIVATED = 1
|
||||||
|
@ -27,9 +37,9 @@ class User(models.Model):
|
||||||
|
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
surname = models.CharField(max_length=255)
|
surname = models.CharField(max_length=255)
|
||||||
pseudo = models.CharField(max_length=255, unique=True)
|
pseudo = models.CharField(max_length=32, unique=True, help_text="Doit contenir uniquement des lettres, chiffres, ou tirets", validators=[linux_user_validator])
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
school = models.ForeignKey('School', on_delete=models.PROTECT)
|
school = models.ForeignKey('School', on_delete=models.PROTECT, null=False, blank=False)
|
||||||
comment = models.CharField(help_text="Commentaire, promo", max_length=255, blank=True)
|
comment = models.CharField(help_text="Commentaire, promo", max_length=255, blank=True)
|
||||||
room = models.OneToOneField('topologie.Room', on_delete=models.PROTECT, blank=True, null=True)
|
room = models.OneToOneField('topologie.Room', on_delete=models.PROTECT, blank=True, null=True)
|
||||||
pwd_ssha = models.CharField(max_length=255)
|
pwd_ssha = models.CharField(max_length=255)
|
||||||
|
@ -66,7 +76,7 @@ class Ban(models.Model):
|
||||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||||
raison = models.CharField(max_length=255)
|
raison = models.CharField(max_length=255)
|
||||||
date_start = models.DateTimeField(auto_now_add=True)
|
date_start = models.DateTimeField(auto_now_add=True)
|
||||||
date_end = models.DateTimeField(help_text='%m/%d/%y %H:%M:%S')
|
date_end = models.DateTimeField(help_text='%d/%m/%y %H:%M:%S')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.user) + ' ' + str(self.raison)
|
return str(self.user) + ' ' + str(self.raison)
|
||||||
|
@ -75,24 +85,11 @@ class Whitelist(models.Model):
|
||||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||||
raison = models.CharField(max_length=255)
|
raison = models.CharField(max_length=255)
|
||||||
date_start = models.DateTimeField(auto_now_add=True)
|
date_start = models.DateTimeField(auto_now_add=True)
|
||||||
date_end = models.DateTimeField(help_text='%m/%d/%y %H:%M:%S')
|
date_end = models.DateTimeField(help_text='%d/%m/%y %H:%M:%S')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.user) + ' ' + str(self.raison)
|
return str(self.user) + ' ' + str(self.raison)
|
||||||
|
|
||||||
class UserForm(ModelForm):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(InfoForm, self).__init__(*args, **kwargs)
|
|
||||||
self.fields['name'].label = 'Nom'
|
|
||||||
self.fields['surname'].label = 'Prénom'
|
|
||||||
self.fields['school'].label = 'Établissement'
|
|
||||||
self.fields['comment'].label = 'Commentaire'
|
|
||||||
self.fields['room'].label = 'Chambre'
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = User
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
class InfoForm(ModelForm):
|
class InfoForm(ModelForm):
|
||||||
force = forms.BooleanField(label="Forcer le déménagement ?", initial=False, required=False)
|
force = forms.BooleanField(label="Forcer le déménagement ?", initial=False, required=False)
|
||||||
|
|
||||||
|
@ -103,6 +100,8 @@ class InfoForm(ModelForm):
|
||||||
self.fields['school'].label = 'Établissement'
|
self.fields['school'].label = 'Établissement'
|
||||||
self.fields['comment'].label = 'Commentaire'
|
self.fields['comment'].label = 'Commentaire'
|
||||||
self.fields['room'].label = 'Chambre'
|
self.fields['room'].label = 'Chambre'
|
||||||
|
self.fields['room'].empty_label = "Pas de chambre"
|
||||||
|
self.fields['school'].empty_label = "Séléctionner un établissement"
|
||||||
|
|
||||||
def clean_force(self):
|
def clean_force(self):
|
||||||
if self.cleaned_data.get('force', False):
|
if self.cleaned_data.get('force', False):
|
||||||
|
@ -113,6 +112,10 @@ class InfoForm(ModelForm):
|
||||||
model = User
|
model = User
|
||||||
fields = ['name','surname','pseudo','email', 'school', 'comment', 'room']
|
fields = ['name','surname','pseudo','email', 'school', 'comment', 'room']
|
||||||
|
|
||||||
|
class UserForm(InfoForm):
|
||||||
|
class Meta(InfoForm.Meta):
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
class PasswordForm(ModelForm):
|
class PasswordForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
|
@ -128,10 +131,22 @@ class SchoolForm(ModelForm):
|
||||||
model = School
|
model = School
|
||||||
fields = ['name']
|
fields = ['name']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(SchoolForm, self).__init__(*args, **kwargs)
|
||||||
|
self.fields['name'].label = 'Établissement à ajouter'
|
||||||
|
|
||||||
|
class DelSchoolForm(ModelForm):
|
||||||
|
schools = forms.ModelMultipleChoiceField(queryset=School.objects.all(), label="Etablissements actuels", widget=forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
exclude = ['name']
|
||||||
|
model = School
|
||||||
|
|
||||||
class RightForm(ModelForm):
|
class RightForm(ModelForm):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(RightForm, self).__init__(*args, **kwargs)
|
super(RightForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['right'].label = 'Droit'
|
self.fields['right'].label = 'Droit'
|
||||||
|
self.fields['right'].empty_label = "Choisir un nouveau droit"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Right
|
model = Right
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<td>{{ ban.raison }}</td>
|
<td>{{ ban.raison }}</td>
|
||||||
<td>{{ ban.date_start }}</td>
|
<td>{{ ban.date_start }}</td>
|
||||||
<td>{{ ban.date_end }}</td>
|
<td>{{ ban.date_end }}</td>
|
||||||
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-ban' ban.id %}"><i class="glyphicon glyphicon-grain"></i> Editer</a></td>
|
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-ban' ban.id %}"><i class="glyphicon glyphicon-pushpin"></i> Editer</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<th>Prénom</th>
|
<th>Prénom</th>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Pseudo</th>
|
<th>Pseudo</th>
|
||||||
<th>Inscrit le</th>
|
<th>Fin de cotisation le</th>
|
||||||
<th>Connexion</th>
|
<th>Connexion</th>
|
||||||
<th>Profil</th>
|
<th>Profil</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -14,19 +14,15 @@
|
||||||
<td>{{ donnee.0.name }}</td>
|
<td>{{ donnee.0.name }}</td>
|
||||||
<td>{{ donnee.0.surname }}</td>
|
<td>{{ donnee.0.surname }}</td>
|
||||||
<td>{{ donnee.0.pseudo }}</td>
|
<td>{{ donnee.0.pseudo }}</td>
|
||||||
<td>{{ donnee.0.registered }}</td>
|
<td>{{ donnee.2 }}</td>
|
||||||
<td>{% if donnee.1 == True %}
|
<td>{% if donnee.1 == True %}
|
||||||
<font color="green">Active</font>
|
<font color="green">Active</font>
|
||||||
{% else %}
|
{% else %}
|
||||||
<font color="red">Désactivée</font>
|
<font color="red">Désactivée</font>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td><form method="POST" action="{% url "users:profil"%}">
|
<td><a href="{% url "users:profil" donnee.0.id%}" class="btn btn-primary btn-sm" role="button"><i class="glyphicon glyphicon-user"></i></a>
|
||||||
{% csrf_token %}
|
</td>
|
||||||
<input type="hidden" name="user" id="user" value="{{ donnee.0.pseudo }}"></input>
|
|
||||||
<button class="btn btn-primary btn-sm" type="submit"><i class="glyphicon glyphicon-tree-deciduous"></i></button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<td>{{ whitelist.raison }}</td>
|
<td>{{ whitelist.raison }}</td>
|
||||||
<td>{{ whitelist.date_start }}</td>
|
<td>{{ whitelist.date_start }}</td>
|
||||||
<td>{{ whitelist.date_end }}</td>
|
<td>{{ whitelist.date_end }}</td>
|
||||||
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-whitelist' whitelist.id %}"><i class="glyphicon glyphicon-grain"></i> Editer</a></td>
|
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-whitelist' whitelist.id %}"><i class="glyphicon glyphicon-flag"></i> Editer</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
{% block title %}Utilisateurs{% endblock %}
|
{% block title %}Utilisateurs{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<h2>Adhérents</h2>
|
||||||
{% include "users/aff_users.html" with users_list=users_list %}
|
{% include "users/aff_users.html" with users_list=users_list %}
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
13
users/templates/users/index_ban.html
Normal file
13
users/templates/users/index_ban.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends "users/sidebar.html" %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}Utilisateurs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Bannissements</h2>
|
||||||
|
{% include "users/aff_bans.html" with ban_list=ban_list %}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
||||||
|
|
13
users/templates/users/index_whitelist.html
Normal file
13
users/templates/users/index_whitelist.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends "users/sidebar.html" %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}Utilisateurs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Accès à titre gracieux</h2>
|
||||||
|
{% include "users/aff_whitelists.html" with white_list=white_list %}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Adhérent</h2>
|
<h2>Adhérent</h2>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-info' user.id %}"><i class="glyphicon glyphicon-fire"></i> Editer</a>
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-info' user.id %}"><i class="glyphicon glyphicon-edit"></i> Editer</a>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:password' user.id %}"><i class="glyphicon glyphicon-lock"></i> Changer le mot de passe</a>
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:password' user.id %}"><i class="glyphicon glyphicon-lock"></i> Changer le mot de passe</a>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:state' user.id %}"><i class="glyphicon glyphicon-flash"></i> Changer le statut</a>
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:state' user.id %}"><i class="glyphicon glyphicon-flash"></i> Changer le statut</a>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-right' user.id %}"><i class="glyphicon glyphicon-ok"></i> Ajouter un droit</a>
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-right' user.id %}"><i class="glyphicon glyphicon-ok"></i> Ajouter un droit</a>
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<th>Droits</th>
|
<th>Droits</th>
|
||||||
{% if list_droits %}
|
{% if list_droits %}
|
||||||
<td>{% for droit in list_droits %}{{ droit.right }} - {% endfor %}</td>
|
<td>{% for droit in list_droits %}{{ droit.right }}{% if list_droits|length != forloop.counter %} - {% endif %} {% endfor %}</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td>Aucun</td>
|
<td>Aucun</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
<p>Aucun bannissement</p>
|
<p>Aucun bannissement</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h2>Accès à titre gracieux :</h2>
|
<h2>Accès à titre gracieux :</h2>
|
||||||
<h4><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-whitelist' user.id %}"><i class="glyphicon glyphicon-pushpin"></i> Accorder un accès à titre gracieux</a></h4>
|
<h4><a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-whitelist' user.id %}"><i class="glyphicon glyphicon-flag"></i> Accorder un accès à titre gracieux</a></h4>
|
||||||
{% if white_list %}
|
{% if white_list %}
|
||||||
{% include "users/aff_whitelists.html" with white_list=white_list %}
|
{% include "users/aff_whitelists.html" with white_list=white_list %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
<p><a href="{% url "users:new-user" %}">Créer un adhérent</a></p>
|
<p><a href="{% url "users:new-user" %}">Créer un adhérent</a></p>
|
||||||
<p><a href="{% url "search:search" %}">Editer un adhérent</a></p>
|
|
||||||
<p><a href="{% url "users:index" %}">Liste des adhérents</a></p>
|
<p><a href="{% url "users:index" %}">Liste des adhérents</a></p>
|
||||||
<p><a href="{% url "search:search" %}">Ajouter un bannissement</a></p>
|
<p><a href="{% url "users:index-ban" %}">Liste des bannissements</a></p>
|
||||||
<p><a href="{% url "search:search" %}">Gérer les bannissements</a></p>
|
<p><a href="{% url "users:index-white" %}">Liste des accès à titre gracieux</a></p>
|
||||||
|
<p><a href="{% url "users:add-school" %}">Ajouter un établissement</a></p>
|
||||||
|
<p><a href="{% url "users:del-school" %}">Supprimer un établissement</a></p>
|
||||||
<p><a href="{% url "users:del-right" %}">Retirer un droit rezo</a></p>
|
<p><a href="{% url "users:del-right" %}">Retirer un droit rezo</a></p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -13,7 +13,11 @@ urlpatterns = [
|
||||||
url(r'^edit_whitelist/(?P<whitelistid>[0-9]+)$', views.edit_whitelist, name='edit-whitelist'),
|
url(r'^edit_whitelist/(?P<whitelistid>[0-9]+)$', views.edit_whitelist, name='edit-whitelist'),
|
||||||
url(r'^add_right/(?P<userid>[0-9]+)$', views.add_right, name='add-right'),
|
url(r'^add_right/(?P<userid>[0-9]+)$', views.add_right, name='add-right'),
|
||||||
url(r'^del_right/$', views.del_right, name='del-right'),
|
url(r'^del_right/$', views.del_right, name='del-right'),
|
||||||
url(r'^profil/$', views.profil, name='profil'),
|
url(r'^add_school/$', views.add_school, name='add-school'),
|
||||||
|
url(r'^del_school/$', views.del_school, name='del-school'),
|
||||||
|
url(r'^profil/(?P<userid>[0-9]+)$', views.profil, name='profil'),
|
||||||
|
url(r'^index_ban/$', views.index_ban, name='index-ban'),
|
||||||
|
url(r'^index_white/$', views.index_white, name='index-white'),
|
||||||
url(r'^$', views.index, name='index'),
|
url(r'^$', views.index, name='index'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ from django.shortcuts import render_to_response, get_object_or_404
|
||||||
from django.core.context_processors import csrf
|
from django.core.context_processors import csrf
|
||||||
from django.template import Context, RequestContext, loader
|
from django.template import Context, RequestContext, loader
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db.models import Max
|
from django.db.models import Max, ProtectedError
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from users.models import User, Right, Ban, DelRightForm, UserForm, InfoForm, PasswordForm, StateForm, RightForm, BanForm, ProfilForm, Whitelist, WhitelistForm
|
from users.models import User, Right, Ban, DelRightForm, UserForm, InfoForm, PasswordForm, StateForm, RightForm, BanForm, ProfilForm, Whitelist, WhitelistForm, DelSchoolForm, SchoolForm
|
||||||
from cotisations.models import Facture
|
from cotisations.models import Facture
|
||||||
from machines.models import Machine, Interface
|
from machines.models import Machine, Interface
|
||||||
from users.forms import PassForm
|
from users.forms import PassForm
|
||||||
|
@ -62,10 +62,13 @@ def is_whitelisted(user):
|
||||||
|
|
||||||
def has_access(user):
|
def has_access(user):
|
||||||
""" Renvoie si un utilisateur a accès à internet"""
|
""" Renvoie si un utilisateur a accès à internet"""
|
||||||
if user.state == User.STATE_ACTIVE and not is_ban(user) and ( is_adherent(user) or is_whitelisted(user)):
|
return user.state == User.STATE_ACTIVE and not is_ban(user) and ( is_adherent(user) or is_whitelisted(user))
|
||||||
return True
|
|
||||||
else:
|
def is_active(interface):
|
||||||
return False
|
""" Renvoie si une interface doit avoir accès ou non """
|
||||||
|
machine = interface.machine
|
||||||
|
user = machine.user
|
||||||
|
return machine.active and has_access(user)
|
||||||
|
|
||||||
def form(ctx, template, request):
|
def form(ctx, template, request):
|
||||||
c = ctx
|
c = ctx
|
||||||
|
@ -214,31 +217,63 @@ def edit_whitelist(request, whitelistid):
|
||||||
return redirect("/users/")
|
return redirect("/users/")
|
||||||
return form({'userform': whitelist}, 'users/user.html', request)
|
return form({'userform': whitelist}, 'users/user.html', request)
|
||||||
|
|
||||||
|
def add_school(request):
|
||||||
|
school = SchoolForm(request.POST or None)
|
||||||
|
if school.is_valid():
|
||||||
|
school.save()
|
||||||
|
messages.success(request, "L'établissement a été ajouté")
|
||||||
|
return redirect("/users/")
|
||||||
|
return form({'userform': school}, 'users/user.html', request)
|
||||||
|
|
||||||
|
def del_school(request):
|
||||||
|
school = DelSchoolForm(request.POST or None)
|
||||||
|
if school.is_valid():
|
||||||
|
school_dels = school.cleaned_data['schools']
|
||||||
|
for school_del in school_dels:
|
||||||
|
try:
|
||||||
|
school_del.delete()
|
||||||
|
messages.success(request, "L'établissement a été supprimé")
|
||||||
|
except ProtectedError:
|
||||||
|
messages.error(request, "L'établissement %s est affecté à au moins un user, vous ne pouvez pas le supprimer" % school_del)
|
||||||
|
return redirect("/users/")
|
||||||
|
return form({'userform': school}, 'users/user.html', request)
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
users_list = User.objects.order_by('pk')
|
users_list = User.objects.order_by('pk')
|
||||||
connexion = []
|
connexion = []
|
||||||
for user in users_list:
|
for user in users_list:
|
||||||
connexion.append([user, has_access(user)])
|
end = end_adhesion(user)
|
||||||
|
access = has_access(user)
|
||||||
|
if(end!=None):
|
||||||
|
connexion.append([user, access, end])
|
||||||
|
else:
|
||||||
|
connexion.append([user, access, "Non adhérent"])
|
||||||
return render(request, 'users/index.html', {'users_list': connexion})
|
return render(request, 'users/index.html', {'users_list': connexion})
|
||||||
|
|
||||||
def profil(request):
|
def index_ban(request):
|
||||||
if request.method == 'POST':
|
ban_list = Ban.objects.order_by('date_start')
|
||||||
profil = ProfilForm(request.POST or None)
|
return render(request, 'users/index_ban.html', {'ban_list':ban_list})
|
||||||
if profil.is_valid():
|
|
||||||
profils = profil.cleaned_data['user']
|
def index_white(request):
|
||||||
users = User.objects.get(pseudo = profils)
|
white_list = Whitelist.objects.order_by('date_start')
|
||||||
machines = Interface.objects.filter(machine=Machine.objects.filter(user__pseudo = users))
|
return render(request, 'users/index_whitelist.html', {'white_list':white_list})
|
||||||
factures = Facture.objects.filter(user__pseudo = users)
|
|
||||||
bans = Ban.objects.filter(user__pseudo = users)
|
def profil(request, userid):
|
||||||
whitelists = Whitelist.objects.filter(user__pseudo = users)
|
try:
|
||||||
end_bans = None
|
users = User.objects.get(pk=userid)
|
||||||
end_whitelists = None
|
except User.DoesNotExist:
|
||||||
if(is_ban(users)):
|
messages.error(request, u"Utilisateur inexistant" )
|
||||||
end_bans=end_ban(users)
|
return redirect("/users/")
|
||||||
if(is_whitelisted(users)):
|
machines = Interface.objects.filter(machine=Machine.objects.filter(user__pseudo = users))
|
||||||
end_whitelists=end_whitelist(users)
|
factures = Facture.objects.filter(user__pseudo = users)
|
||||||
list_droits = Right.objects.filter(user=users)
|
bans = Ban.objects.filter(user__pseudo = users)
|
||||||
return render(request, 'users/profil.html', {'user': users, 'machine_list' :machines, 'facture_list':factures, 'ban_list':bans, 'white_list':whitelists,'end_ban':end_bans,'end_whitelist':end_whitelists, 'end_adhesion':end_adhesion(users), 'actif':has_access(users), 'list_droits': list_droits})
|
whitelists = Whitelist.objects.filter(user__pseudo = users)
|
||||||
return redirect("/users/")
|
end_bans = None
|
||||||
return redirect("/users/")
|
end_whitelists = None
|
||||||
|
if(is_ban(users)):
|
||||||
|
end_bans=end_ban(users)
|
||||||
|
if(is_whitelisted(users)):
|
||||||
|
end_whitelists=end_whitelist(users)
|
||||||
|
list_droits = Right.objects.filter(user=users)
|
||||||
|
return render(request, 'users/profil.html', {'user': users, 'machine_list' :machines, 'facture_list':factures, 'ban_list':bans, 'white_list':whitelists,'end_ban':end_bans,'end_whitelist':end_whitelists, 'end_adhesion':end_adhesion(users), 'actif':has_access(users), 'list_droits': list_droits})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue