diff --git a/server/vbv_lernwelt/assignment/creators/create_assignments.py b/server/vbv_lernwelt/assignment/creators/create_assignments.py index c0ba555d..c69d043a 100644 --- a/server/vbv_lernwelt/assignment/creators/create_assignments.py +++ b/server/vbv_lernwelt/assignment/creators/create_assignments.py @@ -14,7 +14,11 @@ 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, COURSE_VERSICHERUNGSVERMITTLERIN_ID +from vbv_lernwelt.course.consts import ( + COURSE_UK, + COURSE_UK_FR, + COURSE_VERSICHERUNGSVERMITTLERIN_ID, +) from vbv_lernwelt.course.models import CoursePage from wagtail.blocks import StreamValue from wagtail.blocks.list_block import ListBlock, ListValue @@ -465,7 +469,481 @@ def create_uk_fahrzeug_casework(course_id=COURSE_UK): return assignment -def create_uk_fahrzeug_prep_assignment(course_id=COURSE_UK): +def create_uk_fr_fahrzeug_casework(course_id=COURSE_UK_FR): + assignment_list_page = ( + CoursePage.objects.get(course_id=course_id) + .get_children() + .exact_type(AssignmentListPage) + .first() + ) + + assignment = AssignmentFactory( + parent=assignment_list_page, + title="Vérification d'une police d’assurance de véhicule à moteur", + effort_required="5 heures environ", + intro_text=replace_whitespace( + """ +
+ Une personne de ta famille ou de tes connaissances souhaite faire vérifier sa police d'assurance. Elle se + tourne alors vers toi et te demande, en ta qualité de spécialiste de l'assurance, de l'examiner d’un œil + critique et de lui soumettre, le cas échéant, des propositions d'adaptation. Dans le cadre de cette évaluation + des compétences, tu peux maintenant prouver tes connaissances et tes compétences dans le domaine de l'assurance + des véhicules à moteur. +
+ """ + ), + performance_objectives=[ + ( + "performance_objective", + PerformanceObjectiveBlockFactory( + text="d2.pv.ük3: Ils expliquent les services et les produits dans le domaine de l’assurance." + ), + ), + ( + "performance_objective", + PerformanceObjectiveBlockFactory( + text="c3.pv.ük11: Ils évaluent les solutions d’assurance courantes avec professionnalisme (C3)." + ), + ), + ], + evaluation_document_url="/static/media/assignments/fr_üK1_FZ_09_NACH_KN_Beurteilungsraster.pdf", + evaluation_description="Diese geleitete Fallarbeit wird auf Grund des folgenden Beurteilungsintrument bewertet.", + ) + + assignment.evaluation_tasks = [] + assignment.evaluation_tasks.append( + ( + "task", + EvaluationTaskBlockFactory( + title="Exposé de la situation de départ", + description=RichText( + "L'apprenant(e) expose-t-il / elle la situation de départ dans son intégralité?" + ), + max_points=6, + sub_tasks=ListValue( + ListBlock(EvaluationSubTaskBlock()), + values=[ + EvaluationSubTaskBlockFactory( + title="La situation de départ est décrite dans son intégralité:", + description=RichText( + replace_whitespace( + """ +
+ Compétence opérationnelle d2 : Mener des entretiens d’information et de conseil avec des
+ clients et des fournisseurs
+ Situation de travail 4 : Conseiller les clients et s’occuper des processus correspondants
+
+ Compétence opérationnelle e4 : Préparer des contenus en lien avec l’entreprise à l’aide d’outils multimédia
+ Situation de travail 1 : Mettre en avant les caractéristiques de la branche et les points forts de l’entreprise
+
+ Imagine que tu viens de réussir ton permis de conduire et que tu vas enfin pouvoir être davantage mobile. + Quelle sera ta première voiture? Et cette voiture, tu vas évidemment vouloir la protéger et l’assurer correctement. +
+ """ + ), + performance_objectives=[], + ) + + assignment.tasks = [] + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Exercice 1: Obtenez un premier aperçu du sujet.", + # it is hard to create a StreamValue programmatically, we have to + # create a `StreamValue` manually. Ask Daniel and/or Ramon + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=RichText( + 'Commence par te faire une première idée de ce sujet: regarde la vidéo suivante: Comment fonctionne une assurance auto? Un sujet expliqué simplement?' + ) + ), + ), + ( + "user_confirmation", + ExplanationBlockFactory( + text=RichText( + "Oui, j'ai regardé la vidéo et j'ai compris." + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Exercice 2: Lire le chapitre «Droit de la responsabilité civile et assurances des véhicules à moteur»", + # it is hard to create a StreamValue programmatically, we have to + # create a `StreamValue` manually. Ask Daniel and/or Ramon + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=RichText( + "Lis et traite les chapitres correspondants dans le manuel «Droit de la responsabilité civile et assurances des véhicules à moteur»." + ) + ), + ), + ( + "user_confirmation", + ExplanationBlockFactory( + text=RichText("Oui, j'ai lu et compris le chapitre.") + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Exercice 3: Établir une offre", + # it is hard to create a StreamValue programmatically, we have to + # create a `StreamValue` manually. Ask Daniel and/or Ramon + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=RichText( + replace_whitespace( + """ ++ C’est parti! Établis une offre correspondante pour ta première voiture. Réfléchis aux couvertures que tu souhaites absolument inclure et celles qui seraient souhaitables dans ton cas. À cet effet, utilise l’outil de ta compagnie pour l’établissement des offres. Tu peux aussi utiliser n'importe quel outil équivalent en ligne. +
++ Tu devras peut-être tricher un peu avec ton année de naissance pour être assez âgé(e) pour t’établir une offre. +
+ """ + ) + ) + ), + ), + ( + "user_confirmation", + ExplanationBlockFactory( + text=RichText("Oui, j'ai établi une offre.") + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Exercice 4: Notes et questions", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=RichText( + "Au cours de ce processus, prends des notes pour répondre aux questions suivantes:" + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Comment as-tu procédé pour établir ton offre?" + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Quelles difficultés as-tu rencontrées lors de l’établissement de l’offre? Comment as-tu résolu ces difficultés?" + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Quelles informations sont indispensables pour pouvoir établir une offre correcte d’assurance des véhicules à moteur?" + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Pour quelles couvertures complémentaires as-tu opté? Pour quelles raisons?" + ) + ), + ), + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Quels sont les principaux facteurs / éléments qui déterminent le montant de la prime?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Exercice 5: Cours en présentiel", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "explanation", + ExplanationBlockFactory( + text=RichText( + "Apporte l’offre et tes notes en cours.
" + "N'oublie pas les CGA correspondantes. Ce n’est pas un problème si tu n’as ces documents que sous forme électronique.
" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.save() + + return assignment + + def create_uk_kickoff_prep_assignment(course_id=COURSE_UK): assignment_list_page = ( CoursePage.objects.get(course_id=course_id) @@ -1407,6 +2123,310 @@ def create_uk_reflection(course_id=COURSE_UK, circle_title="Fahrzeug"): return assignment +def create_uk_fr_reflection(course_id=COURSE_UK_FR, circle_title="Véhicule"): + assignment_list_page = ( + CoursePage.objects.get(course_id=course_id) + .get_children() + .exact_type(AssignmentListPage) + .first() + ) + + assignment = AssignmentFactory( + parent=assignment_list_page, + assignment_type=AssignmentType.REFLECTION.name, + title=f"Reflexion", + effort_required="", + intro_text=replace_whitespace( + """ ++ Tu as reçu beaucoup de nouveaux contenus et d'inputs dans ce Circle. Il est maintenant temps de jeter à nouveau un coup d'œil sur ton profil de compétences. Répondre aux questions de réflexion t'aide à rendre visible et compréhensible ton propre processus d'apprentissage et de réflexion. Elle met en évidence tes forces et tes faiblesses personnelles pendant l'élaboration et t'aide à t'améliorer en permanence. +
+ """ + ), + performance_objectives=[], + ) + + assignment.tasks = [] + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Question 1: Qu'est-ce que je réussis déjà bien?", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory(), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Question 2: Approfondissment", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Où dois-je encore approfondir ou répéter? " + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Question 3: Qu'est-ce que je retiens?", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory(), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Question 4: Préparation", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Comment me suis-je préparé(e) au Cercle (par ex. en prévoyant du temps d'étude)?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Question 5: Cours de présence", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Quel a été mon degré d'engagement dans les cours de présence?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Question 6: Amélioration", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Qu'est-ce que je veux changer/améliorer dans le processus d'apprentissage pour le prochain Circle?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.save() + + return assignment + + +def create_uk_it_reflection(course_id=COURSE_UK_FR, circle_title="Véhicule"): + assignment_list_page = ( + CoursePage.objects.get(course_id=course_id) + .get_children() + .exact_type(AssignmentListPage) + .first() + ) + + assignment = AssignmentFactory( + parent=assignment_list_page, + assignment_type=AssignmentType.REFLECTION.name, + title=f"Riflessione", + effort_required="", + intro_text=replace_whitespace( + """ ++ In questo Circle hai ricevuto molti nuovi contenuti e input. Ora è il momento di dare un'altra occhiata al tuo profilo di competenza. Rispondere alle domande di riflessione aiuta a rendere visibile e comprensibile il proprio processo di apprendimento e di pensiero. Rivela i punti di forza e di debolezza personali durante l'elaborazione e aiuta a migliorare continuamente. +
+ """ + ), + performance_objectives=[], + ) + + assignment.tasks = [] + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Domanda 1: Cosa sto già facendo bene?", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory(), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Domanda 2: Approfondimento", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Dove devo ancora approfondire o ripetere le mie conoscenze?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Domanda 3: Cosa porterò con me?", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory(), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Domanda 4: Preparazione", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Come mi sono preparato per il Circle (ad esempio, programmando il tempo di studio)?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Domanda 5: Insegnamento in classe", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText("Quanto mi sono impegnato in classe?") + ), + ), + ], + ), + ), + ) + ) + + assignment.tasks.append( + ( + "task", + TaskBlockFactory( + title="Domanda 6: Miglioramento", + content=StreamValue( + TaskContentStreamBlock(), + stream_data=[ + ( + "user_text_input", + UserTextInputBlockFactory( + text=RichText( + "Cosa voglio cambiare/migliorare nel processo di apprendimento per il prossimo Circle?" + ) + ), + ), + ], + ), + ), + ) + ) + + assignment.save() + + return assignment + + def create_vv_reflection( course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID, _circle_title="Fahrzeug" ): diff --git a/server/vbv_lernwelt/competence/create_uk_competence_profile.py b/server/vbv_lernwelt/competence/create_uk_competence_profile.py index b617c087..09996f09 100644 --- a/server/vbv_lernwelt/competence/create_uk_competence_profile.py +++ b/server/vbv_lernwelt/competence/create_uk_competence_profile.py @@ -273,72 +273,13 @@ def create_uk_fr_competence_profile(course_id=COURSE_UK_FR): items=[("item", i) for i in c["items"]], ) + # Circle Fahrzeug PerformanceCriteriaFactory( parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="c3" ), - competence_id="e4.pv.ük1", - title="Sie erläutern die Dienstleistungen des Betriebs. (K2)", - learning_unit=LearningUnit.objects.get( - slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" - ), - competence_id="e4.pv.ük3", - title="Sie stellen die Wertschöpfungskette und die verschiedenen organisatorischen Bereiche ihres Betriebs dar. (K2).", - learning_unit=LearningUnit.objects.get( - slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" - ), - competence_id="e4.pv.ük4", - title="Sie erläutern die relevanten rechtlichen Grundlagen ihrer Branche situationsgerecht. (K2)", - learning_unit=LearningUnit.objects.get( - slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" - ), - competence_id="d2.pv.ük1", - title="Sie beschreiben die wichtigsten gesetzlichen Grundlagen im Versicherungsbereich umfassend. (K2)", - learning_unit=LearningUnit.objects.get( - slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" - ), - competence_id="d2.pv.ük2", - title="Sie nennen die relevanten Dienstleistungen und Produkte im Versicherungsbereich. (K1)", - learning_unit=LearningUnit.objects.get( - slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" - ), - competence_id="d2.pv.ük3", - title="Sie erklären die Leistungen und Produkte im Versicherungsbereich. (K2)", - learning_unit=LearningUnit.objects.get( - slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" - ), - ) - PerformanceCriteriaFactory( - parent=CompetencePage.objects.get( - slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" - ), - competence_id="d2.pv.ük4", - title="Sie erläutern die Prozesse und Abläufe im privaten Versicherungsbereich verständlich. (K2)", + competence_id="c3.pv.ci2", + title="Je suis capable de d'expliquer les fondements légaux applicables dans le champ d'action des véhicules.", learning_unit=LearningUnit.objects.get( slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" ), @@ -347,8 +288,8 @@ def create_uk_fr_competence_profile(course_id=COURSE_UK_FR): parent=CompetencePage.objects.get( slug__startswith=slug_prefix.replace("-lp", ""), competence_id="c3" ), - competence_id="c3.pv.ük7", - title="Sie erläutern die gesetzlichen Bestimmungen bei Schaden- und Leistungsfällen. (K2)", + competence_id="c3.pv.ci7", + title="Je suis capable de d'expliquer les dispositions légales en cas de sinistres et de versement de prestations dans le champ d'action des véhicules.", learning_unit=LearningUnit.objects.get( slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" ), @@ -357,8 +298,78 @@ def create_uk_fr_competence_profile(course_id=COURSE_UK_FR): parent=CompetencePage.objects.get( slug__startswith=slug_prefix.replace("-lp", ""), competence_id="c3" ), - competence_id="c3.pv.ük11", - title="Sie beurteilen gängige Versicherungslösungen fachkundig. (K3)", + competence_id="c3.pv.ci11", + title="Je suis capable de d'évaluer de manière compétente les solutions d’assurance courantes dans le domaine d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci1", + title="Je suis capable de décrire de manière complète les principales bases légales dans le domaine de l'assurance des véhicules à moteur.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci2", + title="Je suis capable de citer les prestations de service et les produits pertinents dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci3", + title="Je suis capable de d'expliquer les services et les produits dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci4", + title="Je suis capable de d'expliquer de manière compréhensible les processus et procédures dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + ), + competence_id="e4.pv.ci1", + title="Je suis capable de d'expliquer les services de l'entreprise dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + ), + competence_id="e4.pv.ci2", + title="Je suis capable de de distinguer les concurrents dans le secteur des assurances privées dans le champ d'action des véhicules à l'aide des critères pertinents.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + ), + competence_id="e4.pv.ci4", + title="Je suis capable de d'expliquer les principes sur lesquelles reposent les produits d'assurance automobile.", learning_unit=LearningUnit.objects.get( slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" ), diff --git a/server/vbv_lernwelt/competence/create_uk_training_competence_profile.py b/server/vbv_lernwelt/competence/create_uk_training_competence_profile.py index 7e8048b3..458ce705 100644 --- a/server/vbv_lernwelt/competence/create_uk_training_competence_profile.py +++ b/server/vbv_lernwelt/competence/create_uk_training_competence_profile.py @@ -4,7 +4,7 @@ from vbv_lernwelt.competence.factories import ( PerformanceCriteriaFactory, ) from vbv_lernwelt.competence.models import CompetencePage -from vbv_lernwelt.course.consts import COURSE_UK, COURSE_UK_FR +from vbv_lernwelt.course.consts import COURSE_UK from vbv_lernwelt.course.models import CoursePage from vbv_lernwelt.learnpath.models import LearningPath, LearningUnit @@ -160,3 +160,156 @@ def create_uk_training_competence_profile(course_id=COURSE_UK): slug=f"{slug_prefix}-circle-fahrzeug-lu-vorbereitung" ), ) + + +def create_uk_fr_training_competence_profile(course_id=COURSE_UK): + course_page = CoursePage.objects.get(course_id=course_id) + slug_prefix = course_page.get_children().exact_type(LearningPath).first().slug + + competence_profile_page = CompetenceProfilePageFactory( + title="KompetenzNavi", + parent=course_page, + ) + + competences = [ + { + "competence_id": "c3", + "title": "Betriebliche Prozesse dokumentieren, koordinieren und umsetzen", + "items": [], + }, + { + "competence_id": "e2", + "title": "Informationen im wirtschaftlichen und kaufmännischen Bereich recherchieren", + "items": [], + }, + { + "competence_id": "e4", + "title": "Betriebsbezogene Inhalte multimedial aufbereiten", + "items": [], + }, + { + "competence_id": "d2", + "title": "Informations- und Beratungsgespräche mit Kunden oder Lieferanten führen", + "items": [], + }, + { + "competence_id": "d3", + "title": "Betriebliche Prozesse dokumentieren, koordinieren und umsetzen", + "items": [], + }, + { + "competence_id": "d1", + "title": "Anliegen von Kunden oder Lieferanten entgegennehmen", + "items": [], + }, + ] + + for c in competences: + print(c["title"]) + CompetencePageFactory( + parent=competence_profile_page, + competence_id=c["competence_id"], + title=c["title"], + items=[("item", i) for i in c["items"]], + ) + # Circle Fahrzeug + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="c3" + ), + competence_id="c3.pv.ci2", + title="Je suis capable de d'expliquer les fondements légaux applicables dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="c3" + ), + competence_id="c3.pv.ci7", + title="Je suis capable de d'expliquer les dispositions légales en cas de sinistres et de versement de prestations dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="c3" + ), + competence_id="c3.pv.ci11", + title="Je suis capable de d'évaluer de manière compétente les solutions d’assurance courantes dans le domaine d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci1", + title="Je suis capable de décrire de manière complète les principales bases légales dans le domaine de l'assurance des véhicules à moteur.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci2", + title="Je suis capable de citer les prestations de service et les produits pertinents dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci3", + title="Je suis capable de d'expliquer les services et les produits dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="d2" + ), + competence_id="d2.pv.ci4", + title="Je suis capable de d'expliquer de manière compréhensible les processus et procédures dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + ), + competence_id="e4.pv.ci1", + title="Je suis capable de d'expliquer les services de l'entreprise dans le champ d'action des véhicules.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + ), + competence_id="e4.pv.ci2", + title="Je suis capable de de distinguer les concurrents dans le secteur des assurances privées dans le champ d'action des véhicules à l'aide des critères pertinents.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) + PerformanceCriteriaFactory( + parent=CompetencePage.objects.get( + slug__startswith=slug_prefix.replace("-lp", ""), competence_id="e4" + ), + competence_id="e4.pv.ci4", + title="Je suis capable de d'expliquer les principes sur lesquelles reposent les produits d'assurance automobile.", + learning_unit=LearningUnit.objects.get( + slug=f"{slug_prefix}-circle-véhicule-lu-vorbereitung" + ), + ) diff --git a/server/vbv_lernwelt/course/admin.py b/server/vbv_lernwelt/course/admin.py index ab5d2bbe..d168f3b6 100644 --- a/server/vbv_lernwelt/course/admin.py +++ b/server/vbv_lernwelt/course/admin.py @@ -48,6 +48,9 @@ class CourseSessionUserAdmin(admin.ModelAdmin): "course_session", "role", ] + raw_id_fields = [ + "user", + ] fieldsets = [ (None, {"fields": ("user", "course_session", "role")}), diff --git a/server/vbv_lernwelt/course/consts.py b/server/vbv_lernwelt/course/consts.py index 23fc2105..5960844d 100644 --- a/server/vbv_lernwelt/course/consts.py +++ b/server/vbv_lernwelt/course/consts.py @@ -4,3 +4,4 @@ COURSE_UK = -3 COURSE_VERSICHERUNGSVERMITTLERIN_ID = -4 COURSE_UK_FR = -5 COURSE_UK_TRAINING = -6 +COURSE_UK_TRAINING_FR = -7 diff --git a/server/vbv_lernwelt/course/creators/uk_circle_goals_fr.py b/server/vbv_lernwelt/course/creators/uk_circle_goals_fr.py new file mode 100644 index 00000000..d213ab2f --- /dev/null +++ b/server/vbv_lernwelt/course/creators/uk_circle_goals_fr.py @@ -0,0 +1,32 @@ +UK_FR_CIRCLE_GOALS = { + "fahrzeug": """ +Pour beaucoup, la voiture est la plus grande fierté. Mais elle recèle aussi un grand potentiel de +danger. Les prix actuels des véhicules et les frais de réparation peuvent rapidement atteindre des +sommes considérables que le propriétaire du véhicule a souvent du mal à assumer lui-même en cas +de sinistre important. L'assurance automobile a pour but de te protéger et de protéger financièrement +les autres usagers de la route en cas d'accident. Ce Cercle t'aide à y voir plus clair dans la jungle des +assurances véhicules à moteur et à prendre la route en toute sécurité!
+Dans ce cercle, tu développes tes compétences d'action pour ces thèmes:
+Tu travailles sur les objectifs évaluateurs suivants du profil de qualification:
+Je suis capable de...
+In der Mediathek unter «Allgemeines zu Versicherungen» findest du alle relevanten Ressourcen für deine Fachkompetenzen.
" + f"Wir empfehlen dir vor der Absolvierung der weiteren Lerneinheiten dich in die Thematik einzulesen.
" + ), + content_url=f"/course/überbetriebliche-kurse/media", + ) + LearningContentAssignmentFactory( + title="Versicherungswirtschaft", + assignment_type="PREP_ASSIGNMENT", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"überbetriebliche-kurse-assignment-kickoff-versicherungswirtschaft" + ), + ), + LearningSequenceFactory(title="Training", parent=circle) + LearningUnitFactory(title="Präsenzkurs", title_hidden=True, parent=circle) + LearningContentAttendanceCourseFactory( + title="Präsenzkurs Kickoff", + parent=circle, + ) + LearningContentDocumentListFactory( + title="Unterlagen für den Unterricht", + parent=circle, + documents=[ + ( + "document", + LearnMediaBlockFactory( + title="Präsentation 1a", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_KO_03b_A_Einteilungen.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Präsentation 1b", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_KO_03b_A_Einteilungen.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Arbeitsblatt Einteilung der Versicherungen", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_KO_03b_A_Einteilungen.pdf", + ), + ), + ], + ) + LearningUnitFactory(title="Feedback", title_hidden=True, parent=circle) + LearningContentFeedbackFactory( + parent=circle, + ) + LearningSequenceFactory(title="Transfer", parent=circle, icon="it-icon-ls-end") + LearningUnitFactory(title="Reflexion", title_hidden=True, parent=circle) + LearningContentAssignmentFactory( + title="Reflexion", + assignment_type="REFLECTION", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"überbetriebliche-kurse-assignment-reflexion" + ), + ), + + def create_uk_circle_basis(lp, title="Basis"): circle = CircleFactory( title=title, @@ -412,6 +501,114 @@ In diesem Circle lernst du die wichtigsten Grundlagen bezüglich Versicherungswi ), +def create_uk_fr_circle_basis(lp, title="Base"): + circle = CircleFactory( + title=title, + parent=lp, + description=""" +In diesem Circle lernst du die wichtigsten Grundlagen bezüglich Versicherungswirtschaft und Versicherungsrecht. + """.strip(), + goals=UK_CIRCLE_GOALS["basis"], + ) + LearningSequenceFactory( + title="Vorbereitung", parent=circle, icon="it-icon-ls-start" + ) + LearningUnitFactory(title="Vorbereitung", title_hidden=True, parent=circle) + LearningContentMediaLibraryFactory( + title=f"Allgemeines zu Versicherungen", + parent=circle, + description=RichText( + f"In der Mediathek unter «Allgemeines zu Versicherungen» findest du alle relevanten Ressourcen für deine Fachkompetenzen.
" + f"Wir empfehlen dir vor der Absolvierung der weiteren Lerneinheiten dich in die Thematik einzulesen.
" + ), + content_url=f"/course/überbetriebliche-kurse/media", + ) + LearningContentAssignmentFactory( + title="Vorbereitungsauftrag Circle Basis", + assignment_type="PREP_ASSIGNMENT", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"überbetriebliche-kurse-assignment-circle-basis" + ), + ), + LearningSequenceFactory(title="Training", parent=circle) + LearningUnitFactory(title="Präsenzkurs", title_hidden=True, parent=circle) + LearningContentAttendanceCourseFactory( + title="Präsenzkurs Basis", + parent=circle, + ) + LearningContentDocumentListFactory( + title="Unterlagen für den Unterricht", + parent=circle, + documents=[ + ( + "document", + LearnMediaBlockFactory( + title="Präsentation", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_BA_04_A_Risikomanagement.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Risikomanagement", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_BA_04_A_Risikomanagement.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Quizzes", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_BA_05_QR_Quizzes.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Versicherungsrecht", + description="Antragsannahme, Bindefrist und Widerrufsrecht – Kleine Fallstudie", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Dokument anzeigen", + url="/static/media/uk/de_üK1_BA_06_A_Versicherungsrecht.pdf", + ), + ), + ], + ) + LearningUnitFactory(title="Kompetenznachweis", title_hidden=True, parent=circle) + LearningContentTestFactory( + title="Wissens- und Verständnisfragen", + parent=circle, + description=RichText( + "Folgender Test mit Wissens- und Verständnisfragen ist Teil des Kompetenznachweises. Der Test kann nur einmal durchgeführt werden und ist notenrelevant.
" + ), + checkbox_text="Hiermit bestätige ich, dass ich die Anweisungen verstanden habe und den Test durchführen möchte.", + content_url="https://exam.vbv-afa.ch/", + ) + LearningUnitFactory(title="Feedback", title_hidden=True, parent=circle) + LearningContentFeedbackFactory( + parent=circle, + ) + LearningSequenceFactory(title="Transfer", parent=circle, icon="it-icon-ls-end") + LearningUnitFactory(title="Reflexion", parent=circle) + LearningContentAssignmentFactory( + title="Reflexion", + assignment_type="REFLECTION", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"überbetriebliche-kurse-assignment-reflexion" + ), + ), + + def create_uk_circle_fahrzeug(lp, title="Fahrzeug"): circle = CircleFactory( title=title, @@ -548,6 +745,142 @@ def create_uk_circle_fahrzeug(lp, title="Fahrzeug"): ), +def create_uk_fr_circle_fahrzeug(lp, title="Véhicule"): + circle = CircleFactory( + title=title, + parent=lp, + description="Dans ce cercle, tu apprends tout ce qui concerne les assurances véhicules à moteur.", + goals=UK_FR_CIRCLE_GOALS["fahrzeug"], + ) + course_slug = lp.slug.replace("-lp", "") + LearningSequenceFactory(title="Préparation", parent=circle, icon="it-icon-ls-start") + LearningUnitFactory(title="Vorbereitung", title_hidden=True, parent=circle) + LearningContentMediaLibraryFactory( + title=f"Champs d’action «Véhicule à moteur»", + parent=circle, + description=RichText( + f"Trouve toutes les ressources des champs d’action, comme les outils didactiques, les liens et autres informations utiles.
" + f"Nous te recommandons de te familiariser avec le sujet avant de suivre les autres unités de cours.
" + ), + content_url=f"/course/{course_slug}/media/category/{slugify(title)}", + ) + LearningContentAssignmentFactory( + title="Véhicule à moteur – Ma première voiture", + assignment_type="PREP_ASSIGNMENT", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"{course_slug}-assignment-véhicule-à-moteur-ma-première-voiture" + ), + ), + LearningSequenceFactory(title="Training", parent=circle) + LearningUnitFactory(title="Cours de présence", title_hidden=True, parent=circle) + LearningContentAttendanceCourseFactory( + title="Cours de présence Véhicule à moteur", + parent=circle, + ) + LearningContentDocumentListFactory( + title="Documentation pour la formation", + parent=circle, + documents=[ + ( + "document", + LearnMediaBlockFactory( + title="Présentation", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Afficher le document", + url="/static/media/uk/fr_üK1_FZ_00_Prгentation.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Notions", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Afficher le document", + url="/static/media/uk/fr_üK1_FZ_02_Begriffe.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Checklist", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Afficher le document", + url="/static/media/uk/fr_üK1_FZ_04_Checkliste.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Fiche de travail cas de sinistres", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Afficher le document", + url="/static/media/uk/fr_üK1_FZ_05_A_Schaden.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Aperçu casco", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Aperçu casco", + url="/static/media/uk/fr_üK1_FZ_07_Kasko.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Offre et entretien de vente", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Afficher le document", + url="/static/media/uk/fr_üK1_FZ_08_A_Offerte und Verkaufsgespräch.pdf", + ), + ), + ( + "document", + LearnMediaBlockFactory( + title="Fiche de travail cas de sinistres (réserve)", + description="", + icon_url="/static/icons/demo/icon-hf-book.png", + link_display_text="Afficher le document", + url="/static/media/uk/fr_üK1_FZ_A_Reserve_Schaden.pdf", + ), + ), + ], + ) + LearningUnitFactory(title="Feedback", title_hidden=True, parent=circle) + LearningContentFeedbackFactory( + parent=circle, + ) + + LearningSequenceFactory(title="Transfert", parent=circle, icon="it-icon-ls-end") + LearningUnitFactory( + title="Contrôle de compétences", title_hidden=True, parent=circle + ) + LearningContentAssignmentFactory( + title="Vérification d'une police d’assurance de véhicule à moteur", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"{course_slug}-assignment-vérification-d-une-police-d-assurance-de-véhicule-à-moteur" + ), + ), + LearningUnitFactory(title="Réflexion", title_hidden=True, parent=circle) + LearningContentAssignmentFactory( + title="Réflexion", + assignment_type="REFLECTION", + parent=circle, + content_assignment=Assignment.objects.get( + slug__startswith=f"{course_slug}-assignment-reflexion" + ), + ), + + UK_CIRCLE_GOALS = { "kickoff": """Hey, willkommen im ersten überbetrieblichen Kurs! Du bist in einer spannenden Branche gelandet. Wir wissen, dass es am Anfang oft eine Herausforderung sein kann, sich in einem neuen Umfeld zurechtzufinden und die vielen neuen Eindrücke zu verarbeiten. Aber keine Sorge, wir sind hier, um dir dabei zu helfen. In deiner Ausbildung wirst du viele neue Fähigkeiten erlernen und dein Wissen vertiefen. In diesem Circle helfen wir dir dabei, den Überblick zu gewinnen und dich mit den neuen Arbeitsabläufen und myVBV vertraut zu machen. Lass uns gemeinsam diese neue Herausforderung meistern und das Beste aus deiner Ausbildung herausholen!
diff --git a/server/vbv_lernwelt/course/creators/uk_training_course.py b/server/vbv_lernwelt/course/creators/uk_training_course.py index 87398c7c..89135f40 100644 --- a/server/vbv_lernwelt/course/creators/uk_training_course.py +++ b/server/vbv_lernwelt/course/creators/uk_training_course.py @@ -5,8 +5,11 @@ from wagtail.models import Locale, Page, Site from wagtail_localize.models import LocaleSynchronization from vbv_lernwelt.core.admin import User -from vbv_lernwelt.course.consts import COURSE_UK -from vbv_lernwelt.course.creators.uk_course import create_uk_circle_fahrzeug +from vbv_lernwelt.course.consts import COURSE_UK_TRAINING, COURSE_UK_TRAINING_FR +from vbv_lernwelt.course.creators.uk_course import ( + create_uk_circle_fahrzeug, + create_uk_fr_circle_fahrzeug, +) from vbv_lernwelt.course.models import CoursePage from vbv_lernwelt.learnpath.tests.learning_path_factories import ( LearningPathFactory, @@ -14,7 +17,9 @@ from vbv_lernwelt.learnpath.tests.learning_path_factories import ( ) -def create_uk_training_learning_path(course_id=COURSE_UK, user=None, skip_locales=True): +def create_uk_training_learning_path( + course_id=COURSE_UK_TRAINING, user=None, skip_locales=True +): if user is None: user = User.objects.get(username="info@iterativ.ch") @@ -33,8 +38,12 @@ def create_uk_training_learning_path(course_id=COURSE_UK, user=None, skip_locale parent=course_page, ) - TopicFactory(title="Training", is_visible=True, parent=lp) - create_uk_circle_fahrzeug(lp) + if course_id == COURSE_UK_TRAINING: + TopicFactory(title="Training", is_visible=True, parent=lp) + create_uk_circle_fahrzeug(lp) + elif course_id == COURSE_UK_TRAINING_FR: + TopicFactory(title="Training", is_visible=True, parent=lp) + create_uk_fr_circle_fahrzeug(lp) # locales if not skip_locales: 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 f503ad39..f6dfdce8 100644 --- a/server/vbv_lernwelt/course/management/commands/create_default_courses.py +++ b/server/vbv_lernwelt/course/management/commands/create_default_courses.py @@ -7,6 +7,9 @@ from vbv_lernwelt.assignment.creators.create_assignments import ( create_uk_basis_prep_assignment, create_uk_fahrzeug_casework, create_uk_fahrzeug_prep_assignment, + create_uk_fr_fahrzeug_casework, + create_uk_fr_fahrzeug_prep_assignment, + create_uk_fr_reflection, create_uk_kickoff_prep_assignment, create_uk_reflection, create_vv_einkommenssicherung_casework, @@ -22,6 +25,7 @@ from vbv_lernwelt.competence.create_uk_competence_profile import ( create_uk_fr_competence_profile, ) from vbv_lernwelt.competence.create_uk_training_competence_profile import ( + create_uk_fr_training_competence_profile, create_uk_training_competence_profile, ) from vbv_lernwelt.competence.create_vv_new_competence_profile import ( @@ -35,6 +39,7 @@ from vbv_lernwelt.course.consts import ( COURSE_UK, COURSE_UK_FR, COURSE_UK_TRAINING, + COURSE_UK_TRAINING_FR, COURSE_VERSICHERUNGSVERMITTLERIN_ID, ) from vbv_lernwelt.course.creators.test_course import create_test_course @@ -88,6 +93,7 @@ ADMIN_EMAILS = ["info@iterativ.ch", "admin"] COURSE_VERSICHERUNGSVERMITTLERIN_ID, COURSE_UK_FR, COURSE_UK_TRAINING, + COURSE_UK_TRAINING_FR, ], ) def command(course): @@ -118,6 +124,9 @@ def command(course): if COURSE_UK_TRAINING in course: create_course_training_de() + if COURSE_UK_TRAINING_FR in course: + create_course_training_fr() + def create_versicherungsvermittlerin_course(): # Versicherungsvermittler/in mit neuen Circles @@ -339,9 +348,17 @@ def create_course_uk_de(): def create_course_uk_fr(): # Überbetriebliche Kurse FR - create_versicherungsvermittlerin_with_categories( + course = create_versicherungsvermittlerin_with_categories( course_id=COURSE_UK_FR, title="Course hors établissement" ) + + # assignments create assignments parent page + _assignment_list_page = AssignmentListPageFactory( + parent=course.coursepage, + ) + create_uk_fr_fahrzeug_casework(course_id=COURSE_UK_FR) + create_uk_fr_fahrzeug_prep_assignment(course_id=COURSE_UK_FR) + create_uk_fr_reflection(course_id=COURSE_UK_FR) create_uk_fr_learning_path(course_id=COURSE_UK_FR) create_uk_fr_competence_profile(course_id=COURSE_UK_FR) create_default_media_library(course_id=COURSE_UK_FR) @@ -478,7 +495,6 @@ def create_course_training_de(): f"{current_dir}/../../../importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx", ) import_students_from_excel( - course, f"{current_dir}/../../../importer/tests/Schulungen_Teilnehmende.xlsx", ) @@ -529,3 +545,90 @@ def create_course_training_de(): ) csu.save() + + +def create_course_training_fr(): + # Test Lehrgang für üK Trainer FR + course = create_versicherungsvermittlerin_with_categories( + course_id=COURSE_UK_TRAINING_FR, title="myVBV Training (FR)" + ) + + # assignments create assignments parent page + _assignment_list_page = AssignmentListPageFactory( + parent=course.coursepage, + ) + create_uk_fr_fahrzeug_casework(course_id=COURSE_UK_TRAINING_FR) + create_uk_fr_fahrzeug_prep_assignment(course_id=COURSE_UK_TRAINING_FR) + create_uk_fr_reflection(course_id=COURSE_UK_TRAINING_FR) + + create_uk_training_learning_path(course_id=COURSE_UK_TRAINING_FR) + create_uk_fr_training_competence_profile(course_id=COURSE_UK_TRAINING_FR) + create_default_media_library(course_id=COURSE_UK_TRAINING_FR) + + current_dir = os.path.dirname(os.path.realpath(__file__)) + print(current_dir) + course = Course.objects.get(id=COURSE_UK_TRAINING_FR) + import_course_sessions_from_excel( + course, + f"{current_dir}/../../../importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx", + language="fr", + ) + import_trainers_from_excel( + course, + f"{current_dir}/../../../importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx", + language="fr", + ) + import_students_from_excel( + f"{current_dir}/../../../importer/tests/Schulungen_Teilnehmende.xlsx", + ) + + for cs in CourseSession.objects.filter(course_id=COURSE_UK_TRAINING_FR): + cs.assignment_details_list = [ + { + "learningContentId": LearningContentAssignment.objects.get( + slug=f"{course.slug}-lp-circle-véhicule-lc-vérification-dune-police-dassurance-de-véhicule-à-moteur" + ).id, + "submissionDeadlineDateTimeUtc": "2023-06-13T19:00:00Z", + "evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z", + }, + { + "learningContentId": LearningContentAssignment.objects.get( + slug=f"{course.slug}-lp-circle-véhicule-lc-véhicule-à-moteur-ma-première-voiture" + ).id, + "submissionDeadlineDateTimeUtc": "2023-06-13T19:00:00Z", + "evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z", + }, + ] + cs.save() + + # attach users as trainers to ÜK course + course_uk = Course.objects.filter(id=COURSE_UK_FR).first() + if course_uk: + users = [ + csu.user + for csu in CourseSessionUser.objects.filter( + course_session__course_id=COURSE_UK_TRAINING_FR + ) + ] + + cs = CourseSession.objects.get( + course_id=COURSE_UK_FR, + title="Cours hors établissement année 1 - Région Fribourg", + ) + + for user in users: + csu, _created = CourseSessionUser.objects.get_or_create( + course_session_id=cs.id, user_id=user.id + ) + csu.role = CourseSessionUser.Role.EXPERT + csu.expert.add( + Circle.objects.get(slug="überbetriebliche-kurse-lp-circle-kickoff") + ) + csu.expert.add( + Circle.objects.get(slug="überbetriebliche-kurse-lp-circle-basis") + ) + csu.expert.add( + Circle.objects.get(slug="überbetriebliche-kurse-lp-circle-fahrzeug") + ) + + csu.save() diff --git a/server/vbv_lernwelt/importer/services.py b/server/vbv_lernwelt/importer/services.py index f2b39779..7e53de5f 100644 --- a/server/vbv_lernwelt/importer/services.py +++ b/server/vbv_lernwelt/importer/services.py @@ -52,16 +52,20 @@ def create_or_update_user( return user -def import_course_sessions_from_excel(course: Course, filename: str): +def import_course_sessions_from_excel(course: Course, filename: str, language="de"): workbook = load_workbook(filename=filename) sheet = workbook["Schulungen Durchführung"] tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet) for row in tuple_list: - create_or_update_course_session(course, dict(row), circles=["Fahrzeug"]) + create_or_update_course_session( + course, dict(row), language=language, circles=["Fahrzeug"] + ) -def create_or_update_course_session(course: Course, data: Dict[str, Any], circles=None): +def create_or_update_course_session( + course: Course, data: Dict[str, Any], language="de", circles=None +): """ :param data: the following keys are required to process the data: Generation, Region, Klasse :return: @@ -86,6 +90,10 @@ def create_or_update_course_session(course: Course, data: Dict[str, Any], circle title = f"{region} {generation} {group}" + if not import_id.lower().startswith(language.lower()): + # FIXME: language check depends on import_id format for now... + return None + cs, _created = CourseSession.objects.get_or_create( import_id=import_id, group=group, course=course ) @@ -102,56 +110,80 @@ def create_or_update_course_session(course: Course, data: Dict[str, Any], circle 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": "", - } + if language == "de": + attendance_course_lp_qs = LearningContentAttendanceCourse.objects.filter( + slug=f"{course.slug}-lp-circle-{circle.lower()}-lc-präsenzkurs-{circle.lower()}" ) - cs.save() + 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() + elif language == "fr": + # todo: this is a hack remove me + print(f"{course.slug}-lp-circle-véhicule-lc-cours-de-présence-véhicule") + attendance_course_lp_qs = LearningContentAttendanceCourse.objects.filter( + slug=f"{course.slug}-lp-circle-véhicule-lc-cours-de-présence-véhicule-à-moteur" + ) + 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): +def import_trainers_from_excel(course: Course, filename: str, language="de"): workbook = load_workbook(filename=filename) sheet = workbook["Schulungen Trainer"] tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet) for row in tuple_list: - create_or_update_trainer(course, dict(row)) + create_or_update_trainer(course, dict(row), language=language) -def create_or_update_trainer(course: Course, data: Dict[str, Any]): +def create_or_update_trainer(course: Course, data: Dict[str, Any], language="de"): logger.debug( "create_or_update_trainer", - course=course.title, data=data, label="import", ) user = create_or_update_user( - email=data["Email"], + email=data["Email"].lower(), first_name=data["Vorname"], last_name=data["Name"], ) - # TODO: handle language - groups = [g.strip() for g in data["Klasse"].strip().split(",")] # general expert handling for group in groups: import_id = f"{data['Generation'].strip()} {group}" course_session = CourseSession.objects.filter( - import_id=import_id, group=group, course=course + import_id=import_id, + group=group, ).first() if course_session: csu, _created = CourseSessionUser.objects.get_or_create( @@ -159,19 +191,34 @@ def create_or_update_trainer(course: Course, data: Dict[str, Any]): ) csu.role = CourseSessionUser.Role.EXPERT csu.save() + else: + logger.warning( + "create_or_update_trainer: course_session not found", + import_id=import_id, + group=group, + label="import", + ) + + if not course: + return # 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(",")] + # FIXME: hardcoded translation + if language == "fr" and circle_name == "Fahrzeug": + circle_name = "Véhicule" + # print(circle_name, groups) for group in groups: import_id = f"{data['Generation'].strip()} {group}" course_session = CourseSession.objects.filter( - import_id=import_id, group=group, course=course + import_id=import_id, group=group ).first() circle = Circle.objects.filter( slug=f"{course.slug}-lp-circle-{circle_name.lower()}" @@ -186,25 +233,24 @@ def create_or_update_trainer(course: Course, data: Dict[str, Any]): csu.save() -def import_students_from_excel(course: Course, filename: str): +def import_students_from_excel(filename: str): workbook = load_workbook(filename=filename) sheet = workbook.active tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet) for row in tuple_list: - create_or_update_student(course, dict(row)) + create_or_update_student(dict(row)) -def create_or_update_student(course: Course, data: Dict[str, Any]): +def create_or_update_student(data: Dict[str, Any]): logger.debug( "create_or_update_student", - course=course.title, data=data, label="import", ) user = create_or_update_user( - email=data["Email"], + email=data["Email"].lower(), first_name=data["Vorname"], last_name=data["Name"], ) @@ -214,9 +260,7 @@ def create_or_update_student(course: Course, data: Dict[str, Any]): # general expert handling import_ids = [i.strip() for i in data["Durchführungen"].split(",")] for import_id in import_ids: - course_session = CourseSession.objects.filter( - import_id=import_id, course=course - ).first() + course_session = CourseSession.objects.filter(import_id=import_id).first() if course_session: csu, _created = CourseSessionUser.objects.get_or_create( course_session_id=course_session.id, user_id=user.id diff --git a/server/vbv_lernwelt/importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx b/server/vbv_lernwelt/importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx index 0989d20c..ff26f824 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/Schulungen_Teilnehmende.xlsx b/server/vbv_lernwelt/importer/tests/Schulungen_Teilnehmende.xlsx index d2d17245..84d84b57 100644 Binary files a/server/vbv_lernwelt/importer/tests/Schulungen_Teilnehmende.xlsx and b/server/vbv_lernwelt/importer/tests/Schulungen_Teilnehmende.xlsx differ diff --git a/server/vbv_lernwelt/importer/tests/test_import_course_sessions.py b/server/vbv_lernwelt/importer/tests/test_import_course_sessions.py index adf1c715..cb63de9f 100644 --- a/server/vbv_lernwelt/importer/tests/test_import_course_sessions.py +++ b/server/vbv_lernwelt/importer/tests/test_import_course_sessions.py @@ -25,10 +25,10 @@ class ImportCourseSessionTestCase(TestCase): for row in tuple_list: print(row) create_or_update_course_session( - self.course, dict(row), circles=["Fahrzeug"] + self.course, dict(row), language="de", circles=["Fahrzeug"] ) - self.assertEqual(CourseSession.objects.count(), 6) + self.assertEqual(CourseSession.objects.count(), 3) class CreateOrUpdateCourseSessionTestCase(TestCase): diff --git a/server/vbv_lernwelt/importer/tests/test_import_students.py b/server/vbv_lernwelt/importer/tests/test_import_students.py index 6e2186e2..98de80b2 100644 --- a/server/vbv_lernwelt/importer/tests/test_import_students.py +++ b/server/vbv_lernwelt/importer/tests/test_import_students.py @@ -29,7 +29,7 @@ class ImportStudentsTestCase(TestCase): tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet) for row in tuple_list: print(row) - create_or_update_student(self.course, dict(row)) + create_or_update_student(dict(row)) self.assertEqual(CourseSessionUser.objects.count(), 14) @@ -59,7 +59,7 @@ class CreateOrUpdateStudentTestCase(TestCase): (None, None), ] - create_or_update_student(self.course, dict(row)) + create_or_update_student(dict(row)) self.assertEqual( CourseSessionUser.objects.filter( diff --git a/server/vbv_lernwelt/sso/views.py b/server/vbv_lernwelt/sso/views.py index 98aa587e..957a1b8e 100644 --- a/server/vbv_lernwelt/sso/views.py +++ b/server/vbv_lernwelt/sso/views.py @@ -37,7 +37,7 @@ def authorize(request): user_data = _user_data_from_token_data(decoded_token) user = create_or_update_user( - email=user_data.get("email"), + email=user_data.get("email").lower(), sso_id=user_data.get("sso_id"), first_name=user_data.get("first_name", ""), last_name=user_data.get("last_name", ""), diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_00_Prгentation.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_00_Prгentation.pdf new file mode 100644 index 00000000..89df5cfb Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_00_Prгentation.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_01_VOR.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_01_VOR.pdf new file mode 100644 index 00000000..656b54bd Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_01_VOR.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_02_Begriffe.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_02_Begriffe.pdf new file mode 100644 index 00000000..c216e082 Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_02_Begriffe.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_03_A_VOR.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_03_A_VOR.pdf new file mode 100644 index 00000000..f39a1aee Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_03_A_VOR.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_04_Checkliste.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_04_Checkliste.pdf new file mode 100644 index 00000000..5e812122 Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_04_Checkliste.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_05_A_Schaden.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_05_A_Schaden.pdf new file mode 100644 index 00000000..f5eb9615 Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_05_A_Schaden.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_07_Kasko.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_07_Kasko.pdf new file mode 100644 index 00000000..403b4ce7 Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_07_Kasko.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_08_A_Offerte und Verkaufsgespr⏀h.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_08_A_Offerte und Verkaufsgespr⏀h.pdf new file mode 100644 index 00000000..7d9306af Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_08_A_Offerte und Verkaufsgespr⏀h.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_09_NACH_KN.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_09_NACH_KN.pdf new file mode 100644 index 00000000..0fe06a52 Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_09_NACH_KN.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_09_NACH_KN_Beurteilungsraster.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_09_NACH_KN_Beurteilungsraster.pdf new file mode 100644 index 00000000..4b86cc6b Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_09_NACH_KN_Beurteilungsraster.pdf differ diff --git a/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_A_Reserve_Schaden.pdf b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_A_Reserve_Schaden.pdf new file mode 100644 index 00000000..9e2ab6e2 Binary files /dev/null and b/server/vbv_lernwelt/static/media/uk/fr_üK1_FZ_A_Reserve_Schaden.pdf differ