Browse Source

administration via django-admin

Élie Bouttier 8 years ago
parent
commit
3acfc913d5
53 changed files with 437 additions and 1235 deletions
  1. 1 0
      .gitignore
  2. 0 86
      accounts/admin.py
  3. 1 7
      accounts/forms.py
  4. 0 3
      accounts/models.py
  5. 2 2
      accounts/tests.py
  6. 2 2
      accounts/views.py
  7. 100 10
      adhesions/admin.py
  8. 1 1
      adhesions/apps.py
  9. 6 14
      adhesions/forms.py
  10. 36 0
      adhesions/migrations/0010_auto_20170514_1539.py
  11. 15 19
      adhesions/models.py
  12. 1 1
      adhesions/templates/adhesions/adherent.html
  13. 0 16
      adhesions/templates/adhesions/adhesion_detail.html
  14. 0 9
      adhesions/templates/adhesions/adhesion_edit.html
  15. 0 42
      adhesions/templates/adhesions/adhesion_list.html
  16. 0 60
      adhesions/templates/adhesions/corporation_detail.html
  17. 0 23
      adhesions/templates/adhesions/corporation_form.html
  18. 0 40
      adhesions/templates/adhesions/corporation_list.html
  19. 0 82
      adhesions/templates/adhesions/user_detail.html
  20. 0 23
      adhesions/templates/adhesions/user_form.html
  21. 0 44
      adhesions/templates/adhesions/user_list.html
  22. 2 14
      adhesions/urls.py
  23. 2 117
      adhesions/views.py
  24. 1 1
      banking/admin.py
  25. 17 0
      banking/forms.py
  26. 7 4
      services/templates/services/service_form.html
  27. 1 2
      djadhere/settings.py
  28. 0 11
      djadhere/templates/admin.html
  29. 11 32
      djadhere/templates/base.html
  30. 2 1
      djadhere/urls.py
  31. 0 1
      requirements.txt
  32. 1 1
      run-server.sh
  33. 81 10
      services/admin.py
  34. 19 0
      services/migrations/0019_remove_servicetype_group.py
  35. 27 0
      services/migrations/0020_auto_20170514_1602.py
  36. 46 0
      services/migrations/0021_auto_20170514_2243.py
  37. 37 0
      services/migrations/0022_auto_20170514_2302.py
  38. 5 21
      services/models.py
  39. 1 1
      services/templates/services/_service_list.html
  40. 0 55
      services/templates/services/ipresource_detail.html
  41. 0 9
      services/templates/services/ipresource_form.html
  42. 0 63
      services/templates/services/ipresource_list.html
  43. 0 24
      services/templates/services/resourceallocation_form.html
  44. 7 17
      services/templates/services/service_detail.html
  45. 0 37
      services/templates/services/service_detail_user.html
  46. 0 52
      services/templates/services/service_list.html
  47. 0 46
      services/templates/services/servicetype_detail.html
  48. 0 22
      services/templates/services/servicetype_form.html
  49. 0 38
      services/templates/services/servicetype_list.html
  50. 0 19
      services/templates/services/tags/deallocate_modal_div.html
  51. 0 2
      services/templates/services/tags/deallocate_modal_js.html
  52. 1 16
      services/urls.py
  53. 4 135
      services/views.py

+ 1 - 0
.gitignore

@@ -8,3 +8,4 @@ djadhere/*_settings.py
 .coverage
 htmlcov
 /bower/
+.stfolder

+ 0 - 86
accounts/admin.py

@@ -1,86 +0,0 @@
-from django.contrib import admin
-from django.contrib.auth.models import User
-from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
-#from django.core.exceptions import PermissionDenied
-
-
-from .models import Profile
-#from .forms import UserCreationForm
-from adhesions.admin import AdhesionInline
-
-
-class ProfileInline(admin.StackedInline):
-    model = Profile
-
-    def has_add_permission(self, request):
-        return False
-
-    def has_delete_permission(self, request, obj=None):
-        return False
-
-
-class UserAdmin(AuthUserAdmin):
-    list_display = AuthUserAdmin.list_display + ('adherent_id',)
-    inlines = (ProfileInline, AdhesionInline,)
-
-    def adherent_id(self, user):
-        adherent = user.profile.adhesion
-        if adherent:
-            return adherent.id
-    adherent_id.short_description = 'Numéro d’adhérent'
-#
-#    def get_readonly_fields(self, request, obj=None):
-#        readonly_fields = super().get_readonly_fields(request, obj)
-#        if obj and not request.user.is_superuser:
-#            readonly_fields += ('username',)
-#        return readonly_fields
-#
-#    def get_fieldsets(self, request, obj=None):
-#        if request.user.is_superuser:
-#            return (
-#                AuthUserAdmin.fieldsets[0],
-#                AuthUserAdmin.fieldsets[1],
-#                (AuthUserAdmin.fieldsets[2][0], {
-#                    'classes': ('collapse',),
-#                    'fields': ('is_active', 'is_staff', 'is_superuser', 'groups',), # removing of user_permissions
-#                }),
-#                (AuthUserAdmin.fieldsets[3][0], {
-#                    'classes': ('collapse',),
-#                    'fields': AuthUserAdmin.fieldsets[3][1]['fields'],
-#                }),
-#            )
-#        if obj:
-#            return (
-#                AuthUserAdmin.fieldsets[0],  # Note: password is mandatory (but readonly)
-#                AuthUserAdmin.fieldsets[1],
-#            )
-#        else:
-#            return (
-#                (None, {'fields': ('username',)}),
-#                AuthUserAdmin.fieldsets[1],
-#            )
-#
-#    def get_form(self, request, obj=None, **kwargs):
-#        # get_inlines does not exists :-(
-#        if obj:
-#            self.inlines = (ProfileInline, AdherentInline,)
-#        else:
-#            self.inlines = ()
-#
-#        if request.user.is_superuser or obj:
-#            return super().get_form(request, obj, **kwargs)
-#        else:
-#            # This creation form does not ask for a password
-#            return UserCreationForm
-#
-#    def user_change_password(self, request, id):
-#        if not request.user.is_superuser:
-#            # Les non admin peuvent modifier le mot de passe des utilisateurs qui ne sont ni staff ni admin
-#            user = User.objects.get(pk=id)
-#            if user.is_staff or user.is_superuser:
-#                raise PermissionDenied
-#        return super().user_change_password(request, id)
-
-
-admin.site.unregister(User)
-admin.site.register(User, UserAdmin)

+ 1 - 7
accounts/forms.py

@@ -4,13 +4,7 @@ from django.contrib.auth.models import User
 from .models import Profile
 
 
-class UserCreateForm(ModelForm):
-    class Meta:
-        model = User
-        fields = ('username', 'first_name', 'last_name', 'email',)
-
-
-class UserChangeForm(ModelForm):
+class UserForm(ModelForm):
     class Meta:
         model = User
         fields = ('username', 'first_name', 'last_name', 'email',)

+ 0 - 3
accounts/models.py

@@ -34,8 +34,5 @@ class Profile(models.Model):
             | models.Q(adherent_type=corp_type, adherent_id__in=Corporation.objects.filter(members=self.user).values_list('pk'))
         )
 
-    def get_absolute_url(self):
-        return reverse('user-detail', kwargs={'pk': self.user.pk})
-
     def __str__(self):
         return self.user.get_full_name() or self.user.username

+ 2 - 2
accounts/tests.py

@@ -3,7 +3,7 @@ from django.core.urlresolvers import reverse
 from django.test import TestCase
 
 from .models import Profile
-from .forms import UserChangeForm, ProfileForm
+from .forms import UserForm, ProfileForm
 
 
 class ViewsTestCase(TestCase):
@@ -34,7 +34,7 @@ class ViewsTestCase(TestCase):
         response = self.client.get(reverse('profile'))
         self.assertEqual(response.status_code, 200)
         user = User.objects.get(username='user')
-        user_form = UserChangeForm(None, instance=user)
+        user_form = UserForm(None, instance=user)
         data = {key: getattr(user_form.instance, key) for key in user_form.fields}
         profile_form = ProfileForm(instance=user.profile)
         data.update({key: getattr(profile_form.instance, key) for key in profile_form.fields})

+ 2 - 2
accounts/views.py

@@ -2,12 +2,12 @@ from django.contrib.auth.decorators import login_required
 from django.shortcuts import get_object_or_404, redirect, render
 from django.contrib import messages
 
-from .forms import UserChangeForm, ProfileForm
+from .forms import UserForm, ProfileForm
 
 
 @login_required
 def profile(request):
-    user_form = UserChangeForm(request.POST or None, instance=request.user)
+    user_form = UserForm(request.POST or None, instance=request.user)
     for key in user_form.Meta.admin_only_fields:
         user_form.fields[key].disabled = True
     profile_form = ProfileForm(request.POST or None, instance=request.user.profile)

+ 100 - 10
adhesions/admin.py

@@ -1,22 +1,75 @@
 from django.contrib import admin
-from django.contrib.auth.models import User
-from django.contrib.contenttypes.admin import GenericStackedInline
+from django.contrib.auth.models import User, Group
+from django.contrib.contenttypes.admin import GenericStackedInline, GenericTabularInline
 from django.db.models import Q
 from django.contrib.contenttypes.models import ContentType
+from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
+from django.core.urlresolvers import reverse
+from django.utils.html import format_html
 
-from .forms import AdhesionAdminForm
-from .models import Adhesion, Corporation
+from .forms import AdhesionForm
+from .models import ProxyUser, Corporation, Adhesion
+from accounts.models import Profile
 from banking.admin import PaymentInline
 
 
-class AdhesionInline(GenericStackedInline):
+class AdhesionInline(GenericTabularInline):
     model = Adhesion
     ct_field = 'adherent_type'
     ct_fk_field = 'adherent_id'
-    form = AdhesionAdminForm
+    form = AdhesionForm
+    min_num = 1
     max_num = 1
     extra = 0
 
+    def has_delete_permission(self, request, obj=None):
+        return False
+
+
+class ProfileInlineDjango(admin.StackedInline):
+    model = Profile
+
+    def has_add_permission(self, request):
+        return False
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
+
+class UserAdmin(AuthUserAdmin):
+    list_display = AuthUserAdmin.list_display + ('adherent_id',)
+    list_filter = (AuthUserAdmin.list_filter[2],) # actif
+    inlines = (ProfileInlineDjango, AdhesionInline,)
+
+    def adherent_id(self, user):
+        adherent = user.profile.adhesion
+        if adherent:
+            return adherent.id
+    adherent_id.short_description = 'Numéro d’adhérent'
+
+    def get_fieldsets(self, request, obj=None):
+        return (
+            AuthUserAdmin.fieldsets[0],
+            AuthUserAdmin.fieldsets[1],
+            (AuthUserAdmin.fieldsets[2][0], {
+                'classes': ('collapse',),
+                'fields': ('is_active', 'is_staff', 'is_superuser',), # removing groups and user_permissions
+            }),
+            (AuthUserAdmin.fieldsets[3][0], {
+                'classes': ('collapse',),
+                'fields': AuthUserAdmin.fieldsets[3][1]['fields'],
+            }),
+        )
+
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_delete_permission(self, request, obj=None):
+        return obj and not obj.profile.adhesion
+
 
 class AdherentTypeFilter(admin.SimpleListFilter):
     title = 'type d’adhérent'
@@ -38,12 +91,25 @@ class AdherentTypeFilter(admin.SimpleListFilter):
 
 
 class AdhesionAdmin(admin.ModelAdmin):
-    list_display = ('id', 'get_adherent_name', 'type',)
+    list_display = ('get_id', 'get_adherent_link', 'type',)
     list_filter = (AdherentTypeFilter,)
     fields = ('id',)
     readonly_fields = ('id',)
     search_fields = ('id',)
-    inlines = (PaymentInline,)
+    #inlines = (PaymentInline,)
+
+    def get_id(self, obj):
+        return 'ADT%d' % obj.id
+    get_id.short_description = 'Numéro d’adhérent'
+
+    def get_adherent_link(self, obj):
+        if obj.is_physical():
+            model_name = 'proxyuser'
+        else:
+            model_name = 'corporation'
+        url = reverse('admin:adhesions_%s_change' % model_name, args=(obj.adherent.id,))
+        return format_html(u'<a href="{}">{}</a>', url, str(obj.adherent))
+    get_adherent_link.short_description = 'Nom ou raison sociale'
 
     def get_search_results(self, request, queryset, search_term):
         queryset, use_distinct = super().get_search_results(request, queryset, search_term)
@@ -53,20 +119,32 @@ class AdhesionAdmin(admin.ModelAdmin):
                     | Q(last_name__icontains=search_term)
         )
         user_type = ContentType.objects.get_for_model(User)
-        queryset |= Adhesion.objects.filter(adherent_type=user_type, adherent_id__in=users.values_list('pk'))
+        queryset |= Adhesion.objects.filter(adherent_type=user_type,
+                                            adherent_id__in=users.values_list('pk'))
         corporations = Corporation.objects.filter(social_reason__icontains=search_term)
         corporation_type = ContentType.objects.get_for_model(Corporation)
-        queryset |= Adhesion.objects.filter(adherent_type=corporation_type, adherent_id__in=corporations.values_list('pk'))
+        queryset |= Adhesion.objects.filter(adherent_type=corporation_type,
+                                            adherent_id__in=corporations.values_list('pk'))
         return queryset, use_distinct
 
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
     def has_add_permission(self, request):
         return False
 
+    def has_delete_permission(self, request, obj=None):
+        return False
+
 
 class CorporationAdmin(admin.ModelAdmin):
     list_display = ('social_reason', 'adherent_id')
     inlines = (AdhesionInline,)
     search_fields = ('social_reason',)
+    filter_horizontal = ('members',)
 
     def adherent_id(self, corporation):
         adherent = corporation.adhesion
@@ -74,6 +152,18 @@ class CorporationAdmin(admin.ModelAdmin):
             return adherent.id
     adherent_id.short_description = 'Numéro d’adhérent'
 
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_delete_permission(self, request, obj=None):
+        return obj and not obj.adhesion
+
 
+admin.site.unregister(User)
+admin.site.unregister(Group)
+admin.site.register(ProxyUser, UserAdmin)
 admin.site.register(Corporation, CorporationAdmin)
 admin.site.register(Adhesion, AdhesionAdmin)

+ 1 - 1
adhesions/apps.py

@@ -3,4 +3,4 @@ from django.apps import AppConfig
 
 class AdhesionsConfig(AppConfig):
     name = 'adhesions'
-    verbose_name = 'Adhésions'
+    verbose_name = 'Adhérents'

+ 6 - 14
adhesions/forms.py

@@ -1,15 +1,12 @@
 from django import forms
+from django.contrib.auth.models import User
 
 from djadhere.utils import StringWidget
-from .models import Adhesion
+from .models import Adhesion, Corporation
 
 
-class AdhesionForm(forms.Form):
-    adherent = forms.BooleanField(label='Adhérent ?')
-
-
-class AdhesionAdminForm(forms.ModelForm):
-    adherent_id = forms.CharField(disabled=True, label='Numéro d’adhérent')
+class AdhesionForm(forms.ModelForm):
+    adhesion = forms.BooleanField(label='Adhérent ?', required=False)
 
     class Meta:
         model = Adhesion
@@ -18,10 +15,5 @@ class AdhesionAdminForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         if self.instance.id:
-            self.fields['adherent_id'].initial = self.instance.id
-        else:
-            self.fields['adherent_id'].initial = 'Veuillez sauvegarder pour obtenir un numéro d’adhérent.'
-            self.fields['adherent_id'].widget = StringWidget()
-
-    def has_changed(self):
-        return True
+            self.fields['adhesion'].initial = True
+            self.fields['adhesion'].widget.attrs['readonly'] = True

+ 36 - 0
adhesions/migrations/0010_auto_20170514_1539.py

@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2017-05-14 13:39
+from __future__ import unicode_literals
+
+import django.contrib.auth.models
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('auth', '0008_alter_user_username_max_length'),
+        ('adhesions', '0009_auto_20170507_0228'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ProxyUser',
+            fields=[
+            ],
+            options={
+                'verbose_name': 'personne physique',
+                'verbose_name_plural': 'personnes physiques',
+                'proxy': True,
+                'indexes': [],
+            },
+            bases=('auth.user',),
+            managers=[
+                ('objects', django.contrib.auth.models.UserManager()),
+            ],
+        ),
+        migrations.AlterModelOptions(
+            name='adhesion',
+            options={'ordering': ('id',), 'verbose_name': 'adhésion'},
+        ),
+    ]

+ 15 - 19
adhesions/models.py

@@ -25,7 +25,7 @@ class Adhesion(models.Model):
     created = models.DateTimeField(null=True, blank=True, auto_now_add=True)
 
     class Meta:
-        verbose_name = 'adhérent'
+        verbose_name = 'adhésion'
         unique_together = ("adherent_type", "adherent_id")
         ordering = ('id',)
 
@@ -58,28 +58,27 @@ class Adhesion(models.Model):
             return str(self.adherent)
     get_adherent_name.short_description = 'Nom ou raison sociale'
 
-    def get_adherent_detail_url(self):
-        if self.is_physical():
-            return reverse('user-detail', kwargs={'pk': self.adherent.pk})
-        else:
-            return reverse('corporation-detail', kwargs={'pk': self.adherent.pk})
-
-    def get_adherent_edit_url(self):
-        if self.is_physical():
-            return reverse('user-edit', kwargs={'pk': self.adherent.pk})
-        else:
-            return reverse('corporation-edit', kwargs={'pk': self.adherent.pk})
-
-    def get_absolute_url(self):
-        return reverse('adhesion-detail', kwargs={'pk': self.pk})
-
     def __str__(self):
+        return 'ADT%d' % self.id
         if self.id is None:
             return '?'
         else:
             return 'ADT%d (%s)' % (self.id, self.get_adherent_name())
 
 
+class ProxyUser(User):
+    class Meta:
+        proxy = True
+        verbose_name = 'personne physique'
+        verbose_name_plural = 'personnes physiques'
+
+    def get_model_perms(self, request):
+        return {}
+    
+    def __str__(self):
+        return str(self.profile)
+
+
 class Corporation(models.Model):
     social_reason = models.CharField(max_length=256, verbose_name='Raison sociale', unique=True)
     description = models.TextField(blank=True, default='')
@@ -99,9 +98,6 @@ class Corporation(models.Model):
         except Adhesion.DoesNotExist:
             return None
 
-    def get_absolute_url(self):
-        return reverse('corporation-detail', kwargs={'pk': self.pk})
-
     class Meta:
         verbose_name = 'personne morale'
         verbose_name_plural = 'personnes morales'

+ 1 - 1
adhesions/templates/adhesions/adherent.html

@@ -6,7 +6,7 @@
 
 {% include 'adhesions/_adhesion_detail.html' %}
 
-{% with services=adhesion.services.all service_detail_url='service-detail-user' %}
+{% with services=adhesion.services.all service_detail_url='service-detail' %}
 {% include 'services/_service_list.html' %}
 {% endwith %}
 

+ 0 - 16
adhesions/templates/adhesions/adhesion_detail.html

@@ -1,16 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-<li><a href="{% url 'adhesion-list' %}">Adhérents</a></li>
-<li class="active">{{ adhesion }}</li>
-{% endblock %}
-
-{% block content %}
-
-{% include 'adhesions/_adhesion_detail.html' %}
-
-{% with services=adhesion.services.all service_detail_url='service-detail' %}
-{% include 'services/_service_list.html' %}
-{% endwith %}
-
-{% endblock %}

+ 0 - 9
adhesions/templates/adhesions/adhesion_edit.html

@@ -1,9 +0,0 @@
-{% extends 'base.html' %}
-
-{% block content %}
-<h1>{% if adhesion %}Modification {{ adhesion }}{% else %}Ajouter un adhérents{% endif %}</h1>
-
-
-{% include '_form.html' %}
-
-{% endblock %}

+ 0 - 42
adhesions/templates/adhesions/adhesion_list.html

@@ -1,42 +0,0 @@
-{% extends 'admin.html' %}
-{% load bootstrap3 %}
-
-{% block breadcrumb %}
-<li class="active">Adhérents</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <div class="pull-right">
-            <a class="btn btn-success" href="{% url 'user-add' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;Ajouter un utilisateur</a>
-            <a class="btn btn-success" href="{% url 'corporation-add' %}"><span class="glyphicon glyphicon-globe"></span>&nbsp;Ajouter une association</a>
-        </div>
-        <h4>Adhérents</h4>
-    </div>
-    {% for adhesion in object_list %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>Numéro d’adhérent</th>
-            <th>Nom ou raison social</th>
-            <th>Type</th>
-            {% comment %}<th></th>{% endcomment %}
-        </tr>
-    {% endif %}
-        <tr>
-            <td><a href="{% url 'adhesion-detail' adhesion.id %}">ADT{{ adhesion.id }}</a></td>
-            <td><a href="{{ adhesion.get_adherent_detail_url }}">{{ adhesion.get_adherent_name }}</a></td>
-            <td>{{ adhesion.type }}</td>
-            {% comment %}<td class="text-right"><a href="{{ adhesion.get_adherent_edit_url }}"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Modifier</a></td>{% endcomment %}
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% endfor %}
-</div>
-
-<div class="text-center">
-    {% bootstrap_pagination page_obj %}
-</div>
-{% endblock %}

+ 0 - 60
adhesions/templates/adhesions/corporation_detail.html

@@ -1,60 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<li><a href="{% url 'corporation-list' %}">Associations</a></li>
-<li class="active">{{ corporation }}</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <a href="{% url 'corporation-edit' corporation.pk %}" class="btn btn-success pull-right">Éditer</a>
-        <h4>{{ corporation }}</h4>
-    </div>
-    <table class="table table-bordered">
-        <tr>
-            <th>Numéro d’adhérent</th>
-            <td>
-                {% if corporation.adhesion %}
-                <a href="{% url 'adhesion-detail' corporation.adhesion.id %}">ADT{{ corporation.adhesion.id }}</a>
-                {% else %}
-                <em>Non adhérent.</em>
-                {% endif %}
-            </td>
-        </tr>
-    </table>
-</div>
-
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>Membres</h4>
-    </div>
-    <table class="table table-bordered">
-        {% for user in corporation.members.all %}
-        {% if forloop.first %}
-        <tr>
-            <th>Nom</th>
-            <th>Numéro d’adhérent</th>
-        </tr>
-        {% endif %}
-        <tr>
-            <td>
-                <a href="{% url 'user-detail' user.pk %}">{{ user.profile }}</a>
-            </td>
-            <td>
-                {% if user.profile.adhesion %}
-                <a href="{% url 'adhesion-detail' user.profile.adhesion.pk %}">ADT{{ user.profile.adhesion.pk }}</a>
-                {% else %}
-                –
-                {% endif %}
-            </td>
-        </tr>
-        {% empty %}
-        <tr>
-            <td><em>Aucun membre.</em></td>
-        </tr>
-        {% endfor %}
-    </table>
-</div>
-{% endblock %}

+ 0 - 23
adhesions/templates/adhesions/corporation_form.html

@@ -1,23 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<li><a href="{% url 'corporation-list' %}">Associations</a></li>
-{% if corporation %}
-<li><a href="{{ corporation.get_absolute_url }}">{{ corporation }}</a></li>
-<li class="active">Modification</li>
-{% else %}
-<li class="active">Nouvelle</li>
-{% endif %}
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>{% if corporation %}Modifier{% else %}Ajouter{% endif %} une association</h4>
-    </div>
-    <div class="panel-body">
-{% include '_form.html' %}
-    </div>
-</div>
-{% endblock %}

+ 0 - 40
adhesions/templates/adhesions/corporation_list.html

@@ -1,40 +0,0 @@
-{% extends 'admin.html' %}
-{% load bootstrap3 %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<li class="active">Associations</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <a class="btn btn-success pull-right" href="{% url 'corporation-add' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;Ajouter une association</a>
-        <h4>Associations</h4>
-    </div>
-    {% for corp in object_list %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>Raison sociale</th>
-            <th>Numéro d’adhérent</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr>
-            <td><a href="{% url 'corporation-detail' corp.pk %}">{{ corp.social_reason }}</a></td>
-            <td>{% if corp.adhesion %}<a href="{% url 'adhesion-detail' corp.adhesion.pk %}">ADT{{ corp.adhesion.pk }}</a>{% else %}–{% endif %}</td>
-            <td class="text-right">
-                <a href="{% url 'corporation-edit' corp.pk %}"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Modifier</a>
-            </td>
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% endfor %}
-</div>
-
-<div class="text-center">
-    {% bootstrap_pagination page_obj %}
-</div>
-{% endblock %}

+ 0 - 82
adhesions/templates/adhesions/user_detail.html

@@ -1,82 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<li><a href="{% url 'user-list' %}">Utilisateurs</a></li>
-<li class="active">{{ user.profile }}</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <a href="{% url 'user-edit' user.pk %}" class="btn btn-success pull-right">Éditer</a>
-        <h4>{{ user.profile }}</h4>
-    </div>
-    <table class="table table-bordered">
-        <tr>
-            <th>Numéro d’adhérent</th>
-            <td>
-                {% if user.profile.adhesion %}
-                <a href="{% url 'adhesion-detail' user.profile.adhesion.id %}">ADT{{ user.profile.adhesion.id }}</a>
-                {% else %}
-                <em>non adhérent</em>
-                {% endif %}
-            </td>
-        </tr>
-        <tr>
-            <th>Nom d’utilisateur</th>
-            <td>{{ user }}</td>
-        </tr>
-        <tr>
-            <th>Prénom</th>
-            <td>{{ user.first_name }}</td>
-        </tr>
-        <tr>
-            <th>Nom</th>
-            <td>{{ user.last_name }}</td>
-        </tr>
-        <tr>
-            <th>Adresse e-mail</th>
-            <td>{{ user.email }}</td>
-        </tr>
-        <tr>
-            <th>Numéro de téléphone</th>
-            <td>{{ user.profile.phone_number }}</td>
-        </tr>
-        <tr>
-            <th>Adresse</th>
-            <td>{{ user.profile.address|linebreaksbr }}</td>
-        </tr>
-    </table>
-</div>
-
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>Associations</h4>
-    </div>
-    <table class="table table-bordered">
-        {% for corp in user.corporations.all %}
-        {% if forloop.first %}
-        <tr>
-            <th>Raison sociale</th>
-            <th>Numéro d’adhérent</th>
-        </tr>
-        {% endif %}
-        <tr>
-            <td><a href="{% url 'corporation-detail' corp.pk %}">{{ corp }}</a></td>
-            <td>
-                {% if corp.adhesion %}
-                <a href="{% url 'adhesion-detail' corp.adhesion.pk %}">ADT{{ corp.adhesion.pk }}</a>
-                {% else %}
-                –
-                {% endif %}
-            </td>
-        </tr>
-        {% empty %}
-        <tr>
-            <td><em>Aucune association.</em></td>
-        </tr>
-        {% endfor %}
-    </table>
-</div>
-{% endblock %}

+ 0 - 23
adhesions/templates/adhesions/user_form.html

@@ -1,23 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<li><a href="{% url 'user-list' %}">Utilisateurs</a></li>
-{% if user %}
-<li><a href="{{ user.profile.get_absolute_url }}">{{ user.profile }}</a></li>
-<li class="active">Modification</li>
-{% else %}
-<li class="active">Nouveau</li>
-{% endif %}
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>{% if user %}Modifier{% else %}Ajouter{% endif %} un utilisateur</h4>
-    </div>
-    <div class="panel-body">
-{% include '_form.html' %}
-    </div>
-</div>
-{% endblock %}

+ 0 - 44
adhesions/templates/adhesions/user_list.html

@@ -1,44 +0,0 @@
-{% extends 'admin.html' %}
-{% load bootstrap3 %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<li class="active">Utilisateurs</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <a class="btn btn-success pull-right" href="{% url 'user-add' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;Ajouter un utilisateur</a>
-        <h4>Utilisateurs</h4>
-    </div>
-    {% for user in object_list %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>Nom d’utilisateur</th>
-            <th>Prénom</th>
-            <th>Nom</th>
-            <th>Numéro d’adhérent</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr>
-            <td><a href="{% url 'user-detail' user.pk %}">{{ user.username }}</a></td>
-            <td>{{ user.first_name }}</td>
-            <td>{{ user.last_name }}</td>
-            <td>{% if user.profile.adhesion %}<a href="{% url 'adhesion-detail' user.profile.adhesion.pk %}">ADT{{ user.profile.adhesion.pk }}</a>{% else %}–{% endif %}</td>
-            <td class="text-right">
-                <a href="{% url 'user-edit' user.pk %}"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Modifier</a>
-            </td>
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% endfor %}
-</div>
-
-<div class="text-center">
-    {% bootstrap_pagination page_obj %}
-</div>
-{% endblock %}

+ 2 - 14
adhesions/urls.py

@@ -4,18 +4,6 @@ from . import views
 
 
 urlpatterns = [
-    # User views
-    url(r'^$', views.user, name='adhesion-detail-user'),
-    url(r'^asso/(?P<pk>[0-9]+)/$', views.corporation, name='corporation-detail-user'),
-    # Admin views
-    url(r'^admin/users/$', views.UserList.as_view(), name='user-list'),
-    url(r'^admin/users/add/$', views.user_edit, name='user-add'),
-    url(r'^admin/users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view(), name='user-detail'),
-    url(r'^admin/users/(?P<pk>[0-9]+)/edit/$', views.user_edit, name='user-edit'),
-    url(r'^admin/corporations/$', views.CorporationList.as_view(), name='corporation-list'),
-    url(r'^admin/corporations/add/$', views.CorporationCreate.as_view(), name='corporation-add'),
-    url(r'^admin/corporations/(?P<pk>[0-9]+)/$', views.CorporationDetail.as_view(), name='corporation-detail'),
-    url(r'^admin/corporations/(?P<pk>[0-9]+)/edit/$', views.CorporationUpdate.as_view(), name='corporation-edit'),
-    url(r'^admin/adhesions/$', views.AdhesionList.as_view(), name='adhesion-list'),
-    url(r'^admin/adhesions/(?P<pk>[0-9]+)/$', views.AdhesionDetail.as_view(), name='adhesion-detail'),
+    url(r'^$', views.user, name='adhesion-detail'),
+    url(r'^asso/(?P<pk>[0-9]+)/$', views.corporation, name='corporation-detail'),
 ]

+ 2 - 117
adhesions/views.py

@@ -1,18 +1,9 @@
 from django.contrib.auth.decorators import login_required
 from django.core.exceptions import PermissionDenied
-from django.shortcuts import render, redirect, get_object_or_404
+from django.shortcuts import render, get_object_or_404
 from django.contrib.auth.models import User
-from django.contrib.auth.mixins import PermissionRequiredMixin
-from django.contrib.auth.decorators import permission_required
-from django.views.generic import ListView, DetailView, CreateView, UpdateView
-from django.contrib.contenttypes.models import ContentType
-from django.contrib import messages
 
-from accounts.models import Profile
-from accounts.forms import UserCreateForm, UserChangeForm, ProfileForm
-
-from .models import Adhesion, Corporation
-from .forms import AdhesionForm
+from .models import Corporation
 
 
 @login_required
@@ -33,109 +24,3 @@ def corporation(request, pk):
         'adherent': corporation,
         'adhesion': corporation.adhesion,
     })
-
-
-class UserMixin(PermissionRequiredMixin):
-    model = User
-    permission_required = 'auth.change_user'
-
-
-class UserList(UserMixin, ListView):
-    template_name = 'adhesions/user_list.html'
-    paginate_by = 50
-
-
-class UserDetail(UserMixin, DetailView):
-    template_name = 'adhesions/user_detail.html'
-
-
-@permission_required('auth.change_user')
-def user_edit(request, pk=None):
-    if pk:
-        user = get_object_or_404(User, pk=pk)
-        user_form = UserChangeForm(request.POST or None, instance=user)
-        profile = user.profile
-    else:
-        user = None
-        user_form = UserCreateForm(request.POST or None)
-        profile = None
-    profile_form = ProfileForm(request.POST or None, instance=profile)
-    forms = [user_form, profile_form]
-    if not pk or not user.profile.adhesion:
-        adhesion_form = AdhesionForm(request.POST or None)
-        forms += [adhesion_form]
-    else:
-        adhesion_form = None
-    if request.method == 'POST' and all([form.is_valid() for form in forms]):
-        error = False
-        if user: # update
-            user_form.save()
-            profile_form.save()
-        else:
-            user = user_form.save()
-            # profile created by user post_save signal
-            profile = Profile.objects.get(user__pk=user.pk)
-            profile_form = ProfileForm(request.POST, instance=profile)
-            if profile_form.is_valid():
-                profile_form.save()
-            else:
-                # we need a new user form bind to user instance
-                user_form = UserForm(request.POST or None, instance=user)
-                forms[0] = user_form
-                error = True
-        if adhesion_form:
-            if adhesion_form.is_valid():
-                if adhesion_form.cleaned_data['adherent']:
-                    Adhesion.objects.create(
-                        adherent_type=ContentType.objects.get_for_model(User),
-                        adherent_id=user.pk,
-                    )
-                    # TODO: contribution
-            else:
-                error = True
-        if not error:
-            messages.success(request, 'Utilisateur créé avec succès.')
-            return redirect('user-detail', pk=user.pk)
-        messages.warn(request, 'Utilisateur créé mais certaines informations du profil '
-                               'n’ont pas été sauvegardé, veuillez les corriger.')
-    return render(request, 'adhesions/user_form.html', {
-        'forms': forms,
-        'user': user,
-    })
-
-
-class CorporationMixin(PermissionRequiredMixin):
-    model = Corporation
-    permission_required = 'adhesions.change_corporation'
-
-
-class CorporationList(CorporationMixin, ListView):
-    paginate_by = 50
-
-
-class CorporationDetail(CorporationMixin, DetailView):
-    pass
-
-
-class CorporationCreate(CorporationMixin, CreateView):
-    fields = ('social_reason', 'email', 'phone_number', 'address', 'notes')
-
-
-class CorporationUpdate(CorporationMixin, UpdateView):
-    fields = ('social_reason', 'email', 'phone_number', 'address', 'notes')
-
-
-class AdhesionMixin(PermissionRequiredMixin):
-    model = Adhesion
-    permission_required = 'adhesions.change_adhesion'
-
-
-class AdhesionList(AdhesionMixin, ListView):
-    paginate_by = 50
-
-
-class AdhesionDetail(AdhesionMixin, DetailView):
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context['show_adherent'] = True
-        return context

+ 1 - 1
banking/admin.py

@@ -169,4 +169,4 @@ class PaymentAdmin(admin.ModelAdmin):
 #        return False
 
 
-admin.site.register(Payment, PaymentAdmin)
+#admin.site.register(Payment, PaymentAdmin)

+ 17 - 0
banking/forms.py

@@ -0,0 +1,17 @@
+from django.forms import ModelForm
+from django.core.exceptions import ValidationError
+
+from .models import Payment
+
+
+class PaymentForm(ModelForm):
+    class Meta:
+        model = Payment
+        fields = ['amount', 'period', 'payment_method', 'start']
+
+    def clean_start(self):
+        start = self.cleaned_data['start']
+        if self.instance.pk:
+            if start < self.instance.start:
+                raise ValidationError(_('Invalid value'), code='invalid')
+        return start

+ 7 - 4
services/templates/services/service_form.html

@@ -1,9 +1,12 @@
 {% extends 'admin.html' %}
 
 {% block breadcrumb %}
-<li><a href="{% url 'service-list' %}">Services</a></li>
-{% if service %}
-<li><a href="{{ service.get_absolute_url }}">{{ service }}</a></li>
+<li><a href="{% url 'payment-list' %}">Paiements</a></li>
+{% if reason %}
+<li><a href="{{ reason.get_absolute_url }}">{{ reason }}</a></li>
+{% endif %}
+{% if payment %}
+<li><a href="{{ payment.get_absolute_url }}">{{ payment }}</a></li>
 <li class="active">Modification</li>
 {% else %}
 <li class="active">Nouveau</li>
@@ -13,7 +16,7 @@
 {% block content %}
 <div class="panel panel-primary">
     <div class="panel-heading">
-        <h4>{% if service %}Modifier{% else %}Ajouter{% endif %} un service</h4>
+        <h4>{% if payment %}Modifier{% else %}Ajouter{% endif %} un paiement</h4>
     </div>
     <div class="panel-body">
 {% include '_form.html' %}

+ 1 - 2
djadhere/settings.py

@@ -38,7 +38,6 @@ INSTALLED_APPS = [
     'djadhere',
 
     'bootstrap3',
-    'django_select2',
 
     'django.contrib.admin',
     'django.contrib.auth',
@@ -136,7 +135,7 @@ USE_TZ = True
 
 STATIC_URL = '/static/'
 
-LOGOUT_REDIRECT_URL = 'adhesion-detail-user'
+LOGOUT_REDIRECT_URL = 'adhesion-detail'
 
 BOOTSTRAP3 = {
 

+ 0 - 11
djadhere/templates/admin.html

@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load bootstrap3 staticfiles %} 
-
-{% block managetab %} active{% endblock %}
-
-{% block breadcrumbol %}
-<ol class="breadcrumb">
-{% block breadcrumb %}
-{% endblock %}
-</ol>
-{% endblock %}

+ 11 - 32
djadhere/templates/base.html

@@ -14,7 +14,6 @@
 {% endblock %}
 
 {% block body %}
-{% block navbar %}
     <nav class="navbar navbar-default" role="navigation">
       <div class="container">
         <div class="navbar-header">
@@ -28,7 +27,7 @@
         </div>
         <div id="navbar" class="navbar-collapse collapse">
           <ul class="nav navbar-nav">
-            <li{% block usertab %}{% endblock %}><a href="{% url 'adhesion-detail-user' %}"><span class="glyphicon glyphicon-heart-empty"></span>&nbsp;Mon adhésion</a></li>
+            <li{% block usertab %}{% endblock %}><a href="{% url 'adhesion-detail' %}"><span class="glyphicon glyphicon-heart-empty"></span>&nbsp;Mon adhésion</a></li>
             {% for corp in request.corporations %}
             {% if forloop.first %}
             <li class="dropdown{% block corptab %}{% endblock %}">
@@ -37,7 +36,7 @@
                 </a>
                 <ul class="dropdown-menu">
             {% endif %}
-                    <li><a href="{% url 'corporation-detail-user' corp.object.pk %}">{{ corp.object.social_reason }}</a></li>
+                    <li><a href="{% url 'corporation-detail' corp.object.pk %}">{{ corp.object.social_reason }}</a></li>
             {% if forloop.last %}
                 </ul>
             </li>
@@ -46,23 +45,7 @@
           </ul>
           <ul class="nav navbar-nav navbar-right">
             {% if request.user.is_staff %}
-            <li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-dashboard"></span>&nbsp;Django-Admin</a></li>
-            {% endif %}
-            {% if request.user.is_staff %}
-            <li class="dropdown{% block managetab %}{% endblock %}">
-                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-                    <span class="glyphicon glyphicon-cog"></span>&nbsp;Gestion <span class="caret"></span>
-                </a>
-                <ul class="dropdown-menu">
-                    <li><a href="{% url 'user-list' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;Utilisateurs</a></li>
-                    <li><a href="{% url 'corporation-list' %}"><span class="glyphicon glyphicon-globe"></span>&nbsp;Associations</a></li>
-                    <li><a href="{% url 'adhesion-list' %}"><span class="glyphicon glyphicon-heart-empty"></span>&nbsp;Adhérents</a></li>
-                    <li><a href="{% url 'service-list' %}"><span class="glyphicon glyphicon-tasks"></span>&nbsp;Services</a></li>
-                    <li><a href="{% url 'servicetype-list' %}"><span class="glyphicon glyphicon-king"></span>&nbsp;Types de services</a></li>
-                    <li><a href="{% url 'ip-list' %}"><span class="glyphicon glyphicon-asterisk"></span>&nbsp;IP</a></li>
-                    <li><a href="{% url 'payment-list' %}"><span class="glyphicon glyphicon-piggy-bank"></span>&nbsp;Paiements</a></li>
-                </ul>
-            </li>
+            <li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-dashboard"></span>&nbsp;Administration</a></li>
             {% endif %}
             <li{% block profiletab %}{% endblock %}><a href="{% url 'profile' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;Profil</a></li>
             <li><a href="{% url 'logout' %}" data-toggle="tooltip" data-placement="bottom" title="Logout"><span class="glyphicon glyphicon-log-out"></span></a></li>
@@ -70,24 +53,20 @@
         </div>
       </div>
     </nav>
-{% endblock %}
+
 
 {% block container %}
 	<div class="container">
-      <div class="row">
-        <div id="content" class="col-md-12">
-{% block breadcrumbol %}{% endblock %}
-          {% bootstrap_messages %}
+      {% block breadcrumbol %}{% endblock %}
+      {% bootstrap_messages %}
 {% block content %}{% endblock %}
 {% block pagefooter %}
-          <hr>
-          <footer>
-            <p class="text-muted">Propulsé par <a href="https://code.ffdn.org/tetaneutral.net/djadhere">djadhere</a></p>
-          </footer>
+      <hr>
+      <footer>
+        <p class="text-muted">Propulsé par <a href="https://code.ffdn.org/tetaneutral.net/djadhere">djadhere</a></p>
+      </footer>
 {% endblock %}
-        </div>
-      </div>
-	</div>
+	</div> <!-- container-fluid -->
 {% endblock %}
 
 {% endblock %}

+ 2 - 1
djadhere/urls.py

@@ -22,8 +22,9 @@ urlpatterns = [
     url(r'^', include('services.urls')),
     url(r'^', include('adhesions.urls')),
     url(r'^', include('banking.urls')),
-    url(r'^djangoadmin/', admin.site.urls),
+    url(r'^admin/', admin.site.urls),
 ]
 
 admin.site.site_title = 'tetaneutral.net'
 admin.site.site_header = 'Administration de tetaneutral.net'
+admin.site.index_title = 'Administration'

+ 0 - 1
requirements.txt

@@ -1,3 +1,2 @@
 django<1.12
 django-bootstrap3
-django_select2

+ 1 - 1
run-server.sh

@@ -5,4 +5,4 @@ BASEDIR="$(dirname $0)"
 
 . "$BASEDIR"/venv/bin/activate
 
-"$BASEDIR"/manage.py runserver --settings=djadhere.local_settings $(hostname):8000
+"$BASEDIR"/manage.py runserver --settings=djadhere.$(hostname)_settings $(hostname):8000

+ 81 - 10
services/admin.py

@@ -5,10 +5,8 @@ from django.utils import timezone
 from django.core.urlresolvers import reverse
 from django.utils.html import format_html
 
-from djadhere.utils import get_active_filter
-from banking.models import Payment
-from banking.admin import PaymentInline
 from .models import Service, ServiceType, IPResource, Route, ResourceAllocation
+from djadhere.utils import get_active_filter
 
 
 ### Filters
@@ -70,7 +68,7 @@ def get_foreignkey_link_func(field):
         obj = getattr(instance, field)
         url = reverse('admin:%s_%s_change' % (obj._meta.app_label,  
                                                 obj._meta.model_name),
-                        args=(obj.id,))
+                        args=(obj.pk,))
         return format_html(u'<a href="{}">{}</a>', url, str(obj))
     return foreignkey_link
 
@@ -80,10 +78,18 @@ def get_foreignkey_link_func(field):
 class AllocationInline(admin.TabularInline):
     model = ResourceAllocation
     extra = 0
-    fields = ('id', 'service', 'resource', 'start', 'end')
+    fields = ('id', 'service', 'resource', 'route', 'start', 'end')
     raw_id_fields = ('service', 'resource',)
     verbose_name_plural = 'Allocations'
 
+    def get_max_num(self, request, obj=None, **kwargs):
+        existing = obj.allocations.count() if obj else 0
+        # pour simplifier la validation, on ajoute qu’une allocation à la fois
+        return existing + 1
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
 
 ### Actions
 
@@ -98,15 +104,25 @@ ends_resource.short_description = 'Terminer les allocations sélectionnées'
 class ServiceAdmin(admin.ModelAdmin):
     list_display = ('id', 'adhesion', 'service_type', 'label', 'active')
     list_filter = ('active', ServiceTypeFilter,)
-    inlines = (PaymentInline, AllocationInline,)
+    inlines = (AllocationInline,)
     search_fields = ('id', 'service_type__name', 'label')
     raw_id_fields = ('adhesion',)
 
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
 
 class IPResourceAdmin(admin.ModelAdmin):
     list_display = ('__str__', 'in_use_display')
     list_filter = (ResourceInUseFilter,)
-    fields =('ip', 'mask',)
+    fields = ('ip',)
+    readonly_fields = ('ip',)
     search_fields = ('ip',)
     inlines = (AllocationInline,)
 
@@ -115,12 +131,41 @@ class IPResourceAdmin(admin.ModelAdmin):
     in_use_display.short_description = 'Disponible'
     in_use_display.boolean = True
 
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_add_permission(self, request, obj=None):
+        return False
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
+
+class RouteAdmin(admin.ModelAdmin):
+    fields = ('name',)
+    readonly_fields = ('name',)
+
+    def has_add_permission(self, request, obj=None):
+        return False
+
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
 
 class ResourceAllocationAdmin(admin.ModelAdmin):
     list_display = ('id', 'resource_link', 'service_link', 'start', 'end',)
     list_filter = (AllocationStatusFilter,)
     actions = (ends_resource,)
-    raw_id_fields = ('service',)
+    raw_id_fields = ('resource', 'service',)
     search_fields = ('resource__ip', 'service__id', 'service__service_type__name', 'service__label')
 
     resource_link = get_foreignkey_link_func('resource')
@@ -129,9 +174,35 @@ class ResourceAllocationAdmin(admin.ModelAdmin):
     service_link = get_foreignkey_link_func('service')
     service_link.short_description = 'Service'
 
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
+
+class ServiceTypeAdmin(admin.ModelAdmin):
+    fields = ('name',)
+    readonly_fields = ('name',)
+
+    def get_actions(self, request):
+        actions = super().get_actions(request)
+        if 'delete_selected' in actions:
+            del actions['delete_selected']
+        return actions
+
+    def has_add_permission(self, request, obj=None):
+        return False
+
+    def has_delete_permission(self, request, obj=None):
+        return False
+
 
-admin.site.register(ServiceType)
+admin.site.register(ServiceType, ServiceTypeAdmin)
 admin.site.register(Service, ServiceAdmin)
 admin.site.register(IPResource, IPResourceAdmin)
-admin.site.register(Route)
+admin.site.register(Route, RouteAdmin)
 admin.site.register(ResourceAllocation, ResourceAllocationAdmin)

+ 19 - 0
services/migrations/0019_remove_servicetype_group.py

@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2017-05-14 13:39
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('services', '0018_auto_20170509_1602'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='servicetype',
+            name='group',
+        ),
+    ]

+ 27 - 0
services/migrations/0020_auto_20170514_1602.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.1 on 2017-05-14 20:33
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('services', '0019_remove_servicetype_group'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='ipresource',
+            options={'ordering': ['ip'], 'verbose_name': 'IP', 'verbose_name_plural': 'IP'},
+        ),
+        migrations.AlterModelOptions(
+            name='servicetype',
+            options={'ordering': ['name'], 'verbose_name': 'type de service', 'verbose_name_plural': 'types de service'},
+        ),
+        migrations.RemoveField(
+            model_name='ipresource',
+            name='mask',
+        ),
+    ]

+ 46 - 0
services/migrations/0021_auto_20170514_2243.py

@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.1 on 2017-05-14 20:43
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+def migrate(apps, schema_editor):
+    db_alias = schema_editor.connection.alias
+    IPResource = apps.get_model('services', 'IPResource')
+    NewIPResource = apps.get_model('services', 'NewIPResource')
+    ResourceAllocation = apps.get_model('services', 'ResourceAllocation')
+    for ip in IPResource.objects.all():
+        NewIPResource.objects.create(ip=ip.ip, reserved=ip.reserved)
+    for alloc in ResourceAllocation.objects.all():
+        alloc.newresource = NewIPResource.objects.get(ip=alloc.resource.ip)
+        alloc.save()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('services', '0020_auto_20170514_1602'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='NewIPResource',
+            fields=[
+                ('ip', models.GenericIPAddressField(primary_key=True, serialize=False, verbose_name='IP')),
+                ('reserved', models.BooleanField(default=False)),
+            ],
+            options={
+                'verbose_name': 'IP',
+                'ordering': ['ip'],
+                'verbose_name_plural': 'IP',
+            },
+        ),
+        migrations.AddField(
+            model_name='resourceallocation',
+            name='newresource',
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='allocations', related_query_name='allocation', to='services.NewIPResource', verbose_name='Ressource'),
+        ),
+        migrations.RunPython(migrate),
+    ]

+ 37 - 0
services/migrations/0022_auto_20170514_2302.py

@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.1 on 2017-05-14 22:07
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('services', '0021_auto_20170514_2243'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='resourceallocation',
+            name='resource',
+        ),
+        migrations.DeleteModel(
+            name='IPResource',
+        ),
+        migrations.RenameModel(
+            old_name='NewIPResource',
+            new_name='IPResource',
+        ),
+        migrations.RenameField(
+            model_name='resourceallocation',
+            old_name='newresource',
+            new_name='resource',
+        ),
+        migrations.AlterField(
+            model_name='resourceallocation',
+            name='resource',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='allocations', related_query_name='allocation', to='services.IPResource', verbose_name='Ressource'),
+        ),
+    ]

+ 5 - 21
services/models.py

@@ -15,9 +15,7 @@ from banking.models import Payment
 
 
 class IPResource(models.Model):
-    ip = models.GenericIPAddressField(verbose_name='IP')
-    mask = models.PositiveIntegerField(validators=[MaxValueValidator(128)],
-                                       default=0, verbose_name='Masque')
+    ip = models.GenericIPAddressField(verbose_name='IP', primary_key=True)
     reserved = models.BooleanField(default=False)
 
     @property
@@ -33,32 +31,21 @@ class IPResource(models.Model):
 
     class Meta:
         ordering = ['ip']
-        verbose_name = 'ressource IP'
-        verbose_name_plural = 'ressources IP'
-
-    def get_absolute_url(self):
-        return reverse('ip-detail', kwargs={'pk': self.pk})
+        verbose_name = 'IP'
+        verbose_name_plural = 'IP'
 
     def __str__(self):
-        r = str(self.ip)
-        if self.mask:
-            r += '/%d' % self.mask
-        return r
+        return str(self.ip)
 
 
 class ServiceType(models.Model):
     name = models.CharField(max_length=64, verbose_name='Nom', unique=True)
-    group = models.ForeignKey(Group, null=True, blank=True,
-                              verbose_name='Groupe de gestion',
-                              related_name='service_types')
 
     class Meta:
+        ordering = ['name']
         verbose_name = 'type de service'
         verbose_name_plural = 'types de service'
 
-    def get_absolute_url(self):
-        return reverse('servicetype-detail', kwargs={'pk': self.pk})
-
     def __str__(self):
         return self.name
 
@@ -98,9 +85,6 @@ class Service(models.Model):
         if self.label != '' and Service.objects.exclude(pk=self.pk).filter(service_type=self.service_type, label=self.label):
             raise ValidationError("Un service du même type existe déjà avec ce label.")
 
-    def get_absolute_url(self):
-        return reverse('service-detail', kwargs={'pk': self.pk})
-
     def __str__(self):
         s = str(self.service_type)
         if self.label:

+ 1 - 1
services/templates/services/_service_list.html

@@ -12,7 +12,7 @@
     </div>
     <div class="list-group">
 {% endif %}
-    <a href="{% url service_detail_url service.pk %}" class="list-group-item {% if service.active %}list-group-item-success{% else %}list-group-item-danger{% endif %}">
+    <a href="{% url 'service-detail' service.pk %}" class="list-group-item {% if service.active %}list-group-item-success{% else %}list-group-item-danger{% endif %}">
         <span class="badge">#{{ service.id }}</span>
         <h4 class="list-group-item-heading">
             <b>{{ service.service_type }}</b>

+ 0 - 55
services/templates/services/ipresource_detail.html

@@ -1,55 +0,0 @@
-{% extends 'admin.html' %}
-
-{% load bootstrap3 services %}
-
-{% block breadcrumb %}
-<li><a href="{% url 'ip-list' %}">IP</a></li>
-<li class="active">{{ ipresource }}</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        {% if not ipresource.in_use %}<a class="btn btn-success pull-right" href="{% url 'ip-allocate' ipresource.pk %}">Allouer</a>{% endif %}
-        <h4>{{ ipresource }}</h4>
-        <h5>Historique des allocations</h5>
-    </div>
-    {% for allocation in ipresource.allocations.all %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>Service</th>
-            <th>Début</th>
-            <th>Fin</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr>
-            <td><a href="{% url 'service-detail' allocation.service.pk %}">{{ allocation.service }}</a></td>
-            <td>{{ allocation.start }}</td>
-            <td>{{ allocation.end|default:'–' }}</td>
-            <td class="text-right">
-                {% if allocation.active %}
-                <a href="#" data-toggle="modal" data-target="#confirm-deallocate" data-action="{% url 'deallocate' allocation.pk %}" data-ip="{{ allocation.resource }}" data-service="{{ allocation.service }}" class="btn btn-xs btn-danger">
-                    <span class="glyphicon glyphicon-remove"></span>&nbsp;Désallouer
-                </a>
-                {% endif %}
-            </td>
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% empty %}
-    <div class="panel-body">
-        <em>Auncune allocation.</em>
-    </div>
-    {% endfor %}
-</div>
-
-{% deallocate_modal_div %}
-{% endblock %}
-
-{% block js_end %}
-{{ block.super }}
-{% deallocate_modal_js %}
-{% endblock %}

+ 0 - 9
services/templates/services/ipresource_form.html

@@ -1,9 +0,0 @@
-{% comment %}{% extends 'base.html' %}
-
-{% block content %}
-
-<h1>{% if ipresource %}Modifier{% else %}Ajouter{% endif %} une ressource IP</h1>
-
-{% include '_form.html' %}
-
-{% endblock %}{% endcomment %}

+ 0 - 63
services/templates/services/ipresource_list.html

@@ -1,63 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-<li class="active">IP</li>
-{% endblock %}
-
-{% load bootstrap3 services %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>Liste des IP</h4>
-    </div>
-    {% for ip in object_list %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>Adresse</th>
-            <th>Affectation</th>
-            <th>Depuis le</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr>
-            {% with service=ip.allocation.service %}
-            <td><a href="{% url 'ip-detail' ip.pk %}">{{ ip }}</a></td>
-            {% if service %}
-            <td><a href="{% url 'service-detail' service.pk %}">{{ service }}</a></td>
-            <td>{{ ip.allocation.start }}</td>
-            {% else %}
-            <td>–</td>
-            <td>–</td>
-            {% endif %}
-            <td class="text-right">
-                {% if service %}
-                <a href="#" data-toggle="modal" data-target="#confirm-deallocate" data-action="{% url 'deallocate' ip.allocation.pk %}" data-ip="{{ ip }}" data-service="{{ ip.allocation.service }}" class="btn btn-xs btn-danger">
-                    <span class="glyphicon glyphicon-remove"></span>&nbsp;Désallouer
-                </a>
-                {% elif not ip.reserved %}
-                <a href="{% url 'ip-allocate' ip.pk %}" class="btn btn-xs btn-success">
-                    <span class="glyphicon glyphicon-plus"></span>&nbsp;Allouer
-                </a>
-                {% endif %}
-            </td>
-            {% endwith %}
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% endfor %}
-</div>
-
-<div class="text-center">
-    {% bootstrap_pagination page_obj %}
-</div>
-
-{% deallocate_modal_div %}
-{% endblock %}
-
-{% block js_end %}
-{{ block.super }}
-{% deallocate_modal_js %}
-{% endblock %}

+ 0 - 24
services/templates/services/resourceallocation_form.html

@@ -1,24 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-{% if service %}
-    <li><a href="{% url 'service-list' %}">Services</a></li>
-    <li><a href="{{ service.get_absolute_url }}">{{ service }}</a></li>
-{% elif ipresource %}
-    <li><a href="{% url 'ip-list' %}">IP</a></li>
-    <li><a href="{{ ipresource.get_absolute_url }}">{{ ipresource }}</a></li>
-{% endif %}
-<li class="active">Allocation</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>Allouer une IP</h4>
-    </div>
-    <div class="panel-body">
-        {% include '_form.html' %}
-    </div>
-</div>
-
-{% endblock %}

+ 7 - 17
services/templates/services/service_detail.html

@@ -1,18 +1,13 @@
-{% extends 'admin.html' %}
+{% extends 'base.html' %}
 
 {% load bootstrap3 %}
 
-{% block breadcrumb %}
-<li><a href="{% url 'service-list' %}">Services</a></li>
-<li class="active">{{ service }}</li>
-{% endblock %}
+{% block usertab %}{% if service.adhesion == request.user.profile.adhesion %} class="active"{% endif %}{% endblock %}
+{% block corptab %}{% if service.adhesion != request.user.profile.adhesion %} active{% endif %}{% endblock %}
 
 {% block content %}
 <div class="panel panel-{{ service.active|yesno:"success,danger"}}">
     <div class="panel-heading">
-        {% if perms.services.change_service %}
-        <a class="btn btn-success pull-right" href="{% url 'service-edit' service.pk %}"><span class="glyphicon glyphicon-edit"></span>&nbsp;Éditer</a>
-        {% endif %}
         <h3>{{ service.service_type }}</h3>
         {% if service.label %}
         <h4>{{ service.label }}</h4>
@@ -20,27 +15,22 @@
     </div>
     <div class="panel-body">
         <p>Identifiant du service : #{{ service.id }}</p>
-        <p>Responsable :
-            <a href="{% url 'adhesion-detail' service.adhesion.id %}">ADT{{ service.adhesion.id }}</a>
-            –
-            <a href="{{ service.adhesion.get_adherent_detail_url }}">{{ service.adhesion.get_adherent_name }}</a>
-        </p>
+        <p>Responsable : {{ service.adhesion }}</p>
         {% if service.contribution %}
-        <p>Contribution : <a href="{{ service.contribution.get_absolute_url }}">{{ service.contribution }}</a></p>
+        <p>Contribution : {{ service.contribution }}</p>
         {% else %}
         <p>Contribution : pas de contribution</p>
         {% endif %}
         <p>Actif : {{ service.active|yesno:"oui,non" }}</p>
         <p>
-            Ressources IP :
+            IP allouée{{ service.active_allocations.count|pluralize }} :
             {% for allocation in service.active_allocations %}
             {% if forloop.first %}<ul>{% endif %}
-                <li><a href="{% url 'ip-detail' allocation.resource.pk %}">{{ allocation.resource }}</a> (depuis le {{ allocation.start }})</li>
+                <li>{{ allocation.resource }} (depuis le {{ allocation.start }})</li>
             {% if forloop.last %}</ul>{% endif %}
             {% empty %}
             aucune IP allouée
             {% endfor %}
-            <a href="{% url 'service-allocate' service.pk %}" class="btn btn-success">Allouer une IP</a>
         </p>
     </div>
 </div>

+ 0 - 37
services/templates/services/service_detail_user.html

@@ -1,37 +0,0 @@
-{% extends 'base.html' %}
-
-{% load bootstrap3 %}
-
-{% block usertab %}{% if service.adhesion == request.user.profile.adhesion %} class="active"{% endif %}{% endblock %}
-{% block corptab %}{% if service.adhesion != request.user.profile.adhesion %} active{% endif %}{% endblock %}
-
-{% block content %}
-<div class="panel panel-{{ service.active|yesno:"success,danger"}}">
-    <div class="panel-heading">
-        <h3>{{ service.service_type }}</h3>
-        {% if service.label %}
-        <h4>{{ service.label }}</h4>
-        {% endif %}
-    </div>
-    <div class="panel-body">
-        <p>Identifiant du service : #{{ service.id }}</p>
-        <p>Responsable : {{ service.adhesion }}</p>
-        {% if service.contribution %}
-        <p>Contribution : {{ service.contribution }}</p>
-        {% else %}
-        <p>Contribution : pas de contribution</p>
-        {% endif %}
-        <p>Actif : {{ service.active|yesno:"oui,non" }}</p>
-        <p>
-            IP allouée{{ service.active_allocations.count|pluralize }} :
-            {% for allocation in service.active_allocations %}
-            {% if forloop.first %}<ul>{% endif %}
-                <li>{{ allocation.resource }} (depuis le {{ allocation.start }})</li>
-            {% if forloop.last %}</ul>{% endif %}
-            {% empty %}
-            aucune IP allouée
-            {% endfor %}
-        </p>
-    </div>
-</div>
-{% endblock %}

+ 0 - 52
services/templates/services/service_list.html

@@ -1,52 +0,0 @@
-{% extends 'admin.html' %}
-
-{% load bootstrap3 %}
-
-{% block breadcrumb %}
-<li class="active">Services</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <a class="btn btn-success pull-right" href="{% url 'service-add' %}">Ajouter un service</a>
-        <h4>Services</h4>
-    </div>
-    {% for service in object_list %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>#</th>
-            <th>Type</th>
-            <th>Label</th>
-            <th>Adhérent</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr class="{{ service.active|yesno:"success,danger" }}">
-            <td><a href="{% url 'service-detail' service.pk %}">#{{ service.pk }}</a></td>
-            <td>{{ service.service_type }}</td>
-            <td>{{ service.label }}</td>
-            <td>
-                <a href="{% url 'adhesion-detail' service.adhesion.id %}">ADT{{ service.adhesion.pk }}</a>
-                –
-                <a href="{{ service.adhesion.get_adherent_detail_url }}">{{ service.adhesion.get_adherent_name }}</a>
-            </td>
-            <td class="text-right">
-                <a href="{% url 'service-edit' service.pk %}"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Modifier</a>
-            </td>
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% empty %}
-    <div class="panel-body">
-        <em>Aucun service.</em>
-    </div>
-    {% endfor %}
-</div>
-
-<div class="text-center">
-    {% bootstrap_pagination page_obj %}
-</div>
-{% endblock %}

+ 0 - 46
services/templates/services/servicetype_detail.html

@@ -1,46 +0,0 @@
-{% extends 'admin.html' %}
-
-{% load bootstrap3 %}
-
-{% block breadcrumb %}
-<li><a href="{% url 'servicetype-list' %}">Types de services</a></li>
-<li class="active">{{ servicetype }}</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>{{ servicetype }}</h4>
-    </div>
-    {% for service in servicetype.services.all %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>#</th>
-            <th>Label</th>
-            <th>Adhérent</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr>
-            <td><a href="{% url 'service-detail' service.pk %}">#{{ service.pk }}</a></td>
-            <td>{{ service.label }}</td>
-            <td>
-                <a href="{% url 'adhesion-detail' service.adhesion.id %}">ADT{{ service.adhesion.pk }}</a>
-                –
-                <a href="{{ service.adhesion.get_adherent_detail_url }}">{{ service.adhesion.get_adherent_name }}</a>
-            </td>
-            <td class="text-right">
-                <a href="{% url 'service-edit' service.pk %}"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Modifier</a>
-            </td>
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% empty %}
-    <div class="panel-body">
-        <em>Aucun service.</em>
-    </div>
-    {% endfor %}
-</div>
-{% endblock %}

+ 0 - 22
services/templates/services/servicetype_form.html

@@ -1,22 +0,0 @@
-{% extends 'admin.html' %}
-
-{% block breadcrumb %}
-<li><a href="{% url 'servicetype-list' %}">Types de services</a></li>
-{% if servicetype %}
-<li><a href="{{ servicetype.get_absolute_url }}">{{ servicetype }}</a></li>
-<li class="active">Modification</li>
-{% else %}
-<li class="active">Nouveau</li>
-{% endif %}
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <h4>{% if servicetype %}Modifier{% else %}Ajouter{% endif %} un type de service</h4>
-    </div>
-    <div class="panel-body">
-{% include '_form.html' %}
-    </div>
-</div>
-{% endblock %}

+ 0 - 38
services/templates/services/servicetype_list.html

@@ -1,38 +0,0 @@
-{% extends 'admin.html' %}
-
-{% load bootstrap3 %}
-
-{% block breadcrumb %}
-<li class="active">Types de services</li>
-{% endblock %}
-
-{% block content %}
-<div class="panel panel-primary">
-    <div class="panel-heading">
-        <a class="btn btn-success pull-right" href="{% url 'servicetype-add' %}">Ajouter un type de service</a>
-        <h4>Types de services</h4>
-    </div>
-    {% for type in object_list %}
-    {% if forloop.first %}
-    <table class="table">
-        <tr>
-            <th>Nom</th>
-            <th></th>
-        </tr>
-    {% endif %}
-        <tr>
-            <td><a href="{% url 'servicetype-detail' type.pk %}">{{ type.name }}</a></td>
-            <td class="text-right">
-                <a href="{% url 'servicetype-edit' type.pk %}"><span class="glyphicon glyphicon-pencil"></span>&nbsp;Modifier</a>
-            </td>
-        </tr>
-    {% if forloop.last %}
-    </table>
-    {% endif %}
-    {% empty %}
-    <div class="panel-body">
-        <em>Aucun type de service.</em>
-    </div>
-    {% endfor %}
-</div>
-{% endblock %}

+ 0 - 19
services/templates/services/tags/deallocate_modal_div.html

@@ -1,19 +0,0 @@
-<div class="modal" id="confirm-deallocate" tabindex="-1" role="dialog" aria-hidden="true">
-  <div class="modal-dialog modal-sm">
-    <div class="panel panel-danger">
-      <div class="panel-heading" id="confirm-deallocate-title">
-        Désallouer <span class="confirm-deallocate-ip"></span> ?
-      </div>
-      <div class="panel-body">
-        <form action="" method="post" role="form" id="confirm-deallocate-form" class="text-center">
-          {% csrf_token %}
-          <p>
-            Êtes vous sûr de vouloir désallouer l’IP <strong class="confirm-deallocate-ip"></strong> actuellement affecté au service <strong class="confirm-deallocate-service"></strong> ?
-          </p>
-          <button type="submit" class="btn btn-danger">{% block confirm-ok %}Confirmer{% endblock %}</button>
-          <button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
-        </form>
-      </div>
-    </div>
-  </div>
-</div>

+ 0 - 2
services/templates/services/tags/deallocate_modal_js.html

@@ -1,2 +0,0 @@
-{% load staticfiles %}
-<script src="{% static 'js/deallocate_modal.js' %}"></script>

+ 1 - 16
services/urls.py

@@ -4,20 +4,5 @@ from . import views
 
 
 urlpatterns = [
-    # User views
-    url(r'^services/(?P<pk>[0-9]+)/$', views.ServiceDetail.as_view(template_name='services/service_detail_user.html'), name='service-detail-user'),
-    # Admin views
-    url(r'^admin/services/$', views.ServiceList.as_view(), name='service-list'),
-    url(r'^admin/services/(?P<pk>[0-9]+)/$', views.ServiceDetail.as_view(), name='service-detail'),
-    url(r'^admin/services/add/$', views.ServiceCreate.as_view(), name='service-add'),
-    url(r'^admin/services/(?P<pk>[0-9]+)/edit/$', views.ServiceUpdate.as_view(), name='service-edit'),
-    url(r'^admin/services/(?P<pk>[0-9]+)/allocate/$', views.ServiceAllocate.as_view(), name='service-allocate'),
-    url(r'^admin/servicetypes/$', views.ServiceTypeList.as_view(), name='servicetype-list'),
-    url(r'^admin/servicetypes/add/$', views.ServiceTypeCreate.as_view(), name='servicetype-add'),
-    url(r'^admin/servicetypes/(?P<pk>[0-9]+)/$', views.ServiceTypeDetail.as_view(), name='servicetype-detail'),
-    url(r'^admin/servicetypes/(?P<pk>[0-9]+)/edit/$', views.ServiceTypeUpdate.as_view(), name='servicetype-edit'),
-    url(r'^admin/ip/$', views.IPResourceList.as_view(), name='ip-list'),
-    url(r'^admin/ip/(?P<pk>[0-9]+)/$', views.IPResourceDetail.as_view(), name='ip-detail'),
-    url(r'^admin/ip/(?P<pk>[0-9]+)/allocate/$', views.IPResourceAllocate.as_view(), name='ip-allocate'),
-    url(r'^admin/allocations/(?P<pk>[0-9]+)/deallocate/$', views.ResourceAllocationDeallocate.as_view(), name='deallocate'),
+    url(r'^services/(?P<pk>[0-9]+)/$', views.ServiceDetail.as_view(), name='service-detail'),
 ]

+ 4 - 135
services/views.py

@@ -1,142 +1,11 @@
-from django.shortcuts import render, get_object_or_404
-from django.views.generic import ListView, CreateView, DetailView, UpdateView, RedirectView
-from django.views.generic.detail import SingleObjectMixin
+from django.views.generic import DetailView
 from django.contrib.auth.mixins import LoginRequiredMixin
-from django.contrib.auth.mixins import PermissionRequiredMixin
-from django.http import HttpResponseGone
-from django.urls import reverse
 
-from djadhere.utils import get_active_filter
-from .models import Service, ServiceType, IPResource, ResourceAllocation
-from .forms import ServiceForm, ResourceAllocationForm
-
-
-class ServiceMixin(PermissionRequiredMixin):
-    model = Service
-    permission_required = 'services.change_service'
-
-
-class ServiceList(ServiceMixin, ListView):
-    paginate_by = 50
-
-
-class ServiceCreate(ServiceMixin, CreateView):
-    form_class = ServiceForm
+from .models import Service
 
 
 class ServiceDetail(LoginRequiredMixin, DetailView):
     def get_queryset(self):
-        if self.request.user.is_superuser:
-            return Service.objects.all()
-        else:
-            return Service.objects.filter(adhesion__pk__in=self.request.user.profile.adhesions.values_list('pk')) \
+        return Service.objects.filter(adhesion__pk__in=\
+                        self.request.user.profile.adhesions.values_list('pk')) \
                         .order_by('-created')
-
-
-class ServiceUpdate(ServiceMixin, UpdateView):
-    fields = ('label', 'notes', 'active',)
-
-
-class ServiceAllocate(PermissionRequiredMixin, CreateView):
-    model = ResourceAllocation
-    permission_required = 'services.change_resourceallocation'
-    form_class = ResourceAllocationForm
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context['service'] = get_object_or_404(Service, pk=self.kwargs['pk'])
-        return context
-
-    def get_form(self):
-        service = get_object_or_404(Service, pk=self.kwargs['pk'])
-        kwargs = super().get_form_kwargs()
-        kwargs['initial'].update({'service': service.pk})
-        form = self.get_form_class()(**kwargs)
-        form.fields['service'].disabled = True
-        form.fields['resource'].queryset = IPResource.objects.filter(reserved=False).exclude(get_active_filter('allocation'))
-        return form
-
-    def get_success_url(self):
-        return reverse('service-detail', kwargs={'pk': self.kwargs['pk']})
-
-
-class ServiceTypeMixin(PermissionRequiredMixin):
-    model = ServiceType
-    permission_required = 'services.change_servicetype'
-
-
-class ServiceTypeList(ServiceTypeMixin, ListView):
-    pass
-
-
-class ServiceTypeCreate(ServiceTypeMixin, CreateView):
-    fields = ('name',)
-
-
-class ServiceTypeDetail(ServiceTypeMixin, DetailView):
-    pass
-
-
-class ServiceTypeUpdate(ServiceTypeMixin, UpdateView):
-    fields = ('name',)
-
-
-class IPResourceMixin(PermissionRequiredMixin):
-    model = IPResource
-    permission_required = 'services.change_ipresource'
-
-
-class IPResourceList(IPResourceMixin, ListView):
-    paginate_by = 50
-
-
-class IPResourceDetail(IPResourceMixin, DetailView):
-    pass
-
-
-class IPResourceAllocate(PermissionRequiredMixin, CreateView):
-    model = ResourceAllocation
-    permission_required = 'services.change_resourceallocation'
-    form_class = ResourceAllocationForm
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context['ipresource'] = get_object_or_404(IPResource, pk=self.kwargs['pk'])
-        return context
-
-    def get(self, request, *args, **kwargs):
-        resource = get_object_or_404(IPResource, pk=self.kwargs['pk'])
-        if resource.in_use:
-            return HttpResponseGone("Cette IP est déjà allouée !")
-        if resource.reserved:
-            return HttpResponseGone("Cette IP est réservée !")
-        return super().get(request, *args, **kwargs)
-
-    def get_form(self):
-        resource = get_object_or_404(IPResource, pk=self.kwargs['pk'])
-        kwargs = super().get_form_kwargs()
-        kwargs['initial'].update({'resource': resource.pk})
-        form = self.get_form_class()(**kwargs)
-        form.fields['resource'].disabled = True
-        return form
-
-    def get_success_url(self):
-        return reverse('ip-detail', kwargs={'pk': self.kwargs['pk']})
-
-
-class ResourceAllocationMixin(PermissionRequiredMixin):
-    model = ResourceAllocation
-    permission_required = 'services.change_resourceallocation'
-
-
-class ResourceAllocationDeallocate(ResourceAllocationMixin, SingleObjectMixin, RedirectView):
-    http_method_names = ['post']
-
-    def get_object(self, queryset=None):
-        obj = super().get_object(queryset)
-        obj.deallocate()
-        obj.save()
-        return obj
-
-    def get_redirect_url(self, *args, **kwargs):
-        return self.get_object().get_absolute_url()