get_cookie_key method for BasketMiddleware for multi-sites
In a multi-site scenario, one might want different cookie baskets
per site. In that case, an easy way to achieve this is to set different
cookie keys per site. The introduced method provides an easy hook to do
just that.
This finishes the changes made in v0.6 where basket lines started
requiring a stockrecord FK. v0.7 handles the upgrade in middleware by
updating basket lines that didn't have a stockrecord. But since the
patch for v0.7 requires additional database queries, it's time to remove
it - which is what this change does.
This will be a slightly fiddly upgrade for some people as they will need
to run a data migration on their DB before applying the new basket
migration. I've included a sample snippet in the release notes which
should help.
To add caching to the basket contents we need a basket hash but we don't
want to load and process all offers. Separate the retrieval of the
basket and make the hash accessible via request.basket_hash
This is a major performance improvement for pages where the basket is
not used (other pages or loading basket async via javascript).
Note that request.basket is now not available when calling
`apply_offers_to_basket`. Note sure why this is required since the
basket is passed along.
apply_offers_to_basket may depend on it, so we attach it before calling
that.
Reported and code supplied by @vovanbo. I re-did the work to add
comments.
Fixes #1172
Stop using home-rolled encryption for basket cookies
For anon users, the basket ID is stored in a cookie. Previously, this
was stored with a simple crc32 hash to prevent users enumerating baskets
by changing their cookies. However, home-rolled encryption is always a
bad idea. In this case, it may have probably exposed too much
information allowing the SECRET_KEY to be determined.
This change switches away from the home-rolled encryption to use
Django's built-in crypto signing functionality to store the basket ID.
Thanks to Raphael Kimmig for reporting this issue and providing this
patch.
Fix issue with updating basket cookie in the middleware
Handle the case correctly where the basket cookie needs to be deleted
and updated in the same request. This can happen when unfreezing the
basket. Django's response.delete_cookie doesn't remove the cookie from
request.COOKIES so we need to manually check this.
This change handles the backwards compatiblity issue of adding a
required stockrecord field onto the basket line model.
When a basket in encountered which has a line without a stockrecord, we
delete it and attempt to re-add it to the basket.
We also merge the middleware together for simplicity.
Hmmm, this turned out to be a monster commit. This change allows the
basket to be able to correctly calculate prices including tax.
It also requires a whole load of test changes since all baskets now
require a strategy instance to be assigned.
Move basket status constants onto the Basket class
It was a mistake to have them at module level as it meant it was a pain
to import them when they were needed for filtering. Having them on
the basket is much nicer as they available whenever the Basket class is.
This commit may cause a few gremlins for people updating to 0.4 but I
think it's a necessary pain at this stage. It's trivial to fix too.
When merging a cookie basket with a user basket, we now set the new line
quantity to the max of that from the two baskets. This is to prevent
stock rules being violated by merging these baskets.