From 81c3a538aa7504e0725b0131898abffb27cbc021 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Fri, 10 Jul 2020 12:31:47 +0200
Subject: [PATCH] Allow setting personal notes only if lesson isn't cancelled

---
 .../alsijil/class_register/lesson.html        | 110 +++++++++---------
 aleksis/apps/alsijil/views.py                 |  34 +++---
 2 files changed, 77 insertions(+), 67 deletions(-)

diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html
index 5748e84a6..e7ece9d4a 100644
--- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html
+++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html
@@ -128,66 +128,68 @@
       </div>
     </div>
 
-    <div class="row">
-      <div class="col s12">
-        <div class="card">
-          <div class="card-content">
-      <span class="card-title">
-        {% blocktrans %}Personal notes{% endblocktrans %}
-      </span>
-            {% form form=personal_note_formset.management_form %}{% endform %}
-
-            <table class="striped responsive-table alsijil-table">
-              <thead>
-              <tr>
-                <th>{% blocktrans %}Person{% endblocktrans %}</th>
-                <th>{% blocktrans %}Absent{% endblocktrans %}</th>
-                <th>{% blocktrans %}Tardiness{% endblocktrans %}</th>
-                <th>{% blocktrans %}Excused{% endblocktrans %}</th>
-                <th>{% blocktrans %}Remarks{% endblocktrans %}</th>
-              </tr>
-              </thead>
-              <tbody>
-              {% for form in personal_note_formset %}
+    {% if not lesson_period.get_substitution.cancelled %}
+      <div class="row">
+        <div class="col s12">
+          <div class="card">
+            <div class="card-content">
+              <span class="card-title">
+                {% blocktrans %}Personal notes{% endblocktrans %}
+              </span>
+              {% form form=personal_note_formset.management_form %}{% endform %}
+
+              <table class="striped responsive-table alsijil-table">
+                <thead>
                 <tr>
-                  {{ form.id }}
-                  <td>{{ form.person_name }}{{ form.person_name.value }}</td>
-                  <td class="center-align">
-                    <label>
-                      {{ form.absent }}
-                      <span></span>
-                    </label>
-                  </td>
-                  <td>
-                    <div class="input-field">
-                      {{ form.late }}
-                      <label for="{{ form.absent.id_for_label }}">
-                        {% trans "Tardiness (in m)" %}
+                  <th>{% blocktrans %}Person{% endblocktrans %}</th>
+                  <th>{% blocktrans %}Absent{% endblocktrans %}</th>
+                  <th>{% blocktrans %}Tardiness{% endblocktrans %}</th>
+                  <th>{% blocktrans %}Excused{% endblocktrans %}</th>
+                  <th>{% blocktrans %}Remarks{% endblocktrans %}</th>
+                </tr>
+                </thead>
+                <tbody>
+                {% for form in personal_note_formset %}
+                  <tr>
+                    {{ form.id }}
+                    <td>{{ form.person_name }}{{ form.person_name.value }}</td>
+                    <td class="center-align">
+                      <label>
+                        {{ form.absent }}
+                        <span></span>
                       </label>
-                    </div>
-                  </td>
-                  <td class="center-align">
-                    <label>
-                      {{ form.excused }}
-                      <span></span>
-                    </label>
-                  </td>
-                  <td>
-                    <div class="input-field">
-                      {{ form.remarks }}
-                      <label for="{{ form.absent.id_for_label }}">
-                        {% trans "Remarks" %}
+                    </td>
+                    <td>
+                      <div class="input-field">
+                        {{ form.late }}
+                        <label for="{{ form.absent.id_for_label }}">
+                          {% trans "Tardiness (in m)" %}
+                        </label>
+                      </div>
+                    </td>
+                    <td class="center-align">
+                      <label>
+                        {{ form.excused }}
+                        <span></span>
                       </label>
-                    </div>
-                  </td>
-                </tr>
-              {% endfor %}
-              </tbody>
-            </table>
+                    </td>
+                    <td>
+                      <div class="input-field">
+                        {{ form.remarks }}
+                        <label for="{{ form.absent.id_for_label }}">
+                          {% trans "Remarks" %}
+                        </label>
+                      </div>
+                    </td>
+                  </tr>
+                {% endfor %}
+                </tbody>
+              </table>
+            </div>
           </div>
         </div>
       </div>
-    </div>
+    {% endif %}
 
     <div class="row">
       <div class="col s12">
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index 8fa58f62a..0caa7674a 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -12,7 +12,7 @@ from calendarweek import CalendarWeek
 from django_tables2 import RequestConfig
 
 from aleksis.apps.chronos.managers import TimetableType
-from aleksis.apps.chronos.models import LessonPeriod
+from aleksis.apps.chronos.models import LessonPeriod, LessonSubstitution
 from aleksis.apps.chronos.util.chronos_helpers import get_el_by_pk
 from aleksis.core.models import Group, Person, SchoolTerm
 from aleksis.core.util import messages
@@ -98,17 +98,19 @@ def lesson(
         if lesson_documentation_form.is_valid():
             lesson_documentation_form.save()
 
-        if personal_note_formset.is_valid():
-            instances = personal_note_formset.save()
-
-            # Iterate over personal notes and carry changed absences to following lessons
-            for instance in instances:
-                instance.person.mark_absent(
-                    wanted_week[lesson_period.period.weekday],
-                    lesson_period.period.period + 1,
-                    instance.absent,
-                    instance.excused,
-                )
+        substitution = lesson_period.get_substitution()
+        if not getattr(substitution, "cancelled", False):
+            if personal_note_formset.is_valid():
+                instances = personal_note_formset.save()
+
+                # Iterate over personal notes and carry changed absences to following lessons
+                for instance in instances:
+                    instance.person.mark_absent(
+                        wanted_week[lesson_period.period.weekday],
+                        lesson_period.period.period + 1,
+                        instance.absent,
+                        instance.excused,
+                    )
 
     context["lesson_documentation"] = lesson_documentation
     context["lesson_documentation_form"] = lesson_documentation_form
@@ -297,7 +299,13 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
 
     persons = group.members.annotate(
         absences_count=Count(
-            "personal_notes__absent", filter=Q(personal_notes__absent=True)
+            "personal_notes__absent", filter=Q(personal_notes__absent=True) & ~Q(personal_notes__lesson_period__substitutions=Subquery(
+                    LessonSubstitution.objects.filter(
+                        lesson_period__pk=OuterRef("personal_notes__lesson_period__pk"),
+                        cancelled=True,
+                        week=OuterRef("personal_notes__week"),
+                    ).values("pk")
+            ))
         ),
         unexcused=Count(
             "personal_notes__absent",
-- 
GitLab