Commit 4f5589e3 by Awais Qureshi

Merge pull request #11759 from edx/awais786/ECOM-2931-update-credit-eligible-email

Add the providers information in the email.
parents 7c5a9da7 a154e7f1
......@@ -4,6 +4,7 @@ import datetime
import json
from django.conf import settings
from django.contrib.auth.models import User
from django.test import TestCase
from django.test.utils import override_settings
from freezegun import freeze_time
......@@ -99,3 +100,13 @@ class EdxRestApiClientTest(TestCase):
)
actual_object = ecommerce_api_client(self.user).baskets(1).order.get()
self.assertEqual(actual_object, {u"result": u"Préparatoire"})
def test_client_with_user_without_profile(self):
"""
Verify client initialize successfully for users having no profile.
"""
worker = User.objects.create_user(username='test_worker', email='test@example.com')
api_client = ecommerce_api_client(worker)
self.assertEqual(api_client._store['session'].auth.__dict__['username'], worker.username) # pylint: disable=protected-access
self.assertIsNone(api_client._store['session'].auth.__dict__['full_name']) # pylint: disable=protected-access
......@@ -34,13 +34,25 @@
</p>
<p>
${_(u"Congratulations! You are eligible to receive course credit for successfully completing your {platform_name} course! {link_start}Get your credit now.{link_end}").format(
link_start=u'<a href="{dashboard_url}">'.format(
dashboard_url=dashboard_link
),
link_end=u'</a>',
platform_name=settings.PLATFORM_NAME
)}
% if providers:
${_(u"Congratulations! You are eligible to receive course credit from {providers} for successfully completing your {platform_name} course! {link_start}Get your credit now.{link_end}").format(
link_start=u'<a href="{dashboard_url}">'.format(
dashboard_url=dashboard_link
),
link_end=u'</a>',
platform_name=settings.PLATFORM_NAME,
providers=providers
)}
% else:
${_(u"Congratulations! You are eligible to receive course credit for successfully completing your {platform_name} course! {link_start}Get your credit now.{link_end}").format(
link_start=u'<a href="{dashboard_url}">'.format(
dashboard_url=dashboard_link
),
link_end=u'</a>',
platform_name=settings.PLATFORM_NAME
)}
% endif
</p>
<p>
......
......@@ -5,7 +5,11 @@ ${_(u"Hi {name},").format(name=full_name)}
${_(u"Hi,")}
% endif
${_(u"Congratulations! You are eligible to receive course credit for successfully completing your edX course!")}
% if providers:
${_(u"Congratulations! You are eligible to receive course credit from {providers} for successfully completing your edX course!").format(providers=providers)}
% else:
${_(u"Congratulations! You are eligible to receive course credit for successfully completing your edX course!")}
% endif
${_(u"Click on the link below to get your credit now:")}
......
......@@ -28,11 +28,13 @@ def is_commerce_service_configured():
def ecommerce_api_client(user):
""" Returns an E-Commerce API client setup with authentication for the specified user. """
return EdxRestApiClient(settings.ECOMMERCE_API_URL,
settings.ECOMMERCE_API_SIGNING_KEY,
user.username,
user.profile.name,
user.email,
tracking_context=create_tracking_context(user),
issuer=settings.JWT_ISSUER,
expires_in=settings.JWT_EXPIRATION)
return EdxRestApiClient(
settings.ECOMMERCE_API_URL,
settings.ECOMMERCE_API_SIGNING_KEY,
user.username,
user.profile.name if hasattr(user, 'profile') else None,
user.email,
tracking_context=create_tracking_context(user),
issuer=settings.JWT_ISSUER,
expires_in=settings.JWT_EXPIRATION
)
......@@ -3,7 +3,7 @@ Django admin page for credit eligibility
"""
from ratelimitbackend import admin
from openedx.core.djangoapps.credit.models import (
CreditCourse, CreditProvider, CreditEligibility, CreditRequest
CreditConfig, CreditCourse, CreditProvider, CreditEligibility, CreditRequest
)
......@@ -51,3 +51,4 @@ admin.site.register(CreditCourse, CreditCourseAdmin)
admin.site.register(CreditProvider, CreditProviderAdmin)
admin.site.register(CreditEligibility, CreditEligibilityAdmin)
admin.site.register(CreditRequest, CreditRequestAdmin)
admin.site.register(CreditConfig)
......@@ -21,10 +21,11 @@ from django.utils.translation import ugettext as _
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from eventtracking import tracker
from edxmako.shortcuts import render_to_string
from edxmako.template import Template
from microsite_configuration import microsite
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
from openedx.core.djangoapps.credit.models import CreditConfig, CreditProvider
from xmodule.modulestore.django import modulestore
......@@ -67,6 +68,26 @@ def send_credit_notifications(username, course_key):
# strip enclosing angle brackets from 'logo_image' cache 'Content-ID'
logo_image_id = logo_image.get('Content-ID', '')[1:-1]
providers = get_credit_provider_display_names(course_key)
providers_string = None
if providers:
if len(providers) > 1:
if len(providers) > 2:
# Translators: The join of three or more university names. The first of these formatting strings
# represents a comma-separated list of names (e.g., MIT, Harvard, Dartmouth).
providers_string = _("{first_providers}, and {last_provider}").format(
first_providers=u", ".join(providers[:-1]),
last_provider=providers[-1]
)
else:
# Translators: The join of two university names (e.g., Harvard and MIT).
providers_string = _("{first_provider} and {second_provider}").format(
first_provider=providers[0],
second_provider=providers[1]
)
else:
providers_string = providers[0]
context = {
'full_name': user.get_full_name(),
'platform_name': settings.PLATFORM_NAME,
......@@ -75,6 +96,7 @@ def send_credit_notifications(username, course_key):
'dashboard_link': dashboard_link,
'credit_course_link': credit_course_link,
'tracking_pixel': tracking_pixel,
'providers': providers_string,
}
# create the root email message
......@@ -85,6 +107,10 @@ def send_credit_notifications(username, course_key):
notification_msg.attach(msg_alternative)
# render the credit notification templates
subject = _(u'Course Credit Eligibility')
if providers:
subject = _(u'You are eligible for credit from {providers_string}').format(
providers_string=providers_string
)
# add alternative plain text message
email_body_plain = render_to_string('credit_notifications/credit_eligibility_email.txt', context)
......@@ -180,3 +206,56 @@ def _email_url_parser(url_name, extra_param=None):
dashboard_url_path = reverse(url_name) + extra_param if extra_param else reverse(url_name)
dashboard_link_parts = ("https", site_name, dashboard_url_path, '', '', '')
return urlparse.urlunparse(dashboard_link_parts)
def get_credit_provider_display_names(course_key):
"""Get the course information from ecommerce and parse the data to get providers.
Arguments:
course_key (CourseKey): The identifier for the course.
Returns:
List of credit provider display names.
"""
course_id = unicode(course_key)
credit_config = CreditConfig.current()
cache_key = None
provider_names = None
if credit_config.is_cache_enabled:
cache_key = '{key_prefix}.{course_key}'.format(
key_prefix=credit_config.CACHE_KEY, course_key=course_id
)
provider_names = cache.get(cache_key)
if provider_names is not None:
return provider_names
try:
user = User.objects.get(username=settings.ECOMMERCE_SERVICE_WORKER_USERNAME)
response = ecommerce_api_client(user).courses(course_id).get(include_products=1)
except Exception: # pylint: disable=broad-except
log.exception("Failed to receive data from the ecommerce course API for Course ID '%s'.", course_id)
return provider_names
if not response:
log.info("No Course information found from ecommerce API for Course ID '%s'.", course_id)
return provider_names
provider_ids = []
for product in response.get('products'):
provider_ids += [
attr.get('value') for attr in product.get('attribute_values') if attr.get('name') == 'credit_provider'
]
provider_names = []
credit_providers = CreditProvider.get_credit_providers()
for provider in credit_providers:
if provider['id'] in provider_ids:
provider_names.append(provider['display_name'])
if credit_config.is_cache_enabled:
cache.set(cache_key, provider_names, credit_config.cache_ttl)
return provider_names
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('credit', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='CreditConfig',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')),
('enabled', models.BooleanField(default=False, verbose_name='Enabled')),
('cache_ttl', models.PositiveIntegerField(default=0, help_text='Specified in seconds. Enable caching by setting this to a value greater than 0.', verbose_name='Cache Time To Live')),
('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')),
],
options={
'ordering': ('-change_date',),
'abstract': False,
},
),
]
......@@ -6,23 +6,22 @@ Credit courses allow students to receive university credit for
successful completion of a course on EdX
"""
import datetime
from collections import defaultdict
import datetime
import logging
import pytz
from config_models.models import ConfigurationModel
from django.conf import settings
from django.core.cache import cache
from django.dispatch import receiver
from django.db import models, transaction, IntegrityError
from django.core.validators import RegexValidator
from simple_history.models import HistoricalRecords
from django.db import models, transaction, IntegrityError
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy, ugettext as _
from jsonfield.fields import JSONField
from model_utils.models import TimeStampedModel
import pytz
from simple_history.models import HistoricalRecords
from xmodule_django.models import CourseKeyField
from django.utils.translation import ugettext_lazy
CREDIT_PROVIDER_ID_REGEX = r"[a-z,A-Z,0-9,\-]+"
......@@ -709,3 +708,25 @@ class CreditRequest(TimeStampedModel):
provider=self.provider.provider_id,
status=self.status,
)
class CreditConfig(ConfigurationModel):
""" Manage credit configuration """
CACHE_KEY = 'credit.providers.api.data'
cache_ttl = models.PositiveIntegerField(
verbose_name=_("Cache Time To Live"),
default=0,
help_text=_(
"Specified in seconds. Enable caching by setting this to a value greater than 0."
)
)
@property
def is_cache_enabled(self):
"""Whether responses from the commerce API will be cached."""
return self.enabled and self.cache_ttl > 0
def __unicode__(self):
"""Unicode representation of the config. """
return 'Credit Configuration'
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