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

137 lines
4.4 KiB
Python

import graphene
import structlog
from graphene.types.generic import GenericScalar
from graphene_django.types import ErrorType
from vbv_lernwelt.course.models import CourseCompletionStatus, CourseSession
from vbv_lernwelt.course.permissions import has_course_session_access
from vbv_lernwelt.course.services import mark_course_completion
from vbv_lernwelt.feedback.graphql.types import (
FeedbackResponseObjectType as FeedbackResponseType,
)
from vbv_lernwelt.feedback.models import FeedbackResponse
from vbv_lernwelt.feedback.serializers import CourseFeedbackSerializer
from vbv_lernwelt.learnpath.models import LearningContentFeedback
logger = structlog.get_logger(__name__)
# https://medium.com/open-graphql/jsonfield-models-in-graphene-django-308ae43d14ee
class SendFeedbackMutation(graphene.Mutation):
feedback_response = graphene.Field(FeedbackResponseType)
errors = graphene.List(
ErrorType, description="May contain more than one error for same field."
)
class Arguments:
course_session_id = graphene.ID(required=True)
learning_content_page_id = graphene.ID(required=True)
data = GenericScalar()
submitted = graphene.Boolean(required=False, default_value=False)
@classmethod
def mutate(
cls,
root,
info,
course_session_id,
learning_content_page_id,
data,
submitted,
):
feedback_user_id = info.context.user.id
learning_content = LearningContentFeedback.objects.get(
id=learning_content_page_id
)
circle = learning_content.get_circle()
course_session = CourseSession.objects.get(id=course_session_id)
if not has_course_session_access(
info.context.user,
course_session.id,
):
return SendFeedbackMutation(
errors=[
ErrorType(
field="send_feedback", messages=["Insufficient permissions"]
)
]
)
logger.info(
"creating feedback",
label="feedback",
feedback_user_id=feedback_user_id,
circle_title=circle.title,
course_session_id=course_session_id,
)
serializer = CourseFeedbackSerializer(data=data)
if not serializer.is_valid():
logger.error(
"creating feedback serializer invalid",
error_list=serializer.errors,
label="feedback",
)
errors = [
ErrorType(field=field, messages=msgs)
for field, msgs in serializer.errors.items()
]
return SendFeedbackMutation(errors=errors)
feedback_response, _ = FeedbackResponse.objects.get_or_create(
feedback_user_id=feedback_user_id,
circle_id=circle.id,
course_session=course_session,
)
original_data = feedback_response.data
updated_data = serializer.validated_data
initial_data = {
"satisfaction": None,
"goal_attainment": None,
"proficiency": None,
"preparation_task_clarity": None,
"instructor_competence": None,
"instructor_respect": None,
"instructor_open_feedback": "",
"would_recommend": None,
"course_negative_feedback": "",
"course_positive_feedback": "",
}
merged_data = initial_data | {
key: updated_data[key]
if updated_data.get(key, "") != ""
else original_data.get(key)
for key in initial_data.keys()
}
feedback_response.data = merged_data
if submitted:
feedback_response.submitted = submitted
feedback_response.save()
if submitted:
mark_course_completion(
user=info.context.user,
page=learning_content,
course_session=course_session,
completion_status=CourseCompletionStatus.SUCCESS.value,
)
logger.info(
"feedback successfully created",
label="feedback",
feedback_user_id=feedback_user_id,
circle_title=circle.title,
course_session_id=course_session_id,
)
return SendFeedbackMutation(feedback_response=feedback_response)
class FeedbackMutation(object):
send_feedback = SendFeedbackMutation.Field()