* flesh-out initial opaque data-model
refactors the basket line consumption into a facade object.
the goals is accomodating combitions of various offers on the same basket-lines,
while remaining backward compatible with the current single offer per line
policy.
* add docstrings
* add exclusive flag to conditionaloffer model and continue refactoring
* test new offer consumption on basket view
* cleanups
* fix exclusivity
* code style
* add cast to pacify tests
* spelling
* add some documentation to the release notes
* move documentation to new 1.6 release docs
Fix handling of free products when calculating basket totals in Python 3.
In Python 2, adding None to the basket total worked, but in Python 3 this raises a TypeError. This fixes the handling of totals to distinguish between a zero price and a non-existent price.
The pk kwarg on views is a string type. The message format string was expecting a numeric value. This updates that format string to expect a string value, which will always display correctly.
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.
Prevent trying to save a negative quantity to a Basket
basket.Line.quantity is a positive integer field, but the quantity sumation in
basket.Basket.add_product made it possible to try and save negative values. This
makes add_product never go below 0-quantity, thereby preventing a db exception
from being thrown. Also adds a test for the described behavior.
Trigger product unavailable warning message using availability policy rather than reproducing the stockrecord check, to allow for greater extensibility.
Replace assert statements with appropriate assert* method.
Replace 'assert' with 'assert*' method.
Convert tests.unit.forms.widget_tests to use TestCase class.
Convert bankcard tests to use TestCase.
Convert tests.unit.logging_tests to use TestCase.
Validate that basket additions have the same currency as the basket
And this is the outer-most frame of the Yak-shave: preventing the many
errors messages I get from the public sandbox site where people try to
add products of multiple currencies to their basket.
It was quite a journey...
Test basket's strategy class is correctly exercised by form
This shows the problem with forms knowing too much of the details of
collaborators. This is a design smell and will be looked at before
things get too stinky.
This is quite a large change. It:
- Alters the add-to-basket URL to have the "base" product's PK in it
- Changes the constructor of the AddToBasket form to not require
purchase_info (even though I only just introduced it!)
- Renames the product_id field to variant_id and only uses it for group
products
These changes are motivated by the variant workflow. Before this change,
you effectively had different forms being used for rending and
validation as the product being passed to the form constructor was the
group product when rendering but the variant when validating. This just
about worked but was not nice.
The purchase_info param is removed as we can only calculate the
purchase_info once the variant product has been validated. Hence we
again violate Demeter and make a deep call to the purchase info
calculation within the basket form. Might revisit this again.
This change also simplifies the basket view logic and allows a form to
be removed.
This means we don't need to do the law-of-demeter-violating call to
fetch the purchase info for a product (line 79 of forms.py). HOWEVER,
I'm starting to have second thoughts about this - I've discovered that
the adding to basket process is quite confusing for variants and I
intend to refactor.
This commit also adds some useful tests though so it's a valid stepping
stone to a better place.
The word "stock info" was bugging me as it's not quite correct for the
combination of availability and price information. The problem is the
word "stock" which implies physical widgets in a warehouse somewhere.
It sounds weird for ask for stock info for a digital product.
Hence, I came up with PurchaseInfo, which is a bit more vague but
captures the information better.
We no longer need to pass the StockInfo instance as the basket has a
reference to the strategy class and can fetch it for itself. This means
we don't have to break backwards compatibility with Oscar < 0.6.