from dataclasses import dataclass from typing import List, Set from vbv_lernwelt.core.models import User from vbv_lernwelt.course.models import CourseSession, CourseSessionUser from vbv_lernwelt.course_session_group.models import CourseSessionGroup from vbv_lernwelt.learning_mentor.models import LearningMentor @dataclass(frozen=True) class CourseSessionWithRoles: _original: CourseSession roles: Set[str] def __getattr__(self, name: str): # Delegate attribute access to the _original CourseSession object return getattr(self._original, name) def save(self, *args, **kwargs): raise NotImplementedError("This proxy object cannot be saved.") def get_course_sessions_with_roles_for_user(user: User) -> List[CourseSessionWithRoles]: result_course_sessions = {} # participant/member/expert course sessions csu_qs = CourseSessionUser.objects.filter(user=user).prefetch_related( "course_session", "course_session__course" ) for csu in csu_qs: cs = csu.course_session # member/expert is mutually exclusive... cs.roles = {csu.role} result_course_sessions[cs.id] = cs # enrich with supervisor course sessions csg_qs = CourseSessionGroup.objects.filter(supervisor=user).prefetch_related( "course_session", "course_session__course" ) for csg in csg_qs: for cs in csg.course_session.all(): cs.roles = set() cs = result_course_sessions.get(cs.id, cs) cs.roles.add("SUPERVISOR") result_course_sessions[cs.id] = cs # enrich with mentor course sessions lm_qs = LearningMentor.objects.filter(mentor=user).prefetch_related( "course_session", "course_session__course" ) for lm in lm_qs: cs = lm.course_session cs.roles = set() cs = result_course_sessions.get(cs.id, cs) cs.roles.add("LEARNING_MENTOR") result_course_sessions[cs.id] = cs return [ CourseSessionWithRoles(cs, cs.roles) for cs in result_course_sessions.values() ] def has_cs_role(roles: Set[str]) -> bool: return bool(roles & {"SUPERVISOR", "EXPERT", "MEMBER"}) def user_role(roles: Set[str]) -> str: if "SUPERVISOR" in roles: return "SUPERVISOR" if "EXPERT" in roles: return "EXPERT" if "MEMBER" in roles: return "MEMBER" return "LEARNING_MENTOR" def create_course_session_dict(course_session_object, my_role, user_role): return { "id": str(course_session_object.id), "session_title": course_session_object.title, "course_id": str(course_session_object.course.id), "course_title": course_session_object.course.title, "course_slug": course_session_object.course.slug, "region": course_session_object.region, "generation": course_session_object.generation, "my_role": my_role, "user_role": user_role, "is_uk": course_session_object.course.configuration.is_uk, "is_vv": course_session_object.course.configuration.is_vv, } def create_person_list_with_roles( user, course_session_ids=None, include_private_data=False ): def create_user_dict(user_object): user_data = { "user_id": user_object.id, "first_name": user_object.first_name, "last_name": user_object.last_name, "email": user_object.email, "avatar_url_small": user_object.avatar_url_small, "avatar_url": user_object.avatar_url, "course_sessions": [], } if include_private_data: user_data["phone_number"] = user_object.phone_number user_data["Lehrvertragsnummer"] = user_object.additional_json_data.get( "Lehrvertragsnummer", "" ) return user_data course_sessions = get_course_sessions_with_roles_for_user(user) result_persons = {} for cs in course_sessions: if has_cs_role(cs.roles) and cs.course.configuration.is_uk: course_session_users = CourseSessionUser.objects.filter( course_session=cs.id ).select_related("user") my_role = user_role(cs.roles) for csu in course_session_users: person_data = result_persons.get( csu.user.id, create_user_dict(csu.user) ) person_data["course_sessions"].append( create_course_session_dict(cs, my_role, csu.role) ) result_persons[csu.user.id] = person_data # add persons where request.user is mentor for cs in course_sessions: if "LEARNING_MENTOR" in cs.roles: lm = LearningMentor.objects.filter( mentor=user, course_session=cs.id ).first() for participant in lm.participants.all(): course_session_entry = create_course_session_dict( cs, "LEARNING_MENTOR", "LEARNING_MENTEE", ) if participant.user.id not in result_persons: person_data = create_user_dict(participant.user) person_data["course_sessions"] = [course_session_entry] result_persons[participant.user.id] = person_data else: # user is already in result_persons result_persons[participant.user.id]["course_sessions"].append( course_session_entry ) # add persons where request.user is mentee mentor_relation_qs = LearningMentor.objects.filter( participants__user=user ).prefetch_related("mentor", "course_session") for mentor_relation in mentor_relation_qs: cs = mentor_relation.course_session course_session_entry = create_course_session_dict( cs, "LEARNING_MENTEE", "LEARNING_MENTOR", ) if mentor_relation.mentor.id not in result_persons: person_data = create_user_dict(mentor_relation.mentor) person_data["course_sessions"] = [course_session_entry] result_persons[mentor_relation.mentor.id] = person_data else: # user is already in result_persons result_persons[mentor_relation.mentor.id]["course_sessions"].append( course_session_entry ) return result_persons.values()