diff --git a/areas/templates/areas/area_confirm_delete_DELETE.html b/areas/templates/areas/area_confirm_delete_DELETE.html new file mode 100644 index 0000000..5a73330 --- /dev/null +++ b/areas/templates/areas/area_confirm_delete_DELETE.html @@ -0,0 +1,22 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+ +
+ +
+
+ +
+ {% csrf_token %} +

Alle unter diesem Bereich erstellten Aufgaben und Standards werden gelöscht!

+
+   + Abbrechen +
+
+
+{% endblock content %} \ No newline at end of file diff --git a/areas/templates/areas/areas_add_DELETE.html b/areas/templates/areas/areas_add_DELETE.html new file mode 100644 index 0000000..8402eb9 --- /dev/null +++ b/areas/templates/areas/areas_add_DELETE.html @@ -0,0 +1,43 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+

Neuen Bereich anlegen

+
+
+ {% csrf_token %} + {{ form|crispy }} +
+ Farbe +
+

Nachdem Erstellen eines Bereichs können Mitarbeiter zugewiesen werden.

+
+   + Abbrechen +
+
+ + + + +{% endblock content %} diff --git a/areas/templates/areas/areas_management_DELETE.html b/areas/templates/areas/areas_management_DELETE.html new file mode 100644 index 0000000..b187327 --- /dev/null +++ b/areas/templates/areas/areas_management_DELETE.html @@ -0,0 +1,101 @@ +{% extends "users/base.html" %} +{% block content %} + +
+

Bereichsverwaltung

+
+

+ Bereiche unterteilen die Agentur in verschiedene Verantwortungsbereiche. +

+
+ +
+
+
+ +
+
+ + + + + + + + + + + + {% for item in areas_of_agency %} + + + + + + + + {% endfor %} + +
NameErstellt vonErstellt amFarbe 
{{ item.name }}{{ item.created_area_by.first_name }} {{ item.created_area_by.last_name }}{{ item.created_area_date }}
+ + +
+
+
+ + +{% endblock content %} diff --git a/areas/templates/areas/areas_update_DELETE.html b/areas/templates/areas/areas_update_DELETE.html new file mode 100644 index 0000000..2922aeb --- /dev/null +++ b/areas/templates/areas/areas_update_DELETE.html @@ -0,0 +1,172 @@ +{% extends "users/base.html" %} +{% load static %} +{% load crispy_forms_tags %} +{% block content %} +
+

Bereich aktualisieren

+
+
+ {% csrf_token %} + {{ form|crispy }} +
+ Farbe +
+
Mitarbeiter hinzufügen
+
+ +
+ + +
+ + {% for us in possible_users %} + + {% endfor %} + + +
+
+
Zugewiesene Mitarbeiter
+
+ {% if added_users|length > 0 %} + + {% for us in added_users %} + {{ us.first_name }} {{ us.last_name }}   + + {% endfor %} + {% else %} +

Diesem Bereich ist noch kein Mitarbeiter zugewiesen.

+ {% endif %} +
+
+ +   + Abbrechen +
+
+ + + + +{% endblock content %} diff --git a/cloud/__pycache__/functionviews.cpython-38.pyc b/cloud/__pycache__/functionviews.cpython-38.pyc new file mode 100644 index 0000000..84d3af5 Binary files /dev/null and b/cloud/__pycache__/functionviews.cpython-38.pyc differ diff --git a/cloud/migrations/0005_datadir.py b/cloud/migrations/0005_datadir.py new file mode 100644 index 0000000..4caf8d8 --- /dev/null +++ b/cloud/migrations/0005_datadir.py @@ -0,0 +1,32 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:34 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0062_auto_20200213_2207'), + ('cloud', '0004_data_subdir'), + ] + + operations = [ + migrations.CreateModel( + name='DataDir', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, default='', max_length=2000, null=True)), + ('is_root', models.BooleanField(default=True)), + ('date_created', models.DateTimeField(default=django.utils.timezone.now)), + ('date_last_modified', models.DateTimeField(default=django.utils.timezone.now)), + ('agency', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='users.Agency')), + ('dirs', models.ManyToManyField(blank=True, related_name='dirs_in_dirs', to='cloud.DataDir')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ('visibleby', models.ManyToManyField(blank=True, related_name='visible_by_user', to='users.AgencyGroup')), + ], + ), + ] diff --git a/cloud/migrations/0006_datafiles.py b/cloud/migrations/0006_datafiles.py new file mode 100644 index 0000000..6c4d1a4 --- /dev/null +++ b/cloud/migrations/0006_datafiles.py @@ -0,0 +1,32 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:34 + +import cloud.models +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0062_auto_20200213_2207'), + ('cloud', '0005_datadir'), + ] + + operations = [ + migrations.CreateModel( + name='DataFiles', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, default='', max_length=2000, null=True)), + ('file', models.FileField(max_length=255, null=True, upload_to=cloud.models.user_directory_path)), + ('date_created', models.DateTimeField(default=django.utils.timezone.now)), + ('date_last_modified', models.DateTimeField(default=django.utils.timezone.now)), + ('agency', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='users.Agency')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ('parent', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cloud.DataDir')), + ], + ), + ] diff --git a/cloud/migrations/0007_auto_20200214_2236.py b/cloud/migrations/0007_auto_20200214_2236.py new file mode 100644 index 0000000..182225b --- /dev/null +++ b/cloud/migrations/0007_auto_20200214_2236.py @@ -0,0 +1,24 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:36 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cloud', '0006_datafiles'), + ] + + operations = [ + migrations.AddField( + model_name='datadir', + name='datafiles', + field=models.ManyToManyField(blank=True, related_name='files_in_dir', to='cloud.DataFiles'), + ), + migrations.AlterField( + model_name='datafiles', + name='parent', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='thisfileindir', to='cloud.DataDir'), + ), + ] diff --git a/cloud/migrations/0008_auto_20200214_2237.py b/cloud/migrations/0008_auto_20200214_2237.py new file mode 100644 index 0000000..d9c9c93 --- /dev/null +++ b/cloud/migrations/0008_auto_20200214_2237.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cloud', '0007_auto_20200214_2236'), + ] + + operations = [ + migrations.AlterField( + model_name='datadir', + name='is_root', + field=models.BooleanField(default=False), + ), + ] diff --git a/cloud/migrations/0009_auto_20200214_2238.py b/cloud/migrations/0009_auto_20200214_2238.py new file mode 100644 index 0000000..8606028 --- /dev/null +++ b/cloud/migrations/0009_auto_20200214_2238.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:38 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0062_auto_20200213_2207'), + ('cloud', '0008_auto_20200214_2237'), + ] + + operations = [ + migrations.RenameModel( + old_name='DataFiles', + new_name='DataFile', + ), + ] diff --git a/cloud/migrations/0010_auto_20200214_2241.py b/cloud/migrations/0010_auto_20200214_2241.py new file mode 100644 index 0000000..2ef2f99 --- /dev/null +++ b/cloud/migrations/0010_auto_20200214_2241.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:41 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cloud', '0009_auto_20200214_2238'), + ] + + operations = [ + migrations.AlterField( + model_name='datadir', + name='owner', + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/cloud/migrations/0011_auto_20200214_2241.py b/cloud/migrations/0011_auto_20200214_2241.py new file mode 100644 index 0000000..bc70796 --- /dev/null +++ b/cloud/migrations/0011_auto_20200214_2241.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.2 on 2020-02-14 22:41 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cloud', '0010_auto_20200214_2241'), + ] + + operations = [ + migrations.AlterField( + model_name='datadir', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/cloud/migrations/0012_auto_20200214_2313.py b/cloud/migrations/0012_auto_20200214_2313.py new file mode 100644 index 0000000..18985ed --- /dev/null +++ b/cloud/migrations/0012_auto_20200214_2313.py @@ -0,0 +1,25 @@ +# Generated by Django 3.0.2 on 2020-02-14 23:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0062_auto_20200213_2207'), + ('cloud', '0011_auto_20200214_2241'), + ] + + operations = [ + migrations.AddField( + model_name='datadir', + name='parent', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dir_in_dir', to='cloud.DataDir'), + ), + migrations.AlterField( + model_name='datadir', + name='agency', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency'), + ), + ] diff --git a/cloud/migrations/0013_auto_20200215_1347.py b/cloud/migrations/0013_auto_20200215_1347.py new file mode 100644 index 0000000..b25c06f --- /dev/null +++ b/cloud/migrations/0013_auto_20200215_1347.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.2 on 2020-02-15 13:47 + +import cloud.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cloud', '0012_auto_20200214_2313'), + ] + + operations = [ + migrations.AlterField( + model_name='datafile', + name='file', + field=models.FileField(blank=True, max_length=255, null=True, upload_to=cloud.models.user_directory_path), + ), + ] diff --git a/cloud/migrations/0014_auto_20200215_1411.py b/cloud/migrations/0014_auto_20200215_1411.py new file mode 100644 index 0000000..71355a6 --- /dev/null +++ b/cloud/migrations/0014_auto_20200215_1411.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.2 on 2020-02-15 14:11 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cloud', '0013_auto_20200215_1347'), + ] + + operations = [ + migrations.AlterField( + model_name='datafile', + name='parent', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='thisfileindir', to='cloud.DataDir'), + ), + ] diff --git a/cloud/migrations/0015_auto_20200215_1427.py b/cloud/migrations/0015_auto_20200215_1427.py new file mode 100644 index 0000000..d5d566e --- /dev/null +++ b/cloud/migrations/0015_auto_20200215_1427.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.2 on 2020-02-15 14:27 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0062_auto_20200213_2207'), + ('cloud', '0014_auto_20200215_1411'), + ] + + operations = [ + migrations.AlterField( + model_name='datafile', + name='agency', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.Agency'), + ), + migrations.AlterField( + model_name='datafile', + name='owner', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/cloud/migrations/0016_remove_datadir_datafiles.py b/cloud/migrations/0016_remove_datadir_datafiles.py new file mode 100644 index 0000000..70b797a --- /dev/null +++ b/cloud/migrations/0016_remove_datadir_datafiles.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.2 on 2020-02-15 15:25 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cloud', '0015_auto_20200215_1427'), + ] + + operations = [ + migrations.RemoveField( + model_name='datadir', + name='datafiles', + ), + ] diff --git a/cloud/migrations/0017_auto_20200215_1910.py b/cloud/migrations/0017_auto_20200215_1910.py new file mode 100644 index 0000000..6d478ea --- /dev/null +++ b/cloud/migrations/0017_auto_20200215_1910.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.2 on 2020-02-15 19:10 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0062_auto_20200213_2207'), + ('cloud', '0016_remove_datadir_datafiles'), + ] + + operations = [ + migrations.AlterField( + model_name='datadir', + name='agency', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='users.Agency'), + ), + migrations.AlterField( + model_name='datadir', + name='parent', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='dir_in_dir', to='cloud.DataDir'), + ), + migrations.AlterField( + model_name='datafile', + name='agency', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='users.Agency'), + ), + ] diff --git a/cloud/migrations/0018_auto_20200215_1911.py b/cloud/migrations/0018_auto_20200215_1911.py new file mode 100644 index 0000000..4d0aad7 --- /dev/null +++ b/cloud/migrations/0018_auto_20200215_1911.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.2 on 2020-02-15 19:11 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0062_auto_20200213_2207'), + ('cloud', '0017_auto_20200215_1910'), + ] + + operations = [ + migrations.AlterField( + model_name='datadir', + name='agency', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency'), + ), + migrations.AlterField( + model_name='datadir', + name='parent', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dir_in_dir', to='cloud.DataDir'), + ), + migrations.AlterField( + model_name='datafile', + name='agency', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.Agency'), + ), + ] diff --git a/cloud/migrations/__pycache__/0005_datadir.cpython-38.pyc b/cloud/migrations/__pycache__/0005_datadir.cpython-38.pyc new file mode 100644 index 0000000..d67dac4 Binary files /dev/null and b/cloud/migrations/__pycache__/0005_datadir.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0006_datafiles.cpython-38.pyc b/cloud/migrations/__pycache__/0006_datafiles.cpython-38.pyc new file mode 100644 index 0000000..1f81e11 Binary files /dev/null and b/cloud/migrations/__pycache__/0006_datafiles.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0007_auto_20200214_2236.cpython-38.pyc b/cloud/migrations/__pycache__/0007_auto_20200214_2236.cpython-38.pyc new file mode 100644 index 0000000..58d9837 Binary files /dev/null and b/cloud/migrations/__pycache__/0007_auto_20200214_2236.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0008_auto_20200214_2237.cpython-38.pyc b/cloud/migrations/__pycache__/0008_auto_20200214_2237.cpython-38.pyc new file mode 100644 index 0000000..a9de322 Binary files /dev/null and b/cloud/migrations/__pycache__/0008_auto_20200214_2237.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0009_auto_20200214_2238.cpython-38.pyc b/cloud/migrations/__pycache__/0009_auto_20200214_2238.cpython-38.pyc new file mode 100644 index 0000000..3a0eae6 Binary files /dev/null and b/cloud/migrations/__pycache__/0009_auto_20200214_2238.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0010_auto_20200214_2241.cpython-38.pyc b/cloud/migrations/__pycache__/0010_auto_20200214_2241.cpython-38.pyc new file mode 100644 index 0000000..ef5ca55 Binary files /dev/null and b/cloud/migrations/__pycache__/0010_auto_20200214_2241.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0011_auto_20200214_2241.cpython-38.pyc b/cloud/migrations/__pycache__/0011_auto_20200214_2241.cpython-38.pyc new file mode 100644 index 0000000..05cd638 Binary files /dev/null and b/cloud/migrations/__pycache__/0011_auto_20200214_2241.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0012_auto_20200214_2313.cpython-38.pyc b/cloud/migrations/__pycache__/0012_auto_20200214_2313.cpython-38.pyc new file mode 100644 index 0000000..56406f9 Binary files /dev/null and b/cloud/migrations/__pycache__/0012_auto_20200214_2313.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0013_auto_20200215_1347.cpython-38.pyc b/cloud/migrations/__pycache__/0013_auto_20200215_1347.cpython-38.pyc new file mode 100644 index 0000000..93684c6 Binary files /dev/null and b/cloud/migrations/__pycache__/0013_auto_20200215_1347.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0014_auto_20200215_1411.cpython-38.pyc b/cloud/migrations/__pycache__/0014_auto_20200215_1411.cpython-38.pyc new file mode 100644 index 0000000..a8ee809 Binary files /dev/null and b/cloud/migrations/__pycache__/0014_auto_20200215_1411.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0015_auto_20200215_1427.cpython-38.pyc b/cloud/migrations/__pycache__/0015_auto_20200215_1427.cpython-38.pyc new file mode 100644 index 0000000..d35eb6e Binary files /dev/null and b/cloud/migrations/__pycache__/0015_auto_20200215_1427.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0016_remove_datadir_datafiles.cpython-38.pyc b/cloud/migrations/__pycache__/0016_remove_datadir_datafiles.cpython-38.pyc new file mode 100644 index 0000000..d6b69ce Binary files /dev/null and b/cloud/migrations/__pycache__/0016_remove_datadir_datafiles.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0017_auto_20200215_1910.cpython-38.pyc b/cloud/migrations/__pycache__/0017_auto_20200215_1910.cpython-38.pyc new file mode 100644 index 0000000..ce6a17b Binary files /dev/null and b/cloud/migrations/__pycache__/0017_auto_20200215_1910.cpython-38.pyc differ diff --git a/cloud/migrations/__pycache__/0018_auto_20200215_1911.cpython-38.pyc b/cloud/migrations/__pycache__/0018_auto_20200215_1911.cpython-38.pyc new file mode 100644 index 0000000..4747555 Binary files /dev/null and b/cloud/migrations/__pycache__/0018_auto_20200215_1911.cpython-38.pyc differ diff --git a/cloud/templates/cloud/noentrie.html b/cloud/templates/cloud/noentrie.html new file mode 100644 index 0000000..bddf137 --- /dev/null +++ b/cloud/templates/cloud/noentrie.html @@ -0,0 +1,7 @@ +{% extends "users/base.html" %} +{% block content %} +
+

Auf diesen Dateibereich haben Sie keinen Zugriff!

+
+
+{% endblock %} \ No newline at end of file diff --git a/dasettings/__init__.py b/dasettings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dasettings/__pycache__/__init__.cpython-38.pyc b/dasettings/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..5b34a81 Binary files /dev/null and b/dasettings/__pycache__/__init__.cpython-38.pyc differ diff --git a/dasettings/__pycache__/admin.cpython-38.pyc b/dasettings/__pycache__/admin.cpython-38.pyc new file mode 100644 index 0000000..af142da Binary files /dev/null and b/dasettings/__pycache__/admin.cpython-38.pyc differ diff --git a/dasettings/__pycache__/apps.cpython-38.pyc b/dasettings/__pycache__/apps.cpython-38.pyc new file mode 100644 index 0000000..79620bc Binary files /dev/null and b/dasettings/__pycache__/apps.cpython-38.pyc differ diff --git a/dasettings/__pycache__/forms.cpython-38.pyc b/dasettings/__pycache__/forms.cpython-38.pyc new file mode 100644 index 0000000..278fb38 Binary files /dev/null and b/dasettings/__pycache__/forms.cpython-38.pyc differ diff --git a/dasettings/__pycache__/models.cpython-38.pyc b/dasettings/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000..a0bfe95 Binary files /dev/null and b/dasettings/__pycache__/models.cpython-38.pyc differ diff --git a/dasettings/__pycache__/urls.cpython-38.pyc b/dasettings/__pycache__/urls.cpython-38.pyc new file mode 100644 index 0000000..91cb794 Binary files /dev/null and b/dasettings/__pycache__/urls.cpython-38.pyc differ diff --git a/dasettings/__pycache__/views.cpython-38.pyc b/dasettings/__pycache__/views.cpython-38.pyc new file mode 100644 index 0000000..e8b88b4 Binary files /dev/null and b/dasettings/__pycache__/views.cpython-38.pyc differ diff --git a/dasettings/admin.py b/dasettings/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/dasettings/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/dasettings/apps.py b/dasettings/apps.py new file mode 100644 index 0000000..8764e82 --- /dev/null +++ b/dasettings/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DASettingsConfig(AppConfig): + name = 'dasettings' diff --git a/dasettings/forms.py b/dasettings/forms.py new file mode 100644 index 0000000..b4fe5b9 --- /dev/null +++ b/dasettings/forms.py @@ -0,0 +1,110 @@ +from django import forms +from django.db import models +from django.contrib.auth.models import User +from users.models import AgencyGroup, Agency, Profile, AgencyJob +from PIL import Image + +# Change logged Users Data (Usernamen an Email) NUR HIER MÖGLICH! +class UsersSelfChangeForm(forms.ModelForm): + email = forms.EmailField() + + class Meta: + model = User + fields = ['email'] + +# Form für die Benachrichtigungseinstellungen +class UsersNotificationForm(forms.ModelForm): + + class Meta: + model = Profile + labels = { + "news_mail" : "Agentur-News", + "user_standard_public_mail" : "Veröffentlichung meiner Standards", + "agency_new_standard_mail" : "Neue Agentur-Standards", + 'add_new_group_mail' : "Gruppenmitgliedschaften", + 'add_task_mail' : "Tätigkeitsbereich" + } + fields = ['news_mail', 'news_push', 'user_standard_public_mail', 'user_standard_public_push', 'agency_new_standard_mail', 'agency_new_standard_push', 'add_new_group_mail', 'add_new_group_push', 'add_task_mail', 'add_task_push'] + +# PERMISSION GROUPS FORM +class AgencyGroupPerms(forms.Form): + ''' + Permission-System + + Persmissions werden im Model gesetzt, hier automatisch als Form ausgegeben. + Hat der Nutzer eine der genannten Rechte, wird die Checkbox automatisch TRUE gesetzt. + Die erstellen Felder werden entsprechend den Feldern hinzugefügt und ausgegeben. + + @param: user + - User ist der aufgerufene User! + ''' + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + temprof = AgencyGroup + for ele in temprof._meta.permissions: + self.fields[ele[0]] = forms.BooleanField(required=False, initial=False, help_text=(ele[1])) + +# LOADING ALL MODUL-OPTIONS +class AgencyModulsForm(forms.ModelForm): + + class Meta: + model = Agency + labels = { + 'module_news' : "Agentur-News", + 'module_quicklinks' : "Quicklinks", + 'module_files' : "Dateien", + 'module_organigramm' : "Organigramm", + } + fields = ['module_news','module_quicklinks','module_files','module_organigramm'] + +# NEW USER FORM +class UserNewUserForm(forms.ModelForm): + + class Meta: + model = User + fields = ["first_name", "last_name", "email"] + +# NEW USER PROFILE FORM +class UserProfileForm(forms.ModelForm): + + x = forms.FloatField(widget=forms.HiddenInput()) + y = forms.FloatField(widget=forms.HiddenInput()) + width = forms.FloatField(widget=forms.HiddenInput()) + height = forms.FloatField(widget=forms.HiddenInput()) + rotation = forms.FloatField(widget=forms.HiddenInput()) + + class Meta: + model = Profile + labels = { + "persnumber" : "Personalnummer", + "visible" : "Im Organigramm sichtbar", + "phonemobile" : "Mobilnummer", + "phoneland" : "Festnetznummer", + "image": "Profilbild", + "func" : "Agenturfunktion", + "compfunc" : "Tätigkeit" + } + widgets = {"parent" : forms.HiddenInput()} + fields = ["parent", "func", "compfunc", "visible", "phoneland", "phonemobile", "persnumber", "image" ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['func'].queryset = AgencyJob.objects.filter(agency__pk=self.instance.agency.pk) + + def save(self): + photo = super(UserProfileForm, self).save() + try: + x = self.cleaned_data.get('x') + y = self.cleaned_data.get('y') + w = self.cleaned_data.get('width') + h = self.cleaned_data.get('height') + rotation = self.cleaned_data.get('rotation') + image = Image.open(photo.image) + rotatet_image = image.rotate(rotation, expand=True) + cropped_image = rotatet_image.crop((x, y, w+x, h+y)) + resized_image = cropped_image.resize((300, 300), Image.ANTIALIAS) + resized_image.save(photo.image.path) + return photo + except: + print("no photo") + diff --git a/dasettings/migrations/__init__.py b/dasettings/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dasettings/migrations/__pycache__/__init__.cpython-38.pyc b/dasettings/migrations/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..06057d3 Binary files /dev/null and b/dasettings/migrations/__pycache__/__init__.cpython-38.pyc differ diff --git a/dasettings/models.py b/dasettings/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/dasettings/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/dasettings/templates/dasettings/agency_content.html b/dasettings/templates/dasettings/agency_content.html new file mode 100644 index 0000000..81cd17c --- /dev/null +++ b/dasettings/templates/dasettings/agency_content.html @@ -0,0 +1,340 @@ +{% load crispy_forms_tags %} +{% load static %} +{% load mathfilters %} +{% load humanize %} + +
+ + +
+ +
+ + + {% csrf_token %} +
+ +
+
+ {% for formfield in agencyform %} + {% if forloop.counter|divisibleby:5 %} +
+
+ {{formfield|as_crispy_field}} + {% else %} + {{formfield|as_crispy_field}} + {% endif %} + {% endfor %} +
+
+
Abrechnung
+

Kontostand: {{request.user.profile.agency.balance|floatformat:0}} €

+

Nächste Abbuchung am {{request.user.profile.agency.nextdebiting|date:"d.m.Y"}}

+

Max. Nutzungszeit:  {{request.user.profile.agency.balance|div:30|floatformat:0}} Monate

+

IBAN: DE4412345678912345

+

Laden Sie das Konto mit einem beliebigen Geldbetrag auf. Die Kosten belaufen sich auf 40 € pro Monat.

+
+
+
+
+
+   +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/dasettings/templates/dasettings/groups_content.html b/dasettings/templates/dasettings/groups_content.html new file mode 100644 index 0000000..432cbec --- /dev/null +++ b/dasettings/templates/dasettings/groups_content.html @@ -0,0 +1,476 @@ +{% load counter_tag %} +
+ + + + + + +
+
+{% for aggroup in agencygroups %} +{% setvar 0 %} + {% for user in usersofagency %} + {% for group in user.groups.all %} + {% if group.name == aggroup.group.name %} + {% incvar %} + {% endif %} + {% endfor %} + {% endfor %} +{% getvar as varcounter %} +
+
+
+     + + + {% if not aggroup.savefordel %} + + {% endif %} + {% if aggroup.savefordel %} + + {% endif %} +
+
+ +
+
+
Gruppenrechte 
+
+
+ {% for perm in perms %} + {% if forloop.counter|divisibleby:7 %} +
+
+
+ + +
+ {% else %} +
+ + +
+ {% endif %} + {% endfor %} +
+
+
+
+
Mitarbeiter zur Gruppe {{aggroup.agencygroupname}} hinzufügen
+
+ +
+ +
+ + {% for user in usersofagency %} + {% if not user|has_group:aggroup.group.name %} + + +
+
+
Gruppenmitglieder in {{aggroup.agencygroupname}}
+ {% if varcounter > 0 %} + + {% else %} + Diese Gruppe hat noch keine Mitglieder. + {% endif %} +
+ {% for user in usersofagency %} + {% for group in user.groups.all %} + {% if group.name == aggroup.group.name %} + {% if request.user == user and aggroup.is_admin %} + + {% else %} + {{ user.first_name }} {{ user.last_name }}   + + {% endif %} + {% endif %} + {% endfor %} + {% endfor %} +
+
+ +
+
+
+{% endfor %} +
+
+
+ +{% for aggroup in agencygroups %} + {% for p in aggroup.group.permissions.all %} + {% for perm in perms %} + {% if p.codename == perm.name %} + + {% endif %} + {% endfor %} + {% endfor %} +{% endfor %} + + + + + + + \ No newline at end of file diff --git a/dasettings/templates/dasettings/moduls_content.html b/dasettings/templates/dasettings/moduls_content.html new file mode 100644 index 0000000..4db9b03 --- /dev/null +++ b/dasettings/templates/dasettings/moduls_content.html @@ -0,0 +1,28 @@ +{% load crispy_forms_tags %} +
+ + + + + + + + + + + {% csrf_token %} + + +{% for formfield in modulform %} + + + + + +{% endfor %} + +
ModulAktiviertEinstellungen
{{formfield.label_tag}}{{formfield}}
+ + +
+ diff --git a/dasettings/templates/dasettings/notifications_content.html b/dasettings/templates/dasettings/notifications_content.html new file mode 100644 index 0000000..d5accf2 --- /dev/null +++ b/dasettings/templates/dasettings/notifications_content.html @@ -0,0 +1,64 @@ +{% load crispy_forms_tags %} +
+ + + + + + + + + +{% for formfield in notificationform %} + {% if forloop.counter|divisibleby:2 %} + + + {% else %} + + + + {% endif %} +{% endfor %} + +
BenachrichtigungE-MailPush
{{formfield}}
{{formfield.label_tag}}{{formfield}}
+ +
+ \ No newline at end of file diff --git a/dasettings/templates/dasettings/profil_content.html b/dasettings/templates/dasettings/profil_content.html new file mode 100644 index 0000000..855b187 --- /dev/null +++ b/dasettings/templates/dasettings/profil_content.html @@ -0,0 +1,114 @@ +{% load crispy_forms_tags %} +
+ +
+ +
+
+
+
Name
+

+ {{ user.first_name }} {{ user.last_name }} +

+
E-Mail
+

+ {{ user.email }} +

+
Agenturfunktion
+

+ {{ user.profile.func }} +

+
+
+
Tätigkeit
+

+ {{ user.profile.compfunc }} +

+
Festnetz
+

+ {{ user.profile.phoneland }} +

+
Mobil
+

+ {{ user.profile.phonemobile }} +

+
+
+
+
+ +
+
+ {% csrf_token %} + + +
+ + Profil bearbeiten + + {% if request.user.profile.showtooltips %} +
+ + +
+ {% else %} +
+ + +
+ {% endif %} + + {{ userform|crispy }} +
+ + Agenturrelevante Daten (Bild, Telefonnummer etc.) werden in der Benutzerverwaltung verändert. +
+   +
+
+
+ {% csrf_token %} + + +
+ + {{ passwordform|crispy}} +
+ +
+   +
+
+
+ diff --git a/dasettings/templates/dasettings/settings.html b/dasettings/templates/dasettings/settings.html new file mode 100644 index 0000000..ecdd3dc --- /dev/null +++ b/dasettings/templates/dasettings/settings.html @@ -0,0 +1,184 @@ +{% extends "users/base.html" %} +{% load counter_tag %} +{% block content %} + +
+ + +
+
+ + +
+
+ +

Einstellungen 

+
+ +
+
+
Profileinstellungen 
+
+ {% block profil_content %} + {% include "dasettings/profil_content.html" %} + {% endblock %} +
+
+
Benachrichtigungen 
+ + {% block notifications_content %} + {% include "dasettings/notifications_content.html" %} + {% endblock %} +
+ {% if user|usergperm:"agencyinfo" %} +
+
Agenturinformationen 
+
+ {% block agency_content %} + {% include "dasettings/agency_content.html" %} + {% endblock %} +
+ {% endif %} + {% if user|usergperm:"structuremanager" %} +
+
Struktur 
+
+ {% block structure_content %} + {% include "dasettings/structure_content.html" %} + {% endblock %} +
+ {% endif %} + {% if user|usergperm:"usermanager" %} +
+
Mtarbeiter 
+
+ {% block user_content %} + {% include "dasettings/user_content.html" %} + {% endblock %} +
+ {% endif %} + {% if user|usergperm:"groupmanager" %} +
+
Gruppen 
+
+ {% block groups_content %} + {% include "dasettings/groups_content.html" %} + {% endblock %} +
+ {% endif %} + {% if user|usergperm:"modulesconfig" %} +
+
Module 
+ {% block moduls_content %} + {% include "dasettings/moduls_content.html" %} + {% endblock %} +
+ {% endif %} +
+
+ +{% endblock content %} \ No newline at end of file diff --git a/dasettings/templates/dasettings/structure_content.html b/dasettings/templates/dasettings/structure_content.html new file mode 100644 index 0000000..2398b06 --- /dev/null +++ b/dasettings/templates/dasettings/structure_content.html @@ -0,0 +1,747 @@ +{% load static %} +{% load counter_tag %} + + + + + + + + +
+ +
+ +
+
+{%for area in agencyareas%} +
+
+
+ +      + + + + +
+
+
+
+ + + + + + + + + + + + + {% for task in alltasks %} + {% if task.area.pk == area.pk %} + + + + + + + + {% endif %} + {% endfor %} + +
NameBereichErstellt vonErstellt am 
{{task.name }}{{ task.area.name }}{{ task.created_area_by.first_name }} {{ task.created_area_by.last_name }}{{ task.created_area_date }} + + +
+
+
+
+ +{% endfor %} +
+
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/dasettings/templates/dasettings/user_changemaindata.html b/dasettings/templates/dasettings/user_changemaindata.html new file mode 100644 index 0000000..8694f97 --- /dev/null +++ b/dasettings/templates/dasettings/user_changemaindata.html @@ -0,0 +1,16 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+

Stammdaten von {{user_fullname}} ändern

+
+
+ {% csrf_token %} + {{ userform|crispy }} +
+ Abbrechen + +
+
+
+{% endblock content %} \ No newline at end of file diff --git a/dasettings/templates/dasettings/user_content.html b/dasettings/templates/dasettings/user_content.html new file mode 100644 index 0000000..a42305c --- /dev/null +++ b/dasettings/templates/dasettings/user_content.html @@ -0,0 +1,51 @@ +{% load counter_tag %} ++ Mitarbeiter +
+
+
+ +
+
+ + + + + + + + + + + + + + {% for item in usersofagency %} + + + + + + + + + + {% endfor %} + +
NameE-MailAgenturfunktionTätigkeitTelefonMobil 
{{item.first_name }} {{ item.last_name }}{{ item.email }}{% if item.profile.func == None %}-{%else%}{{ item.profile.func }}{%endif%}{{ item.profile.compfunc }}{{ item.profile.phoneland }}{{ item.profile.phonemobile }} + {% if item != request.user %} + + {% endif %} +
+
+
+ + diff --git a/dasettings/templates/dasettings/user_newuser_step1.html b/dasettings/templates/dasettings/user_newuser_step1.html new file mode 100644 index 0000000..e1f1c87 --- /dev/null +++ b/dasettings/templates/dasettings/user_newuser_step1.html @@ -0,0 +1,30 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+

Neuer Benutzer 

+
+
+
Schritt 1: Stammdaten
+
+Legen Sie hier die Stammdaten des neuen Mitarbeiters fest. + +
+ {% csrf_token %} + {{ newuserform|crispy }} + +
+ + +
+ *: Der Benutzer erhält direkt eine E-Mail mit einem Link zur Passworterstellung, wenn der Haken bei E-Mailbenachrichtung schicken gesetzt ist. Dies kann später auch wiederholt werden. + +
+ Abbrechen + +
+
+ +{% endblock content %} \ No newline at end of file diff --git a/dasettings/templates/dasettings/user_usprof.html b/dasettings/templates/dasettings/user_usprof.html new file mode 100644 index 0000000..294e25c --- /dev/null +++ b/dasettings/templates/dasettings/user_usprof.html @@ -0,0 +1,325 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% load counter_tag %} +{% load static %} +{% block content %} + + + + +
+ + +
+
+ + +
+ + +
+

Profil von {{user_fullname}} bearbeiten 

+
+ {% if newuser == 1 %} +
+
Schritt 2: Profildaten festlegen
+
+ {% endif %} +
+ +
+
+
+
Name
+

+ {{ user_fullname }} +

+
E-Mail
+

+ {{ mail }} +

+ Stammdaten ändern +
+
+
+
+
+
+ +
+

Gruppen 

+
+
+ {% for g in agencygroups %} + {% if forloop.counter|divisibleby:6 %} +
+
+ {% if vieweduser|useringroupbyid:g.group.name %} + + {% else %} + + {% endif %} + +
+ {% else %} +
+ {% if vieweduser|useringroupbyid:g.group.name %} + + {% else %} + + {% endif %} + +
+ {% endif %} + {% endfor %} +
+
+
+
+

Übergeordneter Mitarbeiter 

+ +
+
+

Persönliches Profil

+ {% csrf_token %} +
+
+ {% for field in profileform %} + {% if forloop.counter|divisibleby:6 %} +
+
+ {{field|as_crispy_field}} + {% else %} + {{field|as_crispy_field}} + {% endif %} + {% endfor %} +
+
+ +
+ {% if newuser == 1 %} + + {% else %} + + {% endif %} + Profilbearbeitung abbrechen +
+
+ + + + +{% endblock content %} \ No newline at end of file diff --git a/dasettings/tests.py b/dasettings/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dasettings/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dasettings/urls.py b/dasettings/urls.py new file mode 100644 index 0000000..555fd34 --- /dev/null +++ b/dasettings/urls.py @@ -0,0 +1,16 @@ +from django.urls import path +from django.contrib.auth import views as auth_views +from django.contrib.auth.decorators import login_required, permission_required +from . import views +from .views import NewUserFirstStep, UserProfileUpdate, UserChangeMain +''' +Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben! +''' + +urlpatterns = [ + path('main/', views.DASettings, name='dasettings'), + path('newuser/s1', permission_required('users.usermanager')(views.NewUserFirstStep), name='newuserfirst'), + path('changeus//', permission_required('users.usermanager')(views.UserChangeMain), name='changeusermaindata'), + path('ajax/', views.SettingsAjaxRouter, name="dasettings-ajax"), + path('usprof//', permission_required('users.usermanager')(views.UserProfileUpdate), name="user_updateprofile") +] \ No newline at end of file diff --git a/dasettings/views.py b/dasettings/views.py new file mode 100644 index 0000000..ab270f9 --- /dev/null +++ b/dasettings/views.py @@ -0,0 +1,557 @@ +from django.shortcuts import render, redirect +from django.contrib.auth.decorators import login_required +from django.http import HttpResponseRedirect,HttpResponse, JsonResponse +from .forms import UsersSelfChangeForm, UsersNotificationForm, AgencyGroupPerms, AgencyModulsForm, UserNewUserForm, UserProfileForm +from django.contrib import messages +from django.contrib.auth import update_session_auth_hash +from django.contrib.auth.forms import PasswordChangeForm +from users.usersforms import AgencyUpdateForm +from users.models import AgencyJob, AgencyGroup +from django.contrib.auth.models import User, Group, Permission +import random +import string +from users.usersforms import UsersPermForm +from django.contrib.auth.mixins import LoginRequiredMixin +from django.views.generic import CreateView +from users.models import Profile +from areas.models import Areas +from tasks.models import Tasks +import webcolors +from datetime import datetime +from standards.models import Standards + +def randomString(stringLength=10): + """Generate a random string of fixed length """ + letters = string.ascii_lowercase + return ''.join(random.choice(letters) for i in range(stringLength)) + +@login_required +def checkForGroupName(request, newgroupname): + stat = True + groupsagency = AgencyGroup.objects.filter(agency__pk=request.user.profile.agency.pk) + for group in groupsagency: + if group.agencygroupname.upper() == newgroupname.upper(): + stat = False + return stat + +@login_required +def getAllForms(request, context): + # USERFORMS + userform = UsersSelfChangeForm(instance=request.user) + passwordform = PasswordChangeForm(request.user) + context.update({'userform' : userform}) + context.update({'passwordform' : passwordform}) + + # NOTIFICTAION FORMS + notificationform = UsersNotificationForm(instance=request.user.profile) + context.update({'notificationform' : notificationform}) + + # AGENCY UPDATE FORMS + agencyform = AgencyUpdateForm(instance=request.user.profile.agency) + context.update({'agencyform' : agencyform}) + + #PERMS + perms = AgencyGroupPerms() + context.update({'perms' : perms}) + + #MODULFORMS + modulform = AgencyModulsForm(instance=request.user.profile.agency) + context.update({'modulform' : modulform}) + + # USER FOR USERTABLE + users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk) + return context + + +''' + Lädt die Formulare für die einzelnen Einstellungen vollständig +''' +@login_required +def DASettings(request): + context = { + 'active_link' : 'dasettings' + } + context = getAllForms(request, context) + + # USERS FOR MEMBERS AND GROUPCOUNTERS + usersofagency = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).order_by("last_name") + context.update({"usersofagency" : usersofagency}) + + # LOAD AGENCYJOBS + context.update({"agencyjobs" : AgencyJob.objects.filter(agency__pk=request.user.profile.agency.pk).order_by("name")}) + + # LOAD GROUPS + agencygroups = AgencyGroup.objects.filter(agency__pk=request.user.profile.agency.pk).order_by("agencygroupname") + context.update({"agencygroups" : agencygroups}) + + # LOAD AREAS + agencyareas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk).order_by('areaorder') + context.update({"agencyareas" : agencyareas}) + + # LOAD TASKS + alltasks = Tasks.objects.filter(agency__pk=request.user.profile.agency.pk).order_by('name') + context.update({"alltasks" : alltasks}) + + if request.method == 'POST' and request.POST.get("settings_area") == "profil": + return SettingsProfilManagement(request, context) + elif request.method == 'POST' and request.POST.get("settings_area") == "agency": + return SettingsAgency(request, context) + elif request.method == 'POST' and request.POST.get("settings_area") == "moduls": + return SettingsAgencyModuls(request, context) + + + + # Returning the data from database for normal-loading Settings + else: + # DEFAULT DATA FORM-INFOS + # Hier müssen alle Standard-Formulare rein, damit die Seite Settings + # generell geladen werden kann. + # PROFILE FORMS + userform = UsersSelfChangeForm(instance=request.user) + passwordform = PasswordChangeForm(request.user) + context.update({'userform' : userform}) + context.update({'passwordform' : passwordform}) + + # NOTIFICTAION FORMS + notificationform = UsersNotificationForm(instance=request.user.profile) + context.update({'notificationform' : notificationform}) + + # AGENCY UPDATE FORMS + agencyform = AgencyUpdateForm(instance=request.user.profile.agency) + context.update({'agencyform' : agencyform}) + + return render(request, 'dasettings/settings.html', context) + +''' + +AGENCY + +Hier werden die Agenturinfos ink. Agenturcropper für das Agenturbild angepasst. + +''' +@login_required +def SettingsAgency(request, context): + if request.POST.get("form_type") == "agencyform": + agencyform = AgencyUpdateForm(request.POST, instance=request.user.profile.agency) + if agencyform.is_valid(): + if 'agencypic' in request.FILES: + request.user.profile.agency.agencypic = request.FILES['agencypic'] + agencyform.save() + context['agencyform'] = AgencyUpdateForm(instance=request.user.profile.agency) + messages.success(request, f'Agenturdaten aktualisiert!') + return render(request, 'dasettings/settings.html', context) + else: + messages.success(request, f'Daten falsch eingegeben!') + context['agencyform'] = AgencyUpdateForm(instance=request.user.profile.agency) + return render(request, 'dasettings/settings.html', context) + +@login_required +def SettingsAgencyModuls(request, context): + if request.POST.get("form_type") == "agencymodform": + agencymoduleform = AgencyModulsForm(request.POST, instance=request.user.profile.agency) + if agencymoduleform.is_valid(): + agencymoduleform.save() + context['modulform'] = AgencyModulsForm(instance=request.user.profile.agency) + messages.success(request, f'Moduleinstellungen aktualisiert!') + return render(request, 'dasettings/settings.html', context) + else: + context['modulform'] = AgencyModulsForm(instance=request.user.profile.agency) + messages.success(request, f'Fehler beim aktualisieren! Bitte wenden Sie sich an den Support.') + return render(request, 'dasettings/settings.html', context) + +''' + +Hier werden die Profilinfos des User zurückgesetzt; Parameter kommen von Settings() + +- Email +- Passwort aktualisieren + +''' +@login_required +def SettingsProfilManagement(request, context): + # Check, which form + # USERFORM + if request.POST.get("form_type") == "userform": + userform = UsersSelfChangeForm(request.POST, instance=request.user) + if userform.is_valid(): + userform.save() + messages.success(request, f'E-Mailadresse aktualisiert!') + passwordform = PasswordChangeForm(request.user) + context['userform'] = userform + context['passwordform'] = passwordform + return render(request, 'dasettings/settings.html', context) + else: + messages.success(request, f'Keine E-Mailadresse eingegeben oder E-Mail bereits vorhanden!') + passwordform = PasswordChangeForm(request.user) + userform = UsersSelfChangeForm(instance=request.user) + context['userform'] = userform + context['passwordform'] = passwordform + return render(request, 'dasettings/settings.html', context) + # PASSWORDFORM + elif request.POST.get("form_type") == "passwordform": + passwordform = PasswordChangeForm(request.user, request.POST) + if passwordform.is_valid(): + passwordform.save() + update_session_auth_hash(request, request.user) + userform = UsersSelfChangeForm(instance=request.user) + context['userform'] = userform + context['passwordform'] = passwordform + messages.success(request, f'Passwort aktualisiert!') + return render(request, 'dasettings/settings.html', context) + else: + messages.success(request, f'Passwort falsch eingegeben!') + passwordform = PasswordChangeForm(request.user) + userform = UsersSelfChangeForm(instance=request.user) + context['userform'] = userform + context['passwordform'] = passwordform + return render(request, 'dasettings/settings.html', context) + +@login_required +def SettingsAjaxRouter(request): + success = False + data = {} + # UPDATE NOTIFICATIONS BY FIELDNAME AND NEW VALUE + if request.method == 'GET' and request.GET['action'] == "update_notifications" : + success = False + new_stat = request.GET['new_stat'] + field_to_change = getattr(request.user.profile, request.GET['fieldname']) + if(field_to_change or not field_to_change): + if(new_stat == "1"): + setattr(request.user.profile, request.GET['fieldname'], True) + else: + setattr(request.user.profile, request.GET['fieldname'], False) + request.user.profile.save() + success = True + # UPDATE TOOLTUP + elif request.method == 'GET' and request.GET['action'] == "change_showtooltips" : + newtooltipvalue = False + user = User.objects.get(pk=request.user.pk, profile__agency=request.user.profile.agency) + if user.profile.showtooltips: + user.profile.showtooltips = False + else: + user.profile.showtooltips = True + newtooltipvalue = True + user.save() + success = True + data = {'newttvalue' : newtooltipvalue} + # UPDATE AGENCYJOB + elif request.method == 'GET' and request.GET['action'] == "update_agencyfunc" : + job_id = request.GET['id'] + job_value = request.GET['newvalue'] + tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency) + tempjob.name = job_value + tempjob.save() + success = True + # DELETE AGENVY JOB FUNC - RETURN ONLY NAME FOR CONFIRM + elif request.method == 'GET' and request.GET['action'] == "get_agencyfunc" : + job_id = request.GET['id'] + tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency) + data = {"funcname" : tempjob.name} + success = True + # DELETE FINAL AGECY JOB + elif request.method == 'GET' and request.GET['action'] == "delete_agencyfunc" : + job_id = request.GET['id'] + tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency) + tempjob.delete() + success = True + elif request.method == 'GET' and request.GET['action'] == "add_agencyfunc" : + tempjob = AgencyJob(name="", agency=request.user.profile.agency) + tempjob.save() + data = {"new_id" : tempjob.pk} + success = True + # GRUPPENAMEN AKTUALISIEREN + elif request.method == 'GET' and request.GET['action'] == "update_groupname" : + group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + if(checkForGroupName(request, request.GET['newvalue'])): + group.agencygroupname = request.GET['newvalue'] + group.save() + data = {"newvalue" : group.agencygroupname} + success = True + else: + success = False + # GRUPPENNAMEN HOLEN + elif request.method == 'GET' and request.GET['action'] == "get_groupname" : + group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + data = {"groupname" : group.agencygroupname} + success = True + elif request.method == 'GET' and request.GET['action'] == "add_group" : + if(checkForGroupName(request, request.GET['newvalue'])): + tempgroup = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8)) + tempgroup.save() + tempgroup_ag = AgencyGroup(savefordel=False, group=tempgroup, agency=request.user.profile.agency, agencygroupname=request.GET['newvalue']) + tempgroup_ag.save() + success = True + data = {"group_id" : tempgroup_ag.pk, "group_name" : tempgroup_ag.agencygroupname} + else: + success = False + elif request.method == 'GET' and request.GET['action'] == "delete_group" : + groupag = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + group_to_del = groupag.group + group_to_del.delete() + success = True + # PERMISSIONS ON GROUP! + elif request.method == 'GET' and request.GET['action'] == "change_perm_group" : + success = True + group_id = request.GET['id'] + perm_name = request.GET['perm'] + val = request.GET['val'] + aggroup = AgencyGroup.objects.get(pk=group_id, agency=request.user.profile.agency) + # CHECK IF REQUESTED USER IS IN THIS AGENCY + if(request.user.profile.agency.pk == aggroup.agency.pk): + if(val == "true"): + tempperm = Permission.objects.get(codename=perm_name) + aggroup.group.permissions.add(tempperm) + else: + tempperm = Permission.objects.get(codename=perm_name) + aggroup.group.permissions.remove(tempperm) + else: + success = False + # REMOVE USER FROM GROUP + elif request.method == 'GET' and request.GET['action'] == "remove_user_from_group" : + success = True + groupid = request.GET['groupid'] + userid = request.GET['userid'] + aggroup = AgencyGroup.objects.get(pk=groupid, agency=request.user.profile.agency) + usertoremove = User.objects.get(pk=userid, profile__agency=request.user.profile.agency) + # CHECK IF REQUESTED USER IS IN THIS AGENCY + if(request.user.profile.agency.pk == aggroup.agency.pk): + if aggroup.group in usertoremove.groups.all(): + aggroup.group.user_set.remove(usertoremove) + + data = {"userid" : usertoremove.pk, "groupid" : aggroup.pk, "user_fname" : usertoremove.first_name, "user_lname" : usertoremove.last_name} + else: + success = False + # ADD USER TO GROUP + elif request.method == 'GET' and request.GET['action'] == "add_user_to_group" : + success = True + groupid = request.GET['groupid'] + userid = request.GET['userid'] + aggroup = AgencyGroup.objects.get(pk=groupid, agency=request.user.profile.agency) + usertoadd = User.objects.get(pk=userid, profile__agency=request.user.profile.agency) + # CHECK IF REQUESTED USER IS IN THIS AGENCY + if(request.user.profile.agency.pk == aggroup.agency.pk): + aggroup.group.user_set.add(usertoadd) + data = {"userid" : usertoadd.pk, "groupid" : aggroup.pk, "user_fname" : usertoadd.first_name, "user_lname" : usertoadd.last_name} + else: + success = False + # AREA + # AREANAMEN HOLEN + elif request.method == 'GET' and request.GET['action'] == "get_areaname" : + area = Areas.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + data = {"areaname" : area.name, "areacolor" : area.color} + success = True + # ARENAMEN UPDATE + elif request.method == 'GET' and request.GET['action'] == "update_areaname" : + area = Areas.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + area.name = request.GET['newvalue'] + area.color = request.GET['color'] + area.save() + data = {"newvalue" : area.name, "color" : area.color} + success = True + # ADD AREA + elif request.method == 'GET' and request.GET['action'] == "add_area" : + area = Areas(created_area_by=request.user, agency=request.user.profile.agency, name=request.GET["newvalue"], color=request.GET['color']) + area.save() + success = True + # REMOVE AREA + elif request.method == 'GET' and request.GET['action'] == "remove_area" : + Areas(pk=request.GET['id']).delete() + success = True + # ADD TASK + elif request.method == 'GET' and request.GET['action'] == "add_task" : + task = Tasks(created_area_by=request.user, area=Areas.objects.get(pk=request.GET['areaid']), agency=request.user.profile.agency, name=request.GET["newvalue"]) + task.save() + taskcreator_fullname = task.created_area_by.first_name + " " + task.created_area_by.last_name + data = {"name" : task.name, "newtaskid" : task.pk, "areaname" : task.area.name, "taskcreator_fullname" : taskcreator_fullname, "createdate" : task.created_area_date.strftime("%d. %B %Y")} + success = True + # TASKNAME VISIBLE UND USERS HOLEN + elif request.method == 'GET' and request.GET['action'] == "get_taskname" : + task = Tasks.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + # User still in Area + # Get all Users from same Agency which are NOT in context_added_users + added_users = task.usersfield.all() + addus = {} + posus = {} + i = 0 + # GET ADDED USERS + for us in added_users: + addus.update({ i : {"fullname" : us.first_name + " " + us.last_name, "userid" : us.pk}}) + i += 1 + + # GET POSSIBLE TO ADD USERS + k = 0 + possible_users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk).exclude(pk__in=added_users) + print(possible_users) + for us in possible_users: + posus.update({ k : {"fullname" : us.first_name + " " + us.last_name, "userid" : us.pk}}) + k += 1 + print(posus) + data = {"taskname" : task.name, "visible" : task.visible, "added_users" : addus, "addedl" : i, "possl" : k, "possible_users" : posus, "taskarea" : task.area.pk} + success = True + # REMOVE Task + elif request.method == 'GET' and request.GET['action'] == "remove_task" : + Tasks.objects.get(pk=request.GET['id'], agency=request.user.profile.agency).delete() + success = True + # UPDATE TASK VISIBLE + elif request.method == 'GET' and request.GET['action'] == "update_visible_taskname" : + task = Tasks.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) + if(task.visible): + task.visible = False; + else: + task.visible = True; + task.save() + success = True + # UPDATE TASKNAME + elif request.method == 'GET' and request.GET['action'] == "change_taskname" : + task = Tasks.objects.get(pk=request.GET['id']) + task.name = request.GET["newvalue"] + data = {"newvalue" : task.name} + newareaid = request.GET["newareaid"] + standardsmoved = False + if int(task.area.pk) != int(newareaid): + standardsmoved = True + newareaobj = Areas.objects.get(pk=newareaid, agency=request.user.profile.agency) + Standards.objects.filter(agency=request.user.profile.agency, area=task.area).update(area=newareaobj) + task.area = newareaobj + task.save() + data = {"newvalue" : task.name, "smoved" : standardsmoved} + success = True + else: + success = False + return JsonResponse({"success" : success, "data" : data}) + + +''' + UserProfileUpdate + + unterscheidet zwischen newuser=0 --> PROFIL AKTUALISIEREN + und newuser=1 --> PROFIL Neu speichern + +''' +@login_required +def UserProfileUpdate(request, pk, newuser=0): + usertochange = User.objects.get(pk=pk) + user_fullname = usertochange.first_name + " " + usertochange.last_name + parentuser = "" + if(usertochange.profile.parent != None): + parentuser = usertochange.profile.parent.pk + + if request.method == 'POST': + if 'image' in request.FILES: + usertochange.profile.image = request.FILES['image'] + formtosave = False + + formtosave = UserProfileForm(request.POST, instance=usertochange.profile) + + if formtosave.is_valid(): + try: + usertochange.profile.parent = User.objects.get(pk=request.POST['usertoparent'], profile__agency=request.user.profile.agency) + usertochange.save() + except Exception as e: + usertochange.profile.parent = None + usertochange.save() + + formtosave.save() + messages.success(request, f'Profil gespeichert!') + return redirect('dasettings') + else: + messages.success(request, f'Fehlerhafte Eingabe!') + context = { + 'active_link' : 'dasettings', + 'user_fullname' : user_fullname, + 'newuser' : newuser, + 'vieweduser' : usertochange.pk, + 'parentuser' : parentuser, + 'mail' : usertochange.email, + 'imagelink' : usertochange.profile.get_photo_url, + 'profileform' : UserProfileForm(instance=usertochange.profile), + 'usertoparent' : User.objects.filter(profile__agency__pk=usertochange.profile.agency.pk, profile__visible=True) + } + return render(request, 'dasettings/user_usprof.html', context) + else: + + context = { + 'active_link' : 'dasettings', + 'user_fullname' : user_fullname, + 'newuser' : newuser, + 'mail' : usertochange.email, + 'vieweduser' : usertochange.pk, + 'imagelink' : usertochange.profile.get_photo_url, + 'profileform' : UserProfileForm(instance=usertochange.profile), + 'parentuser' : parentuser, + 'usertoparent' : User.objects.filter(profile__agency__pk=usertochange.profile.agency.pk, profile__visible=True), + 'agencygroups' : AgencyGroup.objects.filter(agency__pk=usertochange.profile.agency.pk).order_by("agencygroupname") + } + return render(request, 'dasettings/user_usprof.html', context) + +# View zur Veränderung der Stammdaten des Benutzers +@login_required +def UserChangeMain(request, pk): + usertochange = User.objects.get(pk=pk, profile__agency=request.user.profile.agency) + user_fullname = usertochange.first_name + " " + usertochange.last_name + if request.method == 'POST': + formtosave = UserNewUserForm(request.POST, instance=usertochange) + if formtosave.is_valid(): + formtosave.save() + formtosave.save() + messages.success(request, f'Stammdaten aktualisiert!') + return redirect('dasettings') + else: + messages.success(request, f'Fehlerhafte Eingabe! Mailadresse bereits vorhanden!') + context = { + 'active_link' : 'dasettings', + 'user_fullname' : user_fullname, + 'userform' : UserNewUserForm(request.POST, instance=usertochange), + } + return render(request, 'dasettings/user_changemaindata.html', context) + else: + context = { + 'active_link' : 'dasettings', + 'user_fullname' : user_fullname, + 'userform' : UserNewUserForm(instance=usertochange), + } + return render(request, 'dasettings/user_changemaindata.html', context) + +# Method for first User-Creation-Step +@login_required +def NewUserFirstStep(request): + + context = { + 'active_link' : 'dasettings' + } + + if request.method == 'POST': + newuserform = UserNewUserForm(request.POST) + if newuserform.is_valid(): + if(request.POST.get("sendmailnewuser")): + send_mail( + request.user.profile.agency.name + ' Account', + 'Hallo ' + newuserform.cleaned_data.get('first_name') + ' ' + newuserform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://digitale-agentur.com/password-reset/ ein Passwort.', + 'support@digitale-agentur.com', + [newuserform.cleaned_data.get('email')], + html_message=msg_html, + fail_silently=False, + ) + newuser = newuserform.save(commit=False) + newuser.username = newuser.email + newprofile = Profile(agency=request.user.profile.agency, parent=None) + newprofile.save() + newuser.profile = newprofile + newuser.save() + newuser_id = newuser.id + messages.success(request, f'Benutzer angelegt!') + getadmingroup = AgencyGroup.objects.filter(savefordel=True, is_admin=False, agency=request.user.profile.agency) + for g in getadmingroup: + g.group.user_set.add(newuser) + return redirect('/dasettings/usprof/'+str(newuser_id)+'/1') + else: + messages.success(request, f'Daten falsch eingegeben!') + context['newuserform'] = UserNewUserForm(request.POST) + return render(request, 'dasettings/user_newuser_step1.html', context) + + # Returning the data from database for normal-loading Settings + else: + newuserform = UserNewUserForm() + context.update({'newuserform' : newuserform}) + + return render(request, 'dasettings/user_newuser_step1.html', context) diff --git a/notificsys/__init__.py b/notificsys/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/notificsys/__pycache__/__init__.cpython-38.pyc b/notificsys/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..9d95a1e Binary files /dev/null and b/notificsys/__pycache__/__init__.cpython-38.pyc differ diff --git a/notificsys/__pycache__/admin.cpython-38.pyc b/notificsys/__pycache__/admin.cpython-38.pyc new file mode 100644 index 0000000..af1266e Binary files /dev/null and b/notificsys/__pycache__/admin.cpython-38.pyc differ diff --git a/notificsys/__pycache__/apps.cpython-38.pyc b/notificsys/__pycache__/apps.cpython-38.pyc new file mode 100644 index 0000000..e32efbe Binary files /dev/null and b/notificsys/__pycache__/apps.cpython-38.pyc differ diff --git a/notificsys/__pycache__/models.cpython-38.pyc b/notificsys/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000..b86a6f2 Binary files /dev/null and b/notificsys/__pycache__/models.cpython-38.pyc differ diff --git a/notificsys/__pycache__/urls.cpython-38.pyc b/notificsys/__pycache__/urls.cpython-38.pyc new file mode 100644 index 0000000..73da4a3 Binary files /dev/null and b/notificsys/__pycache__/urls.cpython-38.pyc differ diff --git a/notificsys/__pycache__/views.cpython-38.pyc b/notificsys/__pycache__/views.cpython-38.pyc new file mode 100644 index 0000000..704ac26 Binary files /dev/null and b/notificsys/__pycache__/views.cpython-38.pyc differ diff --git a/notificsys/admin.py b/notificsys/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/notificsys/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/notificsys/apps.py b/notificsys/apps.py new file mode 100644 index 0000000..fbcb947 --- /dev/null +++ b/notificsys/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class NotificsysConfig(AppConfig): + name = 'notificsys' diff --git a/notificsys/migrations/0001_initial.py b/notificsys/migrations/0001_initial.py new file mode 100644 index 0000000..7f6b942 --- /dev/null +++ b/notificsys/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 3.0.2 on 2020-02-09 15:35 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='UserNotification', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('notificationtype', models.CharField(blank=True, max_length=60)), + ('wassend', models.BooleanField(default=False)), + ('wasviewed', models.BooleanField(default=False)), + ('created', models.DateTimeField(default=django.utils.timezone.now)), + ('notificationtext', models.CharField(blank=True, max_length=200)), + ('fromuser', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='fromuser', to=settings.AUTH_USER_MODEL)), + ('touser', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='touser', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/notificsys/migrations/0002_remove_usernotification_fromuser.py b/notificsys/migrations/0002_remove_usernotification_fromuser.py new file mode 100644 index 0000000..e5749d1 --- /dev/null +++ b/notificsys/migrations/0002_remove_usernotification_fromuser.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.2 on 2020-02-09 16:06 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('notificsys', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='usernotification', + name='fromuser', + ), + ] diff --git a/notificsys/migrations/0003_auto_20200209_1620.py b/notificsys/migrations/0003_auto_20200209_1620.py new file mode 100644 index 0000000..35f118b --- /dev/null +++ b/notificsys/migrations/0003_auto_20200209_1620.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.2 on 2020-02-09 16:20 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('notificsys', '0002_remove_usernotification_fromuser'), + ] + + operations = [ + migrations.AlterField( + model_name='usernotification', + name='touser', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/notificsys/migrations/0004_usernotification_elementid.py b/notificsys/migrations/0004_usernotification_elementid.py new file mode 100644 index 0000000..8fea905 --- /dev/null +++ b/notificsys/migrations/0004_usernotification_elementid.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.2 on 2020-02-09 21:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notificsys', '0003_auto_20200209_1620'), + ] + + operations = [ + migrations.AddField( + model_name='usernotification', + name='elementid', + field=models.IntegerField(blank=True, default=None, null=True), + ), + ] diff --git a/notificsys/migrations/__init__.py b/notificsys/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/notificsys/migrations/__pycache__/0001_initial.cpython-38.pyc b/notificsys/migrations/__pycache__/0001_initial.cpython-38.pyc new file mode 100644 index 0000000..69e0d0f Binary files /dev/null and b/notificsys/migrations/__pycache__/0001_initial.cpython-38.pyc differ diff --git a/notificsys/migrations/__pycache__/0002_remove_usernotification_fromuser.cpython-38.pyc b/notificsys/migrations/__pycache__/0002_remove_usernotification_fromuser.cpython-38.pyc new file mode 100644 index 0000000..f828d87 Binary files /dev/null and b/notificsys/migrations/__pycache__/0002_remove_usernotification_fromuser.cpython-38.pyc differ diff --git a/notificsys/migrations/__pycache__/0003_auto_20200209_1620.cpython-38.pyc b/notificsys/migrations/__pycache__/0003_auto_20200209_1620.cpython-38.pyc new file mode 100644 index 0000000..3f9dd1b Binary files /dev/null and b/notificsys/migrations/__pycache__/0003_auto_20200209_1620.cpython-38.pyc differ diff --git a/notificsys/migrations/__pycache__/0004_usernotification_elementid.cpython-38.pyc b/notificsys/migrations/__pycache__/0004_usernotification_elementid.cpython-38.pyc new file mode 100644 index 0000000..5afb99d Binary files /dev/null and b/notificsys/migrations/__pycache__/0004_usernotification_elementid.cpython-38.pyc differ diff --git a/notificsys/migrations/__pycache__/__init__.cpython-38.pyc b/notificsys/migrations/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..5006479 Binary files /dev/null and b/notificsys/migrations/__pycache__/__init__.cpython-38.pyc differ diff --git a/notificsys/models.py b/notificsys/models.py new file mode 100644 index 0000000..ce09657 --- /dev/null +++ b/notificsys/models.py @@ -0,0 +1,27 @@ +from django.db import models +from django.utils import timezone +from datetime import datetime, timedelta +from django.contrib.auth.models import User +# Create your models here. +''' + + class UserNotification + + Model für Benachrichtigungen + +''' +class UserNotification(models.Model): + + # Wenn der User gelöscht wird, wird auch die Notification entfernt + touser = models.ForeignKey(User, on_delete=models.CASCADE) + notificationtype = models.CharField(max_length=60, blank=True) + # Notifcaton was send or not (for sound-update at the client) + wassend = models.BooleanField(default=False) + # Wurde gesehen + wasviewed = models.BooleanField(default=False) + created = models.DateTimeField(default=timezone.now) + elementid = models.IntegerField(default=None, null=True, blank=True) + # Eventuell automatisches Lösch-Datum + #willdeleted = models.DateTimeField(default=timezone.now()+timedelta(days=30)) + # Textcontent + notificationtext = models.CharField(max_length=200, blank=True) \ No newline at end of file diff --git a/notificsys/templates/notificsys/allnotifications.html b/notificsys/templates/notificsys/allnotifications.html new file mode 100644 index 0000000..790db6e --- /dev/null +++ b/notificsys/templates/notificsys/allnotifications.html @@ -0,0 +1,87 @@ +{% extends "users/base.html" %} +{% block content %} +
+

Alle Benachrichtigungen

+
+ + {% for notification in usernotifications %} + +
+
+ +

+ {% if notification.notificationtype == "agencynews" %} + + {{notification.notificationtext}} +
+ {% else %} + {{notification.notificationtext}}
+ {% endif %} + Am {{notification.created}} +

+
+ {% endfor %} +
+ + + + + +{% endblock content %} \ No newline at end of file diff --git a/notificsys/templates/notificsys/notification_mail.html b/notificsys/templates/notificsys/notification_mail.html new file mode 100644 index 0000000..a7c7c9d --- /dev/null +++ b/notificsys/templates/notificsys/notification_mail.html @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + +
+

+ +
+
+

Digitale Agentur | Benachrichtigung

+
+
+
+

Hallo {{username}},

+

{{notificationtext}}

+

Weitere Informationen erhalten Sie von Ihrem Agenturleiter. Vielen Dank, dass Sie die Plattform Digitale Agentur nutzen!

+

Mit freundlichen Grüßen

+

Ihr Team von Digitale Agentur

+
+
+

+ +
+
+ +
+
+ +
+ + + \ No newline at end of file diff --git a/notificsys/tests.py b/notificsys/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/notificsys/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/notificsys/urls.py b/notificsys/urls.py new file mode 100644 index 0000000..c195aac --- /dev/null +++ b/notificsys/urls.py @@ -0,0 +1,11 @@ +from django.urls import path +from .views import CheckNotifications, GetBasicNotifications, ShowAllNotifications, ChangeNotificationsToViewed, delAllNotification, delSingleNotification + +urlpatterns = [ + path('checknotifications/', CheckNotifications, name='checknotifications'), + path('getnotifications/', GetBasicNotifications, name='getnotifications'), + path('showallnotificaions/', ShowAllNotifications, name='showallnotificaions'), + path('newnotificationsviewed/', ChangeNotificationsToViewed, name='newnotificationsviewed'), + path('delsingle/', delSingleNotification, name='delsinglenotification'), + path('delall/', delAllNotification, name='delall'), +] diff --git a/notificsys/views.py b/notificsys/views.py new file mode 100644 index 0000000..812a1c7 --- /dev/null +++ b/notificsys/views.py @@ -0,0 +1,108 @@ +from django.shortcuts import render +from django.http import HttpResponseRedirect,HttpResponse, JsonResponse +from .models import UserNotification +from django.views import generic +from django.contrib.auth.decorators import login_required +# Create your views here. + +@login_required +def CheckNotifications(request): + if request.method == 'GET': + if request.GET['action'] == 'checknotifications': + #print("HERE WE ARE") + unknownnotification = UserNotification.objects.filter(touser__pk=request.user.pk, wassend=False).order_by('-created')[:5] + + data = {}; + i = 0 + for notify in unknownnotification: + + elelink = "notifications/showallnotificaions/" + if notify.notificationtype == "agencynews": + elelink = "news/news/" + str(notify.elementid) + "/single" + + formatedDate = notify.created.strftime("%d.%m.20%y um %H:%M") + + data.update({ i : { + "not_id" : notify.pk, + "type": notify.notificationtype, + "date" : formatedDate, + "text" : notify.notificationtext, + "elelink" : elelink + }}) + i += 1 + notify.save() + + return JsonResponse({"unknownnotification" : data}) + +# Create your views here. +@login_required +def GetBasicNotifications(request): + if request.method == 'GET': + if request.GET['action'] == 'oldnotifications': + #print("HERE WE ARE") + oldnotifications = UserNotification.objects.filter(touser__pk=request.user.pk, wassend=True, wasviewed=False).order_by('-created')[:5] + + data = {}; + i = 0 + for notify in oldnotifications: + + elelink = "notifications/showallnotificaions/" + if notify.notificationtype == "agencynews": + elelink = "news/news/" + str(notify.elementid) + "/single" + + formatedDate = notify.created.strftime("%d.%m.20%y um %H:%M") + + data.update({ i : { + "not_id" : notify.pk, + "type": notify.notificationtype, + "date" : formatedDate, + "text" : notify.notificationtext, + "elelink" : elelink + }}) + i += 1 + notify.save() + + return JsonResponse({"oldnotifications" : data}) + +@login_required +def ShowAllNotifications(request): + context ={} + context["usernotifications"] = UserNotification.objects.filter(touser__pk=request.user.pk).order_by('-created') + return render(request, "notificsys/allnotifications.html", context) + +@login_required +def ChangeNotificationsToViewed(request): + if request.method == 'GET': + if request.GET['action'] == 'newnotificationsviewed': + oldnotifications = UserNotification.objects.filter(touser__pk=request.user.pk, wassend=False, wasviewed=False).order_by('-created')[:5] + data = {}; + i = 0 + for notify in oldnotifications: + formatedDate = notify.created.strftime("%d.%m.20%y um %H:%M") + data.update({ i : { + "not_id" : notify.pk, + "type": notify.notificationtype, + "date" : formatedDate, + "text" : notify.notificationtext + }}) + i += 1 + notify.wassend = True + notify.save() + return JsonResponse({}) + +@login_required +def delSingleNotification(request): + if request.method == 'GET': + if request.GET['action'] == 'delsingle': + todelnotification = UserNotification.objects.get(pk=request.GET['todelid']) + todelnotification.delete() + + return JsonResponse({}) + +@login_required +def delAllNotification(request): + if request.method == 'GET': + if request.GET['action'] == 'delall': + todelnotification = UserNotification.objects.filter(touser__pk=request.user.pk).delete() + + return JsonResponse({}) \ No newline at end of file diff --git a/re.txt b/re.txt new file mode 100644 index 0000000..01b20d0 --- /dev/null +++ b/re.txt @@ -0,0 +1,25 @@ +Django==3.0.2 +django-appconf==1.0.3 +django-bootstrap-datepicker-plus==3.0.5 +django-cleanup==4.0.0 +django-colorful==1.3 +django-crispy-forms==1.8.1 +django-image-cropping==1.3.0 +django-js-asset==1.2.2 +django-jsonfield==1.3.1 +django-mathfilters==0.4.0 +django-mptt==0.11.0 +django-polymorphic==2.0.3 +django-redis==4.11.0 +django-staticfiles==1.2.1 +django-summernote==0.8.11.6 +django-templatetags==1.1 +django-user-agents==0.4.0 +djangorestframework==3.11.0 +easy-thumbnails==2.7 +mysqlclient==1.4.6 +Pillow==6.2.1 +requests==2.22.0 +requests-oauthlib==1.3.0 +user-agents==2.1 +webcolors==1.10 diff --git a/standards/templates/standards/standards_noentrie.html b/standards/templates/standards/standards_noentrie.html new file mode 100644 index 0000000..45453ac --- /dev/null +++ b/standards/templates/standards/standards_noentrie.html @@ -0,0 +1,7 @@ +{% extends "users/base.html" %} +{% block content %} +
+

Auf diesen Standard haben Sie keinen Zugriff!

+
+
+{% endblock %} \ No newline at end of file diff --git a/users/static/users/css/colorPick.css b/users/static/users/css/colorPick.css new file mode 100644 index 0000000..9554afb --- /dev/null +++ b/users/static/users/css/colorPick.css @@ -0,0 +1,88 @@ +/*! +* +* ColorPick jQuery plugin +* https://github.com/philzet/ColorPick.js +* +* Copyright (c) 2017-2019 Phil Zet (a.k.a. Phil Zakharchenko) +* Licensed under the MIT License +* +*/ + +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 400; + src: local("Open Sans"), local("OpenSans"), + url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff) + format("woff"); +} +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 700; + src: local("Open Sans Bold"), local("OpenSans-Bold"), + url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzKRDOzjiPcYnFooOUGCOsRk.woff) + format("woff"); +} + +#colorPick * { + -webkit-transition: all linear 0.2s; + -moz-transition: all linear 0.2s; + -ms-transition: all linear 0.2s; + -o-transition: all linear 0.2s; + transition: all linear 0.2s; +} + +#colorPick { + background: rgba(255, 255, 255, 0.85); + -webkit-backdrop-filter: blur(15px); + position: absolute; + border-radius: 5px; + box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.2); + padding: 15px; + font-family: "Open Sans", sans-serif; + width: 140px; +} + +#colorPick span { + font-size: 9pt; + text-transform: uppercase; + font-weight: bold; + color: #bbb; + margin-bottom: 5px; + display: block; + clear: both; +} + +.customColorHash { + border-radius: 5px; + height: 23px; + width: 122px; + margin: 1px 4px; + padding: 0 4px; + border: 1px solid #babbba; + outline: none; +} +.customColorHash.error { + border-color: #ff424c; + color: #ff424c; +} + +.colorPickButton { + border-radius: 5px; + width: 20px; + height: 20px; + margin: 0px 3px; + cursor: pointer; + display: inline-block; + border: thin solid #eee; +} + +.colorPickButton:hover { + transform: scale(1.1); +} + +.colorPickDummy { + background: #fff; + border: 1px dashed #bbb; +} diff --git a/users/static/users/css/jsLists.css b/users/static/users/css/jsLists.css new file mode 100644 index 0000000..10ba2ee --- /dev/null +++ b/users/static/users/css/jsLists.css @@ -0,0 +1,24 @@ +*, *:before, *:after {box-sizing: border-box;} +ul, ol {margin: 0; padding: 0;} +li {list-style: none; line-height: 1.6rem;} + +/* List styling */ +.jslists{ + font-size: 1.3rem; + font-family: Arial, Helvetica, sans-serif; +} +.jslist-ul, .jslist-ol, .jslist-li {margin-left: 12px;} /* Unordered lists */ +.jsl-collapsed {display: none;} +.jsl-list-closed { + float: left; + clear: both; + margin: 2px 4px 2px 0px; + width: 18px; + height: 18px; + cursor: pointer; + background-image: url('data:image/svg+xml;utf8,'); + background-repeat: no-repeat; + background-position: center; +} +.jsl-open {display: block;} +.jsl-list-open {background-image: url('data:image/svg+xml;utf8,');} \ No newline at end of file diff --git a/users/static/users/js/colorPick.js b/users/static/users/js/colorPick.js new file mode 100644 index 0000000..8473191 --- /dev/null +++ b/users/static/users/js/colorPick.js @@ -0,0 +1,163 @@ +/*! +* +* ColorPick jQuery plugin +* https://github.com/philzet/ColorPick.js +* +* Copyright (c) 2017-2019 Phil Zet (a.k.a. Phil Zakharchenko) +* Licensed under the MIT License +* +*/ +(function( $ ) { + + $.fn.colorPick = function(config) { + + return this.each(function() { + new $.colorPick(this, config || {}); + }); + + }; + + $.colorPick = function (element, options) { + options = options || {}; + this.options = $.extend({}, $.fn.colorPick.defaults, options); + if(options.str) { + this.options.str = $.extend({}, $.fn.colorPick.defaults.str, options.str); + } + $.fn.colorPick.defaults = this.options; + this.color = this.options.initialColor.toUpperCase(); + this.element = $(element); + + var dataInitialColor = this.element.data('initialcolor'); + if (dataInitialColor) { + this.color = dataInitialColor; + this.appendToStorage(this.color); + } + + var uniquePalette = []; + $.each($.fn.colorPick.defaults.palette.map(function(x){ return x.toUpperCase() }), function(i, el){ + if($.inArray(el, uniquePalette) === -1) uniquePalette.push(el); + }); + + this.palette = uniquePalette; + + return this.element.hasClass(this.options.pickrclass) ? this : this.init(); + }; + + $.fn.colorPick.defaults = { + 'initialColor': '#3498db', + 'paletteLabel': 'Farbauswahl', + 'allowRecent': true, + 'recentMax': 5, + 'allowCustomColor': false, + 'palette': ["#1abc9c", "#16a085", "#2ecc71", "#27ae60", "#3498db", "#2980b9", "#9b59b6", "#8e44ad", "#34495e", "#2c3e50", "#f1c40f", "#f39c12", "#e67e22", "#d35400", "#e74c3c", "#c0392b", "#ecf0f1", "#bdc3c7", "#95a5a6", "#7f8c8d"], + 'onColorSelected': function() { + this.element.css({'backgroundColor': this.color, 'color': this.color}); + } + }; + + $.colorPick.prototype = { + + init : function(){ + + var self = this; + var o = this.options; + + $.proxy($.fn.colorPick.defaults.onColorSelected, this)(); + + this.element.click(function(event) { + event.preventDefault(); + self.show(event.pageX, event.pageY); + + $('.customColorHash').val(self.color); + + $('.colorPickButton').click(function(event) { + self.color = $(event.target).attr('hexValue'); + self.appendToStorage($(event.target).attr('hexValue')); + self.hide(); + $.proxy(self.options.onColorSelected, self)(); + return false; + }); + $('.customColorHash').click(function(event) { + return false; + }).keyup(function (event) { + var hash = $(this).val(); + if (hash.indexOf('#') !== 0) { + hash = "#"+hash; + } + if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hash)) { + self.color = hash; + self.appendToStorage(hash); + $.proxy(self.options.onColorSelected, self)(); + $(this).removeClass('error'); + } else { + $(this).addClass('error'); + } + }); + + return false; + }).blur(function() { + self.element.val(self.color); + $.proxy(self.options.onColorSelected, self)(); + self.hide(); + return false; + }); + + $(document).on('click', function(event) { + self.hide(); + return true; + }); + + return this; + }, + + appendToStorage: function(color) { + if ($.fn.colorPick.defaults.allowRecent === true) { + var storedColors = JSON.parse(localStorage.getItem("colorPickRecentItems")); + if (storedColors == null) { + storedColors = []; + } + if ($.inArray(color, storedColors) == -1) { + storedColors.unshift(color); + storedColors = storedColors.slice(0, $.fn.colorPick.defaults.recentMax) + localStorage.setItem("colorPickRecentItems", JSON.stringify(storedColors)); + } + } + }, + + show: function(left, top) { + + $("#colorPick").remove(); + + $("#mainmodalArea").append(''); + jQuery.each(this.palette, function (index, item) { + $("#colorPick").append('
'); + }); + if ($.fn.colorPick.defaults.allowCustomColor === true) { + $("#colorPick").append(''); + } + if ($.fn.colorPick.defaults.allowRecent === true) { + $("#colorPick").append('Kürzlich'); + if (JSON.parse(localStorage.getItem("colorPickRecentItems")) == null || JSON.parse(localStorage.getItem("colorPickRecentItems")) == []) { + $("#colorPick").append('
'); + } else { + jQuery.each(JSON.parse(localStorage.getItem("colorPickRecentItems")), function (index, item) { + $("#colorPick").append('
'); + if (index == $.fn.colorPick.defaults.recentMax-1) { + return false; + } + }); + } + } + $("#colorPick").fadeIn(200); + }, + + hide: function() { + $( "#colorPick" ).fadeOut(200, function() { + $("#colorPick").remove(); + return this; + }); + }, + + }; + +}( jQuery )); diff --git a/users/static/users/js/jsLists.js b/users/static/users/js/jsLists.js new file mode 100644 index 0000000..9f53550 --- /dev/null +++ b/users/static/users/js/jsLists.js @@ -0,0 +1,181 @@ +/* + * JSLists v0.4.5 + * © 2016 George Duff + * + * Release date: 01/06/2016 + * The MIT License (MIT) + * Copyright (c) 2016 George Duff + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// TO DO LIST - Will get round to most of them at some point! +// Add folder & file icons dynamically from param +// Collapse All & Open All are ropey at best! +// Add a search function +// Make the margins user definable +// Add support for UL & OL + +var blackCircle = '● '; +var openCircle = '◎ '; + +(function() { + "use strict"; + function define_JSLists() { + var JSLists = {}; + + var JSLists_Error = function(error, alertType) { + console.log(error); + } + var getUl = function(){ + return document.getElementsByTagName("UL"); + }; + + var getOl = function(){ + return document.getElementsByTagName("OL"); + }; + + var getAllLists = function(){ + var olLists = Array.prototype.slice.call(document.getElementsByTagName("UL")), + ulLists = Array.prototype.slice.call(document.getElementsByTagName("OL")) + var gLists = olLists.concat(ulLists); + return gLists; + } + + JSLists.searchList = function(listId, searchTerm) { + var i, j, lilNodes, liItems = document.getElementsByTagName("LI"); + for(i=0; i 0) { + curElem = document.getElementById(listItems[i].id); + ulCount = document.getElementById(listItems[i].id).getElementsByTagName("UL"); + if(ulCount.length > 0){ + for(j=0; j 0) { //There is a nested UL in this LI element, now find the position of the UL + for(j=0; j +

Agentur {{ request.user.profile.agency.name }}

+
+
+
Inhaber
+

+ {{ request.user.profile.agency.inhaber }} +

+
Adresse
+

+ {{ request.user.profile.agency.street }} +

+

+ {{ request.user.profile.agency.plz }} {{ request.user.profile.agency.city }} +

+
Kontaktdaten
+

+ {{ request.user.profile.agency.agency_email }} +

+

+ {{ request.user.profile.agency.phone }} +

+
Agenturbild
+

+ +

+
+ +{% endblock content %} \ No newline at end of file diff --git a/users/templates/users/agency_update_DELETE.html b/users/templates/users/agency_update_DELETE.html new file mode 100644 index 0000000..72c4ffc --- /dev/null +++ b/users/templates/users/agency_update_DELETE.html @@ -0,0 +1,23 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+ +
+
+ {% csrf_token %} +
+ + Agenturinformationen bearbeiten + + + {{ form|crispy }} +
+
+   + Abbrechen +
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/users/templates/users/profile_DELETE.html b/users/templates/users/profile_DELETE.html new file mode 100644 index 0000000..64a37a6 --- /dev/null +++ b/users/templates/users/profile_DELETE.html @@ -0,0 +1,62 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+ +
+ +
+
+
+
Name
+

+ {{ user.first_name }} {{ user.last_name }} +

+
E-Mail
+

+ {{ user.email }} +

+
Agenturfunktion
+

+ {{ user.profile.get_func_display }} +

+
+
+
Tätigkeit
+

+ {{ user.profile.compfunc }} +

+
Festnetz
+

+ {{ user.profile.phoneland }} +

+
Mobil
+

+ {{ user.profile.phonemobile }} +

+
+
+
+
+ +
+
+ {% csrf_token %} +
+ + Profil bearbeiten + + + {{ u_form|crispy }} +
+ + Agenturrelevante Daten werden in der Benutzerverwaltung verändert. +
+   + Abbrechen +
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/users/templates/users/profile_update_DELETE.html b/users/templates/users/profile_update_DELETE.html new file mode 100644 index 0000000..4865676 --- /dev/null +++ b/users/templates/users/profile_update_DELETE.html @@ -0,0 +1,262 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% load static %} +{% block content %} + + +
+
+ +
+ +
+
+
+
Name
+

+ {{ prof_user.first_name}} {{ prof_user.last_name }} +

+
E-Mail
+

+ {{ prof_user.email }} +

+
Agenturfunktion
+

+ {{ prof_user.profile.get_func_display }} +

+
+
+
Tätigkeit
+

+ {{ prof_user.profile.compfunc }} +

+
Festnetz
+

+ {{ prof_user.profile.phoneland }} +

+
Mobil
+

+ {{ prof_user.profile.phonemobile }} +

+
+
+
+
+ +
+
+ {% csrf_token %} +
+ + Profil bearbeiten + + + {{ profileform_form|crispy }} +    +
+ Übergeordneter Mitarbeiter: {{prof_user.profile.parent.first_name}} {{prof_user.profile.parent.last_name}} +
+ +
+ + +
+ + {% for us in possible_users %} + + {% endfor %} + + +
+
+
+   + Abbrechen +
+
+
+
+ + + +{% block javascript %} + +{% endblock %} + + +{% endblock content %} \ No newline at end of file diff --git a/users/templates/users/users_adduser_DELETE.html b/users/templates/users/users_adduser_DELETE.html new file mode 100644 index 0000000..e91c08e --- /dev/null +++ b/users/templates/users/users_adduser_DELETE.html @@ -0,0 +1,24 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+

Neuer Benutzer

+
+ +
+ {% csrf_token %} + {{ form|crispy }} +
+ + +
+ *: Der Benutzer erhält direkt eine E-Mail mit einem Link zur Passworterstellung, wenn der Haken bei E-Mailbenachrichtung schicken gesetzt ist. Dies kann später auch wiederholt werden. +
+   + Abbrechen +
+ +
+{% endblock content %} \ No newline at end of file diff --git a/users/templates/users/users_management_DELETE.html b/users/templates/users/users_management_DELETE.html new file mode 100644 index 0000000..61af915 --- /dev/null +++ b/users/templates/users/users_management_DELETE.html @@ -0,0 +1,81 @@ + + + + +{% extends "users/base.html" %} +{% block content %} +
+

Benutzerverwaltung

+
+

+ Erstellen Sie weitere Mitarbeiter ihrer Agentur. Die neuen Benutzer erhalten eine E-Mail mit einem entsprechenden Link, um ihr Passwort zu generieren. +

+ +
+
+ +
+
+ + + + + + + + + + + + + + + {% for item in users_of_agency %} + + + + + + + + + + + {% endfor %} + +
NameBenutzernameE-MailAgenturfunktionTätigkeitTelefonMobil 
{{item.first_name }} {{ item.last_name }}{{ item.username }}{{ item.email }}{{ item.profile.get_func_display }}{{ item.profile.compfunc }}{{ item.profile.phoneland }}{{ item.profile.phonemobile }} + +
+
+
+
+ +{% endblock content %} \ No newline at end of file diff --git a/users/templates/users/users_prio_DELETE.html b/users/templates/users/users_prio_DELETE.html new file mode 100644 index 0000000..eb7bf2e --- /dev/null +++ b/users/templates/users/users_prio_DELETE.html @@ -0,0 +1,51 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+

Reihenfolge im Organigramm von {{ user_first_name }} {{ user_last_name }}

+ Elemente mit einer größeren Zahl werden im Organigramm weiter oben angezeigt. Die Änderungen werden sofort gespeichert. +
+
+ {% for area in areas %} +

Bereich {{ area.name }}

+ {% for prio in prios %} + {% if prio.task.area == area %} +
+ +
+
+
+ {% endif %} + {% endfor%} +
+ {% endfor %} +
+ Zum Dashboard +
+ + +{% endblock content %} +