From 4c4cd1ca0353207a3e4817974d7272101bc1f63b Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Sun, 2 Apr 2023 17:47:24 +0200 Subject: [PATCH] Allow viewing reports by day --- .../0016_alter_paymentmethod_options.py | 20 ++++++++ src/purchase/models.py | 1 + src/purchase/templates/purchase/reports.html | 9 ++-- .../{by_day.html => by_day_table.html} | 4 +- .../purchase/snippets/htmx_plot.html | 2 +- src/purchase/views/reports.py | 51 +++++++++++++++---- 6 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 src/purchase/migrations/0016_alter_paymentmethod_options.py rename src/purchase/templates/purchase/snippets/{by_day.html => by_day_table.html} (74%) diff --git a/src/purchase/migrations/0016_alter_paymentmethod_options.py b/src/purchase/migrations/0016_alter_paymentmethod_options.py new file mode 100644 index 0000000..2fc717d --- /dev/null +++ b/src/purchase/migrations/0016_alter_paymentmethod_options.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.7 on 2023-04-02 16:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("purchase", "0015_remove_product_image_product_initials"), + ] + + operations = [ + migrations.AlterModelOptions( + name="paymentmethod", + options={ + "ordering": ("name",), + "verbose_name": "payment method", + "verbose_name_plural": "payment methods", + }, + ), + ] diff --git a/src/purchase/models.py b/src/purchase/models.py index fc2344b..32db2b9 100644 --- a/src/purchase/models.py +++ b/src/purchase/models.py @@ -49,6 +49,7 @@ class PaymentMethod(Model): class Meta: verbose_name = _("payment method") verbose_name_plural = _("payment methods") + ordering = ("name",) def __str__(self): return self.name diff --git a/src/purchase/templates/purchase/reports.html b/src/purchase/templates/purchase/reports.html index 217129a..1835e8b 100644 --- a/src/purchase/templates/purchase/reports.html +++ b/src/purchase/templates/purchase/reports.html @@ -15,15 +15,18 @@

{% translate "By day" %}

- {% include "purchase/snippets/by_day.html" %} + {% include "purchase/snippets/by_day_table.html" %} + +

{% translate "By hour" %} {{ date }}

{% include "purchase/snippets/htmx_plot.html" with url='purchase:by_hour_plot' %} -

{% translate "Products" %}

+

{% translate "Products" %} {{ date }}

{% include "purchase/snippets/report_products.html" %} {% include "purchase/snippets/htmx_plot.html" with url='purchase:products_plots' %} -

{% translate "Turnover by payment method" %}

+

{% translate "Turnover by payment method" %} {{ date }}

{% include "purchase/snippets/report_payment_methods.html" %} + {% endblock %} {% block extrascript %} diff --git a/src/purchase/templates/purchase/snippets/by_day.html b/src/purchase/templates/purchase/snippets/by_day_table.html similarity index 74% rename from src/purchase/templates/purchase/snippets/by_day.html rename to src/purchase/templates/purchase/snippets/by_day_table.html index 467a16a..3a71787 100644 --- a/src/purchase/templates/purchase/snippets/by_day.html +++ b/src/purchase/templates/purchase/snippets/by_day_table.html @@ -11,7 +11,9 @@ {% for report in by_day %} - {{ report.date }} + {% with d=report.date %} + {{ d }} + {% endwith %} {{ report.count }} {{ report.turnover|currency }} {{ report.average_basket|currency }} diff --git a/src/purchase/templates/purchase/snippets/htmx_plot.html b/src/purchase/templates/purchase/snippets/htmx_plot.html index 2e497b6..e9adfc5 100644 --- a/src/purchase/templates/purchase/snippets/htmx_plot.html +++ b/src/purchase/templates/purchase/snippets/htmx_plot.html @@ -1,5 +1,5 @@ {% load static %} -
diff --git a/src/purchase/views/reports.py b/src/purchase/views/reports.py index bac3fed..417986b 100644 --- a/src/purchase/views/reports.py +++ b/src/purchase/views/reports.py @@ -9,7 +9,6 @@ from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import permission_required from django.shortcuts import render -from django.template.response import TemplateResponse from django.utils.translation import gettext as _ from django.views.decorators.http import condition from matplotlib import pyplot as plt @@ -34,7 +33,18 @@ mpl.use("SVG") @permission_required("purchase.view_basket") @condition(etag_func=reports_etag, last_modified_func=reports_last_modified) def products_plots_view(request): - products = Product.objects.with_turnover().with_sold() + year = int(request.GET.get("year", 0)) + month = int(request.GET.get("month", 0)) + day = int(request.GET.get("day", 0)) + + if year and month and day: + date = datetime.date(year, month, day) + baskets = Basket.objects.by_date(date) + products = Product.objects.filter(basket_items__basket__in=baskets) + else: + products = Product.objects.all() + + products = products.with_turnover().with_sold().exclude(sold=0) ( products_plot, products_sold_pie, @@ -49,7 +59,16 @@ def products_plots_view(request): @permission_required("purchase.view_basket") @condition(etag_func=reports_etag, last_modified_func=reports_last_modified) def by_hour_plot_view(request): - baskets = list(Basket.objects.priced().order_by("created_at")) + year = int(request.GET.get("year", 0)) + month = int(request.GET.get("month", 0)) + day = int(request.GET.get("day", 0)) + + if year and month and day: + date = datetime.date(year, month, day) + baskets = list(Basket.objects.by_date(date).priced().order_by("created_at")) + else: + baskets = list(Basket.objects.priced().order_by("created_at")) + context = { "plots": [by_hour_plot(baskets)], } @@ -84,17 +103,31 @@ def reports(request): for date in dates ] - products = Product.objects.with_turnover().with_sold() - context = { "turnover": Basket.objects.turnover(), - "by_day": by_day_report, "average_basket": Basket.objects.average_basket(), - "products": products, - "payment_methods": PaymentMethod.objects.with_turnover().with_sold(), "basket_count": Basket.objects.count(), + "by_day": by_day_report, } - return TemplateResponse(request, template_name, context) + + methods = PaymentMethod.objects.order_by("name") + products = Product.objects.all() + + year = int(request.GET.get("year", 0)) + month = int(request.GET.get("month", 0)) + day = int(request.GET.get("day", 0)) + + if year and month and day: + date = datetime.date(year, month, day) + baskets = Basket.objects.by_date(date) + context["date"] = date + products = products.filter(basket_items__basket__in=baskets) + methods = methods.filter(baskets__in=baskets) + + context["products"] = products.with_turnover().with_sold().exclude(sold=0) + context["payment_methods"] = methods.with_turnover().with_sold().exclude(sold=0) + + return render(request, template_name, context) def get_products_plots(products: ProductQuerySet):