diff --git a/lms/djangoapps/shoppingcart/models.py b/lms/djangoapps/shoppingcart/models.py index ce80f47121..a80388f971 100644 --- a/lms/djangoapps/shoppingcart/models.py +++ b/lms/djangoapps/shoppingcart/models.py @@ -1,5 +1,6 @@ import pytz import logging +import smtplib from datetime import datetime from django.db import models from django.conf import settings @@ -9,7 +10,9 @@ from django.utils.translation import ugettext as _ from django.db import transaction from model_utils.managers import InheritanceManager from courseware.courses import get_course_about_section +from django.core.mail import send_mail +from mitxmako.shortcuts import render_to_string from xmodule.modulestore.django import modulestore from xmodule.course_module import CourseDescriptor @@ -121,6 +124,17 @@ class Order(models.Model): orderitems = OrderItem.objects.filter(order=self).select_subclasses() for item in orderitems: item.purchase_item() + # send confirmation e-mail + subject = _("Order Payment Confirmation") + message = render_to_string('emails/order_confirmation_email.txt', { + 'order': self, + 'order_items': orderitems + }) + try: + send_mail(subject, message, + settings.DEFAULT_FROM_EMAIL, [self.user.email]) + except smtplib.SMTPException: + log.error('Failed sending confirmation e-mail for order %d', self.id) class OrderItem(models.Model): @@ -307,8 +321,8 @@ class CertificateItem(OrderItem): item.status = order.status item.qty = 1 item.unit_cost = cost - item.line_desc = "{mode} certificate for course {course_id}".format(mode=item.mode, - course_id=course_id) + item.line_desc = _("{mode} certificate for course {course_id}").format(mode=item.mode, + course_id=course_id) item.currency = currency order.currency = currency order.save() diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py index 65483d7404..42df02267d 100644 --- a/lms/djangoapps/shoppingcart/tests/test_models.py +++ b/lms/djangoapps/shoppingcart/tests/test_models.py @@ -6,6 +6,7 @@ from factory import DjangoModelFactory from mock import patch from django.test import TestCase from django.test.utils import override_settings +from django.core import mail from django.conf import settings from django.db import DatabaseError from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase @@ -77,6 +78,12 @@ class OrderTest(TestCase): cart.purchase() self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course_id)) + # test e-mail sending + self.assertEquals(len(mail.outbox), 1) + self.assertEquals('Order Payment Confirmation', mail.outbox[0].subject) + self.assertIn(settings.PAYMENT_SUPPORT_EMAIL, mail.outbox[0].body) + self.assertIn(unicode(cart.total_cost), mail.outbox[0].body) + def test_purchase_item_failure(self): # once again, we're testing against the specific implementation of # CertificateItem @@ -87,6 +94,8 @@ class OrderTest(TestCase): cart.purchase() # verify that we rolled back the entire transaction self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_id)) + # verify that e-mail wasn't sent + self.assertEquals(len(mail.outbox), 0) def purchase_with_data(self, cart): """ purchase a cart with billing information """ diff --git a/lms/templates/emails/order_confirmation_email.txt b/lms/templates/emails/order_confirmation_email.txt new file mode 100644 index 0000000000..4bbc70491b --- /dev/null +++ b/lms/templates/emails/order_confirmation_email.txt @@ -0,0 +1,15 @@ +<%! from django.utils.translation import ugettext as _ %> + +${_("Thank you for your order! Payment was successful, and you should be able to see the results on your dashboard.")} + +${_("Your order number is: {order_number}").format(order_number=order.id)} + +${_("Items in your order:")} + +${_("Quantity - Description - Price")} +%for order_item in order_items: + ${order_item.qty} - ${order_item.line_desc} - $(order_item.line_cost} +%endfor +${_("Total: {total_cost}").format(total_cost=order.total_cost)} + +${_("If you have any issues, please contact us at {billing_email}").format(billing_email=settings.PAYMENT_SUPPORT_EMAIL)}