123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- from django.contrib import admin
- from django.db import models
- from django.forms import ModelForm, BaseInlineFormSet
- from django.utils import timezone
- from django.core.urlresolvers import reverse
- from django.utils.html import format_html
- from django.core.mail import mail_managers
- from adhesions.models import Adhesion
- from djadhere.utils import get_active_filter
- from .models import Service, ServiceType, IPResource, Route, ResourceAllocation
- from .utils import notify_allocation
- ### Filters
- class ResourceInUseFilter(admin.SimpleListFilter):
- title = 'disponibilité'
- parameter_name = 'available'
- def lookups(self, request, model_admin):
- return (
- (1, 'Disponible'),
- (0, 'Non disponible'),
- )
- def queryset(self, request, queryset):
- now = timezone.now()
- active_filter = get_active_filter('allocation')
- if self.value() == '0': # non disponible
- return queryset.filter(active_filter | models.Q(reserved=True))
- if self.value() == '1': # disponible
- return queryset.exclude(reserved=True).exclude(active_filter)
- class AllocationStatusFilter(admin.SimpleListFilter):
- title = 'statut'
- parameter_name = 'status'
- def lookups(self, request, model_admin):
- return (
- (1, 'En cours'),
- (0, 'Terminée'),
- )
- def queryset(self, request, queryset):
- now = timezone.now()
- active_filter = get_active_filter()
- if self.value() == '0': # inactif
- return queryset.exclude(active_filter)
- if self.value() == '1': # actif
- return queryset.filter(active_filter)
- ### Inlines
- class ResourceAllocationInlineFormSet(BaseInlineFormSet):
- def save_new(self, form, commit=True):
- obj = super().save_new(form, commit)
- notify_allocation(self.request, obj)
- return obj
- def save_existing(self, form, instance, commit=True):
- old = ResourceAllocation.objects.get(pk=instance.pk)
- notify_allocation(self.request, instance, old)
- return super().save_existing(form, instance, commit)
- class AllocationInline(admin.TabularInline):
- model = ResourceAllocation
- formset = ResourceAllocationInlineFormSet
- extra = 0
- fields = ('id', 'service', 'resource', 'route', 'start', 'end')
- raw_id_fields = ('service', 'resource',)
- verbose_name_plural = 'Allocations'
- show_change_link = True
- def get_formset(self, request, obj=None, **kwargs):
- formset = super().get_formset(request, obj, **kwargs)
- formset.request = request
- return formset
- 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
- # il faudrait surcharger la méthode clean du formset pour supprimer cette limite
- return existing + 1
- def has_delete_permission(self, request, obj=None):
- return False
- ### Actions
- def ends_resource(resource, request, queryset):
- now = timezone.now()
- queryset.exclude(start__lte=now, end__isnull=False).update(end=now)
- # TODO: send mail
- ends_resource.short_description = 'Terminer les allocations sélectionnées'
- ### ModelAdmin
- class ServiceAdmin(admin.ModelAdmin):
- list_display = ('id', 'get_adhesion_link', 'get_adherent_link', 'service_type', 'label', 'active')
- list_select_related = ('adhesion',) # to reduce database requests
- list_filter = (
- 'active',
- ('service_type', admin.RelatedOnlyFieldListFilter),
- )
- inlines = (AllocationInline,)
- search_fields = ('id', 'service_type__name', 'label', 'adhesion__id',)
- raw_id_fields = ('adhesion',)
- get_adhesion_link = lambda self, service: service.adhesion.get_adhesion_link()
- get_adhesion_link.short_description = Adhesion.get_adhesion_link.short_description
- get_adherent_link = lambda self, service: service.adhesion.get_adherent_link()
- get_adherent_link.short_description = Adhesion.get_adherent_link.short_description
- 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__', 'available_display')
- list_filter = (
- ResourceInUseFilter,
- ('prefixes', admin.RelatedOnlyFieldListFilter),
- )
- fields = ('ip', 'reserved', 'notes')
- readonly_fields = ('ip', 'reserved',)
- search_fields = ('ip',)
- inlines = (AllocationInline,)
- def available_display(self, obj):
- return not obj.reserved and not obj.in_use
- available_display.short_description = 'Disponible'
- available_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', 'service', 'start', 'end',)
- list_display_links = ('resource', 'service',)
- list_filter = (AllocationStatusFilter,)
- #actions = (ends_resource,)
- raw_id_fields = ('resource', 'service',)
- search_fields = ('resource__ip', 'service__id', 'service__service_type__name', 'service__label')
- 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
- def save_model(self, request, obj, form, change):
- if change:
- old_alloc = ResourceAllocation.objects.get(pk=obj.pk)
- else:
- old_alloc = None
- super().save_model(request, obj, form, change)
- notify_allocation(request, obj, old_alloc)
- 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, ServiceTypeAdmin)
- admin.site.register(Service, ServiceAdmin)
- admin.site.register(IPResource, IPResourceAdmin)
- admin.site.register(Route, RouteAdmin)
- admin.site.register(ResourceAllocation, ResourceAllocationAdmin)
|