Statistics on sold and unsold seats, as well as potential profi… (#1613)

* Statistics on sold and unsold seats, as well as potential profits

* Rework of seats-stats

* Fix crash when all seats are assigned

* Update src/pretix/plugins/statistics/views.py

Co-Authored-By: Raphael Michel <michel@rami.io>

* Update src/pretix/plugins/statistics/views.py

Co-Authored-By: Raphael Michel <michel@rami.io>

* Update src/pretix/plugins/statistics/views.py

Co-Authored-By: Raphael Michel <michel@rami.io>

* Fix count of sold seats

Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
Martin Gross
2020-03-16 15:20:30 +01:00
committed by GitHub
parent bd238f76ce
commit f00012a63e
3 changed files with 156 additions and 5 deletions

View File

@@ -1,9 +1,10 @@
import datetime
import json
from decimal import Decimal
import dateutil.parser
import dateutil.rrule
from django.db.models import Count, DateTimeField, Max, OuterRef, Subquery
from django.db.models import Count, DateTimeField, Max, Min, OuterRef, Subquery
from django.utils import timezone
from django.views.generic import TemplateView
@@ -162,4 +163,56 @@ class IndexView(EventPermissionRequiredMixin, ChartContainingView, TemplateView)
ctx['has_orders'] = self.request.event.orders.exists()
ctx['seats'] = {}
if not self.request.event.has_subevents or (ckey != "all" and subevent):
ev = subevent or self.request.event
if ev.seating_plan_id is not None:
seats_qs = ev.free_seats(sales_channel=None, include_blocked=True)
ctx['seats']['blocked_seats'] = seats_qs.filter(blocked=True).count()
ctx['seats']['free_seats'] = seats_qs.filter(blocked=False).count()
ctx['seats']['purchased_seats'] = \
ev.seats.count() - ctx['seats']['blocked_seats'] - ctx['seats']['free_seats']
seats_qs = seats_qs.values('product', 'blocked').annotate(count=Count('id'))\
.order_by('product__category__position', 'product__position', 'product', 'blocked')
ctx['seats']['products'] = {}
ctx['seats']['stats'] = {}
item_cache = {i.pk: i for i in
ev.items.annotate(has_variations=Count('variations')).filter(
pk__in={p['product'] for p in seats_qs if p['product']}
)}
item_cache[None] = None
for item in seats_qs:
if item_cache[item['product']] not in ctx['seats']['products']:
product = item_cache[item['product']]
if product and product.has_variations:
price = product.variations.aggregate(Min('default_price'))['default_price__min']
elif product:
price = product.default_price
else:
price = Decimal('0.00')
ctx['seats']['products'][product] = {
'free': {
'seats': 0,
'potential': Decimal('0.00'),
},
'blocked': {
'seats': 0,
'potential': Decimal('0.00'),
},
'price': price,
}
data = ctx['seats']['products'][product]
if item['blocked']:
data['blocked']['seats'] = item['count']
data['blocked']['potential'] = item['count'] * data['price']
else:
data['free']['seats'] = item['count']
data['free']['potential'] = item['count'] * data['price']
return ctx