import graphene from django.core.exceptions import MultipleObjectsReturned from graphene import relay from graphql_relay import from_global_id from rest_framework.exceptions import PermissionDenied from api.utils import get_object from assignments.models import Assignment, StudentSubmission, SubmissionFeedback from assignments.schema.types import AssignmentNode, StudentSubmissionNode, SubmissionFeedbackNode from .inputs import AssignmentInput, SubmissionFeedbackInput class UpdateAssignment(relay.ClientIDMutation): class Input: assignment = graphene.Argument(AssignmentInput) updated_assignment = graphene.Field(AssignmentNode) submission = graphene.Field(StudentSubmissionNode) successful = graphene.Boolean() errors = graphene.List(graphene.String) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): assignment_data = kwargs.get('assignment') assignment = get_object(Assignment, assignment_data.get('id')) student = info.context.user # todo: replace with middleware if student.read_only: raise PermissionError('No valid license') try: (submission, _created) = assignment.submissions.get_or_create(student=student) except MultipleObjectsReturned: for submission in assignment.submissions.filter(student=student): submission.delete() submission = assignment.submissions.create(student=student) submission.text = assignment_data.get('answer', '') submission.document = assignment_data.get('document', '') final = assignment_data.get('final') if final is not None: submission.final = final submission.save() return cls(successful=True, updated_assignment=assignment, submission=submission, errors=None) class UpdateSubmissionFeedback(relay.ClientIDMutation): class Input: submission_feedback = graphene.Argument(SubmissionFeedbackInput) updated_submission_feedback = graphene.Field(SubmissionFeedbackNode) successful = graphene.Boolean() errors = graphene.List(graphene.String) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): submission_feedback_data = kwargs.get('submission_feedback') user = info.context.user student_submission_id = from_global_id(submission_feedback_data['student_submission'])[1] student_submission = StudentSubmission.objects.get(id=student_submission_id) if not user.is_teacher() or not student_submission.student in user.users_in_active_school_class(): raise PermissionDenied('Missing permissions') # todo: replace with middleware if user.read_only: raise PermissionError('No valid license') (submission_feedback, created) = SubmissionFeedback.objects.get_or_create( student_submission_id=student_submission_id, defaults={ 'teacher': user }) final = submission_feedback_data.get( 'final') if 'final' in submission_feedback_data else submission_feedback.final submission_feedback.teacher = user submission_feedback.final = final submission_feedback.text = submission_feedback_data.get('text') submission_feedback.save() return cls(successful=True, updated_submission_feedback=submission_feedback, errors=None) class AssignmentMutations(object): update_assignment = UpdateAssignment.Field() update_submission_feedback = UpdateSubmissionFeedback.Field()