Newer
Older
from collections import OrderedDict
from datetime import date, datetime, timedelta
from django.contrib.auth.decorators import login_required
from django.db.models import Count
from django.http import HttpRequest, HttpResponse, HttpResponseNotFound
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone

Nik | Klampfradler
committed
from django.utils.translation import ugettext as _
from aleksis.core.decorators import admin_required
from aleksis.core.models import Person, Group
from aleksis.core.util import messages
from .forms import LessonSubstitutionForm
from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room
from .tables import LessonsTable
from .util.js import date_unix
from .util.min_max import period_min, period_max, weekday_min_, weekday_max
from .util.prev_next import get_next_relevant_day, get_prev_next_by_day
from .util.weeks import CalendarWeek, get_weeks_for_year
from aleksis.core.util.core_helpers import has_person
def all_timetables(request: HttpRequest) -> HttpResponse:
teachers = Person.objects.annotate(
lessons_count=Count("lessons_as_teacher")
).filter(lessons_count__gt=0)
classes = Group.objects.annotate(lessons_count=Count("lessons")).filter(
lessons_count__gt=0, parent_groups=None
)
rooms = Room.objects.annotate(lessons_count=Count("lesson_periods")).filter(
lessons_count__gt=0
)
context["teachers"] = teachers
context["classes"] = classes
context["rooms"] = rooms
return render(request, "chronos/all.html", context)
@login_required
def my_timetable(
request: HttpRequest,
year: Optional[int] = None,
month: Optional[int] = None,
day: Optional[int] = None,
) -> HttpResponse:
context = {}
if day:
wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = get_next_relevant_day(wanted_day)
else:
wanted_day = get_next_relevant_day(timezone.now().date(), datetime.now().time())
person = request.user.person
if person.is_teacher:
# Teacher
type_ = "teacher"
super_el = person
lesson_periods_person = person.lesson_periods_as_teacher
elif person.primary_group:
# Student
type_ = "group"
super_el = person.primary_group
lesson_periods_person = person.lesson_periods_as_participant
else:
# If no student or teacher, redirect to all timetables
return redirect("all_timetables")
lesson_periods = lesson_periods_person.on_day(wanted_day)
# Build dictionary with lessons
per_period = {}
for lesson_period in lesson_periods:
if lesson_period.period.period in per_period:
per_period[lesson_period.period.period].append(lesson_period)
else:
per_period[lesson_period.period.period] = [lesson_period]
context["lesson_periods"] = OrderedDict(sorted(per_period.items()))
context["super"] = {"type": type_, "el": super_el}
context["type"] = type_
context["day"] = wanted_day
context["periods"] = TimePeriod.get_times_dict()
context["url_prev"], context["url_next"] = get_prev_next_by_day(
return render(request, "chronos/my_timetable.html", context)
request: HttpRequest,
type_: str,
pk: int,
year: Optional[int] = None,
week: Optional[int] = None,
regular: Optional[str] = None,
el = get_object_or_404(Group, pk=pk)
el = get_object_or_404(Person, pk=pk)
el = get_object_or_404(Room, pk=pk)
else:
return HttpResponseNotFound()
if year and week:
wanted_week = CalendarWeek(year=year, week=week)
else:
# TODO: On not used days show next week
wanted_week = CalendarWeek()

Nik | Klampfradler
committed
lesson_periods = LessonPeriod.objects.in_week(wanted_week)
lesson_periods = lesson_periods.filter_from_type(type_, pk)
# Regroup lesson periods per weekday
per_period = {}
for lesson_period in lesson_periods:

Jonathan Weth
committed
added = False
if lesson_period.period.period in per_period:

Jonathan Weth
committed
if lesson_period.period.weekday in per_period[lesson_period.period.period]:
per_period[lesson_period.period.period][
lesson_period.period.weekday
].append(lesson_period)
added = True

Jonathan Weth
committed
if not added:
per_period.setdefault(lesson_period.period.period, {})[
lesson_period.period.weekday
] = [lesson_period]
for period_num in range(period_min, period_max + 1):
if period_num not in per_period.keys():
per_period[period_num] = {}
# Fill in empty lessons on this workday
for weekday_num in range(weekday_min_, weekday_max + 1):
if weekday_num not in per_period[period_num].keys():

Jonathan Weth
committed
per_period[period_num][weekday_num] = []
per_period[period_num] = OrderedDict(sorted(per_period[period_num].items()))
context["lesson_periods"] = OrderedDict(sorted(per_period.items()))
context["periods"] = TimePeriod.get_times_dict()
context["weekdays"] = dict(
TimePeriod.WEEKDAY_CHOICES[weekday_min_ : weekday_max + 1]
)
context["weekdays_short"] = dict(
TimePeriod.WEEKDAY_CHOICES_SHORT[weekday_min_ : weekday_max + 1]
)
context["weeks"] = get_weeks_for_year(year=wanted_week.year)
context["pk"] = pk
context["el"] = el
context["week_select"] = {
"year": wanted_week.year,
"dest": reverse("timetable", args=[type_, pk]),
week_prev = wanted_week - 1
week_next = wanted_week + 1
context["url_prev"] = reverse(
"timetable_by_week", args=[type_, pk, week_prev.year, week_prev.week]
)
context["url_next"] = reverse(
"timetable_by_week", args=[type_, pk, week_next.year, week_next.week]
)
return render(request, "chronos/timetable.html", context)
@login_required
def lessons_day(
request: HttpRequest,
year: Optional[int] = None,
month: Optional[int] = None,
day: Optional[int] = None,
) -> HttpResponse:
context = {}
if day:
wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = get_next_relevant_day(wanted_day)
wanted_day = get_next_relevant_day(timezone.now().date(), datetime.now().time())
lesson_periods = LessonPeriod.objects.on_day(wanted_day)
lessons_table = LessonsTable(lesson_periods.all())
context["lessons_table"] = lessons_table
context["day"] = wanted_day
context["lesson_periods"] = lesson_periods
context["datepicker"] = {
"date": date_unix(wanted_day),
"dest": reverse("lessons_day"),
context["url_prev"], context["url_next"] = get_prev_next_by_day(
wanted_day, "lessons_day_by_date"
return render(request, "chronos/lessons_day.html", context)
def edit_substitution(request: HttpRequest, id_: int, week: int) -> HttpResponse:
lesson_period = get_object_or_404(LessonPeriod, pk=id_)
wanted_week = lesson_period.lesson.get_calendar_week(week)
lesson_substitution = LessonSubstitution.objects.filter(
week=wanted_week.week, lesson_period=lesson_period
).first()
if lesson_substitution:
edit_substitution_form = LessonSubstitutionForm(
request.POST or None, instance=lesson_substitution
)
edit_substitution_form = LessonSubstitutionForm(
request.POST or None,
initial={"week": wanted_week.week, "lesson_period": lesson_period},
)
context["substitution"] = lesson_substitution
if edit_substitution_form.is_valid():
edit_substitution_form.save(commit=True)
messages.success(request, _("The substitution has been saved."))
date = wanted_week[lesson_period.period.weekday]
"lessons_day_by_date", year=date.year, month=date.month, day=date.day
context["edit_substitution_form"] = edit_substitution_form
return render(request, "chronos/edit_substitution.html", context)
def delete_substitution(request: HttpRequest, id_: int, week: int) -> HttpResponse:
lesson_period = get_object_or_404(LessonPeriod, pk=id_)
wanted_week = lesson_period.lesson.get_calendar_week(week)
LessonSubstitution.objects.filter(
week=wanted_week.week, lesson_period=lesson_period
).delete()
messages.success(request, _("The substitution has been deleted."))
date = wanted_week[lesson_period.period.weekday]
"lessons_day_by_date", year=date.year, month=date.month, day=date.day
request: HttpRequest,
year: Optional[int] = None,
month: Optional[int] = None,
day: Optional[int] = None,
is_print: Optional[str] = None,
is_print = is_print == "print"
print(is_print)
if day:
wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = get_next_relevant_day(wanted_day)
wanted_day = get_next_relevant_day(timezone.now().date(), datetime.now().time())
DAY_COUNT = 2
day_contexts = {}
if is_print:
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
next_day = wanted_day
for i in range(DAY_COUNT):
print(i, next_day)
day_contexts[next_day] = {"day": next_day}
next_day = get_next_relevant_day(next_day + timedelta(days=1))
print(day_contexts)
print(day_contexts)
else:
day_contexts = {wanted_day: {"day": wanted_day}}
print(day_contexts)
for day in day_contexts:
day_contexts[day]["substitutions"] = LessonSubstitution.objects.on_day(
day
).order_by("lesson_period__lesson__groups", "lesson_period__period")
print(day_contexts[day]["substitutions"].count(), day)
print(day_contexts)
if not is_print:
context = day_contexts[wanted_day]
context["datepicker"] = {
"date": date_unix(wanted_day),
"dest": reverse("substitutions"),
}
context["url_prev"], context["url_next"] = get_prev_next_by_day(
wanted_day, "substitutions_by_date"
)
template_name = "chronos/substitutions.html"
else:
context["days"] = day_contexts
template_name = "chronos/substitutions_print.html"
print(context)
return render(request, template_name, context)