Add number of baskets in reports & reformat reports by day

This commit is contained in:
Gabriel Augendre 2023-04-02 16:25:59 +02:00
parent 31f3c10f61
commit df7e592f8c
5 changed files with 170 additions and 150 deletions

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-27 16:54+0200\n"
"POT-Creation-Date: 2023-04-02 16:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,97 +18,97 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: purchase/admin.py:19
#: purchase/admin.py:26
msgid "unit price"
msgstr ""
#: purchase/admin.py:23
#: purchase/admin.py:30
msgid "sold"
msgstr ""
#: purchase/admin.py:27 purchase/admin.py:40
#: purchase/admin.py:34 purchase/admin.py:47
msgid "turnover"
msgstr ""
#: purchase/admin.py:54 purchase/admin.py:71
#: purchase/admin.py:61 purchase/admin.py:78
msgid "price"
msgstr ""
#: purchase/forms.py:27
#: purchase/forms.py:29
msgid "Save"
msgstr ""
#: purchase/models.py:17
#: purchase/models.py:16
msgid "created at"
msgstr ""
#: purchase/models.py:18
#: purchase/models.py:17
msgid "updated at"
msgstr ""
#: purchase/models.py:46 purchase/models.py:93
#: purchase/models.py:45 purchase/models.py:92
msgid "name"
msgstr ""
#: purchase/models.py:51 purchase/models.py:193
#: purchase/models.py:50 purchase/models.py:158
msgid "payment method"
msgstr ""
#: purchase/models.py:52
#: purchase/models.py:51
msgid "payment methods"
msgstr ""
#: purchase/models.py:94
msgid "image"
msgstr ""
#: purchase/models.py:96 purchase/models.py:229
#: purchase/models.py:94 purchase/models.py:194
msgid "unit price (cents)"
msgstr ""
#: purchase/models.py:98
#: purchase/models.py:96
msgid ""
"Unit price in cents. Use zero to denote that the product has no fixed price."
msgstr ""
#: purchase/models.py:103
#: purchase/models.py:101
msgid "initials"
msgstr ""
#: purchase/models.py:107
msgid "display order"
msgstr ""
#: purchase/models.py:110 purchase/models.py:219
#: purchase/models.py:114 purchase/models.py:184
msgid "product"
msgstr ""
#: purchase/models.py:111
#: purchase/models.py:115
msgid "products"
msgstr ""
#: purchase/models.py:199 purchase/models.py:225
#: purchase/models.py:164 purchase/models.py:190
msgid "basket"
msgstr ""
#: purchase/models.py:200
#: purchase/models.py:165
msgid "baskets"
msgstr ""
#: purchase/models.py:203
#: purchase/models.py:168
#, python-format
msgid "Basket #%(id)s"
msgstr ""
#: purchase/models.py:227
#: purchase/models.py:192
msgid "quantity"
msgstr ""
#: purchase/models.py:230
#: purchase/models.py:195
msgid "product's unit price in cents at the time of purchase"
msgstr ""
#: purchase/models.py:236
#: purchase/models.py:201
msgid "basket item"
msgstr ""
#: purchase/models.py:237
#: purchase/models.py:202
msgid "basket items"
msgstr ""
@ -122,11 +122,11 @@ msgid "Missing payment method."
msgstr ""
#: purchase/templates/purchase/basket_form.html:17
#: purchase/templates/purchase/basket_form.html:52
#: purchase/templates/purchase/basket_form.html:58
msgid "New basket"
msgstr ""
#: purchase/templates/purchase/basket_form.html:36
#: purchase/templates/purchase/basket_form.html:38
msgid "Add product"
msgstr ""
@ -151,7 +151,7 @@ msgid "Reports"
msgstr ""
#: purchase/templates/purchase/reports.html:10
msgid "General"
msgid "All times"
msgstr ""
#: purchase/templates/purchase/reports.html:12
@ -162,54 +162,51 @@ msgstr ""
msgid "Average basket:"
msgstr ""
#: purchase/templates/purchase/reports.html:16
msgid "By day"
#: purchase/templates/purchase/reports.html:14
msgid "Number of baskets:"
msgstr ""
#: purchase/templates/purchase/reports.html:17
msgid "By day"
msgstr ""
#: purchase/templates/purchase/reports.html:21
msgid "Products"
msgstr ""
#: purchase/templates/purchase/reports.html:25
msgid "Turnover by payment method"
msgstr ""
#: purchase/templates/purchase/snippets/by_day.html:6
msgid "Date"
msgstr ""
#: purchase/templates/purchase/snippets/by_day.html:7
#: purchase/templates/purchase/snippets/report_payment_methods.html:7
msgid "# baskets"
msgstr ""
#: purchase/templates/purchase/snippets/by_day.html:8
#: purchase/templates/purchase/snippets/report_payment_methods.html:8
#: purchase/templates/purchase/snippets/report_products.html:8
msgid "Turnover"
msgstr ""
#: purchase/templates/purchase/reports.html:23
#: purchase/templates/purchase/snippets/by_day.html:9
msgid "Average basket"
msgstr ""
#: purchase/templates/purchase/reports.html:32
msgid "Products"
msgstr ""
#: purchase/templates/purchase/reports.html:36
msgid "Turnover by payment method"
msgstr ""
#: purchase/templates/purchase/reports.html:39
msgid "Baskets without payment method"
msgstr ""
#: purchase/templates/purchase/snippets/report_no_payment_method.html:6
msgid "Basket"
msgstr ""
#: purchase/templates/purchase/snippets/report_no_payment_method.html:7
msgid "Price"
msgstr ""
#: purchase/templates/purchase/snippets/report_payment_methods.html:6
msgid "Payment method"
msgstr ""
#: purchase/templates/purchase/snippets/report_payment_methods.html:7
msgid "# baskets"
msgstr ""
#: purchase/templates/purchase/snippets/report_products.html:6
msgid "Product"
msgstr ""
#: purchase/templates/purchase/snippets/report_products.html:7
#: purchase/views/reports.py:102 purchase/views/reports.py:116
#: purchase/views/reports.py:115 purchase/views/reports.py:129
msgid "# sold"
msgstr ""
@ -225,26 +222,26 @@ msgstr ""
msgid "Basket successfully deleted."
msgstr ""
#: purchase/views/reports.py:64
#: purchase/views/reports.py:73
msgid "No sale to report"
msgstr ""
#: purchase/views/reports.py:93
#: purchase/views/reports.py:106
msgid "Sales by product"
msgstr ""
#: purchase/views/reports.py:108 purchase/views/reports.py:123
#: purchase/views/reports.py:121 purchase/views/reports.py:136
msgid "Turnover by product"
msgstr ""
#: purchase/views/reports.py:147
#: purchase/views/reports.py:160
msgid "Sales by hour"
msgstr ""
#: purchase/views/reports.py:158
#: purchase/views/reports.py:171
msgid "Basket count by hour"
msgstr ""
#: purchase/views/reports.py:166
#: purchase/views/reports.py:179
msgid "Turnover by hour"
msgstr ""

View file

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-27 16:54+0200\n"
"POT-Creation-Date: 2023-04-02 16:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,97 +15,99 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: purchase/admin.py:19
#: purchase/admin.py:26
msgid "unit price"
msgstr "prix unitaire"
#: purchase/admin.py:23
#: purchase/admin.py:30
msgid "sold"
msgstr "vendu"
#: purchase/admin.py:27 purchase/admin.py:40
#: purchase/admin.py:34 purchase/admin.py:47
msgid "turnover"
msgstr "chiffre d'affaires"
#: purchase/admin.py:54 purchase/admin.py:71
#: purchase/admin.py:61 purchase/admin.py:78
msgid "price"
msgstr "prix"
#: purchase/forms.py:27
#: purchase/forms.py:29
msgid "Save"
msgstr "Enregistrer"
#: purchase/models.py:17
#: purchase/models.py:16
msgid "created at"
msgstr "créé à"
#: purchase/models.py:18
#: purchase/models.py:17
msgid "updated at"
msgstr "mis à jour à"
#: purchase/models.py:46 purchase/models.py:93
#: purchase/models.py:45 purchase/models.py:92
msgid "name"
msgstr "nom"
#: purchase/models.py:51 purchase/models.py:193
#: purchase/models.py:50 purchase/models.py:158
msgid "payment method"
msgstr "moyen de paiement"
#: purchase/models.py:52
#: purchase/models.py:51
msgid "payment methods"
msgstr "moyens de paiement"
#: purchase/models.py:94
msgid "image"
msgstr "image"
#: purchase/models.py:96 purchase/models.py:229
#: purchase/models.py:94 purchase/models.py:194
msgid "unit price (cents)"
msgstr "prix unitaire (centimes)"
#: purchase/models.py:98
#: purchase/models.py:96
msgid ""
"Unit price in cents. Use zero to denote that the product has no fixed price."
msgstr "Prix unitaire en centimes. Utiliser zéro pour indiquer que le produit n'a pas de prix fixe."
msgstr ""
"Prix unitaire en centimes. Utiliser zéro pour indiquer que le produit n'a "
"pas de prix fixe."
#: purchase/models.py:103
#: purchase/models.py:101
msgid "initials"
msgstr "initiales"
#: purchase/models.py:107
msgid "display order"
msgstr "ordre d'affichage"
#: purchase/models.py:110 purchase/models.py:219
#: purchase/models.py:114 purchase/models.py:184
msgid "product"
msgstr "produit"
#: purchase/models.py:111
#: purchase/models.py:115
msgid "products"
msgstr "produits"
#: purchase/models.py:199 purchase/models.py:225
#: purchase/models.py:164 purchase/models.py:190
msgid "basket"
msgstr "panier"
#: purchase/models.py:200
#: purchase/models.py:165
msgid "baskets"
msgstr "paniers"
#: purchase/models.py:203
#: purchase/models.py:168
#, python-format
msgid "Basket #%(id)s"
msgstr "Panier n°%(id)s"
#: purchase/models.py:227
#: purchase/models.py:192
msgid "quantity"
msgstr "quantité"
#: purchase/models.py:230
#: purchase/models.py:195
msgid "product's unit price in cents at the time of purchase"
msgstr "prix unitaire du produit en centimes au moment de l'achat"
#: purchase/models.py:236
#: purchase/models.py:201
msgid "basket item"
msgstr "article de panier"
#: purchase/models.py:237
#: purchase/models.py:202
msgid "basket items"
msgstr "articles de panier"
@ -119,11 +121,11 @@ msgid "Missing payment method."
msgstr "Moyen de paiement manquant."
#: purchase/templates/purchase/basket_form.html:17
#: purchase/templates/purchase/basket_form.html:52
#: purchase/templates/purchase/basket_form.html:58
msgid "New basket"
msgstr "Nouveau panier"
#: purchase/templates/purchase/basket_form.html:36
#: purchase/templates/purchase/basket_form.html:38
msgid "Add product"
msgstr "Ajouter un produit"
@ -148,8 +150,8 @@ msgid "Reports"
msgstr "Rapports"
#: purchase/templates/purchase/reports.html:10
msgid "General"
msgstr "Général"
msgid "All times"
msgstr "Tous les temps"
#: purchase/templates/purchase/reports.html:12
msgid "Total turnover:"
@ -159,54 +161,51 @@ msgstr "Chiffre d'affaires total :"
msgid "Average basket:"
msgstr "Panier moyen :"
#: purchase/templates/purchase/reports.html:16
#: purchase/templates/purchase/reports.html:14
msgid "Number of baskets:"
msgstr "Nombre de paniers :"
#: purchase/templates/purchase/reports.html:17
msgid "By day"
msgstr "Par jour"
#: purchase/templates/purchase/reports.html:17
#: purchase/templates/purchase/reports.html:21
msgid "Products"
msgstr "Produits"
#: purchase/templates/purchase/reports.html:25
msgid "Turnover by payment method"
msgstr "Chiffre d'affaires par moyen de paiement"
#: purchase/templates/purchase/snippets/by_day.html:6
msgid "Date"
msgstr "Date"
#: purchase/templates/purchase/snippets/by_day.html:7
#: purchase/templates/purchase/snippets/report_payment_methods.html:7
msgid "# baskets"
msgstr "Nb. de paniers"
#: purchase/templates/purchase/snippets/by_day.html:8
#: purchase/templates/purchase/snippets/report_payment_methods.html:8
#: purchase/templates/purchase/snippets/report_products.html:8
msgid "Turnover"
msgstr "Chiffre d'affaires"
#: purchase/templates/purchase/reports.html:23
#: purchase/templates/purchase/snippets/by_day.html:9
msgid "Average basket"
msgstr "Panier moyen"
#: purchase/templates/purchase/reports.html:32
msgid "Products"
msgstr "Produits"
#: purchase/templates/purchase/reports.html:36
msgid "Turnover by payment method"
msgstr "Chiffre d'affaires par moyen de paiement"
#: purchase/templates/purchase/reports.html:39
msgid "Baskets without payment method"
msgstr "Paniers sans moyen de paiement"
#: purchase/templates/purchase/snippets/report_no_payment_method.html:6
msgid "Basket"
msgstr "Panier"
#: purchase/templates/purchase/snippets/report_no_payment_method.html:7
msgid "Price"
msgstr "Prix"
#: purchase/templates/purchase/snippets/report_payment_methods.html:6
msgid "Payment method"
msgstr "Moyen de paiement"
#: purchase/templates/purchase/snippets/report_payment_methods.html:7
msgid "# baskets"
msgstr "Nb. de paniers"
#: purchase/templates/purchase/snippets/report_products.html:6
msgid "Product"
msgstr "Produit"
#: purchase/templates/purchase/snippets/report_products.html:7
#: purchase/views/reports.py:102 purchase/views/reports.py:116
#: purchase/views/reports.py:115 purchase/views/reports.py:129
msgid "# sold"
msgstr "Nb. vendus"
@ -222,26 +221,26 @@ msgstr "Panier correctement modifié."
msgid "Basket successfully deleted."
msgstr "Panier correctement supprimé."
#: purchase/views/reports.py:64
#: purchase/views/reports.py:73
msgid "No sale to report"
msgstr "Aucune vente à afficher"
#: purchase/views/reports.py:93
#: purchase/views/reports.py:106
msgid "Sales by product"
msgstr "Ventes par produit"
#: purchase/views/reports.py:108 purchase/views/reports.py:123
#: purchase/views/reports.py:121 purchase/views/reports.py:136
msgid "Turnover by product"
msgstr "Chiffre d'affaires par produit"
#: purchase/views/reports.py:147
#: purchase/views/reports.py:160
msgid "Sales by hour"
msgstr "Ventes par heure"
#: purchase/views/reports.py:158
#: purchase/views/reports.py:171
msgid "Basket count by hour"
msgstr "Nombre de paniers par heure"
#: purchase/views/reports.py:166
#: purchase/views/reports.py:179
msgid "Turnover by hour"
msgstr "Chiffre d'affaires par heure"

View file

@ -7,26 +7,15 @@
{% block content %}
<h1>{% translate "Reports" %}</h1>
<h2>{% translate "General" %}</h2>
<h2>{% translate "All times" %}</h2>
<ul>
<li>{% translate "Total turnover:" %} {{ turnover|currency }}</li>
<li>{% translate "Average basket:" %} {{ average_basket|currency }}</li>
<li>{% translate "Number of baskets:" %} {{ basket_count }}</li>
</ul>
<h3>{% translate "By day" %}</h3>
<h4>{% translate "Turnover" %}</h4>
<ul>
{% for date, turnover in turnover_by_day.items %}
<li>{{ date }} : {{ turnover|currency }}</li>
{% endfor %}
</ul>
<h4>{% translate "Average basket" %}</h4>
<ul>
{% for date, average in average_basket_by_day.items %}
<li>{{ date }} : {{ average|currency }}</li>
{% endfor %}
</ul>
{% include "purchase/snippets/by_day.html" %}
{% include "purchase/snippets/htmx_plot.html" with url='purchase:by_hour_plot' %}
<h2>{% translate "Products" %}</h2>

View file

@ -0,0 +1,21 @@
{% load i18n %}
{% load purchase %}
<table class="table table-hover table-sm">
<thead><tr>
<th scope="col">{% translate "Date" %}</th>
<th scope="col">{% translate "# baskets" %}</th>
<th scope="col">{% translate "Turnover" %}</th>
<th scope="col">{% translate "Average basket" %}</th>
</tr></thead>
<tbody>
{% for report in by_day %}
<tr>
<th scope="row">{{ report.date }}</th>
<td>{{ report.count }}</td>
<td>{{ report.turnover|currency }}</td>
<td>{{ report.average_basket|currency }}</td>
</tr>
{% endfor %}
</tbody>
</table>

View file

@ -1,3 +1,4 @@
import dataclasses
import datetime
from io import StringIO
from zoneinfo import ZoneInfo
@ -55,6 +56,14 @@ def by_hour_plot_view(request):
return render(request, "purchase/snippets/plots.html", context)
@dataclasses.dataclass
class ByDayReport:
date: datetime.date
turnover: float
average_basket: float
count: int
@permission_required("purchase.view_basket")
@condition(etag_func=reports_etag, last_modified_func=reports_last_modified)
def reports(request):
@ -65,20 +74,25 @@ def reports(request):
return TemplateResponse(request, template_name, {})
dates = Basket.objects.values_list("created_at__date", flat=True).distinct()
average_basket_by_day = {
date: Basket.objects.by_date(date).average_basket() for date in dates
}
turnover_by_day = {date: Basket.objects.by_date(date).turnover() for date in dates}
by_day_report = [
ByDayReport(
date=date,
turnover=Basket.objects.by_date(date).turnover(),
average_basket=Basket.objects.by_date(date).average_basket(),
count=Basket.objects.by_date(date).count(),
)
for date in dates
]
products = Product.objects.with_turnover().with_sold()
context = {
"turnover": Basket.objects.turnover(),
"turnover_by_day": turnover_by_day,
"by_day": by_day_report,
"average_basket": Basket.objects.average_basket(),
"average_basket_by_day": average_basket_by_day,
"products": products,
"payment_methods": PaymentMethod.objects.with_turnover().with_sold(),
"basket_count": Basket.objects.count(),
}
return TemplateResponse(request, template_name, context)