refactor: user stats view

This commit is contained in:
imperosol
2025-11-24 15:42:36 +01:00
parent 4ff4d179a1
commit 5271783e88
4 changed files with 71 additions and 82 deletions

View File

@@ -22,9 +22,9 @@
#
#
import itertools
from datetime import datetime, timedelta, timezone
# This file contains all the views that concern the user model
from datetime import date, timedelta
from operator import itemgetter
from smtplib import SMTPException
@@ -32,7 +32,7 @@ from django.contrib.auth import login, views
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from django.db.models import DateField, QuerySet
from django.db.models import DateField, F, QuerySet, Sum
from django.db.models.functions import Trunc
from django.forms.models import modelform_factory
from django.http import Http404
@@ -57,6 +57,7 @@ from honeypot.decorators import check_honeypot
from core.auth.mixins import CanEditMixin, CanEditPropMixin, CanViewMixin
from core.models import Gift, Preferences, User
from core.utils import get_start_of_semester
from core.views.forms import (
GiftForm,
LoginForm,
@@ -66,9 +67,8 @@ from core.views.forms import (
UserProfileForm,
)
from core.views.mixins import TabedViewMixin, UseFragmentsMixin
from counter.models import Counter, Refilling, Selling
from counter.models import Refilling, Selling
from eboutic.models import Invoice
from subscription.models import Subscription
from trombi.views import UserTrombiForm
@@ -353,87 +353,47 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
context_object_name = "profile"
template_name = "core/user_stats.jinja"
current_tab = "stats"
queryset = User.objects.exclude(customer=None).select_related("customer")
def dispatch(self, request, *arg, **kwargs):
profile = self.get_object()
if not hasattr(profile, "customer"):
raise Http404
if not (
profile == request.user or request.user.has_perm("counter.view_customer")
):
raise PermissionDenied
return super().dispatch(request, *arg, **kwargs)
def get_context_data(self, **kwargs):
kwargs = super().get_context_data(**kwargs)
from django.db.models import Sum
foyer = Counter.objects.filter(name="Foyer").first()
mde = Counter.objects.filter(name="MDE").first()
gommette = Counter.objects.filter(name="La Gommette").first()
semester_start = Subscription.compute_start(d=date.today(), duration=3)
start = get_start_of_semester()
semester_start = datetime(
start.year, start.month, start.day, tzinfo=timezone.utc
)
kwargs["perm_time"] = list(
self.object.permanencies.filter(end__isnull=False, counter__type="BAR")
.values("counter", "counter__name")
.annotate(total=Sum(F("end") - F("start"), default=timedelta(seconds=0)))
.order_by("-total")
)
kwargs["total_perm_time"] = sum(
[p.end - p.start for p in self.object.permanencies.exclude(end=None)],
timedelta(),
[perm["total"] for perm in kwargs["perm_time"]], start=timedelta(seconds=0)
)
kwargs["total_foyer_time"] = sum(
[
p.end - p.start
for p in self.object.permanencies.filter(counter=foyer).exclude(
end=None
)
],
timedelta(),
)
kwargs["total_mde_time"] = sum(
[
p.end - p.start
for p in self.object.permanencies.filter(counter=mde).exclude(end=None)
],
timedelta(),
)
kwargs["total_gommette_time"] = sum(
[
p.end - p.start
for p in self.object.permanencies.filter(counter=gommette).exclude(
end=None
)
],
timedelta(),
)
kwargs["total_foyer_buyings"] = sum(
[
b.unit_price * b.quantity
for b in self.object.customer.buyings.filter(
counter=foyer, date__gte=semester_start
)
]
)
kwargs["total_mde_buyings"] = sum(
[
b.unit_price * b.quantity
for b in self.object.customer.buyings.filter(
counter=mde, date__gte=semester_start
)
]
)
kwargs["total_gommette_buyings"] = sum(
[
b.unit_price * b.quantity
for b in self.object.customer.buyings.filter(
counter=gommette, date__gte=semester_start
)
]
kwargs["purchase_sums"] = list(
self.object.customer.buyings.filter(
date__gte=semester_start, counter__type="BAR"
)
.values("counter", "counter__name")
.annotate(total=Sum(F("unit_price") * F("quantity")))
.order_by("-total")
)
kwargs["total_purchases"] = sum(s["total"] for s in kwargs["purchase_sums"])
kwargs["top_product"] = (
self.object.customer.buyings.values("product__name")
.annotate(product_sum=Sum("quantity"))
.exclude(product_sum=None)
.order_by("-product_sum")
.all()[:10]
.all()[:15]
)
return kwargs