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 LearningMentor, MentorInvitation from vbv_lernwelt.learning_mentor.serializers import ( InvitationSerializer, MentorAssignmentStatusSerializer, MentorSerializer, ) 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) mentor = get_object_or_404( LearningMentor, mentor=request.user, course_session=course_session ) participants = mentor.participants.filter(course_session=course_session) users = [p.user for p in participants] 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( { "mentor_id": mentor.id, "participants": [UserSerializer(user).data for user in users], "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}" 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 = LearningMentor.objects.filter( course_session=course_session, participants=course_session_user ) return Response(MentorSerializer(mentors, many=True).data) @api_view(["DELETE"]) @permission_classes([IsAuthenticated]) def remove_participant_from_mentor( request, course_session_id: int, mentor_id: int, participant_user_id: uuid.UUID ): requester_user = request.user mentor = get_object_or_404( LearningMentor, id=mentor_id, course_session_id=course_session_id ) is_requester_mentor = requester_user.id == mentor.mentor_id is_requester_participant = mentor.participants.filter( user=requester_user, course_session_id=course_session_id ).exists() 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, ) course_session = get_object_or_404(CourseSession, id=course_session_id) course_session_user = get_object_or_404( CourseSessionUser, user=participant_user_id, course_session=course_session ) mentor.participants.remove(course_session_user) 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, ) mentor, _ = LearningMentor.objects.get_or_create( mentor=request.user, course_session=course_session ) mentor.participants.add(invitation.participant) invitation.delete() return Response( { "course_slug": course_session.course.slug, "user": UserSerializer(invitation.participant.user).data, } )