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

Create new build mechanism for substitution lists (in order to implement events etc. later)

- Use new template for cancellation badge (badge.html)
- Show more details like comment or specific cancellation types
- Fix some rules in substitution templates
- Fix cycle mechanism in substitutions_print.html
parent 75088d27
No related branches found
No related tags found
1 merge request!47Advanced data in timetable views
...@@ -4,6 +4,7 @@ from collections import OrderedDict ...@@ -4,6 +4,7 @@ from collections import OrderedDict
from datetime import date, datetime, timedelta, time from datetime import date, datetime, timedelta, time
from typing import Dict, Optional, Tuple, Union from typing import Dict, Optional, Tuple, Union
from constance import config
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
...@@ -442,6 +443,18 @@ class Lesson(ExtensibleModel): ...@@ -442,6 +443,18 @@ class Lesson(ExtensibleModel):
def group_names(self, sep: Optional[str] = ", ") -> str: def group_names(self, sep: Optional[str] = ", ") -> str:
return sep.join([group.short_name for group in self.groups.all()]) return sep.join([group.short_name for group in self.groups.all()])
@property
def groups_to_show(self) -> models.QuerySet:
groups = self.groups.all()
if groups.count() == 1 and groups[0].parent_groups.all() and config.CHRONOS_USE_PARENT_GROUPS:
return groups[0].parent_groups.all()
else:
return groups
@property
def groups_to_show_names(self, sep: Optional[str] = ", ") -> str:
return sep.join([group.short_name for group in self.groups_to_show])
def get_calendar_week(self, week: int): def get_calendar_week(self, week: int):
year = self.date_start.year year = self.date_start.year
if week < int(self.date_start.strftime("%V")): if week < int(self.date_start.strftime("%V")):
...@@ -485,9 +498,10 @@ class LessonSubstitution(ExtensibleModel): ...@@ -485,9 +498,10 @@ class LessonSubstitution(ExtensibleModel):
@property @property
def type_(self): def type_(self):
# TODO: Add cases events and supervisions
if self.cancelled: if self.cancelled:
return "cancellation" return "cancellation"
elif self.cancelled_for_teachers:
return "cancellation_for_teachers"
else: else:
return "substitution" return "substitution"
......
...@@ -34,8 +34,7 @@ ...@@ -34,8 +34,7 @@
{% endif %} {% endif %}
{# Badge #} {# Badge #}
<span class="badge new green darken-2">{% if sub.cancelled_for_teachers %} {% include "chronos/partials/subs/badge.html" with sub=sub %}
{% trans "Cancelled for teachers" %}{% else %}{% trans "Cancelled" %}{% endif %}</span>
{% else %} {% else %}
{# Display sub #} {# Display sub #}
......
{% load i18n %}
{% if sub.cancelled %}
<span class="badge new green">{% trans "Cancelled" %}</span>
{% elif item.el.cancelled_for_teachers %}
<span class="badge new green">{% trans "Cancelled for teachers" %}</span>
{% endif %}
{% if not sub.is_event %} {% if sub.cancelled or sub.cancelled_for_teachers %}
{% if sub.sub.type == 3 %} {# Canceled lesson: no room #}
{# Supervisement #} {% elif sub.room and sub.lesson_period.room %}
{{ sub.sub.corridor.name }} {# New and old room available #}
{% elif sub.sub.type == 1 or sub.sub.type == 2 %} <span class="tooltipped" data-position="bottom"
{# Canceled lesson: no room #} data-tooltip="{{ sub.lesson_period.room.name }} → {{ sub.lesson_period.room.name }}"
{% elif sub.room and sub.lesson_period.room %} title="{{ sub.lesson_period.room.name }} → {{ sub.lesson_period.room.name }}">
{# New and old room available #} <a href="{% url "timetable" "room" sub.lesson_period.room.pk %}">
<span class="tooltipped" data-position="bottom" <s>{{ sub.lesson_period.room.short_name }}</s>
data-tooltip="{{ sub.lesson_period.room.name }} → {{ sub.lesson_period.room.name }}"> </a>
<a href="{% url "timetable" "room" sub.lesson_period.room.pk %}">
<s>{{ sub.lesson_period.room.short_name }}</s> <a href="{% url "timetable" "room" sub.room.pk %}">
</a> <strong>{{ sub.room.short_name }}</strong>
</a>
<a href="{% url "timetable" "room" sub.room.pk %}"> </span>
<strong>{{ sub.room.short_name }}</strong> {% elif sub.room and not sub.lesson_period.room %}
</a> {# Only new room available #}
</span> <span class="tooltipped" data-position="bottom"
{% elif sub.room and not sub.lesson_period.room %} data-tooltip="{{ sub.room.name }}"
{# Only new room available #} title="{{ sub.room.name }}">
<span class="tooltipped" data-position="bottom" <a href="{% url "timetable" "room" sub.room.pk %}">
data-tooltip="{{ sub.room.name }}"> {{ sub.room.short_name }}
<a href="{% url "timetable" "room" sub.room.pk %}"> </a>
{{ sub.room.short_name }} </span>
</a> {% elif not sub.room and not sub.lesson_period.room %}
</span> {# Nothing to view #}
{% elif not sub.room and not sub.lesson_period.room %}
{# Nothing to view #}
{% else %}
{# Only old room available #}
<span class="tooltipped" data-position="bottom"
data-tooltip="{{ sub.lesson_period.room.name }}">
<a href="{% url "timetable" "room" sub.lesson_period.room.pk %}">
{{ sub.lesson_period.room.short_name }}
</a>
</span>
{% endif %}
{% else %} {% else %}
{% for room in sub.rooms %} {# Only old room available #}
<span class="tooltipped" data-position="bottom" <span class="tooltipped" data-position="bottom"
data-tooltip="{{ room.name }}"> data-tooltip="{{ sub.lesson_period.room.name }}"
<a href="{% url "timetable_smart_plan" "room" room.id %}"> title="{{ sub.lesson_period.room.name }}">
<strong>{{ room.short_name }}{% if not forloop.last %},{% endif %}</strong> <a href="{% url "timetable" "room" sub.lesson_period.room.pk %}">
</a> {{ sub.lesson_period.room.short_name }}
</span> </a>
{% endfor %} </span>
{% endif %} {% endif %}
{% load i18n %} {% load i18n %}
{% if not sub.sub.is_event %} {% if not sub.lesson_period.lesson.subject and not sub.subject %}
{% if sub.sub.type == 3 %} {% elif sub.cancelled or sub.cancelled_for_teachers %}
<strong>{% trans "Supervision" %}</strong> <span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.lesson_period.lesson.subject.name }}">
{% elif not sub.lesson_period.lesson.subject and not sub.subject %} <s>{{ sub.lesson_period.lesson.subject.abbrev }}</s>
{% elif sub.sub.type == 1 or sub.sub.type == 2 %} </span>
<span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.lesson_period.lesson.subject.name }}"> {% elif sub.subject and sub.lesson_period.lesson.subject %}
<s>{{ sub.lesson_period.lesson.subject.abbrev }}</s> <span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.lesson_period.lesson.subject.name }}">
</span> <s>{{ sub.lesson_period.lesson.subject.abbrev }}</s>
{% elif sub.subject and sub.lesson_period.lesson.subject %} </span>
<span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.lesson_period.lesson.subject.name }}">
<s>{{ sub.lesson_period.lesson.subject.abbrev }}</s> <span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.subject.name }}">
</span> <strong>{{ sub.subject.abbrev }}</strong>
</span>
<span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.subject.name }}"> {% elif sub.subject and not sub.lesson_period.lesson.subject %}
<strong>{{ sub.subject.abbrev }}</strong> <span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.subject.name }}">
</span> <strong>{{ sub.subject.abbrev }}</strong>
{% elif sub.subject and not sub.lesson_period.lesson.subject %} </span>
<span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.subject.name }}"> {% else %}
<strong>{{ sub.subject.abbrev }}</strong> <span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.lesson_period.lesson.subject.name }}">
</span> <strong>{{ sub.lesson_period.lesson.subject.abbrev }}</strong>
{% else %} </span>
<span data-position="bottom" class="tooltipped" data-tooltip="{{ sub.lesson_period.lesson.subject.name }}">
<strong>{{ sub.lesson_period.lesson.subject.abbrev }}</strong>
</span>
{% endif %}
{% endif %} {% endif %}
{% if not sub.is_event %} {% if sub.cancelled and sub.lesson_period.lesson.teachers.all %}
{% if sub.sub.type == 1 and sub.lesson_period.lesson.teachers.all %} {% include "chronos/partials/teachers.html" with teachers=sub.lesson_period.lesson.teachers.all %}
{% elif sub.teachers.all and sub.lesson_period.lesson.teachers.all %}
<s>
{% include "chronos/partials/teachers.html" with teachers=sub.lesson_period.lesson.teachers.all %} {% include "chronos/partials/teachers.html" with teachers=sub.lesson_period.lesson.teachers.all %}
{% elif sub.teachers.all and sub.lesson_period.lesson.teachers.all %} </s>
<s>
{% include "chronos/partials/teachers.html" with teachers=sub.lesson_period.lesson.teachers.all %} <strong>
</s>
<strong>
{% include "chronos/partials/teachers.html" with teachers=sub.teachers.all %}
</strong>
{% elif sub.teachers.all and not sub.lesson_period.lesson.teachers.all %}
{% include "chronos/partials/teachers.html" with teachers=sub.teachers.all %} {% include "chronos/partials/teachers.html" with teachers=sub.teachers.all %}
{% elif sub.lesson_period.lesson.teachers.all %} </strong>
{% include "chronos/partials/teachers.html" with teachers=sub.lesson_period.lesson.teachers.all %} {% elif sub.teachers.all and not sub.lesson_period.lesson.teachers.all %}
{% endif %}
{% else %}
{% include "chronos/partials/teachers.html" with teachers=sub.teachers.all %} {% include "chronos/partials/teachers.html" with teachers=sub.teachers.all %}
{% elif sub.lesson_period.lesson.teachers.all %}
{% include "chronos/partials/teachers.html" with teachers=sub.lesson_period.lesson.teachers.all %}
{% endif %} {% endif %}
...@@ -57,37 +57,38 @@ ...@@ -57,37 +57,38 @@
</p> </p>
</td> </td>
{% endif %} {% endif %}
{% for sub in substitutions %} {% for item in substitutions %}
<tr class="{% if sub.type_ == "cancellation" %}green-text{% else %}black-text{% endif %}"> <tr class="
{% if item.type == "substitution" %}
{% if item.el.cancelled or item.el.cancelled_for_teachers %}green-text{% else %}black-text{% endif %}
{% endif %}
">
{# TODO: Extend support for blue and purple (supervisions and events) #} {# TODO: Extend support for blue and purple (supervisions and events) #}
<td> <td>
{% include "chronos/partials/groups.html" with groups=sub.lesson_period.lesson.groups.all %} {% include "chronos/partials/groups.html" with groups=item.el.lesson_period.lesson.groups.all %}
</td> </td>
<td> <td>
<strong> <strong>
{{ sub.lesson_period.period.period }}. {{ item.el.lesson_period.period.period }}.
</strong> </strong>
</td> </td>
<td> <td>
{% include "chronos/partials/subs/teachers.html" %} {% include "chronos/partials/subs/teachers.html" with sub=item.el %}
</td> </td>
<td> <td>
{% include "chronos/partials/subs/subject.html" %} {% include "chronos/partials/subs/subject.html" with sub=item.el %}
</td> </td>
<td> <td>
{% include "chronos/partials/subs/room.html" %} {% include "chronos/partials/subs/room.html" with sub=item.el %}
</td> </td>
<td> <td>
{% if sub.cancelled %} <span class="hide-on-med-and-up">
{# TODO: Support other cases#} {% include "chronos/partials/subs/badge.html" with sub=item.el %}
<span class="badge new green hide-on-med-and-up">{% trans "Cancelled" %}</span> </span>
{% endif %} <em>{{ sub.comment|default:"" }}</em>
{# <em>{{ sub.text|default:"" }}</em>#}
</td> </td>
<td class="hide-on-small-and-down"> <td class="hide-on-small-and-down">
{% if sub.cancelled %} {% include "chronos/partials/subs/badge.html" with sub=item.el %}
<span class="badge new green darken-2">{% trans "Cancelled" %}</span>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -46,38 +46,39 @@ ...@@ -46,38 +46,39 @@
{% endif %} {% endif %}
<tbody> <tbody>
{% for sub in c.substitutions %} {% for item in c.substitutions %}
<tr class="{% if sub.type_ == "cancellation" %}green-text{% else %}black-text{% endif %} "> {% ifchanged item.el.lesson_period.lesson.groups_to_show_names %}
</tbody>
<tbody class="{% cycle "striped" "not-striped" %}">
{% endifchanged %}
<tr class="
{% if item.type == "substitution" %}
{% if item.el.cancelled or item.el.cancelled_for_teachers %}green-text{% else %}black-text{% endif %}
{% endif %}
">
<td> <td>
{% include "chronos/partials/groups.html" with groups=sub.lesson_period.lesson.groups.all %} {% include "chronos/partials/groups.html" with groups=item.el.lesson_period.lesson.groups.all %}
</td> </td>
<td> <td>
<strong> <strong>
{{ sub.lesson_period.period.period }}. {{ item.el.lesson_period.period.period }}.
</strong> </strong>
</td> </td>
<td> <td>
{% include "chronos/partials/subs/teachers.html" %} {% include "chronos/partials/subs/teachers.html" with sub=item.el %}
</td> </td>
<td> <td>
{% include "chronos/partials/subs/subject.html" %} {% include "chronos/partials/subs/subject.html" with sub=item.el %}
</td> </td>
<td> <td>
{% include "chronos/partials/subs/room.html" %} {% include "chronos/partials/subs/room.html" with sub=item.el %}
</td> </td>
<td> <td>
{% if sub.cancelled %} {% include "chronos/partials/subs/badge.html" with sub=item.el %}
{# TODO: Support other cases#} <em>{{ sub.comment|default:"" }}</em>
<span class="badge new green">{% trans "Cancelled" %}</span>
{% endif %}
{# <em>{{ sub.text|default:"" }}</em>#}
</td> </td>
</tr> </tr>
{% ifchanged sub.lesson_period.lesson.groups %}
</tbody>
<tbody class="{% cycle "not-striped" "striped" %}">
{% endifchanged %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
......
from collections import OrderedDict from collections import OrderedDict
from datetime import date from datetime import date
from typing import Union from typing import Union, List
from calendarweek import CalendarWeek from calendarweek import CalendarWeek
from django.apps import apps from django.apps import apps
...@@ -11,6 +11,7 @@ LessonPeriod = apps.get_model("chronos", "LessonPeriod") ...@@ -11,6 +11,7 @@ LessonPeriod = apps.get_model("chronos", "LessonPeriod")
TimePeriod = apps.get_model("chronos", "TimePeriod") TimePeriod = apps.get_model("chronos", "TimePeriod")
Break = apps.get_model("chronos", "Break") Break = apps.get_model("chronos", "Break")
Supervision = apps.get_model("chronos", "Supervision") Supervision = apps.get_model("chronos", "Supervision")
LessonSubstitution = apps.get_model("chronos", "LessonSubstitution")
def build_timetable( def build_timetable(
...@@ -155,3 +156,28 @@ def build_timetable( ...@@ -155,3 +156,28 @@ def build_timetable(
rows.append(row) rows.append(row)
return rows return rows
def build_substitutions_list(wanted_day: date) -> List[dict]:
rows = []
subs = LessonSubstitution.objects.on_day(wanted_day).order_by(
"lesson_period__lesson__groups", "lesson_period__period"
)
for sub in subs:
if not sub.cancelled_for_teachers:
sort_a = sub.lesson_period.lesson.group_names
else:
sort_a = "Z.{}".format(sub.lesson_period.lesson.teacher_names)
row = {
"type": "substitution",
"sort_a": sort_a,
"sort_b": "{}".format(sub.lesson_period.period.period),
"el": sub,
}
rows.append(row)
return rows
...@@ -18,7 +18,7 @@ from aleksis.core.util import messages ...@@ -18,7 +18,7 @@ from aleksis.core.util import messages
from .forms import LessonSubstitutionForm from .forms import LessonSubstitutionForm
from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room
from .tables import LessonsTable from .tables import LessonsTable
from .util.build import build_timetable from .util.build import build_timetable, build_substitutions_list
from .util.js import date_unix from .util.js import date_unix
from .util.date import CalendarWeek, get_weeks_for_year from .util.date import CalendarWeek, get_weeks_for_year
from aleksis.core.util.core_helpers import has_person from aleksis.core.util.core_helpers import has_person
...@@ -295,12 +295,14 @@ def substitutions( ...@@ -295,12 +295,14 @@ def substitutions(
day_contexts = {wanted_day: {"day": wanted_day}} day_contexts = {wanted_day: {"day": wanted_day}}
for day in day_contexts: for day in day_contexts:
subs = LessonSubstitution.objects.on_day(day).order_by("lesson_period__lesson__groups", "lesson_period__period") 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).filter(show_in_timetables=True) day_contexts[day]["announcements"] = Announcement.for_timetables().on_date(day).filter(show_in_timetables=True)
if config.CHRONOS_SUBSTITUTIONS_SHOW_HEADER_BOX: if config.CHRONOS_SUBSTITUTIONS_SHOW_HEADER_BOX:
subs = LessonSubstitution.objects.on_day(day).order_by("lesson_period__lesson__groups",
"lesson_period__period")
day_contexts[day]["affected_teachers"] = subs.affected_teachers() day_contexts[day]["affected_teachers"] = subs.affected_teachers()
day_contexts[day]["affected_groups"] = subs.affected_groups() day_contexts[day]["affected_groups"] = subs.affected_groups()
......
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