vbv/server/vbv_lernwelt/assignment/graphql/mutations.py

138 lines
4.9 KiB
Python

import json
import graphene
import structlog
from rest_framework.exceptions import PermissionDenied
from wagtail.models import Page
from vbv_lernwelt.assignment.graphql.types import AssignmentCompletionObjectType
from vbv_lernwelt.assignment.models import Assignment, AssignmentCompletionStatus
from vbv_lernwelt.assignment.services import update_assignment_completion
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.iam.permissions import can_evaluate_assignments, has_course_access
logger = structlog.get_logger(__name__)
class AssignmentCompletionMutation(graphene.Mutation):
assignment_completion = graphene.Field(AssignmentCompletionObjectType)
class Arguments:
assignment_id = graphene.ID(required=True)
course_session_id = graphene.ID(required=True)
learning_content_page_id = graphene.ID()
assignment_user_id = graphene.UUID()
completion_status = graphene.Argument(
graphene.Enum.from_enum(AssignmentCompletionStatus)
)
completion_data_string = graphene.String()
evaluation_points = graphene.Float()
evaluation_passed = graphene.Boolean()
evaluation_user_id = graphene.ID(required=False)
initialize_completion = graphene.Boolean(required=False)
@classmethod
def mutate(
cls,
root,
info,
assignment_id,
course_session_id,
learning_content_page_id=None,
assignment_user_id=None,
completion_status: AssignmentCompletionStatus = AssignmentCompletionStatus.IN_PROGRESS,
completion_data_string="{}",
evaluation_points=None,
evaluation_passed=None,
evaluation_user_id=None,
initialize_completion=False,
):
if assignment_user_id is None:
assignment_user_id = info.context.user.id
assignment_user = User.objects.get(id=assignment_user_id)
assignment = Assignment.objects.get(id=assignment_id)
if not has_course_access(
info.context.user,
assignment.get_course().id,
):
raise PermissionDenied()
course_session = CourseSession.objects.get(id=course_session_id)
learning_content_page = None
if learning_content_page_id:
learning_content_page = Page.objects.get(id=learning_content_page_id)
if learning_content_page is None:
learning_content_page = assignment.find_attached_learning_content()
assignment_data = {
"assignment_user": assignment_user,
"assignment": assignment,
"course_session": course_session,
"completion_data": json.loads(completion_data_string),
"completion_status": completion_status,
"learning_content_page": learning_content_page,
}
if completion_status == AssignmentCompletionStatus.SUBMITTED:
if evaluation_user_id:
assignment_data["evaluation_user"] = User.objects.get(
id=evaluation_user_id
)
else:
# TODO: determine proper way to assign evaluation user
experts = CourseSessionUser.objects.filter(
course_session=course_session, role="EXPERT"
)
if not experts:
raise PermissionDenied()
assignment_data["evaluation_user"] = experts[0].user
evaluation_data = {}
if completion_status in (
AssignmentCompletionStatus.EVALUATION_SUBMITTED,
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS,
):
if not can_evaluate_assignments(
evaluation_user=info.context.user,
assignment_user_ids=[assignment_user_id],
course_session_id=course_session_id,
):
raise PermissionDenied()
evaluation_data = {
"evaluation_user": info.context.user,
"evaluation_points": evaluation_points,
"evaluation_passed": evaluation_passed,
}
ac, created = update_assignment_completion(
copy_task_data=False,
initialize_completion=initialize_completion,
**assignment_data,
**evaluation_data,
)
logger.debug(
"AssignmentCompletionMutation successful",
label="assignment_api",
assignment_id=assignment.id,
assignment_title=assignment.title,
assignment_user_id=assignment_user_id,
course_session_id=course_session_id,
completion_status=completion_status,
created=created,
)
return AssignmentCompletionMutation(assignment_completion=ac)
class AssignmentMutation:
upsert_assignment_completion = AssignmentCompletionMutation.Field()