From 53b88764763f623ba3bcdd618c4411d705438738 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@cs.tu-darmstadt.de>
Date: Fri, 25 Oct 2019 17:18:18 +0200
Subject: [PATCH] Allow edit and delete of AK slot durations

---
 AKSubmission/forms.py                         | 12 ++-
 .../locale/de_DE/LC_MESSAGES/django.po        | 87 ++++++++++++++++---
 .../templates/AKSubmission/ak_detail.html     | 11 +++
 .../AKSubmission/akslot_add_update.html       | 37 ++++++++
 .../templates/AKSubmission/akslot_delete.html | 43 +++++++++
 AKSubmission/urls.py                          |  3 +
 AKSubmission/views.py                         | 70 ++++++++++++++-
 7 files changed, 245 insertions(+), 18 deletions(-)
 create mode 100644 AKSubmission/templates/AKSubmission/akslot_add_update.html
 create mode 100644 AKSubmission/templates/AKSubmission/akslot_delete.html

diff --git a/AKSubmission/forms.py b/AKSubmission/forms.py
index fdb8f194..dc8bd854 100644
--- a/AKSubmission/forms.py
+++ b/AKSubmission/forms.py
@@ -4,7 +4,7 @@ from django import forms
 from django.core.exceptions import ValidationError
 from django.utils.translation import ugettext_lazy as _
 
-from AKModel.models import AK, AKOwner, AKCategory, AKRequirement
+from AKModel.models import AK, AKOwner, AKCategory, AKRequirement, AKSlot
 
 
 class AKForm(forms.ModelForm):
@@ -135,3 +135,13 @@ class AKOwnerForm(forms.ModelForm):
     class Meta:
         model = AKOwner
         fields = ['name', 'institution', 'link']
+
+
+class AKDurationForm(forms.ModelForm):
+    class Meta:
+        model = AKSlot
+        fields = ['duration', 'ak', 'event']
+        widgets = {
+            'ak': forms.HiddenInput,
+            'event': forms.HiddenInput
+        }
diff --git a/AKSubmission/locale/de_DE/LC_MESSAGES/django.po b/AKSubmission/locale/de_DE/LC_MESSAGES/django.po
index 86af55c0..d91e4032 100644
--- a/AKSubmission/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKSubmission/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: 2019-10-25 00:53+0000\n"
+"POT-Creation-Date: 2019-10-25 15:15+0000\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,20 +17,20 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: forms.py:40
+#: forms.py:43
 msgid "Separate multiple tags with semicolon"
 msgstr "Mehrere Tags mit Semikolon trennen"
 
-#: forms.py:61
+#: forms.py:67
 #, python-format
 msgid "\"%(duration)s\" is not a valid duration"
 msgstr "\"%(duration)s\" ist keine gültige Dauer"
 
-#: forms.py:95
+#: forms.py:110
 msgid "Duration(s)"
 msgstr "Dauer(n)"
 
-#: forms.py:96
+#: forms.py:112
 msgid ""
 "Enter at least one planned duration (in hours). If your AK should have "
 "multiple slots, use multiple lines"
@@ -42,6 +42,8 @@ msgstr ""
 #: templates/AKSubmission/ak_edit.html:8 templates/AKSubmission/ak_list.html:8
 #: templates/AKSubmission/ak_list.html:14
 #: templates/AKSubmission/akowner_create_update.html:7
+#: templates/AKSubmission/akslot_add_update.html:7
+#: templates/AKSubmission/akslot_delete.html:7
 #: templates/AKSubmission/submission_overview.html:6
 #: templates/AKSubmission/submission_overview.html:15
 #: templates/AKSubmission/submit_new.html:8
@@ -50,6 +52,7 @@ msgid "AKs"
 msgstr "AKs"
 
 #: templates/AKSubmission/ak_detail.html:8
+#: templates/AKSubmission/akslot_delete.html:30
 #, fuzzy
 #| msgid "AKs"
 msgid "AK"
@@ -60,6 +63,8 @@ msgstr "AKs"
 #: templates/AKSubmission/ak_list.html:13
 #: templates/AKSubmission/ak_list.html:18
 #: templates/AKSubmission/akowner_create_update.html:13
+#: templates/AKSubmission/akslot_add_update.html:13
+#: templates/AKSubmission/akslot_delete.html:13
 #: templates/AKSubmission/submission_overview.html:6
 #: templates/AKSubmission/submission_overview.html:11
 #: templates/AKSubmission/submit_new.html:19
@@ -96,18 +101,23 @@ msgstr "Tags"
 msgid "Reso?"
 msgstr "Reso?"
 
-#: templates/AKSubmission/ak_detail.html:60
+#: templates/AKSubmission/ak_detail.html:62
 msgid "When?"
 msgstr "Wann?"
 
-#: templates/AKSubmission/ak_detail.html:61
+#: templates/AKSubmission/ak_detail.html:63
+#: templates/AKSubmission/akslot_delete.html:31
 msgid "Duration"
 msgstr "Dauer"
 
-#: templates/AKSubmission/ak_detail.html:62
+#: templates/AKSubmission/ak_detail.html:64
 msgid "Room"
 msgstr "Raum"
 
+#: templates/AKSubmission/ak_detail.html:86
+msgid "Add another slot"
+msgstr "Einen neuen AK-Slot hinzufügen"
+
 #: templates/AKSubmission/ak_edit.html:8 templates/AKSubmission/ak_edit.html:21
 msgid "Edit AK"
 msgstr "AK bearbeiten"
@@ -139,19 +149,42 @@ msgid "AK Owner"
 msgstr "AK-Leitung"
 
 #: templates/AKSubmission/akowner_create_update.html:25
+#: templates/AKSubmission/akslot_add_update.html:26
 #: templates/AKSubmission/submit_new.html:34
 msgid "Reset"
 msgstr "Zurücksetzen"
 
 #: templates/AKSubmission/akowner_create_update.html:29
+#: templates/AKSubmission/akslot_add_update.html:30
+#: templates/AKSubmission/akslot_delete.html:36
 #: templates/AKSubmission/submit_new.html:38
 msgid "Cancel"
 msgstr "Abbrechen"
 
 #: templates/AKSubmission/akowner_create_update.html:32
+#: templates/AKSubmission/akslot_add_update.html:33
 msgid "Continue"
 msgstr "Weiter"
 
+#: templates/AKSubmission/akslot_add_update.html:7
+#: templates/AKSubmission/akslot_add_update.html:15
+#: templates/AKSubmission/akslot_add_update.html:20
+#: templates/AKSubmission/akslot_delete.html:7
+#: templates/AKSubmission/akslot_delete.html:15
+#: templates/AKSubmission/akslot_delete.html:20
+#, fuzzy
+#| msgid "Duration(s)"
+msgid "AK Duration(s)"
+msgstr "Dauer(n)"
+
+#: templates/AKSubmission/akslot_delete.html:25
+msgid "Do you really want to delete this AK Slot?"
+msgstr ""
+
+#: templates/AKSubmission/akslot_delete.html:39
+msgid "Confirm"
+msgstr "Bestätigen"
+
 #: templates/AKSubmission/submission_overview.html:19
 msgid ""
 "On this page you can see a list of current AKs, change them and add new ones."
@@ -193,28 +226,54 @@ msgstr "Aktuelle AKs"
 msgid "Submit"
 msgstr "Eintragen"
 
-#: views.py:44
+#: views.py:43
 msgid "Wishes"
 msgstr "Wünsche"
 
-#: views.py:44
+#: views.py:43
 msgid "AKs one would like to have"
 msgstr ""
 "AKs die sich gewünscht wurden, aber bei denen noch nicht klar ist, wer sie "
 "macht. Falls du dir das vorstellen kannst, trag dich einfach ein"
 
-#: views.py:105
+#: views.py:104
 msgid "AK successfully created"
 msgstr "AK erfolgreich angelegt"
 
-#: views.py:152
+#: views.py:157
 msgid "AK successfully updated"
 msgstr "AK erfolgreich bearbeitet"
 
-#: views.py:209
+#: views.py:215
 msgid "Person Info successfully updated"
 msgstr "Personen-Info erfolgreich bearbeitet"
 
-#: views.py:221
+#: views.py:228
 msgid "No user selected"
 msgstr "Keine Person ausgewählt"
+
+#: views.py:254
+#, fuzzy
+#| msgid "AK successfully created"
+msgid "AK Slot successfully added"
+msgstr "AK erfolgreich angelegt"
+
+#: views.py:266
+msgid "You cannot edit a slot that has already been scheduled"
+msgstr "Bereits geplante AK-Slots können nicht mehr bearbeitet werden"
+
+#: views.py:276
+#, fuzzy
+#| msgid "AK successfully updated"
+msgid "AK Slot successfully updated"
+msgstr "AK erfolgreich bearbeitet"
+
+#: views.py:287
+msgid "You cannot delete a slot that has already been scheduled"
+msgstr "Bereits geplante AK-Slots können nicht mehr gelöscht werden"
+
+#: views.py:297
+#, fuzzy
+#| msgid "AK successfully created"
+msgid "AK Slot successfully deleted"
+msgstr "AK erfolgreich angelegt"
diff --git a/AKSubmission/templates/AKSubmission/ak_detail.html b/AKSubmission/templates/AKSubmission/ak_detail.html
index 2e9bd6f4..0bf39673 100644
--- a/AKSubmission/templates/AKSubmission/ak_detail.html
+++ b/AKSubmission/templates/AKSubmission/ak_detail.html
@@ -60,6 +60,7 @@
                 <th>{% trans "When?" %}</th>
                 <th>{% trans "Duration" %}</th>
                 <th>{% trans "Room" %}</th>
+                <th></th>
             </tr>
         </thead>
         <tbody>
@@ -68,9 +69,19 @@
                     <td>{{ slot.start_simplified }}</td>
                     <td>{{ slot.duration }}</td>
                     <td>{{ slot.room }}</td>
+                    <td>
+                        {% if not slot.start %}
+                            <a href="{% url 'submit:akslot_edit' event_slug=ak.event.slug pk=slot.pk %}" class="btn btn-success">{%  fontawesome_icon 'pencil-alt' %}</a>
+                            <a href="{% url 'submit:akslot_delete' event_slug=ak.event.slug pk=slot.pk %}" class="btn btn-danger">{%  fontawesome_icon 'times' %}</a>
+                        {% endif %}
+                    </td>
                 </tr>
             {% endfor %}
         </tbody>
     </table>
 
+    <div class="">
+        <a href="{% url 'submit:akslot_add' event_slug=ak.event.slug pk=ak.pk %}" class="btn btn-success">{%  fontawesome_icon 'plus' %} {% trans "Add another slot" %}</a>
+    </div>
+
 {% endblock %}
diff --git a/AKSubmission/templates/AKSubmission/akslot_add_update.html b/AKSubmission/templates/AKSubmission/akslot_add_update.html
new file mode 100644
index 00000000..8ef2d78d
--- /dev/null
+++ b/AKSubmission/templates/AKSubmission/akslot_add_update.html
@@ -0,0 +1,37 @@
+{% extends 'base.html' %}
+
+{% load i18n %}
+{% load bootstrap4 %}
+{% load fontawesome %}
+
+{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Duration(s)" %}{% endblock %}
+
+{% block breadcrumbs %}
+    <li class="breadcrumb-item"><a href="#">AKPlanning</a></li>
+    <li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li>
+    <li class="breadcrumb-item"><a
+            href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
+    <li class="breadcrumb-item"><a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}">{{ ak.short_name }}</a></li>
+    <li class="breadcrumb-item active">{% trans "AK Duration(s)" %}</li>
+{% endblock %}
+
+{% block content %}
+    {% block headline %}
+        <h2>{% trans 'AK Duration(s)' %}</h2>
+    {% endblock %}
+    <form method="POST" class="post-form">{% csrf_token %}
+        {% bootstrap_form form %}
+        {% buttons %}
+            <button type="reset" class="btn btn-danger">
+                {% fontawesome_icon "undo-alt" %} {% trans "Reset" %}
+            </button>
+
+            <a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}" class="btn btn-secondary">
+                {% fontawesome_icon "times" %} {% trans "Cancel" %}
+            </a>
+            <button type="submit" class="save btn btn-primary float-right">
+                {% fontawesome_icon "check" %} {% trans "Continue" %}
+            </button>
+        {% endbuttons %}
+    </form>
+{% endblock %}
diff --git a/AKSubmission/templates/AKSubmission/akslot_delete.html b/AKSubmission/templates/AKSubmission/akslot_delete.html
new file mode 100644
index 00000000..9233ba7d
--- /dev/null
+++ b/AKSubmission/templates/AKSubmission/akslot_delete.html
@@ -0,0 +1,43 @@
+{% extends 'base.html' %}
+
+{% load i18n %}
+{% load bootstrap4 %}
+{% load fontawesome %}
+
+{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Duration(s)" %}{% endblock %}
+
+{% block breadcrumbs %}
+    <li class="breadcrumb-item"><a href="#">AKPlanning</a></li>
+    <li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li>
+    <li class="breadcrumb-item"><a
+            href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
+    <li class="breadcrumb-item"><a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}">{{ ak.short_name }}</a></li>
+    <li class="breadcrumb-item active">{% trans "AK Duration(s)" %}</li>
+{% endblock %}
+
+{% block content %}
+    {% block headline %}
+        <h2>{% trans 'AK Duration(s)' %}</h2>
+    {% endblock %}
+    <form method="POST" class="post-form">{% csrf_token %}
+
+        <div class="alert alert-danger" style="margin-top:20px;margin-bottom: 20px;">
+            <h4>{% trans "Do you really want to delete this AK Slot?" %}</h4>
+        </div>
+
+        <table class="table">
+            <tbody>
+            <tr><td>{% trans "AK" %}</td><td>{{ akslot.ak }}</td></tr>
+            <tr><td>{% trans "Duration" %}</td><td>{{ akslot.duration }}</td></tr>
+            </tbody>
+        </table>
+        {% buttons %}
+            <a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}" class="btn btn-secondary">
+                {% fontawesome_icon "times" %} {% trans "Cancel" %}
+            </a>
+            <button type="submit" class="save btn btn-danger float-right" value="Confirm">
+                {% fontawesome_icon "check" %} {% trans "Confirm" %}
+            </button>
+        {% endbuttons %}
+    </form>
+{% endblock %}
diff --git a/AKSubmission/urls.py b/AKSubmission/urls.py
index 637ce835..c40cb596 100644
--- a/AKSubmission/urls.py
+++ b/AKSubmission/urls.py
@@ -11,6 +11,9 @@ urlpatterns = [
             path('', views.SubmissionOverviewView.as_view(), name='submission_overview'),
             path('ak/<int:pk>', views.AKDetailView.as_view(), name='ak_detail'),
             path('ak/<int:pk>/edit/', views.AKEditView.as_view(), name='ak_edit'),
+            path('ak/<int:pk>/add_slot/', views.AKSlotAddView.as_view(), name='akslot_add'),
+            path('akslot/<int:pk>/edit/', views.AKSlotEditView.as_view(), name='akslot_edit'),
+            path('akslot/<int:pk>/delete/', views.AKSlotDeleteView.as_view(), name='akslot_delete'),
             path('aks/', views.AKListView.as_view(), name='ak_list'),
             path('aks/category/<int:category_pk>', views.AKListByCategoryView.as_view(), name='ak_list_by_category'),
             path('aks/tag/<int:tag_pk>', views.AKListByTagView.as_view(), name='ak_list_by_tag'),
diff --git a/AKSubmission/views.py b/AKSubmission/views.py
index 45b1a288..66ab16f5 100644
--- a/AKSubmission/views.py
+++ b/AKSubmission/views.py
@@ -1,17 +1,17 @@
 from django.conf import settings
 from django.contrib import messages
 from django.http import Http404, HttpResponseRedirect
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, redirect
 from django.urls import reverse_lazy
 from django.utils.translation import gettext_lazy as _
 from django.views import View
-from django.views.generic import ListView, DetailView, CreateView, UpdateView
+from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
 
 from AKModel.models import AK, AKCategory, AKTag, AKOwner, AKSlot
 from AKModel.models import Event
 from AKModel.views import EventSlugMixin
 from AKModel.views import FilterByEventSlugMixin
-from AKSubmission.forms import AKWishForm, AKOwnerForm, AKEditForm, AKSubmissionForm
+from AKSubmission.forms import AKWishForm, AKOwnerForm, AKEditForm, AKSubmissionForm, AKDurationForm
 
 
 class SubmissionOverviewView(FilterByEventSlugMixin, ListView):
@@ -232,3 +232,67 @@ class AKOwnerEditDispatchView(EventSlugMixin, View):
         owner = get_object_or_404(AKOwner, pk=request.POST["owner_id"])
         return HttpResponseRedirect(
             reverse_lazy('submit:akowner_edit', kwargs={'event_slug': kwargs['event_slug'], 'slug': owner.slug}))
+
+
+class AKSlotAddView(EventSlugMixin, CreateView):
+    model = AKSlot
+    form_class = AKDurationForm
+    template_name = "AKSubmission/akslot_add_update.html"
+
+    def get_initial(self):
+        initials = super(AKSlotAddView, self).get_initial()
+        initials['event'] = self.event
+        initials['ak'] = get_object_or_404(AK, pk=self.kwargs['pk'])
+        return initials
+
+    def get_context_data(self, *, object_list=None, **kwargs):
+        context = super().get_context_data(object_list=object_list, **kwargs)
+        context['ak'] = get_object_or_404(AK, pk=self.kwargs['pk'])
+        return context
+
+    def get_success_url(self):
+        messages.add_message(self.request, messages.SUCCESS, _("AK Slot successfully added"))
+        return reverse_lazy('submit:ak_detail', kwargs={'event_slug': self.kwargs['event_slug'], 'pk': self.object.ak.pk})
+
+
+class AKSlotEditView(EventSlugMixin, UpdateView):
+    model = AKSlot
+    form_class = AKDurationForm
+    template_name = "AKSubmission/akslot_add_update.html"
+
+    def get(self, request, *args, **kwargs):
+        akslot = get_object_or_404(AKSlot, pk=kwargs["pk"])
+        if akslot.start is not None:
+            messages.add_message(self.request, messages.WARNING, _("You cannot edit a slot that has already been scheduled"))
+            return redirect('submit:ak_detail', event_slug=self.kwargs['event_slug'], pk=akslot.ak.pk)
+        return super().get(request, *args, **kwargs)
+
+    def get_context_data(self, *, object_list=None, **kwargs):
+        context = super().get_context_data(object_list=object_list, **kwargs)
+        context['ak'] = self.object.ak
+        return context
+
+    def get_success_url(self):
+        messages.add_message(self.request, messages.SUCCESS, _("AK Slot successfully updated"))
+        return reverse_lazy('submit:ak_detail', kwargs={'event_slug': self.kwargs['event_slug'], 'pk': self.object.ak.pk})
+
+
+class AKSlotDeleteView(EventSlugMixin, DeleteView):
+    model = AKSlot
+    template_name = "AKSubmission/akslot_delete.html"
+
+    def get(self, request, *args, **kwargs):
+        akslot = get_object_or_404(AKSlot, pk=kwargs["pk"])
+        if akslot.start is not None:
+            messages.add_message(self.request, messages.WARNING, _("You cannot delete a slot that has already been scheduled"))
+            return redirect('submit:ak_detail', event_slug=self.kwargs['event_slug'], pk=akslot.ak.pk)
+        return super().get(request, *args, **kwargs)
+
+    def get_context_data(self, *, object_list=None, **kwargs):
+        context = super().get_context_data(object_list=object_list, **kwargs)
+        context['ak'] = self.object.ak
+        return context
+
+    def get_success_url(self):
+        messages.add_message(self.request, messages.SUCCESS, _("AK Slot successfully deleted"))
+        return reverse_lazy('submit:ak_detail', kwargs={'event_slug': self.kwargs['event_slug'], 'pk': self.object.ak.pk})
-- 
GitLab