Add CourseSessionAttendance course and CourseSessionAssignment
This commit is contained in:
parent
a5acc66981
commit
2706d6785d
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -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)
|
||||
|
|
@ -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":
|
||||
|
|
|
|||
Loading…
Reference in New Issue