Features: 1) Add discount_price field to ProductDetailSerializer, PromotionDetailSerializer, and Product GraphQL type; 2) Introduce promos and discount_price properties in the Product model;
Fixes: None; Extra: 1) Update field inclusion lists and methods in serializers to reflect the new `discount_price` field; 2) Add model property caching for `discount_price`;
This commit is contained in:
parent
75cc74e592
commit
753a2059d4
4 changed files with 25 additions and 0 deletions
|
|
@ -481,6 +481,7 @@ class ProductType(DjangoObjectType): # type: ignore [misc]
|
||||||
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."))
|
rating = Float(description=_("rating value from 1 to 10, inclusive, or 0 if not set."))
|
||||||
|
discount_price = Float(description=_("discount price"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Product
|
model = Product
|
||||||
|
|
@ -577,6 +578,9 @@ class ProductType(DjangoObjectType): # type: ignore [misc]
|
||||||
"hreflang": info.context.LANGUAGE_CODE,
|
"hreflang": info.context.LANGUAGE_CODE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def resolve_discount_price(self: Product, _info) -> float | None:
|
||||||
|
return self.discount_price
|
||||||
|
|
||||||
|
|
||||||
class AttributeValueType(DjangoObjectType): # type: ignore [misc]
|
class AttributeValueType(DjangoObjectType): # type: ignore [misc]
|
||||||
value = String(description=_("attribute value"))
|
value = String(description=_("attribute value"))
|
||||||
|
|
|
||||||
|
|
@ -658,6 +658,17 @@ class Product(ExportModelOperationsMixin("product"), NiceModel): # type: ignore
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def promos(self) -> QuerySet["Promotion"]:
|
||||||
|
return Promotion.objects.filter(
|
||||||
|
is_active=True,
|
||||||
|
products__in=[self.pk],
|
||||||
|
).order_by("-discount_percent")
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def discount_price(self) -> float | None:
|
||||||
|
return self.promos.first().discount_percent if self.promos.exists() else None # type: ignore [union-attr]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rating(self) -> float:
|
def rating(self) -> float:
|
||||||
feedbacks = Feedback.objects.filter(order_product__product_id=self.pk)
|
feedbacks = Feedback.objects.filter(order_product__product_id=self.pk)
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,7 @@ class ProductDetailSerializer(ModelSerializer):
|
||||||
price = SerializerMethodField()
|
price = SerializerMethodField()
|
||||||
quantity = SerializerMethodField()
|
quantity = SerializerMethodField()
|
||||||
feedbacks_count = SerializerMethodField()
|
feedbacks_count = SerializerMethodField()
|
||||||
|
discount_price = SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Product
|
model = Product
|
||||||
|
|
@ -308,6 +309,7 @@ class ProductDetailSerializer(ModelSerializer):
|
||||||
"price",
|
"price",
|
||||||
"created",
|
"created",
|
||||||
"modified",
|
"modified",
|
||||||
|
"discount_price",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_rating(self, obj: Product) -> float:
|
def get_rating(self, obj: Product) -> float:
|
||||||
|
|
@ -322,6 +324,9 @@ class ProductDetailSerializer(ModelSerializer):
|
||||||
def get_quantity(self, obj: Product) -> int:
|
def get_quantity(self, obj: Product) -> int:
|
||||||
return obj.quantity
|
return obj.quantity
|
||||||
|
|
||||||
|
def get_discount_price(self, obj: Product) -> float | None:
|
||||||
|
return obj.discount_price
|
||||||
|
|
||||||
|
|
||||||
class PromotionDetailSerializer(ModelSerializer):
|
class PromotionDetailSerializer(ModelSerializer):
|
||||||
products = ProductDetailSerializer(
|
products = ProductDetailSerializer(
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@ class ProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
|
||||||
quantity = SerializerMethodField()
|
quantity = SerializerMethodField()
|
||||||
feedbacks_count = SerializerMethodField()
|
feedbacks_count = SerializerMethodField()
|
||||||
personal_orders_only = SerializerMethodField()
|
personal_orders_only = SerializerMethodField()
|
||||||
|
discount_price = SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Product
|
model = Product
|
||||||
|
|
@ -178,6 +179,7 @@ class ProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
|
||||||
"rating",
|
"rating",
|
||||||
"price",
|
"price",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"discount_price",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_rating(self, obj: Product) -> float:
|
def get_rating(self, obj: Product) -> float:
|
||||||
|
|
@ -195,6 +197,9 @@ class ProductSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
|
||||||
def get_personal_orders_only(self, obj: Product) -> bool:
|
def get_personal_orders_only(self, obj: Product) -> bool:
|
||||||
return obj.personal_orders_only
|
return obj.personal_orders_only
|
||||||
|
|
||||||
|
def get_discount_price(self, obj: Product) -> float | None:
|
||||||
|
return obj.discount_price
|
||||||
|
|
||||||
|
|
||||||
class VendorSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
|
class VendorSimpleSerializer(ModelSerializer): # type: ignore [type-arg]
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue