cleaning: PEP8, html, permissions
This commit is contained in:
parent
7070129add
commit
de9387c6ad
|
@ -505,6 +505,10 @@ class OperationGroup(models.Model):
|
||||||
related_name = "+",
|
related_name = "+",
|
||||||
blank = True, null = True, default = None)
|
blank = True, null = True, default = None)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ', '.join(map(str, self.opes.all()))
|
||||||
|
|
||||||
|
|
||||||
class Operation(models.Model):
|
class Operation(models.Model):
|
||||||
PURCHASE = 'purchase'
|
PURCHASE = 'purchase'
|
||||||
DEPOSIT = 'deposit'
|
DEPOSIT = 'deposit'
|
||||||
|
@ -549,6 +553,18 @@ class Operation(models.Model):
|
||||||
max_digits = 6, decimal_places = 2,
|
max_digits = 6, decimal_places = 2,
|
||||||
blank = True, null = True, default = None)
|
blank = True, null = True, default = None)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
templates = {
|
||||||
|
self.PURCHASE: "{nb} {article.name} ({amount}€)",
|
||||||
|
self.DEPOSIT: "charge ({amount})",
|
||||||
|
self.WITHDRAW: "retrait ({amount})",
|
||||||
|
self.INITIAL: "initial ({amount})",
|
||||||
|
}
|
||||||
|
return templates[self.type].format(nb=self.article_nb,
|
||||||
|
article=self.article,
|
||||||
|
amount=self.amount)
|
||||||
|
|
||||||
|
|
||||||
class GlobalPermissions(models.Model):
|
class GlobalPermissions(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
managed = False
|
managed = False
|
||||||
|
|
|
@ -364,3 +364,11 @@ textarea {
|
||||||
.help h4 {
|
.help h4 {
|
||||||
margin:15px 0;
|
margin:15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Statistiques
|
||||||
|
*/
|
||||||
|
|
||||||
|
.stat-graph {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
|
@ -15,8 +15,11 @@
|
||||||
<script>
|
<script>
|
||||||
jQuery(document).ready(function() {
|
jQuery(document).ready(function() {
|
||||||
var stat_last = $("#stat_last");
|
var stat_last = $("#stat_last");
|
||||||
|
var stat_balance = $("#stat_balance");
|
||||||
var stat_last_url = "{% url 'kfet.account.stat.last' trigramme=account.trigramme %}";
|
var stat_last_url = "{% url 'kfet.account.stat.last' trigramme=account.trigramme %}";
|
||||||
|
var stat_balance_url = "{% url 'kfet.account.stat.balance' trigramme=account.trigramme %}";
|
||||||
get_thing(stat_last_url, stat_last, "Stat non trouvées :(");
|
get_thing(stat_last_url, stat_last, "Stat non trouvées :(");
|
||||||
|
get_thing(stat_balance_url, stat_balance, "Stat non trouvées :(");
|
||||||
// FONCTIONS
|
// FONCTIONS
|
||||||
// Permet de raffraichir un champ, étant donné :
|
// Permet de raffraichir un champ, étant donné :
|
||||||
// thing_url : l'url contenant le contenu
|
// thing_url : l'url contenant le contenu
|
||||||
|
@ -76,13 +79,21 @@ jQuery(document).ready(function() {
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if account.user == request.user %}
|
{% if account.user == request.user %}
|
||||||
<div class="content-right-block">
|
<div class="content-right-block content-right-block-transparent">
|
||||||
<h2>Statistiques</h2>
|
<h2>Statistiques</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 col-md-6 nopadding">
|
<div class="col-sm-12 nopadding">
|
||||||
|
<div class="panel-md-margin">
|
||||||
|
<h3>Ma balance</h3>
|
||||||
|
<div id="stat_balance" class"stat-graph"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div><!-- /row -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 nopadding">
|
||||||
<div class="panel-md-margin">
|
<div class="panel-md-margin">
|
||||||
<h3>Ma consommation</h3>
|
<h3>Ma consommation</h3>
|
||||||
<div id="stat_last"></div>
|
<div id="stat_last" class"stat-graph"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /row -->
|
</div><!-- /row -->
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
{% load dictionary_extras %}
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<canvas id="{{ chart_id }}"></canvas>
|
<canvas id="{{ chart_id }}" height="100"></canvas>
|
||||||
|
{% comment %}
|
||||||
|
<ul>
|
||||||
|
{% for change in changes %}
|
||||||
|
<li>
|
||||||
|
{{ change | get_item:'label'}}
|
||||||
|
| {{ change | get_item:'at'}}
|
||||||
|
| ({{ change | get_item:'amount'}})
|
||||||
|
| balance {{ change | get_item:'balance'}}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
jQuery(document).ready(function() {
|
jQuery(document).ready(function() {
|
||||||
|
@ -9,29 +22,21 @@ jQuery(document).ready(function() {
|
||||||
var myChart = new Chart(ctx1, {
|
var myChart = new Chart(ctx1, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: [
|
|
||||||
{% for k,label in labels.items %}
|
|
||||||
{% if forloop.last %}
|
|
||||||
"{{ label }}"
|
|
||||||
{% else %}
|
|
||||||
"{{ label }}",
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
],
|
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Nb items achetés',
|
label: 'Balance',
|
||||||
borderColor: 'rgb(255, 99, 132)',
|
borderColor: 'rgb(255, 99, 132)',
|
||||||
backgroundColor: 'rgb(255, 99, 132)',
|
backgroundColor: 'rgba(255, 99, 132, 0.5)',
|
||||||
data: [
|
data: [
|
||||||
{% for k,nb in nb_ventes.items %}
|
{% for change in changes %}
|
||||||
{% if forloop.last %}
|
{
|
||||||
"{{ nb }}"
|
x: new Date("{{ change | get_item:'at'}}"),
|
||||||
{% else %}
|
y: {{ change | get_item:'balance'| stringformat:"f" }},
|
||||||
"{{ nb }}",
|
label: "{{change|get_item:'label'}}"
|
||||||
{% endif %}
|
}{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
],
|
],
|
||||||
fill: false,
|
fill: true,
|
||||||
|
steppedLine: true,
|
||||||
lineTension: 0,
|
lineTension: 0,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
@ -45,6 +50,40 @@ jQuery(document).ready(function() {
|
||||||
mode: 'nearest',
|
mode: 'nearest',
|
||||||
intersect: false,
|
intersect: false,
|
||||||
},
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
type: "time",
|
||||||
|
display: true,
|
||||||
|
scaleLabel: {
|
||||||
|
display: false,
|
||||||
|
labelString: 'Date'
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
tooltipFormat: 'll HH:mm',
|
||||||
|
min: new Date("{{ min_date }}"),
|
||||||
|
max: new Date("{{ max_date }}"),
|
||||||
|
displayFormats: {
|
||||||
|
'millisecond': 'SSS [ms]',
|
||||||
|
'second': 'mm:ss a',
|
||||||
|
'minute': 'DD MMM',
|
||||||
|
'hour': 'ddd h[h]',
|
||||||
|
'day': 'DD MMM',
|
||||||
|
'week': 'DD MMM',
|
||||||
|
'month': 'MMM',
|
||||||
|
'quarter': 'MMM',
|
||||||
|
'year': 'YYYY',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
display: true,
|
||||||
|
scaleLabel: {
|
||||||
|
display: false,
|
||||||
|
labelString: 'value'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<canvas id="{{ chart_id }}"></canvas>
|
<canvas id="{{ chart_id }}" height="100" ></canvas>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
jQuery(document).ready(function() {
|
jQuery(document).ready(function() {
|
||||||
|
|
|
@ -78,9 +78,11 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /row-->
|
</div><!-- /row-->
|
||||||
|
</div>
|
||||||
|
<div class="content-right-block content-right-block-transparent">
|
||||||
<h2>Statistiques</h2>
|
<h2>Statistiques</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 col-md-6 nopadding">
|
<div class="col-sm-12 nopadding">
|
||||||
<div class="panel-md-margin">
|
<div class="panel-md-margin">
|
||||||
<h3>Ventes de {{ article.name }}</h3>
|
<h3>Ventes de {{ article.name }}</h3>
|
||||||
<div id="stat_last"></div>
|
<div id="stat_last"></div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<canvas id="{{ chart_id }}"></canvas>
|
<canvas id="{{ chart_id }}" height="100" ></canvas>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
jQuery(document).ready(function() {
|
jQuery(document).ready(function() {
|
||||||
|
|
|
@ -5,27 +5,47 @@
|
||||||
<div class="btn-group btn-group-justified" role="group" aria-label="select-period">
|
<div class="btn-group btn-group-justified" role="group" aria-label="select-period">
|
||||||
{% for k,stat in stats.items %}
|
{% for k,stat in stats.items %}
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button id="{{ stat | get_item:'btn' }}" type="button" class="btn btn-primary">{{ stat | get_item:'label' }}</button>
|
<button id="{{ stat | get_item:'btn' }}" type="button" class="btn btn-primary {{ id_prefix }}-btn {%if k == default_stat%} focus{%endif%}">{{ stat | get_item:'label' }}</button>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div><!-- /boutons -->
|
</div><!-- /boutons -->
|
||||||
<div id="{{ content_id}}">
|
<div id="{{ content_id}}">
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
jQuery(document).ready(function() {
|
||||||
|
// FONCTIONS
|
||||||
|
// Permet de raffraichir un champ, étant donné :
|
||||||
|
// thing_url : l'url contenant le contenu
|
||||||
|
// thing_div : le div où le mettre
|
||||||
|
// empty_... : le truc à dire si on a un contenu vide
|
||||||
|
function get_thing(thing_url, thing_div, empty_thing_message) {
|
||||||
|
$.get(thing_url, function(data) {
|
||||||
|
if(jQuery.trim(data).length==0) {
|
||||||
|
thing_div.html(empty_thing_message);
|
||||||
|
} else {
|
||||||
|
thing_div.html(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
jQuery(document).ready(function() {
|
jQuery(document).ready(function() {
|
||||||
// VARIABLES
|
// VARIABLES
|
||||||
// défaut
|
{{id_prefix}}_content_id = $("#{{content_id}}");
|
||||||
{{if_prefix}}_content_id = $("#{{content_id}}");
|
{{id_prefix}}_btns = $(".{{id_prefix}}-btn");
|
||||||
{% for k,stat in stats.items %}
|
{% for k,stat in stats.items %}
|
||||||
{% if k == default_stat %}
|
{% if k == default_stat %}
|
||||||
{{id_prefix}}_default_url = "{{ stat | get_item:'url' }}";
|
{{id_prefix}}_default_url = "{{ stat | get_item:'url' }}";
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
// INIT
|
// INIT
|
||||||
get_thing({{id_prefix}}_default_url, {{if_prefix}}_content_id, "Ouppss ?");
|
get_thing({{id_prefix}}_default_url, {{id_prefix}}_content_id, "Ouppss ?");
|
||||||
{% for k,stat in stats.items %}
|
{% for k,stat in stats.items %}
|
||||||
$("#{{stat|get_item:'btn'}}").on('click', function() {
|
$("#{{stat|get_item:'btn'}}").on('click', function() {
|
||||||
get_thing("{{stat|get_item:'url'}}", {{if_prefix}}_content_id, "Ouuups ?")
|
get_thing("{{stat|get_item:'url'}}", {{id_prefix}}_content_id, "Ouuups ?");
|
||||||
|
{{id_prefix}}_btns.removeClass("focus");
|
||||||
|
$("#{{stat|get_item:'btn'}}").addClass("focus");
|
||||||
});
|
});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
// FONCTIONS
|
// FONCTIONS
|
||||||
|
|
133
kfet/views.py
133
kfet/views.py
|
@ -24,11 +24,12 @@ from django.db.models import F, Sum, Prefetch, Count, Func
|
||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
from gestioncof.models import CofProfile, Clipper
|
from gestioncof.models import CofProfile, Clipper
|
||||||
from kfet.decorators import teamkfet_required
|
from kfet.decorators import teamkfet_required
|
||||||
from kfet.models import (Account, Checkout, Article, Settings, AccountNegative,
|
from kfet.models import (Account, Checkout, Article, Settings, AccountNegative,
|
||||||
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
|
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
|
||||||
InventoryArticle, Order, OrderArticle, Operation)
|
InventoryArticle, Order, OrderArticle, Operation, OperationGroup, Transfer)
|
||||||
from kfet.forms import *
|
from kfet.forms import *
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from kfet import consumers
|
from kfet import consumers
|
||||||
|
@ -2087,18 +2088,23 @@ class AccountStatBalanceAll(ObjectResumeStat):
|
||||||
def get_object_url_kwargs(self, **kwargs):
|
def get_object_url_kwargs(self, **kwargs):
|
||||||
return {'trigramme': self.object.trigramme}
|
return {'trigramme': self.object.trigramme}
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(AccountStatBalanceAll, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Rend un graphe (ou un json) de l'évolution de la balance personelle
|
# Rend un graphe (ou un json) de l'évolution de la balance personelle
|
||||||
# entre begin_date et end_date
|
# entre begin_date et end_date
|
||||||
# prend en compte les opérations et les transferts
|
# prend en compte les opérations et les transferts
|
||||||
# ne prend pas en compte les autorisations de négatif (TODO?)
|
# ne prend pas en compte les balance offset (TODO?)
|
||||||
class AccountStatBalance(HybridDetailView):
|
class AccountStatBalance(HybridDetailView):
|
||||||
model = Account
|
model = Account
|
||||||
trigramme_url_kwarg = 'trigramme'
|
trigramme_url_kwarg = 'trigramme'
|
||||||
template_name = 'kfet/account_stat_balance.html'
|
template_name = 'kfet/account_stat_balance.html'
|
||||||
context_object_name = 'account'
|
context_object_name = 'account'
|
||||||
begin_date = this_morning()
|
begin_date = this_morning()
|
||||||
end_date = timezone.now()
|
end_date = timezone.now() # ne gère pas encore autre chose que now
|
||||||
|
anytime = False # un cas particulier
|
||||||
id_prefix = "lol"
|
id_prefix = "lol"
|
||||||
|
|
||||||
def get_object(self, **kwargs):
|
def get_object(self, **kwargs):
|
||||||
|
@ -2108,25 +2114,23 @@ class AccountStatBalance(HybridDetailView):
|
||||||
def get_changes_list(self, **kwargs):
|
def get_changes_list(self, **kwargs):
|
||||||
account = self.object
|
account = self.object
|
||||||
# On récupère les opérations
|
# On récupère les opérations
|
||||||
|
# TODO: retirer les opgroup dont tous les op sont annulées
|
||||||
opgroups = list(OperationGroup.objects
|
opgroups = list(OperationGroup.objects
|
||||||
.filter(on_acc=account)
|
.filter(on_acc=account)
|
||||||
.filter(at__gte=self.begin_date)
|
.filter(at__gte=self.begin_date)
|
||||||
.filter(at__lte=self.end_date)
|
.filter(at__lte=self.end_date))
|
||||||
)
|
|
||||||
# On récupère les transferts reçus
|
# On récupère les transferts reçus
|
||||||
received_transfers = list(Transfer.objects
|
received_transfers = list(Transfer.objects
|
||||||
.filter(to_acc=account)
|
.filter(to_acc=account)
|
||||||
.filter(canceled_at=None)
|
.filter(canceled_at=None)
|
||||||
.filter(transfers__at__gte=self.begin_date)
|
.filter(group__at__gte=self.begin_date)
|
||||||
.filter(transfers__at__lte=self.end_date)
|
.filter(group__at__lte=self.end_date))
|
||||||
)
|
|
||||||
# On récupère les transferts émis
|
# On récupère les transferts émis
|
||||||
emitted_transfers = list(Transfer.objects
|
emitted_transfers = list(Transfer.objects
|
||||||
.filter(to_acc=account)
|
.filter(from_acc=account)
|
||||||
.filter(canceled_at=None)
|
.filter(canceled_at=None)
|
||||||
.filter(transfers__at__gte=self.begin_date)
|
.filter(group__at__gte=self.begin_date)
|
||||||
.filter(transfers__at__lte=self.end_date)
|
.filter(group__at__lte=self.end_date))
|
||||||
)
|
|
||||||
# On transforme tout ça en une liste de dictionnaires sous la forme
|
# On transforme tout ça en une liste de dictionnaires sous la forme
|
||||||
# {'at': date,
|
# {'at': date,
|
||||||
# 'amount': changement de la balance (négatif si diminue la balance,
|
# 'amount': changement de la balance (négatif si diminue la balance,
|
||||||
|
@ -2136,46 +2140,74 @@ class AccountStatBalance(HybridDetailView):
|
||||||
# sera mis à jour lors d'une
|
# sera mis à jour lors d'une
|
||||||
# autre passe)
|
# autre passe)
|
||||||
# }
|
# }
|
||||||
actions=[]
|
actions = [
|
||||||
for op in opgroups:
|
# Maintenant (à changer si on gère autre chose que now)
|
||||||
action = {
|
{
|
||||||
'at': op.at,
|
'at': self.end_date.isoformat(),
|
||||||
|
'amout': 0,
|
||||||
|
'label': "actuel",
|
||||||
|
'balance': 0,
|
||||||
|
}
|
||||||
|
] + [
|
||||||
|
{
|
||||||
|
'at': op.at.isoformat(),
|
||||||
'amount': op.amount,
|
'amount': op.amount,
|
||||||
'label': "opération", #TODO
|
'label': str(op),
|
||||||
|
'balance': 0,
|
||||||
|
} for op in opgroups
|
||||||
|
] + [
|
||||||
|
{
|
||||||
|
'at': tr.group.at.isoformat(),
|
||||||
|
'amount': tr.amount,
|
||||||
|
'label': "%d€: %s -> %s" % (tr.amount,
|
||||||
|
tr.from_acc.trigramme,
|
||||||
|
tr.to_acc.trigramme),
|
||||||
|
'balance': 0,
|
||||||
|
} for tr in received_transfers
|
||||||
|
] + [
|
||||||
|
{
|
||||||
|
'at': tr.group.at.isoformat(),
|
||||||
|
'amount': -tr.amount,
|
||||||
|
'label': "%d€: %s -> %s" % (tr.amount,
|
||||||
|
tr.from_acc.trigramme,
|
||||||
|
tr.to_acc.trigramme),
|
||||||
|
'balance': 0,
|
||||||
|
} for tr in emitted_transfers
|
||||||
|
]
|
||||||
|
if not self.anytime:
|
||||||
|
actions += [
|
||||||
|
# Date de début :
|
||||||
|
{
|
||||||
|
'at': self.begin_date.isoformat(),
|
||||||
|
'amount': 0,
|
||||||
|
'label': "début",
|
||||||
'balance': 0,
|
'balance': 0,
|
||||||
}
|
}
|
||||||
actions.append(action)
|
]
|
||||||
for tr in received_transfers:
|
|
||||||
action = {
|
|
||||||
'at': tr.transfers.at,
|
|
||||||
'amount': re.amount,
|
|
||||||
'label': "Transfert", #TODO
|
|
||||||
'balance': 0,
|
|
||||||
}
|
|
||||||
actions.append(action)
|
|
||||||
for tr in emitted_transfers:
|
|
||||||
action = {
|
|
||||||
'at': tr.transfers.at,
|
|
||||||
'amount': -re.amount,
|
|
||||||
'label': "Transfert", #TODO
|
|
||||||
'balance': 0,
|
|
||||||
}
|
|
||||||
actions.append(action)
|
|
||||||
# Maintenant on trie la liste des actions par ordre du plus récent
|
# Maintenant on trie la liste des actions par ordre du plus récent
|
||||||
# an plus ancien et on met à jour la balance
|
# an plus ancien et on met à jour la balance
|
||||||
actions = sorted(actions, key=lambda k: k['at'], reverse=True)
|
actions = sorted(actions, key=lambda k: k['at'], reverse=True)
|
||||||
actions[0]['balance'] = account.balance
|
actions[0]['balance'] = account.balance
|
||||||
for i in range(len(actions)-1):
|
for i in range(len(actions)-1):
|
||||||
actions[i+1]['balance'] = actions[i]['balance'] - actions[i+1]['amount']
|
actions[i+1]['balance'] = actions[i]['balance'] \
|
||||||
|
- actions[i+1]['amount']
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {}
|
context = {}
|
||||||
changes = self.get_changes_list()
|
changes = self.get_changes_list()
|
||||||
context['changes'] = changes
|
context['changes'] = changes
|
||||||
|
context['chart_id'] = "%s_%s" % (self.id_prefix,
|
||||||
|
self.object.id)
|
||||||
|
context['min_date'] = changes[len(changes)-1]['at']
|
||||||
|
context['max_date'] = changes[0]['at']
|
||||||
# TODO: offset
|
# TODO: offset
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(AccountStatBalance, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Rend l'évolution de la balance perso de ces 30 derniers jours
|
# Rend l'évolution de la balance perso de ces 30 derniers jours
|
||||||
class AccountStatBalanceMonth(AccountStatBalance):
|
class AccountStatBalanceMonth(AccountStatBalance):
|
||||||
|
@ -2205,6 +2237,7 @@ class AccountStatBalanceYear(AccountStatBalance):
|
||||||
class AccountStatBalanceAnytime(AccountStatBalance):
|
class AccountStatBalanceAnytime(AccountStatBalance):
|
||||||
begin_date = timezone.datetime(year=1980, month=1, day=1)
|
begin_date = timezone.datetime(year=1980, month=1, day=1)
|
||||||
id_prefix = ID_PREFIX_ACC_BALANCE_ANYTIME
|
id_prefix = ID_PREFIX_ACC_BALANCE_ANYTIME
|
||||||
|
anytime = True
|
||||||
|
|
||||||
|
|
||||||
# ------------------------
|
# ------------------------
|
||||||
|
@ -2237,6 +2270,10 @@ class AccountStatLastAll(ObjectResumeStat):
|
||||||
def get_object_url_kwargs(self, **kwargs):
|
def get_object_url_kwargs(self, **kwargs):
|
||||||
return {'trigramme': self.object.trigramme}
|
return {'trigramme': self.object.trigramme}
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(AccountStatLastAll, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class AccountStatLast(HybridDetailView):
|
class AccountStatLast(HybridDetailView):
|
||||||
model = Account
|
model = Account
|
||||||
|
@ -2302,6 +2339,10 @@ class AccountStatLast(HybridDetailView):
|
||||||
self.object.id)
|
self.object.id)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(AccountStatLast, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Rend les achats pour ce compte des 7 derniers jours
|
# Rend les achats pour ce compte des 7 derniers jours
|
||||||
# Aujourd'hui non compris
|
# Aujourd'hui non compris
|
||||||
|
@ -2367,6 +2408,10 @@ class ArticleStatLastAll(ObjectResumeStat):
|
||||||
'kfet.article.stat.last.week',
|
'kfet.article.stat.last.week',
|
||||||
'kfet.article.stat.last.day']
|
'kfet.article.stat.last.day']
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(ArticleStatLastAll, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Rend un graph des ventes sur une plage de temps à préciser.
|
# Rend un graph des ventes sur une plage de temps à préciser.
|
||||||
# Le graphique distingue les ventes sur LIQ et sur les autres trigrammes
|
# Le graphique distingue les ventes sur LIQ et sur les autres trigrammes
|
||||||
|
@ -2444,6 +2489,10 @@ class ArticleStatLast(HybridDetailView):
|
||||||
self.object.id)
|
self.object.id)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(ArticleStatLast, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# Rend les ventes des 7 derniers jours
|
# Rend les ventes des 7 derniers jours
|
||||||
# Aujourd'hui non compris
|
# Aujourd'hui non compris
|
||||||
|
@ -2472,6 +2521,7 @@ class ArticleStatLastWeek(ArticleStatLast):
|
||||||
weeks = lastweeks(7)
|
weeks = lastweeks(7)
|
||||||
return weeknames(weeks)
|
return weeknames(weeks)
|
||||||
|
|
||||||
|
|
||||||
# Rend les ventes des 7 derniers mois
|
# Rend les ventes des 7 derniers mois
|
||||||
# Le mois en cours n'est pas compris
|
# Le mois en cours n'est pas compris
|
||||||
class ArticleStatLastMonth(ArticleStatLast):
|
class ArticleStatLastMonth(ArticleStatLast):
|
||||||
|
@ -2489,6 +2539,7 @@ class ArticleStatLastMonth(ArticleStatLast):
|
||||||
# Article Statistique Catégories
|
# Article Statistique Catégories
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
|
|
||||||
class DurationStat(HybridListView):
|
class DurationStat(HybridListView):
|
||||||
lookup_duration_type = 'day' # 'day' || 'week' || 'month'
|
lookup_duration_type = 'day' # 'day' || 'week' || 'month'
|
||||||
lookup_duration_number = 3 # ie ici : 3 jours
|
lookup_duration_number = 3 # ie ici : 3 jours
|
||||||
|
@ -2500,7 +2551,8 @@ class DurationStat(HybridListView):
|
||||||
return this_monday_morning()
|
return this_monday_morning()
|
||||||
elif self.lookup_duration_type == 'month':
|
elif self.lookup_duration_type == 'month':
|
||||||
return this_first_month_day()
|
return this_first_month_day()
|
||||||
else: raise ValueError('duration_type invalid')
|
else:
|
||||||
|
raise ValueError('duration_type invalid')
|
||||||
|
|
||||||
def get_begining_date(self, **kwargs):
|
def get_begining_date(self, **kwargs):
|
||||||
end_date = self.get_end_date(self, **kwargs)
|
end_date = self.get_end_date(self, **kwargs)
|
||||||
|
@ -2510,13 +2562,18 @@ class DurationStat(HybridListView):
|
||||||
days = 7*self.lookup_nb_duration
|
days = 7*self.lookup_nb_duration
|
||||||
elif self.lookup_duration_type == 'month':
|
elif self.lookup_duration_type == 'month':
|
||||||
days = 30*self.lookup_nb_duration
|
days = 30*self.lookup_nb_duration
|
||||||
else: raise ValueError('this should not be happening.')
|
else:
|
||||||
|
raise ValueError('this should not be happening.')
|
||||||
delta = timezone.timedelta(days=days)
|
delta = timezone.timedelta(days=days)
|
||||||
return end_date - delta
|
return end_date - delta
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
return super(DurationStat, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# class CategoryStatAll(DurationStat):
|
# class CategoryDurationStat(DurationStat):
|
||||||
# model = ArticleCategory
|
# model = ArticleCategory
|
||||||
# template_name = 'kfet/category_stat.html'
|
# template_name = 'kfet/category_stat.html'
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in a new issue