Refactoring
This commit is contained in:
parent
7ccc771ca7
commit
89ff4af3c8
|
|
@ -14,6 +14,4 @@ import { defineProps } from "vue";
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
dueDate: DueDate;
|
dueDate: DueDate;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
console.log(props.dueDate);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
console.log(props.maxCount);
|
|
||||||
|
|
||||||
const dueDates = courseSession.value.duedates.slice(0, props.maxCount);
|
const dueDates = courseSession.value.duedates.slice(0, props.maxCount);
|
||||||
console.log(courseSession.value.duedates);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
export const dueDatesTestData = () => {
|
export const dueDatesTestData = () => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
start: "2023-06-14T15:00:00+02:00",
|
start: dayjs("2023-06-14T15:00:00+02:00"),
|
||||||
end: "2023-06-14T18:00:00+02:00",
|
end: dayjs("2023-06-14T18:00:00+02:00"),
|
||||||
title: "Präsenzkurs Kickoff",
|
title: "Präsenzkurs Kickoff",
|
||||||
url: "/course/überbetriebliche-kurse/learn/kickoff/präsenzkurs-kickoff",
|
url: "/course/überbetriebliche-kurse/learn/kickoff/präsenzkurs-kickoff",
|
||||||
course_session: 2,
|
course_session: 2,
|
||||||
|
|
@ -11,8 +13,8 @@ export const dueDatesTestData = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
start: "2023-06-15T15:00:00+02:00",
|
start: dayjs("2023-06-15T15:00:00+02:00"),
|
||||||
end: "2023-06-15T18:00:00+02:00",
|
end: dayjs("2023-06-15T18:00:00+02:00"),
|
||||||
title: "Präsenzkurs Basis",
|
title: "Präsenzkurs Basis",
|
||||||
url: "/course/überbetriebliche-kurse/learn/basis/präsenzkurs-basis",
|
url: "/course/überbetriebliche-kurse/learn/basis/präsenzkurs-basis",
|
||||||
course_session: 2,
|
course_session: 2,
|
||||||
|
|
@ -20,8 +22,8 @@ export const dueDatesTestData = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
start: "2023-06-16T15:00:00+02:00",
|
start: dayjs("2023-06-16T15:00:00+02:00"),
|
||||||
end: "2023-06-16T18:00:00+02:00",
|
end: dayjs("2023-06-16T18:00:00+02:00"),
|
||||||
title: "Präsenzkurs Fahrzeug",
|
title: "Präsenzkurs Fahrzeug",
|
||||||
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
||||||
course_session: 2,
|
course_session: 2,
|
||||||
|
|
@ -29,8 +31,8 @@ export const dueDatesTestData = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
start: "2023-06-16T15:00:00+02:00",
|
start: dayjs("2023-06-16T15:00:00+02:00"),
|
||||||
end: "2023-06-16T18:00:00+02:00",
|
end: dayjs("2023-06-16T18:00:00+02:00"),
|
||||||
title: "Präsenzkurs Flugzeuge",
|
title: "Präsenzkurs Flugzeuge",
|
||||||
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
||||||
course_session: 2,
|
course_session: 2,
|
||||||
|
|
@ -38,8 +40,8 @@ export const dueDatesTestData = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 5,
|
||||||
start: "2023-07-16T11:00:00+02:00",
|
start: dayjs("2023-07-16T11:00:00+02:00"),
|
||||||
end: "2023-07-16T18:00:00+02:00",
|
end: dayjs("2023-07-16T18:00:00+02:00"),
|
||||||
title: "Präsenzkurs Motorräder",
|
title: "Präsenzkurs Motorräder",
|
||||||
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
||||||
course_session: 2,
|
course_session: 2,
|
||||||
|
|
@ -47,8 +49,8 @@ export const dueDatesTestData = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 6,
|
||||||
start: "2023-08-09T15:00:00+02:00",
|
start: dayjs("2023-08-09T15:00:00+02:00"),
|
||||||
end: "2023-08-09T19:00:00+02:00",
|
end: dayjs("2023-08-09T19:00:00+02:00"),
|
||||||
title: "Präsenzkurs Fahrräder",
|
title: "Präsenzkurs Fahrräder",
|
||||||
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
url: "/course/überbetriebliche-kurse/learn/fahrzeug/präsenzkurs-fahrzeug",
|
||||||
course_session: 2,
|
course_session: 2,
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
export const formatDate = (start_str: string, end_str: string) => {
|
import type { Dayjs } from "dayjs";
|
||||||
const start = new Date(start_str);
|
|
||||||
const end = new Date(end_str);
|
|
||||||
|
|
||||||
|
export const formatDate = (start: Dayjs, end: Dayjs) => {
|
||||||
const startDateString = getDateString(start);
|
const startDateString = getDateString(start);
|
||||||
const endDateString = getDateString(end);
|
const endDateString = getDateString(end);
|
||||||
|
|
||||||
|
|
@ -14,14 +13,10 @@ export const formatDate = (start_str: string, end_str: string) => {
|
||||||
)}`;
|
)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTimeString = (date: Date) => {
|
const getTimeString = (date: Dayjs) => {
|
||||||
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
return `${date.format("HH:mm")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDateString = (date: Date) => {
|
const getDateString = (date: Dayjs) => {
|
||||||
return date.toLocaleDateString([], {
|
return `${date.format("DD MMM YYYY")}`;
|
||||||
day: "numeric",
|
|
||||||
month: "short",
|
|
||||||
year: "numeric",
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import * as log from "loglevel";
|
|
||||||
import { computed, onMounted } from "vue";
|
import { computed, onMounted } from "vue";
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
@ -17,7 +16,6 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
log.debug("LearningPathCircle mounted");
|
|
||||||
render();
|
render();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import type {
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
import eventBus from "@/utils/eventBus";
|
import eventBus from "@/utils/eventBus";
|
||||||
import { useLocalStorage } from "@vueuse/core";
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
|
import dayjs from "dayjs";
|
||||||
import uniqBy from "lodash/uniqBy";
|
import uniqBy from "lodash/uniqBy";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
@ -25,7 +26,6 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
|
|
||||||
async function loadCourseSessionsData(reload = false) {
|
async function loadCourseSessionsData(reload = false) {
|
||||||
log.debug("loadCourseSessionsData called");
|
log.debug("loadCourseSessionsData called");
|
||||||
|
|
||||||
allCourseSessions.value = await itGetCached(`/api/course/sessions/`, {
|
allCourseSessions.value = await itGetCached(`/api/course/sessions/`, {
|
||||||
reload: reload,
|
reload: reload,
|
||||||
});
|
});
|
||||||
|
|
@ -39,6 +39,11 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
reload: reload,
|
reload: reload,
|
||||||
})) as CourseSessionUser[];
|
})) as CourseSessionUser[];
|
||||||
cs.users = users;
|
cs.users = users;
|
||||||
|
cs.duedates.forEach((dueDate) => {
|
||||||
|
dueDate.start = dayjs(dueDate.start);
|
||||||
|
dueDate.end = dayjs(dueDate.end);
|
||||||
|
console.log(dueDate);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import type { AssignmentCompletionStatus as AssignmentCompletionStatusGenerated } from "@/gql/graphql";
|
import type { AssignmentCompletionStatus as AssignmentCompletionStatusGenerated } from "@/gql/graphql";
|
||||||
import type { Circle } from "@/services/circle";
|
import type { Circle } from "@/services/circle";
|
||||||
|
import { Dayjs } from "dayjs";
|
||||||
import type { Component } from "vue";
|
import type { Component } from "vue";
|
||||||
|
|
||||||
export type LoginMethod = "local" | "sso";
|
export type LoginMethod = "local" | "sso";
|
||||||
|
|
@ -560,8 +561,8 @@ export interface UserAssignmentCompletionStatus {
|
||||||
|
|
||||||
export type DueDate = {
|
export type DueDate = {
|
||||||
id: number;
|
id: number;
|
||||||
start: string;
|
start: Dayjs;
|
||||||
end: string;
|
end: Dayjs;
|
||||||
title: string;
|
title: string;
|
||||||
url: string;
|
url: string;
|
||||||
course_session: number | null;
|
course_session: number | null;
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
"media_library_url",
|
"media_library_url",
|
||||||
"course_url",
|
"course_url",
|
||||||
"documents",
|
"documents",
|
||||||
"duedates"
|
"duedates",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,7 @@ from vbv_lernwelt.learnpath.models import (
|
||||||
@admin.register(DueDate)
|
@admin.register(DueDate)
|
||||||
class DueDateAdmin(admin.ModelAdmin):
|
class DueDateAdmin(admin.ModelAdmin):
|
||||||
date_hierarchy = "end"
|
date_hierarchy = "end"
|
||||||
list_display = [
|
list_display = ["title", "course_session", "start", "end", "unset"]
|
||||||
"title",
|
|
||||||
"course_session",
|
|
||||||
"start",
|
|
||||||
"end",
|
|
||||||
"unset"
|
|
||||||
]
|
|
||||||
list_filter = ["course_session"]
|
list_filter = ["course_session"]
|
||||||
|
|
||||||
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,20 @@ import structlog
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from factory.django import DjangoModelFactory
|
from factory.django import DjangoModelFactory
|
||||||
|
|
||||||
from .models import DueDate
|
|
||||||
from ..assignment.models import Assignment
|
from ..assignment.models import Assignment
|
||||||
from ..course.models import CourseSession
|
from ..course.models import CourseSession
|
||||||
from ..learnpath.models import LearningContentAttendanceCourse
|
from ..learnpath.models import LearningContentAttendanceCourse
|
||||||
|
|
||||||
|
from .models import DueDate
|
||||||
|
|
||||||
logger = structlog.get_logger(__name__)
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_date(date_string):
|
def get_date(date_string):
|
||||||
return datetime.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 DueDateFactory(DjangoModelFactory):
|
class DueDateFactory(DjangoModelFactory):
|
||||||
|
|
@ -26,14 +30,18 @@ class DueDateFactory(DjangoModelFactory):
|
||||||
|
|
||||||
def generate_events(start=timezone.now()):
|
def generate_events(start=timezone.now()):
|
||||||
for i in range(20):
|
for i in range(20):
|
||||||
DueDateFactory(title=f"{i}", start=start + datetime.timedelta(days=i),
|
DueDateFactory(
|
||||||
end=start + datetime.timedelta(days=i, hours=1))
|
title=f"{i}",
|
||||||
|
start=start + datetime.timedelta(days=i),
|
||||||
|
end=start + datetime.timedelta(days=i, hours=1),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def hour_rounder(t):
|
def hour_rounder(t):
|
||||||
# Rounds to nearest hour by adding a timedelta hour if minute >= 30
|
# Rounds to nearest hour by adding a timedelta hour if minute >= 30
|
||||||
return (t.replace(second=0, microsecond=0, minute=0, hour=t.hour)
|
return t.replace(
|
||||||
+ datetime.timedelta(hours=t.minute // 30))
|
second=0, microsecond=0, minute=0, hour=t.hour
|
||||||
|
) + datetime.timedelta(hours=t.minute // 30)
|
||||||
|
|
||||||
|
|
||||||
def create_duedates_for_all_course_sessions():
|
def create_duedates_for_all_course_sessions():
|
||||||
|
|
@ -45,22 +53,33 @@ def create_duedates_for_all_course_sessions():
|
||||||
|
|
||||||
def create_duedates_for_course_session(course_session: CourseSession):
|
def create_duedates_for_course_session(course_session: CourseSession):
|
||||||
course = course_session.course
|
course = course_session.course
|
||||||
attendance_courses = list(LearningContentAttendanceCourse.objects.descendant_of(course.get_learning_path()))
|
attendance_courses = list(
|
||||||
|
LearningContentAttendanceCourse.objects.descendant_of(
|
||||||
|
course.get_learning_path()
|
||||||
|
)
|
||||||
|
)
|
||||||
assignments = list(Assignment.objects.descendant_of(course.get_learning_path()))
|
assignments = list(Assignment.objects.descendant_of(course.get_learning_path()))
|
||||||
contents = attendance_courses + assignments
|
contents = attendance_courses + assignments
|
||||||
|
|
||||||
for content in contents:
|
for content in contents:
|
||||||
if callable(getattr(content, 'get_frontend_url', None)):
|
if callable(getattr(content, "get_frontend_url", None)):
|
||||||
url = content.get_frontend_url()
|
url = content.get_frontend_url()
|
||||||
|
|
||||||
duedate, created = DueDate.objects.get_or_create(course_session=course_session,
|
duedate, created = DueDate.objects.get_or_create(
|
||||||
|
course_session=course_session,
|
||||||
title=content.title,
|
title=content.title,
|
||||||
url=url,
|
url=url,
|
||||||
page=content.specific)
|
page=content.specific,
|
||||||
|
)
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
pass
|
pass
|
||||||
logger.info("Created duedate ", duedate=duedate, course_session=course_session, content=content)
|
logger.info(
|
||||||
|
"Created duedate ",
|
||||||
|
duedate=duedate,
|
||||||
|
course_session=course_session,
|
||||||
|
content=content,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def set_default_times_for_duedates():
|
def set_default_times_for_duedates():
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import djclick as click
|
import djclick as click
|
||||||
|
|
||||||
from vbv_lernwelt.duedate.factories import create_duedates_for_all_course_sessions, set_default_times_for_duedates
|
from vbv_lernwelt.duedate.factories import (
|
||||||
|
create_duedates_for_all_course_sessions,
|
||||||
|
set_default_times_for_duedates,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Generated by Django 3.2.13 on 2023-06-14 09:29
|
# Generated by Django 3.2.13 on 2023-06-14 09:29
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
@ -9,20 +9,40 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('course', '0004_import_fields'),
|
("course", "0004_import_fields"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='DueDate',
|
name="DueDate",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('start', models.DateTimeField(db_index=True, null=True)),
|
"id",
|
||||||
('end', models.DateTimeField(db_index=True, null=True)),
|
models.BigAutoField(
|
||||||
('title', models.CharField(default='Termin', max_length=1024)),
|
auto_created=True,
|
||||||
('url', models.URLField(blank=True, max_length=1024, null=True)),
|
primary_key=True,
|
||||||
('learning_content_id', models.CharField(blank=True, max_length=255, null=True)),
|
serialize=False,
|
||||||
('course_session', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='events', to='course.coursesession')),
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("start", models.DateTimeField(db_index=True, null=True)),
|
||||||
|
("end", models.DateTimeField(db_index=True, null=True)),
|
||||||
|
("title", models.CharField(default="Termin", max_length=1024)),
|
||||||
|
("url", models.URLField(blank=True, max_length=1024, null=True)),
|
||||||
|
(
|
||||||
|
"learning_content_id",
|
||||||
|
models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"course_session",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="events",
|
||||||
|
to="course.coursesession",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,29 @@
|
||||||
# Generated by Django 3.2.13 on 2023-06-14 13:00
|
# Generated by Django 3.2.13 on 2023-06-14 13:00
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('wagtailcore', '0083_workflowcontenttype'),
|
("wagtailcore", "0083_workflowcontenttype"),
|
||||||
('duedate', '0001_initial'),
|
("duedate", "0001_initial"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(
|
||||||
model_name='duedate',
|
model_name="duedate",
|
||||||
name='learning_content_id',
|
name="learning_content_id",
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='duedate',
|
model_name="duedate",
|
||||||
name='page',
|
name="page",
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wagtailcore.page'),
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="wagtailcore.page",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ from vbv_lernwelt.course.models import CourseSession
|
||||||
class DueDate(models.Model):
|
class DueDate(models.Model):
|
||||||
start = models.DateTimeField(null=True, db_index=True)
|
start = models.DateTimeField(null=True, db_index=True)
|
||||||
end = models.DateTimeField(db_index=True, null=True)
|
end = models.DateTimeField(db_index=True, null=True)
|
||||||
title = models.CharField(default=_('Termin'), max_length=1024)
|
title = models.CharField(default=_("Termin"), max_length=1024)
|
||||||
url = models.URLField(null=True, blank=True, max_length=1024)
|
url = models.URLField(null=True, blank=True, max_length=1024)
|
||||||
course_session = models.ForeignKey(
|
course_session = models.ForeignKey(
|
||||||
'course.CourseSession',
|
"course.CourseSession",
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='duedates',
|
related_name="duedates",
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
@ -25,12 +25,12 @@ class DueDate(models.Model):
|
||||||
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True, blank=True)
|
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
|
||||||
def Meta(self):
|
def Meta(self):
|
||||||
ordering = ['start', 'end']
|
ordering = ["start", "end"]
|
||||||
verbose_name = _("Termin")
|
verbose_name = _("Termin")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
start_str = self.start.strftime('%Y-%m-%d %H:%M') if self.start else ''
|
start_str = self.start.strftime("%Y-%m-%d %H:%M") if self.start else ""
|
||||||
end_str = self.end.strftime('%Y-%m-%d %H:%M') if self.end else ''
|
end_str = self.end.strftime("%Y-%m-%d %H:%M") if self.end else ""
|
||||||
return f"DueDate: {self.title} {start_str} to {end_str}"
|
return f"DueDate: {self.title} {start_str} to {end_str}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -44,7 +44,9 @@ class DueDate(models.Model):
|
||||||
return self.end - self.start
|
return self.end - self.start
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_users_next_events_qs(cls, user: User, course_session: CourseSession = None, limit=10):
|
def get_users_next_events_qs(
|
||||||
|
cls, user: User, course_session: CourseSession = None, limit=10
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Returns a queryset of all duedates that are relevant for the given user. Ordered nearest start date first.
|
Returns a queryset of all duedates that are relevant for the given user. Ordered nearest start date first.
|
||||||
If course_session is given, only duedates for that course_session are returned.
|
If course_session is given, only duedates for that course_session are returned.
|
||||||
|
|
@ -54,11 +56,14 @@ class DueDate(models.Model):
|
||||||
qs = cls.get_next_duedates_qs()
|
qs = cls.get_next_duedates_qs()
|
||||||
|
|
||||||
if course_session:
|
if course_session:
|
||||||
qs = qs.filter(course_session=course_session, course_session__course_assignment__user=user)
|
qs = qs.filter(
|
||||||
|
course_session=course_session,
|
||||||
|
course_session__course_assignment__user=user,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
qs = qs.filter(course_session__course_assignment__user=user)
|
qs = qs.filter(course_session__course_assignment__user=user)
|
||||||
|
|
||||||
qs = qs.order_by('start')[:limit]
|
qs = qs.order_by("start")[:limit]
|
||||||
|
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ from vbv_lernwelt.duedate.models import DueDate
|
||||||
class DueDateSerializer(serializers.ModelSerializer):
|
class DueDateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = DueDate
|
model = DueDate
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,8 @@ class TesDueDatetModel(TestCase):
|
||||||
|
|
||||||
def generate_duedates(start=timezone.now()):
|
def generate_duedates(start=timezone.now()):
|
||||||
for i in range(20):
|
for i in range(20):
|
||||||
DueDateFactory(title=f"{i}", start=start + datetime.timedelta(days=i),
|
DueDateFactory(
|
||||||
end=start + datetime.timedelta(days=i, hours=1))
|
title=f"{i}",
|
||||||
|
start=start + datetime.timedelta(days=i),
|
||||||
|
end=start + datetime.timedelta(days=i, hours=1),
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,4 @@ class TestDueDatetSerializer(TestCase):
|
||||||
|
|
||||||
duedates = DueDate.objects.all()
|
duedates = DueDate.objects.all()
|
||||||
result = DueDateSerializer(duedates, many=True).data
|
result = DueDateSerializer(duedates, many=True).data
|
||||||
assert result[0]['title'] == 'Prüfung Versicherungsvermittler/-in'
|
assert result[0]["title"] == "Prüfung Versicherungsvermittler/-in"
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,7 @@ class LearningContentAttendanceCourse(LearningContent):
|
||||||
"""
|
"""
|
||||||
Präsenzkurs
|
Präsenzkurs
|
||||||
"""
|
"""
|
||||||
|
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue