Commit f3c26c89 by Diana Huang

Add tracking for refunds.

parent 7699b5ff
......@@ -438,15 +438,23 @@ class Order(models.Model):
csv_file, courses_info = self.generate_registration_codes_csv(orderitems, site_name)
self.send_confirmation_emails(orderitems, self.order_type == OrderTypes.BUSINESS, csv_file, site_name, courses_info)
self._emit_purchase_event(orderitems)
self._emit_order_event('Completed Order', orderitems)
def _emit_purchase_event(self, orderitems):
def refund(self):
"""
Emit an analytics purchase event for this Order. Will iterate over all associated
Refund the given order. As of right now, this just marks the order as refunded.
"""
self.status = 'refunded'
self.save()
orderitems = OrderItem.objects.filter(order=self).select_subclasses()
self._emit_order_event('Refunded Order', orderitems)
def _emit_order_event(self, event_name, orderitems):
"""
Emit an analytics event with the given name for this Order. Will iterate over all associated
OrderItems and add them as products in the event as well.
"""
event_name = 'Completed Order' # Required event name by Segment
try:
if settings.FEATURES.get('SEGMENT_IO_LMS') and settings.SEGMENT_IO_LMS_KEY:
tracking_context = tracker.get_tracker().resolve_context()
......@@ -1243,8 +1251,8 @@ class CertificateItem(OrderItem):
target_cert.status = 'refunded'
target_cert.refund_requested_time = datetime.now(pytz.utc)
target_cert.save()
target_cert.order.status = 'refunded'
target_cert.order.save()
target_cert.order.refund()
order_number = target_cert.order_id
# send billing an email so they can handle refunding
......
......@@ -576,6 +576,35 @@ class CertificateItemTest(ModuleStoreTestCase):
self.mock_tracker = patcher.start()
self.addCleanup(patcher.stop)
analytics_patcher = patch('shoppingcart.models.analytics')
self.mock_analytics_tracker = analytics_patcher.start()
self.addCleanup(analytics_patcher.stop)
def _assert_refund_tracked(self):
"""
Assert that we fired a refund event.
"""
self.mock_analytics_tracker.track.assert_called_with( # pylint: disable=maybe-no-member
self.user.id,
'Refunded Order',
{
'orderId': 1,
'currency': 'usd',
'total': '40',
'products': [
{
'sku': u'CertificateItem.verified',
'name': unicode(self.course_key),
'category': unicode(self.course_key.org),
'price': '40',
'id': 1,
'quantity': 1
}
]
},
context={'Google Analytics': {'clientId': None}}
)
def test_existing_enrollment(self):
CourseEnrollment.enroll(self.user, self.course_key)
cart = Order.get_cart_for_user(user=self.user)
......@@ -598,18 +627,29 @@ class CertificateItemTest(ModuleStoreTestCase):
self.assertEquals(cert_item.single_item_receipt_template,
'shoppingcart/receipt.html')
@override_settings(
SEGMENT_IO_LMS_KEY="foobar",
FEATURES={
'SEGMENT_IO_LMS': True,
'STORE_BILLING_INFO': True,
}
)
def test_refund_cert_callback_no_expiration(self):
# When there is no expiration date on a verified mode, the user can always get a refund
CourseEnrollment.enroll(self.user, self.course_key, 'verified')
cart = Order.get_cart_for_user(user=self.user)
CertificateItem.add_to_order(cart, self.course_key, self.cost, 'verified')
cart.purchase()
CourseEnrollment.unenroll(self.user, self.course_key)
# need to prevent analytics errors from appearing in stderr
with patch('sys.stderr', sys.stdout.write):
cart.purchase()
CourseEnrollment.unenroll(self.user, self.course_key)
target_certs = CertificateItem.objects.filter(course_id=self.course_key, user_id=self.user, status='refunded', mode='verified')
self.assertTrue(target_certs[0])
self.assertTrue(target_certs[0].refund_requested_time)
self.assertEquals(target_certs[0].order.status, 'refunded')
self._assert_refund_tracked()
def test_no_refund_on_cert_callback(self):
# If we explicitly skip refunds, the unenroll action should not modify the purchase.
......@@ -629,29 +669,40 @@ class CertificateItemTest(ModuleStoreTestCase):
self.assertFalse(target_certs[0].refund_requested_time)
self.assertEquals(target_certs[0].order.status, 'purchased')
@override_settings(
SEGMENT_IO_LMS_KEY="foobar",
FEATURES={
'SEGMENT_IO_LMS': True,
'STORE_BILLING_INFO': True,
}
)
def test_refund_cert_callback_before_expiration(self):
# If the expiration date has not yet passed on a verified mode, the user can be refunded
many_days = datetime.timedelta(days=60)
course = CourseFactory.create()
course_key = course.id
course_mode = CourseMode(course_id=course_key,
self.course_key = course.id
course_mode = CourseMode(course_id=self.course_key,
mode_slug="verified",
mode_display_name="verified cert",
min_price=self.cost,
expiration_datetime=(datetime.datetime.now(pytz.utc) + many_days))
course_mode.save()
CourseEnrollment.enroll(self.user, course_key, 'verified')
CourseEnrollment.enroll(self.user, self.course_key, 'verified')
cart = Order.get_cart_for_user(user=self.user)
CertificateItem.add_to_order(cart, course_key, self.cost, 'verified')
cart.purchase()
CertificateItem.add_to_order(cart, self.course_key, self.cost, 'verified')
CourseEnrollment.unenroll(self.user, course_key)
target_certs = CertificateItem.objects.filter(course_id=course_key, user_id=self.user, status='refunded', mode='verified')
# need to prevent analytics errors from appearing in stderr
with patch('sys.stderr', sys.stdout.write):
cart.purchase()
CourseEnrollment.unenroll(self.user, self.course_key)
target_certs = CertificateItem.objects.filter(course_id=self.course_key, user_id=self.user, status='refunded', mode='verified')
self.assertTrue(target_certs[0])
self.assertTrue(target_certs[0].refund_requested_time)
self.assertEquals(target_certs[0].order.status, 'refunded')
self._assert_refund_tracked()
def test_refund_cert_callback_before_expiration_email(self):
""" Test that refund emails are being sent correctly. """
......
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