diff --git a/.gitattributes b/.gitattributes
index 185b40aef..30ebb98eb 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,3 +3,4 @@ src/static/lightbox/* linguist-vendored
src/static/typeahead/* linguist-vendored
src/static/moment/* linguist-vendored
src/static/datetimepicker/* linguist-vendored
+src/static/charts/* linguist-vendored
diff --git a/src/pretix/control/templates/pretixcontrol/base.html b/src/pretix/control/templates/pretixcontrol/base.html
index 21ee7b563..58368abbc 100644
--- a/src/pretix/control/templates/pretixcontrol/base.html
+++ b/src/pretix/control/templates/pretixcontrol/base.html
@@ -17,9 +17,12 @@
+
+
+
{% endcompress %}
{{ html_head|safe }}
diff --git a/src/pretix/control/templates/pretixcontrol/items/quota.html b/src/pretix/control/templates/pretixcontrol/items/quota.html
index 8edac0886..dba341fc4 100644
--- a/src/pretix/control/templates/pretixcontrol/items/quota.html
+++ b/src/pretix/control/templates/pretixcontrol/items/quota.html
@@ -46,9 +46,13 @@
{% if quota.pk and quota.size != None %}
-
+
+
{% endif %}
diff --git a/src/pretix/control/views/__init__.py b/src/pretix/control/views/__init__.py
index c6a463ed2..c8e063b5f 100644
--- a/src/pretix/control/views/__init__.py
+++ b/src/pretix/control/views/__init__.py
@@ -26,3 +26,12 @@ class UpdateView(EventBasedFormMixin, edit.UpdateView):
properly.
"""
pass
+
+
+class ChartContainingView:
+
+ def get(self, request, *args, **kwargs):
+ resp = super().get(request, *args, **kwargs)
+ # required by raphael.js
+ resp['Content-Security-Policy'] = "script-src {static} 'unsafe-eval'; style-src {static} 'unsafe-inline'"
+ return resp
diff --git a/src/pretix/control/views/item.py b/src/pretix/control/views/item.py
index d817c7e6f..380d81c39 100644
--- a/src/pretix/control/views/item.py
+++ b/src/pretix/control/views/item.py
@@ -1,3 +1,5 @@
+import json
+
from django.contrib import messages
from django.core.files import File
from django.core.urlresolvers import resolve, reverse
@@ -6,7 +8,7 @@ from django.forms.models import ModelMultipleChoiceField, inlineformset_factory
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.utils.functional import cached_property
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext, ugettext_lazy as _
from django.views.generic import ListView
from django.views.generic.base import TemplateView
from django.views.generic.detail import SingleObjectMixin
@@ -24,7 +26,7 @@ from pretix.control.permissions import (
EventPermissionRequiredMixin, event_permission_required,
)
-from . import CreateView, UpdateView
+from . import ChartContainingView, CreateView, UpdateView
class ItemList(ListView):
@@ -525,13 +527,39 @@ class QuotaCreate(EventPermissionRequiredMixin, QuotaEditorMixin, CreateView):
return ret
-class QuotaUpdate(EventPermissionRequiredMixin, QuotaEditorMixin, UpdateView):
+class QuotaUpdate(EventPermissionRequiredMixin, QuotaEditorMixin, ChartContainingView, UpdateView):
model = Quota
form_class = QuotaForm
template_name = 'pretixcontrol/items/quota.html'
permission = 'can_change_items'
context_object_name = 'quota'
+ def get_context_data(self, *args, **kwargs):
+ ctx = super().get_context_data()
+ ctx['quota_chart_data'] = json.dumps([
+ {
+ 'label': ugettext('Paid orders'),
+ 'value': self.object.count_paid_orders()
+ },
+ {
+ 'label': ugettext('Pending orders'),
+ 'value': self.object.count_pending_orders()
+ },
+ {
+ 'label': ugettext('Vouchers'),
+ 'value': self.object.count_blocking_vouchers()
+ },
+ {
+ 'label': ugettext('Current user\'s carts'),
+ 'value': self.object.count_in_cart()
+ },
+ {
+ 'label': ugettext('Current availability'),
+ 'value': self.object.availability()[1]
+ }
+ ])
+ return ctx
+
def get_object(self, queryset=None) -> Quota:
try:
return self.request.event.quotas.get(
diff --git a/src/pretix/plugins/statistics/signals.py b/src/pretix/plugins/statistics/signals.py
index d420781f8..0ddaed768 100644
--- a/src/pretix/plugins/statistics/signals.py
+++ b/src/pretix/plugins/statistics/signals.py
@@ -1,11 +1,9 @@
from django.core.urlresolvers import resolve, reverse
from django.dispatch import receiver
-from django.template import Context
-from django.template.loader import get_template
from django.utils.translation import ugettext_lazy as _
from pretix.base.signals import order_paid, order_placed
-from pretix.control.signals import html_head, nav_event
+from pretix.control.signals import nav_event
@receiver(nav_event, dispatch_uid="statistics_nav")
@@ -26,17 +24,6 @@ def control_nav_import(sender, request=None, **kwargs):
]
-@receiver(html_head, dispatch_uid="statistics_html_head")
-def html_head_presale(sender, request=None, **kwargs):
- url = resolve(request.path_info)
- if url.namespace == 'plugins:statistics':
- template = get_template('pretixplugins/statistics/control_head.html')
- ctx = Context({})
- return template.render(ctx)
- else:
- return ""
-
-
def clear_cache(sender, *args, **kwargs):
cache = sender.get_cache()
cache.delete('statistics_obd_data')
diff --git a/src/pretix/plugins/statistics/templates/pretixplugins/statistics/control_head.html b/src/pretix/plugins/statistics/templates/pretixplugins/statistics/control_head.html
deleted file mode 100644
index 4e3b76164..000000000
--- a/src/pretix/plugins/statistics/templates/pretixplugins/statistics/control_head.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% load staticfiles %}
-{% load compress %}
-
-{% compress css %}
-
-{% endcompress %}
-
-
diff --git a/src/pretix/plugins/statistics/views.py b/src/pretix/plugins/statistics/views.py
index e5d678405..d1382f1fa 100644
--- a/src/pretix/plugins/statistics/views.py
+++ b/src/pretix/plugins/statistics/views.py
@@ -9,19 +9,14 @@ from django.views.generic import TemplateView
from pretix.base.models import Item, Order, OrderPosition
from pretix.control.permissions import EventPermissionRequiredMixin
+from pretix.control.views import ChartContainingView
from pretix.plugins.statistics.signals import clear_cache
-class IndexView(EventPermissionRequiredMixin, TemplateView):
+class IndexView(EventPermissionRequiredMixin, ChartContainingView, TemplateView):
template_name = 'pretixplugins/statistics/index.html'
permission = 'can_view_orders'
- def get(self, request, *args, **kwargs):
- resp = super().get(request, *args, **kwargs)
- # required by raphael.js
- resp['Content-Security-Policy'] = "script-src {static} 'unsafe-eval'; style-src {static} 'unsafe-inline'"
- return resp
-
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
tz = timezone.get_current_timezone()
diff --git a/src/pretix/plugins/statistics/static/pretixplugins/statistics/morris.css b/src/static/charts/morris.css
similarity index 100%
rename from src/pretix/plugins/statistics/static/pretixplugins/statistics/morris.css
rename to src/static/charts/morris.css
diff --git a/src/pretix/plugins/statistics/static/pretixplugins/statistics/morris.min.js b/src/static/charts/morris.min.js
similarity index 100%
rename from src/pretix/plugins/statistics/static/pretixplugins/statistics/morris.min.js
rename to src/static/charts/morris.min.js
diff --git a/src/pretix/plugins/statistics/static/pretixplugins/statistics/raphael-min.js b/src/static/charts/raphael-min.js
similarity index 100%
rename from src/pretix/plugins/statistics/static/pretixplugins/statistics/raphael-min.js
rename to src/static/charts/raphael-min.js
diff --git a/src/static/pretixcontrol/js/ui/quota.js b/src/static/pretixcontrol/js/ui/quota.js
new file mode 100644
index 000000000..b0860091a
--- /dev/null
+++ b/src/static/pretixcontrol/js/ui/quota.js
@@ -0,0 +1,20 @@
+/*globals $, Morris, gettext*/
+$(function () {
+ if (!$("#quota-stats").length) {
+ return;
+ }
+
+ $(".chart").css("height", "250px");
+ new Morris.Donut({
+ element: 'quota_chart',
+ data: JSON.parse($("#quota-chart-data").html()),
+ resize: true,
+ colors: [
+ '#0044CC', // paid
+ '#0088CC', // pending
+ '#BD362F', // vouchers
+ '#F89406', // carts
+ '#51A351' // available
+ ]
+ });
+});
diff --git a/src/static/pretixcontrol/scss/main.scss b/src/static/pretixcontrol/scss/main.scss
index 55171d513..7a19e8a5f 100644
--- a/src/static/pretixcontrol/scss/main.scss
+++ b/src/static/pretixcontrol/scss/main.scss
@@ -4,6 +4,7 @@ $fa-font-path: static("fontawesome/fonts");
@import "../../fontawesome/scss/font-awesome.scss";
@import "../../typeahead/typeahead.css";
@import "../css/metisMenu.min.css";
+@import "../../charts/morris.css";
@import "../../datetimepicker/_bootstrap-datetimepicker.scss";
@import "_sb-admin-2.scss";
@import "_forms.scss";