Merge pull request #879 from ae-utbm/optimize-products-page

optimize: product list views
This commit is contained in:
thomas girod 2024-10-13 19:20:01 +02:00 committed by GitHub
commit d77358eaac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 51 deletions

View File

@ -8,25 +8,17 @@
{% if current_tab == "products" %} {% if current_tab == "products" %}
<p><a href="{{ url('counter:new_product') }}">{% trans %}New product{% endtrans %}</a></p> <p><a href="{{ url('counter:new_product') }}">{% trans %}New product{% endtrans %}</a></p>
{% endif %} {% endif %}
{% if product_list %}
<h3>{% trans %}Product list{% endtrans %}</h3> <h3>{% trans %}Product list{% endtrans %}</h3>
{% for t in ProductType.objects.all().order_by('name') %} {%- for product_type, products in object_list -%}
<h4>{{ t }}</h4> <h4>{{ product_type or _("Uncategorized") }}</h4>
<ul> <ul>
{% for p in product_list.filter(product_type=t).all().order_by('name') %} {%- for product in products -%}
<li><a href="{{ url('counter:product_edit', product_id=p.id) }}">{{ p }} ({{ p.code }})</a></li> <li><a href="{{ url('counter:product_edit', product_id=product.id) }}">{{ product }} ({{ product.code }})</a></li>
{% endfor %} {%- endfor -%}
</ul> </ul>
{% endfor %} {%- else -%}
<h4>{% trans %}Uncategorized{% endtrans %}</h4>
<ul>
{% for p in product_list.filter(product_type=None).all().order_by('name') %}
<li><a href="{{ url('counter:product_edit', product_id=p.id) }}">{{ p }} ({{ p.code }})</a></li>
{% endfor %}
</ul>
{% else %}
{% trans %}There is no products in this website.{% endtrans %} {% trans %}There is no products in this website.{% endtrans %}
{% endif %} {%- endfor -%}
{% endblock %} {% endblock %}

View File

@ -19,11 +19,7 @@ from counter.views import *
urlpatterns = [ urlpatterns = [
path("<int:counter_id>/", CounterMain.as_view(), name="details"), path("<int:counter_id>/", CounterMain.as_view(), name="details"),
path( path("<int:counter_id>/click/<int:user_id>/", CounterClick.as_view(), name="click"),
"<int:counter_id>/click/<int:user_id>/",
CounterClick.as_view(),
name="click",
),
path( path(
"<int:counter_id>/last_ops/", "<int:counter_id>/last_ops/",
CounterLastOperationsView.as_view(), CounterLastOperationsView.as_view(),
@ -34,19 +30,11 @@ urlpatterns = [
CounterCashSummaryView.as_view(), CounterCashSummaryView.as_view(),
name="cash_summary", name="cash_summary",
), ),
path( path("<int:counter_id>/activity/", CounterActivityView.as_view(), name="activity"),
"<int:counter_id>/activity/",
CounterActivityView.as_view(),
name="activity",
),
path("<int:counter_id>/stats/", CounterStatView.as_view(), name="stats"), path("<int:counter_id>/stats/", CounterStatView.as_view(), name="stats"),
path("<int:counter_id>/login/", counter_login, name="login"), path("<int:counter_id>/login/", counter_login, name="login"),
path("<int:counter_id>/logout/", counter_logout, name="logout"), path("<int:counter_id>/logout/", counter_logout, name="logout"),
path( path("eticket/<int:selling_id>/pdf/", EticketPDFView.as_view(), name="eticket_pdf"),
"eticket/<int:selling_id>/pdf/",
EticketPDFView.as_view(),
name="eticket_pdf",
),
path( path(
"customer/<int:customer_id>/card/add/", "customer/<int:customer_id>/card/add/",
StudentCardFormView.as_view(), StudentCardFormView.as_view(),
@ -59,17 +47,11 @@ urlpatterns = [
), ),
path("admin/<int:counter_id>/", CounterEditView.as_view(), name="admin"), path("admin/<int:counter_id>/", CounterEditView.as_view(), name="admin"),
path( path(
"admin/<int:counter_id>/prop/", "admin/<int:counter_id>/prop/", CounterEditPropView.as_view(), name="prop_admin"
CounterEditPropView.as_view(),
name="prop_admin",
), ),
path("admin/", CounterListView.as_view(), name="admin_list"), path("admin/", CounterListView.as_view(), name="admin_list"),
path("admin/new/", CounterCreateView.as_view(), name="new"), path("admin/new/", CounterCreateView.as_view(), name="new"),
path( path("admin/delete/<int:counter_id>/", CounterDeleteView.as_view(), name="delete"),
"admin/delete/<int:counter_id>/",
CounterDeleteView.as_view(),
name="delete",
),
path("admin/invoices_call/", InvoiceCallView.as_view(), name="invoices_call"), path("admin/invoices_call/", InvoiceCallView.as_view(), name="invoices_call"),
path( path(
"admin/cash_summary/list/", "admin/cash_summary/list/",
@ -81,10 +63,10 @@ urlpatterns = [
CashSummaryEditView.as_view(), CashSummaryEditView.as_view(),
name="cash_summary_edit", name="cash_summary_edit",
), ),
path("admin/product/list/", ProductListView.as_view(), name="product_list"), path("admin/product/list/", ActiveProductListView.as_view(), name="product_list"),
path( path(
"admin/product/list_archived/", "admin/product/list_archived/",
ProductArchivedListView.as_view(), ArchivedProductListView.as_view(),
name="product_list_archived", name="product_list_archived",
), ),
path("admin/product/create/", ProductCreateView.as_view(), name="new_product"), path("admin/product/create/", ProductCreateView.as_view(), name="new_product"),

View File

@ -12,10 +12,12 @@
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# #
import itertools
import re import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from datetime import timezone as tz from datetime import timezone as tz
from http import HTTPStatus from http import HTTPStatus
from operator import attrgetter
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from urllib.parse import parse_qs from urllib.parse import parse_qs
@ -804,25 +806,41 @@ class ProductTypeEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
current_tab = "products" current_tab = "products"
class ProductArchivedListView(CounterAdminTabsMixin, CounterAdminMixin, ListView): class ProductListView(CounterAdminTabsMixin, CounterAdminMixin, ListView):
model = Product
queryset = Product.objects.annotate(type_name=F("product_type__name"))
template_name = "counter/product_list.jinja"
ordering = [
F("product_type__priority").desc(nulls_last=True),
"product_type",
"name",
]
def get_context_data(self, **kwargs):
res = super().get_context_data(**kwargs)
res["object_list"] = itertools.groupby(
res["object_list"], key=attrgetter("type_name")
)
return res
class ArchivedProductListView(ProductListView):
"""A list view for the admins.""" """A list view for the admins."""
model = Product
template_name = "counter/product_list.jinja"
queryset = Product.objects.filter(archived=True)
ordering = ["name"]
current_tab = "archive" current_tab = "archive"
def get_queryset(self):
return super().get_queryset().filter(archived=True)
class ProductListView(CounterAdminTabsMixin, CounterAdminMixin, ListView):
class ActiveProductListView(ProductListView):
"""A list view for the admins.""" """A list view for the admins."""
model = Product
template_name = "counter/product_list.jinja"
queryset = Product.objects.filter(archived=False)
ordering = ["name"]
current_tab = "products" current_tab = "products"
def get_queryset(self):
return super().get_queryset().filter(archived=False)
class ProductCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView): class ProductCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView):
"""A create view for the admins.""" """A create view for the admins."""