mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-24 18:14:22 +00:00
Merge pull request #872 from ae-utbm/invoices-bug
fix: InvoiceQuerySet.annotate_total()
This commit is contained in:
commit
2fa9daf627
@ -7,7 +7,7 @@ from django.test import Client, TestCase
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from model_bakery import baker, seq
|
from model_bakery import baker, seq
|
||||||
from model_bakery.recipe import Recipe
|
from model_bakery.recipe import Recipe, foreign_key
|
||||||
|
|
||||||
from core.baker_recipes import (
|
from core.baker_recipes import (
|
||||||
old_subscriber_user,
|
old_subscriber_user,
|
||||||
@ -16,6 +16,7 @@ from core.baker_recipes import (
|
|||||||
)
|
)
|
||||||
from core.models import User
|
from core.models import User
|
||||||
from counter.models import Counter, Refilling, Selling
|
from counter.models import Counter, Refilling, Selling
|
||||||
|
from eboutic.models import Invoice, InvoiceItem
|
||||||
|
|
||||||
|
|
||||||
class TestSearchUsers(TestCase):
|
class TestSearchUsers(TestCase):
|
||||||
@ -148,3 +149,19 @@ class TestFilterInactive(TestCase):
|
|||||||
def test_filter_inactive(self):
|
def test_filter_inactive(self):
|
||||||
res = User.objects.filter(id__in=[u.id for u in self.users]).filter_inactive()
|
res = User.objects.filter(id__in=[u.id for u in self.users]).filter_inactive()
|
||||||
assert list(res) == [self.users[0], self.users[5]]
|
assert list(res) == [self.users[0], self.users[5]]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_user_invoice_with_multiple_items():
|
||||||
|
"""Test that annotate_total() works when invoices contain multiple items."""
|
||||||
|
user: User = subscriber_user.make()
|
||||||
|
item_recipe = Recipe(InvoiceItem, invoice=foreign_key(Recipe(Invoice, user=user)))
|
||||||
|
item_recipe.make(_quantity=3, quantity=1, product_unit_price=5)
|
||||||
|
item_recipe.make(_quantity=1, quantity=1, product_unit_price=5)
|
||||||
|
res = list(
|
||||||
|
Invoice.objects.filter(user=user)
|
||||||
|
.annotate_total()
|
||||||
|
.order_by("-total")
|
||||||
|
.values_list("total", flat=True)
|
||||||
|
)
|
||||||
|
assert res == [15, 5]
|
||||||
|
@ -167,10 +167,15 @@ class InvoiceQueryset(models.QuerySet):
|
|||||||
The total amount is the sum of (product_unit_price * quantity)
|
The total amount is the sum of (product_unit_price * quantity)
|
||||||
for all items related to the invoice.
|
for all items related to the invoice.
|
||||||
"""
|
"""
|
||||||
|
# aggregates within subqueries require a little bit of black magic,
|
||||||
|
# but hopefully, django gives a comprehensive documentation for that :
|
||||||
|
# https://docs.djangoproject.com/en/stable/ref/models/expressions/#using-aggregates-within-a-subquery-expression
|
||||||
return self.annotate(
|
return self.annotate(
|
||||||
total=Subquery(
|
total=Subquery(
|
||||||
InvoiceItem.objects.filter(invoice_id=OuterRef("pk"))
|
InvoiceItem.objects.filter(invoice_id=OuterRef("pk"))
|
||||||
.annotate(total=Sum(F("product_unit_price") * F("quantity")))
|
.annotate(item_amount=F("product_unit_price") * F("quantity"))
|
||||||
|
.values("item_amount")
|
||||||
|
.annotate(total=Sum("item_amount"))
|
||||||
.values("total")
|
.values("total")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user