Exemplo n.º 1
0
def get_product_context(request, product, language=None):   # noqa (C901)
    """
    Get product context

    Used in `shuup.front.views.product:ProductDetailView`

    :return: A context dict containing everything needed to render product view
    :rtype: dict
    """
    if not language:
        language = get_language()

    shop_product = product.get_shop_instance(request.shop)
    context = {}
    context["product"] = product
    context["category"] = shop_product.primary_category
    context["orderability_errors"] = list(shop_product.get_orderability_errors(
        supplier=None, quantity=1, customer=request.customer, ignore_minimum=True))
    context["variation_children"] = []
    if product.mode == ProductMode.SIMPLE_VARIATION_PARENT:
        context["variation_children"] = cache_product_things(
            request,
            sorted(
                product.variation_children.language(language).all(),
                key=lambda p: get_string_sort_order(p.variation_name or p.name)
            )
        )
        context["orderable_variation_children"] = []
        for p in context["variation_children"]:
            try:
                if p.get_shop_instance(request.shop).is_orderable(supplier=None, customer=request.customer, quantity=1):
                    context["orderable_variation_children"].append(p)
            except ShopProduct.DoesNotExist:
                pass

    elif product.mode == ProductMode.VARIABLE_VARIATION_PARENT:
        variation_variables = product.variation_variables.all().prefetch_related("values")
        orderable_children, is_orderable = get_orderable_variation_children(product, request, variation_variables)
        context["orderable_variation_children"] = orderable_children
        context["variation_orderable"] = is_orderable
        context["variation_variables"] = variation_variables
    elif product.is_container():
        children = product.get_all_package_children().translated().order_by("translations__name")
        context["package_children"] = cache_product_things(request, children)

    context["shop_product"] = shop_product
    context["attributes"] = product.attributes.filter(
        attribute__visibility_mode=AttributeVisibility.SHOW_ON_PRODUCT_PAGE)
    context["primary_image"] = shop_product.public_primary_image
    context["images"] = shop_product.public_images
    context["order_form"] = _get_order_form(request, context, product, language)

    for provide_object in get_provide_objects("product_context_extra"):
        provider = provide_object(request, product, language)
        if provider.provides_extra_context():
            context.update(provider.extra_context)

    return context
Exemplo n.º 2
0
def get_product_context(request, product, language=None):
    """
    Get product context

    Used in `shuup.front.views.product:ProductDetailView`

    :return: A context dict containing everything needed to render product view
    :rtype: dict
    """
    if not language:
        language = get_language()

    shop_product = product.get_shop_instance(request.shop)
    context = {}
    context["product"] = product
    context["category"] = shop_product.primary_category
    context["orderability_errors"] = list(shop_product.get_orderability_errors(
        supplier=None, quantity=1, customer=request.customer, ignore_minimum=True))
    context["variation_children"] = []
    if product.mode == ProductMode.SIMPLE_VARIATION_PARENT:
        context["variation_children"] = cache_product_things(
            request,
            sorted(
                product.variation_children.language(language).all(),
                key=lambda p: get_string_sort_order(p.variation_name or p.name)
            )
        )
        context["orderable_variation_children"] = [
            p for p in context["variation_children"]
            if p.get_shop_instance(request.shop).is_orderable(supplier=None, customer=request.customer, quantity=1)
        ]
    elif product.mode == ProductMode.VARIABLE_VARIATION_PARENT:
        variation_variables = product.variation_variables.all().prefetch_related("values")
        orderable_children, is_orderable = get_orderable_variation_children(product, request, variation_variables)
        context["orderable_variation_children"] = orderable_children
        context["variation_orderable"] = is_orderable
        context["variation_variables"] = variation_variables
    elif product.is_container():
        children = product.get_all_package_children().translated().order_by("translations__name")
        context["package_children"] = cache_product_things(request, children)

    context["shop_product"] = shop_product
    context["attributes"] = product.attributes.filter(
        attribute__visibility_mode=AttributeVisibility.SHOW_ON_PRODUCT_PAGE)
    context["primary_image"] = shop_product.public_primary_image
    context["images"] = shop_product.public_images
    context["order_form"] = _get_order_form(request, context, product, language)

    for provide_object in get_provide_objects("product_context_extra"):
        provider = provide_object(request, product, language)
        if provider.provides_extra_context():
            context.update(provider.extra_context)

    return context
Exemplo n.º 3
0
    def get_context_data(self, **kwargs):
        context = super(ProductDetailView, self).get_context_data(**kwargs)
        language = self.language = get_language()
        product = self.object
        context["category"] = self.shop_product.primary_category
        context["orderability_errors"] = list(self.shop_product.get_orderability_errors(
            supplier=None,
            quantity=1,
            customer=self.request.customer,
            ignore_minimum=True
        ))
        context["variation_children"] = []
        if product.mode == ProductMode.SIMPLE_VARIATION_PARENT:
            context["variation_children"] = cache_product_things(
                self.request,
                sorted(
                    product.variation_children.language(language).all(),
                    key=lambda p: get_string_sort_order(p.variation_name or p.name)
                )
            )
            context["orderable_variation_children"] = [
                p for p in context["variation_children"]
                if p.get_shop_instance(self.request.shop).is_orderable(
                    supplier=None,
                    customer=self.request.customer,
                    quantity=1
                )
            ]
        elif product.mode == ProductMode.VARIABLE_VARIATION_PARENT:
            context["variation_variables"] = product.variation_variables.all().prefetch_related("values")
        elif product.mode == ProductMode.PACKAGE_PARENT:
            children = (
                product.get_all_package_children()
                .translated()
                .order_by("translations__name")
            )
            context["package_children"] = cache_product_things(self.request, children)

        context["shop_product"] = self.shop_product

        primary_image = None
        if self.shop_product.shop_primary_image_id:
            primary_image = self.shop_product.shop_primary_image
        elif product.primary_image_id:
            primary_image = self.shop_product.primary_image

        context["primary_image"] = primary_image
        context["images"] = self.shop_product.images.all()

        # TODO: Maybe add hook for ProductDetailView get_context_data?
        # dispatch_hook("get_context_data", view=self, context=context)

        return context
Exemplo n.º 4
0
def get_product_context(request, product, language=None):
    """
    Get product context

    Used in `shuup.front.views.product:ProductDetailView`

    :return: A context dict containing everything needed to render product view
    :rtype: dict
    """

    if not language:
        language = get_language()

    shop_product = product.get_shop_instance(request.shop)
    context = {}
    context["product"] = product
    context["category"] = shop_product.primary_category
    context["orderability_errors"] = list(
        shop_product.get_orderability_errors(supplier=None,
                                             quantity=1,
                                             customer=request.customer,
                                             ignore_minimum=True))
    context["variation_children"] = []
    if product.mode == ProductMode.SIMPLE_VARIATION_PARENT:
        context["variation_children"] = cache_product_things(
            request,
            sorted(product.variation_children.language(language).all(),
                   key=lambda p: get_string_sort_order(p.variation_name or p.
                                                       name)))
        context["orderable_variation_children"] = [
            p for p in context["variation_children"]
            if p.get_shop_instance(request.shop).is_orderable(
                supplier=None, customer=request.customer, quantity=1)
        ]
    elif product.mode == ProductMode.VARIABLE_VARIATION_PARENT:
        context["variation_variables"] = product.variation_variables.all(
        ).prefetch_related("values")
    elif product.mode == ProductMode.PACKAGE_PARENT:
        children = product.get_all_package_children().translated().order_by(
            "translations__name")
        context["package_children"] = cache_product_things(request, children)

    context["shop_product"] = shop_product
    context["attributes"] = product.attributes.filter(
        attribute__visibility_mode=AttributeVisibility.SHOW_ON_PRODUCT_PAGE)
    context["primary_image"] = shop_product.public_primary_image
    context["images"] = shop_product.public_images
    return context
Exemplo n.º 5
0
def get_best_selling_products(context,
                              n_products=12,
                              cutoff_days=30,
                              orderable_only=True):
    request = context["request"]
    data = get_best_selling_product_info(shop_ids=[request.shop.pk],
                                         cutoff_days=cutoff_days)
    product_ids = [d[0] for d in data][:n_products]

    products = []
    if orderable_only:
        # get suppliers for later use
        suppliers = Supplier.objects.all()
    for product in Product.objects.filter(id__in=product_ids):
        shop_product = product.get_shop_instance(request.shop)
        if orderable_only:
            for supplier in suppliers:
                if shop_product.is_orderable(
                        supplier, request.customer,
                        shop_product.minimum_purchase_quantity):
                    products.append(product)
                    break
        elif shop_product.is_visible(request.customer):
            products.append(product)
    products = cache_product_things(request, products)
    products = sorted(
        products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 6
0
def get_context_data(context, request, category, product_filters):
    data = request.GET
    context["form"] = form = ProductListForm(
        request=request, shop=request.shop, category=category, data=data)
    form.full_clean()
    data = form.cleaned_data
    if "sort" in form.fields and not data.get("sort"):
        # Use first choice by default
        data["sort"] = form.fields["sort"].widget.choices[0][0]

    # TODO: Check if context cache can be utilized here
    products = Product.objects.listed(
        customer=request.customer,
        shop=request.shop
    ).filter(
        **product_filters
    ).filter(get_query_filters(request, category, data=data))

    products = get_product_queryset(products, request, category, data).distinct()
    products = post_filter_products(request, category, products, data)
    products = cache_product_things(request, products)
    products = sort_products(request, category, products, data)
    context["page_size"] = data.get("limit", 12)
    context["products"] = products

    if "supplier" in data:
        context["supplier"] = data.get("supplier")

    return context
Exemplo n.º 7
0
def get_context_data(context, request, category, product_filters):
    data = request.GET
    context["form"] = form = ProductListForm(request=request,
                                             shop=request.shop,
                                             category=category,
                                             data=data)
    form.full_clean()
    data = form.cleaned_data
    if "sort" in form.fields and not data.get("sort"):
        # Use first choice by default
        data["sort"] = form.fields["sort"].widget.choices[0][0]

    # TODO: Check if context cache can be utilized here
    products = (Product.objects.listed(
        customer=request.customer,
        shop=request.shop).filter(**product_filters).filter(
            get_query_filters(request, category, data=data)).prefetch_related(
                "sales_unit", "sales_unit__translations"))

    products = get_product_queryset(products, request, category,
                                    data).distinct()
    products = post_filter_products(request, category, products, data)
    products = cache_product_things(request, products)
    products = sort_products(request, category, products, data)
    context["page_size"] = data.get("limit", 12)
    context["products"] = products

    if "supplier" in data:
        context["supplier"] = data.get("supplier")

    return context
Exemplo n.º 8
0
def get_random_products(context, n_products=6, orderable_only=True):
    request = context["request"]
    products = _get_listed_products(
        context, n_products, ordering="?", filter_dict={"variation_parent": None}, orderable_only=orderable_only
    )
    products = cache_product_things(request, products)
    return products
Exemplo n.º 9
0
def _get_best_selling_products(cutoff_days, n_products, orderable_only, request):  # noqa (C901)
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days
    )
    combined_variation_products = defaultdict(int)
    for product_id, parent_id, qty in data:
        if parent_id:
            combined_variation_products[parent_id] += qty
        else:
            combined_variation_products[product_id] += qty
    product_ids = [
        d[0] for
        d in sorted(six.iteritems(combined_variation_products), key=lambda i: i[1], reverse=True)
    ][:n_products]
    products = []
    if orderable_only:
        # get suppliers for later use
        suppliers = Supplier.objects.filter(shops__in=[request.shop])
    for product in Product.objects.filter(id__in=product_ids):
        try:
            shop_product = product.get_shop_instance(request.shop, allow_cache=True)
        except ShopProduct.DoesNotExist:
            continue
        if orderable_only:
            for supplier in suppliers:
                if shop_product.is_orderable(supplier, request.customer, shop_product.minimum_purchase_quantity):
                    products.append(product)
                    break
        elif shop_product.is_visible(request.customer):
            products.append(product)
    products = cache_product_things(request, products)
    products = sorted(products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 10
0
    def get_context_data(self, **kwargs):
        context = super(CategoryView, self).get_context_data(**kwargs)
        category = self.object
        data = self.request.GET
        context["form"] = form = ProductListForm(request=self.request,
                                                 shop=self.request.shop,
                                                 category=category,
                                                 data=data)
        form.full_clean()
        data = form.cleaned_data
        if "sort" in form.fields and not data.get("sort"):
            # Use first choice by default
            data["sort"] = form.fields["sort"].widget.choices[0][0]

        products = Product.objects.listed(
            customer=self.request.customer, shop=self.request.shop).filter(
                shop_products__shop=self.request.shop,
                variation_parent__isnull=True,
                shop_products__categories=category).filter(
                    get_query_filters(self.request, category, data=data))
        products = get_product_queryset(products, self.request, category,
                                        data).distinct()

        products = post_filter_products(self.request, category, products, data)
        products = cache_product_things(self.request, products)
        products = sort_products(self.request, category, products, data)
        context["page_size"] = data.get("limit", 12)
        context["products"] = products
        return context
Exemplo n.º 11
0
def get_listed_products(context, n_products, ordering=None, filter_dict=None, orderable_only=True, extra_filters=None):
    """
    A cached version of _get_listed_products
    """
    request = context["request"]

    key, products = context_cache.get_cached_value(
        identifier="listed_products",
        item=cache_utils.get_listed_products_cache_item(request.shop),
        context=request,
        n_products=n_products,
        ordering=ordering,
        filter_dict=filter_dict,
        orderable_only=orderable_only,
        extra_filters=hash(str(extra_filters))
    )
    if products is not None:
        return products

    products = _get_listed_products(
        context,
        n_products,
        ordering=ordering,
        filter_dict=filter_dict,
        orderable_only=orderable_only,
        extra_filters=extra_filters
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 12
0
def get_best_selling_products(context, n_products=12, cutoff_days=30, orderable_only=True):
    request = context["request"]
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days
    )
    combined_variation_products = defaultdict(int)
    for product_id, parent_id, qty in data:
        if parent_id:
            combined_variation_products[parent_id] += qty
        else:
            combined_variation_products[product_id] += qty
    product_ids = [
        d[0] for d in sorted(six.iteritems(combined_variation_products), key=lambda i: i[1], reverse=True)][:n_products]
    products = []
    if orderable_only:
        # get suppliers for later use
        suppliers = Supplier.objects.all()
    for product in Product.objects.filter(id__in=product_ids):
        shop_product = product.get_shop_instance(request.shop)
        if orderable_only:
            for supplier in suppliers:
                if shop_product.is_orderable(supplier, request.customer, shop_product.minimum_purchase_quantity):
                    products.append(product)
                    break
        elif shop_product.is_visible(request.customer):
            products.append(product)
    products = cache_product_things(request, products)
    products = sorted(products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 13
0
def get_products_for_categories(context,
                                categories,
                                n_products=6,
                                orderable_only=True):
    request = context["request"]
    key, products = context_cache.get_cached_value(
        identifier="products_for_category",
        item=cache_utils.get_products_for_category_cache_item(request.shop),
        context=request,
        n_products=n_products,
        categories=categories,
        orderable_only=orderable_only)
    if products is not None:
        return products

    products = _get_listed_products(context,
                                    n_products,
                                    ordering="?",
                                    filter_dict={
                                        "variation_parent": None,
                                        "shop_products__categories__in":
                                        categories
                                    },
                                    orderable_only=orderable_only)
    products = cache_product_things(request, products)
    context_cache.set_cached_value(
        key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 14
0
def get_random_products(context,
                        n_products=6,
                        orderable_only=True,
                        sale_items_only=False):
    request = context["request"]
    key, product_ids = context_cache.get_cached_value(
        identifier="random_products",
        item=None,
        context=request,
        n_products=n_products,
        orderable_only=orderable_only,
        sale_items_only=sale_items_only)
    if product_ids is not None and _can_use_cache(product_ids, request.shop,
                                                  request.customer):
        return Product.objects.filter(id__in=product_ids)

    products = get_listed_products(context,
                                   n_products,
                                   ordering="?",
                                   filter_dict={"variation_parent": None},
                                   orderable_only=orderable_only,
                                   sale_items_only=sale_items_only)
    products = cache_product_things(request, products)
    product_ids = [product.id for product in products]
    context_cache.set_cached_value(
        key, product_ids, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 15
0
def get_products_for_category(context,
                              category,
                              n_products=6,
                              orderable_only=True):
    request = context["request"]
    key, products = context_cache.get_cached_value(
        identifier="products_for_category",
        item=None,
        context=request,
        n_products=n_products,
        category=category,
        orderable_only=orderable_only)
    if products is not None and _can_use_cache(products, request.shop,
                                               request.customer):
        return products

    products = get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None,
            "shop_products__categories__in": category
        },
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(
        key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 16
0
def get_products_for_categories(context,
                                categories,
                                n_products=6,
                                orderable_only=True):
    request = context["request"]
    key, product_ids = context_cache.get_cached_value(
        identifier="products_for_category",
        item=cache_utils.get_products_for_category_cache_item(request.shop),
        context=request,
        n_products=n_products,
        categories=categories,
        orderable_only=orderable_only)
    if product_ids is not None and _can_use_cache(product_ids, request.shop,
                                                  request.customer):
        return Product.objects.filter(id__in=product_ids)

    products = get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None,
            "shop_products__categories__in": categories
        },
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    product_ids = [product.id for product in products]
    context_cache.set_cached_value(
        key, product_ids, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 17
0
def get_listed_products(context,
                        n_products,
                        ordering=None,
                        filter_dict=None,
                        orderable_only=True,
                        extra_filters=None):
    """
    A cached version of _get_listed_products
    """
    request = context["request"]

    key, products = context_cache.get_cached_value(
        identifier="listed_products",
        item=cache_utils.get_listed_products_cache_item(request.shop),
        context=request,
        n_products=n_products,
        ordering=ordering,
        filter_dict=filter_dict,
        orderable_only=orderable_only,
        extra_filters=hash(str(extra_filters)))
    if products is not None:
        return products

    products = _get_listed_products(context,
                                    n_products,
                                    ordering=ordering,
                                    filter_dict=filter_dict,
                                    orderable_only=orderable_only,
                                    extra_filters=extra_filters)
    products = cache_product_things(request, products)
    context_cache.set_cached_value(
        key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 18
0
def get_products_for_categories(context, categories, n_products=6, orderable_only=True):
    request = context["request"]
    key, products = context_cache.get_cached_value(
        identifier="products_for_category",
        item=cache_utils.get_products_for_category_cache_item(request.shop),
        context=request,
        n_products=n_products,
        categories=categories,
        orderable_only=orderable_only
    )
    if products is not None:
        return products

    products = _get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None,
            "shop_products__categories__in": categories
        },
        orderable_only=orderable_only
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 19
0
def get_random_products(context, n_products=6, orderable_only=True, sale_items_only=False):
    request = context["request"]
    key, products = context_cache.get_cached_value(
        identifier="random_products",
        item=cache_utils.get_random_products_cache_item(request.shop),
        context=request,
        n_products=n_products, orderable_only=orderable_only,
        sale_items_only=sale_items_only
    )
    if products is not None:
        return products

    products = get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None
        },
        orderable_only=orderable_only,
        sale_items_only=sale_items_only
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 20
0
def _get_best_selling_products(cutoff_days, n_products, orderable_only, request, supplier=None):
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days,
        supplier=supplier,
        orderable_only=orderable_only,
        quantity=n_products,
    )
    sorted_product_ids = sorted(data, key=lambda item: item[1], reverse=True)
    product_ids = [item[0] for item in sorted_product_ids]

    catalog = ProductCatalog(
        ProductCatalogContext(
            shop=request.shop,
            user=getattr(request, "user", None),
            supplier=supplier,
            contact=getattr(request, "customer", None),
            purchasable_only=orderable_only,
            visibility=ShopProductVisibility.LISTED,
        )
    )
    valid_products_qs = (
        catalog.get_products_queryset()
        .filter(id__in=product_ids, mode__in=ProductMode.get_parent_modes())
        .distinct()[:n_products]
    )

    products = cache_product_things(request, valid_products_qs)
    # order products by the best selling order
    products = sorted(products, key=lambda product: product_ids.index(product.pk))
    return products
Exemplo n.º 21
0
    def get_context_data(self, **kwargs):
        context = super(CategoryView, self).get_context_data(**kwargs)
        category = self.object
        data = self.request.GET
        context["form"] = form = ProductListForm(
            request=self.request, shop=self.request.shop, category=category, data=data)
        form.full_clean()
        data = form.cleaned_data
        if "sort" in form.fields and not data.get("sort"):
            # Use first choice by default
            data["sort"] = form.fields["sort"].widget.choices[0][0]

        # TODO: Check if context cache can be utilized here
        products = Product.objects.listed(
            customer=self.request.customer,
            shop=self.request.shop
        ).filter(
            shop_products__shop=self.request.shop,
            variation_parent__isnull=True,
            shop_products__categories=category
        ).filter(get_query_filters(self.request, category, data=data))
        products = get_product_queryset(products, self.request, category, data).distinct()

        products = post_filter_products(self.request, category, products, data)
        products = cache_product_things(self.request, products)
        products = sort_products(self.request, category, products, data)
        context["page_size"] = data.get("limit", 12)
        context["products"] = products
        return context
Exemplo n.º 22
0
    def get_context_data(self, **kwargs):
        context = super(CategoryView, self).get_context_data(**kwargs)
        category = self.object
        data = self.request.GET
        context["form"] = form = ProductListForm(request=self.request,
                                                 shop=self.request.shop,
                                                 category=category,
                                                 data=data)
        form.full_clean()
        data = form.cleaned_data
        if "sort" in form.fields and not data.get("sort"):
            # Use first choice by default
            data["sort"] = form.fields["sort"].widget.choices[0][0]

        # TODO: Check if context cache can be utilized here
        products = Product.objects.listed(
            customer=self.request.customer, shop=self.request.shop).filter(
                **self.get_product_filters()).filter(
                    get_query_filters(self.request, category, data=data))

        products = get_product_queryset(products, self.request, category,
                                        data).distinct()
        products = post_filter_products(self.request, category, products, data)
        products = cache_product_things(self.request, products)
        products = sort_products(self.request, category, products, data)
        context["page_size"] = data.get("limit", 12)
        context["products"] = products

        if "supplier" in data:
            context["supplier"] = data.get("supplier")

        return context
Exemplo n.º 23
0
    def get_context_data(self, **kwargs):
        context = super(ProductDetailView, self).get_context_data(**kwargs)
        language = self.language = get_language()
        product = self.object
        context["category"] = self.shop_product.primary_category
        context["orderability_errors"] = list(
            self.shop_product.get_orderability_errors(
                supplier=None,
                quantity=1,
                customer=self.request.customer,
                ignore_minimum=True))
        context["variation_children"] = []
        if product.mode == ProductMode.SIMPLE_VARIATION_PARENT:
            context["variation_children"] = cache_product_things(
                self.request,
                sorted(product.variation_children.language(language).all(),
                       key=lambda p: get_string_sort_order(p.variation_name or
                                                           p.name)))
            context["orderable_variation_children"] = [
                p for p in context["variation_children"]
                if p.get_shop_instance(self.request.shop).is_orderable(
                    supplier=None, customer=self.request.customer, quantity=1)
            ]
        elif product.mode == ProductMode.VARIABLE_VARIATION_PARENT:
            context["variation_variables"] = product.variation_variables.all(
            ).prefetch_related("values")
        elif product.mode == ProductMode.PACKAGE_PARENT:
            children = (product.get_all_package_children().translated().
                        order_by("translations__name"))
            context["package_children"] = cache_product_things(
                self.request, children)

        context["shop_product"] = self.shop_product

        primary_image = None
        if self.shop_product.shop_primary_image_id:
            primary_image = self.shop_product.shop_primary_image
        elif product.primary_image_id:
            primary_image = self.shop_product.primary_image

        context["primary_image"] = primary_image
        context["images"] = self.shop_product.images.all()

        # TODO: Maybe add hook for ProductDetailView get_context_data?
        # dispatch_hook("get_context_data", view=self, context=context)

        return context
Exemplo n.º 24
0
def _get_best_selling_products(cutoff_days, n_products, orderable_only,
                               request):  # noqa (C901)
    data = get_best_selling_product_info(shop_ids=[request.shop.pk],
                                         cutoff_days=cutoff_days)
    combined_variation_products = defaultdict(int)
    for product_id, parent_id, qty in data:
        if parent_id:
            combined_variation_products[parent_id] += qty
        else:
            combined_variation_products[product_id] += qty

    # get all the product ids
    product_ids = [
        d[0] for d in sorted(six.iteritems(combined_variation_products),
                             key=lambda i: i[1],
                             reverse=True)
    ]

    # group product ids in groups of n_products
    # to prevent querying ALL products at once
    products = []
    for grouped_product_ids in _group_list_items(product_ids, n_products):
        valid_products_qs = Product.objects.listed(
            shop=request.shop, customer=request.customer).filter(
                id__in=grouped_product_ids,
                shop_products__shop=request.shop,
                shop_products__suppliers__enabled=True)
        for product in valid_products_qs.iterator():
            products.append(product)

            if len(products) == n_products:
                break

        if len(products) == n_products:
            break

    if orderable_only:
        valid_products = []
        suppliers = Supplier.objects.enabled().filter(shops=request.shop)

        for product in products:
            # this instance should always exist as the listed() queryset uses the current shop as a filter
            shop_product = product.get_shop_instance(request.shop,
                                                     allow_cache=True)

            for supplier in suppliers:
                if shop_product.is_orderable(
                        supplier, request.customer,
                        shop_product.minimum_purchase_quantity):
                    valid_products.append(product)
                    break

        products = valid_products

    products = cache_product_things(request, products)
    products = sorted(
        products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 25
0
def _get_best_selling_products(cutoff_days, n_products, orderable_only, request, sale_items_only):  # noqa (C901)
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days
    )
    combined_variation_products = defaultdict(int)
    for product_id, parent_id, qty in data:
        if parent_id:
            combined_variation_products[parent_id] += qty
        else:
            combined_variation_products[product_id] += qty

    # get all the product ids
    product_ids = [
        d[0] for
        d in sorted(six.iteritems(combined_variation_products), key=lambda i: i[1], reverse=True)
    ]

    products = []
    suppliers = []
    if orderable_only:
        # get suppliers for later use
        suppliers = Supplier.objects.enabled().filter(shops__in=[request.shop])

    if sale_items_only:
        from shuup.core.pricing import PricingContext
        pricing_context = PricingContext(shop=request.shop, customer=request.customer)

    # group product ids in groups of n_products
    # to prevent querying ALL products at once
    for grouped_product_ids in _group_list_items(product_ids, n_products):
        for product in Product.objects.filter(id__in=grouped_product_ids):
            if len(products) == n_products:
                break

            if sale_items_only and not _is_sale_item(product, pricing_context):
                continue

            try:
                shop_product = product.get_shop_instance(request.shop, allow_cache=True)
            except ShopProduct.DoesNotExist:
                continue

            if orderable_only:
                for supplier in suppliers:
                    if shop_product.is_orderable(supplier, request.customer, shop_product.minimum_purchase_quantity):
                        products.append(product)
                        break

            elif shop_product.is_visible(request.customer):
                products.append(product)

        if len(products) == n_products:
            break

    products = cache_product_things(request, products)
    products = sorted(products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 26
0
def _get_best_selling_products(cutoff_days, n_products, orderable_only, request):  # noqa (C901)
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days
    )
    combined_variation_products = defaultdict(int)
    for product_id, parent_id, qty in data:
        if parent_id:
            combined_variation_products[parent_id] += qty
        else:
            combined_variation_products[product_id] += qty

    # get all the product ids
    product_ids = [
        d[0] for
        d in sorted(six.iteritems(combined_variation_products), key=lambda i: i[1], reverse=True)
    ]

    # group product ids in groups of n_products
    # to prevent querying ALL products at once
    products = []
    for grouped_product_ids in _group_list_items(product_ids, n_products):
        valid_products_qs = Product.objects.listed(
            shop=request.shop,
            customer=request.customer
        ).filter(
            id__in=grouped_product_ids,
            shop_products__shop=request.shop,
            shop_products__suppliers__enabled=True
        )
        for product in valid_products_qs.iterator():
            products.append(product)

            if len(products) == n_products:
                break

        if len(products) == n_products:
            break

    if orderable_only:
        valid_products = []
        suppliers = Supplier.objects.enabled().filter(shops=request.shop)

        for product in products:
            # this instance should always exist as the listed() queryset uses the current shop as a filter
            shop_product = product.get_shop_instance(request.shop, allow_cache=True)

            for supplier in suppliers:
                if shop_product.is_orderable(supplier, request.customer, shop_product.minimum_purchase_quantity):
                    valid_products.append(product)
                    break

        products = valid_products

    products = cache_product_things(request, products)
    products = sorted(products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 27
0
def get_newest_products(context, n_products=6, orderable_only=True):
    request = context["request"]
    products = get_listed_products(
        context,
        n_products,
        ordering="-pk",
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    return products
Exemplo n.º 28
0
def get_random_products(context, n_products=6, orderable_only=True):
    request = context["request"]
    products = get_visible_products(
        context,
        n_products,
        ordering="?",
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    return products
Exemplo n.º 29
0
 def get_context_data(self, **kwargs):
     context = super(SearchView, self).get_context_data(**kwargs)
     context["form"] = self.form
     products = context["products"]
     if products:
         products = cache_product_things(self.request, products)
         products = sort_products(self.request, products, self.form.cleaned_data.get("sort"))
         products = [p for p in products if is_visible({"request": self.request}, p)]
         context["products"] = products
     context["no_results"] = (self.form.is_valid() and not products)
     return context
Exemplo n.º 30
0
def get_products_for_categories(context, categories, n_products=6, orderable_only=True):
    request = context["request"]
    products = _get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={"variation_parent": None, "shop_products__categories__in": categories},
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    return products
Exemplo n.º 31
0
 def get_context_data(self, **kwargs):
     context = super(SearchView, self).get_context_data(**kwargs)
     context["form"] = self.form
     products = context["products"]
     if products:
         products = cache_product_things(self.request, products)
         products = sort_products(self.request, products, self.form.cleaned_data.get("sort"))
         products = [p for p in products if is_visible({"request": self.request}, p)]
         context["products"] = products
     context["no_results"] = (self.form.is_valid() and not products)
     return context
Exemplo n.º 32
0
def get_random_products(context, n_products=6, orderable_only=True):
    request = context["request"]
    products = get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None
        },
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    return products
Exemplo n.º 33
0
def get_listed_products(context, n_products, ordering=None, filter_dict=None, orderable_only=True, extra_filters=None):
    """
    A cached version of _get_listed_products
    """
    request = context["request"]
    products = _get_listed_products(
        context,
        n_products,
        ordering=ordering,
        filter_dict=filter_dict,
        orderable_only=orderable_only,
        extra_filters=extra_filters,
    )
    products = cache_product_things(request, products)
    return products
Exemplo n.º 34
0
def get_random_products(context, n_products=6, orderable_only=True):
    request = context["request"]
    key, products = context_cache.get_cached_value(
        identifier="random_products", item=None, context=request,
        n_products=n_products, orderable_only=orderable_only)
    if products is not None and _can_use_cache(products, request.shop, request.customer):
        return products

    products = get_listed_products(
        context,
        n_products,
        ordering="?",
        filter_dict={
            "variation_parent": None
        },
        orderable_only=orderable_only,
    )
    products = cache_product_things(request, products)
    context_cache.set_cached_value(key, products, settings.SHUUP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemplo n.º 35
0
def get_best_selling_products(context, n_products=12, cutoff_days=30, orderable_only=True):
    request = context["request"]
    data = get_best_selling_product_info(
        shop_ids=[request.shop.pk],
        cutoff_days=cutoff_days
    )
    product_ids = [d[0] for d in data][:n_products]

    products = []
    for product in Product.objects.filter(id__in=product_ids):
        shop_product = product.get_shop_instance(request.shop)
        if orderable_only:
            for supplier in Supplier.objects.all():
                if shop_product.is_orderable(supplier, request.customer, shop_product.minimum_purchase_quantity):
                    products.append(product)
                    break
        elif shop_product.is_visible(request.customer):
            products.append(product)
    products = cache_product_things(request, products)
    products = sorted(products, key=lambda p: product_ids.index(p.id))  # pragma: no branch
    return products
Exemplo n.º 36
0
    def get_context_data(self, **kwargs):
        context = super(CategoryView, self).get_context_data(**kwargs)
        category = self.object
        context["form"] = form = ProductListForm(data=self.request.GET)
        form.full_clean()

        filters = {
            "shop_products__shop": self.request.shop,
            "shop_products__categories": category,
            "variation_parent": None
        }
        manufacturers = form.cleaned_data.get("manufacturers")
        if manufacturers:
            filters["manufacturer__in"] = manufacturers

        products = Product.objects.listed(
            customer=self.request.customer,
            shop=self.request.shop
        ).filter(**filters).distinct()

        products = cache_product_things(self.request, products)
        products = sort_products(self.request, products, self.request.GET.get("sort"))
        context["products"] = products
        return context
Exemplo n.º 37
0
    def get_context_data(self, **kwargs):
        context = super(CategoryView, self).get_context_data(**kwargs)
        category = self.object
        context["form"] = form = ProductListForm(data=self.request.GET)
        form.full_clean()

        filters = {
            "shop_products__shop": self.request.shop,
            "shop_products__categories": category,
            "variation_parent": None
        }
        manufacturers = form.cleaned_data.get("manufacturers")
        if manufacturers:
            filters["manufacturer__in"] = manufacturers

        products = Product.objects.list_visible(
            customer=self.request.customer,
            shop=self.request.shop
        ).filter(**filters).distinct()

        products = cache_product_things(self.request, products)
        products = sort_products(self.request, products, self.request.GET.get("sort"))
        context["products"] = products
        return context