Merge branch 'main' into storefront-nuxt
This commit is contained in:
commit
3d4df235f2
2 changed files with 61 additions and 2 deletions
|
|
@ -16,6 +16,7 @@ from django.db.models import (
|
||||||
When,
|
When,
|
||||||
Max,
|
Max,
|
||||||
Prefetch,
|
Prefetch,
|
||||||
|
BooleanField,
|
||||||
)
|
)
|
||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
from django.utils.http import urlsafe_base64_decode
|
from django.utils.http import urlsafe_base64_decode
|
||||||
|
|
@ -92,6 +93,7 @@ class ProductFilter(FilterSet):
|
||||||
("price_order", "price"),
|
("price_order", "price"),
|
||||||
("sku", "sku"),
|
("sku", "sku"),
|
||||||
("?", "random"),
|
("?", "random"),
|
||||||
|
("personal_order_only", "personal_order_only"),
|
||||||
),
|
),
|
||||||
initial="uuid",
|
initial="uuid",
|
||||||
)
|
)
|
||||||
|
|
@ -279,8 +281,8 @@ class ProductFilter(FilterSet):
|
||||||
|
|
||||||
ordering_param = self.data.get("order_by", "")
|
ordering_param = self.data.get("order_by", "")
|
||||||
if ordering_param:
|
if ordering_param:
|
||||||
order_fields = [field.strip() for field in ordering_param.split(",")]
|
order_fields_no_sign = [field.strip("-") for field in ordering_param.split(",")]
|
||||||
if any(field.lstrip("-") == "rating" for field in order_fields):
|
if "rating" in order_fields_no_sign:
|
||||||
feedback_qs = (
|
feedback_qs = (
|
||||||
Feedback.objects.filter(order_product__product_id=OuterRef("pk"))
|
Feedback.objects.filter(order_product__product_id=OuterRef("pk"))
|
||||||
.values("order_product__product_id")
|
.values("order_product__product_id")
|
||||||
|
|
@ -293,6 +295,58 @@ class ProductFilter(FilterSet):
|
||||||
Value(0, output_field=FloatField()),
|
Value(0, output_field=FloatField()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ordering_param and any(f.lstrip("-") == "price" for f in ordering_param.split(",")):
|
||||||
|
qs = qs.annotate(
|
||||||
|
price_order=Coalesce(
|
||||||
|
Max("stocks__price"),
|
||||||
|
Value(0.0),
|
||||||
|
output_field=FloatField(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
qs = 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(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
requested = [part.strip() for part in ordering_param.split(",") if part.strip()] if ordering_param else []
|
||||||
|
mapped_requested = []
|
||||||
|
for part in requested:
|
||||||
|
desc = part.startswith("-")
|
||||||
|
key = part.lstrip("-")
|
||||||
|
if key == "price":
|
||||||
|
key = "price_order"
|
||||||
|
if key == "random":
|
||||||
|
key = "?"
|
||||||
|
mapped_requested.append(key)
|
||||||
|
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
|
||||||
|
|
||||||
|
if final_ordering:
|
||||||
|
qs = qs.order_by(*final_ordering)
|
||||||
|
|
||||||
return qs.distinct()
|
return qs.distinct()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,7 @@ class ProductType(DjangoObjectType):
|
||||||
feedbacks_count = Int(description=_("number of feedbacks"))
|
feedbacks_count = Int(description=_("number of feedbacks"))
|
||||||
personal_orders_only = Boolean(description=_("only available for personal orders"))
|
personal_orders_only = Boolean(description=_("only available for personal orders"))
|
||||||
seo_meta = Field(SEOMetaType, description=_("SEO Meta snapshot"))
|
seo_meta = Field(SEOMetaType, description=_("SEO Meta snapshot"))
|
||||||
|
rating = Float(description=_("rating value from 1 to 10, inclusive, or 0 if not set."))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Product
|
model = Product
|
||||||
|
|
@ -521,6 +522,7 @@ class ProductType(DjangoObjectType):
|
||||||
"attribute_groups",
|
"attribute_groups",
|
||||||
"images",
|
"images",
|
||||||
"price",
|
"price",
|
||||||
|
"rating",
|
||||||
)
|
)
|
||||||
filter_fields = ["uuid", "name"]
|
filter_fields = ["uuid", "name"]
|
||||||
description = _("products")
|
description = _("products")
|
||||||
|
|
@ -528,6 +530,9 @@ class ProductType(DjangoObjectType):
|
||||||
def resolve_price(self: Product, _info) -> float:
|
def resolve_price(self: Product, _info) -> float:
|
||||||
return self.price or 0.0
|
return self.price or 0.0
|
||||||
|
|
||||||
|
def resolve_rating(self: Product, _info) -> float:
|
||||||
|
return self.rating or 0.0
|
||||||
|
|
||||||
def resolve_feedbacks(self: Product, _info):
|
def resolve_feedbacks(self: Product, _info):
|
||||||
if _info.context.user.has_perm("core.view_feedback"):
|
if _info.context.user.has_perm("core.view_feedback"):
|
||||||
return Feedback.objects.filter(order_product__product=self)
|
return Feedback.objects.filter(order_product__product=self)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue