Repository: ephios-dev/ephios

Issue:
Qualifikationen verwalten
Als Administrator möchte ich die verfügbaren Qualifikationen verwalten. Dies kann vorerst über das Django Admin-Interface geschehen. Dafür erwarte ich, dass es entsprechende Models gibt und diese bei Django Admin registriert sind.

### Qualifikationen
Helfer haben Qualifikationen in verschiedenen Tracks, z.B. medizinisch, Führerschein, Bootsführerschein, Einweisungen in Geräte/Fahrzeuge, Führungsqualifikation, Fachqualifikation...

Qualifikationen können andere beinhalten. Das Beinhalten ist dann transitiv. Jeder NotSan kann als RettSan eingesetzt werden. Jeder RettSan als SanH und damit jeder NotSan als SanH.  Jeder mit Führerschein C darf was fahren, wo er B braucht, usw...

Wichtige Frage: Muss eine Quali mehrere Vorgänger haben können oder reicht einer?


Discussion:

Resolving patch:
diff --git a/jep/management/commands/setupdata.py b/jep/management/commands/setupdata.py
--- a/jep/management/commands/setupdata.py
+++ b/jep/management/commands/setupdata.py
@@ -111,28 +111,6 @@ def create_objects(self, *args, **options):
         user.save()
         volunteers.user_set.add(user)
 
-        medical_category = QualificationCategory.objects.create(
-            title=_("Medical"), uuid=uuid.UUID("50380292-b9c9-4711-b70d-8e03e2784cfb"),
-        )
-
-        rs = Qualification.objects.create(
-            category=medical_category,
-            title="Rettungssanitäter",
-            abbreviation="RS",
-            uuid=uuid.UUID("0b41fac6-ca9e-4b8a-82c5-849412187351"),
-        )
-
-        nfs = Qualification.objects.create(
-            category=medical_category,
-            title="Notfallsanitäter",
-            abbreviation="NFS",
-            uuid=uuid.UUID("d114125b-7cf4-49e2-8908-f93e2f95dfb8"),
-        )
-        nfs.included_qualifications.add(rs)
-
-        QualificationGrant.objects.create(user=user, qualification=nfs)
-        QualificationGrant.objects.create(user=self.admin_user, qualification=rs)
-
         event = Event.objects.create(
             title=_("Concert Medical Service"),
             description=_("Your contact is Lisa Example. Her Phone number is 012345678910"),
@@ -158,6 +136,205 @@ def create_objects(self, *args, **options):
         )
 
 
+@register_dataset
+class QualificationDataset(AbstractDataset):
+    identifier = "qualifications"
+    action = "Create qualification objects for medical qualifications and driver licenses"
+
+    def create_objects(self, *args, **options):
+        medical_category = QualificationCategory.objects.create(
+            title=_("Medical"), uuid=uuid.UUID("50380292-b9c9-4711-b70d-8e03e2784cfb"),
+        )
+
+        eh = Qualification.objects.create(
+            category=medical_category,
+            title="Ersthelfer",
+            abbreviation="EH",
+            uuid=uuid.UUID("8bdb343e-d78d-4cc9-80e7-7ccc36b556e1"),
+        )
+
+        sanh = Qualification.objects.create(
+            category=medical_category,
+            title="Sanitätshelfer",
+            abbreviation="SanH",
+            uuid=uuid.UUID("b1faab38-2e7c-4507-b753-06d1e653412d"),
+        )
+        sanh.included_qualifications.add(eh)
+
+        rh = Qualification.objects.create(
+            category=medical_category,
+            title="Rettungshelfer",
+            abbreviation="RH",
+            uuid=uuid.UUID("de6c2449-a764-4c39-8f44-de276e99451b"),
+        )
+        rh.included_qualifications.add(sanh)
+
+        rs = Qualification.objects.create(
+            category=medical_category,
+            title="Rettungssanitäter",
+            abbreviation="RS",
+            uuid=uuid.UUID("0b41fac6-ca9e-4b8a-82c5-849412187351"),
+        )
+        rs.included_qualifications.add(rh)
+
+        ra = Qualification.objects.create(
+            category=medical_category,
+            title="Rettungsassistent",
+            abbreviation="RA",
+            uuid=uuid.UUID("2a24e395-fa02-4b2e-8215-7763b04d85c8"),
+        )
+        ra.included_qualifications.add(rs)
+
+        nfs = Qualification.objects.create(
+            category=medical_category,
+            title="Notfallsanitäter",
+            abbreviation="NFS",
+            uuid=uuid.UUID("d114125b-7cf4-49e2-8908-f93e2f95dfb8"),
+        )
+        nfs.included_qualifications.add(ra)
+
+        na = Qualification.objects.create(
+            category=medical_category,
+            title="Notarzt",
+            abbreviation="NA",
+            uuid=uuid.UUID("cb4f4ebc-3adf-4d32-a427-0ac0f686038a"),
+        )
+
+        driverslicense_category = QualificationCategory.objects.create(
+            title=_("License"), uuid=uuid.UUID("a5669cc2-7444-4046-8c33-d8ee0bbf881b"),
+        )
+
+        l = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse L",
+            abbreviation="Fe L",
+            uuid=uuid.UUID("1c007860-48eb-4c86-a35b-45c6de903de4"),
+        )
+
+        t = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse T",
+            abbreviation="Fe T",
+            uuid=uuid.UUID("cc5ab73d-a1d6-4e95-93d2-aaf6c51ae91f"),
+        )
+
+        am = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse AM",
+            abbreviation="Fe AM",
+            uuid=uuid.UUID("f96bdfef-f1b8-46aa-8755-e506075ebc88"),
+        )
+
+        a1 = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse A1",
+            abbreviation="Fe A1",
+            uuid=uuid.UUID("d7e9da8f-8386-4e7d-8706-62103bfe78f1"),
+        )
+        a1.included_qualifications.add(am)
+
+        a2 = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse A2",
+            abbreviation="Fe A2",
+            uuid=uuid.UUID("fe06530c-8216-40a0-81dd-2beaa8d803e1"),
+        )
+        a2.included_qualifications.add(a1)
+
+        a = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse A",
+            abbreviation="Fe A",
+            uuid=uuid.UUID("4ff00daa-1501-41c0-8d89-2e54cb43f293"),
+        )
+        a.included_qualifications.add(a2)
+
+        b = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse B",
+            abbreviation="Fe B",
+            uuid=uuid.UUID("0715b687-877a-4fed-bde0-5ea06b1043fc"),
+        )
+        b.included_qualifications.add(am)
+        b.included_qualifications.add(l)
+
+        be = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse BE",
+            abbreviation="Fe BE",
+            uuid=uuid.UUID("31529f69-09d7-44cc-84f6-19fbfd949faa"),
+        )
+        be.included_qualifications.add(b)
+
+        c1 = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse C1",
+            abbreviation="Fe C1",
+            uuid=uuid.UUID("c9898e6c-4ecf-4781-9c0a-884861e36a81"),
+        )
+        c1.included_qualifications.add(b)
+
+        c = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse C",
+            abbreviation="Fe C",
+            uuid=uuid.UUID("2d2fc932-5206-4c2c-bb63-0bc579acea6f"),
+        )
+        c.included_qualifications.add(c1)
+
+        c1e = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse C1E",
+            abbreviation="Fe C1E",
+            uuid=uuid.UUID("f5e3be89-59de-4b13-a92f-5949009f62d8"),
+        )
+        c1e.included_qualifications.add(c1)
+        c1e.included_qualifications.add(be)
+
+        ce = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse CE",
+            abbreviation="Fe CE",
+            uuid=uuid.UUID("736ca05a-7ff9-423a-9fa4-8b4641fde29c"),
+        )
+        ce.included_qualifications.add(c)
+        ce.included_qualifications.add(c1e)
+
+        d1 = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse D1",
+            abbreviation="Fe D1",
+            uuid=uuid.UUID("3df818c6-f4a7-400e-a5bf-64ed087f79ab"),
+        )
+        d1.included_qualifications.add(b)
+
+        d = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse D",
+            abbreviation="Fe D",
+            uuid=uuid.UUID("3238a892-afa8-4e76-b9b9-87d8765c5b72"),
+        )
+        d.included_qualifications.add(d1)
+
+        d1e = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse D1E",
+            abbreviation="Fe D1E",
+            uuid=uuid.UUID("5d0ab40e-fade-4d45-9882-0039118a2445"),
+        )
+        d1e.included_qualifications.add(d1)
+        d1e.included_qualifications.add(be)
+
+        de = Qualification.objects.create(
+            category=driverslicense_category,
+            title="Fahrerlaubnis Klasse DE",
+            abbreviation="Fe DE",
+            uuid=uuid.UUID("64495d88-3ec0-4bbe-bc2b-78b6e6cfbc25"),
+        )
+        de.included_qualifications.add(d)
+        de.included_qualifications.add(d1e)
+
+
 class Command(BaseCommand):
     help = "Load initial data from datasets."
 
diff --git a/user_management/admin.py b/user_management/admin.py
--- a/user_management/admin.py
+++ b/user_management/admin.py
@@ -2,7 +2,12 @@
 from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
 
 from user_management.forms import UserChangeForm, UserCreationForm
-from user_management.models import Qualification, UserProfile
+from user_management.models import (
+    Qualification,
+    UserProfile,
+    QualificationGrant,
+    QualificationCategory,
+)
 
 
 class UserAdmin(BaseUserAdmin):
@@ -43,3 +48,5 @@ class UserAdmin(BaseUserAdmin):
 
 admin.site.register(UserProfile, UserAdmin)
 admin.site.register(Qualification)
+admin.site.register(QualificationGrant)
+admin.site.register(QualificationCategory)
diff --git a/user_management/models.py b/user_management/models.py
--- a/user_management/models.py
+++ b/user_management/models.py
@@ -2,6 +2,7 @@
 from datetime import datetime
 
 import guardian.mixins
+import uuid
 from django.contrib.auth import get_user_model
 from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
 from django.contrib.auth.models import PermissionsMixin
@@ -121,16 +122,19 @@ def get_shifts(self, with_participation_state_in):
 
 
 class QualificationCategory(Model):
-    uuid = models.UUIDField(unique=True)
+    uuid = models.UUIDField(unique=True, default=uuid.uuid4)
     title = CharField(_("title"), max_length=254)
 
     class Meta:
         verbose_name = _("qualification track")
         verbose_name_plural = _("qualification tracks")
 
+    def __str__(self):
+        return self.title
+
 
 class Qualification(Model):
-    uuid = models.UUIDField(unique=True)
+    uuid = models.UUIDField(unique=True, default=uuid.uuid4)
     title = CharField(_("title"), max_length=254)
     abbreviation = CharField(max_length=254)
     category = ForeignKey(
@@ -144,7 +148,7 @@ class Qualification(Model):
     )
 
     def __eq__(self, other):
-        return self.uuid == other.uuid
+        return self.uuid == other.uuid if other else False
 
     def __hash__(self):
         return hash(self.uuid)


Test patch: