diff --git a/blog/migrations/0006_post_meta_description_post_meta_description_ar_ar_and_more.py b/blog/migrations/0006_post_meta_description_post_meta_description_ar_ar_and_more.py index 25fae75f..582bea7e 100644 --- a/blog/migrations/0006_post_meta_description_post_meta_description_ar_ar_and_more.py +++ b/blog/migrations/0006_post_meta_description_post_meta_description_ar_ar_and_more.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("blog", "0005_post_content_fa_ir_post_content_he_il_and_more"), ] diff --git a/core/filters.py b/core/filters.py index 7b3e66ac..5fd261fa 100644 --- a/core/filters.py +++ b/core/filters.py @@ -5,10 +5,10 @@ import uuid from django.core.exceptions import BadRequest from django.db.models import ( Avg, - BooleanField, Case, Exists, FloatField, + IntegerField, Max, OuterRef, Prefetch, @@ -33,7 +33,7 @@ from django_filters import ( ) from core.elasticsearch import process_query -from core.models import Address, Brand, Category, Feedback, Order, Product, Wishlist +from core.models import Address, Brand, Category, Feedback, Order, Product, Stock, Wishlist logger = logging.getLogger("django") @@ -276,41 +276,43 @@ class ProductFilter(FilterSet): ordering_param = self.data.get("order_by", "") + stock_with_price = Stock.objects.filter(product_id=OuterRef("pk"), price__gt=0) + stock_with_qty = Stock.objects.filter(product_id=OuterRef("pk"), quantity__gt=0) + qs = qs.annotate( - has_stock=Case( - When(stocks__quantity__gt=0, then=Value(True)), - default=Value(False), - output_field=BooleanField(), - ), - has_price=Case( - When(stocks__price__gt=0, then=Value(True)), - default=Value(False), - output_field=BooleanField(), - ), + has_price=Exists(stock_with_price), + has_stock=Exists(stock_with_qty), ).annotate( - personal_orders_only=Case( - When(has_stock=False, has_price=False, then=Value(True)), - default=Value(False), - output_field=BooleanField(), + personal_order_tail=Case( + When(Q(has_price=False) | Q(has_stock=False), then=Value(1)), + default=Value(0), + output_field=IntegerField(), ) ) requested = [part.strip() for part in ordering_param.split(",") if part.strip()] if ordering_param else [] - mapped_requested = [] + mapped_requested: list[str] = [] + for part in requested: desc = part.startswith("-") key = part.lstrip("-") + if key == "price": key = "price_order" + if key == "random": - key = "?" - mapped_requested.append(key) + mapped_requested.append("?") continue - if key == "personal_orders_only": + + if key in {"personal_orders_only", "personal_order_only", "personal_order_tail"}: continue + mapped_requested.append(f"-{key}" if desc else key) - final_ordering = mapped_requested + ["personal_orders_only"] + if "?" in mapped_requested: + final_ordering = ["personal_order_tail", "?"] + else: + final_ordering = mapped_requested + ["personal_order_tail"] if final_ordering: qs = qs.order_by(*final_ordering) diff --git a/core/graphene/schema.py b/core/graphene/schema.py index 5382cb66..dcb1730f 100644 --- a/core/graphene/schema.py +++ b/core/graphene/schema.py @@ -1,22 +1,22 @@ 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 django.db.models import Case, Exists, IntegerField, OuterRef, Q, Value, When +from django.utils import timezone from graphene import Field, List, ObjectType, Schema from graphene_django.filter import DjangoFilterConnectionField from blog.filters import PostFilter from blog.graphene.object_types import PostType from core.filters import ( + AddressFilter, BrandFilter, CategoryFilter, FeedbackFilter, OrderFilter, ProductFilter, WishlistFilter, - AddressFilter, ) from core.graphene.mutations import ( AddOrderProduct, @@ -44,6 +44,7 @@ from core.graphene.mutations import ( UpdateProduct, ) from core.graphene.object_types import ( + AddressType, AttributeGroupType, BrandType, CategoryTagType, @@ -61,9 +62,9 @@ from core.graphene.object_types import ( StockType, VendorType, WishlistType, - AddressType, ) from core.models import ( + Address, AttributeGroup, Brand, Category, @@ -79,7 +80,6 @@ from core.models import ( Stock, Vendor, Wishlist, - Address, ) from core.utils import get_project_parameters from core.utils.languages import get_flag_by_language @@ -163,35 +163,24 @@ class Query(ObjectType): .prefetch_related("images", "stocks") ) - base_qs = ( + stock_with_price = Stock.objects.filter(product_id=OuterRef("pk"), price__gt=0) + stock_with_qty = Stock.objects.filter(product_id=OuterRef("pk"), quantity__gt=0) + + return ( 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(), - ) - ), + has_price=Exists(stock_with_price), + has_stock=Exists(stock_with_qty), ) .annotate( - personal_order_only=Case( - When(has_stock=0, has_price=1, then=Value(True)), - default=Value(False), - output_field=BooleanField(), + personal_order_tail=Case( + When(Q(has_price=False) | Q(has_stock=False), then=Value(1)), + default=Value(0), + output_field=IntegerField(), ) ) - .order_by("personal_order_only") + .order_by("personal_order_tail") ) - return base_qs - @staticmethod def resolve_orders(_parent, info, **kwargs): orders = Order.objects diff --git a/storefront/public/robots.txt b/storefront/public/robots.txt index a4a4a489..ddd16e59 100644 --- a/storefront/public/robots.txt +++ b/storefront/public/robots.txt @@ -1,12 +1,9 @@ User-agent: * -Disallow: /admin/ -Disallow: /static/ -Disallow: /media/ -Disallow: /public/wishlist/ -Disallow: /public/cart/ -Disallow: /public/checkout/ -Disallow: /auth/sign-in/ -Disallow: /auth/sign-up/ +Disallow: /*/public/wishlist/ +Disallow: /*/public/cart/ +Disallow: /*/public/checkout/ +Disallow: /*/auth/sign-in/ +Disallow: /*/auth/sign-up/ Allow: /