Compare commits
6 commits
master
...
thubrecht/
Author | SHA1 | Date | |
---|---|---|---|
69472f2c84 | |||
bd109be388 | |||
44c729dfee | |||
ad8c3143b6 | |||
cecbb583c6 | |||
71355bbf7c |
4 changed files with 86 additions and 1 deletions
|
@ -25,6 +25,21 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
<aside>
|
||||
<div class="heading">
|
||||
<span>Export des ventes</span>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="btn btn-primary" href="{% url 'kfet.purchases' 6 %}">
|
||||
6 derniers mois
|
||||
</a>
|
||||
<a class="btn btn-primary" href="{% url 'kfet.purchases' %}">
|
||||
12 derniers mois
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
<li><a href="{% url 'kfet.article' %}">Articles</a></li>
|
||||
<li><a href="{% url 'kfet.inventory' %}">Inventaires</a></li>
|
||||
<li><a href="{% url 'kfet.order' %}">Commandes</a></li>
|
||||
<li><a href="{% url 'kfet.purchases' %}">Export des ventes</a></li>
|
||||
{% if user.username != 'kfet_genericteam' %}
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
|
|
|
@ -236,6 +236,13 @@ urlpatterns = [
|
|||
"k-psul/get_settings", views.kpsul_get_settings, name="kfet.kpsul.get_settings"
|
||||
),
|
||||
# -----
|
||||
# Sales history urls
|
||||
# -----
|
||||
path("purchases", views.SalesStatList.as_view(), name="kfet.purchases"),
|
||||
path(
|
||||
"purchases/<int:n_months>", views.SalesStatList.as_view(), name="kfet.purchases"
|
||||
),
|
||||
# -----
|
||||
# JSON urls
|
||||
# -----
|
||||
path("history.json", views.history_json, name="kfet.history.json"),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import csv
|
||||
import heapq
|
||||
import statistics
|
||||
from collections import defaultdict
|
||||
|
@ -12,12 +13,13 @@ from django.contrib.auth.decorators import login_required, permission_required
|
|||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.contrib.auth.models import Permission, User
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.core.exceptions import SuspiciousOperation, ValidationError
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
from django.db import transaction
|
||||
from django.db.models import Count, F, Max, OuterRef, Prefetch, Q, Subquery, Sum
|
||||
from django.forms import ValidationError, formset_factory
|
||||
from django.http import (
|
||||
Http404,
|
||||
HttpResponse,
|
||||
HttpResponseBadRequest,
|
||||
HttpResponseForbidden,
|
||||
JsonResponse,
|
||||
|
@ -29,6 +31,7 @@ from django.utils.decorators import method_decorator
|
|||
from django.views.generic import DetailView, FormView, ListView, TemplateView
|
||||
from django.views.generic.detail import BaseDetailView
|
||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||
from django.views.generic.list import BaseListView
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
from kfet import KFET_DELETED_TRIGRAMME, consumers
|
||||
|
@ -2451,6 +2454,65 @@ class ScaleMixin(object):
|
|||
return {"labels": self.scale.get_labels()}
|
||||
|
||||
|
||||
# ------------------------
|
||||
# Export des ventes en CSV
|
||||
# ------------------------
|
||||
|
||||
|
||||
@method_decorator(teamkfet_required, name="dispatch")
|
||||
class SalesStatList(BaseListView):
|
||||
model = Operation
|
||||
|
||||
def get_queryset(self):
|
||||
return (
|
||||
super()
|
||||
.get_queryset()
|
||||
.filter(type=Operation.PURCHASE, canceled_at=None, article__isnull=False)
|
||||
.values_list("article__name")
|
||||
.annotate(Sum("article_nb"))
|
||||
)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
scale = MonthScale(n_steps=self.kwargs.get("n_months", 12), last=True)
|
||||
articles = list(Article.objects.order_by("name"))
|
||||
indexes = {a.name: index for index, a in enumerate(articles)}
|
||||
ventes = scale.chunkify_qs(self.get_queryset(), field="group__at")
|
||||
|
||||
ctx["header"] = ["Mois"] + [a.name for a in articles]
|
||||
ctx["ventes"] = []
|
||||
ctx["total"] = [0] * len(articles)
|
||||
|
||||
labels = scale.get_labels()
|
||||
|
||||
for v in ventes:
|
||||
m_ventes = [0] * len(articles)
|
||||
for (a_name, nb_ventes) in v:
|
||||
index = indexes[a_name]
|
||||
m_ventes[index] = nb_ventes
|
||||
ctx["total"][index] += nb_ventes
|
||||
|
||||
ctx["ventes"].append([labels.pop(0)] + m_ventes)
|
||||
|
||||
return ctx
|
||||
|
||||
def render_to_response(self, context):
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = 'attachment; filename="historique_ventes.csv"'
|
||||
|
||||
writer = csv.writer(response)
|
||||
writer.writerow(context["header"])
|
||||
|
||||
# On écrit chaque mois
|
||||
for line in context["ventes"]:
|
||||
writer.writerow(line)
|
||||
|
||||
writer.writerow([])
|
||||
writer.writerow(["Total"] + context["total"])
|
||||
|
||||
return response
|
||||
|
||||
|
||||
# -----------------------
|
||||
# Evolution Balance perso
|
||||
# -----------------------
|
||||
|
|
Loading…
Reference in a new issue