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 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 uk_cs_users_by_org(org: Organisation) -> set[CourseSessionUser]: return set( CourseSessionUser.objects.filter(user__organisation=org) .filter(course_session__course__configuration__is_uk=True) .filter(role=CourseSessionUser.Role.MEMBER.value) .filter(course_session__course_id__in=UK_COURSES) .exclude(course_session_id__in=[4, 5, 6]) ) def vv_cs_users_by_org(org: Organisation) -> set[CourseSessionUser]: return set( CourseSessionUser.objects.filter(user__organisation=org) .filter(course_session__course__configuration__is_uk=False) .filter(role=CourseSessionUser.Role.MEMBER.value) .filter(course_session__course_id__in=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) 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) def create_or_sync_learning_mentor( agent: User, org_members: set[CourseSessionUser] ) -> bool: logger.info( "Creating or syncing berufsbildner/ausbildungsverantwortlicher", berufsbildner=agent, org=agent.organisation.name_de, ) # Check if it is a valid organisation if agent.organisation and agent.organisation.organisation_id < 4: logger.error("Invalid organisation", org=agent.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) -> bool: org_members = uk_cs_users_by_org(organisation) delete_org_supervisor_relation(berufsbildner, org_members) def delete_ausbildungsverantwortlicher_relation(ausbildungsverantwortlicher: User, organisation: Organisation) -> bool: 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, )