ソースを参照

Added fix for issue with users being able to bypass shipping.

Taking inspiration from Asia's pull request.
master
David Winterbottom 13年前
コミット
ec03e45e85
4個のファイルの変更31行の追加32行の削除
  1. 10
    0
      oscar/apps/basket/abstract_models.py
  2. 10
    0
      oscar/apps/checkout/tests.py
  3. 5
    17
      oscar/apps/checkout/utils.py
  4. 6
    15
      oscar/apps/checkout/views.py

+ 10
- 0
oscar/apps/basket/abstract_models.py ファイルの表示

@@ -189,6 +189,16 @@ class AbstractBasket(models.Model):
189 189
         for line in self.all_lines():
190 190
             line.set_as_tax_exempt()
191 191
 
192
+    def is_shipping_required(self):
193
+        """
194
+        Test whether the basket contains physical products that require
195
+        shipping.
196
+        """
197
+        for line in self.all_lines():
198
+            if line.product.is_shipping_required:
199
+                return True
200
+        return False
201
+
192 202
     # =======
193 203
     # Helpers
194 204
     # =======

+ 10
- 0
oscar/apps/checkout/tests.py ファイルの表示

@@ -14,6 +14,11 @@ from oscar.apps.order.models import Order
14 14
 class CheckoutMixin(object):
15 15
     fixtures = ['countries.json']
16 16
 
17
+    def add_product_to_basket(self):
18
+        product = create_product(price=D('12.00'))
19
+        self.client.post(reverse('basket:add'), {'product_id': product.id,
20
+                                                 'quantity': 1})
21
+
17 22
     def complete_guest_email_form(self, email='test@example.com'):
18 23
         response = self.client.post(reverse('checkout:index'),
19 24
                                     {'username': email,
@@ -120,6 +125,7 @@ class ShippingMethodViewTests(ClientTestCase, CheckoutMixin):
120 125
     fixtures = ['countries.json']
121 126
 
122 127
     def test_shipping_method_view_redirects_if_no_shipping_address(self):
128
+        self.add_product_to_basket()
123 129
         response = self.client.get(reverse('checkout:shipping-method'))
124 130
         self.assertIsRedirect(response)
125 131
         self.assertRedirectUrlName(response, 'checkout:shipping-address')
@@ -133,6 +139,7 @@ class ShippingMethodViewTests(ClientTestCase, CheckoutMixin):
133 139
 class PaymentMethodViewTests(ClientTestCase, CheckoutMixin):
134 140
 
135 141
     def test_view_redirects_if_no_shipping_address(self):
142
+        self.add_product_to_basket() 
136 143
         response = self.client.get(reverse('checkout:payment-method'))
137 144
         self.assertIsRedirect(response)
138 145
         self.assertRedirectUrlName(response, 'checkout:shipping-address')
@@ -147,6 +154,7 @@ class PaymentMethodViewTests(ClientTestCase, CheckoutMixin):
147 154
 class PreviewViewTests(ClientTestCase, CheckoutMixin):
148 155
 
149 156
     def test_view_redirects_if_no_shipping_address(self):
157
+        self.add_product_to_basket()
150 158
         response = self.client.get(reverse('checkout:preview'))
151 159
         self.assertIsRedirect(response)
152 160
         self.assertRedirectUrlName(response, 'checkout:shipping-address')
@@ -167,11 +175,13 @@ class PreviewViewTests(ClientTestCase, CheckoutMixin):
167 175
 class PaymentDetailsViewTests(ClientTestCase, CheckoutMixin):
168 176
 
169 177
     def test_view_redirects_if_no_shipping_address(self):
178
+        self.add_product_to_basket()
170 179
         response = self.client.post(reverse('checkout:payment-details'))
171 180
         self.assertIsRedirect(response)
172 181
         self.assertRedirectUrlName(response, 'checkout:shipping-address')
173 182
 
174 183
     def test_view_redirects_if_no_shipping_method(self):
184
+        self.add_product_to_basket()
175 185
         self.complete_shipping_address()
176 186
         response = self.client.post(reverse('checkout:payment-details'))
177 187
         self.assertIsRedirect(response)

+ 5
- 17
oscar/apps/checkout/utils.py ファイルの表示

@@ -64,20 +64,6 @@ class CheckoutSessionData(object):
64 64
         self._unset('shipping', 'new_address_fields')
65 65
         self._unset('shipping', 'user_address_id')
66 66
 
67
-    def no_shipping_required(self):
68
-        """
69
-        Record fact that basket doesn't require a shipping address or method
70
-        """
71
-        self.reset_shipping_data()
72
-        self._set('shipping', 'is_required', False)
73
-
74
-    def shipping_required(self):
75
-        """
76
-        Record fact that basket does require a shipping address or method
77
-        """
78
-        self.reset_shipping_data()
79
-        self._set('shipping', 'is_required', True)
80
-
81 67
     def ship_to_user_address(self, address):
82 68
         """
83 69
         Set existing shipping address id to session and unset address fields from session
@@ -104,10 +90,12 @@ class CheckoutSessionData(object):
104 90
         """
105 91
         return self._get('shipping', 'user_address_id')
106 92
 
107
-    def is_shipping_required(self):
108
-        return self._get('shipping', 'is_required', True)
109
-
110 93
     def is_shipping_address_set(self):
94
+        """
95
+        Test whether a shipping address has been stored in the session.
96
+
97
+        This can be from a new address or re-using an existing address.
98
+        """
111 99
         new_fields = self.new_shipping_address_fields()
112 100
         has_new_address = new_fields is not None
113 101
         has_old_address = self.user_address_id() > 0

+ 6
- 15
oscar/apps/checkout/views.py ファイルの表示

@@ -183,24 +183,14 @@ class ShippingAddressView(CheckoutSessionMixin, FormView):
183 183
 
184 184
         # Check to see that a shipping address is actually required.  It may not be if
185 185
         # the basket is purely downloads
186
-        if not self.does_basket_require_shipping(request.basket):
186
+        if not request.basket.is_shipping_required():
187 187
             messages.info(request, _("Your basket does not require a shipping address to be submitted"))
188
-            self.checkout_session.no_shipping_required()
189 188
             return HttpResponseRedirect(self.get_success_url())
190 189
         else:
191 190
             self.checkout_session.shipping_required()
192 191
 
193 192
         return super(ShippingAddressView, self).get(request, *args, **kwargs)
194 193
 
195
-    def does_basket_require_shipping(self, basket):
196
-        """
197
-        Test whether the contents of the basket require shipping
198
-        """
199
-        for line in basket.all_lines():
200
-            if line.product.is_shipping_required:
201
-                return True
202
-        return False
203
-
204 194
     def get_initial(self):
205 195
         return self.checkout_session.new_shipping_address_fields()
206 196
 
@@ -322,7 +312,7 @@ class ShippingMethodView(CheckoutSessionMixin, TemplateView):
322 312
 
323 313
     def get(self, request, *args, **kwargs):
324 314
         # Check that shipping is required at all
325
-        if not self.checkout_session.is_shipping_required():
315
+        if not request.basket.is_shipping_required():
326 316
             self.checkout_session.use_shipping_method(NoShippingRequired().code)
327 317
             return self.get_success_response()
328 318
 
@@ -398,7 +388,7 @@ class PaymentMethodView(CheckoutSessionMixin, TemplateView):
398 388
 
399 389
     def get(self, request, *args, **kwargs):
400 390
         # Check that shipping address has been completed
401
-        if self.checkout_session.is_shipping_required() and not self.checkout_session.is_shipping_address_set():
391
+        if request.basket.is_shipping_required() and not self.checkout_session.is_shipping_address_set():
402 392
             messages.error(request, _("Please choose a shipping address"))
403 393
             return HttpResponseRedirect(reverse('checkout:shipping-address'))
404 394
         # Check that shipping method has been set
@@ -516,7 +506,7 @@ class OrderPlacementMixin(CheckoutSessionMixin):
516 506
         If the shipping address was selected from the user's address book,
517 507
         then we convert the UserAddress to a ShippingAddress.
518 508
         """
519
-        if not self.checkout_session.is_shipping_required():
509
+        if not self.request.basket.is_shipping_required():
520 510
             return None
521 511
 
522 512
         addr_data = self.checkout_session.new_shipping_address_fields()
@@ -674,7 +664,7 @@ class PaymentDetailsView(OrderPlacementMixin, TemplateView):
674 664
 
675 665
     def get_error_response(self):
676 666
         # Check that shipping address has been completed
677
-        if self.checkout_session.is_shipping_required() and not self.checkout_session.is_shipping_address_set():
667
+        if self.request.basket.is_shipping_required() and not self.checkout_session.is_shipping_address_set():
678 668
             messages.error(self.request, _("Please choose a shipping address"))
679 669
             return HttpResponseRedirect(reverse('checkout:shipping-address'))
680 670
         # Check that shipping method has been set
@@ -695,6 +685,7 @@ class PaymentDetailsView(OrderPlacementMixin, TemplateView):
695 685
         then the method can call submit()
696 686
         """
697 687
         error_response = self.get_error_response()
688
+        
698 689
         if error_response:
699 690
             return error_response
700 691
         if self.preview:

読み込み中…
キャンセル
保存