diff --git a/.gitignore b/.gitignore
index d347aa28bc0a0b7a489ac077f7b66e6c54324346..ffb3de3832416b870bf800ac19d59da9db49bf56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -108,3 +108,6 @@ ENV/
 environment.sh
 environment.ps1
 environment.bat
+
+#PyCharm
+.idea/
\ No newline at end of file
diff --git a/requirements/development.txt b/requirements/development.txt
index 23ec9249da5d8fb5961e4ee464cf3b766be8de7c..91118f565509bfebb4e633fd2f19702300e03c0c 100644
--- a/requirements/development.txt
+++ b/requirements/development.txt
@@ -14,7 +14,7 @@ django-extensions==1.9.9
 django-import-export==1.0.0
 django-social-authsch==0.1
 django-solo==1.1.3
-django==2.0.1
+django>=2.0.10
 djangorestframework==3.7.7
 et-xmlfile==1.0.1         # via openpyxl
 first==2.0.1              # via pip-tools
@@ -38,10 +38,10 @@ pyjwt==1.5.3              # via social-auth-core
 python-language-server==0.13.0
 python3-openid==3.1.0     # via social-auth-core
 pytz==2017.2              # via django
-pyyaml==3.12              # via tablib
+pyyaml>=4.2b1             # via tablib
 requests-oauthlib==0.8.0  # via social-auth-core
-requests==2.18.4          # via requests-oauthlib, social-auth-core
-rope==0.10.7              # via python-language-server
+requests>=2.20.0          # via requests-oauthlib, social-auth-core
+rope>=0.11.0              # via python-language-server
 six==1.10.0               # via django-extensions, pip-tools, pydocstyle, social-auth-app-django, social-auth-core
 snowballstemmer==1.2.1    # via pydocstyle
 social-auth-app-django==2.0.0  # via django-social-authsch
@@ -49,7 +49,7 @@ social-auth-core==1.5.0   # via django-social-authsch, social-auth-app-django
 tablib==0.12.1            # via django-import-export
 typing==3.6.4             # via django-extensions
 unicodecsv==0.14.1        # via tablib
-urllib3==1.22             # via requests
+urllib3>=1.23             # via requests
 xlrd==1.1.0               # via tablib
 xlwt==1.3.0               # via tablib
 yapf==0.20.1              # via python-language-server
diff --git a/src/account/auth_pipeline.py b/src/account/auth_pipeline.py
index b1918c536d09e7b1de94f3c63c249ed6eff9e5f2..34ca0180920054311bbad8835511cac3ae367065 100644
--- a/src/account/auth_pipeline.py
+++ b/src/account/auth_pipeline.py
@@ -1,4 +1,5 @@
 from django.core import exceptions
+from common import email
 
 from . import models
 
@@ -9,3 +10,5 @@ def create_profile(backend, user, response, *args, **kwargs):
             user.profile
         except exceptions.ObjectDoesNotExist:
             models.Profile.objects.create(user=user)
+            if user.email is not None:
+                email.registration(user)
diff --git a/src/account/migrations/0001_initial.py b/src/account/migrations/0001_initial.py
index 8c4b5267abb550ca5a08c3e50a2b3f0f72a54d57..8550f16222d06151f89e7dbf62fb44cc7233e753 100644
--- a/src/account/migrations/0001_initial.py
+++ b/src/account/migrations/0001_initial.py
@@ -1,6 +1,4 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-11 14:13
-from __future__ import unicode_literals
+# Generated by Django 2.0.1 on 2019-01-17 15:06
 
 from django.conf import settings
 from django.db import migrations, models
@@ -16,13 +14,37 @@ class Migration(migrations.Migration):
     ]
 
     operations = [
+        migrations.CreateModel(
+            name='Deadline',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('deadline', models.DateTimeField(null=True)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='GroupChoice',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('choice', models.CharField(choices=[('DT', 'DevTeam'), ('NET', 'NeTeam'), ('ST', 'SecurITeam'), ('SYS', 'SysAdmin'), ('HAT', 'Hallgatói Tudásbázis'), ('N', 'None')], default='N', max_length=10, unique=True)),
+            ],
+        ),
         migrations.CreateModel(
             name='Profile',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('join_date', models.DateField()),
-                ('pref_group', models.CharField(choices=[('DT', 'DevTeam'), ('NET', 'NeTeam'), ('ST', 'SecurITeam'), ('SYS', 'SysAdmin'), ('N', 'None')], default='None', max_length=10)),
-                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+                ('join_date', models.DateTimeField(auto_now_add=True)),
+                ('updated_at', models.DateTimeField(auto_now=True)),
+                ('motivation_about', models.TextField(blank=True, default='')),
+                ('motivation_profession', models.TextField(blank=True, default='')),
+                ('motivation_exercise', models.TextField(blank=True, default='')),
+                ('nick', models.CharField(blank=True, default='', max_length=15)),
+                ('signed', models.BooleanField(default=False)),
+                ('role', models.CharField(choices=[('Staff', 'Staff'), ('Applicant', 'Applicant'), ('Student', 'Student')], default='Applicant', max_length=10)),
+                ('groups', models.ManyToManyField(blank=True, related_name='profiles', to='account.GroupChoice')),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
             ],
         ),
     ]
diff --git a/src/account/migrations/0002_auto_20171114_2144.py b/src/account/migrations/0002_auto_20171114_2144.py
deleted file mode 100644
index fc76cef337448de84b568817d4fe13dd023c0f13..0000000000000000000000000000000000000000
--- a/src/account/migrations/0002_auto_20171114_2144.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-14 20:44
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='profile',
-            name='pref_group',
-            field=models.CharField(choices=[('DT', 'DevTeam'), ('NET', 'NeTeam'), ('ST', 'SecurITeam'), ('SYS', 'SysAdmin'), ('HAT', 'Hallgatói Tudásbázis'), ('N', 'None')], default='None', max_length=10),
-        ),
-    ]
diff --git a/src/account/migrations/0002_auto_20190122_1341.py b/src/account/migrations/0002_auto_20190122_1341.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9ee7b662af95a01f09815050e8650ab04603b30
--- /dev/null
+++ b/src/account/migrations/0002_auto_20190122_1341.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.1 on 2019-01-22 12:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('account', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='profile',
+            name='role',
+            field=models.CharField(choices=[('Staff', 'Staff'), ('Applicant', 'Applicant'), ('Student', 'Student'), ('Denied', 'Denied')], default='Applicant', max_length=10),
+        ),
+    ]
diff --git a/src/account/migrations/0003_profile_nick.py b/src/account/migrations/0003_profile_nick.py
deleted file mode 100644
index 7a3542787808c4e28493012327718f79731e9f3c..0000000000000000000000000000000000000000
--- a/src/account/migrations/0003_profile_nick.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-12-23 11:06
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0002_auto_20171114_2144'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='profile',
-            name='nick',
-            field=models.CharField(blank=True, max_length=15, null=True),
-        ),
-    ]
diff --git a/src/account/migrations/0004_profile_signed.py b/src/account/migrations/0004_profile_signed.py
deleted file mode 100644
index 424407361c1f04b2068daab365199eb7d5aa9e2b..0000000000000000000000000000000000000000
--- a/src/account/migrations/0004_profile_signed.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-12-23 11:10
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0003_profile_nick'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='profile',
-            name='signed',
-            field=models.BooleanField(default=False),
-        ),
-    ]
diff --git a/src/account/migrations/0005_auto_20171223_1455.py b/src/account/migrations/0005_auto_20171223_1455.py
deleted file mode 100644
index d5e5fb83b2f2deeaf85dba89cb35de502a01ea4e..0000000000000000000000000000000000000000
--- a/src/account/migrations/0005_auto_20171223_1455.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-12-23 13:55
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0004_profile_signed'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='profile',
-            name='join_date',
-            field=models.DateField(auto_now=True),
-        ),
-    ]
diff --git a/src/account/migrations/0006_auto_20180123_1713.py b/src/account/migrations/0006_auto_20180123_1713.py
deleted file mode 100644
index 035ce31da185ae28746fa3674f1670e1491e671f..0000000000000000000000000000000000000000
--- a/src/account/migrations/0006_auto_20180123_1713.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-23 16:13
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0005_auto_20171223_1455'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='GroupChoice',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('pref_group', models.CharField(choices=[('DT', 'DevTeam'), ('NET', 'NeTeam'), ('ST', 'SecurITeam'), ('SYS', 'SysAdmin'), ('HAT', 'Hallgatói Tudásbázis'), ('N', 'None')], default='None', max_length=10)),
-            ],
-        ),
-        migrations.RemoveField(
-            model_name='profile',
-            name='pref_group',
-        ),
-        migrations.AddField(
-            model_name='groupchoice',
-            name='profile',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='preferd_groups', to='account.Profile'),
-        ),
-        migrations.AlterUniqueTogether(
-            name='groupchoice',
-            unique_together=set([('pref_group', 'profile')]),
-        ),
-    ]
diff --git a/src/account/migrations/0007_auto_20180123_1723.py b/src/account/migrations/0007_auto_20180123_1723.py
deleted file mode 100644
index 27a4efe8c61f7cb19bb1f349a8c21b6e66f1e60e..0000000000000000000000000000000000000000
--- a/src/account/migrations/0007_auto_20180123_1723.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-23 16:23
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0006_auto_20180123_1713'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='groupchoice',
-            old_name='pref_group',
-            new_name='choice',
-        ),
-        migrations.AlterUniqueTogether(
-            name='groupchoice',
-            unique_together=set([('choice', 'profile')]),
-        ),
-    ]
diff --git a/src/account/migrations/0008_auto_20180124_1821.py b/src/account/migrations/0008_auto_20180124_1821.py
deleted file mode 100644
index fd3af443879f22344cc51f1334eec41e445948ad..0000000000000000000000000000000000000000
--- a/src/account/migrations/0008_auto_20180124_1821.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-24 17:21
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0007_auto_20180123_1723'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='profile',
-            name='user',
-            field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/src/account/migrations/0009_profile_motivation.py b/src/account/migrations/0009_profile_motivation.py
deleted file mode 100644
index c9d1e0a2e2aa16abd91adb4970ac860e5e991ffc..0000000000000000000000000000000000000000
--- a/src/account/migrations/0009_profile_motivation.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-24 17:43
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0008_auto_20180124_1821'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='profile',
-            name='motivation',
-            field=models.TextField(null=True),
-        ),
-    ]
diff --git a/src/account/migrations/0010_auto_20180124_1929.py b/src/account/migrations/0010_auto_20180124_1929.py
deleted file mode 100644
index 2a9b50d5d2e04d41c68b1aba0135774b1bd97bc3..0000000000000000000000000000000000000000
--- a/src/account/migrations/0010_auto_20180124_1929.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-24 18:29
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0009_profile_motivation'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='profile',
-            name='groups',
-            field=models.ManyToManyField(related_name='profiles', to='account.GroupChoice'),
-        ),
-        migrations.AlterField(
-            model_name='groupchoice',
-            name='choice',
-            field=models.CharField(choices=[('DT', 'DevTeam'), ('NET', 'NeTeam'), ('ST', 'SecurITeam'), ('SYS', 'SysAdmin'), ('HAT', 'Hallgatói Tudásbázis'), ('N', 'None')], default='N', max_length=10, unique=True),
-        ),
-        migrations.AlterUniqueTogether(
-            name='groupchoice',
-            unique_together=set([]),
-        ),
-        migrations.RemoveField(
-            model_name='groupchoice',
-            name='profile',
-        ),
-    ]
diff --git a/src/account/migrations/0011_deadline.py b/src/account/migrations/0011_deadline.py
deleted file mode 100644
index e88ed12d346eefbc0226895bd725d1bc49541928..0000000000000000000000000000000000000000
--- a/src/account/migrations/0011_deadline.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-25 18:42
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0010_auto_20180124_1929'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Deadline',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('deadline', models.DateField()),
-            ],
-            options={
-                'abstract': False,
-            },
-        ),
-    ]
diff --git a/src/account/migrations/0012_auto_20180125_1957.py b/src/account/migrations/0012_auto_20180125_1957.py
deleted file mode 100644
index 92845d1c75bcd23abaf68710d8c4bf93162fc7dd..0000000000000000000000000000000000000000
--- a/src/account/migrations/0012_auto_20180125_1957.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2018-01-25 18:57
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0011_deadline'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='deadline',
-            name='deadline',
-            field=models.DateField(null=True),
-        ),
-    ]
diff --git a/src/account/migrations/0013_auto_20180203_2007.py b/src/account/migrations/0013_auto_20180203_2007.py
deleted file mode 100644
index 8ac041e4d538e265f8f47fdaae0960ed54edd6b2..0000000000000000000000000000000000000000
--- a/src/account/migrations/0013_auto_20180203_2007.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-03 19:07
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0012_auto_20180125_1957'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='profile',
-            name='join_date',
-            field=models.DateTimeField(auto_now=True),
-        ),
-    ]
diff --git a/src/account/migrations/0014_auto_20180203_2010.py b/src/account/migrations/0014_auto_20180203_2010.py
deleted file mode 100644
index 0ad3c0554ec582ff41cc7536f02287c77f3fdb66..0000000000000000000000000000000000000000
--- a/src/account/migrations/0014_auto_20180203_2010.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-03 19:10
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0013_auto_20180203_2007'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='deadline',
-            name='deadline',
-            field=models.DateTimeField(null=True),
-        ),
-    ]
diff --git a/src/account/migrations/0015_auto_20180203_2014.py b/src/account/migrations/0015_auto_20180203_2014.py
deleted file mode 100644
index e823387e6830f772c4651f21c876c0ae0534f4cc..0000000000000000000000000000000000000000
--- a/src/account/migrations/0015_auto_20180203_2014.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-03 19:14
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0014_auto_20180203_2010'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='profile',
-            name='updated_at',
-            field=models.DateTimeField(auto_now=True),
-        ),
-        migrations.AlterField(
-            model_name='profile',
-            name='join_date',
-            field=models.DateTimeField(auto_now_add=True),
-        ),
-    ]
diff --git a/src/account/migrations/0016_auto_20180203_2022.py b/src/account/migrations/0016_auto_20180203_2022.py
deleted file mode 100644
index 86c2ae6dc33f0c16b7e8f1ea9489baf1e3d9cdd6..0000000000000000000000000000000000000000
--- a/src/account/migrations/0016_auto_20180203_2022.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-03 19:22
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0015_auto_20180203_2014'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='profile',
-            name='motivation',
-            field=models.TextField(blank=True, default=''),
-        ),
-        migrations.AlterField(
-            model_name='profile',
-            name='nick',
-            field=models.CharField(blank=True, default='', max_length=15),
-        ),
-    ]
diff --git a/src/account/migrations/0017_auto_20180205_2004.py b/src/account/migrations/0017_auto_20180205_2004.py
deleted file mode 100644
index d2137f9af9d55ca32fd4b79ba44f09ce56a8abd5..0000000000000000000000000000000000000000
--- a/src/account/migrations/0017_auto_20180205_2004.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-05 19:04
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0016_auto_20180203_2022'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='profile',
-            old_name='motivation',
-            new_name='motivation_about',
-        ),
-        migrations.AddField(
-            model_name='profile',
-            name='motivation_exercise',
-            field=models.TextField(blank=True, default=''),
-        ),
-        migrations.AddField(
-            model_name='profile',
-            name='motivation_profession',
-            field=models.TextField(blank=True, default=''),
-        ),
-    ]
diff --git a/src/account/models.py b/src/account/models.py
index 71b79f0c59102fe236def8d5459f6e3170e9f417..082a83c98de9be5d956af810734422ca9897c1c7 100644
--- a/src/account/models.py
+++ b/src/account/models.py
@@ -19,16 +19,27 @@ class GroupChoice(models.Model):
 
 
 class Profile(models.Model):
+    ROLES = (
+        ('Staff', 'Staff'),
+        ('Applicant', 'Applicant'),
+        ('Student', 'Student'),
+        ('Denied', 'Denied'),
+    )
     join_date = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True, editable=False)
-    user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)
+    user = models.OneToOneField(
+        User,
+        related_name='profile',
+        on_delete=models.CASCADE
+    )
     # TODO: Change the default to json render side
     motivation_about = models.TextField(blank=True, default='')
     motivation_profession = models.TextField(blank=True, default='')
     motivation_exercise = models.TextField(blank=True, default='')
     nick = models.CharField(max_length=15, blank=True, default='')
     signed = models.BooleanField(default=False, null=False)
-    groups = models.ManyToManyField(GroupChoice, related_name='profiles')
+    groups = models.ManyToManyField(GroupChoice, related_name='profiles', blank=True)
+    role = models.CharField(max_length=10, choices=ROLES, default='Applicant')
 
     @property
     def full_name(self):
diff --git a/src/account/serializers.py b/src/account/serializers.py
index 322a882ae63cca316144a20a811a7607d4e1b609..e38ad58cb689559fb56cb78a93e94631401e0ecc 100644
--- a/src/account/serializers.py
+++ b/src/account/serializers.py
@@ -1,5 +1,7 @@
 from rest_framework import serializers
 from account import models
+from common.middleware import CurrentUserMiddleware
+from common import email
 
 
 class ChoiceSerializer(serializers.ModelSerializer):
@@ -9,31 +11,53 @@ class ChoiceSerializer(serializers.ModelSerializer):
 
 
 class ProfileSerializer(serializers.ModelSerializer):
-    groups = serializers.SlugRelatedField(many=True, slug_field="choice", queryset=models.GroupChoice.objects.all())
+    groups = serializers.SlugRelatedField(many=True, slug_field='choice', queryset=models.GroupChoice.objects.all())
     updated_at = serializers.DateTimeField(read_only=True)
-    signed = serializers.BooleanField()
+    full_name = serializers.SerializerMethodField()
 
     class Meta:
         model = models.Profile
+        read_only_fields = ('id', 'join_date', 'updated_at', 'full_name', )
         fields = (
             'id',
             'join_date',
             'updated_at',
-            'user',
             'nick',
             'signed',
             'groups',
             'motivation_about',
             'motivation_profession',
             'motivation_exercise',
+            'full_name',
+            'role',
         )
 
-    def validate(self, data):
+    def validate_updated_at(self, value):
         deadline = models.Deadline.get_solo().deadline
-        if deadline is None:
-            return data
-
-        if data['signed'] is True and data['updated_at'] > deadline:
+        if deadline is not None and value > deadline:
             raise serializers.ValidationError("You cannot join after the deadline")
-
-        return data
+        return value
+
+    def validate_role(self, value):
+        modifier_role = CurrentUserMiddleware.get_current_user_profile().role
+        if value != modifier_role and modifier_role != "Staff":
+            raise serializers.ValidationError("You don't have permission change role")
+        return value
+
+    def validate_signed(self, value):
+        modifier = CurrentUserMiddleware.get_current_user_profile()
+        if value is False and modifier.role != "Staff":
+            raise serializers.ValidationError("You cannot join without signed")
+        return value
+
+    def update(self, instance, validated_data):
+        new_role = validated_data.get('role', instance.role)
+        if instance.role != new_role:
+            if new_role == 'Student':
+                email.admitted(instance.user)
+            if new_role == 'Denied':
+                email.denied(instance.user)
+        return super().update(instance, validated_data)
+
+    def get_full_name(self, obj):
+        return obj.full_name
diff --git a/src/account/views.py b/src/account/views.py
index fde64a8529b11c5561318014a5305b2ce5aef8df..c2ad4ec5b61ff4ae7545845c8b1b9149ec42bba5 100644
--- a/src/account/views.py
+++ b/src/account/views.py
@@ -2,6 +2,7 @@ from rest_framework import viewsets
 from rest_framework import permissions
 from rest_framework.response import Response
 from rest_framework.decorators import list_route
+from common.permissions import IsSafeOrPatch
 
 from . import models
 from . import serializers
@@ -9,13 +10,15 @@ from . import serializers
 
 class ProfileViewSet(viewsets.ModelViewSet):
     serializer_class = serializers.ProfileSerializer
-    permission_classes = (permissions.IsAuthenticated, )
+    permission_classes = (permissions.IsAuthenticated, IsSafeOrPatch)
 
     def get_queryset(self):
         user = self.request.user
-        if user.has_perm(permissions.IsAdminUser):
+        if user.profile.role == 'Staff':
+            role = self.request.query_params.get("role", None)
+            if role is not None:
+                return models.Profile.objects.filter(role=role)
             return models.Profile.objects.all()
-
         return models.Profile.objects.filter(pk=user.profile.id)
 
     @list_route(methods=['get'])
diff --git a/src/common/email.py b/src/common/email.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c4151ebb776e983001a6f4a7690b904e66148ad
--- /dev/null
+++ b/src/common/email.py
@@ -0,0 +1,32 @@
+from django.core.mail import send_mail
+
+
+def registration(email):
+    subject = "REGISTRATION TEST"
+    message = "Üdvözlünk a kszképzésen!"
+    send_mail(subject, message, 'noreply@devteam.sch.bme.hu', [email, ])
+
+
+def admitted(email):
+    subject = "ADMITTED TEST"
+    message = "Gratulálunk, te vagy a kiválasztott!!"
+    send_mail(subject, message, 'noreply@devteam.sch.bme.hu', [email, ])
+
+
+def denied(email):
+    subject = "DENIED TEST"
+    message = "Sajnos idén nem nyertél felvételt, próbáld meg legközelebb"
+    send_mail(subject, message, 'noreply@devteam.sch.bme.hu', [email, ])
+
+
+def new_homework(emails):
+    subject = "NEW HOMEWORK TEST"
+    message = "Szia!\nEgy új házi lett kiadva, ha tíz percen belül megoldod akkor fasza gyerek vagy," \
+              " ha nem életed végéig bánnifogod..."
+    send_mail(subject, message, 'noreply@devteam.sch.bme.hu', emails)
+
+
+def homework_corrected(email):
+    subject = "HOMEWORK CORRECTED TEST"
+    message = "Nagyszerű mentoraink kijavították házifeladatod, vajon most kaptál meglepit?!"
+    send_mail(subject, message, 'noreply@devteam.sch.bme.hu', [email, ])
diff --git a/src/common/emails/admitted.txt b/src/common/emails/admitted.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f719168dc8c3c64344246577ec5f2ec4d30a4645
--- /dev/null
+++ b/src/common/emails/admitted.txt
@@ -0,0 +1,6 @@
+Kedves %(name)s!
+
+Gratulálunk! Jelentkezésedet elfogadtuk! Innentől kezdve aktívan figyeld leveleidet, mert hamarosan megkapod az első képzésalkalmunkra szóló meghívódat!
+
+Üdvözlettel:
+A mentorok
\ No newline at end of file
diff --git a/src/common/emails/denied.txt b/src/common/emails/denied.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b085e7a886dee3306df419745fd40ccae023e2c7
--- /dev/null
+++ b/src/common/emails/denied.txt
@@ -0,0 +1,6 @@
+Kedves %(name)s!
+
+Sajnos - hely hiányában - idei képzésalkamunkon nem tudsz részt venni. Ne csüggedj, következő évben is indítunk ilyen programot, és ha addig is szorgalmasan tevékenykedsz, akkor biztosan be fogsz kerülni!
+
+Üdvözlettel:
+A mentorok
\ No newline at end of file
diff --git a/src/common/emails/homework_corrected.txt b/src/common/emails/homework_corrected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0128e57221ea25fd7dc69c1bff505cc817a08112
--- /dev/null
+++ b/src/common/emails/homework_corrected.txt
@@ -0,0 +1,7 @@
+Kedves %(name)s!
+
+A(z) %(title)s című házi feladatod státusza %(status)s lett.
+Az alábbi linken tudod megtekinteni a részleteket: %(link)s  .
+
+Üdvözlettel:
+A mentorok
\ No newline at end of file
diff --git a/src/common/emails/new_homework.txt b/src/common/emails/new_homework.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9a6618346dc6ca140dd69b0eaa3238676fcebe7f
--- /dev/null
+++ b/src/common/emails/new_homework.txt
@@ -0,0 +1,7 @@
+Kedves %(name)s!
+
+Új házi feladat került kiadásra, melyet az alábbi linken tudsz megtekinteni: %(link)s
+Határidő: %(deadline)s
+
+Sok sikert!
+A mentorok
\ No newline at end of file
diff --git a/src/common/emails/registration.txt b/src/common/emails/registration.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f9068e283264a6509bf534bc4c7e7a2c677cd432
--- /dev/null
+++ b/src/common/emails/registration.txt
@@ -0,0 +1,10 @@
+Kedves %(name)s!
+
+Örömmel vettük jelenkezésedet az idei KSZKépzés programunkba. Azonban ahhoz, hogy ezt el is tudjuk bírálni, még szükségünk van pár dologra tőled:
+	- ki kell töltened a profilodat,
+	- találsz pár feladatot is az oldalon, ezeket meg kell oldanod,
+	- gyere el Újoncdélutánunkra, erről majd még küldünk emailt.
+A feladatokhoz jó szórakozást kívánunk, és ne ijedj meg, ha valamit nem tudsz fejből, Google-t és egyéb segítséget természetesen használhatsz!
+
+Üdvözlettel:
+A mentorok
diff --git a/src/common/middleware.py b/src/common/middleware.py
new file mode 100644
index 0000000000000000000000000000000000000000..82f040c15458facfd7e6603558465825b2dc4c4a
--- /dev/null
+++ b/src/common/middleware.py
@@ -0,0 +1,19 @@
+from threading import local
+
+_profile = local()
+
+
+class CurrentUserMiddleware(object):
+
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def __call__(self, request):
+        _profile.value = request.user
+        return self.get_response(request)
+
+    def get_current_user_profile():
+        return _profile.value.profile
+
+    def get_current_user():
+        return _profile.value
diff --git a/src/common/permissions.py b/src/common/permissions.py
index 5aac2f078cb7cb6044024c7c29bb01559a8fed64..7d2384c7bf9186939272c68ac9d5f61dbfe58e72 100644
--- a/src/common/permissions.py
+++ b/src/common/permissions.py
@@ -3,27 +3,28 @@ from rest_framework.permissions import SAFE_METHODS
 
 
 class IsStaffOrReadOnly(BasePermission):
-    """
-    The request is authenticated as a staff, or is a read-only request.
-    """
-
     def has_permission(self, request, view):
-        return request.method in SAFE_METHODS or request.user and request.user.is_staff
+        return request.method in SAFE_METHODS or\
+               (request.user.is_authenticated and request.user.profile.role == 'Staff')
 
 
 class IsStaffOrReadOnlyForAuthenticated(BasePermission):
-    """
-    The request is authenticated as a staff, or is a read-only request for authenticated.
-    """
-
     def has_permission(self, request, view):
-        return request.user.is_staff or request.method in SAFE_METHODS and request.user.is_authenticated
+        return request.user.is_authenticated and\
+               (request.method in SAFE_METHODS or request.user.profile.role == 'Staff')
 
 
 class IsStaffUser(BasePermission):
-    """
-    The request is authenticated as a staff
-    """
+    def has_permission(self, request, view):
+        return request.user.is_authenticated and request.user.profile.role == 'Staff'
+
+
+class IsSafeOrPatch(BasePermission):
+    def has_permission(self, request, view):
+        return request.method in SAFE_METHODS or request.method == 'PATCH'
+
 
+class IsStaffOrStudent(BasePermission):
     def has_permission(self, request, view):
-        return request.user.is_staff
+        return request.user.is_authenticated and\
+               (request.user.profile.role == 'Staff' or request.user.profile.role == 'Student')
diff --git a/src/document/migrations/0001_initial.py b/src/document/migrations/0001_initial.py
index 1982261b5587cc0c2c527977925709598452aeac..a6c028301e73f9984456b29c47277a90f2ca37ed 100644
--- a/src/document/migrations/0001_initial.py
+++ b/src/document/migrations/0001_initial.py
@@ -1,5 +1,7 @@
-# Generated by Django 2.0.1 on 2018-05-28 15:21
+# Generated by Django 2.0.1 on 2019-01-17 15:06
 
+import common.validators
+import django.core.validators
 from django.db import migrations, models
 import django.db.models.deletion
 
@@ -9,7 +11,8 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ('account', '0017_auto_20180205_2004'),
+        ('homework', '0001_initial'),
+        ('account', '0001_initial'),
     ]
 
     operations = [
@@ -19,8 +22,9 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('uploaded_at', models.DateTimeField(auto_now_add=True)),
                 ('name', models.CharField(max_length=150)),
-                ('description', models.TextField()),
-                ('file', models.FileField(upload_to='')),
+                ('description', models.TextField(blank=True, default='')),
+                ('file', models.FileField(upload_to='', validators=[django.core.validators.FileExtensionValidator(['png', 'jpeg', 'jpg', 'zip']), common.validators.FileSizeValidator(size_limit=52428800)])),
+                ('solution', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='files', to='homework.Solution')),
                 ('uploaded_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='account.Profile')),
             ],
         ),
diff --git a/src/document/migrations/0002_auto_20190121_1332.py b/src/document/migrations/0002_auto_20190121_1332.py
new file mode 100644
index 0000000000000000000000000000000000000000..5cf755b92259e186c711bd5be422791f17294858
--- /dev/null
+++ b/src/document/migrations/0002_auto_20190121_1332.py
@@ -0,0 +1,20 @@
+# Generated by Django 2.0.1 on 2019-01-21 12:32
+
+import common.validators
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('document', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='document',
+            name='file',
+            field=models.FileField(blank=True, default='', upload_to='', validators=[django.core.validators.FileExtensionValidator(['png', 'jpeg', 'jpg', 'zip']), common.validators.FileSizeValidator(size_limit=52428800)]),
+        ),
+    ]
diff --git a/src/document/migrations/0003_auto_20190121_1335.py b/src/document/migrations/0003_auto_20190121_1335.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa4d1c22ae825d615e093126a69d4a0a76132ad0
--- /dev/null
+++ b/src/document/migrations/0003_auto_20190121_1335.py
@@ -0,0 +1,20 @@
+# Generated by Django 2.0.1 on 2019-01-21 12:35
+
+import common.validators
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('document', '0002_auto_20190121_1332'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='document',
+            name='file',
+            field=models.FileField(blank=True, upload_to='', validators=[django.core.validators.FileExtensionValidator(['png', 'jpeg', 'jpg', 'zip']), common.validators.FileSizeValidator(size_limit=52428800)]),
+        ),
+    ]
diff --git a/src/document/migrations/0004_auto_20190123_1812.py b/src/document/migrations/0004_auto_20190123_1812.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eb42c6664d6d3fe22abb6ec091b7ea965643db5
--- /dev/null
+++ b/src/document/migrations/0004_auto_20190123_1812.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.0.1 on 2019-01-23 17:12
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('document', '0003_auto_20190121_1335'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='document',
+            name='solution',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='files', to='homework.Solution'),
+        ),
+    ]
diff --git a/src/document/migrations/0005_auto_20190129_1438.py b/src/document/migrations/0005_auto_20190129_1438.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c207c4a9776a2776d3d1b5da9d0473d2a283175
--- /dev/null
+++ b/src/document/migrations/0005_auto_20190129_1438.py
@@ -0,0 +1,25 @@
+# Generated by Django 2.0.1 on 2019-01-29 13:38
+
+import common.validators
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('document', '0004_auto_20190123_1812'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='document',
+            name='file',
+            field=models.FileField(blank=True, null=True, upload_to='', validators=[django.core.validators.FileExtensionValidator(['png', 'jpeg', 'jpg', 'zip']), common.validators.FileSizeValidator(size_limit=52428800)]),
+        ),
+        migrations.AlterField(
+            model_name='document',
+            name='name',
+            field=models.CharField(blank=True, default='', max_length=150),
+        ),
+    ]
diff --git a/src/document/models.py b/src/document/models.py
index e2c30e36742be70a2cb4b4f9b429dcde73eab4c5..a9d72a22f77c1d87841b0e580c3747a57b73961e 100644
--- a/src/document/models.py
+++ b/src/document/models.py
@@ -1,14 +1,30 @@
 from django.db import models
+from django.core import validators
 
 from account.models import Profile
+from homework.models import Solution
+from common.validators import FileSizeValidator
 
 
 class Document(models.Model):
     uploaded_by = models.ForeignKey(Profile, on_delete=models.DO_NOTHING)
     uploaded_at = models.DateTimeField(auto_now_add=True, editable=False)
-    name = models.CharField(max_length=150)
-    description = models.TextField()
-    file = models.FileField()
+    name = models.CharField(max_length=150, blank=True, default='')
+    description = models.TextField(blank=True, default='')
+    file = models.FileField(
+        validators=[
+            validators.FileExtensionValidator([
+                'png',
+                'jpeg',
+                'jpg',
+                'zip',
+            ]),
+            FileSizeValidator(size_limit=52428800),  # 52428800 - 50MiB
+        ],
+        blank=True,
+        null=True
+    )
+    solution = models.ForeignKey(Solution, related_name='files', on_delete=models.CASCADE)
 
     def __str__(self):
         return self.name
diff --git a/src/document/serializers.py b/src/document/serializers.py
index 47e0e1cd73d13b5e0bc22bd79aba3535a9e8002e..f7ad1c31123d1a5e159c07187174d087d5daaf6e 100644
--- a/src/document/serializers.py
+++ b/src/document/serializers.py
@@ -1,13 +1,28 @@
 from rest_framework import serializers
-
 from common.serializers import CurrentUserProfileDefault
 from . import models
+from common.middleware import CurrentUserMiddleware
+
+_max_count = 1
 
 
 class DocumentSerializer(serializers.ModelSerializer):
-    uploaded_at = serializers.DateTimeField(read_only=True)
     uploaded_by = serializers.HiddenField(default=CurrentUserProfileDefault())
+    uploaded_by_name = serializers.SerializerMethodField()
 
     class Meta:
         model = models.Document
-        fields = ('uploaded_by', 'uploaded_at', 'name', 'description', 'file')
+        fields = ('uploaded_by', 'uploaded_at', 'name', 'description', 'file', 'uploaded_by_name', 'solution', )
+
+    def get_uploaded_by_name(self, obj):
+        return obj.uploaded_by.full_name
+
+    def validate_solution(self, value):
+        profile = CurrentUserMiddleware.get_current_user_profile()
+        if value not in profile.solution.all():
+            raise serializers.ValidationError('You dont have permission!')
+        count = models.Document.objects.filter(uploaded_by=profile, solution=value).count()
+        if count >= _max_count:
+            raise serializers.ValidationError('You cant upload more than ' + str(_max_count) +
+                                              ' document to one solution!')
+        return value
diff --git a/src/document/views.py b/src/document/views.py
index 70e78a074604bb240aca2930d9325ac31f60d8bc..00f53216570810c84504625b4c1f2abdf2896f2d 100644
--- a/src/document/views.py
+++ b/src/document/views.py
@@ -1,11 +1,38 @@
 from rest_framework import viewsets
-
 from common import permissions
 from . import models
 from . import serializers
+from rest_framework.parsers import JSONParser, MultiPartParser
 
 
 class DocumentViewSet(viewsets.ModelViewSet):
-    queryset = models.Document.objects.all()
     serializer_class = serializers.DocumentSerializer
-    permission_classes = (permissions.IsStaffOrReadOnly, )
+    permission_classes = (permissions.IsStaffOrStudent, )
+    parser_classes = (JSONParser, MultiPartParser)
+
+    def get_queryset(self):
+        user = self.request.user
+        if user.profile.role == 'Staff':
+            queryset = self.staff_queryset()
+        else:
+            queryset = self.student_queryset(user.profile)
+        return queryset
+
+    def staff_queryset(self):
+        queryset = models.Document.objects.all()
+        profile_id = self.request.query_params.get('profileID', None)
+        solution_id = self.request.query_params.get('solutionID', None)
+        if profile_id is not None and solution_id is not None:
+            return queryset.filter(uploaded_by=profile_id, solution=solution_id)
+        if profile_id is not None:
+            return queryset.filter(uploaded_by=profile_id)
+        if solution_id is not None:
+            return queryset.filter(solution=solution_id)
+        return queryset
+
+    def student_queryset(self, profile):
+        queryset = models.Document.objects.filter(uploaded_by=profile)
+        solution_id = self.request.query_params.get('solutionID', None)
+        if solution_id is not None:
+            return queryset.filter(solution=solution_id)
+        return queryset
diff --git a/src/homework/migrations/0001_initial.py b/src/homework/migrations/0001_initial.py
old mode 100755
new mode 100644
index b92796bcb9ea8806d6a15480b2d9ccfe95609d1e..13125342ce3865c45e5e8304a5353c3b5837e371
--- a/src/homework/migrations/0001_initial.py
+++ b/src/homework/migrations/0001_initial.py
@@ -1,7 +1,6 @@
-# Generated by Django 2.0.1 on 2018-04-05 08:33
+# Generated by Django 2.0.1 on 2019-01-17 15:06
 
-import common.validators
-import django.core.validators
+import common.middleware
 from django.db import migrations, models
 import django.db.models.deletion
 
@@ -11,7 +10,7 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ('account', '0017_auto_20180205_2004'),
+        ('account', '0001_initial'),
     ]
 
     operations = [
@@ -21,10 +20,10 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('created_at', models.DateTimeField(auto_now_add=True)),
                 ('updated_at', models.DateTimeField(auto_now=True)),
-                ('ready', models.BooleanField(default=False)),
-                ('accepted', models.BooleanField(default=False)),
-                ('files', models.FileField(upload_to='', validators=[django.core.validators.FileExtensionValidator(['png', 'jpeg', 'jpg', 'zip']), common.validators.FileSizeValidator(size_limit=52428800)])),
-                ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_solution', to='account.Profile')),
+                ('note', models.TextField(blank=True, default='')),
+                ('accepted', models.BooleanField()),
+                ('corrected', models.BooleanField()),
+                ('created_by', models.ForeignKey(default=common.middleware.CurrentUserMiddleware.get_current_user_profile, on_delete=django.db.models.deletion.DO_NOTHING, related_name='solution', to='account.Profile')),
             ],
         ),
         migrations.CreateModel(
@@ -36,12 +35,12 @@ class Migration(migrations.Migration):
                 ('title', models.CharField(max_length=150)),
                 ('text', models.TextField()),
                 ('deadline', models.DateTimeField()),
-                ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='account.Profile')),
+                ('created_by', models.ForeignKey(default=common.middleware.CurrentUserMiddleware.get_current_user_profile, on_delete=django.db.models.deletion.DO_NOTHING, related_name='tasks', to='account.Profile')),
             ],
         ),
         migrations.AddField(
             model_name='solution',
             name='task',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='task_solution', to='homework.Task'),
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='solutions', to='homework.Task'),
         ),
     ]
diff --git a/src/homework/migrations/0002_auto_20180411_0047.py b/src/homework/migrations/0002_auto_20190121_2124.py
similarity index 60%
rename from src/homework/migrations/0002_auto_20180411_0047.py
rename to src/homework/migrations/0002_auto_20190121_2124.py
index cafe25c08698315b551c3d0d0eaa5430eb0ef5d5..3abf5a83e87d8424a882e3c92f55af2f1478d3ee 100644
--- a/src/homework/migrations/0002_auto_20180411_0047.py
+++ b/src/homework/migrations/0002_auto_20190121_2124.py
@@ -1,4 +1,4 @@
-# Generated by Django 2.0.1 on 2018-04-10 22:47
+# Generated by Django 2.0.1 on 2019-01-21 20:24
 
 from django.db import migrations, models
 
@@ -10,13 +10,14 @@ class Migration(migrations.Migration):
     ]
 
     operations = [
-        migrations.RemoveField(
+        migrations.AlterField(
             model_name='solution',
-            name='ready',
+            name='accepted',
+            field=models.BooleanField(default=False),
         ),
         migrations.AlterField(
             model_name='solution',
-            name='accepted',
-            field=models.BooleanField(),
+            name='corrected',
+            field=models.BooleanField(default=False),
         ),
     ]
diff --git a/src/homework/models.py b/src/homework/models.py
index a62333df3d2905702b87c01d835bf099e47b49fd..4ecb6e958c9a9349ca39a26d75c57463f030c1fc 100755
--- a/src/homework/models.py
+++ b/src/homework/models.py
@@ -1,40 +1,38 @@
 from django.db import models
-from django.core import validators
-
-from common.validators import FileSizeValidator
+from common.middleware import CurrentUserMiddleware
 from account.models import Profile
 
 
 class Task(models.Model):
-    created_by = models.ForeignKey(Profile, on_delete=models.DO_NOTHING)
+    created_by = models.ForeignKey(
+        Profile,
+        on_delete=models.DO_NOTHING,
+        related_name='tasks',
+        default=CurrentUserMiddleware.get_current_user_profile,
+    )
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True, editable=False)
     title = models.CharField(max_length=150)
     text = models.TextField()
     deadline = models.DateTimeField()
-    # dokumentum kezeles
 
     def __str__(self):
         return self.title
 
 
 class Solution(models.Model):
-    task = models.ForeignKey(Task, related_name='task_solution', on_delete=models.CASCADE)
-    created_by = models.ForeignKey(Profile, related_name='student_solution', on_delete=models.CASCADE)
+    task = models.ForeignKey(Task, related_name='solutions', on_delete=models.CASCADE)
+    created_by = models.ForeignKey(
+        Profile,
+        related_name='solution',
+        on_delete=models.DO_NOTHING,
+        default=CurrentUserMiddleware.get_current_user_profile
+    )
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True, editable=False)
-    accepted = models.BooleanField()
-    files = models.FileField(
-        validators=[
-            validators.FileExtensionValidator([
-                'png',
-                'jpeg',
-                'jpg',
-                'zip',
-            ]),
-            FileSizeValidator(size_limit=52428800),  # 52428800 - 50MiB
-        ],
-    )
+    note = models.TextField(blank=True, default='')
+    accepted = models.BooleanField(blank=True, default=False)
+    corrected = models.BooleanField(blank=True, default=False)
 
     def __str__(self):
         return "[{}] {}".format(self.created_at, self.created_by.full_name)
diff --git a/src/homework/serializers.py b/src/homework/serializers.py
index f7d7c81b2d31467a445b1d9a547808b85c9bc6f4..c6e4fde20ad2289c20456d7e5a7909bc47c87f2b 100755
--- a/src/homework/serializers.py
+++ b/src/homework/serializers.py
@@ -1,13 +1,12 @@
 from rest_framework import serializers
 from django.utils import timezone
-
-from common.serializers import CurrentUserProfileDefault
+from account.models import Profile
 from . import models
+from common import email
+from common.middleware import CurrentUserMiddleware
 
 
 class TaskSerializer(serializers.ModelSerializer):
-    created_by = serializers.HiddenField(default=CurrentUserProfileDefault())
-
     class Meta:
         model = models.Task
         read_only_fields = ('created_by', 'created_at', 'updated_at')
@@ -18,22 +17,63 @@ class TaskSerializer(serializers.ModelSerializer):
             raise serializers.ValidationError('Please, enter appropriate deadline.')
         return data
 
+    def create(self, validated_data):
+        profiles = Profile.objects.filter(role="Student").exclude(user__email='')
+        for profile in profiles:
+            email.new_homework(profile.user, validated_data.get('deadline'))
+        return self.Meta.model.objects.create(**validated_data)
 
-class SolutionSerializer(serializers.ModelSerializer):
-    created_at = serializers.DateTimeField(read_only=True)
-    updated_at = serializers.DateTimeField(read_only=True)
-    created_by = serializers.HiddenField(default=CurrentUserProfileDefault())
 
+class SolutionSerializer(serializers.ModelSerializer):
     class Meta:
         model = models.Solution
-        read_only_fields = ('created_by', 'created_at', 'updated_at', 'ready')
-        fields = ('task', 'created_at', 'updated_at', 'accepted', 'files', 'created_by')
+        read_only_fields = ('created_by', 'created_at', 'updated_at', 'ready', 'files')
+        fields = (
+            'id',
+            'task',
+            'created_at',
+            'updated_at',
+            'accepted',
+            'files',
+            'created_by',
+            'corrected',
+            'note',
+        )
 
-    def validate(self, data):
-        if timezone.now() > data['task'].deadline:
+    def validate_task(self, value):
+        if timezone.now() > value.deadline:
             raise serializers.ValidationError('You late.')
-        return data
+        return value
+
+    def validate_accepted(self, value):
+        profile = CurrentUserMiddleware.get_current_user_profile()
+        if profile.role != 'Staff' and value:
+            raise serializers.ValidationError("You don't have permission to modify accepted!")
+        return value
+
+    def validate_corrected(self, value):
+        profile = CurrentUserMiddleware.get_current_user_profile()
+        if profile.role != 'Staff' and value:
+            raise serializers.ValidationError("You don't have permission to modify corrected!")
+        return value
+
+    def validate_note(self, value):
+        profile = CurrentUserMiddleware.get_current_user_profile()
+        if profile.role != 'Staff' and value != '':
+            raise serializers.ValidationError("You don't have permission to create note!")
+        return value
+
+    def update(self, instance, validated_data):
+        if instance.corrected == False and validated_data.get('corrected', instance.corrected) == True:
+            email.homework_corrected(
+                instance.created_by.user,
+                instance.task.title,
+                validated_data.get('accepted', instance.accepted)
+            )
+        return super().update(instance, validated_data)
 
     def create(self, validated_data):
-        validated_data['accepted'] = False
-        return self.Meta.model.objects.create(**validated_data)
+        profile = CurrentUserMiddleware.get_current_user_profile()
+        models.Solution.objects.filter(created_by=profile, task=validated_data['task']).delete()
+        return super().create(validated_data)
+
diff --git a/src/homework/views.py b/src/homework/views.py
index 41f1638a5484fe74cf9f471ea353da89cb9ee7c8..9a9d88c415e5b6182a6707bdcfb32db355f7d05a 100755
--- a/src/homework/views.py
+++ b/src/homework/views.py
@@ -1,27 +1,26 @@
 from rest_framework import viewsets
 
-from common import permissions
-from rest_framework.permissions import IsAuthenticated
 from . import serializers
 from . import models
+from common import permissions
 
 
 class TasksViewSet(viewsets.ModelViewSet):
     serializer_class = serializers.TaskSerializer
     queryset = models.Task.objects.all()
-    permission_classes = (permissions.IsStaffOrReadOnlyForAuthenticated, )
+    permission_classes = (permissions.IsStaffOrReadOnlyForAuthenticated, permissions.IsStaffOrStudent, )
 
 
 class SolutionsViewSet(viewsets.ModelViewSet):
     serializer_class = serializers.SolutionSerializer
-    permission_classes = (IsAuthenticated, )
+    permission_classes = (permissions.IsStaffOrStudent, )
 
     def get_queryset(self):
         user = self.request.user
-        queryset = models.Solution.objects.filter(created_by=user)
-        if user.has_perm(permissions.IsStaffUser):
+        queryset = models.Solution.objects.filter(created_by=user.profile)
+        if user.profile.role == 'Staff':
             queryset = models.Solution.objects.all()
-            user_id = self.request.query_params.get('userID', None)
-            if user_id is not None:
-                queryset = queryset.filter(created_by=user_id)
+            profile_id = self.request.query_params.get('profileID', None)
+            if profile_id is not None:
+                queryset = queryset.filter(created_by=profile_id)
         return queryset
diff --git a/src/kszkepzes/settings/base.py b/src/kszkepzes/settings/base.py
index dd73603a60b94e23ef0f7892f885ff713c32de67..b831a0ec690d3c2ff85248e79972ab90f1b260f2 100644
--- a/src/kszkepzes/settings/base.py
+++ b/src/kszkepzes/settings/base.py
@@ -58,6 +58,7 @@ MIDDLEWARE = [
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'common.middleware.CurrentUserMiddleware',
 ]
 
 ROOT_URLCONF = 'kszkepzes.urls'
diff --git a/src/kszkepzes/settings/local.py b/src/kszkepzes/settings/local.py
index 9b5ed21c9e3f65438f966db7f1913bc34b7ffa97..53eb49a1bd60f3f66631867f420381d3070b85a1 100644
--- a/src/kszkepzes/settings/local.py
+++ b/src/kszkepzes/settings/local.py
@@ -1 +1,9 @@
 from .base import *
+
+SESSION_COOKIE_SECURE=False
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'smtp.gmail.com'
+EMAIL_USE_TLS = True
+EMAIL_PORT = 587
+EMAIL_HOST_USER = os.getenv('EMAIL')
+EMAIL_HOST_PASSWORD = os.getenv('EMAIL_PASSWORD')
diff --git a/src/kszkepzes/settings/production.py b/src/kszkepzes/settings/production.py
index ebf105027c4fcc9bd936482fd349dc1d7f526323..cbd865978fa81069cdf9c99a29f8360375bb6fd2 100644
--- a/src/kszkepzes/settings/production.py
+++ b/src/kszkepzes/settings/production.py
@@ -15,7 +15,6 @@ DATABASES = {
     }
 }
 
-
 REST_FRAMEWORK = {
     'DEFAULT_RENDERER_CLASSES': (
         'rest_framework.renderers.JSONRenderer',
@@ -26,3 +25,6 @@ REST_FRAMEWORK = {
 }
 
 STATIC_ROOT = os.path.join(BASE_DIR, 'static_collected')
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+EMAIL_HOST = 'mail.sch.bme.hu'
+EMAIL_PORT = 25
diff --git a/src/news/migrations/0001_initial.py b/src/news/migrations/0001_initial.py
index 3e3bf0cd6b30767f0b17a436e2c1eede7b9061a7..a8f40ce6d982860cc36fa0d335132bf70b770d9e 100644
--- a/src/news/migrations/0001_initial.py
+++ b/src/news/migrations/0001_initial.py
@@ -1,7 +1,6 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-28 19:55
-from __future__ import unicode_literals
+# Generated by Django 2.0.1 on 2019-01-17 15:06
 
+import common.middleware
 from django.db import migrations, models
 import django.db.models.deletion
 
@@ -11,7 +10,7 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ('account', '0002_auto_20171114_2144'),
+        ('account', '0001_initial'),
     ]
 
     operations = [
@@ -21,8 +20,10 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('title', models.CharField(max_length=200)),
                 ('text', models.TextField()),
-                ('date', models.DateTimeField()),
-                ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author', to='account.Profile')),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+                ('updated_at', models.DateTimeField(auto_now=True)),
+                ('author', models.ForeignKey(default=common.middleware.CurrentUserMiddleware.get_current_user_profile, on_delete=django.db.models.deletion.DO_NOTHING, related_name='author', to='account.Profile')),
+                ('updated_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='updater', to='account.Profile')),
             ],
         ),
     ]
diff --git a/src/news/migrations/0002_auto_20171220_1852.py b/src/news/migrations/0002_auto_20171220_1852.py
deleted file mode 100644
index 82274a5e164ffb466661b8358d3839ee44f9f78a..0000000000000000000000000000000000000000
--- a/src/news/migrations/0002_auto_20171220_1852.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-12-20 17:52
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('news', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='article',
-            name='date',
-            field=models.DateTimeField(auto_now_add=True),
-        ),
-    ]
diff --git a/src/news/migrations/0003_auto_20180126_0135.py b/src/news/migrations/0003_auto_20180126_0135.py
deleted file mode 100644
index 744aef9118bc2963df22d62ea5af9c8230adf26c..0000000000000000000000000000000000000000
--- a/src/news/migrations/0003_auto_20180126_0135.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by Django 2.0.1 on 2018-01-26 00:35
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('news', '0002_auto_20171220_1852'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='article',
-            old_name='date',
-            new_name='created_at',
-        ),
-        migrations.AddField(
-            model_name='article',
-            name='updated_at',
-            field=models.DateTimeField(auto_now=True),
-        ),
-        migrations.AlterField(
-            model_name='article',
-            name='author',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='author', to='account.Profile'),
-        ),
-    ]
diff --git a/src/news/models.py b/src/news/models.py
index 0714bf16b3c1e24f9d9da0b476e5f8bdb04f428d..c216221410bc8e9f04f3b76c90265ed94191b9d6 100644
--- a/src/news/models.py
+++ b/src/news/models.py
@@ -1,13 +1,24 @@
 from django.db import models
 from account.models import Profile
+from common.middleware import CurrentUserMiddleware
 
 
 class Article(models.Model):
-    author = models.ForeignKey(Profile, related_name="author", on_delete=models.DO_NOTHING)
+    author = models.ForeignKey(
+        Profile,
+        related_name="author",
+        on_delete=models.DO_NOTHING,
+        default=CurrentUserMiddleware.get_current_user_profile
+    )
     title = models.CharField(null=False, max_length=200)
     text = models.TextField()
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True, editable=False)
+    updated_by = models.ForeignKey(
+        Profile,
+        related_name="updater",
+        on_delete=models.DO_NOTHING
+    )
 
     def __str__(self):
         return self.title
diff --git a/src/news/serializers.py b/src/news/serializers.py
index a4123d8f897dbc3dbf9689998d6c61c065bb1fae..514c63bd416184b25ca57672ed24a276c72a382d 100644
--- a/src/news/serializers.py
+++ b/src/news/serializers.py
@@ -1,13 +1,20 @@
 from news.models import Article
 from rest_framework import serializers
+from common.serializers import CurrentUserProfileDefault
 
 
-class ArticleListSerializer(serializers.ModelSerializer):
-    author_name = serializers.SerializerMethodField()
+class ArticleSerializer(serializers.ModelSerializer):
+    updated_by = serializers.HiddenField(default=CurrentUserProfileDefault())
+    last_update_by = serializers.SerializerMethodField()
+    author = serializers.SerializerMethodField()
 
     class Meta:
         model = Article
-        fields = serializers.ALL_FIELDS
+        read_only_fields = ('author', 'created_at', 'updated_at', 'updated_by')
+        fields = '__all__'
 
-    def get_author_name(self, obj):
-        return obj.author.user.get_full_name()
+    def get_last_update_by(self, obj):
+        return obj.updated_by.full_name
+
+    def get_author(self, obj):
+        return obj.author.full_name
diff --git a/src/news/urls.py b/src/news/urls.py
index d71ed82e9e76d7ee61aa6e91c0f8f868a28b1280..9536ff9f010db9f900d00e84c7d18555dafde6c0 100644
--- a/src/news/urls.py
+++ b/src/news/urls.py
@@ -3,6 +3,6 @@ from news import views
 
 
 router = routers.DefaultRouter()
-router.register(r'news', views.NewsViewSet)
+router.register(r'news', views.NewsViewSet, base_name='news')
 
 urlpatterns = router.urls
diff --git a/src/news/views.py b/src/news/views.py
index 7267fd827e731895a3ab25002b6f1fb5b9c1a581..764d0a93c4aeb7f6ff4a493c6db4aed6f24a6c5c 100644
--- a/src/news/views.py
+++ b/src/news/views.py
@@ -1,10 +1,10 @@
 from common.permissions import IsStaffOrReadOnly
 from rest_framework import viewsets
 from news.models import Article
-from news.serializers import ArticleListSerializer
+from news.serializers import ArticleSerializer
 
 
 class NewsViewSet(viewsets.ModelViewSet):
-    serializer_class = ArticleListSerializer
-    permission_classes = [IsStaffOrReadOnly]
+    serializer_class = ArticleSerializer
+    permission_classes = (IsStaffOrReadOnly,)
     queryset = Article.objects.all().order_by('-created_at')
diff --git a/src/stats/admin.py b/src/stats/admin.py
index 050ebd1b03b37e58ab3bec15a2624270a5e37082..fb841605335f9cd12025ed91abe5361dc7f806f5 100644
--- a/src/stats/admin.py
+++ b/src/stats/admin.py
@@ -15,7 +15,7 @@ class EventAdmin(ExportMixin, admin.ModelAdmin):
 
 @admin.register(models.Note)
 class NoteAdmin(ExportMixin, admin.ModelAdmin):
-    list_display = ('user', 'note', 'event', 'created_by', 'created_at', 'updated_at')
-    list_filter = ('user', 'created_by', 'event')
+    list_display = ('profile', 'note', 'event', 'created_by', 'created_at', 'updated_at')
+    list_filter = ('profile', 'created_by', 'event')
     search_fields = ('event__name', 'note')
     resource_class = resources.NoteResource
diff --git a/src/stats/migrations/0001_initial.py b/src/stats/migrations/0001_initial.py
index 91e32fff21f7f6489284d3c0ab02d8b58949f049..b6e989e8f6f784a782bf6ef238584160ca141329 100644
--- a/src/stats/migrations/0001_initial.py
+++ b/src/stats/migrations/0001_initial.py
@@ -1,8 +1,8 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-11 14:14
-from __future__ import unicode_literals
+# Generated by Django 2.0.1 on 2019-01-17 15:06
 
+import common.middleware
 from django.db import migrations, models
+import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
@@ -15,12 +15,27 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.CreateModel(
-            name='KszkEvent',
+            name='Event',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('date', models.DateField()),
-                ('num_of_pers', models.IntegerField()),
-                ('visitors', models.ManyToManyField(related_name='visitor', to='account.Profile')),
+                ('name', models.CharField(max_length=255)),
+                ('date', models.DateTimeField()),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+                ('updated_at', models.DateTimeField(auto_now=True)),
+                ('created_by', models.ForeignKey(default=common.middleware.CurrentUserMiddleware.get_current_user_profile, on_delete=django.db.models.deletion.DO_NOTHING, related_name='created_event', to='account.Profile')),
+                ('visitors', models.ManyToManyField(blank=True, related_name='events', to='account.Profile')),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Note',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('note', models.TextField()),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+                ('updated_at', models.DateTimeField(auto_now=True)),
+                ('created_by', models.ForeignKey(default=common.middleware.CurrentUserMiddleware.get_current_user_profile, on_delete=django.db.models.deletion.DO_NOTHING, related_name='created_notes', to='account.Profile')),
+                ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='stats.Event')),
+                ('profile', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='account.Profile')),
             ],
         ),
     ]
diff --git a/src/stats/migrations/0002_auto_20171111_1646.py b/src/stats/migrations/0002_auto_20171111_1646.py
deleted file mode 100644
index 7a51b6e003a0e51bf2130254034f7a8bfda83b8b..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0002_auto_20171111_1646.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-11 15:46
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('stats', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='kszkevent',
-            name='num_of_pers',
-            field=models.IntegerField(editable=False),
-        ),
-    ]
diff --git a/src/stats/migrations/0002_event_description.py b/src/stats/migrations/0002_event_description.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7d056636e1bc6c5ad18457d09a92bc56ba30927
--- /dev/null
+++ b/src/stats/migrations/0002_event_description.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.1 on 2019-01-19 14:34
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('stats', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='event',
+            name='description',
+            field=models.TextField(blank=True, default=''),
+        ),
+    ]
diff --git a/src/stats/migrations/0003_auto_20171114_2026.py b/src/stats/migrations/0003_auto_20171114_2026.py
deleted file mode 100644
index 4f61427074f3da7f8f404795ce58528a1be00bb6..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0003_auto_20171114_2026.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-14 19:26
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('stats', '0002_auto_20171111_1646'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='kszkevent',
-            name='date',
-            field=models.DateTimeField(),
-        ),
-    ]
diff --git a/src/stats/migrations/0003_auto_20190122_1449.py b/src/stats/migrations/0003_auto_20190122_1449.py
new file mode 100644
index 0000000000000000000000000000000000000000..a3689e8ee847704324f3821df0508d6b89ffbb0d
--- /dev/null
+++ b/src/stats/migrations/0003_auto_20190122_1449.py
@@ -0,0 +1,24 @@
+# Generated by Django 2.0.1 on 2019-01-22 13:49
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('account', '0002_auto_20190122_1341'),
+        ('stats', '0002_event_description'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='event',
+            name='absent',
+            field=models.ManyToManyField(blank=True, related_name='events_absent', to='account.Profile'),
+        ),
+        migrations.AlterField(
+            model_name='event',
+            name='visitors',
+            field=models.ManyToManyField(blank=True, related_name='events_visitor', to='account.Profile'),
+        ),
+    ]
diff --git a/src/stats/migrations/0004_remove_kszkevent_num_of_pers.py b/src/stats/migrations/0004_remove_kszkevent_num_of_pers.py
deleted file mode 100644
index 06bf71b435fa15cddf94d3352678cba5aa44784a..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0004_remove_kszkevent_num_of_pers.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.5 on 2017-11-14 19:38
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('stats', '0003_auto_20171114_2026'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='kszkevent',
-            name='num_of_pers',
-        ),
-    ]
diff --git a/src/stats/migrations/0005_auto_20180214_2206.py b/src/stats/migrations/0005_auto_20180214_2206.py
deleted file mode 100644
index f4a0033cc39e3b8b311676b83ca7fdb22fa3bccf..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0005_auto_20180214_2206.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-14 21:06
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0017_auto_20180205_2004'),
-        ('stats', '0004_remove_kszkevent_num_of_pers'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Event',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('name', models.CharField(max_length=255)),
-                ('date', models.DateTimeField()),
-                ('visitors', models.ManyToManyField(related_name='visitor', to='account.Profile')),
-            ],
-        ),
-        migrations.RemoveField(
-            model_name='kszkevent',
-            name='visitors',
-        ),
-        migrations.DeleteModel(
-            name='KszkEvent',
-        ),
-    ]
diff --git a/src/stats/migrations/0006_auto_20180214_2239.py b/src/stats/migrations/0006_auto_20180214_2239.py
deleted file mode 100644
index 11bcd479e58a3a965982f251caa3b021c98273f2..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0006_auto_20180214_2239.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-14 21:39
-
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('stats', '0005_auto_20180214_2206'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='event',
-            name='visitors',
-            field=models.ManyToManyField(related_name='visitor', to=settings.AUTH_USER_MODEL),
-        ),
-    ]
diff --git a/src/stats/migrations/0007_auto_20180215_0018.py b/src/stats/migrations/0007_auto_20180215_0018.py
deleted file mode 100644
index 9cd65ce00b95c767f3bf9db33128446d83b79ad2..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0007_auto_20180215_0018.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-14 23:18
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('stats', '0006_auto_20180214_2239'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='event',
-            name='visitors',
-            field=models.ManyToManyField(related_name='visitor', to='account.Profile'),
-        ),
-    ]
diff --git a/src/stats/migrations/0008_note.py b/src/stats/migrations/0008_note.py
deleted file mode 100644
index 8b08926a7916ef37a514309d69c0f9b3ac8779c0..0000000000000000000000000000000000000000
--- a/src/stats/migrations/0008_note.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Generated by Django 2.0.1 on 2018-02-21 00:18
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('account', '0017_auto_20180205_2004'),
-        ('stats', '0007_auto_20180215_0018'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Note',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('note', models.TextField()),
-                ('created_at', models.DateTimeField(auto_now_add=True)),
-                ('updated_at', models.DateTimeField(auto_now=True)),
-                ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='created_notes', to='account.Profile')),
-                ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='stats.Event')),
-                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='account.Profile')),
-            ],
-        ),
-    ]
diff --git a/src/stats/models.py b/src/stats/models.py
index aa38fd947c9ec32fd41c407f52387c1c683779b7..be958204fba61174220ddc988100c21405f44241 100644
--- a/src/stats/models.py
+++ b/src/stats/models.py
@@ -1,28 +1,45 @@
 from django.db import models
 from account.models import Profile
-from django.utils import timezone
-from django.core.exceptions import ValidationError
+from common.middleware import CurrentUserMiddleware
 
 
 class Event(models.Model):
     name = models.CharField(max_length=255)
     date = models.DateTimeField(null=False)
-    visitors = models.ManyToManyField(Profile, related_name='visitor')
-
-    def clean(self):
-        if self.date > timezone.now():
-            raise ValidationError('Invalid date')
+    description = models.TextField(blank=True, default='')
+    visitors = models.ManyToManyField(
+        Profile,
+        related_name='events_visitor',
+        blank=True
+    )
+    absent = models.ManyToManyField(
+        Profile,
+        related_name='events_absent',
+        blank=True
+    )
+    created_by = models.ForeignKey(
+        Profile,
+        related_name='created_event',
+        on_delete=models.DO_NOTHING,
+        default=CurrentUserMiddleware.get_current_user_profile
+    )
+    created_at = models.DateTimeField(auto_now_add=True, editable=False)
+    updated_at = models.DateTimeField(auto_now=True, editable=False)
 
     def __str__(self):
         return self.name
 
 
 class Note(models.Model):
-    event = models.ForeignKey(Event, related_name='notes', on_delete=models.CASCADE)
-    user = models.ForeignKey(Profile, related_name='notes', on_delete=models.CASCADE)
+    event = models.ForeignKey(Event, related_name='notes', on_delete=models.CASCADE, blank=True, null=True)
+    profile = models.ForeignKey(Profile, related_name='notes', on_delete=models.CASCADE, blank=True, null=True)
     note = models.TextField()
-
-    created_by = models.ForeignKey(Profile, related_name='created_notes', on_delete=models.CASCADE)
+    created_by = models.ForeignKey(
+        Profile,
+        related_name='created_notes',
+        on_delete=models.DO_NOTHING,
+        default=CurrentUserMiddleware.get_current_user_profile
+    )
     created_at = models.DateTimeField(auto_now_add=True, editable=False)
     updated_at = models.DateTimeField(auto_now=True, editable=False)
 
diff --git a/src/stats/serializers.py b/src/stats/serializers.py
index 0620c993155de89cea2f2c9e463d00737248b803..e09d7b1b86fe537ddee2106ec72753d626696380 100644
--- a/src/stats/serializers.py
+++ b/src/stats/serializers.py
@@ -1,8 +1,51 @@
 from rest_framework import serializers
+from common.serializers import CurrentUserProfileDefault
 from . import models
 
 
-class EventSerializer(serializers.ModelSerializer):
+class StaffEventSerializer(serializers.ModelSerializer):
+    created_by_name = serializers.SerializerMethodField()
+    visitor_number = serializers.SerializerMethodField()
+
+    class Meta:
+        model = models.Event
+        fields = '__all__'
+        read_only_fields = ('created_at', 'update_at', 'created_by')
+
+    def get_created_by_name(self, obj):
+        return obj.created_by.full_name
+
+    def get_visitor_number(self, obj):
+        return obj.visitors.all().count()
+
+    def validate(self, data):
+        if 'absent' in data and 'visitors' in data:
+            for i in data['absent']:
+                if i in data['visitors']:
+                    raise serializers.ValidationError('You cant add a student to absent and visitor in the same time.')
+        return data
+
+
+class StudentEventSerializer(serializers.ModelSerializer):
     class Meta:
         model = models.Event
-        fields = ('name', 'date', 'visitors')
+        fields = ('id', 'name', 'date', 'description', )
+        read_only_fields = ('id', 'name', 'date', 'description', )
+
+
+class NoteSerializer(serializers.ModelSerializer):
+    created_by = serializers.HiddenField(default=CurrentUserProfileDefault())
+    created_by_name = serializers.SerializerMethodField()
+
+    class Meta:
+        model = models.Note
+        fields = '__all__'
+        read_only_fields = ('created_at', 'update_at', 'created_by')
+
+    def get_created_by_name(self, obj):
+        return obj.created_by.full_name
+
+    def validate(self, data):
+        if data['profile'] is None and data['event'] is None:
+            raise serializers.ValidationError('You have to add profile or event')
+        return data
diff --git a/src/stats/urls.py b/src/stats/urls.py
index 8f270ce8246724e9a29aaf99dd3d1e7d6690aec7..0e669f8037c98287185212ecbe0c2b43c03bd267 100644
--- a/src/stats/urls.py
+++ b/src/stats/urls.py
@@ -1,8 +1,9 @@
 from rest_framework import routers
-
 from . import views
 
 router = routers.DefaultRouter()
-router.register(r'events', views.EventViewSet)
+router.register(r'staff_events', views.StaffEventViewSet, base_name='staff_events')
+router.register(r'student_events', views.StudentEventViewSet, base_name='student_events')
+router.register(r'notes', views.NoteViewSet, base_name='notes')
 
 urlpatterns = router.urls
diff --git a/src/stats/views.py b/src/stats/views.py
index f2c91f1e70a8b38d620a0a500709f38f97359d9c..69ab78cb832c266e1e04a726ed6158f55455a6b3 100644
--- a/src/stats/views.py
+++ b/src/stats/views.py
@@ -1,9 +1,34 @@
 from rest_framework import viewsets
-
 from . import models
 from . import serializers
+from common.permissions import IsStaffUser, IsStaffOrStudent
+
+
+class StaffEventViewSet(viewsets.ModelViewSet):
+    serializer_class = serializers.StaffEventSerializer
+    queryset = models.Event.objects.all().order_by('date')
+    permission_classes = (IsStaffUser, )
+
+
+class StudentEventViewSet(viewsets.ModelViewSet):
+    serializer_class = serializers.StudentEventSerializer
+    queryset = models.Event.objects.all().order_by('date')
+    permission_classes = (IsStaffOrStudent, )
+
+
+class NoteViewSet(viewsets.ModelViewSet):
+    serializer_class = serializers.NoteSerializer
+    permission_classes = (IsStaffUser, )
 
+    def get_queryset(self):
+        queryset = models.Note.objects.all()
+        profile_id = self.request.query_params.get('profileID', None)
+        event_id = self.request.query_params.get('eventID', None)
+        if profile_id is not None and event_id is not None:
+            return queryset.filter(user=profile_id, event=event_id)
+        if profile_id is not None:
+            return queryset.filter(user=profile_id)
+        if event_id is not None:
+            return queryset.filter(event=event_id)
+        return queryset
 
-class EventViewSet(viewsets.ModelViewSet):
-    serializer_class = serializers.EventSerializer
-    queryset = models.Event.objects.all()