Fix Range.all_products() inconsistency with contains_product()
This change fixes the inconsistency with range.all_products() which
didn't check for exclusions when includes_all_products is set
Every other bit of oscar expected range.includes_all_products means
that all products are included, no questions asked. The dashboard
interface even hides the option to edit/remove individual products.
The short circuiting in ConditionalOffer.products() is removed so
the range.all_products() logic is applied consistently.
Refactor Benefit clean methods and add tests for all of them.
- Refactor clean methods to return all validation errors, rather than just the first one we found.
- Fix clean method type errors in Python 3
- Add tests for the clean methods for all benefit types.
Fix logic for checking whether an offer is active based on date.
- If start_datetime is null, then the offer has no start date.
- If end_datetime is null, then the offer never expires.
Use the ActiveOfferManager in Applicator.get_site_offers instead of
reimplementing the same logic there.
Fixes #2344.
Cleanup unused benefits and conditions after conditional offer removal.
Now after ConditionalOffer deleted will be deleted related Benefits and Conditions models (through post_delete signal) if they are no longer used by other offers (with exception of custom benefits/conditions). Plus some small changes related to PEP8 and typos.
The idea of splitting integration from unittests is good in theory
but leads to a lot of mental overhead. Besides whenever a tests
interacts with a database it isn't a unittest anyway.
- Set Meta.app_label on models created in the tests
- Use logging.NullHandler instead of django.utils.log.NullHandler
- Use oscar.core.loading.get_model() instead of django's get_model
- Remove template tags '{% load url from future %}'
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.
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.
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.