Commit 2849067f by Ahsan Ulhaq

Merge pull request #215 from edx/ahsan/ECOM-1885-order-notification

Order Notification
parents 5997cfb7 b9054796
...@@ -3,3 +3,4 @@ Renzo Lucioni <renzo@edx.org> ...@@ -3,3 +3,4 @@ Renzo Lucioni <renzo@edx.org>
Clinton Blackburn <cblackburn@edx.org> Clinton Blackburn <cblackburn@edx.org>
Jim Abramson <jsa@edx.org> Jim Abramson <jsa@edx.org>
Tyler Nickerson <tyler@edx.org> Tyler Nickerson <tyler@edx.org>
Ahsan Ulhaq <ahsan.ulhaq84@gmail.com>
...@@ -76,6 +76,9 @@ switches exist: ...@@ -76,6 +76,9 @@ switches exist:
| ENABLE_CREDIT_APP | Enable the credit checkout page from where student's can purchase credit | | ENABLE_CREDIT_APP | Enable the credit checkout page from where student's can purchase credit |
| | courses. | | | courses. |
+--------------------------------+---------------------------------------------------------------------------+ +--------------------------------+---------------------------------------------------------------------------+
| ENABLE_NOTIFICATIONS | Enable email notification for the different task generated e.g. course |
| | purchase. |
+--------------------------------+---------------------------------------------------------------------------+
.. _Waffle: https://waffle.readthedocs.org/ .. _Waffle: https://waffle.readthedocs.org/
...@@ -97,6 +100,25 @@ To enable custom credit checkout page, please add the following waffle switch: ...@@ -97,6 +100,25 @@ To enable custom credit checkout page, please add the following waffle switch:
``ENABLE_CREDIT_APP`` ``ENABLE_CREDIT_APP``
Notification
------------
To create and send email notifications for a task, we use `Communications API <http://django-oscar.readthedocs.org/en/latest/howto/how_to_customise_oscar_communications.html#communications-api>`_:
1. First you need to define an arbitrary ``Communication Type Code`` that would be use to refer a particular type
of notification. For example, ``Communication Type Code`` used for the course purchased would be ``COURSE_PURCHASED``.
2. Create three template files (HTML, plain text, subject) associated with the email in directory ``ecommerce/ecommerce/templates/customer/emails/``.
Note that the naming convention should be something like ``commtype_{Communication Type Code}_body.html``
For example for ``COURSE_PURCHASED`` code template file names will be ``commtype_course_purchased_body.html``,
``commtype_course_purchased_body.txt`` and ``commtype_course_purchased_subject.txt``. The HTML file should
extend ``email_base.html`` for basic styling. You can override ``block body`` (must) and ``block footer``(optionally)
to add your custom email body and custom footer respectively.
3. Use the method ``send_notification(user, commtype_code, context)``, implemented in ``ecommerce/ecommerce/notifications/notifications.py``.
For more information please read method docstring.
Testing Testing
------- -------
......
import analytics import analytics
import waffle
from django.dispatch import receiver from django.dispatch import receiver
from oscar.core.loading import get_class from oscar.core.loading import get_class
from ecommerce.extensions.analytics.utils import is_segment_configured, parse_tracking_context, log_exceptions from ecommerce.extensions.analytics.utils import is_segment_configured, parse_tracking_context, log_exceptions
from ecommerce.notifications.notifications import send_notification
post_checkout = get_class('checkout.signals', 'post_checkout') post_checkout = get_class('checkout.signals', 'post_checkout')
...@@ -45,3 +47,13 @@ def track_completed_order(sender, order=None, **kwargs): # pylint: disable=unus ...@@ -45,3 +47,13 @@ def track_completed_order(sender, order=None, **kwargs): # pylint: disable=unus
} }
}, },
) )
@receiver(post_checkout, dispatch_uid='send_completed_order_email')
@log_exceptions("Failed to send order completion email.")
def send_course_purchase_email(sender, order=None, **kwargs): # pylint: disable=unused-argument
"""Send course purchase notification email when a course is purchased."""
if waffle.switch_is_active('ENABLE_NOTIFICATIONS'):
# Here we assume that order type will always be a 'Seat' i.e. course
if len(order.lines.all()) == 1:
send_notification(order.user, 'COURSE_PURCHASED', {'course_title': order.lines.first().product.title})
import logging
from django.conf import settings
from oscar.core.loading import get_model, get_class
from premailer import transform
from ecommerce.extensions.analytics.utils import parse_tracking_context
log = logging.getLogger(__name__)
CommunicationEventType = get_model('customer', 'CommunicationEventType')
Dispatcher = get_class('customer.utils', 'Dispatcher')
def send_notification(user, commtype_code, context):
"""Send different notification mail to the user based on the triggering event.
Args:
user(obj): 'User' object to whom email is to send
commtype_code(str): Communication type code
context(dict): context to be used in the mail
"""
tracking_id, client_id = parse_tracking_context(user)
tracking_pixel = 'https://www.google-analytics.com/collect?v=1&t=event&ec=email&ea=open&tid={tracking_id}' \
'&cid={client_id}'.format(tracking_id=tracking_id, client_id=client_id)
full_name = user.get_full_name()
context.update({
'full_name': full_name,
'platform_name': settings.PLATFORM_NAME,
'tracking_pixel': tracking_pixel,
})
try:
event_type = CommunicationEventType.objects.get(code=commtype_code)
except CommunicationEventType.DoesNotExist:
try:
messages = CommunicationEventType.objects.get_and_render(commtype_code, context)
except Exception: # pylint: disable=broad-except
log.error('Unable to locate a DB entry or templates for communication type [%s]. '
'No notification has been sent.', commtype_code)
return
else:
messages = event_type.get_messages(context)
if messages and (messages['body'] or messages['html']):
messages['html'] = transform(messages['html'])
Dispatcher().dispatch_user_messages(user, messages)
{% extends 'customer/email_base.html' %}
{% load i18n %}
{% block body %}
<!-- Message Body -->
<tr>
<td class="container-padding" bgcolor="#ffffff" style="background-color: #ffffff; padding-left: 30px; padding-right: 30px; font-size: 13px; line-height: 20px; font-family: Open Sans, sans-serif; color: #333; border-radius: 5px;" align="left">
<br>
<!--/message HTML content -->
<p>{% blocktrans %}Hi {{full_name}},{% endblocktrans %}</p>
<br>
<p>{% blocktrans with course_title=course_title platform_name=platform_name %}Thank you for purchasing {{course_title}}. The charge below will appear on your next credit or debit card statement with a company name of {{platform_name}}.{% endblocktrans %}</p>
<br>
<p>{% blocktrans %}You can access your course and complete your verification (if required) on your {{platform_name}} dashboard. {% endblocktrans %} </p>
<p>{% blocktrans %}To explore other great courses, visit the {{platform_name}} website. More courses are added every day!{% endblocktrans %}</p>
<br>
<p>{% trans "Thank you. We hope you enjoy the course!" %}</p>
<p>{% blocktrans %}{{platform_name}} team {% endblocktrans %}</p>
<!--/message HTML content -->
<br><br>
</td>
</tr>
<tr>
<td class="footer-padding" style="padding-left: 30px; padding-right: 30px; font-size: 13px; line-height: 20px; font-family: Open Sans, sans-serif; color: #002D40; background-color: #f3f3f3;" align="left">
<!--footer content -->
<br>
<p>{% blocktrans with course_title=course_title platform_name=platform_name %}You are receiving this email because you purchased a seat in the {{platform_name}} course {{course_title}}.{% endblocktrans %}</p>
<br>
<!--/ end footer content -->
</td>
</tr>
<!--/100% wrapper-->
<br>
<br>
{% endblock body %}
{% load i18n %}
{% trans "Receipt Confirmation for: " %}{{notification_data.course_title}}
{% blocktrans %}Hi {{full_name}},{% endblocktrans %}
{% blocktrans with course_title=course_title platform_name=platform_name %}Thank you for purchasing {{course_title}}. The charge below will appear on your next credit or debit card statement with a company name of {{platform_name}}.{% endblocktrans %}
{% blocktrans %}You can access your course and complete your verification (if required) on your {{platform_name}} dashboard. {% endblocktrans %}
{% blocktrans %}To explore other great courses, visit the {{platform_name}} website. More courses are added every day!{% endblocktrans %}
{% trans "Thank you. We hope you enjoy the course!" %}
{% blocktrans %}{{platform_name}} team{% endblocktrans %}
{% trans "The edX team" %}
...@@ -13,6 +13,7 @@ edx-auth-backends==0.1.3 ...@@ -13,6 +13,7 @@ edx-auth-backends==0.1.3
jsonfield==1.0.3 jsonfield==1.0.3
libsass==0.8.2 libsass==0.8.2
paypalrestsdk==1.9.0 paypalrestsdk==1.9.0
premailer==2.9.2
pycountry==1.10 pycountry==1.10
python-dateutil==2.4.2 python-dateutil==2.4.2
pytz==2015.4 pytz==2015.4
......
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