feat: praxis assignments API
This commit is contained in:
parent
56ecb72751
commit
a48ac35e62
|
|
@ -0,0 +1,115 @@
|
|||
from typing import List
|
||||
|
||||
from vbv_lernwelt.assignment.models import (
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
AssignmentCompletionStatus,
|
||||
AssignmentType,
|
||||
)
|
||||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.course.models import CourseSession
|
||||
from vbv_lernwelt.course_session.models import CourseSessionAssignment
|
||||
from vbv_lernwelt.learning_mentor.entities import (
|
||||
CompletionStatus,
|
||||
PraxisAssignmentCompletion,
|
||||
PraxisAssignmentStatus,
|
||||
)
|
||||
|
||||
|
||||
def get_assignment_completions(
|
||||
course_session: CourseSession, assignment: Assignment, participants: List[User]
|
||||
) -> List[PraxisAssignmentCompletion]:
|
||||
evaluation_results = AssignmentCompletion.objects.filter(
|
||||
assignment_user__in=participants,
|
||||
course_session=course_session,
|
||||
assignment=assignment,
|
||||
).values("completion_status", "assignment_user__last_name", "assignment_user")
|
||||
|
||||
user_status_map = {}
|
||||
for result in evaluation_results:
|
||||
completion_status = result["completion_status"]
|
||||
|
||||
if completion_status == AssignmentCompletionStatus.EVALUATION_SUBMITTED.value:
|
||||
status = CompletionStatus.EVALUATED
|
||||
elif completion_status in [
|
||||
AssignmentCompletionStatus.SUBMITTED.value,
|
||||
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS.value,
|
||||
]:
|
||||
status = CompletionStatus.SUBMITTED
|
||||
else:
|
||||
status = CompletionStatus.UNKNOWN
|
||||
|
||||
user_status_map[result["assignment_user"]] = (
|
||||
status,
|
||||
result["assignment_user__last_name"],
|
||||
)
|
||||
|
||||
status_priority = {
|
||||
CompletionStatus.SUBMITTED: 1,
|
||||
CompletionStatus.EVALUATED: 2,
|
||||
CompletionStatus.UNKNOWN: 3,
|
||||
}
|
||||
|
||||
sorted_participants = sorted(
|
||||
participants,
|
||||
key=lambda u: (
|
||||
status_priority.get(
|
||||
user_status_map.get(u.id, (CompletionStatus.UNKNOWN, ""))[0]
|
||||
),
|
||||
user_status_map.get(u.id, ("", u.last_name))[1],
|
||||
),
|
||||
)
|
||||
|
||||
return [
|
||||
PraxisAssignmentCompletion(
|
||||
status=user_status_map.get(
|
||||
user.id, (CompletionStatus.UNKNOWN, user.last_name)
|
||||
)[0],
|
||||
user_id=user.id,
|
||||
last_name=user.last_name,
|
||||
)
|
||||
for user in sorted_participants
|
||||
]
|
||||
|
||||
|
||||
def get_praxis_assignments(
|
||||
course_session: CourseSession, participants: List[User]
|
||||
) -> List[PraxisAssignmentStatus]:
|
||||
records = []
|
||||
|
||||
if not participants:
|
||||
return records
|
||||
|
||||
for course_session_assignment in CourseSessionAssignment.objects.filter(
|
||||
course_session=course_session,
|
||||
learning_content__content_assignment__assignment_type__in=[
|
||||
AssignmentType.PRAXIS_ASSIGNMENT.value,
|
||||
],
|
||||
):
|
||||
learning_content = course_session_assignment.learning_content
|
||||
|
||||
completions = get_assignment_completions(
|
||||
course_session=course_session,
|
||||
assignment=learning_content.content_assignment,
|
||||
participants=participants,
|
||||
)
|
||||
|
||||
submitted_count = len(
|
||||
[
|
||||
completion
|
||||
for completion in completions
|
||||
if completion.status == CompletionStatus.SUBMITTED
|
||||
]
|
||||
)
|
||||
|
||||
records.append(
|
||||
PraxisAssignmentStatus(
|
||||
id=course_session_assignment.id,
|
||||
title=learning_content.content_assignment.title,
|
||||
circle_id=learning_content.get_circle().id,
|
||||
pending_evaluations=submitted_count,
|
||||
completions=completions,
|
||||
)
|
||||
)
|
||||
|
||||
return records
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import List
|
||||
|
||||
|
||||
class CompletionStatus(str, Enum):
|
||||
UNKNOWN = "UNKNOWN"
|
||||
SUBMITTED = "SUBMITTED"
|
||||
EVALUATED = "EVALUATED"
|
||||
|
||||
|
||||
@dataclass
|
||||
class PraxisAssignmentCompletion:
|
||||
status: CompletionStatus
|
||||
user_id: str
|
||||
last_name: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PraxisAssignmentStatus:
|
||||
id: str
|
||||
title: str
|
||||
circle_id: str
|
||||
pending_evaluations: int
|
||||
completions: List[PraxisAssignmentCompletion]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
|
||||
class PraxisAssignmentCompletionSerializer(serializers.Serializer):
|
||||
status = serializers.SerializerMethodField()
|
||||
user_id = serializers.CharField()
|
||||
last_name = serializers.CharField()
|
||||
|
||||
@staticmethod
|
||||
def get_status(obj):
|
||||
return obj.status.value
|
||||
|
||||
|
||||
class PraxisAssignmentStatusSerializer(serializers.Serializer):
|
||||
id = serializers.CharField()
|
||||
title = serializers.CharField()
|
||||
circle_id = serializers.CharField()
|
||||
pending_evaluations = serializers.IntegerField()
|
||||
completions = PraxisAssignmentCompletionSerializer(many=True)
|
||||
|
|
@ -2,10 +2,19 @@ from django.urls import reverse
|
|||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from vbv_lernwelt.assignment.models import (
|
||||
AssignmentCompletion,
|
||||
AssignmentCompletionStatus,
|
||||
AssignmentType,
|
||||
)
|
||||
from vbv_lernwelt.course.creators.test_utils import (
|
||||
add_course_session_user,
|
||||
create_assignment,
|
||||
create_assignment_learning_content,
|
||||
create_circle,
|
||||
create_course,
|
||||
create_course_session,
|
||||
create_course_session_assignment,
|
||||
create_user,
|
||||
)
|
||||
from vbv_lernwelt.course.models import CourseSessionUser
|
||||
|
|
@ -14,8 +23,20 @@ from vbv_lernwelt.learning_mentor.models import LearningMentor
|
|||
|
||||
class LearningMentorAPITest(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
course, course_page = create_course("Test Course")
|
||||
self.course_session = create_course_session(course=course, title="Test VV")
|
||||
self.course, self.course_page = create_course("Test Course")
|
||||
self.course_session = create_course_session(course=self.course, title="Test VV")
|
||||
|
||||
circle, _ = create_circle(title="Circle", course_page=self.course_page)
|
||||
|
||||
self.assignment = create_assignment(
|
||||
course=self.course, assignment_type=AssignmentType.PRAXIS_ASSIGNMENT
|
||||
)
|
||||
|
||||
lca = create_assignment_learning_content(circle, self.assignment)
|
||||
create_course_session_assignment(
|
||||
course_session=self.course_session, learning_content_assignment=lca
|
||||
)
|
||||
|
||||
self.mentor = create_user("mentor")
|
||||
self.participant_1 = add_course_session_user(
|
||||
self.course_session,
|
||||
|
|
@ -87,3 +108,48 @@ class LearningMentorAPITest(APITestCase):
|
|||
self.assertEqual(participant_1["email"], "participant_1@example.com")
|
||||
self.assertEqual(participant_1["first_name"], "Test")
|
||||
self.assertEqual(participant_1["last_name"], "Participant_1")
|
||||
|
||||
def test_api_praxis_assignments(self) -> None:
|
||||
# GIVEN
|
||||
participants = [self.participant_1, self.participant_2, self.participant_3]
|
||||
self.client.force_login(self.mentor)
|
||||
|
||||
mentor = LearningMentor.objects.create(
|
||||
mentor=self.mentor,
|
||||
course=self.course_session.course,
|
||||
)
|
||||
mentor.participants.set(participants)
|
||||
|
||||
AssignmentCompletion.objects.create(
|
||||
assignment_user=self.participant_1.user,
|
||||
course_session=self.course_session,
|
||||
assignment=self.assignment,
|
||||
completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED.value,
|
||||
)
|
||||
|
||||
AssignmentCompletion.objects.create(
|
||||
assignment_user=self.participant_3.user,
|
||||
course_session=self.course_session,
|
||||
assignment=self.assignment,
|
||||
completion_status=AssignmentCompletionStatus.SUBMITTED.value,
|
||||
)
|
||||
|
||||
# WHEN
|
||||
response = self.client.get(self.url)
|
||||
|
||||
# THEN
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(response.data["praxis_assignments"]), 1)
|
||||
|
||||
assignment = response.data["praxis_assignments"][0]
|
||||
self.assertEqual(assignment["pending_evaluations"], 1)
|
||||
|
||||
self.assertEqual(
|
||||
assignment["completions"][0]["last_name"], self.participant_3.user.last_name
|
||||
)
|
||||
self.assertEqual(
|
||||
assignment["completions"][1]["last_name"], self.participant_1.user.last_name
|
||||
)
|
||||
self.assertEqual(
|
||||
assignment["completions"][2]["last_name"], self.participant_2.user.last_name
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ from vbv_lernwelt.course.creators.test_utils import (
|
|||
create_course_session_assignment,
|
||||
create_user,
|
||||
)
|
||||
from vbv_lernwelt.learning_mentor.views import (
|
||||
CompletionStatus,
|
||||
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
||||
get_assignment_completions,
|
||||
get_praxis_assignments,
|
||||
)
|
||||
from vbv_lernwelt.learning_mentor.entities import CompletionStatus
|
||||
|
||||
|
||||
class AttendanceServicesTestCase(TestCase):
|
||||
|
|
|
|||
|
|
@ -1,140 +1,14 @@
|
|||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import List
|
||||
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.response import Response
|
||||
|
||||
from vbv_lernwelt.assignment.models import (
|
||||
Assignment,
|
||||
AssignmentCompletion,
|
||||
AssignmentCompletionStatus,
|
||||
AssignmentType,
|
||||
)
|
||||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.core.serializers import UserSerializer
|
||||
from vbv_lernwelt.course.models import CourseSession
|
||||
from vbv_lernwelt.course_session.models import CourseSessionAssignment
|
||||
from vbv_lernwelt.learning_mentor.content.praxis_assignment import (
|
||||
get_praxis_assignments,
|
||||
)
|
||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||
|
||||
|
||||
class CompletionStatus(str, Enum):
|
||||
UNKNOWN = "UNKNOWN"
|
||||
SUBMITTED = "SUBMITTED"
|
||||
EVALUATED = "EVALUATED"
|
||||
|
||||
|
||||
@dataclass
|
||||
class PraxisAssignmentCompletion:
|
||||
status: CompletionStatus
|
||||
user_id: str
|
||||
last_name: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PraxisAssignmentStatus:
|
||||
id: str
|
||||
title: str
|
||||
circle_id: str
|
||||
pending_evaluations: int
|
||||
completions: List[PraxisAssignmentCompletion]
|
||||
|
||||
|
||||
def get_assignment_completions(
|
||||
course_session: CourseSession, assignment: Assignment, participants: List[User]
|
||||
) -> List[PraxisAssignmentCompletion]:
|
||||
evaluation_results = AssignmentCompletion.objects.filter(
|
||||
assignment_user__in=participants,
|
||||
course_session=course_session,
|
||||
assignment=assignment,
|
||||
).values("completion_status", "assignment_user__last_name", "assignment_user")
|
||||
|
||||
user_status_map = {}
|
||||
for result in evaluation_results:
|
||||
completion_status = result["completion_status"]
|
||||
|
||||
if completion_status == AssignmentCompletionStatus.EVALUATION_SUBMITTED.value:
|
||||
status = CompletionStatus.EVALUATED
|
||||
elif completion_status in [
|
||||
AssignmentCompletionStatus.SUBMITTED.value,
|
||||
AssignmentCompletionStatus.EVALUATION_IN_PROGRESS.value,
|
||||
]:
|
||||
status = CompletionStatus.SUBMITTED
|
||||
else:
|
||||
status = CompletionStatus.UNKNOWN
|
||||
|
||||
user_status_map[result["assignment_user"]] = (
|
||||
status,
|
||||
result["assignment_user__last_name"],
|
||||
)
|
||||
|
||||
status_priority = {
|
||||
CompletionStatus.SUBMITTED: 1,
|
||||
CompletionStatus.EVALUATED: 2,
|
||||
CompletionStatus.UNKNOWN: 3,
|
||||
}
|
||||
|
||||
sorted_participants = sorted(
|
||||
participants,
|
||||
key=lambda u: (
|
||||
status_priority.get(
|
||||
user_status_map.get(u.id, (CompletionStatus.UNKNOWN, ""))[0]
|
||||
),
|
||||
user_status_map.get(u.id, ("", u.last_name))[1],
|
||||
),
|
||||
)
|
||||
|
||||
return [
|
||||
PraxisAssignmentCompletion(
|
||||
status=user_status_map.get(
|
||||
user.id, (CompletionStatus.UNKNOWN, user.last_name)
|
||||
)[0],
|
||||
user_id=user.id,
|
||||
last_name=user.last_name,
|
||||
)
|
||||
for user in sorted_participants
|
||||
]
|
||||
|
||||
|
||||
def get_praxis_assignments(
|
||||
course_session: CourseSession, participants: List[User]
|
||||
) -> List[PraxisAssignmentStatus]:
|
||||
records = []
|
||||
|
||||
for course_session_assignment in CourseSessionAssignment.objects.filter(
|
||||
course_session=course_session,
|
||||
learning_content__content_assignment__assignment_type__in=[
|
||||
AssignmentType.PRAXIS_ASSIGNMENT.value,
|
||||
],
|
||||
):
|
||||
learning_content = course_session_assignment.learning_content
|
||||
|
||||
completions = get_assignment_completions(
|
||||
course_session=course_session,
|
||||
assignment=learning_content.content_assignment,
|
||||
participants=participants,
|
||||
)
|
||||
|
||||
submitted_count = len(
|
||||
[
|
||||
completion
|
||||
for completion in completions
|
||||
if completion.status == CompletionStatus.SUBMITTED
|
||||
]
|
||||
)
|
||||
|
||||
records.append(
|
||||
PraxisAssignmentStatus(
|
||||
id=course_session_assignment.id,
|
||||
title=learning_content.content_assignment.title,
|
||||
circle_id=learning_content.get_circle().id,
|
||||
pending_evaluations=submitted_count,
|
||||
completions=completions,
|
||||
)
|
||||
)
|
||||
|
||||
return records
|
||||
from vbv_lernwelt.learning_mentor.serializers import PraxisAssignmentStatusSerializer
|
||||
|
||||
|
||||
@api_view(["GET"])
|
||||
|
|
@ -150,12 +24,15 @@ def mentor_summary(request, course_session_id: int):
|
|||
)
|
||||
|
||||
participants = mentor.participants.filter(course_session=course_session)
|
||||
users = [p.user for p in participants]
|
||||
|
||||
praxis_assignments = get_praxis_assignments(course_session, users)
|
||||
|
||||
return Response(
|
||||
{
|
||||
"participants": [UserSerializer(p.user).data for p in participants],
|
||||
"praxis_assignments": get_praxis_assignments(
|
||||
course_session, participants
|
||||
),
|
||||
"participants": [UserSerializer(user).data for user in users],
|
||||
"praxis_assignments": PraxisAssignmentStatusSerializer(
|
||||
praxis_assignments, many=True
|
||||
).data,
|
||||
}
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue