From c64341a6c18da6a320997921d11edbb65e5e3e8d Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Fri, 14 Apr 2023 09:05:36 +0200 Subject: [PATCH] Refactor test course to make it more realistic --- .../assignment/creators/create_assignments.py | 277 ++++++++++++++++- .../course/creators/test_course.py | 289 +++++++++++------- .../commands/create_default_courses.py | 6 - 3 files changed, 458 insertions(+), 114 deletions(-) diff --git a/server/vbv_lernwelt/assignment/creators/create_assignments.py b/server/vbv_lernwelt/assignment/creators/create_assignments.py index 62b196e6..c85e9caa 100644 --- a/server/vbv_lernwelt/assignment/creators/create_assignments.py +++ b/server/vbv_lernwelt/assignment/creators/create_assignments.py @@ -1,3 +1,5 @@ +from wagtail.blocks import StreamValue + from vbv_lernwelt.assignment.models import TaskContentStreamBlock from vbv_lernwelt.assignment.tests.assignment_factories import ( AssignmentFactory, @@ -8,9 +10,8 @@ from vbv_lernwelt.assignment.tests.assignment_factories import ( UserTextInputBlockFactory, ) from vbv_lernwelt.core.utils import replace_whitespace -from vbv_lernwelt.course.consts import COURSE_UK +from vbv_lernwelt.course.consts import COURSE_UK, COURSE_TEST_ID from vbv_lernwelt.course.models import CoursePage -from wagtail.blocks import StreamValue def create_uk_assignments(course_id=COURSE_UK): @@ -283,3 +284,275 @@ def create_uk_assignments(course_id=COURSE_UK): ) assignment.save() + + +def create_test_assignments(course_id=COURSE_TEST_ID): + course_page = CoursePage.objects.get(course_id=course_id) + assignment_page = AssignmentListPageFactory( + parent=course_page, + ) + + assignment = AssignmentFactory( + parent=assignment_page, + title="Überprüfen einer Motorfahrzeugs-Versicherungspolice", + effort_required="ca. 5 Stunden", + starting_position=replace_whitespace( + """ + Jemand aus deiner Familie oder aus deinem Freundeskreis möchte sein + Versicherungspolice überprüfen lassen. Diese Person kommt nun mit ihrer Police auf dich zu + und bittet dich als Versicherungsprofi, diese kritisch zu überprüfen und ihr ggf. Anpassungsvorschläge + zu unterbreiten. In diesem Kompetenznachweis kannst du nun dein Wissen und Können im Bereich + der Motorfahrzeugversicherung unter Beweis stellen. + """ + ), + performance_objectives=[ + ( + "performance_objective", + PerformanceObjectiveBlockFactory( + text="Sie erläutern die Leistungen und Produkte im Versicherungsbereich." + ), + ), + ( + "performance_objective", + PerformanceObjectiveBlockFactory( + text="Sie beurteilen gängige Versicherungslösungen fachkundig." + ), + ), + ], + assessment_document_url="https://www.vbv.ch", + assessment_description="Diese geleitete Fallarbeit wird auf Grund des folgenden Beurteilungsintrument bewertet.", + ) + + assignment.tasks = [] + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Teilaufgabe 1: Beispiel einer Versicherungspolice finden", + # it is hard to create a StreamValue programmatically, we have to + # create a `StreamValue` manually. Ask the Daniel and/or Ramon + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory(text="Dies ist ein Beispieltext."), + ), + ( + "user_confirmation", + ExplanationBlockFactory( + text="Ja, ich habe Motorfahrzeugversicherungspolice von jemandem aus meiner Familie oder meinem Freundeskreis erhalten." + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Teilaufgabe 2: Kundensituation und Ausgangslage", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=replace_whitespace( + """ + Erläutere die Kundensituation und die Ausgangslage. + * Hast du alle Informationen, die du für den Policen-Check benötigst? + * Halte die wichtigsten Eckwerte des aktuellen Versicherungsverhältnisse in deiner Dokumentation fest (z.B wie lang wo versichert, Alter des Fahrzeugs, Kundenprofil, etc.) + """ + ) + ), + ), + ("user_text_input", UserTextInputBlockFactory()), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Teilaufgabe 3: Aktuelle Versicherung", + # TODO: add document upload + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=replace_whitespace( + """ + Zeige nun detailliert auf, wie dein Kundenbeispiel momentan versichert ist. + """ + ) + ), + ), + ("user_text_input", UserTextInputBlockFactory()), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Teilaufgabe 4: Deine Empfehlungen", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=replace_whitespace( + """ + Erarbeite nun basierend auf deinen Erkenntnissen eine Empfehlung für die Person. + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Gibt es zusätzliche Deckungen, die du der Person empfehlen würdest? Begründe deine Empfehlung + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Gibt es Deckungen, die du streichen würdest? Begründe deine Empfehlung. + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Wenn die Person gemäss deiner Einschätzung genau richtig versichert ist, argumentiere, warum dies der Fall ist. + """ + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Teilaufgabe 5: Reflexion", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=replace_whitespace( + """ + Reflektiere dein Handeln und halte deine Erkenntnisse fest. Frage dich dabei: + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + War die Bearbeitung dieser geleiteten Fallarbeit erfolgreich? Begründe deine Einschätzung. + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Was ist dir bei der Bearbeitung des Auftrags gut gelungen? + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Was ist dir bei der Bearbeitung des Auftrags weniger gut gelungen? + """ + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Teilaufgabe 6: Learnings", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=replace_whitespace( + """ + Leite aus der Teilaufgabe 5 deine persönlichen Learnings ab. + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Was würdest du beim nächsten Mal anders machen? + """ + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=replace_whitespace( + """ + Was hast du beim Bearbeiten des Auftrags Neues gelernt? + """ + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.save() diff --git a/server/vbv_lernwelt/course/creators/test_course.py b/server/vbv_lernwelt/course/creators/test_course.py index 1a262434..7966fcc4 100644 --- a/server/vbv_lernwelt/course/creators/test_course.py +++ b/server/vbv_lernwelt/course/creators/test_course.py @@ -2,8 +2,11 @@ import json import wagtail_factories from django.conf import settings +from slugify import slugify from wagtail.models import Site +from vbv_lernwelt.assignment.creators.create_assignments import create_test_assignments +from vbv_lernwelt.assignment.models import Assignment from vbv_lernwelt.competence.factories import ( CompetencePageFactory, CompetenceProfilePageFactory, @@ -13,20 +16,20 @@ from vbv_lernwelt.competence.models import CompetencePage from vbv_lernwelt.core.tests.helpers import create_locales_for_wagtail from vbv_lernwelt.course.consts import COURSE_TEST_ID from vbv_lernwelt.course.factories import CoursePageFactory -from vbv_lernwelt.course.models import Course, CourseCategory, CoursePage -from vbv_lernwelt.learnpath.models import LearningUnit +from vbv_lernwelt.course.models import Course, CoursePage, CourseSession, CourseCategory from vbv_lernwelt.learnpath.tests.learning_path_factories import ( CircleFactory, - DocumentBlockFactory, - ExerciseBlockFactory, LearningContentFactory, - LearningModuleBlockFactory, LearningPathFactory, LearningSequenceFactory, LearningUnitFactory, - OnlineTrainingBlockFactory, - TestBlockFactory, TopicFactory, + MediaLibraryBlockFactory, + AttendanceDayBlockFactory, + FeedbackBlockFactory, + VideoBlockFactory, + LearningModuleBlockFactory, + AssignmentBlockFactory, ) from vbv_lernwelt.media_library.tests.media_library_factories import ( create_external_link_block, @@ -42,10 +45,18 @@ from vbv_lernwelt.media_library.tests.media_library_factories import ( def create_test_course(): create_locales_for_wagtail() create_test_course_with_categories() - create_test_learning_path() + + create_test_assignments() create_test_competence_profile() + create_test_learning_path() create_test_media_library() + # course sessions + CourseSession.objects.create( + course_id=COURSE_TEST_ID, + title="Bern 2022 a", + ) + def create_test_course_with_categories(apps=None, schema_editor=None): if apps is not None: @@ -89,118 +100,210 @@ def create_test_learning_path(user=None, skip_locales=True): course_page = CoursePage.objects.get(course_id=COURSE_TEST_ID) lp = LearningPathFactory(title="Test Lernpfad", parent=course_page) - TopicFactory(title="Basis", is_visible=False, parent=lp) + TopicFactory(title="Circle ÜK", is_visible=False, parent=lp) + create_test_uk_circle_fahrzeug(lp, title="Fahrzeug") - circle_basis = CircleFactory( - title="Basis", + TopicFactory(title="Circle VV", is_visible=False, parent=lp) + create_test_circle_reisen(lp) + + +def create_test_uk_circle_fahrzeug(lp, title="Fahrzeug"): + circle = CircleFactory( + title=title, parent=lp, - description="Basis", + description=""" +In diesem Circle erfährst du wie der Lehrgang aufgebaut ist. +Zudem lernst du die wichtigsten Grundlagen, +damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst. + """.strip(), ) LearningSequenceFactory( - title="Starten", parent=circle_basis, icon="it-icon-ls-start" + title="Vorbereitung", parent=circle, icon="it-icon-ls-start" ) - LearningUnitFactory(title="Einführung", parent=circle_basis) + lu = LearningUnitFactory(title="Vorbereitung", parent=circle) LearningContentFactory( - title="Einführung", - parent=circle_basis, - minutes=15, - contents=[("document", DocumentBlockFactory())], - ) - LearningSequenceFactory(title="Beenden", parent=circle_basis, icon="it-icon-ls-end") - LearningUnitFactory(title="Beenden", parent=circle_basis) - LearningContentFactory( - title="Jetzt kann es losgehen!", - parent=circle_basis, - minutes=30, - contents=[("document", DocumentBlockFactory())], - ) - - TopicFactory(title="Beraten der Kunden", parent=lp) - - circle = CircleFactory( - title="Analyse", - parent=lp, - description="Unit-Test Circle", - ) - - LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start") - LearningUnitFactory(title="Einführung", parent=circle) - LearningContentFactory( - title=f'Einleitung Circle "Analyse"', + title="Verschaffe dir einen Überblick", parent=circle, - minutes=15, - contents=[("document", DocumentBlockFactory())], - ) - - LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch") - lu = LearningUnitFactory( - title="Fahrzeug", - parent=circle, - course_category=CourseCategory.objects.get( - course_id=COURSE_TEST_ID, title="Fahrzeug" - ), ) LearningContentFactory( - title="Rafael Fasel wechselt sein Auto", + title=f"Mediathek {title}", parent=circle, - minutes=30, contents=[ ( - "online_training", - OnlineTrainingBlockFactory( - description="In diesem Online-Training lernst du, wie du den Kundenbedarf ermittelst.", - url="", + "media_library", + MediaLibraryBlockFactory( + url=f"/media/überbetriebliche-kurse-media/category/{slugify(title)}" ), ) ], ) LearningContentFactory( - title="Fachcheck Fahrzeug", + title="Vorbereitungsauftrag", parent=circle, - minutes=30, - contents=[("test", TestBlockFactory())], ) - lu = LearningUnitFactory( + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get(competence_id="X1"), + competence_id="X1.1", + title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, die Ziele und Pläne des Kunden zu ergründen (SOLL).", + learning_unit=lu, + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get(competence_id="X1"), + competence_id="X1.1", + title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, die IST-Situation des Kunden mit der geeigneten Gesprächs-/Fragetechnik zu erfassen.", + learning_unit=lu, + ) + + LearningSequenceFactory(title="Training", parent=circle) + LearningUnitFactory(title="Unterlagen", parent=circle) + LearningContentFactory( + title="Unterlagen für den Unterricht", + parent=circle, + ) + LearningUnitFactory(title="Präsenztag", parent=circle) + LearningContentFactory( + title="Präsenztag Fahrzeug", + parent=circle, + contents=[ + ( + "attendance_day", + AttendanceDayBlockFactory(), + ) + ], + ) + LearningUnitFactory(title="Kompetenznachweis", parent=circle) + LearningContentFactory( + title="Wissens- und Verständnisfragen", + parent=circle, + ) + LearningSequenceFactory(title="Transfer", parent=circle, icon="it-icon-ls-end") + LearningUnitFactory(title="Transfer", parent=circle) + LearningContentFactory( + title="Reflexion", + parent=circle, + ) + LearningContentFactory( + title="Überprüfen einer Motorfahrzeug-Versicherungspolice", + parent=circle, + contents=[ + ( + "assignment", + AssignmentBlockFactory( + assignment=Assignment.objects.get( + slug__startswith="test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs" + ) + ), + ) + ], + ) + LearningContentFactory( + title="Feedback", + parent=circle, + contents=[ + ( + "feedback", + FeedbackBlockFactory(), + ) + ], + ) + + +def create_test_circle_reisen(lp): + circle = CircleFactory( title="Reisen", + parent=lp, + ) + LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start") + LearningUnitFactory(title="Einführung", parent=circle) + LearningContentFactory( + title="Verschaff dir einen Überblick", + parent=circle, + contents=[ + ( + "video", + VideoBlockFactory( + url="https://player.vimeo.com/video/772512710?h=30f912f15a", + description="Willkommen im Lehrgang Versicherungsvermitler VBV", + ), + ) + ], + ) + LearningContentFactory( + title=f"Mediathek Reisen", + parent=circle, + contents=[ + ( + "media_library", + MediaLibraryBlockFactory( + url=f"/media/test-lehrgang-media/category/reisen" + ), + ) + ], + ) + + LearningSequenceFactory(title="Analyse", parent=circle) + + # analyse + lu = LearningUnitFactory( + title="Bedarfsanalyse, Ist- und Soll-Situation", parent=circle, course_category=CourseCategory.objects.get( course_id=COURSE_TEST_ID, title="Reisen" ), ) + LearningContentFactory( - title="Reiseversicherung", + title="Emma und Ayla campen durch Amerika - Analyse", parent=circle, - minutes=240, - contents=[("exercise", ExerciseBlockFactory())], - ) - LearningContentFactory( - title="Emma und Ayla campen durch Amerika", - parent=circle, - minutes=120, contents=[ ( "learningmodule", LearningModuleBlockFactory( - url="/static/media/web_based_trainings/story-06-a-01-emma-und-ayla-campen-durch-amerika-einstieg/scormcontent/index.html" + url="https://s3.eu-central-1.amazonaws.com/myvbv-wbt.iterativ.ch/emma-und-ayla-campen-durch-amerika-analyse-xapi-FZoZOP9y/index.html" ), ) ], ) - LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end") - LearningUnitFactory(title="Beenden", parent=circle) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get(competence_id="Y1"), + competence_id=f"Y1.1", + title=f"Ich bin fähig zu Reisen eine Gesprächsführung zu machen", + learning_unit=lu, + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get(competence_id="Y2"), + competence_id=f"Y2.1", + title=f"Ich bin fähig zu Reisen eine Analyse zu machen", + learning_unit=lu, + ) + + # transfer + parent = circle + LearningSequenceFactory(title="Transfer", parent=parent, icon="it-icon-ls-end") + LearningUnitFactory(title="Transfer, Reflexion, Feedback", parent=parent) LearningContentFactory( - title="KompetenzNavi anschauen", - parent=circle, - minutes=30, - contents=[("document", DocumentBlockFactory())], + title="Auswandern: Woran muss ich denken?", + parent=parent, ) LearningContentFactory( - title='Circle "Analyse" abschliessen', - parent=circle, - minutes=30, - contents=[("document", DocumentBlockFactory())], + title=f"Fachcheck Reisen", + parent=parent, + ) + LearningContentFactory( + title="Reflexion", + parent=parent, + ) + LearningContentFactory( + title="Feedback", + parent=parent, + contents=[ + ( + "feedback", + FeedbackBlockFactory(), + ) + ], ) @@ -249,32 +352,6 @@ def create_test_competence_profile(): items=[("item", i) for i in c["items"]], ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get(competence_id="Y1"), - competence_id="Y1.3", - title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, die Ziele und Pläne des Kunden zu ergründen (SOLL).", - learning_unit=LearningUnit.objects.get( - slug="test-lehrgang-lp-circle-analyse-lu-fahrzeug" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get(competence_id="Y2"), - competence_id="Y2.1", - title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, die IST-Situation des Kunden mit der geeigneten Gesprächs-/Fragetechnik zu erfassen.", - learning_unit=LearningUnit.objects.get( - slug="test-lehrgang-lp-circle-analyse-lu-fahrzeug" - ), - ) - - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get(competence_id="Y1"), - competence_id="Y1.3", - title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, die Ziele und Pläne des Kunden zu ergründen (SOLL).", - learning_unit=LearningUnit.objects.get( - slug="test-lehrgang-lp-circle-analyse-lu-reisen" - ), - ) - def create_test_media_library(): course = Course.objects.get(id=COURSE_TEST_ID) diff --git a/server/vbv_lernwelt/course/management/commands/create_default_courses.py b/server/vbv_lernwelt/course/management/commands/create_default_courses.py index fd779e9b..6e2fe032 100644 --- a/server/vbv_lernwelt/course/management/commands/create_default_courses.py +++ b/server/vbv_lernwelt/course/management/commands/create_default_courses.py @@ -69,12 +69,6 @@ def command(course): if COURSE_TEST_ID in course: create_test_course() - # course sessions - CourseSession.objects.create( - course_id=COURSE_TEST_ID, - title="Test Lehrgang Session", - ) - def create_versicherungsvermittlerin_course(): # Versicherungsvermittler/in mit neuen Circles