Source code for shuup.discounts.plugins

from django import forms
from django.db.models import Q
from django.utils.translation import gettext_lazy as _

from shuup.discounts.models import Discount
from shuup.front.template_helpers.general import get_listed_products
from shuup.xtheme import TemplatedPlugin
from shuup.xtheme.plugins.forms import GenericPluginForm, TranslatableField


[docs] class ProductSelectionConfigForm(GenericPluginForm): """ A configuration form for the DiscountedProductsPlugin """
[docs] def populate(self): """ A custom populate method to display product choices """ for field in self.plugin.fields: if isinstance(field, tuple): name, value = field value.initial = self.plugin.config.get(name, value.initial) self.fields[name] = value discounts_qs = Discount.objects.filter( Q(shop=self.request.shop, active=True), Q(Q(product__isnull=False) | Q(category__isnull=False, exclude_selected_category=False)), ) self.fields["discounts"] = forms.ModelMultipleChoiceField( queryset=discounts_qs, label=_("Discounts"), help_text=_( "Select all discounts to render products from. Only active discounts that have " "product or category linked are available." ), required=True, initial=self.plugin.config.get("discounts", None), )
[docs] def clean(self): """ A custom clean method to transform selected discounts into a list of ids """ cleaned_data = super().clean() if cleaned_data.get("discounts"): cleaned_data["discounts"] = [discount.pk for discount in cleaned_data["discounts"]] return cleaned_data
[docs] class DiscountedProductsPlugin(TemplatedPlugin): identifier = "discount_product" name = _("Discounted Products") template_name = "shuup/discounts/product_discount_plugin.jinja" editor_form_class = ProductSelectionConfigForm fields = [ ("title", TranslatableField(label=_("Title"), required=False, initial="")), ("count", forms.IntegerField(label=_("Count"), min_value=1, initial=4)), ( "orderable_only", forms.BooleanField( label=_("Only show in-stock and orderable items"), help_text=_( "Warning: The final number of products can be lower than 'Count' " "as it will filter out unorderable products from a set of 'Count' products." ), initial=True, required=False, ), ), ]
[docs] def get_context_data(self, context): count = self.config.get("count", 4) orderable_only = self.config.get("orderable_only", True) discounts = self.config.get("discounts") products = [] if discounts: # make sure to have only available discounts discounts = Discount.objects.available(shop=context["request"].shop).filter(pk__in=discounts) extra_filters = Q( Q(product_discounts__in=discounts) | Q(shop_products__categories__category_discounts__in=discounts) ) products = get_listed_products( context, count, orderable_only=orderable_only, extra_filters=extra_filters, ) return { "request": context["request"], "title": self.get_translated_value("title"), "products": products, }