from dataclasses import dataclass from datetime import datetime from io import BytesIO import structlog from django.utils import timezone from django.utils.translation import gettext_lazy as _ from openpyxl import Workbook from vbv_lernwelt.assignment.models import ( Assignment, AssignmentCompletion, AssignmentType, ) from vbv_lernwelt.course.models import CourseSession, CourseSessionUser from vbv_lernwelt.course_session.models import ( CourseSessionAssignment, CourseSessionEdoniqTest, ) from vbv_lernwelt.course_session.services.export_attendance import ( add_user_export_data, add_user_headers, get_ordered_csus_by_course_session, group_by_session_title, make_export_filename, sanitize_sheet_name, ) from vbv_lernwelt.learnpath.models import LearningContent logger = structlog.get_logger(__name__) COMPETENCE_ELEMENT_EXPORT_FILE_NAME = _("export_kompetenznachweis_elemente") @dataclass class CompetenceCertificateElement: assignment: Assignment # date: DueDate sort_datetime: datetime learning_content: LearningContent course_session: CourseSession def export_competence_elements( course_session_ids: list[str], circle_ids: list[int] = None, user_ids: list[str] = None, save_as_file: bool = False, ): if len(course_session_ids) == 0: return COMPETENCE_ASSIGNMENT_TYPES = [ AssignmentType.CASEWORK.value, AssignmentType.EDONIQ_TEST.value, ] wb = Workbook() # remove the first sheet is just easier than keeping track of the active sheet wb.remove(wb.active) competence_certificate_elements = _get_competence_certificate_elements( course_session_ids ) assignment_completions = AssignmentCompletion.objects.filter( course_session_id__in=course_session_ids, assignment__assignment_type__in=COMPETENCE_ASSIGNMENT_TYPES, ).order_by("course_session", "assignment") if user_ids: assignment_completions = AssignmentCompletion.objects.filter( assignment_user_id__in=user_ids if user_ids else [], ).order_by("course_session", "assignment") # group all by the sessions title {session_id1: [...], session_id2: [...], ...} grouped_cs_users = get_ordered_csus_by_course_session( course_session_ids, user_ids=user_ids ) grouped_cce = group_by_session_title(competence_certificate_elements) grouped_ac = group_by_session_title(assignment_completions) # create a sheet for each course session for course_session_title, cs_users in grouped_cs_users.items(): logger.debug( "export_assignment_completion", data={ "course_session": course_session_title, }, label="assignment_export", ) # handle the case where there are no competence certificate elements for the course session try: cces = grouped_cce[course_session_title] except KeyError: cces = [] try: acs = grouped_ac[course_session_title] except KeyError: acs = [] _create_sheet( wb, course_session_title, cs_users, cces, acs, circle_ids, ) if save_as_file: wb.save(make_export_filename(COMPETENCE_ELEMENT_EXPORT_FILE_NAME)) else: output = BytesIO() wb.save(output) output.seek(0) return output.getvalue() def _create_sheet( wb: Workbook, title: str, users: list[CourseSessionUser], competence_certificate_element: list[CompetenceCertificateElement], assignment_completions: list[AssignmentCompletion], circle_ids: list[int], ): sheet = wb.create_sheet(title=sanitize_sheet_name(title)) if len(users) == 0 or len(competence_certificate_element) == 0: return sheet # headers # common user headers, Circle