from datetime import datetime from io import BytesIO from itertools import groupby from operator import attrgetter import djclick as click import structlog from openpyxl import Workbook from vbv_lernwelt.feedback.models import FeedbackResponse logger = structlog.get_logger(__name__) VV_FEEDBACK_QUESTIONS = [ ("satisfaction", "Zufriedenheit insgesamt"), ("goal_attainment", "Zielerreichung insgesamt"), ( "proficiency", "Wie beurteilst du deine Sicherheit bezüglichen den Themen nach dem Circle?", ), ("preparation_task_clarity", "Waren die Praxisaufträge klar und verständlich?"), ("would_recommend", "Würdest du den Circle weiterempfehlen?"), ("course_positive_feedback", "Was hat dir besonders gut gefallen?"), ("course_negative_feedback", "Wo siehst du Verbesserungspotential?"), ] logger = structlog.get_logger(__name__) @click.command() @click.argument("course_session_id") @click.option( "--save-as-file/--no-save-as-file", default=True, help="`save-as-file` to save the file, `no-save-as-file` returns bytes. Default is `save-as-file`.", ) def command(course_session_id, save_as_file): # using the output from call_command was a bit cumbersome, so this is just a wrapper for the actual function export_feedback(course_session_id, save_as_file) def export_feedback(course_session_id: str, save_as_file: bool): wb = Workbook() # remove the first sheet is just easier than keeping track of the active sheet wb.remove_sheet(wb.active) feedbacks = FeedbackResponse.objects.filter( course_session_id=course_session_id ).order_by("circle") grouped_feedbacks = groupby(feedbacks, key=attrgetter("circle")) for circle, group_feedbacks in grouped_feedbacks: group_feedbacks = list(group_feedbacks) logger.debug( "export_feedback_for_circle", data={ "circle": circle.title, "course_session_id": course_session_id, "count": len(group_feedbacks), }, label="feedback_export", ) create_sheet(wb, circle.title, group_feedbacks) if save_as_file: wb.save(make_export_filename()) else: output = BytesIO() wb.save(output) output.seek(0) return output.getvalue() def create_sheet(wb: Workbook, title: str, data: list[FeedbackResponse]): sheet = wb.create_sheet(title=title) # add header questions = [q[1] for q in VV_FEEDBACK_QUESTIONS] for col_idx, title in enumerate(questions, start=2): sheet.cell(row=1, column=col_idx, value=title) add_rows(sheet, data) return sheet def add_rows(sheet, data): for row_idx, feedback in enumerate(data, start=2): for col_idx, question in enumerate(VV_FEEDBACK_QUESTIONS, start=2): response = feedback.data.get(question[0], "") sheet.cell(row=row_idx, column=col_idx, value=response) def make_export_filename(): today_date = datetime.today().strftime("%Y-%m-%d") return f"feedback_export_{today_date}.xlsx"