diff --git a/rcr/forms.py b/rcr/forms.py index 7d1add11..c9e4223c 100644 --- a/rcr/forms.py +++ b/rcr/forms.py @@ -25,4 +25,4 @@ class ItemForm(ModelForm): #fields = ["category", "level"] class AssessorAssignmentForm(Form): - items = ModelMultipleChoiceField(queryset=Item.objects.all()) \ No newline at end of file + items = ModelMultipleChoiceField(queryset=Item.objects.filter(assigned_to=None)) \ No newline at end of file diff --git a/rcr/templates/rcr/assessor_assignment_form.html b/rcr/templates/rcr/assessor_assignment_form.html index 911b2a1f..9fce2aa8 100644 --- a/rcr/templates/rcr/assessor_assignment_form.html +++ b/rcr/templates/rcr/assessor_assignment_form.html @@ -3,9 +3,10 @@ {% block content %} -

Items assigned:

+

Assign items to {{user_to_assign}}

+ {% csrf_token %} {{assessor_assignment_form}} diff --git a/rcr/templates/rcr/assessors.html b/rcr/templates/rcr/assessors.html index 27d19c50..3d5c5768 100644 --- a/rcr/templates/rcr/assessors.html +++ b/rcr/templates/rcr/assessors.html @@ -8,7 +8,7 @@ diff --git a/rcr/templates/rcr/index.html b/rcr/templates/rcr/index.html index 8192b6bc..0847c3e6 100644 --- a/rcr/templates/rcr/index.html +++ b/rcr/templates/rcr/index.html @@ -3,41 +3,55 @@ {% block content %} -{% if assessor %} -Assessor: {{assessor}} - -{% endif %} - + {% if assessor %} + Assessor: {{assessor}} + + {% endif %} -{% if completed %} -

Completed items:

-{% else %} -

Items to assess:

-{% endif %} - -{% if items %} - -Click to assess next item - -{% endif %} - - - + {% if completed %} +

Completed items:

+ {% else %} +

Items to assess:

+ {% endif %} -Todo -Done - -{% endblock %} \ No newline at end of file + {% if items %} + + Click to assess next item + + {% endif %} + + + + + + Todo + Done + +{% endblock %} + + +{% block css %} + + +{% endblock css %} diff --git a/rcr/templates/rcr/item_detail.html b/rcr/templates/rcr/item_detail.html index 753100ce..e00941bc 100644 --- a/rcr/templates/rcr/item_detail.html +++ b/rcr/templates/rcr/item_detail.html @@ -21,6 +21,9 @@

Date assessed: {{object.assessed_date}}

+

+ Assigned to: {{object.assigned_to}} +

Assessor(s): diff --git a/rcr/urls.py b/rcr/urls.py index 6a023709..86dd63db 100644 --- a/rcr/urls.py +++ b/rcr/urls.py @@ -14,6 +14,7 @@ urlpatterns = [ path("radiology/", views.radiology_index, name="radiology_index_view"), path("radiology/completed", views.radiology_index_completed, name="radiology_index_completed_view"), path("radiology/assessors", views.radiology_assessors, name="radiology_assessors_view"), + path("radiology/assigned/user/", views.radiology_assigned_user, name="radiology_assigned_user_view"), path("radiology/assessors//assignment", views.radiology_assessor_assignment, name="radiology_assessor_assignment_view"), path("radiology/completed/user/", views.radiology_index_completed_by_user, name="radiology_index_completed_by_user_view"), path("radiology/item//", views.ItemDetailView.as_view(), name="radiology_detail_view"), diff --git a/rcr/views.py b/rcr/views.py index 01dc7fb5..802c9bbf 100644 --- a/rcr/views.py +++ b/rcr/views.py @@ -1,23 +1,59 @@ from typing import Any from django.db import models -from django.http import Http404 +from django.http import Http404, HttpResponseRedirect from django.shortcuts import redirect, render -from django.urls import reverse_lazy +from django.urls import reverse, reverse_lazy from django.views.generic.edit import UpdateView from django.views.generic.detail import DetailView from django.shortcuts import get_object_or_404 from django.conf import settings from django.contrib.auth.models import User +from django.contrib.auth.decorators import user_passes_test from rcr.models import Item from rcr.forms import AssessorAssignmentForm, ItemForm +from django.core.exceptions import PermissionDenied # Create your views here. -def radiology_index(request): +def user_is_rcr(function): + def wrap(request, *args, **kwargs): + if ( + request.user.groups.filter(name="rcr_radiology_assessor").exists() + or request.user.is_superuser + ): + return function(request, *args, **kwargs) + else: + raise PermissionDenied - items = Item.objects.all().exclude(completed=True) + wrap.__doc__ = function.__doc__ + wrap.__name__ = function.__name__ + return wrap + + +class RCRRequiredMixin(object): + def get_object(self, *args, **kwargs): + obj = super().get_object(*args, **kwargs) + if ( + self.request.user.groups.filter(name="rcr_radiology_assessor").exists() + or self.request.user.is_superuser + ): + return obj + if self.request.user not in obj.get_author_objects(): + raise PermissionDenied() # or Http404 + + return obj + +@user_is_rcr +def radiology_index(request, assigned=True, user_pk: int | None = None): + + if assigned: + items = Item.objects.filter(assigned_to=request.user).exclude(completed=True) + elif user_pk is not None: + items = Item.objects.filter(assigned_to__pk=user_pk).exclude(completed=True) + else: + items = Item.objects.all().exclude(completed=True) return render( request, @@ -28,17 +64,39 @@ def radiology_index(request): }, ) +@user_passes_test(lambda u: u.is_superuser) def radiology_assessor_assignment(request, assessor_pk: int): - assessor_assignment_form = AssessorAssignmentForm() + + user = get_object_or_404(User, pk=assessor_pk) + if request.method == "POST": + assessor_assignment_form = AssessorAssignmentForm(request.POST) + + if assessor_assignment_form.is_valid(): + items_to_update = assessor_assignment_form.cleaned_data["items"] + for item in items_to_update: + item.assigned_to = user + + Item.objects.filter(pk__in=items_to_update).bulk_update(items_to_update, ["assigned_to"]) + + return HttpResponseRedirect(reverse("rcr:radiology_assessors_view")) + else: + assessor_assignment_form = AssessorAssignmentForm() return render( request, "rcr/assessor_assignment_form.html", { "assessor_assignment_form": assessor_assignment_form, + "user_to_assign": user }, ) +@user_is_rcr +def radiology_assigned_user(request, user_pk=int): + return radiology_index(request, user_pk=user_pk) + pass + +@user_is_rcr def radiology_assessors(request): assessors = User.objects.filter(groups__name="rcr_radiology_assessor") @@ -50,9 +108,11 @@ def radiology_assessors(request): }, ) +@user_is_rcr def radiology_index_completed_by_user(request, user_pk: int): return radiology_index_completed(request, user_pk = user_pk) +@user_is_rcr def radiology_index_completed(request, user_pk=None): assessor = None @@ -73,7 +133,7 @@ def radiology_index_completed(request, user_pk=None): ) -class ItemUpdateBase(UpdateView): +class ItemUpdateBase(UpdateView, RCRRequiredMixin): def form_valid(self, form): self.object = form.save(commit=False) self.object.save() @@ -81,7 +141,7 @@ class ItemUpdateBase(UpdateView): form.instance.assessed_by.add(self.request.user.id) return super().form_valid(form) -class ItemUpdateView(ItemUpdateBase): +class ItemUpdateView(ItemUpdateBase, RCRRequiredMixin): model = Item form_class = ItemForm @@ -89,7 +149,7 @@ class ItemUpdateView(ItemUpdateBase): #excludes = ["rcr_platform_id"] #fields = ["category", "level"] -class ItemUpdateNextView(ItemUpdateBase): +class ItemUpdateNextView(ItemUpdateBase, RCRRequiredMixin): model = Item form_class = ItemForm @@ -142,7 +202,7 @@ class ItemUpdateNextView(ItemUpdateBase): -class ItemDetailView(DetailView): +class ItemDetailView(DetailView, RCRRequiredMixin): model = Item #template_name = "TEMPLATE_NAME" #excludes = ["rcr_platform_id"]