diff --git a/core/models/assignment.py b/core/models/assignment.py
index fc8cfa17a8dbd90fa730178ce72bf5ed16782ea1..77967461ac5c5ec4cda6b5dfc1e0df803c95d8f7 100644
--- a/core/models/assignment.py
+++ b/core/models/assignment.py
@@ -14,6 +14,10 @@ class DeletionOfDoneAssignmentsNotPermitted(Exception):
     pass
 
 
+class CanOnlyCallFinishOnUnfinishedAssignments(Exception):
+    pass
+
+
 class TutorSubmissionAssignment(models.Model):
 
     assignment_id = models.UUIDField(primary_key=True,
@@ -32,6 +36,20 @@ class TutorSubmissionAssignment(models.Model):
         return (f'{self.subscription.owner} assigned to {self.submission}'
                 f' (done={self.is_done})')
 
+    def finish(self):
+        self.refresh_from_db()
+        if self.is_done:
+            raise CanOnlyCallFinishOnUnfinishedAssignments()
+
+        meta = self.submission.meta
+        # TODO add reviewer final
+        meta.feedback_authors.add(self.subscription.owner)
+        meta.done_assignments += 1
+        meta.has_active_assignment = False
+        self.is_done = True
+        self.save()
+        meta.save()
+
     def delete(self, *args, **kwargs):
         if self.is_done:
             raise DeletionOfDoneAssignmentsNotPermitted()
diff --git a/core/models/submission.py b/core/models/submission.py
index 3687fb679af0458ee21f0e8d9d2575ba40c6ff82..f968a6576dfe208b0405b50ce9ad15887dc118b6 100644
--- a/core/models/submission.py
+++ b/core/models/submission.py
@@ -63,7 +63,9 @@ class MetaSubmission(models.Model):
     done_assignments = models.PositiveIntegerField(default=0)
     has_active_assignment = models.BooleanField(default=False)
 
+    # Managed by signal!
     has_feedback = models.BooleanField(default=False)
+    # Managed by signal!
     has_final_feedback = models.BooleanField(default=False)
 
     feedback_authors = models.ManyToManyField(get_user_model())
diff --git a/core/serializers/feedback.py b/core/serializers/feedback.py
index 92416e1ecfd3a38fe3a5b37c9b68e9dcee42b5d5..238d5d1ca992239f561810c7787de41dc3764b51 100644
--- a/core/serializers/feedback.py
+++ b/core/serializers/feedback.py
@@ -192,8 +192,7 @@ class FeedbackSerializer(DynamicFieldsModelSerializer):
             raise serializers.ValidationError(
                 'Sorry, you have to explain why this does not get full score')
 
-        http_method = self.context['request'].method
-        if hasattr(submission, 'feedback') and http_method == 'POST':
+        if hasattr(submission, 'feedback') and not self.instance:
             raise serializers.ValidationError(
                 'Feedback for this submission already exists')
 
diff --git a/core/signals.py b/core/signals.py
index 95cdcc1a46c21bdc27e5af7389418f1f0fba212d..110a15e8a76c9b7ddf9f6d8aa125c3eb2f50dfce 100644
--- a/core/signals.py
+++ b/core/signals.py
@@ -50,16 +50,6 @@ def update_after_feedback_save(sender, instance, created, **kwargs):
     meta = instance.of_submission.meta
     meta.has_feedback = True
     meta.has_final_feedback = instance.is_final
-
-    undone_assignment = meta.submission.assignments.filter(is_done=False)
-    assert undone_assignment.count() <= 1
-    if undone_assignment.count() > 0:
-        log.debug('SIGNAL -- Completed: %s' % undone_assignment.first())
-        meta.feedback_authors.add(undone_assignment.first().subscription.owner)
-        meta.done_assignments += 1
-        meta.has_active_assignment = False
-        undone_assignment.update(is_done=True)
-
     meta.save()
 
 
diff --git a/core/tests/test_custom_subscription_filter.py b/core/tests/test_custom_subscription_filter.py
index 64525f58e70c9a03f636e02b80e1a13dcbc5a811..c6ac17671dc294c5d314d187a9053b197d09e880 100644
--- a/core/tests/test_custom_subscription_filter.py
+++ b/core/tests/test_custom_subscription_filter.py
@@ -140,6 +140,7 @@ class StopOnPass(APITestCase):
         self.assertEqual(35, self.data['students'][0].student.total_score)
         self.assertTrue(self.data['students'][0].student.passes_exam)
 
+    # TODO why is this code commented?!?
     # def test_submissions_left_after_not_pass_only_student_passed_exam(self):
     #     Feedback.objects.create(
     #         of_submission=self.data['submissions'][3], score=20)
@@ -164,8 +165,10 @@ class StopOnPass(APITestCase):
         # signals recognize the open assignments
         Feedback.objects.create(
             of_submission=a1.submission, score=20)
+        a1.finish()
         Feedback.objects.create(
             of_submission=a2.submission, score=15)
+        a2.finish()
 
         subscription_other_tutor = SubmissionSubscription.objects.create(
             owner=self.tutor02,
@@ -188,8 +191,10 @@ class StopOnPass(APITestCase):
         # signals recognize the open assignments
         Feedback.objects.create(
             of_submission=a1.submission, score=20)
+        a1.finish()
         Feedback.objects.create(
             of_submission=a2.submission, score=15)
+        a2.finish()
 
         subscription_other_tutor = SubmissionSubscription.objects.create(
             owner=self.tutor02,
diff --git a/core/tests/test_feedback.py b/core/tests/test_feedback.py
index dea21a728a6556da10f7cfdb0dd57d225e936dbe..7217cc8630cfcfd00b4dc96ac666a839e199c235 100644
--- a/core/tests/test_feedback.py
+++ b/core/tests/test_feedback.py
@@ -93,7 +93,7 @@ class FeedbackCreateTestCase(APITestCase):
 
     @classmethod
     def setUpTestData(cls):
-        cls.url = '/api/feedback/'
+        cls.url = lambda self: f'/api/assignment/{self.assignment.pk}/finish/'
         cls.user_factory = GradyUserFactory()
         cls.tutor = cls.user_factory.make_tutor(password='p')
         cls.exam = make_exams(exams=[{
@@ -138,7 +138,7 @@ class FeedbackCreateTestCase(APITestCase):
 
         }
         self.assertEqual(Feedback.objects.count(), 0)
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
         self.assertEqual(Feedback.objects.count(), 0)
 
@@ -149,7 +149,7 @@ class FeedbackCreateTestCase(APITestCase):
             'of_submission': self.assignment.submission.pk
         }
         self.assertEqual(Feedback.objects.count(), 0)
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
         self.assertEqual(Feedback.objects.count(), 0)
 
@@ -159,7 +159,7 @@ class FeedbackCreateTestCase(APITestCase):
             'is_final': True,
             'of_submission': self.assignment.submission.pk
         }
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)
         self.assertEqual(Feedback.objects.count(), 0)
 
@@ -169,7 +169,7 @@ class FeedbackCreateTestCase(APITestCase):
             'is_final': False,
             'of_submission': self.assignment.submission.pk
         }
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
         self.assertEqual(Feedback.objects.count(), 0)
 
@@ -180,7 +180,7 @@ class FeedbackCreateTestCase(APITestCase):
             'of_submission': self.assignment.submission.pk
         }
         self.assertEqual(Feedback.objects.count(), 0)
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
         self.assertEqual(Feedback.objects.count(), 0)
 
@@ -191,7 +191,7 @@ class FeedbackCreateTestCase(APITestCase):
             'of_submission': self.assignment.submission.pk
         }
         self.assertEqual(Feedback.objects.count(), 0)
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
         self.assertEqual(Feedback.objects.count(), 0)
 
@@ -209,7 +209,7 @@ class FeedbackCreateTestCase(APITestCase):
             }
         }
         self.assertEqual(self.fst_label.feedback.count(), 0)
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
         self.fst_label.refresh_from_db()
         self.snd_label.refresh_from_db()
@@ -229,7 +229,7 @@ class FeedbackCreateTestCase(APITestCase):
                 }
             }
         }
-        self.client.post(self.url, data, format='json')
+        self.client.post(self.url(), data, format='json')
         object_score = self.sub.feedback.score
         self.assertEqual(object_score, 0.5)
 
@@ -245,7 +245,7 @@ class FeedbackCreateTestCase(APITestCase):
                 }
             }
         }
-        self.client.post(self.url, data, format='json')
+        self.client.post(self.url(), data, format='json')
         object_score = self.sub.feedback.score
         self.assertEqual(object_score, 5)
 
@@ -262,7 +262,7 @@ class FeedbackCreateTestCase(APITestCase):
             }
         }
         self.assertEqual(FeedbackComment.objects.count(), 0)
-        response = self.client.post(self.url, data, format='json')
+        response = self.client.post(self.url(), data, format='json')
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
         self.assertEqual(FeedbackComment.objects.count(), 1)
 
@@ -278,7 +278,7 @@ class FeedbackCreateTestCase(APITestCase):
                 }
             }
         }
-        self.client.post(self.url, data, format='json')
+        self.client.post(self.url(), data, format='json')
         comment = FeedbackComment.objects.first()
         self.assertEqual(comment.of_tutor, self.tutor)
         self.assertEqual(comment.text, 'Nice meth!')
@@ -298,8 +298,8 @@ class FeedbackCreateTestCase(APITestCase):
             }
         }
         self.assignment.delete()
-        response = self.client.post(self.url, data, format='json')
-        self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)
+        response = self.client.post(self.url(), data, format='json')
+        self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
 
     def test_cannot_create_with_someoneelses_assignment(self):
         data = {
@@ -314,8 +314,9 @@ class FeedbackCreateTestCase(APITestCase):
         }
         other_tutor = self.user_factory.make_tutor('Berta')
         self.client.force_authenticate(other_tutor)
-        response = self.client.post(self.url, data, format='json')
-        self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)
+        response = self.client.post(self.url(), data, format='json')
+        # returns 404 since the other users assignment is not visible to this one
+        self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
 
     def test_can_create_multiple_feedback_comments(self):
         data = {
@@ -333,7 +334,7 @@ class FeedbackCreateTestCase(APITestCase):
                 }
             }
         }
-        self.client.post(self.url, data, format='json')
+        self.client.post(self.url(), data, format='json')
         first_comment = FeedbackComment.objects.get(text='Nice meth!')
         self.assertEqual(first_comment.of_tutor, self.tutor)
         self.assertIsNotNone(first_comment.created)
diff --git a/core/tests/test_subscription_assignment_service.py b/core/tests/test_subscription_assignment_service.py
index 79f0f14a6c4e9c2a83233e9372a8e2ed29a147c4..c4522609815a3e07c7610032f334ac5bcae009fd 100644
--- a/core/tests/test_subscription_assignment_service.py
+++ b/core/tests/test_subscription_assignment_service.py
@@ -235,7 +235,6 @@ class TestApiEndpoints(APITestCase):
 
         response_subscription_create = self.client.post(
             '/api/subscription/', {'query_type': 'random'})
-        subscription_pk = response_subscription_create.data['pk']
 
         subscription_pk = response_subscription_create.data['pk']
         response_assignment = self.client.post(
@@ -374,7 +373,7 @@ class TestApiEndpoints(APITestCase):
             })
         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
         response = self.client.post(
-            f'/api/feedback/', {
+            f'/api/assignment/{response.data["pk"]}/finish/', {
                 "score": 23,
                 "of_submission": response.data['submission']['pk'],
                 "feedback_lines": {
@@ -415,8 +414,8 @@ class TestApiEndpoints(APITestCase):
         assignment = models.TutorSubmissionAssignment.objects.get(
             pk=response.data['pk'])
         self.assertFalse(assignment.is_done)
-        response = self.client.patch(
-            '/api/feedback/%s/' % submission_id_in_response, {
+        response = self.client.post(
+            f'/api/assignment/{assignment.pk}/finish/', {
                 "score": 20,
                 "is_final": True,
                 "feedback_lines": {
diff --git a/core/tests/test_tutor_api_endpoints.py b/core/tests/test_tutor_api_endpoints.py
index 7d0f0fc7fd743d21d1b5275141ade200c50d0a80..343b649dc81098ba91078b6e571939b029e9c29d 100644
--- a/core/tests/test_tutor_api_endpoints.py
+++ b/core/tests/test_tutor_api_endpoints.py
@@ -107,6 +107,7 @@ class TutorListTests(APITestCase):
             Feedback.objects.update_or_create(
                 of_submission=assignment.submission,
                 score=35)
+            assignment.finish()
 
         tutor01 = data['tutors'][0]
         tutor02 = data['tutors'][1]
diff --git a/core/urls.py b/core/urls.py
index b0e100b4eb80741b1684cdf98fa9aee7daa4d9b0..aee6e268814e22e9ef38d5f84e62f158ec4ec89f 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -7,6 +7,7 @@ from rest_framework.permissions import AllowAny
 from core import views
 
 # Create a router and register our viewsets with it.
+
 router = DefaultRouter()
 router.register('student', views.StudentReviewerApiViewSet,
                 basename='student')
diff --git a/core/views/feedback.py b/core/views/feedback.py
index 27211eb78eac54d51cc91405b0bda14b33212419..78d943e8ceab625e674283306312ba1397856b82 100644
--- a/core/views/feedback.py
+++ b/core/views/feedback.py
@@ -4,8 +4,11 @@ from multiprocessing import Lock
 from rest_framework import mixins, status, viewsets
 from rest_framework.exceptions import PermissionDenied
 from rest_framework.response import Response
+from rest_framework import decorators
 
 from core import models, permissions, serializers
+from core.views.util import tutor_attempts_to_patch_first_feedback_final, \
+    get_implicit_assignment_for_user
 
 log = logging.getLogger(__name__)
 
@@ -17,11 +20,11 @@ class FeedbackApiView(
         viewsets.GenericViewSet):
     """ Gets a list of an individual exam by Id if provided """
     permission_classes = (permissions.IsTutorOrReviewer,)
-    queryset = models.Feedback.objects\
-        .select_related('of_submission')\
-        .select_related('of_submission__type')\
-        .select_related('of_submission__student')\
-        .select_related('of_submission__student__user')\
+    queryset = models.Feedback.objects \
+        .select_related('of_submission') \
+        .select_related('of_submission__type') \
+        .select_related('of_submission__student') \
+        .select_related('of_submission__student__user') \
         .all()
     serializer_class = serializers.FeedbackSerializer
     lookup_field = 'of_submission__pk'
@@ -35,44 +38,11 @@ class FeedbackApiView(
             role=models.UserAccount.REVIEWER).exists()
         return feedback_is_final and set_by_reviewer and user_is_tutor
 
-    def _get_implicit_assignment_for_user(self, submission):
-        """ Check for tutor if it exists. Not relevant for reviewer """
-        try:
-            return models.TutorSubmissionAssignment.objects.get(
-                subscription__owner=self.request.user,
-                submission=submission
-            )
-        except models.TutorSubmissionAssignment.DoesNotExist:
-            if self.request.user.role == models.UserAccount.REVIEWER:
-                return None
-            raise PermissionDenied(
-                detail='This user has no permission to create this feedback')
-
     def _tutor_attempts_to_set_first_feedback_final(self, serializer):
         is_final_set = serializer.validated_data.get('is_final', False)
         user_is_tutor = self.request.user.role == models.UserAccount.TUTOR
         return is_final_set and user_is_tutor
 
-    # unused
-    def _tutor_is_allowed_to_change_own_feedback(self, serializer):
-        submission = self.get_object().of_submission
-        assignment = self._get_implicit_assignment_for_user(submission)
-        youngest = models.TutorSubmissionAssignment.objects \
-            .filter(submission=submission) \
-            .order_by('-created') \
-            .first()
-
-        return assignment == youngest
-
-    def _tutor_attempts_to_patch_first_feedback_final(self, serializer):
-        if self.request.user.role == models.UserAccount.REVIEWER:
-            return False
-        is_final_set = serializer.validated_data.get('is_final', False)
-        submission = self.get_object().of_submission
-        assignment = self._get_implicit_assignment_for_user(submission)
-        in_creation = assignment.subscription.feedback_stage == models.SubmissionSubscription.FEEDBACK_CREATION  # noqa
-        return is_final_set and in_creation
-
     def get_queryset(self):
         if self.request.user.is_reviewer():
             return self.queryset \
@@ -84,19 +54,16 @@ class FeedbackApiView(
             of_submission__assignments__subscription__owner=self.request.user
         )
 
+    @decorators.permission_classes((permissions.IsReviewer,))
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.data)
         serializer.is_valid(raise_exception=True)
-
-        self._get_implicit_assignment_for_user(
-            serializer.validated_data['of_submission'])
-
-        if self._tutor_attempts_to_set_first_feedback_final(serializer):
-            return Response(
-                {'For tutors it is not allowed to create feedback final.'},
-                status=status.HTTP_403_FORBIDDEN)
-
         self.perform_create(serializer)
+
+        # update MetaSubmission information
+        meta = serializer.validated_data.get('of_submission').meta
+        # TODO add reviewer final
+        meta.feedback_authors.add(self.request.user)
         return Response(serializer.data,
                         status=status.HTTP_201_CREATED)
 
@@ -106,16 +73,17 @@ class FeedbackApiView(
                                          partial=True)
         serializer.is_valid(raise_exception=True)
 
-        self._get_implicit_assignment_for_user(feedback.of_submission)
+        assignment = get_implicit_assignment_for_user(feedback.of_submission, self.request.user)
 
+        # TODO change this to check reviewer final
         if self._tutor_attempts_to_change_final_feedback_of_reviewer(serializer):  # noqa
             raise PermissionDenied(
                 detail="Changing final feedback is not allowed.")
 
-        if self._tutor_attempts_to_patch_first_feedback_final(serializer):
+        if tutor_attempts_to_patch_first_feedback_final(serializer, self.request.user, assignment):
             raise PermissionDenied(
                 detail='Cannot set the first feedback final.')
-
+        # TODO add reviewer final
         serializer.save()
         return Response(serializer.data)
 
diff --git a/core/views/subscription.py b/core/views/subscription.py
index bf77f46731c17239e9720d59ce3ca02b5d55d828..2ea0b0c01cb79898116a1b2f04e4c00504a40f96 100644
--- a/core/views/subscription.py
+++ b/core/views/subscription.py
@@ -2,7 +2,8 @@ import logging
 
 from django.core.exceptions import ObjectDoesNotExist
 from rest_framework import mixins, status, viewsets
-from rest_framework.decorators import action, permission_classes
+from rest_framework import decorators
+from rest_framework.exceptions import PermissionDenied
 from rest_framework.response import Response
 
 from core import models, permissions, serializers
@@ -12,6 +13,8 @@ from core.serializers import AssignmentDetailSerializer, AssignmentSerializer
 
 from multiprocessing import Lock
 
+from core.views.util import tutor_attempts_to_patch_first_feedback_final
+
 log = logging.getLogger(__name__)
 
 
@@ -76,6 +79,7 @@ class AssignmentApiViewSet(
     queryset = TutorSubmissionAssignment.objects\
         .select_related('subscription').all()
     serializer_class = AssignmentSerializer
+    permission_classes = (IsTutorOrReviewer, )
 
     def get_queryset(self):
         if self.action in ['list', 'active', 'destroy']:
@@ -97,11 +101,11 @@ class AssignmentApiViewSet(
                             status=status.HTTP_403_FORBIDDEN)
         return Response(serializer.data, status=status.HTTP_201_CREATED)
 
-    @permission_classes((IsReviewer,))
+    @decorators.permission_classes((IsReviewer,))
     def list(self, *args, **kwargs):
         return super().list(*args, **kwargs)
 
-    @action(detail=False, permission_classes=(IsReviewer,), methods=['get', 'delete'])
+    @decorators.action(detail=False, permission_classes=(IsReviewer,), methods=['get', 'delete'])
     def active(self, request):
         if request.method == 'GET':
             queryset = self.get_queryset().filter(is_done=False)
@@ -111,7 +115,36 @@ class AssignmentApiViewSet(
             self.get_queryset().filter(is_done=False).delete()
             return Response(status=status.HTTP_204_NO_CONTENT)
 
-    @permission_classes((IsTutorOrReviewer,))
+    @decorators.action(detail=True, methods=['post'])
+    def finish(self, request, *args, **kwargs):
+        context = self.get_serializer_context()
+        instance = self.get_object()
+        if instance.is_done or (instance.subscription.owner != request.user):
+            return Response(status=status.HTTP_403_FORBIDDEN)
+        try:
+            orig_feedback = instance.submission.feedback
+            serializer = serializers.FeedbackSerializer(
+                orig_feedback,
+                data=request.data,
+                context=context,
+                partial=True)
+        except models.Feedback.DoesNotExist:
+            serializer = serializers.FeedbackSerializer(
+                data=request.data,
+                context=context)
+
+        serializer.is_valid(raise_exception=True)
+        if tutor_attempts_to_patch_first_feedback_final(serializer, self.request.user, instance):
+            raise PermissionDenied(
+                detail='Cannot set the first feedback final.')
+        # TODO check if is reviewer final
+        serializer.save()
+        instance.finish()
+        response_status = status.HTTP_201_CREATED if \
+            instance.subscription.feedback_stage == \
+            models.SubmissionSubscription.FEEDBACK_CREATION else status.HTTP_200_OK
+        return Response(serializer.data, status=response_status)
+
     def destroy(self, request, pk=None):
         """ Stop working on the assignment before it is finished """
         instance = self.get_object()
@@ -123,7 +156,6 @@ class AssignmentApiViewSet(
         instance.delete()
         return Response(status=status.HTTP_204_NO_CONTENT)
 
-    @permission_classes((IsTutorOrReviewer,))
     def create(self, request, *args, **kwargs):
         with Lock():
             context = self.get_serializer_context()
@@ -133,7 +165,6 @@ class AssignmentApiViewSet(
             assignment = self._fetch_assignment(serializer)
         return assignment
 
-    @permission_classes((IsTutorOrReviewer,))
     def retrieve(self, request, *args, **kwargs):
         assignment = self.get_object()
         if assignment.subscription.owner != request.user:
diff --git a/core/views/util.py b/core/views/util.py
new file mode 100644
index 0000000000000000000000000000000000000000..b03018738c2767f49c46cb3f0d32cf5adf61da5b
--- /dev/null
+++ b/core/views/util.py
@@ -0,0 +1,33 @@
+from rest_framework.exceptions import PermissionDenied
+
+from core import models
+
+
+class NoAssignmentForTutor(Exception):
+    pass
+
+
+def tutor_attempts_to_patch_first_feedback_final(feedback_serializer,
+                                                 user,
+                                                 assignment=None):
+    if user.role == models.UserAccount.REVIEWER:
+        return False
+    if user.role == models.UserAccount.TUTOR and assignment is None:
+        raise NoAssignmentForTutor()
+    is_final_set = feedback_serializer.validated_data.get('is_final', False)
+    in_creation = assignment.subscription.feedback_stage == models.SubmissionSubscription.FEEDBACK_CREATION  # noqa
+    return is_final_set and in_creation
+
+
+def get_implicit_assignment_for_user(submission, user):
+    """ Check for tutor if it exists. Not relevant for reviewer """
+    try:
+        return models.TutorSubmissionAssignment.objects.get(
+            subscription__owner=user,
+            submission=submission
+        )
+    except models.TutorSubmissionAssignment.DoesNotExist:
+        if user.role == models.UserAccount.REVIEWER:
+            return None
+        raise PermissionDenied(
+            detail='This user has no permission to create this feedback')
diff --git a/frontend/src/api.ts b/frontend/src/api.ts
index 1fa6700d78eb3fe7818911fd61fd5746032b8087..89674f81ec3743523859c381052e89ee40f089e1 100644
--- a/frontend/src/api.ts
+++ b/frontend/src/api.ts
@@ -151,14 +151,19 @@ export async function createAssignment (
   return (await ax.post(`/api/assignment/`, data)).data
 }
 
-export async function submitFeedbackForAssignment ({ feedback }: {feedback: Partial<Feedback>}): Promise<Feedback> {
-  return (await ax.post('/api/feedback/', feedback)).data
+export async function submitFeedbackForAssignment ({ feedback, assignment }:
+  {feedback: Partial<Feedback>, assignment: Assignment}): Promise<Feedback> {
+  return (await ax.post(`/api/assignment/${assignment.pk}/finish/`, feedback)).data
 }
 
-export async function submitUpdatedFeedback ({ feedback }: {feedback: Feedback}): Promise<Feedback> {
+export async function submitUpdatedFeedback ({ feedback }: {feedback: Partial<Feedback>}): Promise<Feedback> {
   return (await ax.patch(`/api/feedback/${feedback.ofSubmission}/`, feedback)).data
 }
 
+export async function submitFeedback ({feedback}: {feedback: Partial<Feedback>}): Promise<Feedback> {
+  return (await ax.post(`/api/feedback/`, feedback)).data
+}
+
 export async function fetchSubmissionTypes (): Promise<Array<SubmissionType>> {
   const url = '/api/submissiontype/'
   return (await ax.get(url)).data
diff --git a/frontend/src/store/modules/submission-notes.ts b/frontend/src/store/modules/submission-notes.ts
index 9055ea8149c89903f09f1973c44e527e3e4440b4..7afa5c0912737ca0a896111e30d8200cdf727c66 100644
--- a/frontend/src/store/modules/submission-notes.ts
+++ b/frontend/src/store/modules/submission-notes.ts
@@ -6,6 +6,7 @@ import { RootState } from '@/store/store'
 import { getStoreBuilder, BareActionContext } from 'vuex-typex'
 import { syntaxPostProcess } from '@/util/helpers';
 import { AxiosResponse } from 'axios';
+import { Subscriptions } from './subscriptions';
 
 export interface SubmissionNotesState {
   submission: SubmissionNoType
@@ -181,11 +182,15 @@ Promise<AxiosResponse<void>[]> {
   } else if (feedback.score! < SubmissionNotes.submissionType.fullScore! && !state.hasOrigFeedback) {
     throw new Error('You need to add or change a comment when setting a non full score.')
   }
-  if (!state.hasOrigFeedback) {
-    await api.submitFeedbackForAssignment({ feedback })
-  } else {
+
+  const assignment = Subscriptions.state.currentAssignment
+  if (assignment) {
+    await api.submitFeedbackForAssignment({ feedback , assignment})
+  } else if (state.origFeedback) {
     feedback.pk = state.origFeedback.pk
-    await api.submitUpdatedFeedback(<{ feedback: Feedback }>{ feedback })
+    await api.submitUpdatedFeedback({ feedback })
+  } else {
+    await api.submitFeedback({feedback})
   }
   // delete those comments that have been marked for deletion
   return SubmissionNotes.deleteComments()
diff --git a/functional_tests/test_export_modal.py b/functional_tests/test_export_modal.py
index e6af20036648a6088aa782c685f137db3e70722d..6fa6aa168cd3280f6e34f7e0b4c9c9c66d295531 100644
--- a/functional_tests/test_export_modal.py
+++ b/functional_tests/test_export_modal.py
@@ -117,8 +117,8 @@ class ExportTestModal(LiveServerTestCase):
         os.remove(JSON_EXPORT_FILE)
 
     def test_export_instance(self):
-        self._login()
         fact.SubmissionFactory()
+        self._login()
         self.browser.find_element_by_id('export-btn').click()
         self.browser.find_element_by_id('export-list1').click()
         instance_export_modal = self.browser.find_element_by_id('instance-export-modal')