From 79ddcc1cdf939acb21bb336d1f4b1c0afe10eaf2 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Sat, 11 Jul 2020 21:50:34 +0200 Subject: [PATCH] Add views for managing excuse types --- aleksis/apps/alsijil/forms.py | 10 +++- aleksis/apps/alsijil/menus.py | 6 +++ aleksis/apps/alsijil/tables.py | 20 +++++++ .../templates/alsijil/excuse_type/create.html | 18 +++++++ .../templates/alsijil/excuse_type/edit.html | 17 ++++++ .../templates/alsijil/excuse_type/list.html | 20 +++++++ .../alsijil/excuse_type/warning.html | 10 ++++ aleksis/apps/alsijil/urls.py | 16 ++++++ aleksis/apps/alsijil/views.py | 53 +++++++++++++++++-- 9 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html create mode 100644 aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html create mode 100644 aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html create mode 100644 aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html diff --git a/aleksis/apps/alsijil/forms.py b/aleksis/apps/alsijil/forms.py index 3d7f554eb..99954b530 100644 --- a/aleksis/apps/alsijil/forms.py +++ b/aleksis/apps/alsijil/forms.py @@ -11,7 +11,7 @@ from material import Layout, Row from aleksis.apps.chronos.managers import TimetableType from aleksis.core.models import Group, Person -from .models import LessonDocumentation, PersonalNote, PersonalNoteFilter +from .models import ExcuseType, LessonDocumentation, PersonalNote, PersonalNoteFilter class LessonDocumentationForm(forms.ModelForm): @@ -116,3 +116,11 @@ class PersonalNoteFilterForm(forms.ModelForm): class Meta: model = PersonalNoteFilter fields = ["identifier", "description", "regex"] + + +class ExcuseTypeForm(forms.ModelForm): + layout = Layout("short_name", "name") + + class Meta: + model = ExcuseType + fields = ["short_name", "name"] diff --git a/aleksis/apps/alsijil/menus.py b/aleksis/apps/alsijil/menus.py index 2b84cb6f7..c5fea59e3 100644 --- a/aleksis/apps/alsijil/menus.py +++ b/aleksis/apps/alsijil/menus.py @@ -36,6 +36,12 @@ MENUS = { "icon": "filter_list", "validators": ["menu_generator.validators.is_superuser"], }, + { + "name": _("Excuse types"), + "url": "excuse_types", + "icon": "label", + "validators": ["menu_generator.validators.is_superuser"], + }, ], } ] diff --git a/aleksis/apps/alsijil/tables.py b/aleksis/apps/alsijil/tables.py index bad0dc9f3..3a6762c37 100644 --- a/aleksis/apps/alsijil/tables.py +++ b/aleksis/apps/alsijil/tables.py @@ -17,3 +17,23 @@ class PersonalNoteFilterTable(tables.Table): text=_("Edit"), attrs={"a": {"class": "btn-flat waves-effect waves-orange"}}, ) + + +class ExcuseTypeTable(tables.Table): + class Meta: + attrs = {"class": "highlight"} + + name = tables.LinkColumn("edit_excuse_type", args=[A("id")]) + short_name = tables.Column() + edit = tables.LinkColumn( + "edit_excuse_type", + args=[A("id")], + text=_("Edit"), + attrs={"a": {"class": "btn-flat waves-effect waves-orange orange-text"}}, + ) + delete = tables.LinkColumn( + "delete_excuse_type", + args=[A("id")], + text=_("Delete"), + attrs={"a": {"class": "btn-flat waves-effect waves-red red-text"}}, + ) diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html new file mode 100644 index 000000000..6fc6faefb --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html @@ -0,0 +1,18 @@ +{# -*- engine:django -*- #} + +{% extends "core/base.html" %} +{% load material_form i18n %} + +{% block browser_title %}{% blocktrans %}Create excuse type{% endblocktrans %}{% endblock %} +{% block page_title %}{% blocktrans %}Create excuse type{% endblocktrans %}{% endblock %} + +{% block content %} + {% include "alsijil/excuse_type/warning.html" %} + + <form method="post"> + {% csrf_token %} + {% form form=form %}{% endform %} + {% include "core/partials/save_button.html" %} + </form> + +{% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html new file mode 100644 index 000000000..78396ed66 --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html @@ -0,0 +1,17 @@ +{# -*- engine:django -*- #} + +{% extends "core/base.html" %} +{% load material_form i18n %} + +{% block browser_title %}{% blocktrans %}Edit excuse type{% endblocktrans %}{% endblock %} +{% block page_title %}{% blocktrans %}Edit excuse type{% endblocktrans %}{% endblock %} + +{% block content %} + + <form method="post"> + {% csrf_token %} + {% form form=form %}{% endform %} + {% include "core/partials/save_button.html" %} + </form> + +{% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html new file mode 100644 index 000000000..2be1f28c9 --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html @@ -0,0 +1,20 @@ +{# -*- engine:django -*- #} + +{% extends "core/base.html" %} + +{% load i18n %} +{% load render_table from django_tables2 %} + +{% block browser_title %}{% blocktrans %}Excuse types{% endblocktrans %}{% endblock %} +{% block page_title %}{% blocktrans %}Excuse types{% endblocktrans %}{% endblock %} + +{% block content %} + {% include "alsijil/excuse_type/warning.html" %} + + <a class="btn green waves-effect waves-light" href="{% url 'create_excuse_type' %}"> + <i class="material-icons left">add</i> + {% trans "Create excuse type" %} + </a> + + {% render_table table %} +{% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html new file mode 100644 index 000000000..d90d2e820 --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html @@ -0,0 +1,10 @@ +{% load i18n %} +<div class="alert warning"> + <p> + <i class="material-icons left">warning</i> + {% blocktrans %} + This function should only be used to define alternatives to the default excuse which also will be counted extra. + Don't use this to create a default excuse or if you don't divide between different types of excuse. + {% endblocktrans %} + </p> +</div> diff --git a/aleksis/apps/alsijil/urls.py b/aleksis/apps/alsijil/urls.py index 4406a0685..89ab0ffe5 100644 --- a/aleksis/apps/alsijil/urls.py +++ b/aleksis/apps/alsijil/urls.py @@ -41,4 +41,20 @@ urlpatterns = [ views.delete_personal_note_filter, name="delete_personal_note_filter", ), + path("excuse_types/", views.ExcuseTypeListView.as_view(), name="excuse_types"), + path( + "excuse_types/create/", + views.ExcuseTypeCreateView.as_view(), + name="create_excuse_type", + ), + path( + "excuse_types/<int:pk>/edit/", + views.ExcuseTypeEditView.as_view(), + name="edit_excuse_type", + ), + path( + "excuse_types/<int:pk>/delete/", + views.ExcuseTypeDeleteView.as_view(), + name="delete_excuse_type", + ), ] diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 8fa58f62a..25868ba0d 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -5,27 +5,31 @@ from django.core.exceptions import PermissionDenied from django.db.models import Count, Exists, F, OuterRef, Q, Subquery, Sum from django.http import Http404, HttpRequest, HttpResponse, HttpResponseNotFound from django.shortcuts import get_object_or_404, redirect, render -from django.urls import reverse +from django.urls import reverse, reverse_lazy from django.utils.translation import ugettext as _ from calendarweek import CalendarWeek -from django_tables2 import RequestConfig +from django_tables2 import RequestConfig, SingleTableView +from reversion.views import RevisionMixin +from rules.contrib.views import PermissionRequiredMixin from aleksis.apps.chronos.managers import TimetableType from aleksis.apps.chronos.models import LessonPeriod from aleksis.apps.chronos.util.chronos_helpers import get_el_by_pk +from aleksis.core.mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView from aleksis.core.models import Group, Person, SchoolTerm from aleksis.core.util import messages from .forms import ( + ExcuseTypeForm, LessonDocumentationForm, PersonalNoteFilterForm, PersonalNoteFormSet, RegisterAbsenceForm, SelectForm, ) -from .models import LessonDocumentation, PersonalNoteFilter -from .tables import PersonalNoteFilterTable +from .models import ExcuseType, LessonDocumentation, PersonalNoteFilter +from .tables import ExcuseTypeTable, PersonalNoteFilterTable def lesson( @@ -413,3 +417,44 @@ def delete_personal_note_filter(request: HttpRequest, id_: int) -> HttpResponse: context["personal_note_filter"] = personal_note_filter return redirect("list_personal_note_filters") + + +class ExcuseTypeListView(SingleTableView, PermissionRequiredMixin): + """Table of all excuse types.""" + + model = ExcuseType + table_class = ExcuseTypeTable + permission_required = "core.view_excusetype" + template_name = "alsijil/excuse_type/list.html" + + +class ExcuseTypeCreateView(AdvancedCreateView, PermissionRequiredMixin): + """Create view for excuse types.""" + + model = ExcuseType + form_class = ExcuseTypeForm + permission_required = "core.create_excusetype" + template_name = "alsijil/excuse_type/create.html" + success_url = reverse_lazy("excuse_types") + success_message = _("The excuse type has been created.") + + +class ExcuseTypeEditView(AdvancedEditView, PermissionRequiredMixin): + """Edit view for excuse types.""" + + model = ExcuseType + form_class = ExcuseTypeForm + permission_required = "core.edit_excusetype" + template_name = "alsijil/excuse_type/edit.html" + success_url = reverse_lazy("excuse_types") + success_message = _("The excuse type has been saved.") + + +class ExcuseTypeDeleteView(AdvancedDeleteView, PermissionRequiredMixin, RevisionMixin): + """Delete view for excuse types""" + + model = ExcuseType + permission_required = "core.delete_excusetype" + template_name = "core/pages/delete.html" + success_url = reverse_lazy("excuse_types") + success_message = _("The excuse type has been deleted.") -- GitLab