Repository: django-oscar/django-oscar

Issue:
Extend basket view to use default shipping address
The basket summary view attempts to look up a default shipping method so an indicative order total can be displayed.  The checkout allows the method to be changed later on though.

At the basket stage, we don't know the user's chosen shipping address so we don't pass it.  However, Oscar does have a concept of default shipping address.  We should extend the basket view to pass the user's default shipping address (if one is known).



Discussion:
Its not clear to me - pass where ? to the template so it will be displayed on the page ?

> pass where ?

right here https://github.com/django-oscar/django-oscar/blob/master/src/oscar/apps/shipping/methods.py#L33
how would I calculate the shipping charge, without knowing the address?


Resolving patch:
diff --git a/src/oscar/apps/basket/views.py b/src/oscar/apps/basket/views.py
--- a/src/oscar/apps/basket/views.py
+++ b/src/oscar/apps/basket/views.py
@@ -54,10 +54,15 @@ def get_shipping_methods(self, basket):
             basket=self.request.basket, user=self.request.user,
             request=self.request)
 
+    def get_default_shipping_address(self):
+        if user_is_authenticated(self.request.user):
+            return self.request.user.addresses.filter(is_default_for_shipping=True).first()
+        return
+
     def get_default_shipping_method(self, basket):
         return Repository().get_default_shipping_method(
             basket=self.request.basket, user=self.request.user,
-            request=self.request)
+            request=self.request, shipping_addr=self.get_default_shipping_address())
 
     def get_basket_warnings(self, basket):
         """


Test patch:
diff --git a/tests/fixtures.py b/tests/fixtures.py
--- a/tests/fixtures.py
+++ b/tests/fixtures.py
@@ -19,7 +19,7 @@ class RequestFactory(BaseRequestFactory):
 
     def request(self, user=None, **request):
         request = super(RequestFactory, self).request(**request)
-        request.user = AnonymousUser()
+        request.user = user or AnonymousUser()
         request.session = SessionStore()
         request._messages = FallbackStorage(request)
 
diff --git a/tests/integration/basket/test_views.py b/tests/integration/basket/test_views.py
--- a/tests/integration/basket/test_views.py
+++ b/tests/integration/basket/test_views.py
@@ -1,9 +1,10 @@
 from django.contrib.messages import get_messages
+from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.utils import six
 
 from oscar.apps.basket import views
-from oscar.test.factories import VoucherFactory
+from oscar.test import factories
 from tests.fixtures import RequestFactory
 
 
@@ -20,7 +21,7 @@ def _get_voucher_message(self, request):
         return '\n'.join(six.text_type(m.message) for m in get_messages(request))
 
     def test_post_valid(self):
-        voucher = VoucherFactory()
+        voucher = factories.VoucherFactory()
         self.assertTrue(voucher.is_active())
 
         data = {
@@ -39,7 +40,7 @@ def test_post_valid(self):
 
 class TestVoucherRemoveView(TestCase):
     def test_post_valid(self):
-        voucher = VoucherFactory(num_basket_additions=5)
+        voucher = factories.VoucherFactory(num_basket_additions=5)
 
         data = {
             'code': voucher.code
@@ -68,3 +69,23 @@ def test_post_with_missing_voucher(self):
         actual = list(get_messages(request))[-1].message
         expected = "No voucher found with id '{}'".format(pk)
         self.assertEqual(actual, expected)
+
+
+class TestBasketSummaryView(TestCase):
+    def setUp(self):
+        self.url = reverse('basket:summary')
+        self.country = factories.CountryFactory()
+        self.user = factories.UserFactory()
+
+    def test_default_shipping_address(self):
+        user_address = factories.UserAddressFactory(
+            country=self.country, user=self.user, is_default_for_shipping=True
+        )
+        request = RequestFactory().get(self.url, user=self.user)
+        view = views.BasketView(request=request)
+        self.assertEquals(view.get_default_shipping_address(), user_address)
+
+    def test_default_shipping_address_for_anonymous_user(self):
+        request = RequestFactory().get(self.url)
+        view = views.BasketView(request=request)
+        self.assertIsNone(view.get_default_shipping_address())