Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Updated stats with additional data as requested in #56777 #159

Merged
merged 5 commits into from

2 participants

@elbaschid

I added the following stats:

  • signed up users (total & last 24hrs)
  • number of promotions
  • number of open baskets (total & last 24hrs)

I am not completely sure if the grouping and the group titles are appropriate. Please check if these should be changed.

Sebastian Ve... added some commits
Sebastian Vetter removed filter from dashboard index a10a4c4
Sebastian Vetter Merge remote-tracking branch 'upstream/master'
Conflicts:
	oscar/apps/dashboard/views.py
	oscar/templates/dashboard/index.html
3b2d57b
Sebastian Vetter added additional stats to dashboard (#56777) d05877d
Sebastian Vetter added additional stats to dashboard (#56777) 520283f
Sebastian Vetter fixed minor issue with query in dashboard view ab64473
@codeinthehole codeinthehole merged commit 7954d21 into django-oscar:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 30, 2012
  1. removed filter from dashboard index

    Sebastian Vetter authored
  2. Merge remote-tracking branch 'upstream/master'

    Sebastian Vetter authored
    Conflicts:
    	oscar/apps/dashboard/views.py
    	oscar/templates/dashboard/index.html
Commits on May 1, 2012
  1. added additional stats to dashboard (#56777)

    Sebastian Vetter authored
  2. added additional stats to dashboard (#56777)

    Sebastian Vetter authored
  3. fixed minor issue with query in dashboard view

    Sebastian Vetter authored
This page is out of date. Refresh to see the latest.
Showing with 92 additions and 22 deletions.
  1. +48 −7 oscar/apps/dashboard/views.py
  2. +44 −15 oscar/templates/dashboard/index.html
View
55 oscar/apps/dashboard/views.py
@@ -4,10 +4,15 @@
from django.views.generic import TemplateView
from django.db.models.loading import get_model
from django.db.models import Avg, Sum, Count
+from django.contrib.auth.models import User
+from oscar.apps.basket.abstract_models import OPEN as basket_OPEN
from oscar.apps.offer.models import SITE
+from oscar.apps.promotions.models import AbstractPromotion
+
ConditionalOffer = get_model('offer', 'ConditionalOffer')
Voucher = get_model('voucher', 'Voucher')
+Basket = get_model('basket', 'Basket')
StockAlert = get_model('partner', 'StockAlert')
Product = get_model('catalogue', 'Product')
Order = get_model('order', 'Order')
@@ -25,7 +30,7 @@ def get_context_data(self, **kwargs):
def get_active_site_offers(self):
"""
Return active conditional offers of type "site offer". The returned
- ``Queryset`` of site offers is filtered by end date greater then
+ ``Queryset`` of site offers is filtered by end date greater then
the current date.
"""
return ConditionalOffer.objects.filter(end_date__gt=datetime.now(),
@@ -33,15 +38,40 @@ def get_active_site_offers(self):
def get_active_vouchers(self):
"""
- Get all active vouchers. The returned ``Queryset`` of vouchers
+ Get all active vouchers. The returned ``Queryset`` of vouchers
is filtered by end date greater then the current date.
"""
return Voucher.objects.filter(end_date__gt=datetime.now())
+ def get_number_of_promotions(self, abstract_base=AbstractPromotion):
+ """
+ Get the number of promotions for all promotions derived from
+ *abstract_base*. All subclasses of *abstract_base* are queried
+ and if another abstract base class is found this method is executed
+ recursively.
+ """
+ total = 0
+ for cls in abstract_base.__subclasses__():
+ if cls._meta.abstract:
+ total += self.get_number_of_promotions(cls)
+ else:
+ total += cls.objects.count()
+ return total
+
+ def get_open_baskets(self, filters=None):
+ """
+ Get all open baskets. If *filters* dictionary is provided they will
+ be applied on all open baskets and return only filtered results.
+ """
+ if filters is None:
+ filters = {}
+ filters['status'] = basket_OPEN
+ return Basket.objects.filter(**filters)
+
def get_hourly_report(self, hours=24, segments=10):
"""
Get report of order revenue split up in hourly chunks. A report is
- generated for the last *hours* (default=24) from the current time.
+ generated for the last *hours* (default=24) from the current time.
The report provides ``max_revenue`` of the hourly order revenue sum,
``y-range`` as the labeling for the y-axis in a template and
``order_total_hourly``, a list of properties for hourly chunks.
@@ -95,10 +125,10 @@ def get_hourly_report(self, hours=24, segments=10):
}
def get_stats(self):
- orders = Order.objects.filter()
+ datetime_24hrs_ago = datetime.now() - timedelta(hours=24)
- date_24hrs_ago = datetime.now() - timedelta(hours=24)
- orders_last_day = Order.objects.filter(date_placed__gt=date_24hrs_ago)
+ orders = Order.objects.filter()
+ orders_last_day = orders.filter(date_placed__gt=datetime_24hrs_ago)
open_alerts = StockAlert.objects.filter(status=StockAlert.OPEN)
closed_alerts = StockAlert.objects.filter(status=StockAlert.CLOSED)
@@ -119,15 +149,26 @@ def get_stats(self):
)['total_incl_tax__sum'] or D('0.00'),
'hourly_report_dict': self.get_hourly_report(hours=24),
+ 'total_customers_last_day': User.objects.filter(
+ date_joined__gt=datetime_24hrs_ago,
+ ).count(),
+
+ 'total_open_baskets_last_day': self.get_open_baskets({
+ 'date_created__gt': datetime_24hrs_ago
+ }).count(),
+
'total_products': Product.objects.count(),
'total_open_stock_alerts': open_alerts.count(),
'total_closed_stock_alerts': closed_alerts.count(),
+
'total_site_offers': self.get_active_site_offers().count(),
'total_vouchers': self.get_active_vouchers().count(),
+ 'total_promotions': self.get_number_of_promotions(),
+ 'total_customers': User.objects.count(),
+ 'total_open_baskets': self.get_open_baskets().count(),
'total_orders': orders.count(),
'total_lines': Line.objects.filter(order__in=orders).count(),
-
'total_revenue': orders.aggregate(
Sum('total_incl_tax')
)['total_incl_tax__sum'] or D('0.00'),
View
59 oscar/templates/dashboard/index.html
@@ -71,7 +71,21 @@
<td class="span2" >{{ average_order_costs|currency }}</td>
</tr>
</table>
- </div>
+ </div>
+
+ <div class="span6">
+ <table class="table table-striped table-bordered">
+ <caption>Customers</caption>
+ <tr>
+ <th class="span10">New customers</th>
+ <td class="span2" >{{ total_customers_last_day }}</td>
+ </tr>
+ <tr>
+ <th class="span10">Total <em>open</em> baskets</th>
+ <td class="span2" >{{ total_open_baskets_last_day }}</td>
+ </tr>
+ </table>
+ </div>
</div>
<div class="sub-header">
@@ -81,21 +95,33 @@
<div class='row-fluid'>
<div class="span6">
<table class="table table-striped table-bordered">
- <caption>Orders</caption>
- <tr>
- <th class="span10">Total orders</th>
- <td class="span2" >{{ total_orders }}</td>
- </tr>
- <tr>
- <th class="span10">Total lines</th>
- <td class="span2" >{{ total_lines }}</td>
- </tr>
- <tr>
- <th class="span10">Total revenue</th>
- <td class="span2" >{{ total_revenue|currency }}</td>
- </tr>
+ <caption>Orders</caption>
+ <tr>
+ <th class="span10">Total orders</th>
+ <td class="span2" >{{ total_orders }}</td>
+ </tr>
+ <tr>
+ <th class="span10">Total lines</th>
+ <td class="span2" >{{ total_lines }}</td>
+ </tr>
+ <tr>
+ <th class="span10">Total revenue</th>
+ <td class="span2" >{{ total_revenue|currency }}</td>
+ </tr>
+ <tr>
+ <th class="span10">Total <em>open</em> baskets</th>
+ <td class="span2" >{{ total_open_baskets }}</td>
+ </tr>
</table>
<p><a href="{% url dashboard:order-list %}" class="btn">Manage orders</a></p>
+
+ <table class="table table-striped table-bordered">
+ <caption>Customers</caption>
+ <tr>
+ <th class="span10">Total customers</th>
+ <td class="span2" >{{ total_customers }}</td>
+ </tr>
+ </table>
</div>
<div class="span6">
@@ -118,7 +144,7 @@
<a href="{% url dashboard:stock-alert-list %}" class="btn">View stock alerts</a></p>
<table class="table table-striped table-bordered">
- <caption>Offers and vouchers</caption>
+ <caption>Offers, vouchers and promotions</caption>
<tr>
<th class="span10">Active <em>Site</em> Offers</th>
<td class="span2" >{{ total_site_offers }}</td>
@@ -127,6 +153,9 @@
<th class="span10">Active <em>Vouchers</em></th>
<td class="span2" >{{ total_vouchers }}</td>
</tr>
+ <th class="span10">Promotions</em></th>
+ <td class="span2" >{{ total_promotions }}</td>
+ </tr>
</table>
</div>
</div>
Something went wrong with that request. Please try again.