Newer
Older
from datetime import date, datetime, timedelta
from django.db.models import Count, Q
from django.http import HttpRequest, HttpResponseNotFound
from django.shortcuts import get_object_or_404
from guardian.core import ObjectPermissionChecker
from aleksis.core.models import Announcement, Group, Person, Room
from aleksis.core.util.core_helpers import get_site_preferences
from aleksis.core.util.predicates import check_global_permission
from ..models import (
Absence,
LessonPeriod,
LessonSubstitution,
Supervision,
SupervisionSubstitution,
)
from .build import build_substitutions_list
if TYPE_CHECKING:
from django.contrib.auth import get_user_model
User = get_user_model() # noqa
def get_el_by_pk(
request: HttpRequest,
type_: str,
pk: int,
Group.objects.prefetch_related("owners", "parent_groups") if prefetch else Group,
pk=pk,
elif type_ == TimetableType.TEACHER.value:
return get_object_or_404(Person, pk=pk)
elif type_ == TimetableType.ROOM.value:
return get_object_or_404(Room, pk=pk)
else:
return HttpResponseNotFound()
def get_substitution_by_id(request: HttpRequest, id_: int, week: int):
lesson_period = get_object_or_404(LessonPeriod, pk=id_)
wanted_week = lesson_period.lesson.get_calendar_week(week)
return LessonSubstitution.objects.filter(
week=wanted_week.week, year=wanted_week.year, lesson_period=lesson_period
def get_supervision_substitution_by_id(request: HttpRequest, id_: int, date: datetime.date):
supervision = get_object_or_404(Supervision, pk=id_)
return SupervisionSubstitution.objects.filter(date=date, supervision=supervision).first()
"""Get the teachers whose timetables are allowed to be seen by current user."""
checker = ObjectPermissionChecker(user)
teachers = (
Person.objects.annotate(lessons_count=Count("lesson_events_as_teacher"))
.filter(lessons_count__gt=0)
.order_by("short_name", "last_name")
)
if not check_global_permission(user, "chronos.view_all_person_timetables"):
checker.prefetch_perms(teachers)
wanted_teachers = set()
for teacher in teachers:
if checker.has_perm("core.view_person_timetable", teacher):
wanted_teachers.add(teacher.pk)
teachers = teachers.filter(Q(pk=user.person.pk) | Q(pk__in=wanted_teachers))
teachers = teachers.distinct()
return teachers
def get_groups(user: "User"):
"""Get the groups whose timetables are allowed to be seen by current user."""
checker = ObjectPermissionChecker(user)
groups = (
Group.objects.for_current_school_term_or_all()
.annotate(
lessons_count=Count("lesson_events"),
child_lessons_count=Count("child_groups__lesson_events"),
)
.filter(Q(lessons_count__gt=0) | Q(child_lessons_count__gt=0))
)
group_types = get_site_preferences()["chronos__group_types_timetables"]
if group_types:
groups = groups.filter(group_type__in=group_types)
groups = groups.order_by("short_name", "name")
if not check_global_permission(user, "chronos.view_all_group_timetables"):
checker.prefetch_perms(groups)
wanted_classes = set()
for _class in groups:
if checker.has_perm("core.view_group_timetable", _class):
wanted_classes.add(_class.pk)
groups = groups.filter(
Q(pk__in=wanted_classes) | Q(members=user.person) | Q(owners=user.person)
)
groups = groups.filter(Q(pk=user.person.primary_group.pk))
groups = groups.distinct()
return groups
"""Get the rooms whose timetables are allowed to be seen by current user."""
checker = ObjectPermissionChecker(user)
rooms = (
Room.objects.annotate(lessons_count=Count("lesson_events"))
.filter(lessons_count__gt=0)
.order_by("short_name", "name")
)
if not check_global_permission(user, "chronos.view_all_room_timetables"):
checker.prefetch_perms(rooms)
wanted_rooms = set()
for room in rooms:
if checker.has_perm("core.view_room_timetable", room):
wanted_rooms.add(room.pk)
rooms = rooms.filter(Q(pk__in=wanted_rooms))
rooms = rooms.distinct()
return rooms
def get_substitutions_context_data(
number_of_days: Optional[int] = None,
show_header_box: Optional[bool] = None,
):
"""Get context data for the substitutions table."""
context = {}
day_number = (
number_of_days or get_site_preferences()["chronos__substitutions_print_number_of_days"]
)
show_header_box = (
show_header_box
if show_header_box is not None
else get_site_preferences()["chronos__substitutions_show_header_box"]
)
day_contexts = {}
day = wanted_day
for _i in range(day_number):
day_contexts[day] = {"day": day}
subs, affected_teachers, affected_groups = build_substitutions_list(day)
day_contexts[day]["substitutions"] = subs
day_contexts[day]["announcements"] = Announcement.objects.on_date(day)
if show_header_box:
absences = Absence.objects.on_day(day)
day_contexts[day]["absent_teachers"] = absences.absent_teachers()
day_contexts[day]["absent_groups"] = absences.absent_groups()
day_contexts[day]["affected_teachers"] = sorted(
affected_teachers, key=lambda t: t.short_name or t.full_name
)
day_contexts[day]["affected_groups"] = affected_groups
day = day + timedelta(days=1)
context["days"] = day_contexts
return context