def get_fields(self, request, category=None):
        if not category:
            return

        key, val = context_cache.get_cached_value(
            identifier="productvariationfilter", item=self, context=request, category=category)
        if val:
            return val

        variation_values = defaultdict(set)
        for variation in ProductVariationVariable.objects.filter(
                Q(product__shop_products__categories=category),
                ~Q(product__shop_products__visibility=ShopProductVisibility.NOT_VISIBLE)):
            for value in variation.values.all():
                # TODO: Use ID here instead of this "trick"
                choices = (value.value.replace(" ", "*"), value.value)
                variation_values[slugify(variation.name)].add(choices)

        fields = []
        for variation_key, choices in six.iteritems(variation_values):
            fields.append((
                "variation_%s" % variation_key,
                forms.MultipleChoiceField(
                    choices=choices, required=False, label=capfirst(variation_key), widget=FilterWidget())
            ))
        context_cache.set_cached_value(key, fields)
        return fields
    def get_fields(self, request, category=None):
        if not Category.objects.exists():
            return

        key, val = context_cache.get_cached_value(
            identifier="categoryproductfilter", item=self, context=request, category=category)
        if val:
            return val

        language = get_language()
        base_queryset = Category.objects.all_visible(request.customer, request.shop, language=language)
        if category:
            q = Q(
                Q(shop_products__categories=category),
                ~Q(shop_products__visibility=ShopProductVisibility.NOT_VISIBLE)
            )
            queryset = base_queryset.filter(q).exclude(pk=category.pk).distinct()
        else:
            # Show only first level when there is no category selected
            queryset = base_queryset.filter(parent=None)

        data = [
            (
                "categories",
                forms.ModelMultipleChoiceField(
                    queryset=queryset, required=False, label=_('Categories'), widget=FilterWidget())
            ),
        ]
        context_cache.set_cached_value(key, data)
        return data
Exemple #3
0
def get_best_selling_products(context, n_products=12, cutoff_days=30, orderable_only=True):
    request = context["request"]

    key, products = context_cache.get_cached_value(
        identifier="best_selling_products", item=None, context=request,
        n_products=n_products, cutoff_days=cutoff_days, orderable_only=orderable_only)
    if products is not None and _can_use_cache(products, request.shop, request.customer):
        return products

    products = _get_best_selling_products(cutoff_days, n_products, orderable_only, request)
    context_cache.set_cached_value(key, products, settings.WSHOP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemple #4
0
def get_all_manufacturers(context):
    request = context["request"]
    key, manufacturers = context_cache.get_cached_value(
        identifier="all_manufacturers", item=None, context=request)
    if manufacturers is not None:
        return manufacturers

    products = Product.objects.listed(shop=request.shop, customer=request.customer)
    manufacturers_ids = products.values_list("manufacturer__id").distinct()
    manufacturers = Manufacturer.objects.filter(pk__in=manufacturers_ids)
    context_cache.set_cached_value(key, manufacturers, settings.WSHOP_TEMPLATE_HELPERS_CACHE_DURATION)
    return manufacturers
Exemple #5
0
 def get_shop_instance(self, shop, allow_cache=False):
     """
     :type shop: wshop.core.models.Shop
     :rtype: wshop.core.models.ShopProduct
     """
     key, val = context_cache.get_cached_value(
         identifier="shop_product", item=self, context={"shop": shop}, allow_cache=allow_cache)
     if val is not None:
         return val
     shop_inst = self.shop_products.get(shop_id=shop.id)
     context_cache.set_cached_value(key, shop_inst)
     return shop_inst
Exemple #6
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.WSHOP_TEMPLATE_HELPERS_CACHE_DURATION)
    return products
Exemple #7
0
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

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

    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
Exemple #8
0
def get_orderable_variation_children(product, request,
                                     variation_variables):  # noqa (C901)
    if not variation_variables:
        variation_variables = product.variation_variables.all(
        ).prefetch_related("values")

    key, val = context_cache.get_cached_value(
        identifier="orderable_variation_children",
        item=product,
        context=request,
        variation_variables=variation_variables)
    if val is not None:
        return val

    orderable_variation_children = OrderedDict()
    orderable = 0
    for combo_data in product.get_all_available_combinations():
        combo = combo_data["variable_to_value"]
        for k, v in six.iteritems(combo):
            if k not in orderable_variation_children:
                orderable_variation_children[k] = []

        res = ProductVariationResult.resolve(product, combo)
        try:
            shop_product = res.get_shop_instance(request.shop)
        except ShopProduct.DoesNotExist:
            continue

        if res and shop_product.is_orderable(
                supplier=None, customer=request.customer, quantity=1):
            orderable += 1

            for k, v in six.iteritems(combo):
                if v not in orderable_variation_children[k]:
                    orderable_variation_children[k].append(v)

    values = (orderable_variation_children, orderable != 0)
    context_cache.set_cached_value(key, values)
    return values
Exemple #9
0
def _get_active_modifiers(shop=None, category=None):
    key = None
    if category:
        key, val = context_cache.get_cached_value(
            identifier="active_modifiers", item=category, allow_cache=True, context={"shop": shop})
        if val is not None:
            return val

    configurations = get_configuration(shop=shop, category=category)

    def sorter(extend_obj):
        return extend_obj.get_ordering(configurations)

    objs = []
    for cls in get_provide_objects(FORM_MODIFIER_PROVIDER_KEY):
        obj = cls()
        if obj.should_use(configurations):
            objs.append(obj)

    sorted_objects = sorted(objs, key=sorter)
    if category and key:
        context_cache.set_cached_value(key, sorted_objects)
    return sorted_objects
Exemple #10
0
def get_product_queryset(queryset, request, category, data):
    key_data = OrderedDict()
    for k, v in data.items():
        if isinstance(v, list):
            v = "|".join(v)
        key_data[k] = v

    if request.customer.is_all_seeing:
        identifier = "product_queryset_all_seeing_%d" % request.user.id
    else:
        identifier = "product_queryset"

    key, val = context_cache.get_cached_value(
        identifier=identifier, item=category, allow_cache=True, context=request, data=key_data)
    if val is not None:
        return val

    for extend_obj in _get_active_modifiers(request.shop, category):
        new_queryset = extend_obj.get_queryset(queryset, data)
        if new_queryset is not None:
            queryset = new_queryset
    context_cache.set_cached_value(key, queryset)
    return queryset
Exemple #11
0
    def is_orderable(self, supplier, customer, quantity, allow_cache=True):
        key, val = context_cache.get_cached_value(
            identifier="is_orderable",
            item=self,
            context={"customer": customer},
            supplier=supplier,
            quantity=quantity,
            allow_cache=allow_cache)
        if customer and val is not None:
            return val

        if not supplier:
            supplier = self.get_supplier(customer, quantity)

        for message in self.get_orderability_errors(supplier=supplier,
                                                    quantity=quantity,
                                                    customer=customer):
            if customer:
                context_cache.set_cached_value(key, False)
            return False

        if customer:
            context_cache.set_cached_value(key, True)
        return True
Exemple #12
0
def get_search_product_ids(request, query, limit=settings.WSHOP_SIMPLE_SEARCH_LIMIT):
    query = query.strip().lower()
    cache_key_elements = {
        "query": query,
        "shop": request.shop.pk,
        "customer": request.customer.pk
    }

    key, val = context_cache.get_cached_value(
        identifier="simple_search", item=None, context=request, cache_key_elements=cache_key_elements)
    if val is not None:
        return val

    product_ids = get_product_ids_for_query_str(request, query, limit)
    for word in query.split(" ") or []:
        if word == query:
            break
        prod_count = len(product_ids)
        if prod_count >= limit:
            break
        product_ids += get_product_ids_for_query_str(request, word.strip(), limit, product_ids)

    context_cache.set_cached_value(key, product_ids[:limit])
    return product_ids