diff --git a/kfet/statistic.py b/kfet/statistic.py index 02171267..f308011e 100644 --- a/kfet/statistic.py +++ b/kfet/statistic.py @@ -10,12 +10,16 @@ KFET_WAKES_UP_AT = time(7, 0) def kfet_day(year, month, day, start_at=KFET_WAKES_UP_AT): - """datetime wrapper with time offset.""" + """Étant donné une date, renvoie un objet `datetime` + correspondant au début du 'jour K-Fêt' correspondant.""" naive = datetime.combine(date(year, month, day), start_at) return pytz.timezone("Europe/Paris").localize(naive, is_dst=None) def to_kfet_day(dt, start_at=KFET_WAKES_UP_AT): + """ + Retourne le 'jour K-Fêt' correspondant à un objet `datetime` donné + """ kfet_dt = kfet_day(year=dt.year, month=dt.month, day=dt.day) if dt.time() < start_at: kfet_dt -= timedelta(days=1) @@ -23,6 +27,17 @@ def to_kfet_day(dt, start_at=KFET_WAKES_UP_AT): class Scale(object): + """ + Classe utilisée pour subdiviser un QuerySet (e.g. des opérations) sur + une échelle de temps donnée, avec un pas de temps fixe. + Cette échelle peut être spécifiée : + - par un début et une fin, + - par un début/une fin et un nombre de subdivisions. + + Si le booléen `std_chunk` est activé, les subdivisions sont standardisées : + on appelle `get_chunk_start` sur toutes les subdivisions (enfin, sur la première). + """ + name = None step = None @@ -92,6 +107,10 @@ class Scale(object): def chunkify_qs(self, qs, field=None): if field is None: field = "at" + """ + Découpe un queryset en subdivisions, avec agrégation optionnelle des résultats + NB : on pourrait faire ça en une requête, au détriment de la lisibilité... + """ begin_f = "{}__gte".format(field) end_f = "{}__lte".format(field) return [qs.filter(**{begin_f: begin, end_f: end}) for begin, end in self] @@ -247,6 +266,13 @@ def last_stats_manifest( scale_prefix=scale_prefix, **url_params ) + """ + Convertit une spécification de scales en arguments GET utilisables par ScaleMixin. + La spécification est de la forme suivante : + - scales_def : liste de champs de la forme (label, scale) + - scale_args : arguments à passer à Scale.__init__ + - other_url_params : paramètres GET supplémentaires + """ # Étant donné un queryset d'operations @@ -260,16 +286,9 @@ class ScaleMixin(object): scale_args_prefix = "scale_" def get_scale_args(self, params=None, prefix=None): - """Retrieve scale args from params. - - Should search the same args of Scale constructor. - - Args: - params (dict, optional): Scale args are searched in this. - Default to GET params of request. - prefix (str, optional): Appended at the begin of scale args names. - Default to `self.scale_args_prefix`. + """ + Récupère les paramètres de subdivision encodés dans une requête GET. """ if params is None: params = self.request.GET diff --git a/kfet/views.py b/kfet/views.py index a04cda24..b9c690dd 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -2235,11 +2235,19 @@ class PkUrlMixin(object): class SingleResumeStat(JSONDetailView): - """Manifest for a kind of a stat about an object. + """ + Génère l'interface de sélection pour les statistiques d'un compte/article. + L'interface est constituée d'une série de boutons, qui récupèrent et graphent + des statistiques du même type, sur le même objet mais avec des arguments différents. - Returns JSON whose payload is an array containing descriptions of a stat: - url to retrieve data, label, ... + Attributs : + - url_stat : URL où récupérer les statistiques + - stats : liste de dictionnaires avec les clés suivantes : + - label : texte du bouton + - url_params : paramètres GET à rajouter à `url_stat` + - default : si `True`, graphe à montrer par défaut + On peut aussi définir `stats` dynamiquement, via la fonction `get_stats`. """ id_prefix = "" @@ -2285,7 +2293,8 @@ ID_PREFIX_ACC_BALANCE = "balance_acc" class AccountStatBalanceList(PkUrlMixin, SingleResumeStat): - """Manifest for balance stats of an account.""" + Menu général pour l'historique de balance d'un compte + """ model = Account context_object_name = "account" @@ -2313,10 +2322,11 @@ class AccountStatBalanceList(PkUrlMixin, SingleResumeStat): class AccountStatBalance(PkUrlMixin, JSONDetailView): - """Datasets of balance of an account. - Operations and Transfers are taken into account. + """ + Statistiques (JSON) d'historique de balance d'un compte. + Prend en compte les opérations et transferts sur la période donnée. """ model = Account @@ -2441,7 +2451,10 @@ ID_PREFIX_ACC_LAST_MONTHS = "last_months_acc" class AccountStatOperationList(PkUrlMixin, SingleResumeStat): - """Manifest for operations stats of an account.""" +@method_decorator(login_required, name="dispatch") + """ + Menu général pour l'historique de consommation d'un compte + """ model = Account context_object_name = "account" @@ -2463,7 +2476,10 @@ class AccountStatOperationList(PkUrlMixin, SingleResumeStat): class AccountStatOperation(ScaleMixin, PkUrlMixin, JSONDetailView): - """Datasets of operations of an account.""" +@method_decorator(login_required, name="dispatch") + """ + Statistiques (JSON) de consommation (nb d'items achetés) d'un compte. + """ model = Account pk_url_kwarg = "trigramme" @@ -2535,7 +2551,9 @@ ID_PREFIX_ART_LAST_MONTHS = "last_months_art" class ArticleStatSalesList(SingleResumeStat): - """Manifest for sales stats of an article.""" + """ + Menu pour les statistiques de vente d'un article. + """ model = Article context_object_name = "article" @@ -2550,7 +2568,10 @@ class ArticleStatSalesList(SingleResumeStat): class ArticleStatSales(ScaleMixin, JSONDetailView): - """Datasets of sales of an article.""" + """ + Statistiques (JSON) de vente d'un article. + Sépare LIQ et les comptes K-Fêt, et rajoute le total. + """ model = Article context_object_name = "article"