Browse Source

Automatically generate the codename of a RowLevelPermission

SimonBoulier 7 years ago
parent
commit
0fbd9152b9
2 changed files with 69 additions and 15 deletions
  1. 7 1
      coin/members/admin.py
  2. 62 14
      coin/members/models.py

+ 7 - 1
coin/members/admin.py

@@ -6,6 +6,7 @@ from django.contrib import admin
 from django.contrib import messages
 from django.contrib.auth.admin import UserAdmin
 from django.contrib.auth.models import Group, Permission
+from django.contrib.contenttypes.models import ContentType
 from django.http import HttpResponseRedirect
 from django.conf.urls import url
 from django.db.models.query import QuerySet
@@ -256,9 +257,14 @@ class MembershipFeeAdmin(admin.ModelAdmin):
                     'payment_date')
     form = autocomplete_light.modelform_factory(MembershipFee, fields='__all__')
 
+class RowLevelPermissionAdmin(admin.ModelAdmin):
+    def get_changeform_initial_data(self, request):
+        return {'content_type': ContentType.objects.get_for_model(OfferSubscription)}
+
+
 
 admin.site.register(Member, MemberAdmin)
 admin.site.register(MembershipFee, MembershipFeeAdmin)
 # admin.site.unregister(Group)
 # admin.site.register(LdapUser, LdapUserAdmin)
-admin.site.register(RowLevelPermission)
+admin.site.register(RowLevelPermission, RowLevelPermissionAdmin)

+ 62 - 14
coin/members/models.py

@@ -495,6 +495,29 @@ class LdapUser(ldapdb.models.Model):
 # managed = False  # Indique à Django de ne pas intégrer ce model en base
 
 
+
+@receiver(pre_save, sender=Member)
+def define_username(sender, instance, **kwargs):
+    """
+    Lors de la sauvegarde d'un membre. Si le champ username n'est pas définit,
+    le calcul automatiquement en fonction du nom et du prénom
+    """
+    if not instance.username and not instance.pk:
+        instance.username = get_automatic_username(instance)
+
+
+@receiver(pre_save, sender=LdapUser)
+def define_display_name(sender, instance, **kwargs):
+    """
+    Lors de la sauvegarde d'un utilisateur Ldap, le champ display_name est la
+    concaténation de first_name et last_name
+    """
+    if not instance.display_name:
+        instance.display_name = '%s %s' % (instance.first_name,
+                                           instance.last_name)
+
+
+
 class RowLevelPermission(Permission):
     offer = models.ForeignKey(
         'offers.Offer', null=True, verbose_name="Offre",
@@ -530,24 +553,49 @@ class RowLevelPermission(Permission):
         verbose_name = 'permission fine'
         verbose_name_plural = 'permissions fines'
 
+RowLevelPermission._meta.get_field('codename').blank = True
+RowLevelPermission._meta.get_field('codename').help_text = 'Laisser vide pour le générer automatiquement'
+RowLevelPermission._meta.get_field('content_type').help_text = "Garder 'abonnement' pour une utilisation normale"
 
-
-@receiver(pre_save, sender=Member)
-def define_username(sender, instance, **kwargs):
+def get_automatic_codename(perm):
     """
-    Lors de la sauvegarde d'un membre. Si le champ username n'est pas définit,
-    le calcul automatiquement en fonction du nom et du prénom
+    Calcule le codename automatiquement en fonction du name.
     """
-    if not instance.username and not instance.pk:
-        instance.username = get_automatic_username(instance)
+    if perm.name:
+        codename = perm.name
+    else:
+        raise Exception('Il n\'y a pas sufissement d\'informations pour déterminer un codename automatiquement')
+
+    # Remplacer ou enlever les caractères non ascii
+    codename = unicodedata.normalize('NFD', codename)\
+        .encode('ascii', 'ignore')
+    # Enlever ponctuation (sauf _-.) et espace
+    punctuation = ('!"#$%&\'()*+,/:;<=>?@[\\]^`{|}~').encode('ascii')
+    codename = codename.translate(None, punctuation)
+    # En minuscule
+    codename = codename.lower()
+    # Maximum de 30 char
+    codename = codename[:30]
+    codename = codename.strip().replace(' ', '-')
+
+    # Recherche dans les membres existants un codename identique
+    perm = Permission.objects.filter(codename=codename)
+    base_codename = codename
+    incr = 2
+    # Tant qu'une permission est trouvée, incrémente un entier à la fin
+    while perm:
+        codename = base_codename + str(incr)
+        perm = Permission.objects.filter(codename=codename)
+        incr += 1
 
+    return codename
 
-@receiver(pre_save, sender=LdapUser)
-def define_display_name(sender, instance, **kwargs):
+
+@receiver(pre_save, sender=RowLevelPermission)
+def define_codename(sender, instance, **kwargs):
     """
-    Lors de la sauvegarde d'un utilisateur Ldap, le champ display_name est la
-    concaténation de first_name et last_name
+    Lors de la sauvegarde d'une RowLevelPermission. Si le champ codename n'est pas définit,
+    le calcul automatiquement.
     """
-    if not instance.display_name:
-        instance.display_name = '%s %s' % (instance.first_name,
-                                           instance.last_name)
+    if not instance.codename:
+        instance.codename = get_automatic_codename(instance)