- Bugs behoben

- Rechte wurden falsch übernommen, da Benutzer bearbeiten nicht mitgeschickt wurde.
  - Das andere hab ich vergessen, aber war auch ein Fehler, der nun behoben ist
- Jeder Nutzer kann jetzt Bilder für Standards hochladen
- Standards
  - Werden nun korrekt zugewiesen
  - Es gibt nun Ansichten für Bereiche und Aufgaben, welche über eine Navigation darüber angeklickt werden können
  - Das Veröffentlichen von Standards und unveröffentlichen ist korrekt umgesetzt
- Priorisierung
  - Jeder Benutzer kann nun individuell für sich oder durch Benuterverwalter eine Priorisierung von Aufgaben einstellen
This commit is contained in:
Holger Trampe 2019-12-05 20:54:04 +01:00
parent e965cd623e
commit 92e794fe0f
76 changed files with 388 additions and 110 deletions

View File

@ -6,7 +6,7 @@ from django.conf.urls.static import static
from users.views import AgencyCreateView from users.views import AgencyCreateView
from . import views from . import views
from ckeditor_uploader.views import upload from ckeditor_uploader.views import upload
from django.contrib.auth.decorators import login_required
''' '''
ADMINPAGE - Verwaltung der Super-User ADMINPAGE - Verwaltung der Super-User
- LOGIN-Page - LOGIN-Page
@ -26,8 +26,12 @@ urlpatterns = [
path('password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html'), name='password_reset_confirm'), path('password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html'), name='password_reset_confirm'),
path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'), name='password_reset_complete'), path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'), name='password_reset_complete'),
path('register/', AgencyCreateView.as_view(template_name='users/register.html'), name='register'), path('register/', AgencyCreateView.as_view(template_name='users/register.html'), name='register'),
path('register/done', views.registerdone, name='register-done'), path('register/done', views.registerdone, name='register-done')
path('ckeditor/', include('ckeditor_uploader.urls')),
] ]
if settings.DEBUG: if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += [
path(r'^ckeditor/upload/', login_required(upload), name='ckeditor_upload'),
path(r'^ckeditor/', include('ckeditor_uploader.urls')),
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,50 @@
{% extends "users/base.html" %}
{% block content %}
<div class="content-section col-12">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'standards' %}">Standards</a></li>
<li class="breadcrumb-item active" aria-current="page"><a href="{% url 'standard-area' areaid %}">{{areaname}}</a></li>
</ol>
</nav>
<h4>Standards aus dem Bereich {{areaname}}</h4>
<hr>
<div class="row">
{% for item in standards_of_agency_area %}
{% if item.public or item.created_standard_by == user or perms.users.standard_management %}
<div class=" mb-4 col-5">
<div class="card">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<a href="{% url 'standard-single' item.pk%}">
{% if item.public %}
<h4><u>{{item.name}}</u></h4>
{% else %}
<h4 class="text-warning"><u>{{item.name}}</u></h4>
{% endif %}
</a>
{% if item.created_standard_by == user or perms.users.standard_management %}
<div class="dropdown no-arrow">
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
</a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
<!--<div class="dropdown-header">Benutzerdaten</div>-->
<a class="dropdown-item" href="{% url 'standard-update' item.pk %}">Bearbeiten</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'standard-delete' item.pk %}" >Löschen</a>
</div>
</div>
{% endif %}
</div>
<div class="card-body">
<h5 class="card-title">{{item.created_standard_by.first_name}} {{item.created_standard_by.last_name}} <h6>Zuletzt bearbeitet von {{ item.last_modified_by.first_name }} {{ item.last_modified_by.last_name }} am {{ item.last_modified_on }}</h6>
</h5>
<p class="card-text">{{ item.content|truncatechars:250|safe}}</p>
</div>
</div>
</div>
{% endif %}
{% endfor%}
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,51 @@
{% extends "users/base.html" %}
{% block content %}
<div class="content-section col-12">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'standards' %}">Standards</a></li>
<li class="breadcrumb-item active"><a href="{% url 'standard-area' areaid %}">{{areaname}}</a></li>
<li class="breadcrumb-item active" aria-current="page"><a href="{% url 'standard-task' taskid %}">{{taskname}}</a></li>
</ol>
</nav>
<h4>Standards aus dem Aufgabenbereich {{taskname}} des Bereichs {{areaname}}</h4>
<hr>
<div class="row">
{% for item in standards_of_agency_task %}
{% if item.public or item.created_standard_by == user or perms.users.standard_management %}
<div class=" mb-4 col-5">
<div class="card">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<a href="{% url 'standard-single' item.pk%}">
{% if item.public %}
<h4><u>{{item.name}}</u></h4>
{% else %}
<h4 class="text-warning"><u>{{item.name}}</u></h4>
{% endif %}
</a>
{% if item.created_standard_by == user or perms.users.standard_management %}
<div class="dropdown no-arrow">
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
</a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
<!--<div class="dropdown-header">Benutzerdaten</div>-->
<a class="dropdown-item" href="{% url 'standard-update' item.pk %}">Bearbeiten</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="{% url 'standard-delete' item.pk %}" >Löschen</a>
</div>
</div>
{% endif %}
</div>
<div class="card-body">
<h5 class="card-title">{{item.created_standard_by.first_name}} {{item.created_standard_by.last_name}} <h6>Zuletzt bearbeitet von {{ item.last_modified_by.first_name }} {{ item.last_modified_by.last_name }} am {{ item.last_modified_on }}</h6>
</h5>
<p class="card-text">{{ item.content|truncatechars:250|safe}}</p>
</div>
</div>
</div>
{% endif %}
{% endfor%}
</div>
</div>
{% endblock content %}

View File

@ -1,7 +1,8 @@
{% extends "users/base.html" %} {% extends "users/base.html" %}
{% block content %} {% block content %}
<div class="content-section col-12"> <div class="content-section col-12">
<h3>Standards</h3> <h3>Standards</h3>
<small>Sichtbar sind alle veröffentlichten und von {{ user.first_name }} {{ user.last_name}} erstellten Standards. Nicht veröffentlichte sind gelb markiert.</small>
<hr> <hr>
<p> <p>
Standards dokumentieren und erläutern verschiedenen Verfahren, strukturiert nach Bereichen und Aufgaben. Standards dokumentieren und erläutern verschiedenen Verfahren, strukturiert nach Bereichen und Aufgaben.
@ -14,32 +15,39 @@
<hr> <hr>
<div class="row"> <div class="row">
{% for item in standards_of_agency %} {% for item in standards_of_agency %}
<div class=" mt-4 col-5"> {% if item.public or item.created_standard_by == user or perms.users.standard_management %}
<div class="card"> <div class=" mb-4 col-5">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between"> <div class="card">
<a href="{% url 'standard-single' item.pk%}"><h4><u>{{item.name}}</u></h4></a> <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
{% if item.created_standard_by == user or perms.users.standard_management %} <a href="{% url 'standard-single' item.pk%}">
<div class="dropdown no-arrow"> {% if item.public %}
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <h4><u>{{item.name}}</u></h4>
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i> {% else %}
<h4 class="text-warning"><u>{{item.name}}</u></h4>
{% endif %}
</a> </a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink"> {% if item.created_standard_by == user or perms.users.standard_management %}
<!--<div class="dropdown-header">Benutzerdaten</div>--> <div class="dropdown no-arrow">
<a class="dropdown-item" href="{% url 'standard-update' item.pk %}">Bearbeiten</a> <a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="dropdown-divider"></div> <i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
<a class="dropdown-item text-danger" href="{% url 'standard-delete' item.pk %}" >Löschen</a> </a>
</div> <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
</div> <!--<div class="dropdown-header">Benutzerdaten</div>-->
{% endif %} <a class="dropdown-item" href="{% url 'standard-update' item.pk %}">Bearbeiten</a>
</div> <div class="dropdown-divider"></div>
<div class="card-body"> <a class="dropdown-item text-danger" href="{% url 'standard-delete' item.pk %}" >Löschen</a>
<h5 class="card-title">{{item.created_standard_by.first_name}} {{item.created_standard_by.last_name}} <h6>Zuletzt bearbeitet von {{ item.last_modified_by.first_name }} {{ item.last_modified_by.last_name }} am {{ item.last_modified_on }}</h6> </div>
</h5> </div>
<p class="card-text">{{ item.content|truncatechars:250|safe}}</p> {% endif %}
</div> </div>
</div> <div class="card-body">
</div> <h5 class="card-title">{{item.created_standard_by.first_name}} {{item.created_standard_by.last_name}} <h6>Zuletzt bearbeitet von {{ item.last_modified_by.first_name }} {{ item.last_modified_by.last_name }} am {{ item.last_modified_on }}</h6>
</h5>
<p class="card-text">{{ item.content|truncatechars:250|safe}}</p>
</div>
</div>
</div>
{% endif %}
{% endfor%} {% endfor%}
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -4,11 +4,12 @@
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'standards' %}">Standards</a></li> <li class="breadcrumb-item"><a href="{% url 'standards' %}">Standards</a></li>
<li class="breadcrumb-item active" aria-current="page">{{standard.area.name}}</li> <li class="breadcrumb-item active" aria-current="page"><a href="{% url 'standard-area' standard.area.pk %}">{{standard.area.name}}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{standard.task.name}}</li> <li class="breadcrumb-item active" aria-current="page"><a href="{% url 'standard-task' standard.task.pk %}">{{standard.task.name}}</a></li>
</ol> </ol>
</nav> </nav>
<small> <small>
<h2>{{standard.name}}</h2>
Erstellt durch {{standard.created_standard_by.first_name}} {{standard.created_standard_by.last_name}} am {{standard.created_standard_date}} | Zuletzt bearbeitet von {{ standard.last_modified_by.first_name}} {{ standard.last_modified_by.last_name}} am {{ standard.last_modified_on}}</small> Erstellt durch {{standard.created_standard_by.first_name}} {{standard.created_standard_by.last_name}} am {{standard.created_standard_date}} | Zuletzt bearbeitet von {{ standard.last_modified_by.first_name}} {{ standard.last_modified_by.last_name}} am {{ standard.last_modified_on}}</small>
<hr> <hr>
{{standard.media}} {{standard.media}}

View File

@ -17,7 +17,7 @@
{% if standard_status == False %} {% if standard_status == False %}
<a class="btn btn-primary" href="{% url 'standard-status' standard_id %} ">Standard veröffentlichen</a>&nbsp; <a class="btn btn-primary" href="{% url 'standard-status' standard_id %} ">Standard veröffentlichen</a>&nbsp;
{% else %} {% else %}
<a class="btn btn-warning" href="{% url 'standard-status' standard_id %} ">Standard unveröffentlichen</a>&nbsp; <a class="btn btn-warning" href="{% url 'standard-status' standard_id %} ">Veröffentlichung aufheben</a>&nbsp;
{% endif %} {% endif %}
{% endif %} {% endif %}
<a class="btn" href="{% url 'standards' %} ">Abbrechen</a> <a class="btn" href="{% url 'standards' %} ">Abbrechen</a>

View File

@ -14,5 +14,7 @@ urlpatterns = [
path('ajax/loadtasks/', views.load_tasks, name='ajax_loadtasks'), path('ajax/loadtasks/', views.load_tasks, name='ajax_loadtasks'),
path('standards/<int:pk>/delete', StandardDeleteView.as_view(), name='standard-delete'), path('standards/<int:pk>/delete', StandardDeleteView.as_view(), name='standard-delete'),
path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"), path('standard/<int:pk>/changestat', views.StandardChangePublic, name="standard-status"),
path('standard/<int:pk>/single', views.StandardSingle, name="standard-single") path('standard/<int:pk>/single', views.StandardSingle, name="standard-single"),
path('standard/<int:pk>/area', views.StandardArea, name="standard-area"),
path('standard/<int:pk>/task', views.StandardTask, name="standard-task")
] ]

View File

@ -8,9 +8,10 @@ from django.http import HttpResponse, JsonResponse
from .forms import StandardAddStandard, StandardAddStandardEditor, StandardUpdateStandard, StandardUpdateStandardEditor from .forms import StandardAddStandard, StandardAddStandardEditor, StandardUpdateStandard, StandardUpdateStandardEditor
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from tasks.models import Tasks from tasks.models import Tasks
from areas.models import Areas
from datetime import datetime from datetime import datetime
# Create your views here. # ALLE STANDARDS EINER AGENTUR
class StandardsManagement(LoginRequiredMixin, ListView): class StandardsManagement(LoginRequiredMixin, ListView):
model = Standards model = Standards
# Adding active_link # Adding active_link
@ -23,32 +24,7 @@ class StandardsManagement(LoginRequiredMixin, ListView):
context.update({'active_link' : 'standards', 'standards_of_agency' : standards_of_agency}) context.update({'active_link' : 'standards', 'standards_of_agency' : standards_of_agency})
return context return context
'''
class StandardAdd(LoginRequiredMixin, CreateView):
model = Standards
success_url = '/standards'
form_class = StandardAddStandardForm
def get_form_kwargs(self):
kwargs = super(StandardAdd, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'standards'})
return context
def form_valid(self, form):
# Send message to the site
messages.success(self.request, f'Standard angelegt!')
form.instance.agency = self.request.user.profile.agency
form.instance.created_standard_by = self.request.user
form.instance.published_by = self.request.user
form.instance.last_modifed_by = self.request.user
return super().form_valid(form)
'''
@login_required @login_required
def StandardAdd(request): def StandardAdd(request):
if request.method == 'POST': if request.method == 'POST':
@ -104,8 +80,17 @@ def StandardUpdate(request, id):
existing_standard.task = normalForm.cleaned_data['task'] existing_standard.task = normalForm.cleaned_data['task']
existing_standard.area = normalForm.cleaned_data['area'] existing_standard.area = normalForm.cleaned_data['area']
existing_standard.name = normalForm.cleaned_data['name'] existing_standard.name = normalForm.cleaned_data['name']
existing_standard.content = editorForm.cleaned_data['content'] existing_standard.content = editorForm.cleaned_data['content']
if request.user.has_perm('standard_management'): '''
AKTUALISIERUNG
Wennn der User selbst den Standard erstellt hat und Rechte zur Standardverwaltung hat,
dann wird der Status nicht verändert (public bleibt true bzw. false). Hat der User
aber keine Rechte und ist der Standarf public, wird er auf public=false gesetzt!
'''
if request.user.has_perm('users.standard_management'):
messages.success(request, f'Standard {existing_standard.name} aktualisiert!') messages.success(request, f'Standard {existing_standard.name} aktualisiert!')
else: else:
if existing_standard.public: if existing_standard.public:
@ -166,4 +151,34 @@ def StandardSingle(request, pk):
'active_link':'standards', 'active_link':'standards',
'standard' : standard 'standard' : standard
} }
return render(request, 'standards/standards_single.html', context) return render(request, 'standards/standards_single.html', context)
@login_required
def StandardArea(request, pk):
standards = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(area__pk=pk)
area = Areas.objects.get(pk=pk)
context = {
'active_link':'standards',
'standards_of_agency_area' : standards,
'areaid' : pk,
'areaname' : area.name
}
return render(request, 'standards/standard_area.html', context)
@login_required
def StandardTask(request, pk):
standards = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(task__pk=pk)
task = Tasks.objects.get(pk=pk)
area = Areas.objects.get(pk=task.area.pk)
context = {
'active_link':'standards',
'standards_of_agency_task' : standards,
'taskid' : pk,
'taskname' : task.name,
'areaid' : area.pk,
'areaname' : area.name
}
return render(request, 'standards/standard_task.html', context)

View File

@ -6,6 +6,8 @@ from .models import Tasks
from .forms import TasksAddTaskForm from .forms import TasksAddTaskForm
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from users.priomodel import Prio
# Create your views here. # Create your views here.
class TasksManagement(LoginRequiredMixin, ListView): class TasksManagement(LoginRequiredMixin, ListView):
@ -84,6 +86,13 @@ class TasksUpdateView(LoginRequiredMixin, UpdateView):
context['objectid'] = context['object'].pk context['objectid'] = context['object'].pk
return context return context
'''
Hier werden Aufgaben zu Mitarbeitern zugewiesen oder entfernt. Dabei wird bei jeder Aufgabe auch gleich ein
Prio-Objekt erzeugt/entfernt, damit der Mitarbeiter seine Prioritäten auf dem Organigramm einstellen kann.
'''
def task_addtasks_ajax(request): def task_addtasks_ajax(request):
if request.method == 'GET': if request.method == 'GET':
@ -92,11 +101,17 @@ def task_addtasks_ajax(request):
task = Tasks.objects.get(pk=request.GET['objectid']) task = Tasks.objects.get(pk=request.GET['objectid'])
task.usersfield.add(User.objects.get(pk=request.GET['userid'])) task.usersfield.add(User.objects.get(pk=request.GET['userid']))
task.save() task.save()
# PRIO
prio = Prio(user=User.objects.get(pk=request.GET['userid']), task=task)
prio.save()
# REMOVE USER TO MANY-TO-MANY USERSFIELD # REMOVE USER TO MANY-TO-MANY USERSFIELD
elif request.GET['action'] == 'remuser': elif request.GET['action'] == 'remuser':
task = Tasks.objects.get(pk=request.GET['objectid']) task = Tasks.objects.get(pk=request.GET['objectid'])
task.usersfield.remove(User.objects.get(pk=request.GET['userid'])) task.usersfield.remove(User.objects.get(pk=request.GET['userid']))
task.save() task.save()
# DELETE PRIO
Prio.objects.filter(user__pk=request.GET['userid']).filter(task__pk=request.GET['objectid']).delete()
userid = request.GET['userid'] userid = request.GET['userid']
workinguser = User.objects.get(pk=userid) workinguser = User.objects.get(pk=userid)
username_clean = workinguser.first_name + " " + workinguser.last_name username_clean = workinguser.first_name + " " + workinguser.last_name

Binary file not shown.

View File

@ -1,5 +1,7 @@
from django.contrib import admin from django.contrib import admin
from .models import Profile, Agency from .models import Profile, Agency
from .priomodel import Prio
admin.site.register(Profile) admin.site.register(Profile)
admin.site.register(Agency) admin.site.register(Agency)
admin.site.register(Prio)

View File

@ -0,0 +1,26 @@
# Generated by Django 2.2.7 on 2019-12-05 17:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('tasks', '0003_auto_20191205_0809'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0002_auto_20191204_0857'),
]
operations = [
migrations.CreateModel(
name='Prio',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('prio', models.IntegerField(default=0)),
('task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tasks.Tasks')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

Binary file not shown.

View File

@ -7,6 +7,7 @@ from PIL import Image
from django.contrib.auth.models import AbstractUser, User from django.contrib.auth.models import AbstractUser, User
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
# UNIQUE and NO BLANK fields while user-registration # UNIQUE and NO BLANK fields while user-registration
User._meta.get_field('email')._unique = True User._meta.get_field('email')._unique = True
User._meta.get_field('email').blank = False User._meta.get_field('email').blank = False
@ -105,4 +106,6 @@ class Profile(models.Model):
('areas_management', 'Bereiche bearbeiten'), ('areas_management', 'Bereiche bearbeiten'),
('tasks_management', 'Aufgabenbereiche bearbeiten'), ('tasks_management', 'Aufgabenbereiche bearbeiten'),
('standard_management', 'Standards bearbeiten und freischalten') ('standard_management', 'Standards bearbeiten und freischalten')
] ]

17
users/priomodel.py Normal file
View File

@ -0,0 +1,17 @@
from django.db import models
from django.contrib.auth.models import User, AbstractBaseUser
from django.conf import settings
from tasks.models import Tasks
'''
Model zum Speichern der Priorisierungen von Aufgaben eines Nutzers
'''
class Prio(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
task = models.ForeignKey(Tasks, on_delete=models.CASCADE)
prio = models.IntegerField(default=0)

View File

@ -19,8 +19,7 @@ def create_profile(sender, instance, created, **kwargs):
temprof = Profile temprof = Profile
for ele in temprof._meta.permissions: for ele in temprof._meta.permissions:
tempperm = Permission.objects.get(codename=ele[0]) tempperm = Permission.objects.get(codename=ele[0])
tempuser.user_permissions.add(tempperm) tempuser.user_permissions.add(tempperm)
tempuser.save() tempuser.save()

View File

@ -194,6 +194,10 @@
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
Profil Profil
</a> </a>
<a class="dropdown-item" href="{% url 'users-prio' user.pk %}">
<i class="fab fa-product-hunt fa-sm fa-fw mr-2 text-gray-400"></i>
Priorisierung
</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'users-logout' %}"> <a class="dropdown-item" href="{% url 'users-logout' %}">
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>

View File

@ -29,7 +29,7 @@
<div class="dropdown-header">Benutzerdaten</div> <div class="dropdown-header">Benutzerdaten</div>
<a class="dropdown-item" href="{% url 'users-update' item.profile.pk %}">Bearbeiten</a> <a class="dropdown-item" href="{% url 'users-update' item.profile.pk %}">Bearbeiten</a>
<a class="dropdown-item" href="{% url 'users-perm-update' item.profile.pk %}">Rechte</a> <a class="dropdown-item" href="{% url 'users-perm-update' item.profile.pk %}">Rechte</a>
<a class="dropdown-item" href="#">Priorisierung</a> <a class="dropdown-item" href="{% url 'users-prio' item.pk %}">Priorisierung</a>
<hr class="sidebar-divider"> <hr class="sidebar-divider">
<!--<div class="dropdown-header"></div>--> <!--<div class="dropdown-header"></div>-->
<a class="dropdown-item" href="#">Bereiche</a> <a class="dropdown-item" href="#">Bereiche</a>

View File

@ -11,18 +11,6 @@
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
{% for field in form %} {% for field in form %}
{% if field.name == 'users_usermanagement'%}
{% if user_tochange.pk != request.user.pk %}
<div class="custom-control custom-checkbox mb-2">
{% if field.value %}
<input type="checkbox" name="{{ field.name }}" class="custom-control-input pull-left" id="{{ field.name }}" checked>
{% else %}
<input type="checkbox" name="{{ field.name }}" class="custom-control-input pull-left" id="{{ field.name }}">
{% endif %}
<label class="custom-control-label" for="{{ field.name }}">{{ field.help_text }}</label>
</div>
{%endif %}
{% else %}
<div class="custom-control custom-checkbox mb-2"> <div class="custom-control custom-checkbox mb-2">
{% if field.value %} {% if field.value %}
<input type="checkbox" name="{{ field.name }}" class="custom-control-input pull-left" id="{{ field.name }}" checked> <input type="checkbox" name="{{ field.name }}" class="custom-control-input pull-left" id="{{ field.name }}" checked>
@ -30,8 +18,7 @@
<input type="checkbox" name="{{ field.name }}" class="custom-control-input pull-left" id="{{ field.name }}"> <input type="checkbox" name="{{ field.name }}" class="custom-control-input pull-left" id="{{ field.name }}">
{% endif %} {% endif %}
<label class="custom-control-label" for="{{ field.name }}">{{ field.help_text }}</label> <label class="custom-control-label" for="{{ field.name }}">{{ field.help_text }}</label>
</div> </div>
{% endif %}
{% endfor %} {% endfor %}
<hr> <hr>
<button type="submit" class="btn btn-success">Berechtigungen speichern</button>&nbsp; <button type="submit" class="btn btn-success">Berechtigungen speichern</button>&nbsp;

View File

@ -0,0 +1,51 @@
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<h3>Priorisierung von {{ user_first_name }} {{ user_last_name }} verändern</h3>
<small>Elemente mit einer hohen Zahl werden im Organigramm weiter oben angezeigt. Die Änderungen werden sofort gespeichert.</small>
<hr>
<div class="col-12">
{% for area in areas %}
<h3>Bereich {{ area.name }}</h3>
{% for prio in prios %}
{% if prio.task.area == area %}
<div class="form-group row">
<label for="{{forloop.counter}}" class="col-sm-2 col-form-label"><h5>{{ prio.task.name }}</h5></label>
<div class="col-sm-1" style="float:right" >
<input type="number" min="0" class="form-control" id="{{forloop.counter}}" value="{{ prio.prio}}" onkeyup="javascript:updatePrio({{prio.pk}}, {{prio.task.pk}}, this.value)" onchange="javascript:updatePrio({{prio.pk}}, {{prio.task.pk}}, this.value)"></div><span class="badge badge-success mt-1 mb-3" id="save_{{prio.pk}}" style="display: none; font-size: 0.8em;">Gespeichert</span>
</div>
{% endif %}
{% endfor%}
<hr>
{% endfor %}
</div>
<a href="{% url 'users-dashboard' %}" class="btn btn-success">Zum Dashboard</a>
</div>
<script type="text/javascript">
function updatePrio(prio, task, value)
{
console.log({{userprio.pk}} + " " + prio + " " + task + " VAL: " + value);
$.ajax(
{
type: "GET",
url: "/dashboard/prioupdate",
data:{
userid: {{user_id}},
prioid : 'adduser',
taskid : task,
value : value
},
success: function( data )
{
$('#save_'+prio).show();
setTimeout(function() {
$('#save_'+prio).fadeOut();
}, 1000 );
}
});
}
</script>
{% endblock content %}

View File

@ -22,7 +22,9 @@ urlpatterns = [
path('usersman/<int:pk>/perms', permission_required('users.users_usermanagement')(UsersPermUpdateView.as_view()), name='users-perm-update'), path('usersman/<int:pk>/perms', permission_required('users.users_usermanagement')(UsersPermUpdateView.as_view()), name='users-perm-update'),
path('usersman/<int:pk>/delete', permission_required('users.users_usermanagement')(ProfileDeleteView.as_view()), name='users-delete'), path('usersman/<int:pk>/delete', permission_required('users.users_usermanagement')(ProfileDeleteView.as_view()), name='users-delete'),
path('agencyinfo/', views.agency, name='agencyinfo'), path('agencyinfo/', views.agency, name='agencyinfo'),
path('agencyinfo/<int:pk>/', permission_required('users.agency_change')(AgencyUpdateView.as_view()), name='agency-manage'), path('agencyinfo/<int:pk>/', permission_required('users.agency_change')(AgencyUpdateView.as_view()), name='agency-manage'),
path('usersman/<int:pk>/prio', views.UsersPrio, name='users-prio'),
path('prioupdate/', views.UsersPrioUpdate, name="users-prioupdate")
] ]

View File

@ -63,16 +63,15 @@ class UsersPermForm(forms.Form):
Die erstellen Felder werden entsprechend den Feldern hinzugefügt und ausgegeben. Die erstellen Felder werden entsprechend den Feldern hinzugefügt und ausgegeben.
@param: user @param: user
- User ist der aufgerufene User! - User ist der aufgerufene User!
'''
'''
def __init__(self, user, *args, **kwargs): def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
temprof = Profile temprof = Profile
for ele in temprof._meta.permissions: for ele in temprof._meta.permissions:
if isinstance(user, User): if isinstance(user, User):
if user.has_perm('users.' + ele[0]): if user.has_perm('users.' + ele[0]):
self.fields[ele[0]] = forms.BooleanField(initial=True, help_text=(ele[1])); self.fields[ele[0]] = forms.BooleanField(required=False, initial=True, help_text=(ele[1]))
else: else:
self.fields[ele[0]] = forms.BooleanField(initial=False, help_text=(ele[1])); self.fields[ele[0]] = forms.BooleanField(required=False, initial=False, help_text=(ele[1]))

View File

@ -10,16 +10,15 @@ from django.db import models
from .models import Profile, Agency from .models import Profile, Agency
from django.core.mail import send_mail from django.core.mail import send_mail
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect,HttpResponse
from areas.models import Areas
from tasks.models import Tasks
from .priomodel import Prio
''' '''
DASHBOARD-View DASHBOARD-View
View nach erfolgreichem Login und anzeige des Dashboards. View nach erfolgreichem Login Dashboard
TODO: ROLLENVERTEILUNG
Templates: welcomeusers.html und base.html Templates: welcomeusers.html und base.html
@ -109,19 +108,13 @@ class UsersCreateUser(LoginRequiredMixin, CreateView):
# USER muss eingeloggt sein, um diese Seite zu sehen # USER muss eingeloggt sein, um diese Seite zu sehen
@login_required @login_required
def profile(request): def profile(request):
# NEUE DATEN KOMMEN AN!
if request.method == 'POST': if request.method == 'POST':
# Hier werden die Daten aus POST geholt und in die Instance(konkreten User) gespeichert
u_form = UsersChangeProfil(request.POST, instance=request.user) u_form = UsersChangeProfil(request.POST, instance=request.user)
#p_form = UsersAddProfileForm(request.POST, request.FILES, instance=request.user.profile)
if u_form.is_valid(): if u_form.is_valid():
#if u_form.is_valid() and p_form.is_valid():
u_form.save() u_form.save()
#p_form.save()
prename = request.user.first_name prename = request.user.first_name
name = request.user.last_name name = request.user.last_name
#name = p_form.cleaned_data.get('name')
messages.success(request, f'Daten für {prename} {name} aktualisiert!') messages.success(request, f'Daten für {prename} {name} aktualisiert!')
# Daten neu laden und nicht die "Mächten sie die Daten speichern...?" # Daten neu laden und nicht die "Mächten sie die Daten speichern...?"
return redirect('users-dashboard') return redirect('users-dashboard')
@ -148,6 +141,7 @@ class UserManagementUpdateForm(LoginRequiredMixin, UpdateView):
} }
fields = ['phoneland','phonemobile','compfunc'] fields = ['phoneland','phonemobile','compfunc']
# Update der Zugrifssrechte eines Users
class UsersPermUpdateView(LoginRequiredMixin, View): class UsersPermUpdateView(LoginRequiredMixin, View):
template_name = 'users/users_perm.html' template_name = 'users/users_perm.html'
form_class = UsersPermForm form_class = UsersPermForm
@ -160,11 +154,6 @@ class UsersPermUpdateView(LoginRequiredMixin, View):
user_tochange = Profile.objects.get(pk=kwargs['pk']).user user_tochange = Profile.objects.get(pk=kwargs['pk']).user
return render (request, self.template_name, {'form':self.form_class(user_tochange), 'active_link': 'usersmanagement', 'user_tochange': user_tochange}) return render (request, self.template_name, {'form':self.form_class(user_tochange), 'active_link': 'usersmanagement', 'user_tochange': user_tochange})
#messages.success(self.request, f'Berechtigungen aktualisiert!')
#print(form)
#return super().form_valid(form)
# Handle POST GTTP requests # Handle POST GTTP requests
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
permissions_loaded = dict(request.POST.lists()) permissions_loaded = dict(request.POST.lists())
@ -178,7 +167,11 @@ class UsersPermUpdateView(LoginRequiredMixin, View):
if ele[0] in permissions_loaded: if ele[0] in permissions_loaded:
user_tochange.user_permissions.add(tempperm) user_tochange.user_permissions.add(tempperm)
else: else:
user_tochange.user_permissions.remove(tempperm) # Eingeloggter User darf sich nicht selbst die Userverwaltungsrechte entziehen
if user_tochange == request.user and ele[0]=='users_usermanagement':
messages.warning(request, f'Benutzerverwaltungsrechte für {user_tochange.first_name} {user_tochange.last_name} kann nicht entfernt werden.')
else:
user_tochange.user_permissions.remove(tempperm)
user_tochange.save() user_tochange.save()
messages.success(request, f'Berechtigungen für {user_tochange.first_name} {user_tochange.last_name} aktualisiert!') messages.success(request, f'Berechtigungen für {user_tochange.first_name} {user_tochange.last_name} aktualisiert!')
return HttpResponseRedirect('/dashboard/usersman/') return HttpResponseRedirect('/dashboard/usersman/')
@ -213,8 +206,6 @@ class ProfileDeleteView(LoginRequiredMixin, DeleteView):
return False return False
return True return True
# USER muss eingeloggt sein, um diese Seite zu sehen
@login_required @login_required
def agency(request): def agency(request):
context = { context = {
@ -233,4 +224,55 @@ class AgencyUpdateView(LoginRequiredMixin, UpdateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(AgencyUpdateView, self).get_context_data(**kwargs) context = super(AgencyUpdateView, self).get_context_data(**kwargs)
context['active_link'] = 'agencyinfo' context['active_link'] = 'agencyinfo'
return context return context
# PRIORISIERUNG
'''
Es werden alle Aufgabenbereiche den Bereichen der Agentur zugeordnet und ausgegeben.
'''
def UsersPrio(request, pk):
user = User.objects.get(pk=pk)
prios = Prio.objects.filter(user__pk=pk)
areas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk)
'''
fulldata = []
areas_dict = list(areas)
for area in areas_dict:
fulldata.append({"areaname" : area.name, "area" : area, "tasks" : 0})
for fulldataarea in fulldata:
tasks_of_area = Tasks.objects.filter(area__pk=fulldataarea['area'].pk).exclude(pk__in=prios)
fulldataarea['tasks'] = list(tasks_of_area)
print(fulldataarea)
'''
user_first_name = user.first_name
user_last_name = user.last_name
user_id = user.pk
context = {
'active_link' : '',
'areas' : areas,
'user_first_name' : user_first_name,
'user_last_name' : user_last_name,
'user_id' : user_id,
'prios' : prios
}
return render(request, 'users/users_prio.html', context)
def UsersPrioUpdate(request):
if request.method == 'GET':
prio = Prio.objects.filter(user__pk=request.GET['userid']).filter(task__pk=request.GET['taskid'])
prio = list(prio)[0]
prio.prio = request.GET['value']
prio.save()
return HttpResponse("udated...")
else:
return HttpResponse("Request method is not a GET")