-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ [#4930] Add custom admin view for submission export view
- Loading branch information
1 parent
9c6c899
commit e0ff975
Showing
7 changed files
with
244 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
from .form_definition import FormDefinitionForm # noqa | ||
from .form_definition import FormDefinitionForm | ||
from .form_statistics import ExportStatisticsForm | ||
|
||
__all__ = ["FormDefinitionForm", "ExportStatisticsForm"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
from __future__ import annotations | ||
|
||
from datetime import date | ||
|
||
from django import forms | ||
from django.contrib.admin.widgets import AdminDateWidget | ||
from django.utils import timezone | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from dateutil.relativedelta import relativedelta | ||
|
||
from ..models import Form | ||
|
||
|
||
def get_first_of_current_month() -> date: | ||
now = timezone.now() | ||
return now.replace(day=1).date() | ||
|
||
|
||
def get_first_of_next_month() -> date: | ||
now = timezone.now() | ||
one_month_later = now + relativedelta(months=1) | ||
return one_month_later.replace(day=1).date() | ||
|
||
|
||
class ExportStatisticsForm(forms.Form): | ||
start_date = forms.DateField( | ||
label=_("From"), | ||
required=True, | ||
initial=get_first_of_current_month, | ||
help_text=_( | ||
"Export form submission that were submitted on or after this date." | ||
), | ||
widget=AdminDateWidget, | ||
) | ||
end_date = forms.DateField( | ||
label=_("Until"), | ||
required=True, | ||
initial=get_first_of_next_month, | ||
help_text=_("Export form submission that were submitted before this date."), | ||
widget=AdminDateWidget, | ||
) | ||
limit_to_forms = forms.ModelMultipleChoiceField( | ||
label=_("Forms"), | ||
required=False, | ||
queryset=Form.objects.filter(_is_deleted=False), | ||
help_text=_( | ||
"Limit the export to the selected forms, if specified. Leave the field " | ||
"empty to export all forms. Hold CTRL (or COMMAND on Mac) to select " | ||
"multiple options." | ||
), | ||
) |
11 changes: 11 additions & 0 deletions
11
src/openforms/forms/templates/admin/forms/formstatistics/change_list_object_tools.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{% extends "admin/change_list_object_tools.html" %} | ||
{% load i18n %} | ||
|
||
{% block object-tools-items %} | ||
<li> | ||
<a href="{% url 'admin:formstatistics_export' %}" class="viewlink"> | ||
{% trans "Export submission statistics" %} | ||
</a> | ||
</li> | ||
{{ block.super }} | ||
{% endblock %} |
66 changes: 66 additions & 0 deletions
66
src/openforms/forms/templates/admin/forms/formstatistics/export_form.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
{% extends "admin/base_site.html" %} | ||
{% load static i18n django_admin_index %} | ||
|
||
{% block extrahead %}{{ block.super }} | ||
<script src="{% url 'admin:jsi18n' %}"></script> | ||
{{ media }} | ||
{% endblock %} | ||
|
||
{% block extrastyle %}{{ block.super }} | ||
<link rel="stylesheet" href="{% static "admin/css/forms.css" %}"> | ||
<link rel="stylesheet" href="{% static "admin/css/admin-index.css" %}">{% endblock %} | ||
|
||
{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %} | ||
|
||
{% block title %} {% trans "Export submission statistics" %} {{ block.super }} {% endblock %} | ||
|
||
{% block breadcrumbs %} | ||
<div class="breadcrumbs"> | ||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a> | ||
› <a href="{% url 'admin:forms_formstatistics_changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a> | ||
› {% trans 'Export submission statistics' %} | ||
</div> | ||
{% endblock %} | ||
|
||
{% block content %} | ||
<h1>{% trans 'Export submission statistics' %}</h1> | ||
|
||
<div id="content-main"> | ||
<form action="." method="post"> | ||
{% csrf_token %} | ||
|
||
<fieldset class="module aligned"> | ||
<div class="description">{% blocktrans trimmed %} | ||
<p>Here you can create an export of successfully registered form submissions. The | ||
export file contains the following columns: public reference, form name, | ||
form internal name, the submission datetime and the timestamp of registration.</p> | ||
|
||
<p>You can use the filters below to limit the result set in the export.</p> | ||
{% endblocktrans %}</div> | ||
|
||
{# TODO: doesn't handle checkboxes, see admin/includes/fieldset.html for when this is necessary #} | ||
{% for field in form_fields %} | ||
<div class="form-row {% if field.errors %}errors{% endif %}"> | ||
{{ field.errors }} | ||
<div> | ||
<div class="flex-container {% if field.errors %}errors{% endif %}"> | ||
{{ field.label_tag }} | ||
{{ field.field }} | ||
</div> | ||
</div> | ||
|
||
{% if field.field.help_text %} | ||
<div class="help" {% if field.field.id_for_label %} id="{{ field.field.id_for_label }}_helptext"{% endif %}> | ||
<div>{{ field.field.help_text|safe }}</div> | ||
</div> | ||
{% endif %} | ||
</div> | ||
{% endfor %} | ||
</fieldset> | ||
|
||
<div class="submit-row"> | ||
<input type="submit" class="default" value="{% trans 'Export' %}"> | ||
</div> | ||
</form> | ||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from django.urls import reverse, reverse_lazy | ||
from django.utils.translation import gettext as _ | ||
|
||
from django_webtest import WebTest | ||
from maykin_2fa.test import disable_admin_mfa | ||
|
||
from openforms.accounts.tests.factories import UserFactory | ||
|
||
|
||
@disable_admin_mfa() | ||
class FormStatisticsExportAdminTests(WebTest): | ||
|
||
admin_url = reverse_lazy("admin:formstatistics_export") | ||
|
||
def test_access_control_no_access(self): | ||
# various flavours of users do not have access, only if the right permissions | ||
# are set are you allowed in | ||
invalid_users = ( | ||
( | ||
"plain user", | ||
UserFactory.create(), | ||
302, | ||
), | ||
( | ||
"staff user without perms", | ||
UserFactory.create(is_staff=True), | ||
403, | ||
), | ||
( | ||
"user with perms no staff", | ||
UserFactory.create( | ||
is_staff=False, user_permissions=["forms.view_formstatistics"] | ||
), | ||
302, | ||
), | ||
) | ||
|
||
for label, user, expected_status in invalid_users: | ||
with self.subTest(label, expected_status=expected_status): | ||
response = self.app.get( | ||
self.admin_url, | ||
user=user, | ||
auto_follow=False, | ||
status=expected_status, | ||
) | ||
|
||
self.assertEqual(response.status_code, expected_status) | ||
|
||
def test_navigate_from_changelist(self): | ||
user = UserFactory.create( | ||
is_staff=True, user_permissions=["forms.view_formstatistics"] | ||
) | ||
changelist = self.app.get( | ||
reverse("admin:forms_formstatistics_changelist"), user=user | ||
) | ||
|
||
export_page = changelist.click(_("Export submission statistics")) | ||
|
||
self.assertEqual(export_page.request.path, self.admin_url) |