Commit fc1653aa by PaulWattenberger Committed by GitHub

Merge pull request #890 from edx/pwattenberger/sailthru-3

Add missing basket_addition call.  Handle call to post_checkout with no user=
parents 4a0f47d8 89865d33
......@@ -200,7 +200,7 @@ class CouponViewSet(EdxOrderPlacementMixin, viewsets.ModelViewSet):
# Create an order now since payment is handled out of band via an invoice.
response_data = self.create_order_for_invoice(
basket, coupon_id=coupon_product.id, client=client, invoice_data=invoice_data
basket, coupon_id=coupon_product.id, client=client, invoice_data=invoice_data, request=request
)
return Response(response_data, status=status.HTTP_200_OK)
......@@ -284,7 +284,7 @@ class CouponViewSet(EdxOrderPlacementMixin, viewsets.ModelViewSet):
for category in categories:
ProductCategory.objects.get_or_create(product=coupon, category=category)
def create_order_for_invoice(self, basket, coupon_id, client, invoice_data=None):
def create_order_for_invoice(self, basket, coupon_id, client, invoice_data=None, request=None):
"""Creates an order from the basket and invokes the invoice payment processor."""
order_metadata = data_api.get_order_metadata(basket)
......@@ -304,7 +304,8 @@ class CouponViewSet(EdxOrderPlacementMixin, viewsets.ModelViewSet):
shipping_method=order_metadata[AC.KEYS.SHIPPING_METHOD],
shipping_charge=order_metadata[AC.KEYS.SHIPPING_CHARGE],
billing_address=None,
order_total=order_metadata[AC.KEYS.ORDER_TOTAL]
order_total=order_metadata[AC.KEYS.ORDER_TOTAL],
request=request
)
# Invoice payment processor invocation.
......
......@@ -54,7 +54,7 @@ class OrderViewSet(viewsets.ReadOnlyModelViewSet):
logger.info('Attempting fulfillment of order [%s]...', order.number)
post_checkout = get_class('checkout.signals', 'post_checkout')
post_checkout.send(sender=post_checkout, order=order)
post_checkout.send(sender=post_checkout, order=order, request=request)
if order.is_fulfillable:
logger.warning('Fulfillment of order [%s] failed!', order.number)
......
......@@ -51,6 +51,10 @@ def prepare_basket(request, product, voucher=None):
else:
Referral.objects.filter(basket=basket).delete()
# Call signal handler to notify listeners that something has been added to the basket
basket_addition = get_class('basket.signals', 'basket_addition')
basket_addition.send(sender=basket_addition, product=product, user=request.user, request=request)
return basket
......
......@@ -70,6 +70,7 @@ class EdxOrderPlacementMixin(OrderPlacementMixin):
shipping_charge,
billing_address,
order_total,
request=None,
**kwargs):
"""
Place an order and mark the corresponding basket as submitted.
......@@ -93,9 +94,9 @@ class EdxOrderPlacementMixin(OrderPlacementMixin):
basket.submit()
return self.handle_successful_order(order)
return self.handle_successful_order(order, request)
def handle_successful_order(self, order):
def handle_successful_order(self, order, request=None): # pylint: disable=arguments-differ
"""Send a signal so that receivers can perform relevant tasks (e.g., fulfill the order)."""
audit_log(
'order_placed',
......@@ -114,11 +115,11 @@ class EdxOrderPlacementMixin(OrderPlacementMixin):
# See http://celery.readthedocs.org/en/latest/userguide/tasks.html#database-transactions.
fulfill_order.delay(order.number, site_code=order.site.siteconfiguration.partner.short_code)
else:
post_checkout.send(sender=self, order=order)
post_checkout.send(sender=self, order=order, request=request)
return order
def place_free_order(self, basket):
def place_free_order(self, basket, request=None):
"""Fulfill a free order.
Arguments:
......@@ -155,6 +156,7 @@ class EdxOrderPlacementMixin(OrderPlacementMixin):
shipping_charge=order_metadata[AC.KEYS.SHIPPING_CHARGE],
billing_address=None,
order_total=order_metadata[AC.KEYS.ORDER_TOTAL],
request=request
)
return order
......
......@@ -162,7 +162,8 @@ class CybersourceNotifyView(EdxOrderPlacementMixin, View):
shipping_method,
shipping_charge,
billing_address,
order_total
order_total,
request=request
)
return HttpResponse()
......@@ -255,7 +256,8 @@ class PaypalPaymentExecutionView(EdxOrderPlacementMixin, View):
shipping_method=shipping_method,
shipping_charge=shipping_charge,
billing_address=None,
order_total=order_total
order_total=order_total,
request=request
)
return redirect(receipt_url)
......
......@@ -17,7 +17,8 @@ basket_addition = get_class('basket.signals', 'basket_addition')
@receiver(post_checkout)
@silence_exceptions("Failed to call Sailthru upon order completion.")
def process_checkout_complete(sender, order=None, request=None, user=None, **kwargs): # pylint: disable=unused-argument
def process_checkout_complete(sender, order=None, user=None, request=None, # pylint: disable=unused-argument
response=None, **kwargs): # pylint: disable=unused-argument
"""Tell Sailthru when payment done.
Arguments:
......@@ -27,6 +28,10 @@ def process_checkout_complete(sender, order=None, request=None, user=None, **kwa
if not waffle.switch_is_active('sailthru_enable'):
return
message_id = None
if request:
message_id = request.COOKIES.get('sailthru_bid')
# loop through lines in order
# If multi product orders become common it may be worthwhile to pass an array of
# orders to the worker in one call to save overhead, however, that would be difficult
......@@ -45,15 +50,15 @@ def process_checkout_complete(sender, order=None, request=None, user=None, **kwa
course_url = _build_course_url(course_id)
# pass event to ecommerce_worker.sailthru.v1.tasks to handle asynchronously
update_course_enrollment.delay(user.email, course_url, False, mode_for_seat(product),
update_course_enrollment.delay(order.user.email, course_url, False, mode_for_seat(product),
unit_cost=price, course_id=course_id, currency=order.currency,
site_code=request.site.siteconfiguration.partner.short_code,
message_id=request.COOKIES.get('sailthru_bid'))
site_code=order.site.siteconfiguration.partner.short_code,
message_id=message_id)
@receiver(basket_addition)
@silence_exceptions("Failed to call Sailthru upon basket addition.")
def process_basket_addition(sender, product=None, request=None, user=None, **kwargs): # pylint: disable=unused-argument
def process_basket_addition(sender, product=None, user=None, request=None, **kwargs): # pylint: disable=unused-argument
"""Tell Sailthru when payment started.
Arguments:
......
......@@ -56,9 +56,7 @@ class SailthruTests(CourseCatalogTestMixin, TestCase):
"""
seat, order = self._create_order(99)
process_checkout_complete(None, request=self.request,
user=self.user,
order=order)
process_checkout_complete(None, order=order, request=self.request)
self.assertTrue(mock_update_course_enrollment.called)
mock_update_course_enrollment.assert_called_with(TEST_EMAIL,
self.course_url,
......@@ -71,6 +69,25 @@ class SailthruTests(CourseCatalogTestMixin, TestCase):
unit_cost=order.total_excl_tax)
@patch('ecommerce_worker.sailthru.v1.tasks.update_course_enrollment.delay')
def test_process_checkout_complete_no_request(self, mock_update_course_enrollment):
"""
Test that the process_checkout signal handler properly handles null request
"""
seat, order = self._create_order(99)
process_checkout_complete(None, order=order)
self.assertTrue(mock_update_course_enrollment.called)
mock_update_course_enrollment.assert_called_with(TEST_EMAIL,
self.course_url,
False,
seat.attr.certificate_type,
course_id=self.course_id,
currency=order.currency,
message_id=None,
site_code='edX',
unit_cost=order.total_excl_tax)
@patch('ecommerce_worker.sailthru.v1.tasks.update_course_enrollment.delay')
def test_process_basket_addition(self, mock_update_course_enrollment):
"""
Test that the process_basket_addition signal handler properly calls the task routine
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment