From 0068c3459032057ca6d7a3d9e799e88132011d42 Mon Sep 17 00:00:00 2001
From: "dominik.seeger" <dominik.seeger@stud.uni-goettingen.de>
Date: Wed, 14 Aug 2019 12:50:34 +0200
Subject: [PATCH] added dedicated logic for reviewer final validation

---
 core/migrations/0018_auto_20190709_1526.py | 23 ++++++++++++++++++++++
 core/models/feedback.py                    |  3 +++
 core/serializers/feedback.py               | 11 ++++++++++-
 core/views/feedback.py                     |  7 ++-----
 4 files changed, 38 insertions(+), 6 deletions(-)
 create mode 100644 core/migrations/0018_auto_20190709_1526.py

diff --git a/core/migrations/0018_auto_20190709_1526.py b/core/migrations/0018_auto_20190709_1526.py
new file mode 100644
index 00000000..468d2442
--- /dev/null
+++ b/core/migrations/0018_auto_20190709_1526.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2 on 2019-07-09 15:26
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0017_auto_20190604_1631'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='feedback',
+            name='final_by_reviewer',
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AlterField(
+            model_name='feedbacklabel',
+            name='name',
+            field=models.CharField(max_length=50, unique=True),
+        ),
+    ]
diff --git a/core/models/feedback.py b/core/models/feedback.py
index 15eea22c..742f9428 100644
--- a/core/models/feedback.py
+++ b/core/models/feedback.py
@@ -25,10 +25,13 @@ class Feedback(models.Model):
         points a student receives for his submission.
     origin : IntegerField
         Of whom was this feedback originally created. She below for the choices
+    final_by_reviewer: BooleanField
+        Whether or not this feedback was set to final by a reviewer once
     """
     score = models.DecimalField(max_digits=5, decimal_places=2, default=0)
     created = models.DateTimeField(auto_now_add=True)
     is_final = models.BooleanField(default=False)
+    final_by_reviewer = models.BooleanField(default=False)
 
     of_submission = models.OneToOneField(
         Submission,
diff --git a/core/serializers/feedback.py b/core/serializers/feedback.py
index 92416e1e..da0d45e5 100644
--- a/core/serializers/feedback.py
+++ b/core/serializers/feedback.py
@@ -7,7 +7,7 @@ from rest_framework import serializers
 from rest_framework.utils import html
 
 from core import models
-from core.models import Feedback
+from core.models import Feedback, UserAccount
 from util.factories import GradyUserFactory
 
 from .generic import DynamicFieldsModelSerializer
@@ -121,8 +121,12 @@ class FeedbackSerializer(DynamicFieldsModelSerializer):
         submission = validated_data.pop('of_submission')
         feedback_lines = validated_data.pop('feedback_lines', [])
         labels = validated_data.pop('labels', [])
+        user = self.context['request'].user
         feedback = Feedback.objects.create(of_submission=submission,
                                            **validated_data)
+        if user.role == UserAccount.REVIEWER:
+            feedback.final_by_reviewer = self.context['request'].data['is_final']
+
         for label in labels:
             feedback.labels.add(label)
 
@@ -141,6 +145,11 @@ class FeedbackSerializer(DynamicFieldsModelSerializer):
 
     @transaction.atomic
     def update(self, feedback, validated_data):
+        user = self.context['request'].user
+
+        if user.role == UserAccount.REVIEWER:
+            feedback.final_by_reviewer = self.context['request'].data['is_final']
+
         for comment in validated_data.pop('feedback_lines', []):
             labels = comment.pop('labels', [])
             comment_instance, _ = models.FeedbackComment.objects.update_or_create(
diff --git a/core/views/feedback.py b/core/views/feedback.py
index 27211eb7..e7ccfb22 100644
--- a/core/views/feedback.py
+++ b/core/views/feedback.py
@@ -28,12 +28,9 @@ class FeedbackApiView(
     lookup_url_kwarg = 'submission_pk'
 
     def _tutor_attempts_to_change_final_feedback_of_reviewer(self, serializer):
-        feedback_is_final = serializer.instance.is_final
+        feedback_final_by_reviewer = serializer.instance.final_by_reviewer
         user_is_tutor = self.request.user.role == models.UserAccount.TUTOR
-        authors = serializer.instance.of_submission.meta.feedback_authors
-        set_by_reviewer = authors.filter(
-            role=models.UserAccount.REVIEWER).exists()
-        return feedback_is_final and set_by_reviewer and user_is_tutor
+        return feedback_final_by_reviewer and user_is_tutor
 
     def _get_implicit_assignment_for_user(self, submission):
         """ Check for tutor if it exists. Not relevant for reviewer """
-- 
GitLab