from typing import Dict, Any import structlog from openpyxl.reader.excel import load_workbook from vbv_lernwelt.core.models import User 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 logger = structlog.get_logger(__name__) def create_or_update_user( email: str, first_name: str = "", last_name: str = "", sso_id: str = None ): logger.debug( "create_or_update_user", email=email, first_name=first_name, last_name=last_name, sso_id=sso_id, label="import", ) user = None if sso_id: user_qs = User.objects.filter(sso_id=sso_id) if user_qs.exists(): user = user_qs.first() if not user: user_qs = User.objects.filter(email=email) if user_qs.exists(): user = user_qs.first() if not user: # create user user = User(sso_id=sso_id, email=email, username=email) user.email = email user.sso_id = user.sso_id or sso_id user.username = email user.first_name = first_name user.last_name = last_name user.set_unusable_password() user.save() return user def import_course_sessions_from_excel(course: Course, filename: str): workbook = load_workbook(filename=filename) sheet = workbook["Schulungen Durchführung"] 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)) cs = create_or_update_course_session( course, dict(row_with_header), circles=["Fahrzeug"] ) def create_or_update_course_session(course: Course, data: Dict[str, Any], circles=None): """ :param data: the following keys are required to process the data: Generation, Region, Klasse :return: """ logger.debug( "create_or_update_course_session", course=course.title, data=data, label="import", ) if circles is None: circles = [] # TODO: validation group = data["Klasse"].strip() import_id = data["ID"].strip() generation = str(data["Generation"]).strip() region = data["Region"].strip() title = f"{region} {generation} {group}" cs, _created = CourseSession.objects.get_or_create( import_id=import_id, group=group, course=course ) cs.additional_json_data["import_data"] = data cs.save() cs.title = title cs.generation = generation cs.region = region cs.group = group cs.import_id = import_id cs.save() for circle in circles: attendance_course_lp_qs = LearningContentAttendanceCourse.objects.filter( slug=f"{course.slug}-lp-circle-{circle.lower()}-lc-präsenzkurs-{circle.lower()}" ) if attendance_course_lp_qs.exists(): cs.attendance_courses.append( { "learningContentId": attendance_course_lp_qs.first().id, "start": try_parse_datetime(data[f"{circle} Start"])[1].isoformat(), "end": try_parse_datetime(data[f"{circle} Ende"])[1].isoformat(), "location": data[f"{circle} Raum"], "trainer": "", } ) cs.save() return cs def import_trainers_from_excel(course: Course, filename: str): workbook = load_workbook(filename=filename) 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)) create_or_update_trainer(course, dict(row_with_header)) def create_or_update_trainer(course: Course, data: Dict[str, Any]): logger.debug( "create_or_update_trainer", course=course.title, data=data, label="import", ) 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()