diff --git a/server/vbv_lernwelt/dashboard/graphql/types/attendance.py b/server/vbv_lernwelt/dashboard/graphql/types/attendance.py index 3800c565..66e38dfa 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/attendance.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/attendance.py @@ -29,7 +29,6 @@ class Record(graphene.ObjectType): class AttendanceDayPresences(graphene.ObjectType): records = graphene.List(Record) summary = graphene.Field(AttendanceSummary) - filter = graphene.String() def attendance_day_presences(course_id: graphene.String(), user: User): @@ -40,7 +39,6 @@ def attendance_day_presences(course_id: graphene.String(), user: User): course_session__course_id=course_id, ).order_by("-due_date__end") - _filter = {} records = [] for attendance_day in completed: @@ -62,7 +60,6 @@ def attendance_day_presences(course_id: graphene.String(), user: User): ] ) - _filter[circle.id] = circle.title records.append( Record( course_session_id=course_session.id, @@ -80,7 +77,7 @@ def attendance_day_presences(course_id: graphene.String(), user: User): participants_present=calculate_avg_participation(records), ) - return AttendanceDayPresences(summary=summary, records=records, filter="fuck") + return AttendanceDayPresences(summary=summary, records=records) def calculate_avg_participation(records: List[Record]) -> float: diff --git a/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py b/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py index fb46c300..7013f504 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/dashboard.py @@ -4,20 +4,42 @@ from vbv_lernwelt.dashboard.graphql.types.attendance import ( attendance_day_presences, AttendanceDayPresences, ) -from vbv_lernwelt.dashboard.graphql.types.feedback import FeedbackResponses +from vbv_lernwelt.dashboard.graphql.types.feedback import ( + feedback_responses, + FeedbackResponses, +) -class CourseSessionDashboardType(graphene.ObjectType): +class CourseSessionData(graphene.ObjectType): session_id = graphene.ID() session_title = graphene.String() - session_generation = graphene.String() + + +class CircleData(graphene.ObjectType): + circle_id = graphene.ID() + circle_title = graphene.String() + experts = graphene.List(graphene.String) + + +class CourseSessionProperties(graphene.ObjectType): + sessions = graphene.List(CourseSessionData) + generations = graphene.List(graphene.String) + circles = graphene.List(CircleData) class CourseDashboardType(graphene.ObjectType): course_id = graphene.String() course_title = graphene.String() + course_session_properties = graphene.Field(CourseSessionProperties) attendance_day_presences = graphene.Field(AttendanceDayPresences) feedback_responses = graphene.Field(FeedbackResponses) def resolve_attendance_day_presences(root, info): return attendance_day_presences(root.course_id, info.context.user) + + def resolve_feedback_responses(root, info): + return feedback_responses(root.course_id, info.context.user) + + def resolve_course_session_properties(root, info): + pass + # return course_session_properties(root.course_id, info.context.user) diff --git a/server/vbv_lernwelt/dashboard/graphql/types/feedback.py b/server/vbv_lernwelt/dashboard/graphql/types/feedback.py index 17eeb2e6..d1704194 100644 --- a/server/vbv_lernwelt/dashboard/graphql/types/feedback.py +++ b/server/vbv_lernwelt/dashboard/graphql/types/feedback.py @@ -1,5 +1,11 @@ +from typing import List + import graphene +from vbv_lernwelt.core.models import User +from vbv_lernwelt.course.models import CourseSession, CourseSessionUser +from vbv_lernwelt.feedback.models import FeedbackResponse + class FeedbackSummary(graphene.ObjectType): satisfaction_average = graphene.Float() @@ -16,3 +22,44 @@ class Record(graphene.ObjectType): class FeedbackResponses(graphene.ObjectType): records = graphene.List(Record) summary = graphene.Field(FeedbackSummary) + + +def feedback_responses(course_id: graphene.String(), user: User): + # Get all course sessions for this user in the given course + course_sessions = CourseSession.objects.filter( + coursesessionuser__user=user, + coursesessionuser__role=CourseSessionUser.Role.SESSION_SUPERVISOR, + course_id=course_id, + ) + + for course_session in course_sessions: + fbs = FeedbackResponse.objects.filter( + submitted=True, + course_session=course_session, + # Only get feedbacks from members + feedback_user__in=CourseSessionUser.objects.filter( + course_session=course_session, role=CourseSessionUser.Role.MEMBER + ).values_list("user", flat=True), + ) + circle_feedbacks = circle_feedback_average(fbs) + + return FeedbackResponses() + + +def circle_feedback_average(feedbacks: List[FeedbackResponse]): + circle_data = {} + + for fb in feedbacks: + circle_id = fb.circle.id + satisfaction = fb.data.get("satisfaction", 0) + + if circle_id in circle_data: + circle_data[circle_id]["total"] += satisfaction + circle_data[circle_id]["count"] += 1 + else: + circle_data[circle_id] = {"total": satisfaction, "count": 1} + + for circle_id, data in circle_data.items(): + circle_data[circle_id]["avg_satisfaction"] = data["total"] / data["count"] + + return circle_data diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py index 6c3d62f9..e6ddc8ba 100644 --- a/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_attendance.py @@ -15,7 +15,7 @@ from vbv_lernwelt.dashboard.tests.graphql.utils import ( ) -class DashboardTestCase(GraphQLTestCase): +class DashboardAttendanceTestCase(GraphQLTestCase): GRAPHQL_URL = "/server/graphql/" def test_attendance_day_presences(self): diff --git a/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py b/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py new file mode 100644 index 00000000..ccae60a2 --- /dev/null +++ b/server/vbv_lernwelt/dashboard/tests/graphql/test_feedback.py @@ -0,0 +1,66 @@ +from graphene_django.utils import GraphQLTestCase + +from vbv_lernwelt.course.models import CourseSessionUser +from vbv_lernwelt.dashboard.graphql.types.feedback import feedback_responses +from vbv_lernwelt.dashboard.tests.graphql.utils import ( + add_course_session_user, + create_circle, + create_course, + create_course_session, + create_user, +) +from vbv_lernwelt.feedback.models import FeedbackResponse + + +class DashboardFeedbackTestCase(GraphQLTestCase): + GRAPHQL_URL = "/server/graphql/" + + def test_feedback(self): + # GIVEN + course, course_page = create_course("Test Course") + course_session = create_course_session(course=course, title="Test Bern 2022 a") + + supervisor = create_user("supervisor") + + add_course_session_user( + course_session=course_session, + user=supervisor, + role=CourseSessionUser.Role.SESSION_SUPERVISOR, + ) + + member = create_user("member") + + circle1, _ = create_circle(title="Test Circle 1", course_page=course_page) + circle2, _ = create_circle(title="Test Circle 2", course_page=course_page) + + FeedbackResponse.objects.create( + feedback_user=member, + data={"satisfaction": 3}, + circle=circle1, + course_session=course_session, + ) + FeedbackResponse.objects.create( + feedback_user=member, + data={"satisfaction": 4}, + circle=circle1, + course_session=course_session, + ) + + # Create Feedbacks for circle2 + FeedbackResponse.objects.create( + feedback_user=member, + data={"satisfaction": 5}, + circle=circle2, + course_session=course_session, + ) + FeedbackResponse.objects.create( + feedback_user=member, + data={"satisfaction": 2}, + circle=circle2, + course_session=course_session, + ) + + # Get average satisfaction per circle + result = feedback_responses(course.id, supervisor) + + # THEN