Skip to content
Snippets Groups Projects
Commit 3211fca8 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Merge branch '215-substitutions-pdf-for-new-data-model' into 'master'

Resolve "Substitutions PDF for new data model"

Closes #215

See merge request !315
parents 3c2a4aa0 2aa7a0e9
No related branches found
No related tags found
1 merge request!315Resolve "Substitutions PDF for new data model"
Pipeline #192228 failed
from datetime import datetime, timedelta from datetime import date, datetime, timedelta
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Optional
from django.db.models import Count, Q from django.db.models import Count, Q
from django.http import HttpRequest, HttpResponseNotFound from django.http import HttpRequest, HttpResponseNotFound
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils import timezone
from guardian.core import ObjectPermissionChecker from guardian.core import ObjectPermissionChecker
...@@ -15,15 +13,12 @@ from aleksis.core.util.predicates import check_global_permission ...@@ -15,15 +13,12 @@ from aleksis.core.util.predicates import check_global_permission
from ..managers import TimetableType from ..managers import TimetableType
from ..models import ( from ..models import (
Absence,
LessonPeriod, LessonPeriod,
LessonSubstitution, LessonSubstitution,
Supervision, Supervision,
SupervisionSubstitution, SupervisionSubstitution,
TimePeriod,
) )
from .build import build_substitutions_list from .build import build_substitutions_list
from .js import date_unix
if TYPE_CHECKING: if TYPE_CHECKING:
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
...@@ -160,23 +155,13 @@ def get_rooms(user: "User"): ...@@ -160,23 +155,13 @@ def get_rooms(user: "User"):
def get_substitutions_context_data( def get_substitutions_context_data(
request: Optional[HttpRequest] = None, wanted_day: date,
year: Optional[int] = None,
month: Optional[int] = None,
day: Optional[int] = None,
is_print: bool = False,
number_of_days: Optional[int] = None, number_of_days: Optional[int] = None,
show_header_box: Optional[bool] = None, show_header_box: Optional[bool] = None,
): ):
"""Get context data for the substitutions table.""" """Get context data for the substitutions table."""
context = {} context = {}
if day:
wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = TimePeriod.get_next_relevant_day(wanted_day)
else:
wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), timezone.now().time())
day_number = ( day_number = (
number_of_days or get_site_preferences()["chronos__substitutions_print_number_of_days"] number_of_days or get_site_preferences()["chronos__substitutions_print_number_of_days"]
) )
...@@ -187,50 +172,41 @@ def get_substitutions_context_data( ...@@ -187,50 +172,41 @@ def get_substitutions_context_data(
) )
day_contexts = {} day_contexts = {}
if is_print: day = get_next_relevant_day(wanted_day)
next_day = wanted_day for _i in range(day_number):
for _i in range(day_number): day_contexts[day] = {"day": day}
day_contexts[next_day] = {"day": next_day}
next_day = TimePeriod.get_next_relevant_day(next_day + timedelta(days=1))
else:
day_contexts = {wanted_day: {"day": wanted_day}}
for day in day_contexts: subs, affected_teachers, affected_groups = build_substitutions_list(day)
subs = build_substitutions_list(day)
day_contexts[day]["substitutions"] = subs day_contexts[day]["substitutions"] = subs
day_contexts[day]["announcements"] = Announcement.for_timetables().on_date(day) day_contexts[day]["announcements"] = Announcement.objects.on_date(day)
if show_header_box: if show_header_box:
subs = LessonSubstitution.objects.on_day(day).order_by( day_contexts[day]["affected_teachers"] = sorted(
"lesson_period__lesson__groups", "lesson_period__period" affected_teachers, key=lambda t: t.short_name or t.full_name
) )
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"] = subs.affected_teachers()
affected_groups = subs.affected_groups()
if get_site_preferences()["chronos__affected_groups_parent_groups"]:
groups_with_parent_groups = affected_groups.filter(parent_groups__isnull=False)
groups_without_parent_groups = affected_groups.filter(parent_groups__isnull=True)
affected_groups = Group.objects.filter(
Q(child_groups__pk__in=groups_with_parent_groups.values_list("pk", flat=True))
| Q(pk__in=groups_without_parent_groups.values_list("pk", flat=True))
).distinct()
day_contexts[day]["affected_groups"] = affected_groups day_contexts[day]["affected_groups"] = affected_groups
if not is_print: day = get_next_relevant_day(day + timedelta(days=1))
context = day_contexts[wanted_day]
context["datepicker"] = {
"date": date_unix(wanted_day),
"dest": reverse("substitutions"),
}
context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( context["days"] = day_contexts
wanted_day, "substitutions_by_date"
) return context
def get_next_relevant_day(current: datetime | date) -> date:
"""Get next relevant day for substitution plans."""
relevant_days = get_site_preferences()["chronos__substitutions_relevant_days"]
change_time = get_site_preferences()["chronos__substitutions_day_change_time"]
if isinstance(current, datetime):
current_day = current.date()
if current.time() > change_time:
current_day += timedelta(days=1)
else: else:
context["days"] = day_contexts current_day = current
return context while str(current_day.weekday()) not in relevant_days:
current_day += timedelta(days=1)
return current_day
from datetime import date, datetime
from typing import Optional from typing import Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from rules.contrib.views import permission_required from rules.contrib.views import permission_required
from aleksis.core.decorators import pwa_cache
from aleksis.core.util.pdf import render_pdf from aleksis.core.util.pdf import render_pdf
from .util.chronos_helpers import ( from .util.chronos_helpers import (
...@@ -12,14 +12,12 @@ from .util.chronos_helpers import ( ...@@ -12,14 +12,12 @@ from .util.chronos_helpers import (
) )
@pwa_cache
@permission_required("chronos.view_substitutions_rule") @permission_required("chronos.view_substitutions_rule")
def substitutions_print( def substitutions_print(
request: HttpRequest, request: HttpRequest,
year: Optional[int] = None, day: Optional[str] = None,
month: Optional[int] = None,
day: Optional[int] = None,
) -> HttpResponse: ) -> HttpResponse:
"""View all substitutions on a specified day.""" """View all substitutions on a specified day."""
context = get_substitutions_context_data(request, year, month, day, is_print=True) day = datetime.strptime(day, "%Y-%m-%d").date() if day else date.today()
context = get_substitutions_context_data(day)
return render_pdf(request, "chronos/substitutions_print.html", context) return render_pdf(request, "chronos/substitutions_print.html", context)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment