From 93e1216d3cf9595c5068c68083a778222654fd92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de>
Date: Wed, 17 Aug 2022 22:50:29 +0200
Subject: [PATCH] Introduce admin view to enter interest and ad-hoc comments
 for AKs

Implements #147
---
 AKModel/locale/de_DE/LC_MESSAGES/django.po    |  28 +++--
 AKModel/templates/admin/AKModel/status.html   |   2 +
 AKScheduling/forms.py                         |  13 +++
 .../locale/de_DE/LC_MESSAGES/django.po        | 108 ++++++++++++------
 .../admin/AKScheduling/interest.html          |  45 ++++++++
 AKScheduling/urls.py                          |   4 +-
 AKScheduling/views.py                         |  58 +++++++++-
 7 files changed, 204 insertions(+), 54 deletions(-)
 create mode 100644 AKScheduling/forms.py
 create mode 100644 AKScheduling/templates/admin/AKScheduling/interest.html

diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po
index 7aeb9dfc..6e3bc74d 100644
--- a/AKModel/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKModel/locale/de_DE/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-08-17 17:35+0200\n"
+"POT-Creation-Date: 2022-08-17 22:41+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -459,7 +459,7 @@ msgstr "AK präsentieren"
 msgid "Present results of this AK"
 msgstr "Die Ergebnisse dieses AKs vorstellen"
 
-#: .\AKModel\models.py:262 .\AKModel\templates\admin\AKModel\status.html:95
+#: .\AKModel\models.py:262 .\AKModel\templates\admin\AKModel\status.html:97
 msgid "Requirements"
 msgstr "Anforderungen"
 
@@ -878,7 +878,7 @@ msgid "No AKs with this requirement"
 msgstr "Kein AK mit dieser Anforderung"
 
 #: .\AKModel\templates\admin\AKModel\requirements_overview.html:45
-#: .\AKModel\templates\admin\AKModel\status.html:111
+#: .\AKModel\templates\admin\AKModel\status.html:113
 msgid "Add Requirement"
 msgstr "Anforderung hinzufügen"
 
@@ -923,39 +923,43 @@ msgstr "Scheduling"
 msgid "AKs requiring special attention"
 msgstr ""
 
-#: .\AKModel\templates\admin\AKModel\status.html:84
+#: .\AKModel\templates\admin\AKModel\status.html:83
+msgid "Enter Interest"
+msgstr "Interesse erfassen"
+
+#: .\AKModel\templates\admin\AKModel\status.html:86
 msgid "Manage ak tracks"
 msgstr "AK-Tracks verwalten"
 
-#: .\AKModel\templates\admin\AKModel\status.html:86
+#: .\AKModel\templates\admin\AKModel\status.html:88
 msgid "Export AKs as CSV"
 msgstr "AKs als CSV exportieren"
 
-#: .\AKModel\templates\admin\AKModel\status.html:88
+#: .\AKModel\templates\admin\AKModel\status.html:90
 msgid "Export AKs for Wiki"
 msgstr "AKs im Wiki-Format exportieren"
 
-#: .\AKModel\templates\admin\AKModel\status.html:90
+#: .\AKModel\templates\admin\AKModel\status.html:92
 msgid "Export AK Slides"
 msgstr "AK-Folien exportieren"
 
-#: .\AKModel\templates\admin\AKModel\status.html:92
+#: .\AKModel\templates\admin\AKModel\status.html:94
 msgid "Export AK Slides (Presentation AKs only)"
 msgstr "AK-Folien exportieren (Nur zu präsentierende AKs)"
 
-#: .\AKModel\templates\admin\AKModel\status.html:97
+#: .\AKModel\templates\admin\AKModel\status.html:99
 msgid "No requirements yet"
 msgstr "Bisher keine Anforderungen"
 
-#: .\AKModel\templates\admin\AKModel\status.html:110
+#: .\AKModel\templates\admin\AKModel\status.html:112
 msgid "Show AKs for requirements"
 msgstr "Zu Anforderungen gehörige AKs anzeigen"
 
-#: .\AKModel\templates\admin\AKModel\status.html:114
+#: .\AKModel\templates\admin\AKModel\status.html:116
 msgid "Messages"
 msgstr "Nachrichten"
 
-#: .\AKModel\templates\admin\AKModel\status.html:116
+#: .\AKModel\templates\admin\AKModel\status.html:118
 msgid "Delete all messages"
 msgstr "Alle Nachrichten löschen"
 
diff --git a/AKModel/templates/admin/AKModel/status.html b/AKModel/templates/admin/AKModel/status.html
index 421f6096..f64a5a0c 100644
--- a/AKModel/templates/admin/AKModel/status.html
+++ b/AKModel/templates/admin/AKModel/status.html
@@ -79,6 +79,8 @@
                             href="{% url 'admin:constraint-violations' slug=event.slug %}">{% trans "Constraint Violations" %} <span class="badge badge-secondary">{{ event.constraintviolation_set.count }}</span></a>
                         <a class="btn btn-success"
                             href="{% url 'admin:special-attention' slug=event.slug %}">{% trans "AKs requiring special attention" %}</a>
+                        <a class="btn btn-success"
+                            href="{% url 'admin:enter-interest' event_slug=event.slug pk=event.ak_set.all.first.pk %}">{% trans "Enter Interest" %}</a>
                     {% endif %}
                     <a class="btn btn-success"
                        href="{% url 'admin:tracks_manage' event_slug=event.slug %}">{% trans "Manage ak tracks" %}</a>
diff --git a/AKScheduling/forms.py b/AKScheduling/forms.py
new file mode 100644
index 00000000..d1739eba
--- /dev/null
+++ b/AKScheduling/forms.py
@@ -0,0 +1,13 @@
+from django import forms
+
+from AKModel.models import AK
+
+
+class AKInterestForm(forms.ModelForm):
+    required_css_class = 'required'
+
+    class Meta:
+        model = AK
+        fields = ['interest',
+                  'notes',
+                  ]
diff --git a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
index 239886b5..5729c218 100644
--- a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-10-29 13:36+0000\n"
+"POT-Creation-Date: 2022-08-17 22:41+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,7 +17,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: AKScheduling/models.py:80
+#: .\AKScheduling\models.py:80
 #, python-format
 msgid ""
 "Not enough space for AK interest (Interest: %(interest)d, Capacity: "
@@ -26,7 +26,7 @@ msgstr ""
 "Nicht genug Platz für AK-Interesse (Interesse: %(interest)d, Kapazität: "
 "%(capacity)d)"
 
-#: AKScheduling/models.py:92
+#: .\AKScheduling\models.py:92
 #, python-format
 msgid ""
 "Space is too close to AK interest (Interest: %(interest)d, Capacity: "
@@ -35,116 +35,148 @@ msgstr ""
 "Verfügbarer Platz zu dicht an Interesse (Interesse: %(interest)d, Kapazität: "
 "%(capacity)d)"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:11
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:11
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:10
-msgid "Scheduling for"
-msgstr "Scheduling für"
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:11
+msgid "Constraint Violations for"
+msgstr ""
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:74
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:128
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:78
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:133
 msgid "No violations"
 msgstr "Keine Verletzungen"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:81
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:85
 msgid "Cannot load current violations from server"
 msgstr "Kann die aktuellen Verletzungen nicht vom Server laden"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:106
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:110
 msgid "Violation(s)"
 msgstr "Verletzung(en)"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:109
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:113
 msgid "Auto reload?"
 msgstr "Automatisch neu laden?"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:113
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:117
 msgid "Reload now"
 msgstr "Jetzt neu laden"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:118
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:123
 msgid "Violation"
 msgstr "Verletzung"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:119
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:124
 msgid "Problem"
 msgstr "Problem"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:120
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:125
 msgid "Details"
 msgstr "Details"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:121
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:126
 msgid "Since"
 msgstr "Seit"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:134
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:243
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:208
-#: AKScheduling/templates/admin/AKScheduling/unscheduled.html:34
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:139
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:243
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:208
+#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:43
+#: .\AKScheduling\templates\admin\AKScheduling\unscheduled.html:34
 msgid "Event Status"
 msgstr "Event-Status"
 
-#: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:136
+#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:141
 msgid "Scheduling"
 msgstr "Scheduling"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:129
+#: .\AKScheduling\templates\admin\AKScheduling\interest.html:33
+msgid "Submit"
+msgstr "Abschicken"
+
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:11
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:10
+msgid "Scheduling for"
+msgstr "Scheduling für"
+
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:129
 msgid "Name of new ak track"
 msgstr "Name des neuen AK-Tracks"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:145
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:145
 msgid "Could not create ak track"
 msgstr "Konnte neuen AK-Track nicht anlegen"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:171
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:171
 msgid "Could not update ak track name"
 msgstr "Konnte Namen des AK-Tracks nicht ändern"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:177
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:177
 msgid "Do you really want to delete this ak track?"
 msgstr "Soll dieser AK-Track wirklich gelöscht werden?"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:191
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:191
 msgid "Could not delete ak track"
 msgstr "AK-Track konnte nicht gelöscht werden"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:203
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:203
 msgid "Manage AK Tracks"
 msgstr "AK-Tracks verwalten"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:204
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:204
 msgid "Add ak track"
 msgstr "AK-Track hinzufügen"
 
-#: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:209
+#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:209
 msgid "AKs without track"
 msgstr "AKs ohne Track"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:91
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:91
 msgid "Day (Horizontal)"
 msgstr "Tag (horizontal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:98
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:98
 msgid "Day (Vertical)"
 msgstr "Tag (vertikal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:109
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:109
 msgid "Event (Horizontal)"
 msgstr "Event (horizontal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:118
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:118
 msgid "Event (Vertical)"
 msgstr "Event (vertikal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:146
+#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:146
 msgid "Room"
 msgstr "Raum"
 
-#: AKScheduling/templates/admin/AKScheduling/unscheduled.html:7
+#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:14
+msgid "AKs with public notes"
+msgstr "AKs mit öffentlichen Kommentaren"
+
+#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:21
+msgid "AKs without availabilities"
+msgstr "AKs ohne Verfügbarkeiten"
+
+#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:28
+msgid "AK wishes with slots"
+msgstr "AK-Wünsche mit Slots"
+
+#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:35
+msgid "AKs without slots"
+msgstr "AKs ohne Slots"
+
+#: .\AKScheduling\templates\admin\AKScheduling\unscheduled.html:7
 msgid "Unscheduled AK Slots"
 msgstr "Noch nicht geschedulte AK-Slots"
 
-#: AKScheduling/templates/admin/AKScheduling/unscheduled.html:11
+#: .\AKScheduling\templates\admin\AKScheduling\unscheduled.html:11
 msgid "Count"
 msgstr "Anzahl"
+
+#: .\AKScheduling\views.py:103
+msgid "Interest updated"
+msgstr "Interesse aktualisiert"
+
+#: .\AKScheduling\views.py:141
+msgid "Wishes"
+msgstr "Wünsche"
diff --git a/AKScheduling/templates/admin/AKScheduling/interest.html b/AKScheduling/templates/admin/AKScheduling/interest.html
new file mode 100644
index 00000000..d03cc7a2
--- /dev/null
+++ b/AKScheduling/templates/admin/AKScheduling/interest.html
@@ -0,0 +1,45 @@
+{% extends "admin/base_site.html" %}
+{% load bootstrap4 %}
+
+{% load i18n %}
+{% load l10n %}
+{% load tz %}
+{% load static %}
+{% load fontawesome_5 %}
+
+{% block title %}{{ title }}{% endblock %}
+
+{% block content %}
+    <div class="text-center text-md-center">
+        <h5>
+            {% if previous_ak %}
+                <a href="{% url "admin:enter-interest" event.slug previous_ak.pk %}" class="pull-left">&lt;-{{ previous_ak.name }}</a> |
+            {% endif %}
+            {% if next_ak %}
+                <a href="{% url "admin:enter-interest" event.slug next_ak.pk %}">{{ next_ak.name }} -&gt;</a>
+            {% endif %}
+        </h5>
+    </div>
+
+
+    <h4>{{ ak.name }}</h4>
+    <h5>{{ ak.short_name }}</h5>
+
+    <div class="mb-3">
+        <form method="POST" class="post-form">{% csrf_token %}
+            {% bootstrap_form form %}
+            {% buttons %}
+                <button type="submit" class="save btn btn-primary float-right">
+                    {% fa5_icon "check" 'fas' %} {% trans "Submit" %}
+                </button>
+            {% endbuttons %}
+        </form>
+    </div>
+
+    {% for category, aks in categories_with_aks %}
+        <h5 class="mt-4">{{ category.name }}</h5>
+        {% for link_ak in aks %}
+            <a href="{% url "admin:enter-interest" event.slug link_ak.pk %}">{{ link_ak.name }}</a> &middot;
+        {% endfor %}
+    {% endfor %}
+{% endblock %}
diff --git a/AKScheduling/urls.py b/AKScheduling/urls.py
index 74564ee5..e0fc27f5 100644
--- a/AKScheduling/urls.py
+++ b/AKScheduling/urls.py
@@ -1,7 +1,7 @@
 from django.urls import path
 
 from AKScheduling.views import SchedulingAdminView, UnscheduledSlotsAdminView, TrackAdminView, \
-    ConstraintViolationsAdminView, SpecialAttentionAKsAdminView
+    ConstraintViolationsAdminView, SpecialAttentionAKsAdminView, InterestEnteringAdminView
 
 
 def get_admin_urls_scheduling(admin_site):
@@ -16,4 +16,6 @@ def get_admin_urls_scheduling(admin_site):
              name="special-attention"),
         path('<slug:event_slug>/tracks/', admin_site.admin_view(TrackAdminView.as_view()),
              name="tracks_manage"),
+        path('<slug:event_slug>/enter-interest/<int:pk>', admin_site.admin_view(InterestEnteringAdminView.as_view()),
+             name="enter-interest"),
     ]
diff --git a/AKScheduling/views.py b/AKScheduling/views.py
index 140fe19d..da7ff91a 100644
--- a/AKScheduling/views.py
+++ b/AKScheduling/views.py
@@ -1,8 +1,10 @@
+from django.contrib.messages.views import SuccessMessageMixin
 from django.utils.translation import gettext_lazy as _
-from django.views.generic import ListView, DetailView
+from django.views.generic import ListView, DetailView, UpdateView
 
-from AKModel.models import AKSlot, AKTrack, Event, AK
-from AKModel.views import AdminViewMixin, FilterByEventSlugMixin
+from AKModel.models import AKSlot, AKTrack, Event, AK, AKCategory
+from AKModel.views import AdminViewMixin, FilterByEventSlugMixin, EventSlugMixin
+from AKScheduling.forms import AKInterestForm
 
 
 class UnscheduledSlotsAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
@@ -91,3 +93,53 @@ class SpecialAttentionAKsAdminView(AdminViewMixin, DetailView):
         context["aks_without_availabilities"] = aks_without_availabilities
 
         return context
+
+
+class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMixin, UpdateView):
+    template_name = "admin/AKScheduling/interest.html"
+    model = AK
+    context_object_name = "ak"
+    form_class = AKInterestForm
+    success_message = _("Interest updated")
+
+    def get_success_url(self):
+        return self.request.path
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context["title"] = f"{_('Enter interest')}"
+
+        # Sort AKs into different lists (by their category)
+        ak_wishes = []
+        categories_with_aks = []
+
+        context["previous_ak"] = None
+        context["next_ak"] = None
+        last_ak = None
+        next_is_next = False
+        for other_ak in context['ak'].category.ak_set.all():
+            if other_ak.wish:
+                continue
+            if next_is_next:
+                context['next_ak'] = other_ak
+                next_is_next = False
+            elif other_ak.pk == context['ak'].pk :
+                context['previous_ak'] = last_ak
+                next_is_next = True
+            last_ak = other_ak
+
+        for category in context['event'].akcategory_set.all():
+            aks_for_category = []
+            for ak in category.ak_set.all():
+                if ak.wish:
+                    ak_wishes.append(ak)
+                else:
+                    aks_for_category.append(ak)
+            categories_with_aks.append((category, aks_for_category))
+
+        categories_with_aks.append(
+                (AKCategory(name=_("Wishes"), pk=0, description="-"), ak_wishes))
+
+        context["categories_with_aks"] = categories_with_aks
+
+        return context
-- 
GitLab