The offer tests contained a stray test case that I suppose was once
intended as a base class for all the other tests. But it's only used
twice, and for very little gain, so let's delete it.
Fix ValueError in tests when assigning unsaved instance
Django now throws a ValueError when an unsaved instance is assigned:
https://docs.djangoproject.com/en/1.8/releases/1.8/#assigning-unsaved-objects-to-relations-raises-an-error
This commit changes the offending lines to create objects in the
database instead. But I don't understand why I don't need to make
the same changes for e.g. the country factory.
But I don't really care, as long as the tests pass. I'm guessing it has
something to do with factory-boy and the get_or_create statement.
Unfortunately, this will make our test suite slower. But to make up for
it, Django 1.8 introduces the setUpTestCase method, which we can use
once Django 1.7 is removed.
Refactor the shipping_status method to return a consistent last
complete status. Since dictionaries have no guaranteed order, and also
since the shipping status queryset isn’t ordered the method didn’t
always return the actual last complete status.
Conflicts:
oscar/test/newfactories.py
tests/integration/order/model_tests.py
Backported by @maikhoepfel from #1672.
Refactor the shipping_status method to return a consistent last
complete status. Since dictionaries have no guaranteed order, and also
since the shipping status queryset isn’t ordered the method didn’t
always return the actual last complete status.
Unify to (basket, user=None, request=None) argument order in Applicator
This order offers the simplest API for common needs - as evidenced by the
fact that the apply_offers crook could be removed from two test files,
saving on imports as well.
Now that the category tag is greatly simplified, it's also easier to
test. The tests previously needed to render the template tag; now we can
just test the method itself. Together with some set operations, this
makes for simpler-to-understand and faster tests.
I also corrected a typo: 'Children' instead of 'Childrens'.
As category slugs are relevant for SEO, it is often desirable to be able
to change them independently of the name.
Previously, Oscar by default updated the slug on each save().
This commit completely removes the logic to update an existing slug, as
it is an anti-pattern, as it breaks old links to the site.
It also doesn't raise a ValidationError in the save() method any more,
which is an anti pattern as well. Unfortunately, we can't validate
uniqueness in a clean_slug method (where it should live) as we need
treebeard's information about siblings, which is only available after
save.
This commit replaces the previous slug handling by a simpler approach:
if no slug is supplied, we generate one -- otherwise we assume the user
knows what they're doing.
Repurpose Category.slug to store single slug instead of all slugs
Historically, the slug field contained both the category's slug, and the
slugs of it's ancestor's concatenated together. This leads to various
issues as detailed in #1670.
This commit greatly simplifies the logic by
* introducing a full_slug property, analogous to full_name, that
returns what used to be stored in the slug field
* removing the complex 'update subtree' logic as it's not necessary any
more
* Updating the ProductCategoryView's category fetching logic as needed
It feels like the data migration is scary, but I can't think of many
ways this could go wrong. We do need to be clear to instruct the users
that they must run it as well.
I haven't included a South data migration because we're scheduled to
remove Django 1.6 support per our policy.
We historically stored the name of the category and it's ancestors as
full_name. I'm removing that as:
- It's only used in search indexes, and hence a needless performance
optimisation and denormalisation.
- It makes for yet another thing to think about when updating the
category tree.
- It gets messy when using e.g. django-modeltranslation to translate
categories.
They are from a time when we had one stockrecord per product, and no
strategy classes. They're used for visual purposes only, and were
forgotten when the codebase was updated. They failed loudly, as reported
in #1592.
We really need to either drop them or add a helper method to the
strategy class, but to ensure backwards-compatibility, I've
re-implemented the naive approach of just sorting by price; blindly
ignoring the many shortcomings.
I also added a deprecation notice.
Allow zero weight baskets to still get a weight-based charge
There wasn't really a need to special-case zero weight baskets. This
does mean that stores that rely on this behaviour will need to create a
zero weight band.
Removes the auto_now_add=True. Sets now as the default, but allows changing the date_placed field explicitly if an order is updated after it has been placed.
Fixes #1529
This already worked only within site offers by way of default model
ordering. Site offers are probably the most common offers, however the
ordering of all offers has to be controlled by the applicator.
Conflicts:
tests/integration/offer/applicator_tests.py
Cherry-picked from #1414.
Don't create objects in the database unless necessary
Conflicts:
oscar/apps/offer/models.py
tests/integration/offer/combination_tests.py
tests/integration/offer/percentage_benefit_tests.py
@maikhoepfel duplicated the proxy class short-circuit logic for
Conditions as part of this commit.
Cherry-picked from #1414.
Update handling of child product for product ranges
This commit addresses issue #1253.
Currently, the offers app doesn't really consider child products;
behaviour is undefined. This commit addresses the fact: for now, we
assume that child and parent products are tightly coupled, and forbid
child products in a range. You can only add the parent product (and
with it all children).
This requirement might be lifted in the future, but that will mean
additional complexity and we will see if it's necessary.
Closes #1253.
* Removed unused _save method. It's not called anywhere.
* Simplified comment and logic for display_order
* Reordered imports
* Used items() instead of six.iteritems() because create_range does not
get complex kwargs
* Removed a duplicate test
* Test for the correct exception
It only prevents adding a product to a range; offers can be applied
nonetheless (despite the docs saying otherwise). The same functionality
can be achieved by overriding get_is_discountable, so it can be safely
removed.
Issue #855 is caused when deleting the middle of three product images in
the dashboard. A quick workaround is to renumber the image order values
when deleting an image. Eventually, this should be readressed as part of
issue #856.
This commit is the squashed version of #1429.
Overide delete() on AbstractProductImage.
Ensures the display order is always in consecutive order.
Cleans up after TestProductImages is run.
Fixes #855.
Closes #1429.
At the moment, we don't support setting is_discountable for child
products individually. This does keep things simpler when editing
products. If a use case crops up, it should be reasonably easy to
change.
Ignore capitalisation of local part of email address
Most email servers don't respect capitalisation, and many users don't
know about it. So Oscar now does what the rest of the world does, and
ignores the capitalisation when looking up an email address.
Fixes #1179.
Where I previously thought that renaming HTML/CSS is more hassle than
it's worth, @mbertheau convinced me that to update a codebase, a general
search-and-replace is the best approach already and will catch any
HTML/CSS changes.
I also missed to deprecate the min_variant_price properties.
Replace countries.json fixture by management command
I started looking at this because on the mailing list, having the UK as
only shipping country led to confusion. This is mostly due to the
shipping address form hiding the country field if there's only one
country enabled, but all the validation then requiring UK postcodes and
phone numbers.
It's bothered me for a while that we're using a fixture to populate the
countries, which is at risk of becoming stale.
pycountry offers an excellent data source for a list of countries, so I
polished an existing management command to use it to populate the
country database.
This commit has two immediate effects:
* New setups will use a more current country database
* By default, all countries will be marked as shipping countries
pycountry also ships with localised names of the countries, which should
allow us to populate the database with localised country names.
This is the result of wild grepping through the codebase. Nothing too
exciting to report, really. create_product now sets a products structure
to 'child' if a parent is specified.