vbv/server/vbv_lernwelt/learning_mentor/services.py

138 lines
4.2 KiB
Python

from typing import List
import structlog
from vbv_lernwelt.core.models import Organisation, User
from vbv_lernwelt.course.consts import (
COURSE_UK,
COURSE_UK_FR,
COURSE_UK_IT,
VV_COURSE_IDS,
)
from vbv_lernwelt.course.models import Course, CourseSessionUser
from vbv_lernwelt.learning_mentor.models import (
AgentParticipantRelation,
AgentParticipantRoleType,
)
logger = structlog.get_logger(__name__)
UK_COURSES = [COURSE_UK, COURSE_UK_FR, COURSE_UK_IT]
def users_by_org(
org: Organisation,
is_uk: bool,
courses: List[Course],
excluded_course_sessions: List[int] = None,
) -> set[CourseSessionUser]:
if not excluded_course_sessions:
excluded_course_sessions = []
return set(
CourseSessionUser.objects.filter(user__organisation=org)
.filter(course_session__course__configuration__is_uk=is_uk)
.filter(role=CourseSessionUser.Role.MEMBER.value)
.filter(course_session__course_id__in=courses)
.exclude(course_session_id__in=excluded_course_sessions)
)
def uk_cs_users_by_org(org: Organisation) -> set[CourseSessionUser]:
return users_by_org(
org,
is_uk=True,
courses=UK_COURSES,
# ignore "Demo" course sessions
excluded_course_sessions=[4, 5, 6],
)
def vv_cs_users_by_org(org: Organisation) -> set[CourseSessionUser]:
return users_by_org(org, False, VV_COURSE_IDS)
def create_or_sync_berufsbildner(
berufsbildner: User, organisation: Organisation
) -> bool:
org_members = uk_cs_users_by_org(organisation)
return create_or_sync_learning_mentor(berufsbildner, org_members, organisation)
def create_or_sync_ausbildungsverantwortlicher(
ausbildungsverantwortlicher: User, organisation: Organisation
) -> bool:
org_members = vv_cs_users_by_org(organisation)
return create_or_sync_learning_mentor(
ausbildungsverantwortlicher, org_members, organisation
)
def create_or_sync_learning_mentor(
agent: User, org_members: set[CourseSessionUser], organisation: Organisation
) -> bool:
logger.info(
"Creating or syncing berufsbildner/ausbildungsverantwortlicher",
berufsbildner=agent,
org=organisation.name_de,
)
# Check if it is a valid organisation
# ids < 4 are "andere Broker/Krankenversicherer"
if organisation and organisation.organisation_id < 4:
logger.error("Invalid organisation", org=organisation)
return False
# Get existing connections (full relation objects)
existing_relations = set(agent.agentparticipantrelation_set.all())
# Add new relations that are not in existing relations
existing_members = {relation.participant for relation in existing_relations}
for csu in org_members:
if csu not in existing_members:
AgentParticipantRelation.objects.get_or_create(
agent=agent,
participant=csu,
role=AgentParticipantRoleType.BERUFSBILDNER.value,
)
# Remove old relations that are not in the new relations
for relation in existing_relations:
if relation.participant not in org_members:
relation.delete()
return True
def delete_berufsbildner_relation(berufsbildner: User, organisation: Organisation):
org_members = uk_cs_users_by_org(organisation)
delete_org_supervisor_relation(berufsbildner, org_members)
def delete_ausbildungsverantwortlicher_relation(
ausbildungsverantwortlicher: User, organisation: Organisation
):
org_members = vv_cs_users_by_org(organisation)
delete_org_supervisor_relation(ausbildungsverantwortlicher, org_members)
def delete_org_supervisor_relation(
agent: User,
org_members: set[CourseSessionUser],
):
# As the key berufsbildner is used in several courses, we use org_members to select the ones from the correct
# course sessions
relations_to_delete = agent.agentparticipantrelation_set.filter(
participant__in=org_members
)
# Bulk delete the identified relations
deleted_count, _ = relations_to_delete.delete()
# Log the result
logger.info(
"Deleted ausbildungsverantwortlicher relations",
agent=agent,
deleted_count=deleted_count,
)