Source code for shuup.front.template_helpers.product

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2017, Shoop Commerce Ltd. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from jinja2.utils import contextfunction

from shuup.core.models import (
    AttributeVisibility, Product, ProductAttribute, ProductCrossSell,
    ProductCrossSellType, Supplier
)
from shuup.core.utils import context_cache
from shuup.utils.text import force_ascii


[docs]def get_visible_attributes(product): return ProductAttribute.objects.filter( product=product, attribute__visibility_mode=AttributeVisibility.SHOW_ON_PRODUCT_PAGE )
# Deprecated, see `get_product_cross_sells()` @contextfunction
[docs]def get_products_bought_with(context, product, count=5): related_product_cross_sells = ( ProductCrossSell.objects .filter(product1=product, type=ProductCrossSellType.COMPUTED) .order_by("-weight")[:(count * 4)]) products = [] for cross_sell in related_product_cross_sells: product2 = cross_sell.product2 if product2.is_visible_to_user(context["request"].user) and product2.is_list_visible(): products.append(product2) if len(products) >= count: break return products
@contextfunction
[docs]def is_visible(context, product): request = context["request"] key, val = context_cache.get_cached_value(identifier="is_visible", item=product, context=request) if val is not None: return val shop_product = product.get_shop_instance(shop=request.shop, allow_cache=True) for error in shop_product.get_visibility_errors(customer=request.customer): # pragma: no branch context_cache.set_cached_value(key, False) return False context_cache.set_cached_value(key, True) return True
@contextfunction
[docs]def get_product_cross_sells( context, product, relation_type=ProductCrossSellType.RELATED, count=4, orderable_only=True): request = context["request"] rtype = map_relation_type(relation_type) related_product_ids = list(( ProductCrossSell.objects .filter(product1=product, type=rtype) .order_by("weight")[:(count * 4)]).values_list("product2_id", flat=True) ) related_products = [] for product in Product.objects.filter(id__in=related_product_ids): shop_product = product.get_shop_instance(request.shop, allow_cache=True) if orderable_only: for supplier in Supplier.objects.all(): if shop_product.is_orderable( supplier, request.customer, shop_product.minimum_purchase_quantity, allow_cache=True): related_products.append(product) break elif shop_product.is_visible(request.customer): related_products.append(product) # Order related products by weight. Related product ids is in weight order. # If same related product is linked twice to product then lowest weight stands. related_products.sort(key=lambda prod: list(related_product_ids).index(prod.id)) return related_products[:count]
[docs]def map_relation_type(relation_type): """ Map relation type to enum value. :type relation_type: ProductCrossSellType|str :rtype: ProductCrossSellType :raises: `LookupError` if unknown string is given """ if isinstance(relation_type, ProductCrossSellType): return relation_type attr_name = force_ascii(relation_type).upper() try: return getattr(ProductCrossSellType, attr_name) except AttributeError: raise LookupError('Unknown ProductCrossSellType %r' % (relation_type,))
[docs]def get_shop_product(product, shop): return product.get_shop_instance(shop, get_shop_instance=True)