vbv/server/vbv_lernwelt/learning_mentor/views.py

246 lines
8.0 KiB
Python

import uuid
from uuid import UUID
from rest_framework import permissions, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.generics import get_object_or_404
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from vbv_lernwelt.core.serializers import UserSerializer
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.iam.permissions import is_course_session_member
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
get_praxis_assignments,
)
from vbv_lernwelt.learning_mentor.content.self_evaluation_feedback import (
get_self_feedback_evaluation,
)
from vbv_lernwelt.learning_mentor.models import (
AgentParticipantRelation,
AgentParticipantRoleType,
MentorInvitation,
)
from vbv_lernwelt.learning_mentor.serializers import (
AgentParticipantRelationSerializer,
InvitationSerializer,
MentorAssignmentStatusSerializer,
)
from vbv_lernwelt.learnpath.models import Circle
from vbv_lernwelt.notify.email.email_services import EmailTemplate, send_email
@api_view(["GET"])
@permission_classes([IsAuthenticated])
def mentor_summary(request, course_session_id: int):
course_session = CourseSession.objects.get(id=course_session_id)
participant_qs = AgentParticipantRelation.objects.filter(
agent=request.user,
participant__course_session=course_session,
role=AgentParticipantRoleType.LEARNING_MENTOR.value,
)
if participant_qs.count() == 0:
return Response(status=status.HTTP_404_NOT_FOUND)
users = [p.participant.user for p in participant_qs]
assignments = []
circle_ids = set()
praxis_assignments, praxis_assignments_circle_ids = get_praxis_assignments(
course_session=course_session,
participants=users,
evaluation_user=request.user, # noqa
)
(
self_evaluation_feedbacks,
self_evaluation_feedback_circle_ids,
) = get_self_feedback_evaluation(
participants=users,
evaluation_user=request.user, # noqa
course=course_session.course,
)
circle_ids.update(praxis_assignments_circle_ids)
circle_ids.update(self_evaluation_feedback_circle_ids)
assignments.extend(
MentorAssignmentStatusSerializer(praxis_assignments, many=True).data
)
assignments.extend(
MentorAssignmentStatusSerializer(self_evaluation_feedbacks, many=True).data
)
assignments.sort(
key=lambda x: (-x.get("pending_evaluations", 0), x.get("title", "").lower())
)
return Response(
{
"participant_relations": AgentParticipantRelationSerializer(
participant_qs, many=True
).data,
"circles": list(
Circle.objects.filter(id__in=circle_ids).values("id", "title")
),
"assignments": assignments,
}
)
class IsCourseSessionMember(permissions.BasePermission):
def has_permission(self, request, view):
return is_course_session_member(
request.user, view.kwargs.get("course_session_id")
)
@api_view(["GET"])
@permission_classes([IsAuthenticated, IsCourseSessionMember])
def list_invitations(request, course_session_id: int):
course_session = get_object_or_404(CourseSession, id=course_session_id)
course_session_user = get_object_or_404(
CourseSessionUser, user=request.user, course_session=course_session
)
invitations = MentorInvitation.objects.filter(participant=course_session_user)
serializer = InvitationSerializer(invitations, many=True)
return Response(serializer.data)
@api_view(["DELETE"])
@permission_classes([IsAuthenticated, IsCourseSessionMember])
def delete_invitation(request, course_session_id: int, invitation_id: UUID):
course_session = get_object_or_404(CourseSession, id=course_session_id)
course_session_user = get_object_or_404(
CourseSessionUser, user=request.user, course_session=course_session
)
get_object_or_404(
MentorInvitation, id=invitation_id, participant=course_session_user
).delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@api_view(["POST"])
@permission_classes([IsAuthenticated, IsCourseSessionMember])
def create_invitation(request, course_session_id: int):
user = request.user
course_session = get_object_or_404(
CourseSession,
id=course_session_id,
course__configuration__enable_learning_mentor=True,
)
course_session_user = get_object_or_404(
CourseSessionUser, user=user, course_session=course_session
)
serializer = InvitationSerializer(
data=request.data, context={"course_session_user": course_session_user}
)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
if serializer.validated_data.get("email") == user.email:
return Response(
data={"message": "You cannot invite yourself"},
status=status.HTTP_400_BAD_REQUEST,
)
invitation = serializer.save()
target_url = f"/lernbegleitung/{course_session_id}/invitation/{invitation.id}"
invitation.target_url = target_url
invitation.save()
if course_session.course.configuration.is_uk:
template = EmailTemplate.PRAXISBILDNER_INVITATION
target_url = target_url + "?uk=true"
else:
template = EmailTemplate.LEARNING_MENTOR_INVITATION
send_email(
recipient_email=invitation.email,
template=template,
template_data={
"inviter_name": f"{user.first_name} {user.last_name}",
"inviter_email": user.email,
"target_url": f"https://my.vbv-afa.ch{target_url}",
},
template_language=request.user.language,
fail_silently=True,
)
return Response(serializer.data)
@api_view(["GET"])
@permission_classes([IsAuthenticated, IsCourseSessionMember])
def list_user_mentors(request, course_session_id: int):
course_session = get_object_or_404(CourseSession, id=course_session_id)
course_session_user = get_object_or_404(
CourseSessionUser, user=request.user, course_session=course_session
)
mentors = AgentParticipantRelation.objects.filter(
participant=course_session_user,
role=AgentParticipantRoleType.LEARNING_MENTOR.value,
)
return Response(AgentParticipantRelationSerializer(mentors, many=True).data)
@api_view(["DELETE"])
@permission_classes([IsAuthenticated])
def delete_agent_participant_relation(
request, course_session_id: int, relation_id: uuid.UUID
):
requester_user = request.user
relation = get_object_or_404(AgentParticipantRelation, id=relation_id)
is_requester_mentor = requester_user.id == relation.agent.id
is_requester_participant = requester_user.id == relation.participant.user.id
if not is_requester_mentor and not is_requester_participant:
return Response(
data={"message": "You are not allowed to remove participants"},
status=status.HTTP_403_FORBIDDEN,
)
relation.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@api_view(["POST"])
@permission_classes([IsAuthenticated])
def accept_invitation(request, course_session_id: int):
course_session = get_object_or_404(CourseSession, id=course_session_id)
invitation = get_object_or_404(
MentorInvitation, id=request.data.get("invitation_id")
)
if invitation.participant.course_session != course_session:
return Response(
data={"message": "Invalid invitation", "code": "invalidInvitation"},
status=status.HTTP_400_BAD_REQUEST,
)
AgentParticipantRelation.objects.get_or_create(
agent=request.user,
participant=invitation.participant,
role=AgentParticipantRoleType.LEARNING_MENTOR.value,
)
invitation.delete()
return Response(
{
"course_slug": course_session.course.slug,
"user": UserSerializer(invitation.participant.user).data,
}
)