Beispiel #1
0
def manufacturer_changed_listener(sender, **kwargs):
    # filtered lists of products assigned to manufacturer used at manufacturer page
    cache.delete("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.slug))
    # list of all manufacturer products
    cache.delete("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.pk))
    # if manufacturer assignment was changed then product navigation might be different too
    invalidate_cache_group_id('product_navigation')
Beispiel #2
0
def add_property(request, product_id):
    """Adds a new property to the product with given product id.
    """
    product = Product.objects.get(pk=product_id)
    property_form = PropertyForm(data=request.POST)
    if property_form.is_valid():
        property = property_form.save(commit=False)
        property.title = property.name
        property.type = PROPERTY_SELECT_FIELD
        property.local = True

        # it doesn't make sense to filter by local properties as every local
        # property has an own id. Maybe we can do this with an grouping id or
        # something like that
        property.filterable = False

        property.save()
        product_property = ProductsPropertiesRelation(product=product, property=property, position=999)
        product_property.save()

        # Refresh positions
        for i, product_property in enumerate(product.productsproperties.all()):
            product_property.position = i
            product_property.save()

    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id("properties-%s" % pid)

    html = [["#variants", manage_variants(request, product_id, as_string=True)]]

    result = json.dumps({"html": html, "message": _(u"Property has been added.")}, cls=LazyEncoder)

    return HttpResponse(result, content_type="application/json")
Beispiel #3
0
def change_property_position(request):
    """Changes property position based on parameters passed by request body.
    """
    product_id = request.GET.get("product_id")
    property_id = int(request.GET.get("property_id"))
    direction = request.GET.get("direction")

    try:
        product_property = ProductsPropertiesRelation.objects.get(product=product_id, property=property_id)
    except ObjectDoesNotExist:
        pass
    else:
        if direction == "up":
            product_property.position -= 3
        else:
            product_property.position += 3

        product_property.save()

    _refresh_property_positions(product_id)
    pid = Product.objects.get(pk=product_id).get_parent().pk
    invalidate_cache_group_id("properties-%s" % pid)

    html = (("#variants", manage_variants(request, product_id, as_string=True)),)

    result = json.dumps({"html": html}, cls=LazyEncoder)

    return HttpResponse(result, content_type="application/json")
Beispiel #4
0
def change_property_position(request):
    """Changes property position based on parameters passed by request body.
    """
    product_id = request.GET.get("product_id")
    property_id = int(request.GET.get("property_id"))
    direction = request.GET.get("direction")

    try:
        product_property = ProductsPropertiesRelation.objects.get(
            product=product_id, property=property_id)
    except ObjectDoesNotExist:
        pass
    else:
        if direction == "up":
            product_property.position -= 3
        else:
            product_property.position += 3

        product_property.save()

    _refresh_property_positions(product_id)
    pid = Product.objects.get(pk=product_id).get_parent().pk
    invalidate_cache_group_id('properties-%s' % pid)

    html = (("#variants", manage_variants(request, product_id,
                                          as_string=True)), )

    result = json.dumps({
        "html": html,
    }, cls=LazyEncoder)

    return HttpResponse(result, content_type='application/json')
Beispiel #5
0
def delete_property(request, product_id, property_id):
    """Deletes property with passed property id.
    """
    try:
        property = Property.objects.get(pk=property_id)
        product = Product.objects.get(pk=product_id)
    except ObjectDoesNotExist:
        pass
    else:
        property.delete()
        product_changed.send(product)
        pid = product.get_parent().pk
        invalidate_cache_group_id('properties-%s' % pid)

    html = (("#variants", manage_variants(request, product_id,
                                          as_string=True)), )

    result = json.dumps(
        {
            "html": html,
            "message": _(u"Property has been deleted."),
            "close-dialog": True,
        },
        cls=LazyEncoder)

    return HttpResponse(result, content_type='application/json')
Beispiel #6
0
def update_product_cache(instance):
    # If the instance is a product with variant or a variant we have to
    # delete also the parent and all other variants
    if instance.is_variant():
        parent = instance.parent
    else:
        parent = instance

    # if product was changed then we have to clear all product_navigation caches
    invalidate_cache_group_id('product_navigation')
    invalidate_cache_group_id('properties-%s' % parent.id)
    delete_cache("%s-product-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    delete_cache("%s-product-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
    delete_cache("%s-product-images-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    delete_cache("%s-related-products-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    delete_cache("%s-product-categories-%s-False" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    delete_cache("%s-product-categories-%s-True" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    delete_cache("%s-default-variant-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    if parent.manufacturer:
        delete_cache(
            "%s-manufacturer-all-products-%s" %
            (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.pk))
        delete_cache(
            "%s-manufacturer-products-%s" %
            (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.slug))

    try:
        c = cache.get("%s-shipping-delivery-time" %
                      settings.CACHE_MIDDLEWARE_KEY_PREFIX)
        del c["%s-product-%s" %
              (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug)]
        cache.set(
            "%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX,
            c)
    except (KeyError, TypeError):
        pass

    for variant in parent.get_variants():
        delete_cache("%s-product-%s" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        delete_cache("%s-product-%s" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
        delete_cache("%s-product-images-%s" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        delete_cache("%s-related-products-%s" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        delete_cache("%s-product-categories-%s-False" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        delete_cache("%s-product-categories-%s-True" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        delete_cache("%s-product-shipping-%s" %
                     (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.slug))
Beispiel #7
0
def manufacturer_changed_listener(sender, **kwargs):
    # filtered lists of products assigned to manufacturer used at manufacturer page
    delete_cache("%s-manufacturer-products-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.slug))
    # list of all manufacturer products
    delete_cache("%s-manufacturer-all-products-%s" %
                 (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.pk))
    # if manufacturer assignment was changed then product navigation might be different too
    invalidate_cache_group_id('product_navigation')
Beispiel #8
0
def update_product_cache(instance):
    # If the instance is a product with variant or a variant we have to
    # delete also the parent and all other variants
    if instance.is_variant():
        parent = instance.parent
    else:
        parent = instance

    # if product was changed then we have to clear all product_navigation caches
    invalidate_cache_group_id('product_navigation')
    invalidate_cache_group_id('properties-%s' % parent.id)

    cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id)
    cache.delete(cache_key)
    cache_key_hash = hashlib.md5(cache_key).hexdigest()
    cache.delete(cache_key_hash)

    cache_key_slug = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug)
    cache_key_slug_hash = hashlib.md5(cache_key_slug).hexdigest()
    cache.delete(cache_key_slug)
    cache.delete(cache_key_slug_hash)

    cache.delete("%s-product-images-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    cache.delete("%s-related-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    cache.delete("%s-product-categories-%s-False" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    cache.delete("%s-product-categories-%s-True" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    cache.delete("%s-default-variant-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
    if parent.manufacturer:
        cache.delete("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.pk))
        cache.delete("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.slug))

    try:
        c = cache.get("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
        del c["%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug)]
        cache.set("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX, c)
    except (KeyError, TypeError):
        pass

    for variant in parent.get_variants():
        cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id)
        cache.delete(cache_key)
        cache_key_hash = hashlib.md5(cache_key).hexdigest()
        cache.delete(cache_key_hash)
        cache.delete("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
        cache.delete("%s-product-images-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        cache.delete("%s-related-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        cache.delete("%s-product-categories-%s-False" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        cache.delete("%s-product-categories-%s-True" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
        cache.delete("%s-product-shipping-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.slug))
Beispiel #9
0
def add_property_option(request, product_id):
    """Adds a new option to the property with given property id.

    NOTE: The reason why to pass the product id here is to be able to redirect
    to the product. Properties can belong to more than one product.

    TODO: Do this with REFERER
    """
    property_option_form = PropertyOptionForm(data=request.POST)
    if property_option_form.is_valid():
        names = request.POST.get("name").split(",")
        position = 999
        property_id = request.POST.get("property_id")
        for name in names:
            property_option = PropertyOption(name=name)
            property_option.property_id = property_id
            property_option.position = position
            property_option.save()
            position += 1

        # Refresh positions
        for i, option in enumerate(
                PropertyOption.objects.filter(property=property_id)):
            option.position = i
            option.save()
        message = _(u'Option has been added.')
    else:
        message = _(u'Invalid data. Correct it and try again.')

    product = Product.objects.get(pk=product_id)
    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id('properties-%s' % pid)

    html = [[
        "#variants",
        manage_variants(request, product_id, as_string=True)
    ]]

    result = json.dumps({
        "html": html,
        "message": message,
    }, cls=LazyEncoder)

    return HttpResponse(result, content_type='application/json')
Beispiel #10
0
def add_property(request, product_id):
    """Adds a new property to the product with given product id.
    """
    product = Product.objects.get(pk=product_id)
    property_form = PropertyForm(data=request.POST)
    if property_form.is_valid():
        property = property_form.save(commit=False)
        property.title = property.name
        property.type = PROPERTY_SELECT_FIELD
        property.local = True

        # it doesn't make sense to filter by local properties as every local
        # property has an own id. Maybe we can do this with an grouping id or
        # something like that
        property.filterable = False

        property.save()
        product_property = ProductsPropertiesRelation(product=product,
                                                      property=property,
                                                      position=999)
        product_property.save()

        # Refresh positions
        for i, product_property in enumerate(product.productsproperties.all()):
            product_property.position = i
            product_property.save()

    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id('properties-%s' % pid)

    html = [[
        "#variants",
        manage_variants(request, product_id, as_string=True)
    ]]

    result = simplejson.dumps(
        {
            "html": html,
            "message": _(u"Property has been added."),
        },
        cls=LazyEncoder)

    return HttpResponse(result)
Beispiel #11
0
def add_property_option(request, product_id):
    """Adds a new option to the property with given property id.

    NOTE: The reason why to pass the product id here is to be able to redirect
    to the product. Properties can belong to more than one product.

    TODO: Do this with REFERER
    """
    property_option_form = PropertyOptionForm(data=request.POST)
    if property_option_form.is_valid():
        names = request.POST.get("name").split(",")
        position = 999
        property_id = request.POST.get("property_id")
        for name in names:
            property_option = PropertyOption(name=name)
            property_option.property_id = property_id
            property_option.position = position
            property_option.save()
            position += 1

        # Refresh positions
        for i, option in enumerate(PropertyOption.objects.filter(property=property_id)):
            option.position = i
            option.save()
        message = _(u'Option has been added.')
    else:
        message = _(u'Invalid data. Correct it and try again.')

    product = Product.objects.get(pk=product_id)
    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id('properties-%s' % pid)

    html = [["#variants", manage_variants(request, product_id, as_string=True)]]

    result = json.dumps({
        "html": html,
        "message": message,
    }, cls=LazyEncoder)

    return HttpResponse(result, mimetype='application/json')
Beispiel #12
0
def delete_property_option(request, product_id, option_id):
    """Deletes property option with passed option id.
    """
    try:
        property_option = PropertyOption.objects.get(pk=option_id)
        product = Product.objects.get(pk=product_id)
    except ObjectDoesNotExist:
        pass
    else:
        property_option.delete()
        product_changed.send(product)
        pid = product.get_parent().pk
        invalidate_cache_group_id("properties-%s" % pid)

    html = (("#variants", manage_variants(request, product_id, as_string=True)),)

    result = json.dumps(
        {"html": html, "message": _(u"Property has been deleted."), "close-dialog": True}, cls=LazyEncoder
    )

    return HttpResponse(result, content_type="application/json")
Beispiel #13
0
def delete_property(request, product_id, property_id):
    """Deletes property with passed property id.
    """
    try:
        property = Property.objects.get(pk=property_id)
        product = Product.objects.get(pk=product_id)
    except ObjectDoesNotExist:
        pass
    else:
        property.delete()
        product_changed.send(product)
        pid = product.get_parent().pk
        invalidate_cache_group_id('properties-%s' % pid)

    html = (("#variants", manage_variants(request, product_id, as_string=True)),)

    result = simplejson.dumps({
        "html": html,
        "message": _(u"Property has been deleted."),
        "close-dialog": True,
    }, cls=LazyEncoder)

    return HttpResponse(result)
Beispiel #14
0
def update_variants(request, product_id):
    """Updates/Deletes variants with passed ids (via request body) dependent on
    given action (also via request body).
    """
    product = lfs_get_object_or_404(Product, pk=product_id)

    message = ''
    action = request.POST.get("action")
    if action == "delete":
        message = _(u"Variants have been deleted.")
        for key in request.POST.keys():
            if key.startswith("delete-"):
                try:
                    prop_id = key.split("-")[1]
                    variant = Product.objects.get(pk=prop_id)
                except (IndexError, ObjectDoesNotExist):
                    continue
                else:
                    if product.default_variant == variant:
                        product.default_variant = None
                        product.save()
                    variant.delete()
    elif action == "update":
        # TODO: change all of these to formsets or something that will allow for error hangling/messages
        message = _(u"Variants have been saved.")
        for key, value in request.POST.items():
            if key.startswith("variant-"):
                prop_id = key.split("-")[1]
                try:
                    variant = Product.objects.get(pk=prop_id)
                except ObjectDoesNotExist:
                    continue
                else:
                    for name in ("sku", "price"):
                        value = request.POST.get("%s-%s" % (name, prop_id))
                        if value != "":
                            if name == 'price':
                                value = float(value)
                            setattr(variant, name, value)

                    # handle slug - ensure it is unique
                    slug = request.POST.get("slug-%s" % prop_id)
                    if variant.slug != slug:
                        counter = 1
                        new_slug = slug
                        while Product.objects.exclude(pk=variant.pk).filter(
                                slug=new_slug).exists():
                            new_slug = '%s-%s' % (slug[:(
                                79 - len(str(counter)))], counter)
                            counter += 1
                        variant.slug = new_slug

                    # name
                    variant.name = request.POST.get("name-%s" % prop_id)

                    # active
                    active = request.POST.get("active-%s" % prop_id)
                    if active:
                        variant.active = True
                    else:
                        variant.active = False

                    # active attributes
                    for name in ("active_price", "active_sku", "active_name"):
                        value = request.POST.get("%s-%s" % (name, prop_id))
                        if value:
                            setattr(variant, name, True)
                        else:
                            setattr(variant, name, False)

                    # position
                    position = request.POST.get("position-%s" % prop_id)
                    try:
                        variant.variant_position = int(position)
                    except ValueError:
                        variant.variant_position = 10

                    # default variant
                    try:
                        product.default_variant_id = int(
                            request.POST.get("default_variant"))
                    except TypeError:
                        pass
                    else:
                        product.save()

                variant.save()

            elif key.startswith("property"):
                # properties are marshalled as: property-variant_id|property_id
                temp = key.split("-")[1]
                variant_id, property_id = temp.split("|")
                try:
                    variant = Product.objects.get(pk=variant_id)
                except Product.DoesNotExist:
                    continue
                prop = Property.objects.get(pk=property_id)
                ppv = None
                ppv_filterable = None
                try:
                    ppv = ProductPropertyValue.objects.get(
                        product=variant,
                        property_id=property_id,
                        type=PROPERTY_VALUE_TYPE_VARIANT)
                except ProductPropertyValue.DoesNotExist:
                    pass

                if prop.filterable:
                    try:
                        ppv_filterable = ProductPropertyValue.objects.get(
                            product=variant,
                            property_id=property_id,
                            type=PROPERTY_VALUE_TYPE_FILTER)
                    except ProductPropertyValue.DoesNotExist:
                        pass

                if value != '':
                    if not ppv:
                        ppv = ProductPropertyValue.objects.create(
                            product=variant,
                            property_id=property_id,
                            type=PROPERTY_VALUE_TYPE_VARIANT,
                            value=value)
                    else:
                        ppv.value = value
                        ppv.save()

                    if prop.filterable:
                        if not ppv_filterable:
                            ProductPropertyValue.objects.create(
                                product=variant,
                                property_id=property_id,
                                value=value,
                                type=PROPERTY_VALUE_TYPE_FILTER)
                        else:
                            ppv_filterable.value = value
                            ppv_filterable.save()

                elif ppv:
                    ppv.delete()
                    if ppv_filterable:
                        ppv_filterable.delete()

    # Refresh variant positions
    for i, variant in enumerate(product.variants.order_by("variant_position")):
        variant.variant_position = (i + 1) * 10
        variant.save()

    # Send a signal to update cache
    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id('properties-%s' % pid)

    html = (
        ("#variants", manage_variants(request, product_id, as_string=True)),
        ("#selectable-products-inline",
         _selectable_products_inline(request, product)),
    )

    result = simplejson.dumps({
        "html": html,
        "message": message,
    },
                              cls=LazyEncoder)

    return HttpResponse(result)
Beispiel #15
0
def update_variants(request, product_id):
    """Updates/Deletes variants with passed ids (via request body) dependent on
    given action (also via request body).
    """
    product = lfs_get_object_or_404(Product, pk=product_id)

    message = ""
    action = request.POST.get("action")
    if action == "delete":
        message = _(u"Variants have been deleted.")
        for key in request.POST.keys():
            if key.startswith("delete-"):
                try:
                    prop_id = key.split("-")[1]
                    variant = Product.objects.get(pk=prop_id)
                except (IndexError, ObjectDoesNotExist):
                    continue
                else:
                    if product.default_variant == variant:
                        product.default_variant = None
                        product.save()
                    variant.delete()
    elif action == "update":
        # TODO: change all of these to formsets or something that will allow for error hangling/messages
        message = _(u"Variants have been saved.")
        for key, value in request.POST.items():
            if key.startswith("variant-"):
                prop_id = key.split("-")[1]
                try:
                    variant = Product.objects.get(pk=prop_id)
                except ObjectDoesNotExist:
                    continue
                else:
                    for name in ("sku", "price"):
                        value = request.POST.get("%s-%s" % (name, prop_id))
                        if value != "":
                            if name == "price":
                                value = float(value)
                            setattr(variant, name, value)

                    # handle slug - ensure it is unique
                    slug = request.POST.get("slug-%s" % prop_id)
                    if variant.slug != slug:
                        counter = 1
                        new_slug = slug[:80]
                        while Product.objects.exclude(pk=variant.pk).filter(slug=new_slug).exists():
                            new_slug = "%s-%s" % (slug[: (79 - len(str(counter)))], counter)
                            counter += 1
                        variant.slug = new_slug

                    # name
                    variant.name = request.POST.get("name-%s" % prop_id)

                    # active
                    active = request.POST.get("active-%s" % prop_id)
                    if active:
                        variant.active = True
                    else:
                        variant.active = False

                    # active attributes
                    for name in ("active_price", "active_sku", "active_name"):
                        value = request.POST.get("%s-%s" % (name, prop_id))
                        if value:
                            setattr(variant, name, True)
                        else:
                            setattr(variant, name, False)

                    # position
                    position = request.POST.get("position-%s" % prop_id)
                    try:
                        variant.variant_position = int(position)
                    except ValueError:
                        variant.variant_position = 10

                    # default variant
                    try:
                        product.default_variant_id = int(request.POST.get("default_variant"))
                    except TypeError:
                        pass
                    else:
                        product.save()

                variant.save()

            elif key.startswith("property"):
                # properties are marshalled as: property-variant_id|property_group_id|property_id
                temp = key.split("-")[1]
                variant_id, property_group_id, property_id = temp.split("|")
                if property_group_id == "0":  # local properties are not bound to property groups
                    property_group_id = None
                try:
                    variant = Product.objects.get(pk=variant_id)
                except Product.DoesNotExist:
                    continue
                prop = Property.objects.get(pk=property_id)
                ppv = None
                try:
                    ppv = ProductPropertyValue.objects.get(
                        product=variant,
                        property_id=property_id,
                        property_group_id=property_group_id,
                        type=PROPERTY_VALUE_TYPE_VARIANT,
                    )
                except ProductPropertyValue.DoesNotExist:
                    pass

                if prop.filterable:  # it is possible that multiple values are selected for filter
                    ppv_filterables = ProductPropertyValue.objects.filter(
                        product=variant,
                        property_group_id=property_group_id,
                        property_id=property_id,
                        type=PROPERTY_VALUE_TYPE_FILTER,
                    )

                if value != "":
                    is_changed = True
                    if not ppv:
                        ppv = ProductPropertyValue.objects.create(
                            product=variant,
                            property_group_id=property_group_id,
                            property_id=property_id,
                            type=PROPERTY_VALUE_TYPE_VARIANT,
                            value=value,
                        )
                    else:
                        is_changed = ppv.value != value
                        ppv.value = value
                        ppv.save()

                    if prop.filterable and is_changed:
                        ppv_filterables.delete()
                        ProductPropertyValue.objects.create(
                            product=variant,
                            property_group_id=property_group_id,
                            property_id=property_id,
                            value=value,
                            type=PROPERTY_VALUE_TYPE_FILTER,
                        )

                elif ppv:
                    ppv.delete()
                    ppv_filterables.delete()

    # Refresh variant positions
    for i, variant in enumerate(product.variants.order_by("variant_position")):
        variant.variant_position = (i + 1) * 10
        variant.save()

    # Send a signal to update cache
    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id("properties-%s" % pid)

    html = (
        ("#variants", manage_variants(request, product_id, as_string=True)),
        ("#selectable-products-inline", _selectable_products_inline(request, product)),
    )

    result = json.dumps({"html": html, "message": message}, cls=LazyEncoder)

    return HttpResponse(result, content_type="application/json")
Beispiel #16
0
def update_variants(request, product_id):
    """Updates/Deletes variants with passed ids (via request body) dependent on
    given action (also via request body).
    """
    product = lfs_get_object_or_404(Product, pk=product_id)

    message = ''
    action = request.POST.get("action")
    if action == "delete":
        message = _(u"Variants have been deleted.")
        for key in request.POST.keys():
            if key.startswith("delete-"):
                try:
                    id = key.split("-")[1]
                    variant = Product.objects.get(pk=id)
                except (IndexError, ObjectDoesNotExist):
                    continue
                else:
                    if product.default_variant == variant:
                        product.default_variant = None
                        product.save()
                    variant.delete()
    elif action == "update":
        message = _(u"Variants have been saved.")
        for key, value in request.POST.items():
            if key.startswith("variant-"):
                id = key.split("-")[1]
                try:
                    variant = Product.objects.get(pk=id)
                except ObjectDoesNotExist:
                    continue
                else:
                    for name in ("slug", "sku", "price"):
                        value = request.POST.get("%s-%s" % (name, id))
                        if value != "":
                            if name == 'price':
                                value = float(value)
                            setattr(variant, name, value)

                    # name
                    variant.name = request.POST.get("name-%s" % id)

                    # active
                    active = request.POST.get("active-%s" % id)
                    if active:
                        variant.active = True
                    else:
                        variant.active = False

                    # active attributes
                    for name in ("active_price", "active_sku", "active_name"):
                        value = request.POST.get("%s-%s" % (name, id))
                        if value:
                            setattr(variant, name, True)
                        else:
                            setattr(variant, name, False)

                    # position
                    position = request.POST.get("position-%s" % id)
                    try:
                        variant.variant_position = int(position)
                    except ValueError:
                        variant.variant_position = 10

                    # default variant
                    try:
                        product.default_variant_id = int(request.POST.get("default_variant"))
                    except TypeError:
                        pass
                    else:
                        product.save()
                
                variant.save()

            elif key.startswith("property"):
                # properties are marshalled as: property-variant_id|property_id
                temp = key.split("-")[1]
                variant_id, property_id = temp.split("|")
                variant = Product.objects.get(pk=variant_id)
                prop = Property.objects.get(pk=property_id)
                ppv = None
                ppv_filterable = None
                try:
                    ppv = ProductPropertyValue.objects.get(product=variant,
                                                           property_id=property_id,
                                                           type=PROPERTY_VALUE_TYPE_VARIANT)
                except ProductPropertyValue.DoesNotExist:
                    pass

                if prop.filterable:
                    try:
                        ppv_filterable = ProductPropertyValue.objects.get(product=variant,
                                                                          property_id=property_id,
                                                                          type=PROPERTY_VALUE_TYPE_FILTER)
                    except ProductPropertyValue.DoesNotExist:
                        pass

                if value != '':
                    if not ppv:
                        ppv = ProductPropertyValue.objects.create(product=variant,
                                                                  property_id=property_id,
                                                                  type=PROPERTY_VALUE_TYPE_VARIANT,
                                                                  value=value)
                    else:
                        ppv.value = value
                        ppv.save()

                    if prop.filterable:
                        if not ppv_filterable:
                            ProductPropertyValue.objects.create(product=variant, property_id=property_id,
                                                                value=value,
                                                                type=PROPERTY_VALUE_TYPE_FILTER)
                        else:
                            ppv_filterable.value = value
                            ppv_filterable.save()

                elif ppv:
                    ppv.delete()
                    if ppv_filterable:
                        ppv_filterable.delete()

    # Refresh variant positions
    for i, variant in enumerate(product.variants.order_by("variant_position")):
        variant.variant_position = (i + 1) * 10
        variant.save()

    # Send a signal to update cache
    product_changed.send(product)
    pid = product.get_parent().pk
    invalidate_cache_group_id('properties-%s' % pid)

    html = (
        ("#variants", manage_variants(request, product_id, as_string=True)),
        ("#selectable-products-inline", _selectable_products_inline(request, product)),
    )

    result = simplejson.dumps({
        "html": html,
        "message": message,
    }, cls=LazyEncoder)

    return HttpResponse(result)