Display articles count

This commit is contained in:
Gabriel Augendre 2023-04-29 13:52:54 +02:00
parent 724e18fd76
commit 0fd0a8ac5d
4 changed files with 54 additions and 5 deletions

View file

@ -53,8 +53,10 @@ class BasketForm(forms.ModelForm):
)
fields.append(BasketItemField(field_name, product=product))
total = 0
count = 0
if basket:
total = basket.price / 100
count = basket.articles_count
self.helper.layout = Layout(
Div(
*fields,
@ -63,7 +65,9 @@ class BasketForm(forms.ModelForm):
),
InlineRadios("payment_method"),
Div(
layout.HTML(f"Montant total : {total:.2f}"),
layout.HTML(
f"Montant total : {total:.2f}€<br>Nombre d'articles: {count}",
),
css_id="price_preview",
css_class="mb-2",
),

View file

@ -157,6 +157,9 @@ class Product(Model):
class BasketQuerySet(models.QuerySet):
def with_articles_count(self) -> BasketQuerySet:
return self.annotate(articles_count=Sum(F("items__quantity")))
def priced(self) -> BasketQuerySet:
return self.annotate(
price=Coalesce(Sum(F("items__quantity") * F("items__unit_price_cents")), 0),

View file

@ -0,0 +1,37 @@
from purchase.models import Basket, BasketItem
from purchase.tests.factories import (
PaymentMethodFactory,
ProductFactory,
)
def test_with_articles_count(db):
products = [
ProductFactory(),
ProductFactory(),
ProductFactory(),
]
payment_method = PaymentMethodFactory()
basket = Basket.objects.create(payment_method=payment_method)
BasketItem.objects.create(
basket=basket,
product=products[0],
quantity=1,
unit_price_cents=1,
)
BasketItem.objects.create(
basket=basket,
product=products[1],
quantity=2,
unit_price_cents=2,
)
BasketItem.objects.create(
basket=basket,
product=products[2],
quantity=3,
unit_price_cents=3,
)
basket = Basket.objects.priced().with_articles_count().first()
assert basket.articles_count == 6
assert basket.price == 14

View file

@ -60,7 +60,7 @@ def update_with_unpriced_products(basket: Basket, post_data: MultiValueDict):
@require_http_methods(["GET", "POST"])
@permission_required("purchase.change_basket")
def update_basket(request: WSGIRequest, pk: int) -> HttpResponse:
basket = get_object_or_404(Basket.objects.priced(), pk=pk)
basket = get_object_or_404(Basket.objects.priced().with_articles_count(), pk=pk)
if request.method == "POST":
form = BasketForm(request.POST, instance=basket)
if form.is_valid():
@ -120,15 +120,20 @@ def delete_basket(request: WSGIRequest, pk: int) -> HttpResponse:
@permission_required("purchase.add_basket")
def price_preview(request: WSGIRequest) -> HttpResponse:
total = 0
count = 0
for name in request.POST:
if name.startswith(PRICED_PREFIX):
product_id = name[len(PRICED_PREFIX) :]
product = get_object_or_404(Product, pk=product_id)
total += product.unit_price_cents * int(request.POST.get(name, 0))
number = int(request.POST.get(name, 0))
total += product.unit_price_cents * number
count += number
elif name.startswith(UNPRICED_PREFIX):
total += sum(map(int, request.POST.getlist(name)))
prices = list(filter(lambda x: x > 0, map(int, request.POST.getlist(name))))
total += sum(prices)
count += len(prices)
total = f"{total/100:.2f}"
return HttpResponse(
f'<span hx-swap-oob="true" id="basket-price" class="badge bg-secondary">{total}</span>Montant total : {total}',
f'<span hx-swap-oob="true" id="basket-price" class="badge bg-secondary">{total}</span>Montant total : {total}<br>Nombre d\'articles: {count}',
)