Clean Article stats

kfet.statistic
- delete no longer used defs
- new mixin - ScaleMixin
  - get scale args from GET params
  - chunkify querysets according to a scale

Article stats
- use SingleResumeStat for manifest
- use ScaleMixin for sales
- update urls
- update permission required: teamkfet

Account stats
- update permission required: teamkfet
- operations use ScaleMixin
- fix manifests urls
This commit is contained in:
Aurélien Delobelle 2017-04-03 03:12:52 +02:00
parent f585247224
commit c01de558e1
5 changed files with 132 additions and 221 deletions

View file

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
import ast
from dateutil.relativedelta import relativedelta
from django.utils import timezone
@ -50,7 +52,7 @@ class StatScale(object):
for cls in StatScale.__subclasses__():
if cls.name == name:
return cls
raise Exception('scale %s not found' % name)
return None
def get_from(self, dt):
return self.std_chunk and self.get_chunk_start(dt) or dt
@ -114,32 +116,38 @@ class MonthStatScale(StatScale):
return to_kfet_day(dt).replace(day=1)
def this_first_month_day():
now = timezone.now()
first_day = timezone.datetime(year=now.year,
month=now.month,
day=1,
hour=KFET_WAKES_UP_AT)
return first_day
def stat_manifest(scales_def=None, scale_args=None, **url_params):
if scales_def is None:
scales_def = []
if scale_args is None:
scale_args = {}
return [
dict(
label=label,
url_params=dict(
scale=cls.name,
scale_args=scale_args,
**url_params,
),
)
for label, cls in scales_def
]
def this_monday_morning():
now = timezone.now()
monday = now - timezone.timedelta(days=now.isoweekday()-1)
monday_morning = timezone.datetime(year=monday.year,
month=monday.month,
day=monday.day,
hour=KFET_WAKES_UP_AT)
return monday_morning
def this_morning():
now = timezone.now()
morning = timezone.datetime(year=now.year,
month=now.month,
day=now.day,
hour=KFET_WAKES_UP_AT)
return morning
def last_stats_manifest(scales_def=None, scale_args=None, **url_params):
scales_def = [
('Derniers mois', MonthStatScale, ),
('Dernières semaines', WeekStatScale, ),
('Derniers jours', DayStatScale, ),
]
if scale_args is None:
scale_args = {}
scale_args.update(dict(
last=True,
n_steps=7,
))
return stat_manifest(scales_def=scales_def, scale_args=scale_args,
**url_params)
# Étant donné un queryset d'operations
@ -147,3 +155,38 @@ def this_morning():
def tot_ventes(queryset):
res = queryset.aggregate(Sum('article_nb'))['article_nb__sum']
return res and res or 0
class ScaleMixin(object):
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
scale_name = self.request.GET.get('scale', None)
scale_args = self.request.GET.get('scale_args', None)
cls = StatScale.by_name(scale_name)
if cls is None:
scale = self.get_default_scale()
else:
scale_args = self.request.GET.get('scale_args', {})
if isinstance(scale_args, str):
scale_args = ast.literal_eval(scale_args)
scale = cls(**scale_args)
self.scale = scale
context['labels'] = scale.get_labels()
return context
def get_default_scale(self):
return DayStatScale(n_steps=7, last=True)
def chunkify_qs(self, qs, scale, field=None):
if field is None:
field = 'at'
begin_f = '{}__gte'.format(field)
end_f = '{}__lte'.format(field)
return [
qs.filter(**{begin_f: begin, end_f: end})
for begin, end in scale
]