Add CourseSessionAttendance course and CourseSessionAssignment

This commit is contained in:
Lorenz Padberg 2023-06-26 17:44:31 +02:00
parent a5acc66981
commit 2706d6785d
7 changed files with 288 additions and 52 deletions

View File

@ -1,7 +1,9 @@
import json
from datetime import datetime
import wagtail_factories
from django.conf import settings
from django.utils import timezone
from slugify import slugify
from wagtail.models import Site
from wagtail.rich_text import RichText
@ -34,7 +36,8 @@ from vbv_lernwelt.course.models import (
CourseSession,
CourseSessionUser,
)
from vbv_lernwelt.learnpath.models import Circle
from vbv_lernwelt.course_session.models import CourseSessionAssignment, CourseSessionAttendanceCourse
from vbv_lernwelt.learnpath.models import Circle, LearningContentAssignment, LearningContentAttendanceCourse
from vbv_lernwelt.learnpath.tests.learning_path_factories import (
CircleFactory,
LearningContentAssignmentFactory,
@ -79,16 +82,20 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
create_test_media_library()
if with_sessions:
now = timezone.now()
# course sessions
cs_bern = CourseSession.objects.create(
course_id=COURSE_TEST_ID,
title="Test Bern 2022 a",
id=TEST_COURSE_SESSION_BERN_ID,
start_date=now,
)
cs_zurich = CourseSession.objects.create(
course_id=COURSE_TEST_ID,
title="Test Zürich 2022 a",
id=TEST_COURSE_SESSION_ZURICH_ID,
start_date=now,
)
trainer1 = User.objects.get(email="test-trainer1@example.com")
@ -115,6 +122,12 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
course_session=cs_zurich,
user=student2,
)
for cs in CourseSession.objects.all():
for assignment in LearningContentAssignment.objects.all():
create_course_session_assignment(cs, assignment)
for attendance_course in LearningContentAttendanceCourse.objects.all():
create_course_session_attendance_course(cs, attendance_course)
return course
@ -143,6 +156,28 @@ def create_test_assignment_submitted_data(assignment, course_session, user):
)
def create_course_session_assignment(course_session, assignment):
csa, created = CourseSessionAssignment.objects.get_or_create(
course_session=course_session,
learning_content=assignment,
)
return csa
def create_course_session_attendance_course(course_session, course):
casc = CourseSessionAttendanceCourse.objects.create(
course_session=course_session,
learning_content=course,
location="Handelsschule KV Bern, Zimmer 123, Eigerstrasse 16, 3012 Bern",
trainer="Roland Grossenbacher, roland.grossenbacher@helvetia.ch",
)
casc.due_date.start = timezone.make_aware(datetime(2023, 6, 14, 8, 30))
casc.due_date.end = timezone.make_aware(datetime(2023, 6, 14, 17, 0))
casc.due_date.save()
return casc
def create_test_course_with_categories(apps=None, schema_editor=None):
if apps is not None:
Course = apps.get_model("course", "Course")

View File

@ -1,6 +1,6 @@
import os
import random
from datetime import datetime
from datetime import datetime, timedelta
import djclick as click
from django.utils import timezone
@ -70,7 +70,7 @@ from vbv_lernwelt.course.models import (
CourseSessionUser,
)
from vbv_lernwelt.course.services import mark_course_completion
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse, CourseSessionAssignment
from vbv_lernwelt.duedate.models import DueDate
from vbv_lernwelt.feedback.creators.create_demo_feedback import create_feedback
from vbv_lernwelt.importer.services import (
@ -84,9 +84,9 @@ from vbv_lernwelt.learnpath.create_vv_new_learning_path import (
from vbv_lernwelt.learnpath.models import (
Circle,
LearningContent,
LearningContentAssignment,
LearningContentAttendanceCourse,
)
from vbv_lernwelt.learnpath.models import LearningContentAssignment
from vbv_lernwelt.media_library.create_default_media_library import (
create_default_media_library,
)
@ -252,22 +252,22 @@ def create_course_uk_de():
# "trainer": "Roland Grossenbacher, roland.grossenbacher@helvetia.ch",
# }
# ],
assignment_details_list=[
{
"learningContentId": LearningContentAssignment.objects.get(
slug="überbetriebliche-kurse-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"
).id,
"submissionDeadlineDateTimeUtc": "2023-06-13T19:00:00Z",
"evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
},
{
"learningContentId": LearningContentAssignment.objects.get(
slug="überbetriebliche-kurse-lp-circle-fahrzeug-lc-fahrzeug-mein-erstes-auto"
).id,
"submissionDeadlineDateTimeUtc": "2023-06-13T19:00:00Z",
"evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
},
],
# assignment_details_list=[
# {
# "learningContentId": LearningContentAssignment.objects.get(
# slug="überbetriebliche-kurse-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"
# ).id,
# "submissionDeadlineDateTimeUtc": "2023-06-13T19:00:00Z",
# "evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
# },
# {
# "learningContentId": LearningContentAssignment.objects.get(
# slug="überbetriebliche-kurse-lp-circle-fahrzeug-lc-fahrzeug-mein-erstes-auto"
# ).id,
# "submissionDeadlineDateTimeUtc": "2023-06-13T19:00:00Z",
# "evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
# },
# ],
)
csac = CourseSessionAttendanceCourse.objects.create(
@ -559,8 +559,25 @@ def create_course_training_de():
)
for cs in CourseSession.objects.filter(course_id=COURSE_UK_TRAINING):
csa = CourseSessionAssignment.objects.create(
course_session=cs,
learning_content=LearningContentAssignment.objects.get(
slug=f"{course.slug}-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"
),
)
print(csa)
submission_deadline = csa.submission_deadline
submission_deadline.end = cs.start_date + timedelta(days=14)
submission_deadline.save()
evaluation_deadline = csa.evaluation_deadline
evaluation_deadline.end = cs.start_date + timedelta(days=28)
evaluation_deadline.save()
cs.assignment_details_list = [
{
"learningContentId": LearningContentAssignment.objects.get(
slug=f"{course.slug}-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"
).id,
@ -643,22 +660,22 @@ def create_course_training_fr():
)
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.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
@ -730,22 +747,22 @@ def create_course_training_it():
)
for cs in CourseSession.objects.filter(course_id=COURSE_UK_TRAINING_IT):
cs.assignment_details_list = [
{
"learningContentId": LearningContentAssignment.objects.get(
slug=f"{course.slug}-lp-circle-veicolo-lc-verifica-di-una-polizza-di-assicurazione-veicoli-a-motore"
).id,
"submissionDeadlineDateTimeUtc": "2023-06-20T19:00:00Z",
"evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
},
{
"learningContentId": LearningContentAssignment.objects.get(
slug=f"{course.slug}-lp-circle-veicolo-lc-veicolo-la-mia-prima-auto"
).id,
"submissionDeadlineDateTimeUtc": "2023-06-20T19:00:00Z",
"evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
},
]
# cs.assignment_details_list = [
# {
# "learningContentId": LearningContentAssignment.objects.get(
# slug=f"{course.slug}-lp-circle-veicolo-lc-verifica-di-una-polizza-di-assicurazione-veicoli-a-motore"
# ).id,
# "submissionDeadlineDateTimeUtc": "2023-06-20T19:00:00Z",
# "evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
# },
# {
# "learningContentId": LearningContentAssignment.objects.get(
# slug=f"{course.slug}-lp-circle-veicolo-lc-veicolo-la-mia-prima-auto"
# ).id,
# "submissionDeadlineDateTimeUtc": "2023-06-20T19:00:00Z",
# "evaluationDeadlineDateTimeUtc": "2023-06-27T19:00:00Z",
# },
# ]
cs.save()
# attach users as trainers to ÜK course

View File

@ -0,0 +1,26 @@
from django.contrib import admin
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse, CourseSessionAssignment
@admin.register(CourseSessionAttendanceCourse)
class CourseSessionAttendanceCourseAdmin(admin.ModelAdmin):
# Inline fields are not possible for the DueDate model, because it is not a ForeignKey relatoion.
readonly_fields = ['course_session', 'learning_content', 'due_date']
list_display = [
"course_session",
"learning_content",
"trainer",
]
list_filter = ["course_session__course"]
@admin.register(CourseSessionAssignment)
class CourseSessionAssignmentAdmin(admin.ModelAdmin):
# Inline fields are not possible for the DueDate model, because it is not a ForeignKey relatoion.
readonly_fields = ['course_session', 'learning_content']
list_display = [
"course_session",
"learning_content",
]
list_filter = ["course_session__course"]

View File

@ -1,7 +1,15 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from vbv_lernwelt.duedate.models import DueDate
class CourseSessionAttendanceCourse(models.Model):
"""
Präsenzkurs Durchührung
Kann über einen Zeitraum von meheren Tagen gehen.
"""
course_session = models.ForeignKey(
"course.CourseSession",
on_delete=models.CASCADE,
@ -19,5 +27,68 @@ class CourseSessionAttendanceCourse(models.Model):
location = models.CharField(max_length=255, blank=True, default="")
trainer = models.CharField(max_length=255, blank=True, default="")
def save(self, *args, **kwargs):
if not self.pk:
title = ""
page = None
if self.learning_content_id:
title = self.learning_content.title
page = self.learning_content.page_ptr
self.due_date = DueDate.objects.create(
title=f"{title} {_('Präsenzkurs')}",
course_session=self.course_session,
page=page)
super().save(*args, **kwargs)
def __str__(self):
return f"{self.course_session} - {self.learning_content}"
class CourseSessionAssignment(models.Model):
"""
Auftrag
- Geletitete Fallarbeit ist eine speziefische ausprägung eines Auftrags (assignment_type)
"""
course_session = models.ForeignKey(
"course.CourseSession",
on_delete=models.CASCADE,
)
learning_content = models.ForeignKey(
"learnpath.LearningContentAssignment",
on_delete=models.CASCADE,
)
submission_deadline = models.OneToOneField(
"duedate.DueDate",
on_delete=models.CASCADE,
related_name="assignment_submission_deadline",
)
evaluation_deadline = models.OneToOneField(
"duedate.DueDate",
on_delete=models.CASCADE,
related_name="assignment_evaluation_deadline",
)
def save(self, *args, **kwargs):
if not self.pk:
title = ""
page = None
if self.learning_content_id:
title = self.learning_content.title
page = self.learning_content.page_ptr
self.submission_deadline = DueDate.objects.create(
title=f"{title} {_('Submission Deadline')}",
course_session=self.course_session,
page=page)
self.evaluation_deadline = DueDate.objects.create(
title=f"{title} {_('Evaluation Deadline')}",
course_session=self.course_session,
page=page)
super().save(*args, **kwargs)
def __str__(self):
return f"{self.course_session} - {self.learning_content}"

View File

@ -0,0 +1,47 @@
from datetime import timedelta
from django.test import TestCase
from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.consts import COURSE_TEST_ID
from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.course_session.models import CourseSessionAssignment
from vbv_lernwelt.learnpath.models import Circle
class CourseSessionModelsTestCase(TestCase):
def setUp(self) -> None:
create_default_users()
create_test_course()
self.user = User.objects.get(username="student")
self.expert = User.objects.get(
username="patrizia.huggel@eiger-versicherungen.ch"
)
self.course_session = CourseSession.objects.create(
course_id=COURSE_TEST_ID,
title="Test Lehrgang Session",
)
csu = CourseSessionUser.objects.create(
course_session=self.course_session,
user=User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch"),
role=CourseSessionUser.Role.EXPERT,
)
csu.expert.add(Circle.objects.get(slug="test-lehrgang-lp-circle-fahrzeug"))
def test_course_session_assignment(self):
csa = CourseSessionAssignment.objects.create(
course_session=self.course_session,
# cs learning_content=LearningContentAssignment.objects.get(
# slug=f"{course.slug}-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"
# ),
)
print(csa)
submission_deadline = csa.submission_deadline
submission_deadline.end = self.course_session.start_date + timedelta(days=14)
submission_deadline.save()

View File

@ -0,0 +1,39 @@
from datetime import datetime
from django.test import TestCase
from django.utils import timezone
from vbv_lernwelt.core.create_default_users import create_default_users
from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course_session.models import CourseSessionAssignment, CourseSessionAttendanceCourse
from vbv_lernwelt.duedate.models import DueDate
class CourseSessionModelsTestCase(TestCase):
def setUp(self) -> None:
create_default_users()
create_test_course(with_sessions=True)
def test_course_session_assignment(self):
csa = CourseSessionAssignment.objects.all().first()
submission_deadline = csa.submission_deadline
deadline_date = datetime(2023, 7, 6, 8, 30, tzinfo=timezone.get_current_timezone())
submission_deadline.end = deadline_date
submission_deadline.save()
this_date = DueDate.objects.get(pk=submission_deadline.pk)
self.assertEqual(this_date.end, deadline_date)
def test_course_session_attendance_course(self):
csac = CourseSessionAttendanceCourse.objects.all().first()
due_date = csac.due_date
deadline_date = datetime(2023, 7, 6, 8, 30, tzinfo=timezone.get_current_timezone())
due_date.end = deadline_date
due_date.save()
this_date = DueDate.objects.get(pk=due_date.pk)
self.assertEqual(this_date.end, deadline_date)

View File

@ -14,6 +14,7 @@ class DueDateAdmin(admin.ModelAdmin):
date_hierarchy = "end"
list_display = ["title", "course_session", "start", "end", "unset"]
list_filter = ["course_session"]
readonly_fields = ["course_session", "page"]
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "page":