Skip to content

Commit

Permalink
Fix backwards incompatible changes
Browse files Browse the repository at this point in the history
  • Loading branch information
izidormatusov committed Nov 26, 2013
1 parent dd02c00 commit 92311ce
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 16 deletions.
17 changes: 17 additions & 0 deletions docs/source/releases/v0.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ Customer-facing range pages

Ranges can now be flagged as public which means they can be browsed by
customers. They can be used to created curated collections of products.
Products can be manually reordered to display products in the specific
order to customers.

The core :class:`~oscar.apps.offer.models.Range` model has been extended with a
HTML description field also.
Expand Down Expand Up @@ -334,6 +336,21 @@ Address model changes
* The ``Country`` model's `is_highlighted` column is now an integer field to allow
fine-grained country selection.

Range model changes
~~~~~~~~~~~~~~~~~~~

ManyToManyField ``included_product`` of ``Range`` model was changed to use
``through`` relationship:

* Use ``Range.add_product(product)`` instead of
``Range.included_product.add(product)``.
* Use ``Range.remove_product(product)`` instead of
``Range.included_product.remove(product)``.

When adding a product into a range, position in the range can be specified
with ``display_order`` argument:
``Range.add_product(product, display_order=3)``

Renamed templates
~~~~~~~~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion oscar/apps/dashboard/ranges/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def process(self):
models.Q(stockrecord__partner_sku__in=new_ids) |
models.Q(upc__in=new_ids))
for product in products:
self.range.included_products.add(product)
self.range.add_product(product)

# Processing stats
found_skus = set(filter(bool, products.values_list('stockrecord__partner_sku', flat=True)))
Expand Down
4 changes: 2 additions & 2 deletions oscar/apps/dashboard/ranges/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def get_context_data(self, **kwargs):
def remove_selected_products(self, request, products):
range = self.get_range()
for product in products:
range.included_products.remove(product)
range.remove_product(product)
num_products = len(products)
messages.success(request, ungettext("Removed %d product from range",
"Removed %d products from range",
Expand All @@ -149,7 +149,7 @@ def handle_query_products(self, request, range, form):
return

for product in products:
range.included_products.add(product)
range.add_product(product)

num_products = len(products)
messages.success(request, ungettext("%d product added to range",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,17 @@ def backwards(self, orm):
'excluded_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'excludes'", 'blank': 'True', 'to': u"orm['catalogue.Product']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'included_categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'includes'", 'blank': 'True', 'to': u"orm['catalogue.Category']"}),
'included_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'includes'", 'blank': 'True', 'through': u"orm['offer.RangeOrdering']", 'to': u"orm['catalogue.Product']"}),
'included_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'includes'", 'blank': 'True', 'through': u"orm['offer.RangeProduct']", 'to': u"orm['catalogue.Product']"}),
'includes_all_products': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
'proxy_class': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '128', 'unique': 'True', 'null': 'True'})
},
u'offer.rangeordering': {
'Meta': {'object_name': 'RangeOrdering'},
u'offer.rangeproduct': {
'Meta': {'unique_together': "(('range', 'product'),)", 'object_name': 'RangeProduct'},
'display_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"}),
'range': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['offer.Range']"})
}
Expand Down
34 changes: 34 additions & 0 deletions oscar/apps/offer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,37 @@ def save(self, *args, **kwargs):
# Save Range
super(Range, self).save(*args, **kwargs)

def add_product(self, product, display_order=None):
""" Add product to the range
When adding product that is already in the range, prevent re-adding it.
If display_order is specified, update it.
Standard display_order for a new product in the range (0) puts
the product at the top of the list.
display_order needs to be tested for None because
>>> display_order = 0
>>> not display_order
True
>>> display_order is None
False
"""
initial_order = 0 if display_order is None else display_order
relation, __ = RangeProduct.objects.get_or_create(
range=self, product=product,
defaults={'display_order': initial_order})

if (display_order is not None and
relation.display_order != display_order):
relation.display_order = display_order
relation.save()

def remove_product(self, product):
""" Remove product from range """
RangeProduct.objects.filter(range=self, product=product).delete()

def contains_product(self, product):
"""
Check whether the passed product is part of this range
Expand Down Expand Up @@ -877,6 +908,9 @@ class RangeProduct(models.Model):
product = models.ForeignKey('catalogue.Product')
display_order = models.IntegerField(default=0)

class Meta:
unique_together = (('range', 'product'),)

# ==========
# Conditions
# ==========
Expand Down
1 change: 0 additions & 1 deletion sites/_fixtures/offers.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@
"fields": {
"included_categories": [],
"name": "Site",
"included_products": [],
"proxy_class": null,
"excluded_products": [],
"classes": [],
Expand Down
4 changes: 1 addition & 3 deletions sites/_fixtures/ranges.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"included_categories": [],
"name": "Whole site",
"slug": "whole-site",
"included_products": [],
"proxy_class": null,
"excluded_products": [],
"classes": [],
Expand All @@ -23,12 +22,11 @@
],
"name": "Fiction books",
"slug": "fiction-books",
"included_products": [],
"proxy_class": null,
"excluded_products": [],
"classes": [],
"date_created": "2013-02-21T16:25:38.805Z",
"includes_all_products": false
}
}
]
]
4 changes: 2 additions & 2 deletions tests/functional/dashboard/range_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ def test_missing_skus_are_available(self):

def test_only_dupes_is_invalid(self):
product = create_product(partner_sku='123123')
self.range.included_products.add(product)
self.range.add_product(product)
form = self.submit_form({'query': '123123'})
self.assertFalse(form.is_valid())

def test_dupe_skus_are_available(self):
product = create_product(partner_sku='123123')
create_product(partner_sku='123124')
self.range.included_products.add(product)
self.range.add_product(product)
form = self.submit_form({'query': '123123, 123124'})
self.assertTrue(form.is_valid())
self.assertTrue('123123' in form.get_duplicate_skus())
4 changes: 2 additions & 2 deletions tests/integration/offer/condition_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ def setUp(self):
self.products = [factories.create_product(), factories.create_product()]
self.range = models.Range.objects.create(name="Some products")
for product in self.products:
self.range.included_products.add(product)
self.range.included_products.add(product)
self.range.add_product(product)
self.range.add_product(product)
self.basket = factories.create_basket(empty=True)
self.condition = models.CoverageCondition(
range=self.range, type="Coverage", value=2)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/offer/range_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_all_products_range_with_exception(self):
self.assertFalse(self.range.contains_product(self.prod))

def test_whitelisting(self):
self.range.included_products.add(self.prod)
self.range.add_product(self.prod)
self.assertTrue(self.range.contains_product(self.prod))

def test_blacklisting(self):
Expand Down

0 comments on commit 92311ce

Please sign in to comment.