Fix errors with shipping discounts on free weightbased shipping.
The Repository.apply_shipping_offer() method returns the shipping method
object when there is no additional discount for an order. This however
broke with the WeightBased, because it's implementation does not work.
self.offer is never assigned, nor useful (a copy-paste error?).
Instead, it should work like the non-model `methods.Base` that also
states the method does not have a default shipping discount.
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.
You can't easily create multiple users with the UserFactory without
using a sequence. I also wasn't aware that one can use the nicer
"factories" import instead of "newfactories".
Note that we can't easily use a LazyAttribute for the email address, as
the username may contain spaces.
Multiply charges when exceeding top bands upper limit
This approach imitates sending multiple parcels for a defined cost, and
hopefully approximates reality much better.
Note we still make some assumptions about the cost structure to avoid
having to solve an NP hard problem.
This commit also removes the unused max_upper_limit property and
replaces it by a more useful top_band property.
Drop upper_charge logic for weight based shipping methods
Previously, weight based shipping methods accepted an upper charge
field. When no weight band matched the baskets weight, this was
returned. I am not aware of a single retailer who calculates shipping
charges like that. It's impossible to pick a sensible value for a
retailer, as there's no upper limit to the amount of items ordered, and
any shipping charges would have to cover costs for that.
Get weight-based shipping method to return charges again
Setting band.charge was accidentally killed in the refactor to the new
shipping method interface, so a correct charge was never returned. This
wasn't caught because there was no test for testing the actual shipping
charge calculation...
Both issues are remedied now. I'll have a more detailled look at the
shipping method tests when getting rid of upper_charge.
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.
Use charge_incl_tax instead of basket_charge_incl_tax(). This is
clearer.
Backwards compatible versions of the old methods are kept for now.
Related to #805
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.
This allows updating code in both places, if necessary. Getting Django
1.5 support would be painful otherwise. This also removes the circular
dependency of django-oscar-testsupport on Oscar.
The requirements were merged. The imports were updated
accordingly. Unused imports in the touched files were removed. No
further changes.
shipping/models:ShippingMethod was missing the is_discounted attribute that
exists in the de-facto superclass in shipping/base:ShippingMethod.
Also added a few comments to clarify how they relate to each other, and
tests to check if is_discounted is present on various instances of
ShippingMethods.