|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+from decimal import Decimal
|
|
|
2
|
+
|
|
1
|
3
|
from django.conf import settings
|
|
2
|
4
|
from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponseBadRequest
|
|
3
|
5
|
from django.template import RequestContext
|
|
|
@@ -19,7 +21,7 @@ checkout_signals = import_module('checkout.signals', ['order_placed'])
|
|
19
|
21
|
order_models = import_module('order.models', ['Order', 'ShippingAddress'])
|
|
20
|
22
|
order_utils = import_module('order.utils', ['OrderCreator'])
|
|
21
|
23
|
address_models = import_module('address.models', ['UserAddress'])
|
|
22
|
|
-shipping_models = import_module('shipping.models', ['Method'])
|
|
|
24
|
+shipping_repository = import_module('shipping.repository', ['Repository'])
|
|
23
|
25
|
|
|
24
|
26
|
def prev_steps_must_be_complete(view_fn):
|
|
25
|
27
|
u"""
|
|
|
@@ -78,6 +80,11 @@ class CheckoutView(object):
|
|
78
|
80
|
# Set up the instance variables that are needed to place an order
|
|
79
|
81
|
self.request = request
|
|
80
|
82
|
self.co_data = checkout_utils.CheckoutSessionData(request)
|
|
|
83
|
+ self.basket = basket_factory.BasketFactory().get_open_basket(self.request)
|
|
|
84
|
+ self.context = {'basket': self.basket,
|
|
|
85
|
+ 'order_total': self.get_order_total(),
|
|
|
86
|
+ 'shipping_addr': self.get_shipping_address()}
|
|
|
87
|
+ self.set_shipping_context()
|
|
81
|
88
|
|
|
82
|
89
|
if request.method == 'POST':
|
|
83
|
90
|
response = self.handle_POST()
|
|
|
@@ -87,6 +94,14 @@ class CheckoutView(object):
|
|
87
|
94
|
response = HttpResponseBadRequest()
|
|
88
|
95
|
return response
|
|
89
|
96
|
|
|
|
97
|
+ def set_shipping_context(self):
|
|
|
98
|
+ method = self.co_data.shipping_method()
|
|
|
99
|
+ if method:
|
|
|
100
|
+ method.set_basket(self.basket)
|
|
|
101
|
+ self.context['method'] = method
|
|
|
102
|
+ self.context['shipping_total_excl_tax'] = method.basket_charge_excl_tax()
|
|
|
103
|
+ self.context['shipping_total_incl_tax'] = method.basket_charge_incl_tax()
|
|
|
104
|
+
|
|
90
|
105
|
def handle_GET(self):
|
|
91
|
106
|
u"""
|
|
92
|
107
|
Default behaviour is to set step as complete and redirect
|
|
|
@@ -94,6 +109,20 @@ class CheckoutView(object):
|
|
94
|
109
|
"""
|
|
95
|
110
|
return self.get_success_response()
|
|
96
|
111
|
|
|
|
112
|
+ def get_order_total(self):
|
|
|
113
|
+ calc = checkout_calculators.OrderTotalCalculator(self.request)
|
|
|
114
|
+ return calc.order_total_incl_tax(self.basket)
|
|
|
115
|
+
|
|
|
116
|
+ def get_shipping_address(self):
|
|
|
117
|
+ # Load address data into a blank address model
|
|
|
118
|
+ addr_data = self.co_data.new_address_fields()
|
|
|
119
|
+ if addr_data:
|
|
|
120
|
+ return order_models.ShippingAddress(**addr_data)
|
|
|
121
|
+ addr_id = self.co_data.user_address_id()
|
|
|
122
|
+ if addr_id:
|
|
|
123
|
+ return address_models.UserAddress.objects.get(pk=addr_id)
|
|
|
124
|
+ return None
|
|
|
125
|
+
|
|
97
|
126
|
def get_success_response(self):
|
|
98
|
127
|
u"""
|
|
99
|
128
|
Returns the appropriate redirect response if a checkout
|
|
|
@@ -146,19 +175,13 @@ class ShippingAddressView(CheckoutView):
|
|
146
|
175
|
form = checkout_forms.ShippingAddressForm(addr_fields)
|
|
147
|
176
|
else:
|
|
148
|
177
|
form = checkout_forms.ShippingAddressForm()
|
|
|
178
|
+ self.context['form'] = form
|
|
149
|
179
|
|
|
150
|
|
- # Add in extra template bindings
|
|
151
|
|
- basket = basket_factory.BasketFactory().get_open_basket(self.request)
|
|
152
|
|
- calc = checkout_calculators.OrderTotalCalculator(self.request)
|
|
153
|
|
- order_total = calc.order_total_incl_tax(basket)
|
|
154
|
|
- shipping_total_excl_tax = 0
|
|
155
|
|
- shipping_total_incl_tax = 0
|
|
156
|
|
-
|
|
157
|
180
|
# Look up address book data
|
|
158
|
181
|
if self.request.user.is_authenticated():
|
|
159
|
|
- addresses = address_models.UserAddress.objects.filter(user=self.request.user)
|
|
|
182
|
+ self.context['addresses'] = address_models.UserAddress.objects.filter(user=self.request.user)
|
|
160
|
183
|
|
|
161
|
|
- return render(self.request, self.template_file, locals())
|
|
|
184
|
+ return render(self.request, self.template_file, self.context)
|
|
162
|
185
|
|
|
163
|
186
|
|
|
164
|
187
|
class ShippingMethodView(CheckoutView):
|
|
|
@@ -169,37 +192,22 @@ class ShippingMethodView(CheckoutView):
|
|
169
|
192
|
template_file = 'checkout/shipping_methods.html';
|
|
170
|
193
|
|
|
171
|
194
|
def handle_GET(self):
|
|
172
|
|
- basket = basket_factory.BasketFactory().get_open_basket(self.request)
|
|
173
|
|
- methods = self.get_shipping_methods_for_basket(basket)
|
|
174
|
|
-
|
|
175
|
|
- if not methods.count():
|
|
176
|
|
- # No defined methods - assume delivery is free
|
|
177
|
|
- self.co_data.use_free_shipping()
|
|
178
|
|
- return self.get_success_response()
|
|
179
|
|
-
|
|
180
|
|
- if methods.count() == 1:
|
|
181
|
|
- # Only one method - set this
|
|
|
195
|
+ methods = self.get_available_shipping_methods()
|
|
|
196
|
+ if len(methods) == 1:
|
|
|
197
|
+ # Only one method - set this and redirect onto the next step
|
|
182
|
198
|
self.co_data.use_shipping_method(methods[0].code)
|
|
183
|
199
|
return self.get_success_response()
|
|
184
|
200
|
|
|
185
|
|
- for method in methods:
|
|
186
|
|
- method.set_basket(basket)
|
|
187
|
|
-
|
|
188
|
|
- # Load address data into a blank address model
|
|
189
|
|
- addr_data = self.co_data.new_address_fields()
|
|
190
|
|
- if addr_data:
|
|
191
|
|
- shipping_addr = order_models.ShippingAddress(**addr_data)
|
|
192
|
|
- addr_id = self.co_data.user_address_id()
|
|
193
|
|
- if addr_id:
|
|
194
|
|
- shipping_addr = address_models.UserAddress.objects.get(pk=addr_id)
|
|
195
|
|
-
|
|
196
|
|
- calc = checkout_calculators.OrderTotalCalculator(self.request)
|
|
197
|
|
- order_total = calc.order_total_incl_tax(basket)
|
|
198
|
|
-
|
|
199
|
|
- return render(self.request, self.template_file, locals())
|
|
|
201
|
+ self.context['methods'] = methods
|
|
|
202
|
+ return render(self.request, self.template_file, self.context)
|
|
200
|
203
|
|
|
201
|
|
- def get_shipping_methods_for_basket(self, basket):
|
|
202
|
|
- return shipping_models.Method.objects.all()
|
|
|
204
|
+ def get_available_shipping_methods(self):
|
|
|
205
|
+ u"""
|
|
|
206
|
+ Returns all applicable shipping method objects
|
|
|
207
|
+ for a given basket.
|
|
|
208
|
+ """
|
|
|
209
|
+ repo = shipping_repository.Repository()
|
|
|
210
|
+ return repo.get_shipping_methods(self.request.user, self.basket, self.get_shipping_address())
|
|
203
|
211
|
|
|
204
|
212
|
def handle_POST(self):
|
|
205
|
213
|
method_code = self.request.POST['method_code']
|
|
|
@@ -224,29 +232,9 @@ class OrderPreviewView(CheckoutView):
|
|
224
|
232
|
template_file = 'checkout/preview.html'
|
|
225
|
233
|
|
|
226
|
234
|
def handle_GET(self):
|
|
227
|
|
- basket = basket_factory.BasketFactory().get_open_basket(self.request)
|
|
228
|
|
-
|
|
229
|
|
- # Load address data into a blank address model
|
|
230
|
|
- addr_data = self.co_data.new_address_fields()
|
|
231
|
|
- if addr_data:
|
|
232
|
|
- shipping_addr = order_models.ShippingAddress(**addr_data)
|
|
233
|
|
- addr_id = self.co_data.user_address_id()
|
|
234
|
|
- if addr_id:
|
|
235
|
|
- shipping_addr = address_models.UserAddress.objects.get(pk=addr_id)
|
|
236
|
|
-
|
|
237
|
|
- # Shipping method
|
|
238
|
|
- method = self.co_data.shipping_method()
|
|
239
|
|
- method.set_basket(basket)
|
|
240
|
|
-
|
|
241
|
|
- shipping_total_excl_tax = method.basket_charge_excl_tax()
|
|
242
|
|
- shipping_total_incl_tax = method.basket_charge_incl_tax()
|
|
243
|
|
-
|
|
244
|
|
- # Calculate order total
|
|
245
|
|
- calc = checkout_calculators.OrderTotalCalculator(self.request)
|
|
246
|
|
- order_total = calc.order_total_incl_tax(basket, method)
|
|
247
|
235
|
|
|
248
|
236
|
mark_step_as_complete(self.request)
|
|
249
|
|
- return render(self.request, self.template_file, locals())
|
|
|
237
|
+ return render(self.request, self.template_file, self.context)
|
|
250
|
238
|
|
|
251
|
239
|
|
|
252
|
240
|
class PaymentDetailsView(CheckoutView):
|
|
|
@@ -277,9 +265,8 @@ class SubmitView(CheckoutView):
|
|
277
|
265
|
|
|
278
|
266
|
def handle_POST(self):
|
|
279
|
267
|
|
|
280
|
|
- basket = basket_factory.BasketFactory().get_open_basket(self.request)
|
|
281
|
|
- self._handle_payment(basket)
|
|
282
|
|
- order = self._place_order(basket)
|
|
|
268
|
+ self._handle_payment(self.basket)
|
|
|
269
|
+ order = self._place_order(self.basket)
|
|
283
|
270
|
self._reset_checkout()
|
|
284
|
271
|
|
|
285
|
272
|
# Send signal
|