diff --git a/server/vbv_lernwelt/importer/services.py b/server/vbv_lernwelt/importer/services.py index a7ac207f..e9033e56 100644 --- a/server/vbv_lernwelt/importer/services.py +++ b/server/vbv_lernwelt/importer/services.py @@ -3,9 +3,9 @@ from typing import Dict, Any from openpyxl.reader.excel import load_workbook from vbv_lernwelt.core.models import User -from vbv_lernwelt.course.models import Course, CourseSession -from vbv_lernwelt.importer.utils import try_parse_datetime -from vbv_lernwelt.learnpath.models import LearningContentAttendanceCourse +from vbv_lernwelt.course.models import Course, CourseSession, CourseSessionUser +from vbv_lernwelt.importer.utils import try_parse_datetime, parse_circle_group_string +from vbv_lernwelt.learnpath.models import LearningContentAttendanceCourse, Circle def create_or_update_user( @@ -27,7 +27,7 @@ def create_or_update_user( user = User(sso_id=sso_id, email=email, username=email) user.email = email - user.sso_id = sso_id + user.sso_id = user.sso_id or sso_id user.username = email user.first_name = first_name user.last_name = last_name @@ -100,3 +100,52 @@ def create_or_update_course_session(course: Course, data: Dict[str, Any], circle cs.save() return cs + + +def create_or_update_trainer(course: Course, data: Dict[str, Any]): + user = create_or_update_user( + email=data["Email"], + first_name=data["Vorname"], + last_name=data["Name"], + ) + + # TODO: handle language + + import_id = data["Generation"].strip() + groups = [g.strip() for g in data["Klasse"].strip().split(",")] + + # general expert handling + for group in groups: + course_session = CourseSession.objects.filter( + import_id=import_id, group=group, course=course + ).first() + if course_session: + csu, _created = CourseSessionUser.objects.get_or_create( + course_session_id=course_session.id, user_id=user.id + ) + csu.role = CourseSessionUser.Role.EXPERT + csu.save() + + # circle expert handling + circle_data = parse_circle_group_string(data["Circles"]) + for circle_string in circle_data: + parts = circle_string.split("(", 1) + circle_name = parts[0].strip() + groups = [g.strip() for g in parts[1].rstrip(")").strip().split(",")] + + # print(circle_name, groups) + for group in groups: + course_session = CourseSession.objects.filter( + import_id=import_id, group=group, course=course + ).first() + circle = Circle.objects.filter( + slug=f"{course.slug}-lp-circle-{circle_name.lower()}" + ).first() + + if course_session and circle: + csu = CourseSessionUser.objects.filter( + course_session_id=course_session.id, user_id=user.id + ).first() + if csu: + csu.expert.add(circle) + csu.save() diff --git a/server/vbv_lernwelt/importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx b/server/vbv_lernwelt/importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx index 9df30a5f..d40126c7 100644 Binary files a/server/vbv_lernwelt/importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx and b/server/vbv_lernwelt/importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx differ diff --git a/server/vbv_lernwelt/importer/tests/test_import_trainers.py b/server/vbv_lernwelt/importer/tests/test_import_trainers.py new file mode 100644 index 00000000..f02c8b15 --- /dev/null +++ b/server/vbv_lernwelt/importer/tests/test_import_trainers.py @@ -0,0 +1,76 @@ +import os +from datetime import datetime + +from django.test import TestCase +from openpyxl.reader.excel import load_workbook + +from vbv_lernwelt.course.creators.test_course import create_test_course +from vbv_lernwelt.course.models import CourseSession, CourseSessionUser +from vbv_lernwelt.importer.services import create_or_update_trainer + +test_dir = os.path.dirname(os.path.abspath(__file__)) + + +class ImportTrainerTestCase(TestCase): + def setUp(self): + self.course = create_test_course(include_vv=False) + + def test_import_excel_file(self): + workbook = load_workbook( + filename=f"{test_dir}/Schulungen_Durchfuehrung_Trainer.xlsx" + ) + sheet = workbook["Schulungen Trainer"] + + header = [cell.value for cell in sheet[1]] + + for row in sheet.iter_rows(min_row=2, values_only=True): + row_with_header = list(zip(header, row)) + print(row_with_header) + + +class CreateOrUpdateCourseSessionTestCase(TestCase): + def setUp(self): + self.course = create_test_course(include_vv=False) + self.course_session_a = CourseSession.objects.create( + course=self.course, + title="Deutschschweiz 2023 A", + import_id="DE 2023", + group="A", + ) + self.course_session_a = CourseSession.objects.create( + course=self.course, + title="Deutschschweiz 2023 B", + import_id="DE 2023", + group="B", + ) + + def test_create_course_session(self): + row = [ + ("Name", "Hänni"), + ("Vorname", "Fabienne"), + ("Email", "fabienne.haenni@vbv-afa.ch"), + ("Sprache", "de"), + ("Generation", "DE 2023"), + ("Klasse", "A, B"), + ("Circles", "Fahrzeug (A, B), Reisen (A), KMU (B)"), + ("Status Referenten", "ok"), + (None, "Schulung D"), + ("Klasse foo", datetime(2023, 6, 6, 0, 0)), + ] + + create_or_update_trainer(self.course, dict(row)) + + self.assertEqual( + CourseSessionUser.objects.filter( + user__email="fabienne.haenni@vbv-afa.ch" + ).count(), + 2, + ) + + csu = CourseSessionUser.objects.get( + course_session=self.course_session_a, + ) + + self.assertEqual(csu.role, CourseSessionUser.Role.EXPERT) + self.assertEqual(csu.user.email, "fabienne.haenni@vbv-afa.ch") + self.assertEqual(csu.expert.all().first().title, "Fahrzeug") diff --git a/server/vbv_lernwelt/importer/tests/test_services.py b/server/vbv_lernwelt/importer/tests/test_services.py index b7d76813..3402ef88 100644 --- a/server/vbv_lernwelt/importer/tests/test_services.py +++ b/server/vbv_lernwelt/importer/tests/test_services.py @@ -58,7 +58,6 @@ class CreateOrUpdateUserTestCase(TestCase): email="daniel@example.com", first_name="Daniel", last_name="Marro", - sso_id="12229620-81ea-483d-8d96-6ba8be5f9eb7", ) self.assertEqual(1, User.objects.count()) diff --git a/server/vbv_lernwelt/importer/tests/test_utils.py b/server/vbv_lernwelt/importer/tests/test_utils.py index 210d9ae0..6f5259e1 100644 --- a/server/vbv_lernwelt/importer/tests/test_utils.py +++ b/server/vbv_lernwelt/importer/tests/test_utils.py @@ -5,6 +5,7 @@ from vbv_lernwelt.importer.utils import ( try_parse_date, try_parse_int, try_parse_datetime, + parse_circle_group_string, ) @@ -180,3 +181,12 @@ class TryParseDateTimeTestCase(TestCase): self.assertTrue(flag) self.assertEqual(datetime(2023, 6, 9, 13, 30, 0), value) + + +class ParceCircleGroupStringTestCase(TestCase): + def test_withMultipleCircles(self): + value = "Fahrzeug (A, B), Reisen (A), KMU (B)" + self.assertEqual( + ["Fahrzeug (A, B)", "Reisen (A)", "KMU (B)"], + parse_circle_group_string(value), + ) diff --git a/server/vbv_lernwelt/importer/utils.py b/server/vbv_lernwelt/importer/utils.py index b60d659f..6700209e 100644 --- a/server/vbv_lernwelt/importer/utils.py +++ b/server/vbv_lernwelt/importer/utils.py @@ -1,6 +1,6 @@ import datetime import re -from typing import Any, Tuple, Union, Optional +from typing import Any, Tuple, Union, Optional, List from dateutil.parser import parse from six import string_types @@ -88,3 +88,11 @@ def try_parse_datetime( return False, value else: return False, value + + +def parse_circle_group_string(value: str) -> List[str]: + # This regex pattern matches any comma that is not inside parentheses + pattern = r",(?![^()]*\))" + + # re.split() splits the string based on the pattern + return [x.strip() for x in re.split(pattern, value)]