from django.contrib import admin 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.models import User as AuthUser from django.contrib.auth.admin import UserAdmin as AuthUserAdmin from django.http import HttpResponseRedirect from django.utils.html import format_html, mark_safe from django.urls import reverse from django.utils import timezone from django.conf.urls import url from django.template.response import TemplateResponse from .forms import UserCreationForm from .models import User, Corporation, Adhesion from accounts.models import Profile from services.models import Service from djadhere.utils import ActiveFilter, get_active_filter from banking.models import PaymentUpdate from datetime import timedelta ### Inlines 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 AdhesionInline(admin.StackedInline): model = Adhesion fields = ('id', 'notes',) def has_add_permission(self, request): return False def has_delete_permission(self, request, obj=None): return False class ServiceInline(admin.StackedInline): model = Service extra = 0 show_change_link = True fields = ('service_type', 'label',) readonly_fields = ('service_type', 'label',) def has_add_permission(self, request): return False def has_delete_permission(self, request, obj=None): return False class ActiveServiceInline(ServiceInline): verbose_name_plural = 'Services actifs' def get_queryset(self, request): return super().get_queryset(request).filter(active=True) class InactiveServiceInline(ServiceInline): verbose_name_plural = 'Anciens services' def get_queryset(self, request): return super().get_queryset(request).filter(active=False) ### Filters class AdherentTypeFilter(admin.SimpleListFilter): title = 'type d’adhérent·e' parameter_name = 'type' def lookups(self, request, model_admin): return ( ('physique', 'Personne physique'), ('morale', 'Personne morale'), ) def queryset(self, request, queryset): if self.value() == 'physique': return queryset.filter(user__isnull=False) if self.value() == 'morale': return queryset.filter(corporation__isnull=False) ### Mixins class AdtSearchMixin: adhesion_search_field = 'id' def get_search_results(self, request, queryset, search_term): queryset, use_distinct = super().get_search_results(request, queryset, search_term) if search_term[:3] == 'ADT': try: adh_id = int(search_term[3:]) except ValueError: pass else: queryset |= self.model.objects.filter(**{self.adhesion_search_field: adh_id}) return queryset, use_distinct ### ModelAdmin class UserAdmin(AdtSearchMixin, AuthUserAdmin): list_display = AuthUserAdmin.list_display + ('get_adhesion_link',) list_select_related = ('profile', 'adhesion',) ordering = ('adhesion__id',) search_fields = AuthUserAdmin.search_fields \ + ('profile__phone_number', 'profile__address', 'profile__notes',) \ + ('=adhesion__id', 'adhesion__notes',) readonly_fields = ('get_adhesion_link',) adhesion_search_field = 'adhesion__id' get_adhesion_link = lambda self, corporation: corporation.adhesion.get_adhesion_link() get_adhesion_link.short_description = Adhesion.get_adhesion_link.short_description get_adhesion_link.admin_order_field = 'adhesion__id' def get_inline_instances(self, request, obj=None): if obj: inlines = (ProfileInline, AdhesionInline,) else: inlines = () return [inline(self.model, self.admin_site) for inline in inlines] def get_form(self, request, obj=None, **kwargs): if obj: return super().get_form(request, obj, **kwargs) else: return UserCreationForm def get_fieldsets(self, request, obj=None): if obj: fieldsets = ( (AuthUserAdmin.fieldsets[1][0], { 'fields': ('get_adhesion_link',) + AuthUserAdmin.fieldsets[1][1]['fields'], }), ('Nom d’utilisateur et mot de passe', { 'classes': ('collapse',), 'fields': AuthUserAdmin.fieldsets[0][1]['fields'], }), (AuthUserAdmin.fieldsets[2][0], { 'classes': ('collapse',), 'fields': ('is_active', 'is_staff', 'is_superuser', 'groups',), # removing user_permissions }), (AuthUserAdmin.fieldsets[3][0], { 'classes': ('collapse',), 'fields': AuthUserAdmin.fieldsets[3][1]['fields'], }), ) else: fieldsets = ( (None, { 'fields': ('first_name', 'last_name', 'username', 'email',), }), ) return fieldsets 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 class CorporationAdmin(AdtSearchMixin, admin.ModelAdmin): list_display = ('social_reason', 'get_adhesion_link',) list_select_related = ('adhesion',) ordering = ('adhesion__id',) search_fields = ('social_reason', 'description', 'email', 'phone_number', 'address', 'notes', 'adhesion__id', 'adhesion__notes',) readonly_fields = ('get_adhesion_link',) filter_horizontal = ('members',) adhesion_search_field = 'adhesion__id' get_adhesion_link = lambda self, corporation: corporation.adhesion.get_adhesion_link() get_adhesion_link.short_description = Adhesion.get_adhesion_link.short_description get_adhesion_link.admin_order_field = 'adhesion__id' def get_inline_instances(self, request, obj=None): if obj: inlines = (AdhesionInline,) else: inlines = () return [inline(self.model, self.admin_site) for inline in inlines] def get_actions(self, request): actions = super().get_actions(request) if 'delete_selected' in actions: del actions['delete_selected'] return actions def get_fieldsets(self, request, obj=None): fieldsets = super().get_fieldsets(request, obj) # put adhesion id on top if obj: fields = fieldsets[0][1]['fields'] fields.remove('get_adhesion_link') fieldsets = ( (None, { 'fields': ['get_adhesion_link'] + fields, }), ) return fieldsets def has_delete_permission(self, request, obj=None): return False class AdhesionAdmin(AdtSearchMixin, admin.ModelAdmin): list_display = ('get_id', 'type', 'get_adherent_link', 'is_active') list_filter = (AdherentTypeFilter, ActiveFilter) list_select_related = ('user', 'user__profile', 'corporation',) fields = ('id', 'type', 'get_adherent_link', 'get_membership_link', 'get_antennas_link',) readonly_fields = ('id', 'type', 'get_adherent_link', 'get_membership_link', 'get_antennas_link',) search_fields = ('=id', 'notes',) \ + tuple(['user__%s' % f for f in UserAdmin.search_fields if 'adhesion' not in f]) \ + tuple(['corporation__%s' % f for f in CorporationAdmin.search_fields if 'adhesion' not in f]) inlines = (ActiveServiceInline, InactiveServiceInline,) def get_id(self, obj): return 'ADT%d' % obj.id get_id.short_description = 'Numéro d’adhérent·e' get_id.admin_order_field = 'id' def get_membership_link(self, obj): return format_html(u'{}', obj.membership.get_absolute_url(), obj.membership.get_current_payment_display()) get_membership_link.short_description = 'Cotisation' def get_antennas_link(self, obj): return mark_safe('
'.join(map(lambda antenna: antenna.get_absolute_link(), obj.antenna_set.all()))) get_antennas_link.short_description = 'Antennes' 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): if not obj: return False one_year_ago = timezone.now() - timedelta(days=365) membership = obj.membership.updates.filter(validated=True).first() # si l’adhésion n’a pas été résilié il y a plus d’un an if not membership or membership.payment_method != PaymentUpdate.STOP or membership.start > one_year_ago: return False # si l’adhérent·e est référent pour une antenne if obj.antenna_set.exists(): return False # si l’adherent a un service if obj.services.exists(): return False return True def contact_view(self, request): adhesions = request.GET.get('pk').split(',') adhesions = Adhesion.objects.filter(pk__in=adhesions) user_email = filter(lambda x: x, adhesions.values_list('user__email', flat=True)) corp_email = filter(lambda x: x, adhesions.values_list('corporation__email', flat=True)) user_tel = filter(lambda x: x, adhesions.values_list('user__profile__phone_number', flat=True)) corp_tel = filter(lambda x: x, adhesions.values_list('corporation__phone_number', flat=True)) sms_filter = lambda x: x[:2] == '06' or x[:2] == '07' or x[:3] == '+336' or x[:3] == '+337' return TemplateResponse(request, 'adhesions/contact.html', dict( adhesions = adhesions, emails = set(user_email) | set(corp_email), sms = filter(sms_filter, set(user_tel) | set(corp_tel)) )) def get_urls(self): my_urls = [ url(r'^contact/$', self.admin_site.admin_view(self.contact_view, cacheable=True), name='contact-adherents'), ] return my_urls + super().get_urls() admin.site.unregister(AuthUser) admin.site.register(User, UserAdmin) admin.site.register(Corporation, CorporationAdmin) admin.site.register(Adhesion, AdhesionAdmin)