diff --git a/server/vbv_lernwelt/core/management/commands/reset_schema.py b/server/vbv_lernwelt/core/management/commands/reset_schema.py index 4d9c153a..a5d5603c 100644 --- a/server/vbv_lernwelt/core/management/commands/reset_schema.py +++ b/server/vbv_lernwelt/core/management/commands/reset_schema.py @@ -29,3 +29,4 @@ def command(): call_command("migrate") call_command("create_default_users") call_command("create_default_courses") + call_command("create_default_events") diff --git a/server/vbv_lernwelt/course/models.py b/server/vbv_lernwelt/course/models.py index 2a49e8d9..2394009d 100644 --- a/server/vbv_lernwelt/course/models.py +++ b/server/vbv_lernwelt/course/models.py @@ -193,6 +193,8 @@ class CourseSession(models.Model): Das anhängen kann via CourseSessionUser oder "Schulklasse (TODO)" geschehen """ + # TODO: Das wird durch event modell ersetzt + ATTENDANCE_COURSES_SCHEMA = { "type": "array", "items": { diff --git a/server/vbv_lernwelt/events/admin.py b/server/vbv_lernwelt/events/admin.py index 8c38f3f3..056c7148 100644 --- a/server/vbv_lernwelt/events/admin.py +++ b/server/vbv_lernwelt/events/admin.py @@ -1,3 +1,17 @@ from django.contrib import admin +from vbv_lernwelt.events.models import Event + + # Register your models here. +@admin.register(Event) +class EventAdmin(admin.ModelAdmin): + date_hierarchy = "end" + list_display = [ + "title", + "course_session", + "start", + "end", + "unset" + ] + list_filter = ["course_session"] diff --git a/server/vbv_lernwelt/events/factories.py b/server/vbv_lernwelt/events/factories.py index c6bfa7c6..e7248354 100644 --- a/server/vbv_lernwelt/events/factories.py +++ b/server/vbv_lernwelt/events/factories.py @@ -1,13 +1,19 @@ -from datetime import datetime +import datetime +import structlog from django.utils import timezone from factory.django import DjangoModelFactory from .models import Event +from ..assignment.models import Assignment +from ..course.models import CourseSession +from ..learnpath.models import LearningContentAttendanceCourse + +logger = structlog.get_logger(__name__) def get_date(date_string): - return datetime.strptime(date_string, '%b %d %Y', ).astimezone(timezone.get_current_timezone()) + return datetime.datetime.strptime(date_string, '%b %d %Y', ).astimezone(timezone.get_current_timezone()) class EventFactory(DjangoModelFactory): @@ -16,3 +22,48 @@ class EventFactory(DjangoModelFactory): title = "Prüfung Versicherungsvermittler/-in" end = get_date("Jan 01 2021") + + +def generate_events(start=timezone.now()): + for i in range(20): + EventFactory(title=f"{i}", start=start + datetime.timedelta(days=i), + end=start + datetime.timedelta(days=i, hours=1)) + + +def hour_rounder(t): + # Rounds to nearest hour by adding a timedelta hour if minute >= 30 + return (t.replace(second=0, microsecond=0, minute=0, hour=t.hour) + + datetime.timedelta(hours=t.minute // 30)) + + +def create_events_for_all_course_sessions(): + all_course_sessions: list[CourseSession] = CourseSession.objects.all() + + for course_session in all_course_sessions: + create_events_for_course_session(course_session) + + +def create_events_for_course_session(course_session: CourseSession): + course = course_session.course + attendance_courses = list(LearningContentAttendanceCourse.objects.descendant_of(course.get_learning_path())) + assignments = list(Assignment.objects.descendant_of(course.get_learning_path())) + contents = attendance_courses + assignments + + for content in contents: + if callable(getattr(content, 'get_frontend_url', None)): + url = content.get_frontend_url() + + event, created = Event.objects.get_or_create(course_session=course_session, title=content.title, url=url) + if created: + logger.info(f"Created event {event} for course session {course_session} and content {content}") + + +# + +def set_default_times_for_events(): + now = hour_rounder(timezone.now()) + + for i, event in enumerate(Event.objects.filter(end__isnull=True)): + event.start = now + datetime.timedelta(days=i) + event.end = event.start + datetime.timedelta(hours=3) + event.save() diff --git a/server/vbv_lernwelt/events/management/__init__.py b/server/vbv_lernwelt/events/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/events/management/commands/__init__.py b/server/vbv_lernwelt/events/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/events/management/commands/create_default_events.py b/server/vbv_lernwelt/events/management/commands/create_default_events.py new file mode 100644 index 00000000..57461dfa --- /dev/null +++ b/server/vbv_lernwelt/events/management/commands/create_default_events.py @@ -0,0 +1,9 @@ +import djclick as click + +from vbv_lernwelt.events.factories import create_events_for_all_course_sessions, set_default_times_for_events + + +@click.command() +def command(): + create_events_for_all_course_sessions() + set_default_times_for_events() diff --git a/server/vbv_lernwelt/events/models.py b/server/vbv_lernwelt/events/models.py index e93284c3..a2382f86 100644 --- a/server/vbv_lernwelt/events/models.py +++ b/server/vbv_lernwelt/events/models.py @@ -10,8 +10,9 @@ from vbv_lernwelt.course.models import CourseSession class Event(models.Model): start = models.DateTimeField(null=True, db_index=True) - end = models.DateTimeField(db_index=True) - title = models.CharField(default=_('Termin'), max_length=255) + end = models.DateTimeField(db_index=True, null=True) + title = models.CharField(default=_('Termin'), max_length=1024) + url = models.URLField(null=True, blank=True, max_length=1024) course_session = models.ForeignKey( 'course.CourseSession', on_delete=models.CASCADE, @@ -20,20 +21,18 @@ class Event(models.Model): blank=True, ) - learning_content = models.ForeignKey( - 'learnpath.LearningContentAttendanceCourse', - on_delete=models.CASCADE, - related_name='events', - null=True, - blank=True, - ) + learning_content_id = models.CharField(blank=True, null=True, max_length=255) def Meta(self): ordering = ['start', 'end'] verbose_name = _("Termin") def __str__(self): - return f"{self.title} {self.start}" + return f"Event: {self.title} {self.start} to {self.end}" + + @property + def unset(self): + return self.end is None @property def duration(self): @@ -55,7 +54,7 @@ class Event(models.Model): qs = qs.filter(course_session=course_session, course_session__course_assignment__user=user) else: qs = qs.filter(course_session__course_assignment__user=user) - + qs = qs.order_by('start')[:limit] return qs diff --git a/server/vbv_lernwelt/learnpath/models.py b/server/vbv_lernwelt/learnpath/models.py index 5f412e0c..ccc8d53f 100644 --- a/server/vbv_lernwelt/learnpath/models.py +++ b/server/vbv_lernwelt/learnpath/models.py @@ -279,6 +279,9 @@ class LearningContent(CourseBasePage): class LearningContentAttendanceCourse(LearningContent): + """ + Präsenzkurs + """ parent_page_types = ["learnpath.Circle"] subpage_types = []