Example #1
0
def product_inline(request, product, template_name="lfs/catalog/products/product_inline.html"):
    """
    Part of the product view, which displays the actual data of the product.

    This is factored out to be able to better cached and in might in future used
    used to be updated via ajax requests.
    """
    pid = product.get_parent().pk
    properties_version = get_cache_group_id('global-properties-version')
    group_id = '%s-%s' % (properties_version, get_cache_group_id('properties-%s' % pid))
    cache_key = "%s-%s-product-inline-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, group_id,
                                                request.user.is_superuser, product.id)
    result = cache.get(cache_key)
    if result is not None:
        return result

    # Switching to default variant
    if product.is_product_with_variants():
        temp = product.get_default_variant()
        product = temp if temp else product

    properties = []
    variants = []

    display_variants_list = True
    if product.is_variant():
        parent = product.parent
        properties = parent.get_all_properties(variant=product)

        if parent.variants_display_type != SELECT:
            variants = parent.get_variants()
        else:
            display_variants_list = False

    elif product.is_configurable_product():
        for property in product.get_configurable_properties():
            options = []
            try:
                ppv = ProductPropertyValue.objects.get(product=product, property=property, type=PROPERTY_VALUE_TYPE_DEFAULT)
                ppv_value = ppv.value
            except ProductPropertyValue.DoesNotExist:
                ppv = None
                ppv_value = ""

            for property_option in property.options.all():
                if ppv_value == str(property_option.id):
                    selected = True
                else:
                    selected = False

                options.append({
                    "id": property_option.id,
                    "name": property_option.name,
                    "price": property_option.price,
                    "selected": selected,
                })
            properties.append({
                "obj": property,
                "id": property.id,
                "name": property.name,
                "title": property.title,
                "unit": property.unit,
                "display_price": property.display_price,
                "options": options,
                "value": ppv_value,
            })

    if product.get_template_name() is not None:
        template_name = product.get_template_name()

    if product.get_active_packing_unit():
        packing_result = calculate_packing(request, product.id, 1, True, True)
    else:
        packing_result = ""

    # attachments
    attachments = product.get_attachments()

    result = render_to_string(template_name, RequestContext(request, {
        "product": product,
        "variants": variants,
        "product_accessories": product.get_accessories(),
        "properties": properties,
        "packing_result": packing_result,
        "attachments": attachments,
        "quantity": product.get_clean_quantity(1),
        "price_includes_tax": product.price_includes_tax(request),
        "price_unit": product.get_price_unit(),
        "unit": product.get_unit(),
        "display_variants_list": display_variants_list,
        "for_sale": product.get_for_sale(),
    }))

    cache.set(cache_key, result)
    return result
Example #2
0
def manage_variants(request,
                    product_id,
                    as_string=False,
                    variant_simple_form=None,
                    template_name="manage/product/variants.html"):
    """Manages the variants of a product.
    """
    product = Product.objects.get(pk=product_id)

    all_properties = product.get_property_select_fields()

    property_form = PropertyForm()
    property_option_form = PropertyOptionForm()
    if not variant_simple_form:
        variant_simple_form = ProductVariantSimpleForm(
            all_properties=all_properties)
    display_type_form = DisplayTypeForm(instance=product)
    default_variant_form = DefaultVariantForm(instance=product)
    category_variant_form = CategoryVariantForm(instance=product)

    pid = product.get_parent().pk
    properties_version = get_cache_group_id('global-properties-version')
    group_id = '%s-%s' % (properties_version,
                          get_cache_group_id('properties-%s' % pid))
    cache_key = "%s-manage-properties-variants-%s-%s" % (
        settings.CACHE_MIDDLEWARE_KEY_PREFIX, group_id, product_id)
    variants = cache.get(cache_key)
    # Get all properties. We need to traverse through all property / options
    # in order to select the options of the current variant.
    if variants is None:
        variants = []

        props = product.get_property_select_fields()
        props_options = {}
        for o in PropertyOption.objects.filter(property__in=props):
            props_options.setdefault(o.property_id, {})
            props_options[o.property_id][str(o.pk)] = {
                "id": o.pk,
                "name": o.name,
                "selected": False
            }

        product_variants = product.variants.all().order_by("variant_position")
        selected_options = {}
        for so in ProductPropertyValue.objects.filter(
                property__in=props,
                product__in=product_variants,
                type=PROPERTY_VALUE_TYPE_VARIANT):
            ppk = so.product_id
            selected_options.setdefault(ppk, {})[so.property_id] = so.value

        for variant in product_variants:
            properties = []
            for prop in props:
                options = deepcopy(props_options.get(prop.pk, {}))
                try:
                    sop = selected_options[variant.pk][prop.pk]
                    options[sop]['selected'] = True
                except KeyError:
                    pass

                properties.append({
                    "id": prop.pk,
                    "name": prop.name,
                    "options": options.values()
                })

            variants.append({
                "id": variant.id,
                "active": variant.active,
                "slug": variant.slug,
                "sku": variant.sku,
                "name": variant.name,
                "price": variant.price,
                "active_price": variant.active_price,
                "active_sku": variant.active_sku,
                "active_name": variant.active_name,
                "position": variant.variant_position,
                "properties": properties
            })

        cache.set(cache_key, variants)

    # Generate list of all property groups; used for group selection
    product_property_group_ids = [p.id for p in product.property_groups.all()]
    shop_property_groups = []
    for property_group in PropertyGroup.objects.all():

        shop_property_groups.append({
            "id":
            property_group.id,
            "name":
            property_group.name,
            "selected":
            property_group.id in product_property_group_ids,
        })

    result = render_to_string(
        template_name,
        RequestContext(
            request, {
                "product": product,
                "variants": variants,
                "shop_property_groups": shop_property_groups,
                "local_properties": product.get_local_properties(),
                "all_properties": all_properties,
                "property_option_form": property_option_form,
                "property_form": property_form,
                "variant_simple_form": variant_simple_form,
                "display_type_form": display_type_form,
                "default_variant_form": default_variant_form,
                "category_variant_form": category_variant_form,
            }))

    if as_string:
        return result
    else:
        return HttpResponse(result)
Example #3
0
def product_inline(request,
                   product,
                   template_name="lfs/catalog/products/product_inline.html"):
    """
    Part of the product view, which displays the actual data of the product.

    This is factored out to be able to better cached and in might in future used
    used to be updated via ajax requests.
    """
    pid = product.get_parent().pk
    properties_version = get_cache_group_id('global-properties-version')
    group_id = '%s-%s' % (properties_version,
                          get_cache_group_id('properties-%s' % pid))
    cache_key = "%s-%s-product-inline-%s-%s" % (
        settings.CACHE_MIDDLEWARE_KEY_PREFIX, group_id,
        request.user.is_superuser, product.id)
    result = cache.get(cache_key)
    if result is not None:
        return result

    # Switching to default variant
    if product.is_product_with_variants():
        temp = product.get_default_variant()
        product = temp if temp else product

    properties = []
    variants = []

    display_variants_list = True
    if product.is_variant():
        parent = product.parent
        properties = parent.get_all_properties(variant=product)

        if parent.variants_display_type != SELECT:
            variants = parent.get_variants()
        else:
            display_variants_list = False

    elif product.is_configurable_product():
        for property in product.get_configurable_properties():
            options = []
            try:
                ppv = ProductPropertyValue.objects.get(
                    product=product,
                    property=property,
                    type=PROPERTY_VALUE_TYPE_DEFAULT)
                ppv_value = ppv.value
            except ProductPropertyValue.DoesNotExist:
                ppv = None
                ppv_value = ""

            for property_option in property.options.all():
                if ppv_value == str(property_option.id):
                    selected = True
                else:
                    selected = False

                options.append({
                    "id": property_option.id,
                    "name": property_option.name,
                    "price": property_option.price,
                    "selected": selected,
                })
            properties.append({
                "obj": property,
                "id": property.id,
                "name": property.name,
                "title": property.title,
                "unit": property.unit,
                "display_price": property.display_price,
                "options": options,
                "value": ppv_value,
            })

    if product.get_template_name() is not None:
        template_name = product.get_template_name()

    if product.get_active_packing_unit():
        packing_result = calculate_packing(request, product.id, 1, True, True)
    else:
        packing_result = ""

    # attachments
    attachments = product.get_attachments()

    result = render_to_string(
        template_name,
        RequestContext(
            request, {
                "product": product,
                "variants": variants,
                "product_accessories": product.get_accessories(),
                "properties": properties,
                "packing_result": packing_result,
                "attachments": attachments,
                "quantity": product.get_clean_quantity(1),
                "price_includes_tax": product.price_includes_tax(request),
                "price_unit": product.get_price_unit(),
                "unit": product.get_unit(),
                "display_variants_list": display_variants_list,
                "for_sale": product.get_for_sale(),
            }))

    cache.set(cache_key, result)
    return result
Example #4
0
def product_navigation(context, product):
    """Provides previous and next product links.
    """
    request = context.get("request")
    sorting = request.session.get("sorting", 'effective_price')
    if sorting.strip() == '':
        sorting = 'effective_price'
        request.session["sorting"] = sorting

    slug = product.slug

    # To calculate the position we take only STANDARD_PRODUCT into account.
    # That means if the current product is a VARIANT we switch to its parent
    # product.
    if product.is_variant():
        product = product.parent
        slug = product.slug

    # prepare cache key for product_navigation group
    # used to invalidate cache for all product_navigations at once
    pn_cache_key = get_cache_group_id('product_navigation')

    # if there is last_manufacturer then product was visited from manufacturer view
    # as category view removes last_manufacturer from the session
    lm = request.session.get('last_manufacturer')
    if lm and product.manufacturer == lm:
        cache_key = "%s-%s-product-navigation-manufacturer-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX,
                                                                  pn_cache_key,
                                                                  slug)
        res = cache.get(cache_key)
        if res and sorting in res:
            return res[sorting]

        products = Product.objects.filter(manufacturer=lm)
    else:
        category = product.get_current_category(request)
        if category is None:
            return {"display": False}
        else:
            cache_key = "%s-%s-product-navigation-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX,
                                                         pn_cache_key,
                                                         slug)
            res = cache.get(cache_key)
            if res and sorting in res:
                return res[sorting]

            # First we collect all sub categories. This and using the in operator makes
            # batching more easier
            categories = [category]

            if category.show_all_products:
                categories.extend(category.get_all_children())

            products = Product.objects.filter(categories__in=categories)

    # This is necessary as we display non active products to superusers.
    # So we have to take care for the product navigation too.
    if not request.user.is_superuser:
        products = products.filter(active=True)
    products = products.exclude(sub_type=VARIANT).distinct().order_by(sorting)

    product_slugs = list(products.values_list('slug', flat=True))
    product_index = product_slugs.index(slug)

    if product_index > 0:
        previous = product_slugs[product_index - 1]
    else:
        previous = None

    total = len(product_slugs)
    if product_index < total - 1:
        next_product = product_slugs[product_index + 1]
    else:
        next_product = None

    result = {
        "display": True,
        "previous": previous,
        "next": next_product,
        "current": product_index + 1,
        "total": total,
        "STATIC_URL": context.get("STATIC_URL"),
    }

    cache.set(cache_key, {'sorting': result})

    return result
Example #5
0
def product_navigation(context, product):
    """Provides previous and next product links.
    """
    request = context.get("request")

    try:
        default_sorting = settings.LFS_PRODUCTS_SORTING
    except AttributeError:
        default_sorting = "effective_price"
    sorting = request.session.get("sorting", default_sorting)
    if sorting.strip() == '':
        sorting = 'effective_price'
        request.session["sorting"] = sorting

    slug = product.slug

    # To calculate the position we take only STANDARD_PRODUCT into account.
    # That means if the current product is a VARIANT we switch to its parent
    # product.
    if product.is_variant():
        product = product.parent
        slug = product.slug

    # prepare cache key for product_navigation group
    # used to invalidate cache for all product_navigations at once
    pn_cache_key = get_cache_group_id('product_navigation')

    # if there is last_manufacturer then product was visited from manufacturer view
    # as category view removes last_manufacturer from the session
    lm = request.session.get('last_manufacturer')
    if lm and product.manufacturer == lm:
        cache_key = "%s-%s-product-navigation-manufacturer-%s" % (
            settings.CACHE_MIDDLEWARE_KEY_PREFIX, pn_cache_key, slug)
        res = cache.get(cache_key)
        if res and sorting in res:
            return res[sorting]

        products = Product.objects.filter(manufacturer=lm)
    else:
        category = product.get_current_category(request)
        if category is None:
            return {"display": False}
        else:
            cache_key = "%s-%s-product-navigation-%s" % (
                settings.CACHE_MIDDLEWARE_KEY_PREFIX, pn_cache_key, slug)
            res = cache.get(cache_key)
            if res and sorting in res:
                return res[sorting]

            # First we collect all sub categories. This and using the in operator makes
            # batching more easier
            categories = [category]

            if category.show_all_products:
                categories.extend(category.get_all_children())

            products = Product.objects.filter(categories__in=categories)

    # This is necessary as we display non active products to superusers.
    # So we have to take care for the product navigation too.
    if not request.user.is_superuser:
        products = products.filter(active=True)
    products = products.exclude(sub_type=VARIANT).distinct().order_by(sorting)

    product_slugs = list(products.values_list('slug', flat=True))
    product_index = product_slugs.index(slug)

    if product_index > 0:
        previous = product_slugs[product_index - 1]
    else:
        previous = None

    total = len(product_slugs)
    if product_index < total - 1:
        next_product = product_slugs[product_index + 1]
    else:
        next_product = None

    result = {
        "display": True,
        "previous": previous,
        "next": next_product,
        "current": product_index + 1,
        "total": total,
    }

    cache.set(cache_key, {'sorting': result})

    return result
Example #6
0
def manage_variants(
    request, product_id, as_string=False, variant_simple_form=None, template_name="manage/product/variants.html"
):
    """Manages the variants of a product.
    """
    product = Product.objects.get(pk=product_id)

    all_properties = product.get_variants_properties()

    property_form = PropertyForm()
    property_option_form = PropertyOptionForm()
    if not variant_simple_form:
        variant_simple_form = ProductVariantSimpleForm(all_properties=all_properties)
    display_type_form = DisplayTypeForm(instance=product)
    default_variant_form = DefaultVariantForm(instance=product)
    category_variant_form = CategoryVariantForm(instance=product)

    pid = product.get_parent().pk
    properties_version = get_cache_group_id("global-properties-version")
    group_id = "%s-%s" % (properties_version, get_cache_group_id("properties-%s" % pid))
    cache_key = "%s-manage-properties-variants-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, group_id, product_id)
    variants = cache.get(cache_key)
    # Get all properties. We need to traverse through all property / options
    # in order to select the options of the current variant.
    if variants is None:
        variants = []

        props_dicts = product.get_variants_properties()

        # for each property prepare list of its options
        all_props = [prop_dict["property"] for prop_dict in props_dicts]
        props_options = {}
        for o in PropertyOption.objects.filter(property__in=all_props):
            props_options.setdefault(o.property_id, {})
            props_options[o.property_id][str(o.pk)] = {"id": o.pk, "name": o.name, "selected": False}

        product_variants = product.variants.all().order_by("variant_position")
        selected_options = {}
        for prop_dict in props_dicts:
            prop = prop_dict["property"]
            property_group = prop_dict["property_group"]
            property_group_id = property_group.pk if property_group else 0

            for so in ProductPropertyValue.objects.filter(
                property=prop,
                property_group=property_group,
                product__in=product_variants,
                type=PROPERTY_VALUE_TYPE_VARIANT,
            ):
                ppk = so.product_id
                selected_groups = selected_options.setdefault(ppk, {})
                selected_groups.setdefault(property_group_id, {})[so.property_id] = so.value

        for variant in product_variants:
            properties = []
            for prop_dict in props_dicts:
                prop = prop_dict["property"]
                property_group = prop_dict["property_group"]
                property_group_id = property_group.pk if property_group else 0

                options = deepcopy(props_options.get(prop.pk, {}))
                try:
                    sop = selected_options[variant.pk][property_group_id][prop.pk]
                    options[sop]["selected"] = True
                except KeyError:
                    pass

                properties.append(
                    {
                        "id": prop.pk,
                        "name": prop.name,
                        "options": options.values(),
                        "property_group_id": property_group.pk if property_group else 0,
                        "property_group": property_group,
                    }
                )

            variants.append(
                {
                    "id": variant.id,
                    "active": variant.active,
                    "slug": variant.slug,
                    "sku": variant.sku,
                    "name": variant.name,
                    "price": variant.price,
                    "active_price": variant.active_price,
                    "active_sku": variant.active_sku,
                    "active_name": variant.active_name,
                    "position": variant.variant_position,
                    "properties": properties,
                }
            )

        cache.set(cache_key, variants)

    # Generate list of all property groups; used for group selection
    product_property_group_ids = [p.id for p in product.property_groups.all()]
    shop_property_groups = []
    for property_group in PropertyGroup.objects.all():

        shop_property_groups.append(
            {
                "id": property_group.id,
                "name": property_group.name,
                "selected": property_group.id in product_property_group_ids,
            }
        )

    result = render_to_string(
        template_name,
        RequestContext(
            request,
            {
                "product": product,
                "variants": variants,
                "shop_property_groups": shop_property_groups,
                "local_properties": product.get_local_properties(),
                "all_properties": all_properties,
                "property_option_form": property_option_form,
                "property_form": property_form,
                "variant_simple_form": variant_simple_form,
                "display_type_form": display_type_form,
                "default_variant_form": default_variant_form,
                "category_variant_form": category_variant_form,
            },
        ),
    )

    if as_string:
        return result
    else:
        return HttpResponse(result)
Example #7
0
def manage_variants(request,
                    product_id,
                    as_string=False,
                    template_name="manage/product/variants.html"):
    """Manages the variants of a product.
    """
    product = Product.objects.get(pk=product_id)

    property_form = PropertyForm()
    property_option_form = PropertyOptionForm()
    variant_simple_form = ProductVariantSimpleForm()
    display_type_form = DisplayTypeForm(instance=product)
    default_variant_form = DefaultVariantForm(instance=product)
    category_variant_form = CategoryVariantForm(instance=product)

    pid = product.get_parent().pk
    group_id = get_cache_group_id('properties-%s' % pid)
    cache_key = "%s-manage-properties-variants-%s-%s" % (
        settings.CACHE_MIDDLEWARE_KEY_PREFIX, group_id, product_id)
    variants = cache.get(cache_key)
    # Get all properties. We need to traverse through all property / options
    # in order to select the options of the current variant.
    if variants is None:
        variants = []
        for variant in product.variants.all().order_by("variant_position"):
            properties = []
            for property in product.get_property_select_fields():
                options = []
                for property_option in property.options.all():
                    if variant.has_option(property, property_option):
                        selected = True
                    else:
                        selected = False
                    options.append({
                        "id": property_option.id,
                        "name": property_option.name,
                        "selected": selected
                    })
                properties.append({
                    "id": property.id,
                    "name": property.name,
                    "options": options
                })

            variants.append({
                "id": variant.id,
                "active": variant.active,
                "slug": variant.slug,
                "sku": variant.sku,
                "name": variant.name,
                "price": variant.price,
                "active_price": variant.active_price,
                "active_sku": variant.active_sku,
                "active_name": variant.active_name,
                "position": variant.variant_position,
                "properties": properties
            })

        cache.set(cache_key, variants)

    # Generate list of all property groups; used for group selection
    product_property_group_ids = [p.id for p in product.property_groups.all()]
    shop_property_groups = []
    for property_group in PropertyGroup.objects.all():

        shop_property_groups.append({
            "id":
            property_group.id,
            "name":
            property_group.name,
            "selected":
            property_group.id in product_property_group_ids,
        })

    result = render_to_string(
        template_name,
        RequestContext(
            request, {
                "product": product,
                "variants": variants,
                "shop_property_groups": shop_property_groups,
                "local_properties": product.get_local_properties(),
                "all_properties": product.get_property_select_fields(),
                "property_option_form": property_option_form,
                "property_form": property_form,
                "variant_simple_form": variant_simple_form,
                "display_type_form": display_type_form,
                "default_variant_form": default_variant_form,
                "category_variant_form": category_variant_form,
            }))

    if as_string:
        return result
    else:
        return HttpResponse(result)
Example #8
0
def manage_variants(request, product_id, as_string=False, template_name="manage/product/variants.html"):
    """Manages the variants of a product.
    """
    product = Product.objects.get(pk=product_id)

    property_form = PropertyForm()
    property_option_form = PropertyOptionForm()
    variant_simple_form = ProductVariantSimpleForm()
    display_type_form = DisplayTypeForm(instance=product)
    default_variant_form = DefaultVariantForm(instance=product)
    category_variant_form = CategoryVariantForm(instance=product)

    pid = product.get_parent().pk
    group_id = get_cache_group_id('properties-%s' % pid)
    cache_key = "%s-manage-properties-variants-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, group_id, product_id)
    variants = cache.get(cache_key)
    # Get all properties. We need to traverse through all property / options
    # in order to select the options of the current variant.
    if variants is None:
        variants = []
        for variant in product.variants.all().order_by("variant_position"):
            properties = []
            for property in product.get_property_select_fields():
                options = []
                for property_option in property.options.all():
                    if variant.has_option(property, property_option):
                        selected = True
                    else:
                        selected = False
                    options.append({
                        "id": property_option.id,
                        "name": property_option.name,
                        "selected": selected
                    })
                properties.append({
                    "id": property.id,
                    "name": property.name,
                    "options": options
                })

            variants.append({
                "id": variant.id,
                "active": variant.active,
                "slug": variant.slug,
                "sku": variant.sku,
                "name": variant.name,
                "price": variant.price,
                "active_price": variant.active_price,
                "active_sku": variant.active_sku,
                "active_name": variant.active_name,
                "position": variant.variant_position,
                "properties": properties
            })

        cache.set(cache_key, variants)

    # Generate list of all property groups; used for group selection
    product_property_group_ids = [p.id for p in product.property_groups.all()]
    shop_property_groups = []
    for property_group in PropertyGroup.objects.all():

        shop_property_groups.append({
            "id": property_group.id,
            "name": property_group.name,
            "selected": property_group.id in product_property_group_ids,
        })

    result = render_to_string(template_name, RequestContext(request, {
        "product": product,
        "variants": variants,
        "shop_property_groups": shop_property_groups,
        "local_properties": product.get_local_properties(),
        "all_properties": product.get_property_select_fields(),
        "property_option_form": property_option_form,
        "property_form": property_form,
        "variant_simple_form": variant_simple_form,
        "display_type_form": display_type_form,
        "default_variant_form": default_variant_form,
        "category_variant_form": category_variant_form,
    }))

    if as_string:
        return result
    else:
        return HttpResponse(result)