# # Copyright 2023 © AE UTBM # ae@utbm.fr / ae.info@utbm.fr # # This file is part of the website of the UTBM Student Association (AE UTBM), # https://ae.utbm.fr. # # You can find the source code of the website at https://github.com/ae-utbm/sith # # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE # OR WITHIN THE LOCAL FILE "LICENSE" # # from datetime import date, datetime, timedelta from datetime import timezone as tz from django.db.models import Exists, F, OuterRef from django.shortcuts import redirect from django.utils import timezone from django.views.generic import TemplateView from counter.fields import CurrencyField from counter.forms import InvoiceCallForm from counter.models import Club, InvoiceCall, Refilling, Selling from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin class InvoiceCallView(CounterAdminTabsMixin, CounterAdminMixin, TemplateView): template_name = "counter/invoices_call.jinja" current_tab = "invoices_call" def get(self, request, *args, **kwargs): month_str = request.GET.get("month") if month_str: try: start_date = datetime.strptime(month_str, "%Y-%m").date() today = timezone.now().date().replace(day=1) if start_date > today: return redirect("counter:invoices_call") except ValueError: return redirect("counter:invoices_call") return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): """Add sums to the context.""" kwargs = super().get_context_data(**kwargs) kwargs["months"] = Selling.objects.datetimes("date", "month", order="DESC") month_str = self.request.GET.get("month") if month_str: try: start_date = datetime.strptime(self.request.GET["month"], "%Y-%m") except ValueError: return redirect("counter:invoices_call") else: start_date = datetime( year=timezone.now().year, month=(timezone.now().month + 10) % 12 + 1, day=1, ) start_date = start_date.replace(tzinfo=tz.utc) end_date = (start_date + timedelta(days=32)).replace( day=1, hour=0, minute=0, microsecond=0 ) from django.db.models import Case, Sum, When kwargs["sum_cb"] = Refilling.objects.filter( payment_method="CARD", is_validated=True, date__gte=start_date, date__lte=end_date, ).aggregate(amount=Sum(F("amount"), default=0))["amount"] kwargs["sum_cb"] += Selling.objects.filter( payment_method="CARD", is_validated=True, date__gte=start_date, date__lte=end_date, ).aggregate(amount=Sum(F("quantity") * F("unit_price"), default=0))["amount"] kwargs["start_date"] = start_date kwargs["sums"] = list( Selling.objects.values("club__name") .annotate( selling_sum=Sum( Case( When( date__gte=start_date, date__lt=end_date, then=F("unit_price") * F("quantity"), ), output_field=CurrencyField(), ) ) ) .exclude(selling_sum=None) .order_by("-selling_sum") ) club_names = [i["club__name"] for i in kwargs["sums"]] clubs = Club.objects.filter(name__in=club_names) invoice_calls = InvoiceCall.objects.filter(month=month_str, club__in=clubs) invoice_statuses = {ic.club.name: ic.is_validated for ic in invoice_calls} kwargs["form"] = InvoiceCallForm(clubs=clubs, month=month_str) kwargs["club_data"] = [] for club in clubs: selling_sum = next( ( item["selling_sum"] for item in kwargs["sums"] if item["club__name"] == club.name ), 0, ) kwargs["club_data"].append( { "club": club, "sum": selling_sum, "validated": invoice_statuses.get(club.name, False), } ) return kwargs def post(self, request, *args, **kwargs): month_str = request.POST.get("month") if not month_str: return self.get(request, *args, **kwargs) try: start_date = datetime.strptime(month_str, "%Y-%m") start_date = date(start_date.year, start_date.month, 1) except ValueError: return redirect(request.path) selling_subquery = Selling.objects.filter( club=OuterRef("pk"), date__year=start_date.year, date__month=start_date.month, ) clubs = Club.objects.filter(Exists(selling_subquery)) form = InvoiceCallForm(request.POST, clubs=clubs, month=month_str) if form.is_valid(): form.save() return redirect(f"{request.path}?month={request.POST.get('month', '')}")