mirror of
https://github.com/Crocmagnon/checkout.git
synced 2024-11-25 01:28:02 +01:00
Allow viewing reports by day
This commit is contained in:
parent
9f0969ec9a
commit
4c4cd1ca03
6 changed files with 73 additions and 14 deletions
20
src/purchase/migrations/0016_alter_paymentmethod_options.py
Normal file
20
src/purchase/migrations/0016_alter_paymentmethod_options.py
Normal file
|
@ -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",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -49,6 +49,7 @@ class PaymentMethod(Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("payment method")
|
verbose_name = _("payment method")
|
||||||
verbose_name_plural = _("payment methods")
|
verbose_name_plural = _("payment methods")
|
||||||
|
ordering = ("name",)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -15,15 +15,18 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>{% translate "By day" %}</h3>
|
<h3>{% translate "By day" %}</h3>
|
||||||
{% include "purchase/snippets/by_day.html" %}
|
{% include "purchase/snippets/by_day_table.html" %}
|
||||||
|
|
||||||
|
<h3>{% translate "By hour" %} <small class="text-muted">{{ date }}</small></h3>
|
||||||
{% include "purchase/snippets/htmx_plot.html" with url='purchase:by_hour_plot' %}
|
{% include "purchase/snippets/htmx_plot.html" with url='purchase:by_hour_plot' %}
|
||||||
|
|
||||||
<h2>{% translate "Products" %}</h2>
|
<h2>{% translate "Products" %} <small class="text-muted">{{ date }}</small></h2>
|
||||||
{% include "purchase/snippets/report_products.html" %}
|
{% include "purchase/snippets/report_products.html" %}
|
||||||
{% include "purchase/snippets/htmx_plot.html" with url='purchase:products_plots' %}
|
{% include "purchase/snippets/htmx_plot.html" with url='purchase:products_plots' %}
|
||||||
|
|
||||||
<h2>{% translate "Turnover by payment method" %}</h2>
|
<h2>{% translate "Turnover by payment method" %} <small class="text-muted">{{ date }}</small></h2>
|
||||||
{% include "purchase/snippets/report_payment_methods.html" %}
|
{% include "purchase/snippets/report_payment_methods.html" %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extrascript %}
|
{% block extrascript %}
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for report in by_day %}
|
{% for report in by_day %}
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{{ report.date }}</th>
|
{% with d=report.date %}
|
||||||
|
<th scope="row"><a href="{% url "purchase:reports" %}?year={{ d.year }}&month={{ d.month }}&day={{ d.day }}">{{ d }}</a></th>
|
||||||
|
{% endwith %}
|
||||||
<td>{{ report.count }}</td>
|
<td>{{ report.count }}</td>
|
||||||
<td>{{ report.turnover|currency }}</td>
|
<td>{{ report.turnover|currency }}</td>
|
||||||
<td>{{ report.average_basket|currency }}</td>
|
<td>{{ report.average_basket|currency }}</td>
|
|
@ -1,5 +1,5 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
<div hx-get="{% url url %}"
|
<div hx-get="{% url url %}?year={{ date.year|default:0 }}&month={{ date.month|default:0 }}&day={{ date.day|default:0 }}"
|
||||||
hx-trigger="load"
|
hx-trigger="load"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
>
|
>
|
||||||
|
|
|
@ -9,7 +9,6 @@ from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import permission_required
|
from django.contrib.auth.decorators import permission_required
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template.response import TemplateResponse
|
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views.decorators.http import condition
|
from django.views.decorators.http import condition
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
|
@ -34,7 +33,18 @@ mpl.use("SVG")
|
||||||
@permission_required("purchase.view_basket")
|
@permission_required("purchase.view_basket")
|
||||||
@condition(etag_func=reports_etag, last_modified_func=reports_last_modified)
|
@condition(etag_func=reports_etag, last_modified_func=reports_last_modified)
|
||||||
def products_plots_view(request):
|
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_plot,
|
||||||
products_sold_pie,
|
products_sold_pie,
|
||||||
|
@ -49,7 +59,16 @@ def products_plots_view(request):
|
||||||
@permission_required("purchase.view_basket")
|
@permission_required("purchase.view_basket")
|
||||||
@condition(etag_func=reports_etag, last_modified_func=reports_last_modified)
|
@condition(etag_func=reports_etag, last_modified_func=reports_last_modified)
|
||||||
def by_hour_plot_view(request):
|
def by_hour_plot_view(request):
|
||||||
|
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"))
|
baskets = list(Basket.objects.priced().order_by("created_at"))
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"plots": [by_hour_plot(baskets)],
|
"plots": [by_hour_plot(baskets)],
|
||||||
}
|
}
|
||||||
|
@ -84,17 +103,31 @@ def reports(request):
|
||||||
for date in dates
|
for date in dates
|
||||||
]
|
]
|
||||||
|
|
||||||
products = Product.objects.with_turnover().with_sold()
|
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"turnover": Basket.objects.turnover(),
|
"turnover": Basket.objects.turnover(),
|
||||||
"by_day": by_day_report,
|
|
||||||
"average_basket": Basket.objects.average_basket(),
|
"average_basket": Basket.objects.average_basket(),
|
||||||
"products": products,
|
|
||||||
"payment_methods": PaymentMethod.objects.with_turnover().with_sold(),
|
|
||||||
"basket_count": Basket.objects.count(),
|
"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):
|
def get_products_plots(products: ProductQuerySet):
|
||||||
|
|
Loading…
Reference in a new issue