|
|
@@ -39,15 +39,16 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
39
|
39
|
communication_type_code = 'ORDER_PLACED'
|
|
40
|
40
|
|
|
41
|
41
|
def handle_order_placement(self, order_number, basket, total_incl_tax,
|
|
42
|
|
- total_excl_tax, **kwargs):
|
|
|
42
|
+ total_excl_tax, user=None, **kwargs):
|
|
43
|
43
|
"""
|
|
44
|
44
|
Write out the order models and return the appropriate HTTP response
|
|
45
|
45
|
|
|
46
|
46
|
We deliberately pass the basket in here as the one tied to the request
|
|
47
|
|
- isn't necessarily the correct one to use in placing the order. This can
|
|
48
|
|
- happen when a basket gets frozen.
|
|
|
47
|
+ isn't necessarily the correct one to use in placing the order. This
|
|
|
48
|
+ can happen when a basket gets frozen.
|
|
49
|
49
|
"""
|
|
50
|
|
- order = self.place_order(order_number, basket, total_incl_tax, total_excl_tax, **kwargs)
|
|
|
50
|
+ order = self.place_order(order_number, basket, total_incl_tax,
|
|
|
51
|
+ total_excl_tax, user, **kwargs)
|
|
51
|
52
|
basket.set_as_submitted()
|
|
52
|
53
|
return self.handle_successful_order(order)
|
|
53
|
54
|
|
|
|
@@ -57,7 +58,8 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
57
|
58
|
self._payment_sources.append(source)
|
|
58
|
59
|
|
|
59
|
60
|
def add_payment_event(self, event_type_name, amount):
|
|
60
|
|
- event_type, __ = PaymentEventType.objects.get_or_create(name=event_type_name)
|
|
|
61
|
+ event_type, __ = PaymentEventType.objects.get_or_create(
|
|
|
62
|
+ name=event_type_name)
|
|
61
|
63
|
if self._payment_events is None:
|
|
62
|
64
|
self._payment_events = []
|
|
63
|
65
|
event = PaymentEvent(event_type=event_type, amount=amount)
|
|
|
@@ -65,7 +67,8 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
65
|
67
|
|
|
66
|
68
|
def handle_successful_order(self, order):
|
|
67
|
69
|
"""
|
|
68
|
|
- Handle the various steps required after an order has been successfully placed.
|
|
|
70
|
+ Handle the various steps required after an order has been successfully
|
|
|
71
|
+ placed.
|
|
69
|
72
|
|
|
70
|
73
|
Override this view if you want to perform custom actions when an
|
|
71
|
74
|
order is submitted.
|
|
|
@@ -84,7 +87,8 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
84
|
87
|
def get_success_url(self):
|
|
85
|
88
|
return reverse('checkout:thank-you')
|
|
86
|
89
|
|
|
87
|
|
- def place_order(self, order_number, basket, total_incl_tax, total_excl_tax, **kwargs):
|
|
|
90
|
+ def place_order(self, order_number, basket, total_incl_tax,
|
|
|
91
|
+ total_excl_tax, user=None, **kwargs):
|
|
88
|
92
|
"""
|
|
89
|
93
|
Writes the order out to the DB including the payment models
|
|
90
|
94
|
"""
|
|
|
@@ -97,15 +101,21 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
97
|
101
|
else:
|
|
98
|
102
|
status = kwargs.pop('status')
|
|
99
|
103
|
|
|
|
104
|
+ # We allow a user to be passed in to handle cases where the order is
|
|
|
105
|
+ # being placed on behalf of someone else.
|
|
|
106
|
+ if user is None:
|
|
|
107
|
+ user = self.request.user
|
|
|
108
|
+
|
|
100
|
109
|
# Set guest email address for anon checkout. Some libraries (eg
|
|
101
|
110
|
# PayPal) will pass this explicitly so we take care not to clobber.
|
|
102
|
|
- if not self.request.user.is_authenticated() and 'guest_email' not in kwargs:
|
|
|
111
|
+ if (not self.request.user.is_authenticated() and 'guest_email'
|
|
|
112
|
+ not in kwargs):
|
|
103
|
113
|
kwargs['guest_email'] = self.checkout_session.get_guest_email()
|
|
104
|
114
|
|
|
105
|
115
|
order = OrderCreator().place_order(basket=basket,
|
|
106
|
116
|
total_incl_tax=total_incl_tax,
|
|
107
|
117
|
total_excl_tax=total_excl_tax,
|
|
108
|
|
- user=self.request.user,
|
|
|
118
|
+ user=user,
|
|
109
|
119
|
shipping_method=shipping_method,
|
|
110
|
120
|
shipping_address=shipping_address,
|
|
111
|
121
|
billing_address=billing_address,
|
|
|
@@ -160,7 +170,8 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
160
|
170
|
# Check that this address isn't already in the db as we don't want
|
|
161
|
171
|
# to fill up the customer address book with duplicate addresses
|
|
162
|
172
|
try:
|
|
163
|
|
- UserAddress._default_manager.get(hash=user_addr.generate_hash())
|
|
|
173
|
+ UserAddress._default_manager.get(
|
|
|
174
|
+ hash=user_addr.generate_hash())
|
|
164
|
175
|
except ObjectDoesNotExist:
|
|
165
|
176
|
user_addr.save()
|
|
166
|
177
|
|
|
|
@@ -210,8 +221,8 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
210
|
221
|
"""
|
|
211
|
222
|
Saves any payment sources used in this order.
|
|
212
|
223
|
|
|
213
|
|
- When the payment sources are created, the order model does not exist and
|
|
214
|
|
- so they need to have it set before saving.
|
|
|
224
|
+ When the payment sources are created, the order model does not exist
|
|
|
225
|
+ and so they need to have it set before saving.
|
|
215
|
226
|
"""
|
|
216
|
227
|
if not self._payment_sources:
|
|
217
|
228
|
return
|
|
|
@@ -228,8 +239,9 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
228
|
239
|
|
|
229
|
240
|
def restore_frozen_basket(self):
|
|
230
|
241
|
"""
|
|
231
|
|
- Restores a frozen basket as the sole OPEN basket. Note that this also merges
|
|
232
|
|
- in any new products that have been added to a basket that has been created while payment.
|
|
|
242
|
+ Restores a frozen basket as the sole OPEN basket. Note that this also
|
|
|
243
|
+ merges in any new products that have been added to a basket that has
|
|
|
244
|
+ been created while payment.
|
|
233
|
245
|
"""
|
|
234
|
246
|
try:
|
|
235
|
247
|
fzn_basket = self.get_submitted_basket()
|
|
|
@@ -246,7 +258,7 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
246
|
258
|
def send_confirmation_message(self, order, **kwargs):
|
|
247
|
259
|
code = self.communication_type_code
|
|
248
|
260
|
ctx = {'order': order,
|
|
249
|
|
- 'lines': order.lines.all(),}
|
|
|
261
|
+ 'lines': order.lines.all()}
|
|
250
|
262
|
|
|
251
|
263
|
if not self.request.user.is_authenticated():
|
|
252
|
264
|
path = reverse('customer:anon-order',
|
|
|
@@ -258,18 +270,21 @@ class OrderPlacementMixin(CheckoutSessionMixin):
|
|
258
|
270
|
try:
|
|
259
|
271
|
event_type = CommunicationEventType.objects.get(code=code)
|
|
260
|
272
|
except CommunicationEventType.DoesNotExist:
|
|
261
|
|
- # No event-type in database, attempt to find templates for this type
|
|
262
|
|
- # and render them immediately to get the messages
|
|
|
273
|
+ # No event-type in database, attempt to find templates for this
|
|
|
274
|
+ # type and render them immediately to get the messages
|
|
263
|
275
|
messages = CommunicationEventType.objects.get_and_render(code, ctx)
|
|
264
|
276
|
event_type = None
|
|
265
|
277
|
else:
|
|
266
|
278
|
# Create order event
|
|
267
|
|
- CommunicationEvent._default_manager.create(order=order, event_type=event_type)
|
|
|
279
|
+ CommunicationEvent._default_manager.create(order=order,
|
|
|
280
|
+ event_type=event_type)
|
|
268
|
281
|
messages = event_type.get_messages(ctx)
|
|
269
|
282
|
|
|
270
|
283
|
if messages and messages['body']:
|
|
271
|
284
|
logger.info("Order #%s - sending %s messages", order.number, code)
|
|
272
|
285
|
dispatcher = Dispatcher(logger)
|
|
273
|
|
- dispatcher.dispatch_order_messages(order, messages, event_type, **kwargs)
|
|
|
286
|
+ dispatcher.dispatch_order_messages(order, messages,
|
|
|
287
|
+ event_type, **kwargs)
|
|
274
|
288
|
else:
|
|
275
|
|
- logger.warning("Order #%s - no %s communication event type", order.number, code)
|
|
|
289
|
+ logger.warning("Order #%s - no %s communication event type",
|
|
|
290
|
+ order.number, code)
|