From 0fd0a8ac5ddcc0fc946986176e9aa4f5f38a0061 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Sat, 29 Apr 2023 13:52:54 +0200 Subject: [PATCH] Display articles count --- src/purchase/forms.py | 6 ++++- src/purchase/models.py | 3 +++ src/purchase/tests/test_models.py | 37 +++++++++++++++++++++++++++++++ src/purchase/views/basket.py | 13 +++++++---- 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/purchase/tests/test_models.py diff --git a/src/purchase/forms.py b/src/purchase/forms.py index 01b9a6b..e3f513b 100644 --- a/src/purchase/forms.py +++ b/src/purchase/forms.py @@ -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}€
Nombre d'articles: {count}", + ), css_id="price_preview", css_class="mb-2", ), diff --git a/src/purchase/models.py b/src/purchase/models.py index d4df0f0..84026b0 100644 --- a/src/purchase/models.py +++ b/src/purchase/models.py @@ -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), diff --git a/src/purchase/tests/test_models.py b/src/purchase/tests/test_models.py new file mode 100644 index 0000000..adfe92a --- /dev/null +++ b/src/purchase/tests/test_models.py @@ -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 diff --git a/src/purchase/views/basket.py b/src/purchase/views/basket.py index 3745bd8..78742a2 100644 --- a/src/purchase/views/basket.py +++ b/src/purchase/views/basket.py @@ -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'{total}Montant total : {total}', + f'{total}Montant total : {total}
Nombre d\'articles: {count}', )