Repository: saleor/saleor

Issue:
All products shouldn't be shippable by default
We can add boolean field like shopify does:

![image](https://cloud.githubusercontent.com/assets/1870738/12653691/f1948754-c5f0-11e5-96aa-02b35b0d6439.png)



Discussion:
In my opinion, weight field should be optional field (now it's required). And I agree that we should add boolean field as you suggest :+1: 

:+1:

@patrys What do you think about implementing `requries shipping` flag as a part of ProductClass?
I requested this when discussing product classes initially but it was not implemented.

Resolving patch:
diff --git a/saleor/product/migrations/0026_auto_20161230_0347.py b/saleor/product/migrations/0026_auto_20161230_0347.py
new file mode 100644
--- /dev/null
+++ b/saleor/product/migrations/0026_auto_20161230_0347.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2016-12-30 09:47
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('product', '0025_auto_20161219_0517'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='productclass',
+            name='is_shipping_required',
+            field=models.BooleanField(default=False),
+        ),
+    ]
diff --git a/saleor/product/models/base.py b/saleor/product/models/base.py
--- a/saleor/product/models/base.py
+++ b/saleor/product/models/base.py
@@ -67,12 +67,19 @@ def set_hidden_descendants(self, hidden):
 @python_2_unicode_compatible
 class ProductClass(models.Model):
     name = models.CharField(
-        pgettext_lazy('Product field', 'name'), max_length=128)
-    has_variants = models.BooleanField(default=True)
+        pgettext_lazy('Product class field', 'name'), max_length=128)
+    has_variants = models.BooleanField(
+        pgettext_lazy('Product class field', 'has variants'), default=True)
     product_attributes = models.ManyToManyField(
-        'ProductAttribute', related_name='products_class', blank=True)
+        'ProductAttribute', related_name='products_class', blank=True,
+        verbose_name=pgettext_lazy('Product class field',
+                                   'product attributes'))
     variant_attributes = models.ManyToManyField(
-        'ProductAttribute', related_name='product_variants_class', blank=True)
+        'ProductAttribute', related_name='product_variants_class', blank=True,
+        verbose_name=pgettext_lazy('Product class field', 'variant attributes'))
+    is_shipping_required = models.BooleanField(
+        pgettext_lazy('Product class field', 'is shipping required'),
+        default=False)
 
     class Meta:
         app_label = 'product'
@@ -235,7 +242,7 @@ def as_data(self):
             'unit_price': str(self.get_price_per_item().gross)}
 
     def is_shipping_required(self):
-        return True
+        return self.product.product_class.is_shipping_required
 
     def is_in_stock(self):
         return any(


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -115,7 +115,8 @@ def default_category(db):  # pylint: disable=W0613
 @pytest.fixture
 def product_class(color_attribute, size_attribute):
     product_class = ProductClass.objects.create(name='Default Class',
-                                                has_variants=False)
+                                                has_variants=False,
+                                                is_shipping_required=True)
     product_class.product_attributes.add(color_attribute)
     product_class.variant_attributes.add(size_attribute)
     return product_class