diff --git a/client/src/graphql/gql/mutations/joinClass.gql b/client/src/graphql/gql/mutations/joinClass.gql
new file mode 100644
index 00000000..5386a337
--- /dev/null
+++ b/client/src/graphql/gql/mutations/joinClass.gql
@@ -0,0 +1,5 @@
+mutation JoinClass($input: JoinClassInput!) {
+ joinClass(input: $input) {
+ success
+ }
+}
diff --git a/client/src/pages/joinClass.vue b/client/src/pages/joinClass.vue
index b445fbf1..26456e62 100644
--- a/client/src/pages/joinClass.vue
+++ b/client/src/pages/joinClass.vue
@@ -1,9 +1,52 @@
-
Join Class
+
Schulklasse beitreten {{code}}
+
+
diff --git a/server/users/admin.py b/server/users/admin.py
index 9733310f..db39db05 100644
--- a/server/users/admin.py
+++ b/server/users/admin.py
@@ -15,7 +15,7 @@ class RoleInline(admin.TabularInline):
@admin.register(SchoolClass)
class SchoolClassAdmin(admin.ModelAdmin):
- list_display = ('id', 'name')
+ list_display = ('name', 'code', 'is_deleted')
@admin.register(Role)
diff --git a/server/users/migrations/0010_schoolclass_code.py b/server/users/migrations/0010_schoolclass_code.py
new file mode 100644
index 00000000..b1b9557c
--- /dev/null
+++ b/server/users/migrations/0010_schoolclass_code.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.1.15 on 2020-02-11 10:14
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('users', '0009_auto_20191009_0905'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='schoolclass',
+ name='code',
+ field=models.CharField(blank=True, default=None, max_length=10, null=True, unique=True, verbose_name='Code zum Beitreten'),
+ ),
+ ]
diff --git a/server/users/models.py b/server/users/models.py
index 321c9f18..6477a46a 100644
--- a/server/users/models.py
+++ b/server/users/models.py
@@ -70,9 +70,14 @@ class SchoolClass(models.Model):
name = models.CharField(max_length=100, blank=False, null=False, unique=True)
is_deleted = models.BooleanField(blank=False, null=False, default=False)
users = models.ManyToManyField(get_user_model(), related_name='school_classes', blank=True)
+ code = models.CharField('Code zum Beitreten', blank=True, null=True, max_length=10, unique=True, default=None)
+
+ class Meta:
+ verbose_name = 'Schulklasse'
+ verbose_name_plural = 'Schulklassen'
def __str__(self):
- return 'SchoolClass {}-{}'.format(self.id, self.name)
+ return '{}'.format(self.name)
@classmethod
def generate_default_group_name(cls):
@@ -99,6 +104,11 @@ class SchoolClass(models.Model):
def get_teacher(self):
return self.users.filter(user_roles__role__key='teacher').first()
+ def save(self, *args, **kwargs):
+ if self.code == '': # '' can't be unique, so we null it
+ self.code = None
+ super().save(*args, **kwargs)
+
class Role(models.Model):
key = models.CharField(_('Key'), max_length=100, blank=False, null=False, unique=True)
@@ -165,4 +175,3 @@ class UserRole(models.Model):
class UserSetting(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, related_name='user_setting')
selected_class = models.ForeignKey(SchoolClass, blank=True, null=True, on_delete=models.CASCADE)
-
diff --git a/server/users/mutations.py b/server/users/mutations.py
index bbaae8c0..7a5c814b 100644
--- a/server/users/mutations.py
+++ b/server/users/mutations.py
@@ -9,6 +9,10 @@ from users.models import SchoolClass, UserSetting
from users.serializers import PasswordSerialzer, AvatarUrlSerializer
+class CodeNotFoundException(Exception):
+ pass
+
+
class FieldError(graphene.ObjectType):
code = graphene.String()
@@ -102,8 +106,28 @@ class UpdateSetting(relay.ClientIDMutation):
errors = graphene.List(UpdateError)
+class JoinClass(relay.ClientIDMutation):
+ class Input:
+ code = graphene.String(required=True)
+
+ success = graphene.Boolean()
+
+ @classmethod
+ def mutate_and_get_payload(cls, root, info, **kwargs):
+ user = info.context.user
+ code = kwargs.get('code')
+ try:
+ school_class = SchoolClass.objects.get(code__iexact=code)
+
+ school_class.users.add(user)
+
+ return cls(success=True)
+ except SchoolClass.DoesNotExist:
+ raise CodeNotFoundException('Code ist nicht gültig')
+
+
class ProfileMutations:
update_password = UpdatePassword.Field()
update_avatar = UpdateAvatar.Field()
update_setting = UpdateSetting.Field()
-
+ join_class = JoinClass.Field()