Features: 1) Add annotations for has_stock, has_price, and personal_order_only in product query to enhance filtering and sorting; 2) Implement conditional ordering by personal_order_only in product query;

Fixes: 1) Remove redundant `personal_order_only` mapping from filters to fix duplicate processing; 2) Adjust sorting logic to avoid appending unneeded `personal_order_only` in filters;

Extra: 1) Add missing imports for Django model annotations and fields; 2) Refactor product query for clarity and improved handling of availability and price conditions.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-10-02 15:08:20 +03:00
parent fa97a582d3
commit a344014d9f
2 changed files with 34 additions and 4 deletions

View file

@ -96,7 +96,6 @@ class ProductFilter(FilterSet):
("price_order", "price"),
("sku", "sku"),
("?", "random"),
("personal_order_only", "personal_order_only"),
),
initial="uuid",
)
@ -312,10 +311,11 @@ class ProductFilter(FilterSet):
key = "?"
mapped_requested.append(key)
continue
if key == "personal_order_only":
continue
mapped_requested.append(f"-{key}" if desc else key)
has_personal_in_request = any(p.lstrip("-") == "personal_order_only" for p in mapped_requested)
final_ordering = (["personal_order_only"] if not has_personal_in_request else []) + mapped_requested
final_ordering = ["personal_order_only"] + mapped_requested
if final_ordering:
qs = qs.order_by(*final_ordering)

View file

@ -1,6 +1,7 @@
import logging
from django.core.cache import cache
from django.db.models import Max, Case, When, Value, IntegerField, BooleanField
from django.utils import timezone
from django.core.exceptions import PermissionDenied
from graphene import Field, List, ObjectType, Schema
@ -148,7 +149,7 @@ class Query(ObjectType):
product = Product.objects.get(uuid=kwargs["uuid"])
if product.is_active and product.brand.is_active and product.category.is_active:
info.context.user.add_to_recently_viewed(product.uuid)
return (
base_qs = (
Product.objects.all().select_related("brand", "category").prefetch_related("images", "stocks")
if info.context.user.has_perm("core.view_product")
else Product.objects.filter(
@ -162,6 +163,35 @@ class Query(ObjectType):
.prefetch_related("images", "stocks")
)
base_qs = (
base_qs.annotate(
has_stock=Max(
Case(
When(stocks__quantity__gt=0, then=Value(1)),
default=Value(0),
output_field=IntegerField(),
)
),
has_price=Max(
Case(
When(stocks__price__gt=0, then=Value(1)),
default=Value(0),
output_field=IntegerField(),
)
),
)
.annotate(
personal_order_only=Case(
When(has_stock=0, has_price=1, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
)
.order_by("personal_order_only")
)
return base_qs
@staticmethod
def resolve_orders(_parent, info, **kwargs):
orders = Order.objects