Commits

Kai Diefenbach  committed 6718011 Merge

Merged origin.

  • Participants
  • Parent commits c5db0c1, a507e26

Comments (0)

Files changed (9)

File lfs/catalog/models.py

         else:
             return self.sku
 
+    def get_manufacturer(self):
+        """Always return parent manufacturer for variants.
+        """
+        if self.is_variant():
+            return self.parent.manufacturer
+        else:
+            return self.manufacturer
+
     def get_tax_rate(self, request):
         """Returns the tax rate of the product.
         """

File lfs/manage/urls.py

     url(r'^edit-product-manufacturer/(?P<manufacturer_id>\d*)/(?P<product_id>\d*)$', "edit_product", name="lfs_manufacturer_edit_product"),
     url(r'^category-state-manufacturer/(?P<manufacturer_id>\d*)/(?P<category_id>\d*)$', "category_state", name="lfs_manufacturer_category_state"),
     url(r'^manufacturer-inline/(?P<manufacturer_id>\d*)/(?P<category_id>\d*)$', "manufacturer_inline", name="lfs_manufacturer_inline"),
+    url(r'^manufacturers-ajax/$', "manufacturers_ajax", name="lfs_manufacturers_ajax"),
 )
 
 # Marketing

File lfs/manage/views/manufacturer.py

 from django.utils import simplejson
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.http import require_POST
+from django.views.decorators.cache import never_cache
 
 # lfs imports
 import lfs.core.utils
 from lfs.catalog.models import Product
 from lfs.core.utils import LazyEncoder
 from lfs.manufacturer.models import Manufacturer
-from lfs.manufacturer.models import Manufacturer
 
 
 class ManufacturerDataForm(ModelForm):
         klass = ""
 
     return (checked, klass)
+
+
+@never_cache
+@permission_required("core.manage_shop", login_url="/login/")
+def manufacturers_ajax(request):
+    """ Returns list of manufacturers for autocomplete
+    """
+    term = request.GET.get('term', '')
+    manufacturers = Manufacturer.objects.filter(name__istartswith=term)[:10]
+
+    out = []
+    for man in manufacturers:
+        out.append({'label': man.name,
+                    'value': man.pk})
+
+    result = simplejson.dumps(out, cls=LazyEncoder)
+    return HttpResponse(result)

File lfs/manage/views/product/product.py

 from django.utils import simplejson
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.http import require_POST
+from django.forms.widgets import HiddenInput
+from django.conf import settings
 
 # lfs imports
 import lfs.core.utils
 from lfs.catalog.models import Category
 from lfs.catalog.models import Product
 from lfs.catalog.settings import VARIANT, PRODUCT_TYPE_FORM_CHOICES, PRODUCT_TEMPLATES
+from lfs.manufacturer.models import Manufacturer
 from lfs.core.utils import LazyEncoder
 from lfs.manage.views.product.images import manage_images
 from lfs.manage.views.product.seo import manage_seo
     def __init__(self, *args, **kwargs):
         super(ProductDataForm, self).__init__(*args, **kwargs)
         self.fields["template"].widget = SelectImage(choices=PRODUCT_TEMPLATES)
+        man_count = Manufacturer.objects.count()
+        if man_count > getattr(settings, 'LFS_SELECT_LIMIT', 20):
+            # use autocomplete if there is more manufacturers
+            # than LFS_SELECT_LIMIT
+            self.fields["manufacturer"].widget = HiddenInput()
 
     class Meta:
         model = Product
-        fields = ("active", "name", "slug", "sku", "sku_manufacturer", "price", "tax", "price_calculator",
+        fields = ("active", "name", "slug", "manufacturer", "sku", "sku_manufacturer", "price", "tax", "price_calculator",
             "short_description", "description", "for_sale", "for_sale_price", "static_block", "template",
             "active_price_calculation", "price_calculation", "price_unit", "unit")
 
 
     class Meta:
         model = Product
-        fields = ("active", "active_name", "name", "slug", "active_sku", "sku", "sku_manufacturer",
+        fields = ("active", "active_name", "name", "slug", "manufacturer", "active_sku", "sku", "sku_manufacturer",
             "active_price", "price", "price_calculator", "active_short_description", "short_description", "active_description",
             "description", "for_sale", "for_sale_price", "active_for_sale", "active_for_sale_price",
             "active_related_products", "active_static_block", "static_block", "template")
 
     product = lfs_get_object_or_404(Product, pk=product_id)
     products = _get_filtered_products_for_product_view(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     try:
     """
     product = lfs_get_object_or_404(Product, pk=product_id)
     products = _get_filtered_products_for_product_view(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     if product.sub_type == VARIANT:
         del request.session["product_filters"]
 
     products = _get_filtered_products(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     product_id = request.REQUEST.get("product-id", 0)
     """Saves products with passed ids (by request body).
     """
     products = _get_filtered_products(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     if request.POST.get("action") == "delete":
     request.session["product_filters"] = product_filters
 
     products = _get_filtered_products_for_product_view(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     product_id = request.REQUEST.get("product-id", 0)

File lfs/static/css/lfs.manage.css

 /* input fields */
 #id_name, #id_slug, #id_sku, #id_shop_owner, #id_from_email, #id_title, #id_redirect_to, #id_sku_manufacturer, #redirect_to, #id_position, #id_unit,
 #id_priority, #id_price, #id_for_sale_price, #id_tax, #id_module, #id_link, #id_parent, #id_static_block, #id_price_unit, #id_template, #id_meta_title,
-#id_type, #id_step_type {
+#id_type, #id_step_type, #id_manufacturer_autocomplete, #id_manufacturer, #id_price_calculator {
     width: 300px;
 }
 

File lfs/static/js/lfs.manage.js

 			// ReferenceError due to undefined tinymce
 	    }
         show_ajax_loading();
+
+        // trigger form-save-start event when form is about to be submitted
+        var form = $(this).closest("form");
+        var form_id = form.get(0).id;
+        var event = jQuery.Event("form-save-start");
+        event.form_id = form_id;
+        $('body').trigger(event);
+
         var action = $(this).attr("name")
-        $(this).parents("form:first").ajaxSubmit({
+        form.ajaxSubmit({
             data : {"action" : action},
             success : function(data) {
                 data = $.parseJSON(data);
                 }
                 hide_ajax_loading();
                 update_editor();
+
+                // trigger form-save-end event when new HTML has already been injected into page
+                var event = jQuery.Event("form-save-end");
+                event.form_id = form_id;
+                $('body').trigger(event);
             }
         })
         return false;
         knot.parent().find(".category-state").html("");
     };
 
-    $(function() {
-        $(".category-ajax-link").live("click", function() {
-            var url = $(this).attr("href");
+    $(".category-ajax-link").live("click", function() {
+        var url = $(this).attr("href");
 
-            // Loads children of clicked category.
-            if ($(this).hasClass("collapsed")) {
-                $.post(url, function(data) {
-                    data = $.parseJSON(data);
-                    for (var html in data["html"])
-                        $(data["html"][html][0]).html(data["html"][html][1]);
-                })
-                $(this).removeClass("collapsed");
-                $(this).addClass("expanded");
-            }
-            // Removes children of clicked category.
-            else {
-                $(this).siblings("div").html("")
-                $(this).removeClass("expanded");
-                $(this).addClass("collapsed");
-            }
-            return false;
-        });
+        // Loads children of clicked category.
+        if ($(this).hasClass("collapsed")) {
+            $.post(url, function(data) {
+                data = $.parseJSON(data);
+                for (var html in data["html"])
+                    $(data["html"][html][0]).html(data["html"][html][1]);
+            })
+            $(this).removeClass("collapsed");
+            $(this).addClass("expanded");
+        }
+        // Removes children of clicked category.
+        else {
+            $(this).siblings("div").html("")
+            $(this).removeClass("expanded");
+            $(this).addClass("collapsed");
+        }
+        return false;
+    });
 
-        $(".export-category-input").live("click", function() {
+    $(".export-category-input").live("click", function() {
 
-            // select / deselect all child nodes
-            var input = $(this);
-            var parent_checked = this.checked;
-            $(this).parent().find("input").each(function() { this.checked = parent_checked; })
+        // select / deselect all child nodes
+        var input = $(this);
+        var parent_checked = this.checked;
+        $(this).parent().find("input").each(function() { this.checked = parent_checked; })
 
-            // Updates child and parent categories of clicked category
-            var url = $(this).attr("data");
-            if (parent_checked == true) {
-                $.post(url, {"action" : "add"}, function(data) {
-                    update_sub_categories(input);
-                    update_parent_categories(input);
-                });
-            }
-            else {
-                $.post(url, {"action" : "remove"}, function(data) {
-                    update_sub_categories(input);
-                    update_parent_categories(input);
-                });
-            }
-        });
+        // Updates child and parent categories of clicked category
+        var url = $(this).attr("data");
+        if (parent_checked == true) {
+            $.post(url, {"action" : "add"}, function(data) {
+                update_sub_categories(input);
+                update_parent_categories(input);
+            });
+        }
+        else {
+            $.post(url, {"action" : "remove"}, function(data) {
+                update_sub_categories(input);
+                update_parent_categories(input);
+            });
+        }
+    });
 
-        $(".export-product-input").live("click", function() {
-            // Add / Remove product
-            var input = $(this);
-            var url = $(this).attr("data");
-            var checked = this.checked;
+    $(".export-product-input").live("click", function() {
+        // Add / Remove product
+        var input = $(this);
+        var url = $(this).attr("data");
+        var checked = this.checked;
 
-            // Updates parent catgories of clicked product
-            if (checked == true) {
-                $.post(url, {"action" : "add"}, function(data) { update_parent_categories(input) } );
-            }
-            else {
-                $.post(url, {"action" : "remove"}, function(data) { update_parent_categories(input) });
-            }
-        });
+        // Updates parent catgories of clicked product
+        if (checked == true) {
+            $.post(url, {"action" : "add"}, function(data) { update_parent_categories(input) } );
+        }
+        else {
+            $.post(url, {"action" : "remove"}, function(data) { update_parent_categories(input) });
+        }
     });
 
     $(".category-variants-options").live("change", function() {

File lfs/static/js/lfs.manage.product.js

+/* Handle autocomplete on manufacturer field at product management page
+ * Uses jquery UI autocomplete implementation
+ */
+$(function() {
+    var MANUFACTURER_AUTOCOMPLETE_SETTINGS = {
+         source: MANUFACTURERS_AJAX_URL,
+         select: function(event, ui){
+             $('#id_manufacturer').val(ui.item.value);
+             $('#id_manufacturer_autocomplete').val(ui.item.label);
+             return false;
+         },
+         focus: function(event, ui){
+             $('#id_manufacturer').val(ui.item.value);
+             $('#id_manufacturer_autocomplete').val(ui.item.label);
+             return false;
+         },
+         change: function(event, ui){
+             if (ui.item === null){
+                 // only accept items selected from the list
+                 $('#id_manufacturer').val('');
+                 $('#id_manufacturer_autocomplete').val('');
+             }
+             return false;
+         },
+         minLength: 1
+    };
+
+    $('#id_manufacturer_autocomplete').autocomplete(MANUFACTURER_AUTOCOMPLETE_SETTINGS);
+    $('body').bind('form-save-start', function(evt){
+        if (evt.form_id == 'product-data-form'){
+            // ensure that manufacturer_id is cleared if autocomplete field is empty
+            if ($('#id_manufacturer_autocomplete').val() === ''){
+                $('#id_manufacturer').val('');
+            }
+        }
+    });
+
+    // when form is reloaded we have to reattach autocomplete
+    $('body').bind('form-save-end', function(evt){
+        if (evt.form_id == 'product-data-form'){
+            $('#id_manufacturer_autocomplete').autocomplete(MANUFACTURER_AUTOCOMPLETE_SETTINGS);
+        }
+    });
+})

File lfs/templates/manage/product/data.html

                     </div>
                 {% endif %}
             </div>
+
+            <div class="field">
+                <div class="label">
+                    {{ form.manufacturer.label_tag }}:
+                </div>
+
+                {% if form.manufacturer.errors %}
+                    <div class="error">
+                        {{ form.manufacturer }}
+                        {{ form.manufacturer.errors }}
+                    </div>
+                {% else %}
+                    <div>
+                        {% if product.is_variant %}
+                            {{ product.get_manufacturer|default_if_none:"-" }}
+                        {% else %}
+                            {{ form.manufacturer }}
+                            {% if form.manufacturer.is_hidden %}
+                                <input type="text" id="id_manufacturer_autocomplete" value="{{ form.instance.manufacturer.name }}" />
+                            {% endif %}
+                        {% endif %}
+                    </div>
+                {% endif %}
+            </div>
+
             <div class="field">
                 <div class="label">
                     {{ form.sku_manufacturer.label_tag }}:

File lfs/templates/manage/product/product.html

 {% block title %}{% trans "Manage Product" %}{% endblock %}
 {% block section %}manage-product{% endblock %}
 
+{% block javascript %}
+    <script type="text/javascript" src="{{ STATIC_URL }}js/lfs.manage.product.js"></script>
+    <script type="text/javascript">
+        var MANUFACTURERS_AJAX_URL = '{% url lfs_manufacturers_ajax %}';
+    </script>
+{% endblock %}
+
 {% block left_slot %}
     <form action="{% url lfs_set_product_name_filter %}"
           method="post">