예제 #1
0
def add_option(request, property_id):
    """Adds option to property with passed property id.
    """
    property = get_object_or_404(Property, pk=property_id)

    if request.POST.get("action") == "add":
        name = request.POST.get("name", "")
        price = request.POST.get("price", "")
        try:
            price = abs(atof(str(price)))
        except (TypeError, ValueError):
            price = 0.0

        if name != "":
            option = PropertyOption.objects.create(name=name,
                                                   price=price,
                                                   property_id=property_id)
            message = _(u"Option has been added.")
        else:
            message = _(u"Option could not be added.")
    else:
        for option_id in request.POST.getlist("option"):
            try:
                option = PropertyOption.objects.get(pk=option_id)
            except PropertyOption.DoesNotExist:
                pass
            else:
                try:
                    price = abs(
                        atof(str(request.POST.get("price-%s" % option_id,
                                                  ""))))
                except (TypeError, ValueError):
                    price = 0.0

                try:
                    position = int(
                        request.POST.get("position-%s" % option_id, 99))
                except ValueError:
                    position = 99

                option.position = position
                option.name = request.POST.get("name-%s" % option_id, "")
                option.price = price
                option.save()
        message = _(u"Options have been updated.")

    _update_positions(property)
    # invalidate global properties version number (all product property caches will be invalidated)
    invalidate_cache_group_id('global-properties-version')

    html = [["#options", options_inline(request, property_id)]]
    result = json.dumps({"html": html, "message": message}, cls=LazyEncoder)
    return HttpResponse(result, content_type='application/json')
예제 #2
0
def add_option(request, property_id):
    """Adds option to property with passed property id.
    """
    property = get_object_or_404(Property, pk=property_id)

    if request.POST.get("action") == "add":
        name = request.POST.get("name", "")
        price = request.POST.get("price", "")
        try:
            price = abs(atof(str(price)))
        except (TypeError, ValueError):
            price = 0.0

        if name != "":
            option = PropertyOption.objects.create(name=name, price=price, property_id=property_id)
            message = _(u"Option has been added.")
        else:
            message = _(u"Option could not be added.")
    else:
        for option_id in request.POST.getlist("option"):
            try:
                option = PropertyOption.objects.get(pk=option_id)
            except PropertyOption.DoesNotExist:
                pass
            else:
                try:
                    price = abs(atof(str(request.POST.get("price-%s" % option_id, ""))))
                except (TypeError, ValueError):
                    price = 0.0

                try:
                    position = int(request.POST.get("position-%s" % option_id, 99))
                except ValueError:
                    position = 99

                option.position = position
                option.name = request.POST.get("name-%s" % option_id, "")
                option.price = price
                option.save()
        message = _(u"Options have been updated.")

    _update_positions(property)
    # invalidate global properties version number (all product property caches will be invalidated)
    invalidate_cache_group_id('global-properties-version')

    html = [["#options", options_inline(request, property_id)]]
    result = json.dumps({
        "html": html,
        "message": message
    }, cls=LazyEncoder)
    return HttpResponse(result, content_type='application/json')
예제 #3
0
파일: views.py 프로젝트: vovkd/django-lfs
def refresh_cart(request):
    """
    Refreshes the cart after some changes has been taken place, e.g.: the
    amount of a product or shipping/payment method.
    """
    cart = cart_utils.get_cart(request)
    customer = customer_utils.get_or_create_customer(request)

    # Update country
    country_iso = request.POST.get("country")
    if country_iso:
        selected_country = Country.objects.get(code=country_iso.lower())
        customer.selected_country_id = selected_country.id
        if customer.selected_shipping_address:
            customer.selected_shipping_address.country = selected_country
            customer.selected_shipping_address.save()
            customer.selected_shipping_address.save()
        if customer.selected_invoice_address:
            customer.selected_invoice_address.country = selected_country
            customer.selected_invoice_address.save()
            customer.selected_invoice_address.save()
        # NOTE: The customer has to be saved already here in order to calculate
        # a possible new valid shippig method below, which coulb be triggered by
        # the changing of the shipping country.
        customer.save()

    # Update Amounts
    message = ""
    for item in cart.get_items():
        try:
            value = request.POST.get("amount-cart-item_%s" % item.id, "0.0")
            amount = core_utils.atof(value)
        except (TypeError, ValueError):
            amount = 1.0

        if item.product.manage_stock_amount and amount > item.product.stock_amount and not item.product.order_time:
            amount = item.product.stock_amount
            if amount < 0:
                amount = 0

            if amount == 0:
                message = _(u"Sorry, but '%(product)s' is not available anymore." % {"product": item.product.name})
            elif amount == 1:
                message = _(u"Sorry, but '%(product)s' is only one time available." % {"product": item.product.name})
            else:
                message = _(u"Sorry, but '%(product)s' is only %(amount)s times available.") % {"product": item.product.name, "amount": amount}


        if item.product.get_active_packing_unit():
            item.amount = item.product.get_amount_by_packages(float(amount))
        else:
            item.amount = amount

        if amount == 0:
            item.delete()
        else:
            item.save()

    # IMPORTANT: We have to send the signal already here, because the valid
    # shipping methods might be dependent on the price.
    cart_changed.send(cart, request=request)

    # Update shipping method
    shipping_method = get_object_or_404(ShippingMethod, pk=request.POST.get("shipping_method"))
    customer.selected_shipping_method = shipping_method

    valid_shipping_methods = shipping_utils.get_valid_shipping_methods(request)
    if customer.selected_shipping_method not in valid_shipping_methods:
        customer.selected_shipping_method = shipping_utils.get_default_shipping_method(request)

    # Update payment method
    payment_method = get_object_or_404(PaymentMethod, pk=request.POST.get("payment_method"))
    customer.selected_payment_method = payment_method

    # Last but not least we save the customer ...
    customer.save()

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

    return HttpResponse(result)
예제 #4
0
파일: views.py 프로젝트: vovkd/django-lfs
def add_to_cart(request, product_id=None):
    """
    Adds the passed product with passed product_id to the cart after
    some validations have been taken place. The amount is taken from the query
    string.
    """
    if product_id is None:
        product_id = request.REQUEST.get("product_id")

    product = lfs_get_object_or_404(Product, pk=product_id)

    # Only active and deliverable products can be added to the cart.
    if not (product.is_active() and product.is_deliverable()):
        raise Http404()

    try:
        value = request.POST.get("quantity", "1.0")
        quantity = core_utils.atof(value)
    except (TypeError, ValueError):
        quantity = 1.0

    # Validate properties (They are added below)
    properties_dict = {}
    if product.is_configurable_product():
        for key, value in request.POST.items():
            if key.startswith("property-"):
                try:
                    property_id = key.split("-")[1]
                except IndexError:
                    continue
                try:
                    prop = Property.objects.get(pk=property_id)
                except Property.DoesNotExist:
                    continue

                if prop.is_number_field:
                    try:
                        value = lfs.core.utils.atof(value)
                    except ValueError:
                        value = 0.0

                properties_dict[property_id] = unicode(value)

                # validate property's value
                if prop.is_number_field:

                    if (value < prop.unit_min) or (value > prop.unit_max):
                        msg = _(u"%(name)s must be between %(min)s and %(max)s %(unit)s.") % {"name": prop.title, "min": prop.unit_min, "max": prop.unit_max, "unit": prop.unit}
                        return lfs.core.utils.set_message_cookie(
                            product.get_absolute_url(), msg)

                    # calculate valid steps
                    steps = []
                    x = prop.unit_min
                    while x < prop.unit_max:
                        steps.append("%.2f" % x)
                        x += prop.unit_step
                    steps.append("%.2f" % prop.unit_max)

                    value = "%.2f" % value
                    if value not in steps:
                        msg = _(u"Your entered value for %(name)s (%(value)s) is not in valid step width, which is %(step)s.") % {"name": prop.title, "value": value, "step": prop.unit_step}
                        return lfs.core.utils.set_message_cookie(
                            product.get_absolute_url(), msg)

    if product.get_active_packing_unit():
        quantity = product.get_amount_by_packages(quantity)

    cart = cart_utils.get_or_create_cart(request)

    cart_item = cart.add(product, properties_dict, quantity)
    cart_items = [cart_item]

    # Check stock amount
    message = ""
    if product.manage_stock_amount and cart_item.amount > product.stock_amount and not product.order_time:
        if product.stock_amount == 0:
            message = _(u"Sorry, but '%(product)s' is not available anymore.") % {"product": product.name}
        elif product.stock_amount == 1:
            message = _(u"Sorry, but '%(product)s' is only one time available.") % {"product": product.name}
        else:
            message = _(u"Sorry, but '%(product)s' is only %(amount)s times available.") % {"product": product.name, "amount": product.stock_amount}
        cart_item.amount = product.stock_amount
        cart_item.save()

    # Add selected accessories to cart
    for key, value in request.POST.items():
        if key.startswith("accessory"):
            accessory_id = key.split("-")[1]
            try:
                accessory = Product.objects.get(pk=accessory_id)
            except ObjectDoesNotExist:
                continue

            # Get quantity
            quantity = request.POST.get("quantity-%s" % accessory_id, 0)
            try:
                quantity = float(quantity)
            except TypeError:
                quantity = 1

            cart_item = cart.add(product=accessory, amount=quantity)
            cart_items.append(cart_item)

    # Store cart items for retrieval within added_to_cart.
    request.session["cart_items"] = cart_items
    cart_changed.send(cart, request=request)

    # Update the customer's shipping method (if appropriate)
    customer = customer_utils.get_or_create_customer(request)
    shipping_utils.update_to_valid_shipping_method(request, customer, save=True)

    # Update the customer's payment method (if appropriate)
    payment_utils.update_to_valid_payment_method(request, customer, save=True)

    # Save the cart to update modification date
    cart.save()

    try:
        url_name = settings.LFS_AFTER_ADD_TO_CART
    except AttributeError:
        url_name = "lfs_added_to_cart"

    if message:
        return lfs.core.utils.set_message_cookie(reverse(url_name), message)
    else:
        return HttpResponseRedirect(reverse(url_name))
예제 #5
0
def save_products(request):
    """
    Saves products with passed ids (by request body).
    """
    products = _get_filtered_products(request)
    paginator = Paginator(
        products,
        request.session.get("product_filters", {}).get('amount', 25))
    page = paginator.page(request.REQUEST.get("page", 1))

    if request.POST.get("action") == "delete":
        for key, value in request.POST.items():
            if key.startswith("delete-"):
                id = key.split("-")[1]

                try:
                    product = Product.objects.get(pk=id)
                except Product.DoesNotExist:
                    continue
                else:
                    product.delete()
        msg = _(u"Products have been deleted.")
        # switch to the first page because after some products are removed current page might be out of range
        page = paginator.page(1)

    elif request.POST.get("action") == "save":
        for key, value in request.POST.items():
            if key.startswith("id-"):
                id = value

                try:
                    product = Product.objects.get(pk=id)
                except Product.DoesNotExist:
                    continue

                product.name = request.POST.get("name-%s" % id, "")
                product.sku = request.POST.get("sku-%s" % id, "")
                product.slug = request.POST.get("slug-%s" % id, "")
                product.sub_type = request.POST.get("sub_type-%s" % id, 0)

                try:
                    price = request.POST.get("price-%s" % id, '0')
                    product.price = atof(price)
                except ValueError:
                    product.price = 0
                try:
                    for_sale_price = request.POST.get("for_sale_price-%s" % id,
                                                      '0')
                    product.for_sale_price = atof(for_sale_price)
                except ValueError:
                    product.for_sale_price = 0

                if request.POST.get("for_sale-%s" % id):
                    product.for_sale = True
                else:
                    product.for_sale = False

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

                # TODO: remove IntegrityError and apply some kind of form/formset validation
                try:
                    product.save()
                except IntegrityError:
                    pass

                msg = _(u"Products have been saved")

    html = (("#products-inline", products_inline(request, page, paginator)),
            ("#pages-inline", pages_inline(request, page, paginator, 0)))

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

    return HttpResponse(result, content_type='application/json')
예제 #6
0
def save_products(request):
    """
    Saves products with passed ids (by request body).
    """
    products = _get_filtered_products(request)
    paginator = Paginator(products, request.session.get("product_filters", {}).get('amount', 25))
    page = paginator.page((request.POST if request.method == 'POST' else request.GET).get("page", 1))

    if request.POST.get("action") == "delete":
        for key, value in request.POST.items():
            if key.startswith("delete-"):
                id = key.split("-")[1]

                try:
                    product = Product.objects.get(pk=id)
                except Product.DoesNotExist:
                    continue
                else:
                    product.delete()
        msg = _(u"Products have been deleted.")
        # switch to the first page because after some products are removed current page might be out of range
        page = paginator.page(1)

    elif request.POST.get("action") == "save":
        for key, value in request.POST.items():
            if key.startswith("id-"):
                id = value

                try:
                    product = Product.objects.get(pk=id)
                except Product.DoesNotExist:
                    continue

                product.name = request.POST.get("name-%s" % id, "")
                product.sku = request.POST.get("sku-%s" % id, "")
                product.slug = request.POST.get("slug-%s" % id, "")
                product.sub_type = request.POST.get("sub_type-%s" % id, 0)

                try:
                    price = request.POST.get("price-%s" % id, '0')
                    product.price = atof(price)
                except ValueError:
                    product.price = 0
                try:
                    for_sale_price = request.POST.get("for_sale_price-%s" % id, '0')
                    product.for_sale_price = atof(for_sale_price)
                except ValueError:
                    product.for_sale_price = 0

                if request.POST.get("for_sale-%s" % id):
                    product.for_sale = True
                else:
                    product.for_sale = False

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

                # TODO: remove IntegrityError and apply some kind of form/formset validation
                try:
                    product.save()
                except IntegrityError:
                    pass

                msg = _(u"Products have been saved")

    html = (("#products-inline", products_inline(request, page, paginator)),
            ("#pages-inline", pages_inline(request, page, paginator, 0))
    )

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

    return HttpResponse(result, content_type='application/json')
예제 #7
0
def refresh_cart(request):
    """
    Refreshes the cart after some changes has been taken place, e.g.: the
    amount of a product or shipping/payment method.
    """
    cart = cart_utils.get_cart(request)
    customer = customer_utils.get_or_create_customer(request)

    # Update country
    country_iso = request.POST.get("country")
    if country_iso:
        selected_country = Country.objects.get(code=country_iso.lower())
        customer.selected_country_id = selected_country.id
        if customer.selected_shipping_address:
            customer.selected_shipping_address.country = selected_country
            customer.selected_shipping_address.save()
            customer.selected_shipping_address.save()
        if customer.selected_invoice_address:
            customer.selected_invoice_address.country = selected_country
            customer.selected_invoice_address.save()
            customer.selected_invoice_address.save()
        # NOTE: The customer has to be saved already here in order to calculate
        # a possible new valid shippig method below, which coulb be triggered by
        # the changing of the shipping country.
        customer.save()

    # Update Amounts
    message = ""
    for item in cart.get_items():
        try:
            value = request.POST.get("amount-cart-item_%s" % item.id, "0.0")
            amount = core_utils.atof(value)
        except (TypeError, ValueError):
            amount = 1.0

        if item.product.manage_stock_amount and amount > item.product.stock_amount and not item.product.order_time:
            amount = item.product.stock_amount
            if amount < 0:
                amount = 0

            if amount == 0:
                message = _(u"Sorry, but '%(product)s' is not available anymore." % {"product": item.product.name})
            elif amount == 1:
                message = _(u"Sorry, but '%(product)s' is only one time available." % {"product": item.product.name})
            else:
                message = _(u"Sorry, but '%(product)s' is only %(amount)s times available.") % {
                    "product": item.product.name,
                    "amount": amount,
                }

        if item.product.get_active_packing_unit():
            item.amount = item.product.get_amount_by_packages(float(amount))
        else:
            item.amount = amount

        if amount == 0:
            item.delete()
        else:
            item.save()

    # IMPORTANT: We have to send the signal already here, because the valid
    # shipping methods might be dependent on the price.
    cart_changed.send(cart, request=request)

    # Update shipping method
    shipping_method = get_object_or_404(ShippingMethod, pk=request.POST.get("shipping_method"))
    customer.selected_shipping_method = shipping_method

    valid_shipping_methods = shipping_utils.get_valid_shipping_methods(request)
    if customer.selected_shipping_method not in valid_shipping_methods:
        customer.selected_shipping_method = shipping_utils.get_default_shipping_method(request)

    # Update payment method
    payment_method = get_object_or_404(PaymentMethod, pk=request.POST.get("payment_method"))
    customer.selected_payment_method = payment_method

    # Last but not least we save the customer ...
    customer.save()

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

    return HttpResponse(result)
예제 #8
0
def add_to_cart(request, product_id=None):
    """
    Adds the passed product with passed product_id to the cart after
    some validations have been taken place. The amount is taken from the query
    string.
    """
    if product_id is None:
        product_id = request.REQUEST.get("product_id")

    product = lfs_get_object_or_404(Product, pk=product_id)

    # Only active and deliverable products can be added to the cart.
    if not (product.is_active() and product.is_deliverable()):
        raise Http404()

    try:
        value = request.POST.get("quantity", "1.0")
        quantity = core_utils.atof(value)
    except (TypeError, ValueError):
        quantity = 1.0

    # Validate properties (They are added below)
    properties_dict = {}
    if product.is_configurable_product():
        for key, value in request.POST.items():
            if key.startswith("property-"):
                try:
                    property_id = key.split("-")[1]
                except IndexError:
                    continue
                try:
                    prop = Property.objects.get(pk=property_id)
                except Property.DoesNotExist:
                    continue

                if prop.is_number_field:
                    try:
                        value = lfs.core.utils.atof(value)
                    except ValueError:
                        value = 0.0

                properties_dict[property_id] = unicode(value)

                # validate property's value
                if prop.is_number_field:

                    if (value < prop.unit_min) or (value > prop.unit_max):
                        msg = _(u"%(name)s must be between %(min)s and %(max)s %(unit)s.") % {
                            "name": prop.title,
                            "min": prop.unit_min,
                            "max": prop.unit_max,
                            "unit": prop.unit,
                        }
                        return lfs.core.utils.set_message_cookie(product.get_absolute_url(), msg)

                    # calculate valid steps
                    steps = []
                    x = prop.unit_min
                    while x < prop.unit_max:
                        steps.append("%.2f" % x)
                        x += prop.unit_step
                    steps.append("%.2f" % prop.unit_max)

                    value = "%.2f" % value
                    if value not in steps:
                        msg = _(
                            u"Your entered value for %(name)s (%(value)s) is not in valid step width, which is %(step)s."
                        ) % {"name": prop.title, "value": value, "step": prop.unit_step}
                        return lfs.core.utils.set_message_cookie(product.get_absolute_url(), msg)

    if product.get_active_packing_unit():
        quantity = product.get_amount_by_packages(quantity)

    cart = cart_utils.get_or_create_cart(request)

    cart_item = cart.add(product, properties_dict, quantity)
    cart_items = [cart_item]

    # Check stock amount
    message = ""
    if product.manage_stock_amount and cart_item.amount > product.stock_amount and not product.order_time:
        if product.stock_amount == 0:
            message = _(u"Sorry, but '%(product)s' is not available anymore.") % {"product": product.name}
        elif product.stock_amount == 1:
            message = _(u"Sorry, but '%(product)s' is only one time available.") % {"product": product.name}
        else:
            message = _(u"Sorry, but '%(product)s' is only %(amount)s times available.") % {
                "product": product.name,
                "amount": product.stock_amount,
            }
        cart_item.amount = product.stock_amount
        cart_item.save()

    # Add selected accessories to cart
    for key, value in request.POST.items():
        if key.startswith("accessory"):
            accessory_id = key.split("-")[1]
            try:
                accessory = Product.objects.get(pk=accessory_id)
            except ObjectDoesNotExist:
                continue

            # Get quantity
            quantity = request.POST.get("quantity-%s" % accessory_id, 0)
            try:
                quantity = float(quantity)
            except TypeError:
                quantity = 1

            cart_item = cart.add(product=accessory, amount=quantity)
            cart_items.append(cart_item)

    # Store cart items for retrieval within added_to_cart.
    request.session["cart_items"] = cart_items
    cart_changed.send(cart, request=request)

    # Update the customer's shipping method (if appropriate)
    customer = customer_utils.get_or_create_customer(request)
    shipping_utils.update_to_valid_shipping_method(request, customer, save=True)

    # Update the customer's payment method (if appropriate)
    payment_utils.update_to_valid_payment_method(request, customer, save=True)

    # Save the cart to update modification date
    cart.save()

    try:
        url_name = settings.LFS_AFTER_ADD_TO_CART
    except AttributeError:
        url_name = "lfs_added_to_cart"

    if message:
        return lfs.core.utils.set_message_cookie(reverse(url_name), message)
    else:
        return HttpResponseRedirect(reverse(url_name))
예제 #9
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':
                                try:
                                    value = abs(atof(str(value)))
                                except (TypeError, ValueError):
                                    value = 0.0
                            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')
예제 #10
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':
                                try:
                                    value = abs(atof(str(value)))
                                except (TypeError, ValueError):
                                    value = 0.0
                            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')