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
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)
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
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
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
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)
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)
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)