mirror of
https://github.com/ae-utbm/sith.git
synced 2026-05-22 17:00:19 +00:00
exclude products over clic limit from eboutic
This commit is contained in:
@@ -29,7 +29,12 @@
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
|
||||
&.clickable:hover {
|
||||
&:disabled {
|
||||
background-color: darken($primary-neutral-light-color, 5%);
|
||||
opacity: 65%;
|
||||
}
|
||||
|
||||
&.clickable:not(:disabled):hover {
|
||||
background-color: darken($primary-neutral-light-color, 5%);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
|
||||
&:hover {
|
||||
&:not(.link-like):not(:disabled):hover {
|
||||
background: hsl(0, 0%, 83%);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-11
@@ -22,7 +22,7 @@ import string
|
||||
from datetime import date, datetime, timedelta
|
||||
from datetime import timezone as tz
|
||||
from decimal import Decimal
|
||||
from typing import TYPE_CHECKING, Literal, Self
|
||||
from typing import Literal, Self
|
||||
|
||||
from dict2xml import dict2xml
|
||||
from django.conf import settings
|
||||
@@ -48,9 +48,6 @@ from core.utils import get_start_of_semester
|
||||
from counter.fields import CurrencyField
|
||||
from subscription.models import Subscription
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Sequence
|
||||
|
||||
|
||||
def get_eboutic() -> Counter:
|
||||
return Counter.objects.filter(type="EBOUTIC").order_by("id").first()
|
||||
@@ -773,10 +770,8 @@ class Counter(models.Model):
|
||||
# but they share the same primary key
|
||||
return self.type == "BAR" and any(b.pk == customer.pk for b in self.barmen_list)
|
||||
|
||||
def get_prices_for(
|
||||
self, customer: Customer, *, order_by: Sequence[str] | None = None
|
||||
) -> list[Price]:
|
||||
qs = (
|
||||
def get_prices_for(self, customer: Customer) -> PriceQuerySet:
|
||||
return (
|
||||
Price.objects.filter(
|
||||
product__counters=self, product__product_type__isnull=False
|
||||
)
|
||||
@@ -784,9 +779,6 @@ class Counter(models.Model):
|
||||
.select_related("product", "product__product_type")
|
||||
.prefetch_related("groups")
|
||||
)
|
||||
if order_by:
|
||||
qs = qs.order_by(*order_by)
|
||||
return list(qs)
|
||||
|
||||
|
||||
class CounterSellers(models.Model):
|
||||
|
||||
@@ -596,7 +596,7 @@ class TestCounterClick(TestFullClickBase):
|
||||
product=iter(_product_recipe.make(archived=False, _quantity=2)),
|
||||
groups=[group],
|
||||
)
|
||||
customer_prices = counter.get_prices_for(customer)
|
||||
customer_prices = list(counter.get_prices_for(customer))
|
||||
assert unarchived_prices == customer_prices
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class CounterClick(
|
||||
):
|
||||
return redirect(obj) # Redirect to counter
|
||||
|
||||
self.prices = obj.get_prices_for(self.customer)
|
||||
self.prices = list(obj.get_prices_for(self.customer))
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
@@ -187,9 +187,10 @@
|
||||
{% for price in prices %}
|
||||
<button
|
||||
id="{{ price.id }}"
|
||||
class="card product-button clickable shadow"
|
||||
class="card clickable shadow"
|
||||
:class="{selected: basket.some((i) => i.priceId === {{ price.id }})}"
|
||||
@click='addFromCatalog({{ price.id }}, {{ price.full_label|tojson }}, {{ price.amount }})'
|
||||
{% if price.sold_out %}disabled{% endif %}
|
||||
>
|
||||
{% if price.product.icon %}
|
||||
<img
|
||||
@@ -202,6 +203,9 @@
|
||||
{% endif %}
|
||||
<div class="card-content">
|
||||
<h4 class="card-title">{{ price.full_label }}</h4>
|
||||
{% if price.sold_out -%}
|
||||
<p><em>{% trans %}Product sold out{% endtrans %}</em></p>
|
||||
{%- endif %}
|
||||
<p>{{ price.amount }} €</p>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
+12
-5
@@ -33,7 +33,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.core.exceptions import SuspiciousOperation, ValidationError
|
||||
from django.db import DatabaseError, transaction
|
||||
from django.db.models import Subquery
|
||||
from django.db.models import Exists, OuterRef, Subquery
|
||||
from django.db.models.fields import forms
|
||||
from django.db.utils import cached_property
|
||||
from django.http import HttpResponse
|
||||
@@ -92,7 +92,9 @@ class EbouticMainView(LoginRequiredMixin, FormView):
|
||||
kwargs["form_kwargs"] = {
|
||||
"customer": self.customer,
|
||||
"counter": get_eboutic(),
|
||||
"allowed_prices": {price.id: price for price in self.prices},
|
||||
"allowed_prices": {
|
||||
price.id: price for price in self.prices if not price.sold_out
|
||||
},
|
||||
}
|
||||
return kwargs
|
||||
|
||||
@@ -118,9 +120,14 @@ class EbouticMainView(LoginRequiredMixin, FormView):
|
||||
|
||||
@cached_property
|
||||
def prices(self) -> list[Price]:
|
||||
return get_eboutic().get_prices_for(
|
||||
self.customer,
|
||||
order_by=["product__product_type__order", "product_id", "amount"],
|
||||
eboutic = get_eboutic()
|
||||
sold_out_subquery = ~Exists(
|
||||
eboutic.products.under_clic_limit().filter(id=OuterRef("product_id"))
|
||||
)
|
||||
return list(
|
||||
eboutic.get_prices_for(self.customer)
|
||||
.annotate(sold_out=sold_out_subquery)
|
||||
.order_by("product__product_type__order", "product_id", "amount")
|
||||
)
|
||||
|
||||
@cached_property
|
||||
|
||||
Reference in New Issue
Block a user