mirror of
https://github.com/ae-utbm/sith.git
synced 2026-01-10 04:50:09 +00:00
use FilterSchema for club sales.
This commit is contained in:
@@ -37,6 +37,7 @@ from core.views.widgets.ajax_select import (
|
|||||||
AutoCompleteSelectUser,
|
AutoCompleteSelectUser,
|
||||||
)
|
)
|
||||||
from counter.models import Counter, Selling
|
from counter.models import Counter, Selling
|
||||||
|
from counter.schemas import SaleFilterSchema
|
||||||
|
|
||||||
|
|
||||||
class ClubEditForm(forms.ModelForm):
|
class ClubEditForm(forms.ModelForm):
|
||||||
@@ -191,6 +192,18 @@ class SellingsForm(forms.Form):
|
|||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def to_filter_schema(self) -> SaleFilterSchema:
|
||||||
|
products = (
|
||||||
|
*self.cleaned_data["products"],
|
||||||
|
*self.cleaned_data["archived_products"],
|
||||||
|
)
|
||||||
|
return SaleFilterSchema(
|
||||||
|
after=self.cleaned_data["begin_date"],
|
||||||
|
before=self.cleaned_data["end_date"],
|
||||||
|
counters={c.id for c in self.cleaned_data["counters"]} or None,
|
||||||
|
products={p.id for p in products} or None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ClubOldMemberForm(forms.Form):
|
class ClubOldMemberForm(forms.Form):
|
||||||
members_old = forms.ModelMultipleChoiceField(
|
members_old = forms.ModelMultipleChoiceField(
|
||||||
|
|||||||
@@ -7,16 +7,20 @@ from club.forms import SellingsForm
|
|||||||
from club.models import Club
|
from club.models import Club
|
||||||
from core.models import User
|
from core.models import User
|
||||||
from counter.baker_recipes import product_recipe, sale_recipe
|
from counter.baker_recipes import product_recipe, sale_recipe
|
||||||
from counter.models import Counter, Customer
|
from counter.models import Counter, Customer, Product
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_sales_page_doesnt_crash(client: Client):
|
def test_sales_page_doesnt_crash(client: Client):
|
||||||
|
"""Basic crashtest on club sales view."""
|
||||||
club = baker.make(Club)
|
club = baker.make(Club)
|
||||||
|
product = baker.make(Product, club=club)
|
||||||
admin = baker.make(User, is_superuser=True)
|
admin = baker.make(User, is_superuser=True)
|
||||||
client.force_login(admin)
|
client.force_login(admin)
|
||||||
response = client.get(reverse("club:club_sellings", kwargs={"club_id": club.id}))
|
url = reverse("club:club_sellings", kwargs={"club_id": club.id})
|
||||||
assert response.status_code == 200
|
assert client.get(url).status_code == 200
|
||||||
|
assert client.post(url).status_code == 200
|
||||||
|
assert client.post(url, data={"products": [product.id]}).status_code == 200
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|||||||
@@ -406,33 +406,14 @@ class ClubSellingView(ClubTabsMixin, CanEditMixin, DetailFormView):
|
|||||||
kwargs = super().get_context_data(**kwargs)
|
kwargs = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
kwargs["result"] = Selling.objects.none()
|
kwargs["result"] = Selling.objects.none()
|
||||||
kwargs["paginated_result"] = kwargs["result"]
|
|
||||||
kwargs["total"] = 0
|
kwargs["total"] = 0
|
||||||
kwargs["total_quantity"] = 0
|
kwargs["total_quantity"] = 0
|
||||||
kwargs["benefit"] = 0
|
kwargs["benefit"] = 0
|
||||||
|
|
||||||
form = self.get_form()
|
form: SellingsForm = self.get_form()
|
||||||
if form.is_valid():
|
if form.is_valid() and any(v for v in form.cleaned_data.values()):
|
||||||
qs = Selling.objects.filter(club=self.object)
|
filters = form.to_filter_schema()
|
||||||
if not len([v for v in form.cleaned_data.values() if v is not None]):
|
qs = filters.filter(Selling.objects.filter(club=self.object))
|
||||||
qs = Selling.objects.none()
|
|
||||||
if form.cleaned_data["begin_date"]:
|
|
||||||
qs = qs.filter(date__gte=form.cleaned_data["begin_date"])
|
|
||||||
if form.cleaned_data["end_date"]:
|
|
||||||
qs = qs.filter(date__lte=form.cleaned_data["end_date"])
|
|
||||||
|
|
||||||
if form.cleaned_data["counters"]:
|
|
||||||
qs = qs.filter(counter__in=form.cleaned_data["counters"])
|
|
||||||
|
|
||||||
selected_products = []
|
|
||||||
if form.cleaned_data["products"]:
|
|
||||||
selected_products.extend(form.cleaned_data["products"])
|
|
||||||
if form.cleaned_data["archived_products"]:
|
|
||||||
selected_products.extend(form.cleaned_data["archived_products"])
|
|
||||||
|
|
||||||
if len(selected_products) > 0:
|
|
||||||
qs = qs.filter(product__in=selected_products)
|
|
||||||
|
|
||||||
kwargs["total"] = qs.annotate(
|
kwargs["total"] = qs.annotate(
|
||||||
price=F("quantity") * F("unit_price")
|
price=F("quantity") * F("unit_price")
|
||||||
).aggregate(total=Sum("price", default=0))["total"]
|
).aggregate(total=Sum("price", default=0))["total"]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from datetime import datetime
|
||||||
from typing import Annotated, Self
|
from typing import Annotated, Self
|
||||||
|
|
||||||
from annotated_types import MinLen
|
from annotated_types import MinLen
|
||||||
@@ -100,3 +101,10 @@ class ProductFilterSchema(FilterSchema):
|
|||||||
product_type: set[int] | None = Field(None, q="product_type__in")
|
product_type: set[int] | None = Field(None, q="product_type__in")
|
||||||
club: set[int] | None = Field(None, q="club__in")
|
club: set[int] | None = Field(None, q="club__in")
|
||||||
counter: set[int] | None = Field(None, q="counters__in")
|
counter: set[int] | None = Field(None, q="counters__in")
|
||||||
|
|
||||||
|
|
||||||
|
class SaleFilterSchema(FilterSchema):
|
||||||
|
before: datetime | None = Field(None, q="date__lt")
|
||||||
|
after: datetime | None = Field(None, q="date__gt")
|
||||||
|
counters: set[int] | None = Field(None, q="counter__in")
|
||||||
|
products: set[int] | None = Field(None, q="product__in")
|
||||||
|
|||||||
Reference in New Issue
Block a user