Skip to content
Snippets Groups Projects
Commit 5fd2fc96 authored by Benjamin Hättasch's avatar Benjamin Hättasch
Browse files

Create admin action to create default availabilities

Introduce admin action
Add function to find AKs without availabilities to event model
Link new action on view of AKs requiring special attention
Minor design improvements
This implements the final part of #145
parent e340dfe1
No related branches found
No related tags found
1 merge request!132Make scheduling preparation easier
Pipeline #103205 passed
...@@ -109,6 +109,10 @@ class Event(models.Model): ...@@ -109,6 +109,10 @@ class Event(models.Model):
def get_unscheduled_wish_slots(self): def get_unscheduled_wish_slots(self):
return self.akslot_set.filter(start__isnull=True).annotate(Count('ak__owners')).filter(ak__owners__count=0) return self.akslot_set.filter(start__isnull=True).annotate(Count('ak__owners')).filter(ak__owners__count=0)
def get_aks_without_availabilities(self):
return self.ak_set.annotate(Count('availabilities', distinct=True)).annotate(Count('owners', distinct=True)).filter(availabilities__count=0, owners__count__gt=0)
class AKOwner(models.Model): class AKOwner(models.Model):
""" An AKOwner describes the person organizing/holding an AK. """ An AKOwner describes the person organizing/holding an AK.
""" """
...@@ -331,14 +335,6 @@ class AK(models.Model): ...@@ -331,14 +335,6 @@ class AK(models.Model):
def availabilities(self): def availabilities(self):
return "Availability".objects.filter(ak=self) return "Availability".objects.filter(ak=self)
@property
def availabilities_total_duration(self):
from AKModel.availability.models import Availability
for a in Availability.objects.filter(ak=self):
print(a)
print(a.end)
# [a.end - a.start for a in ]
return 0
class Room(models.Model): class Room(models.Model):
""" A room describes where an AK can be held. """ A room describes where an AK can be held.
......
...@@ -8,7 +8,7 @@ msgid "" ...@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-09-27 14:14+0200\n" "POT-Creation-Date: 2022-09-27 17:59+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
...@@ -79,7 +79,7 @@ msgstr "Seit" ...@@ -79,7 +79,7 @@ msgstr "Seit"
#: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:139 #: .\AKScheduling\templates\admin\AKScheduling\constraint_violations.html:139
#: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:243 #: .\AKScheduling\templates\admin\AKScheduling\manage_tracks.html:243
#: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:208 #: .\AKScheduling\templates\admin\AKScheduling\scheduling.html:208
#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:44 #: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:48
#: .\AKScheduling\templates\admin\AKScheduling\unscheduled.html:34 #: .\AKScheduling\templates\admin\AKScheduling\unscheduled.html:34
msgid "Event Status" msgid "Event Status"
msgstr "Event-Status" msgstr "Event-Status"
...@@ -158,14 +158,18 @@ msgid "AKs without availabilities" ...@@ -158,14 +158,18 @@ msgid "AKs without availabilities"
msgstr "AKs ohne Verfügbarkeiten" msgstr "AKs ohne Verfügbarkeiten"
#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:28 #: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:28
msgid "Create default availabilities"
msgstr "Standardverfügbarkeiten anlegen"
#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:31
msgid "AK wishes with slots" msgid "AK wishes with slots"
msgstr "AK-Wünsche mit Slots" msgstr "AK-Wünsche mit Slots"
#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:34 #: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:38
msgid "Delete slots for wishes" msgid "Delete slots for wishes"
msgstr "" msgstr ""
#: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:36 #: .\AKScheduling\templates\admin\AKScheduling\special_attention.html:40
msgid "AKs without slots" msgid "AKs without slots"
msgstr "AKs ohne Slots" msgstr "AKs ohne Slots"
...@@ -177,29 +181,57 @@ msgstr "Noch nicht geschedulte AK-Slots" ...@@ -177,29 +181,57 @@ msgstr "Noch nicht geschedulte AK-Slots"
msgid "Count" msgid "Count"
msgstr "Anzahl" msgstr "Anzahl"
#: .\AKScheduling\views.py:108 #: .\AKScheduling\views.py:109
msgid "Interest updated" msgid "Interest updated"
msgstr "Interesse aktualisiert" msgstr "Interesse aktualisiert"
#: .\AKScheduling\views.py:146 #: .\AKScheduling\views.py:147
msgid "Wishes" msgid "Wishes"
msgstr "Wünsche" msgstr "Wünsche"
#: .\AKScheduling\views.py:154 #: .\AKScheduling\views.py:155
msgid "Cleanup: Delete unscheduled slots for wishes" msgid "Cleanup: Delete unscheduled slots for wishes"
msgstr "Aufräumen: Noch nicht geplante Slots für Wünsche löschen" msgstr "Aufräumen: Noch nicht geplante Slots für Wünsche löschen"
#: .\AKScheduling\views.py:160 #: .\AKScheduling\views.py:162
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"The following {count} unscheduled slots of wishes will be deleted:\n" "The following {count} unscheduled slots of wishes will be deleted:\n"
"\n" "\n"
" {slots}" " {slots}"
msgstr "" msgstr ""
"Die folgenden {count} noch nicht geplanten Slots von Wünschen werden gelöscht:\n" "Die folgenden {count} noch nicht geplanten Slots von Wünschen werden "
"gelöscht:\n"
"\n" "\n"
" {slots}" " {slots}"
#: .\AKScheduling\views.py:167 #: .\AKScheduling\views.py:169
msgid "Unscheduled slots for wishes successfully deleted" msgid "Unscheduled slots for wishes successfully deleted"
msgstr "Noch nicht geplante Slots für Wünsche erfolgreich gelöscht" msgstr "Noch nicht geplante Slots für Wünsche erfolgreich gelöscht"
#: .\AKScheduling\views.py:174
msgid "Create default availabilities for AKs"
msgstr "Standardverfügbarkeiten für AKs anlegen"
#: .\AKScheduling\views.py:181
#, python-brace-format
msgid ""
"The following {count} AKs don't have any availability information. Create "
"default availability for them:\n"
"\n"
" {aks}"
msgstr ""
"Die folgenden {count} AKs haben keine Verfügbarkeitsinformationen. "
"Standardverfügbarkeiten für sie anlegen:\n"
"\n"
" {aks}"
#: .\AKScheduling\views.py:199
#, python-brace-format
msgid "Could not create default availabilities for AK: {ak}"
msgstr "Konnte keine Verfügbarkeit anlegen für AK: {ak}"
#: .\AKScheduling\views.py:204
#, python-brace-format
msgid "Created default availabilities for {count} AKs"
msgstr "Standardverfügbarkeiten für {count} AKs angelegt"
...@@ -22,14 +22,17 @@ ...@@ -22,14 +22,17 @@
{% for ak in aks_without_availabilities %} {% for ak in aks_without_availabilities %}
<a href="{% url "submit:ak_edit" event_slug=event.slug pk=ak.pk %}">{{ ak }}</a><br> <a href="{% url "submit:ak_edit" event_slug=event.slug pk=ak.pk %}">{{ ak }}</a><br>
{% empty %} {% empty %}
- -<br>
{% endfor %} {% endfor %}
<a class="btn btn-warning mt-2" href="{% url "admin:autocreate-availabilities" event_slug=event.slug %}">{% trans "Create default availabilities" %}</a>
<h4 class="mt-4 mb-4">{% trans "AK wishes with slots" %}</h4> <h4 class="mt-4 mb-4">{% trans "AK wishes with slots" %}</h4>
{% for ak in ak_wishes_with_slots %} {% for ak in ak_wishes_with_slots %}
<a href="{% url "submit:ak_detail" event_slug=event.slug pk=ak.pk %}">{{ ak }}</a> <a href="{% url "admin:AKModel_akslot_changelist" %}?ak={{ ak.pk }}">({{ ak.akslot__count }})</a><br> <a href="{% url "submit:ak_detail" event_slug=event.slug pk=ak.pk %}">{{ ak }}</a> <a href="{% url "admin:AKModel_akslot_changelist" %}?ak={{ ak.pk }}">({{ ak.akslot__count }})</a><br>
{% empty %} {% empty %}
- -<br>
{% endfor %} {% endfor %}
<a class="btn btn-warning mt-2" href="{% url "admin:cleanup-wish-slots" event_slug=event.slug %}">{% trans "Delete slots for wishes" %}</a> <a class="btn btn-warning mt-2" href="{% url "admin:cleanup-wish-slots" event_slug=event.slug %}">{% trans "Delete slots for wishes" %}</a>
...@@ -38,7 +41,7 @@ ...@@ -38,7 +41,7 @@
{% for ak in aks_without_slots %} {% for ak in aks_without_slots %}
<a href="{% url "submit:ak_detail" event_slug=event.slug pk=ak.pk %}">{{ ak }}</a><br> <a href="{% url "submit:ak_detail" event_slug=event.slug pk=ak.pk %}">{{ ak }}</a><br>
{% empty %} {% empty %}
- -<br>
{% endfor %} {% endfor %}
<div class="mt-5"> <div class="mt-5">
......
from django.urls import path from django.urls import path
from AKScheduling.views import SchedulingAdminView, UnscheduledSlotsAdminView, TrackAdminView, \ from AKScheduling.views import SchedulingAdminView, UnscheduledSlotsAdminView, TrackAdminView, \
ConstraintViolationsAdminView, SpecialAttentionAKsAdminView, InterestEnteringAdminView, WishSlotCleanupView ConstraintViolationsAdminView, SpecialAttentionAKsAdminView, InterestEnteringAdminView, WishSlotCleanupView, \
AvailabilityAutocreateView
def get_admin_urls_scheduling(admin_site): def get_admin_urls_scheduling(admin_site):
...@@ -16,6 +17,8 @@ def get_admin_urls_scheduling(admin_site): ...@@ -16,6 +17,8 @@ def get_admin_urls_scheduling(admin_site):
name="special-attention"), name="special-attention"),
path('<slug:event_slug>/cleanup-wish-slots/', admin_site.admin_view(WishSlotCleanupView.as_view()), path('<slug:event_slug>/cleanup-wish-slots/', admin_site.admin_view(WishSlotCleanupView.as_view()),
name="cleanup-wish-slots"), name="cleanup-wish-slots"),
path('<slug:event_slug>/autocreate-availabilities/', admin_site.admin_view(AvailabilityAutocreateView.as_view()),
name="autocreate-availabilities"),
path('<slug:event_slug>/tracks/', admin_site.admin_view(TrackAdminView.as_view()), path('<slug:event_slug>/tracks/', admin_site.admin_view(TrackAdminView.as_view()),
name="tracks_manage"), name="tracks_manage"),
path('<slug:event_slug>/enter-interest/<int:pk>', admin_site.admin_view(InterestEnteringAdminView.as_view()), path('<slug:event_slug>/enter-interest/<int:pk>', admin_site.admin_view(InterestEnteringAdminView.as_view()),
......
...@@ -160,6 +160,7 @@ class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMi ...@@ -160,6 +160,7 @@ class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMi
class WishSlotCleanupView(EventSlugMixin, IntermediateAdminView): class WishSlotCleanupView(EventSlugMixin, IntermediateAdminView):
title = _('Cleanup: Delete unscheduled slots for wishes') title = _('Cleanup: Delete unscheduled slots for wishes')
def get_success_url(self): def get_success_url(self):
return reverse_lazy('admin:special-attention', kwargs={'slug': self.event.slug}) return reverse_lazy('admin:special-attention', kwargs={'slug': self.event.slug})
...@@ -174,3 +175,39 @@ class WishSlotCleanupView(EventSlugMixin, IntermediateAdminView): ...@@ -174,3 +175,39 @@ class WishSlotCleanupView(EventSlugMixin, IntermediateAdminView):
self.event.get_unscheduled_wish_slots().delete() self.event.get_unscheduled_wish_slots().delete()
messages.add_message(self.request, messages.SUCCESS, _("Unscheduled slots for wishes successfully deleted")) messages.add_message(self.request, messages.SUCCESS, _("Unscheduled slots for wishes successfully deleted"))
return super().form_valid(form) return super().form_valid(form)
class AvailabilityAutocreateView(EventSlugMixin, IntermediateAdminView):
title = _('Create default availabilities for AKs')
def get_success_url(self):
return reverse_lazy('admin:special-attention', kwargs={'slug': self.event.slug})
def get_preview(self):
aks = self.event.get_aks_without_availabilities()
return _("The following {count} AKs don't have any availability information. "
"Create default availability for them:\n\n {aks}").format(
count=len(aks),
aks=", ".join(str(ak) for ak in aks)
)
def form_valid(self, form):
from AKModel.availability.models import Availability
success_count = 0
for ak in self.event.get_aks_without_availabilities():
try:
availability = Availability.with_event_length(event=self.event, ak=ak)
availability.save()
success_count += 1
except:
messages.add_message(
self.request, messages.WARNING,
_("Could not create default availabilities for AK: {ak}").format(ak=ak)
)
messages.add_message(
self.request, messages.SUCCESS,
_("Created default availabilities for {count} AKs").format(count=success_count)
)
return super().form_valid(form)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment