Skip to content

Commit

Permalink
add signal to send course completion email to user
Browse files Browse the repository at this point in the history
  • Loading branch information
Muhammad Faraz Maqsood authored and Muhammad Faraz Maqsood committed Feb 28, 2024
1 parent 59b7c4d commit 8d7173c
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 7 deletions.
13 changes: 12 additions & 1 deletion openedx/features/sdaia_features/course_progress/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.contrib.sites.models import Site

from openedx.core.djangoapps.signals.signals import COURSE_GRADE_NOW_PASSED
from openedx.core.lib.celery.task_utils import emulate_http_request
from openedx.features.sdaia_features.course_progress.models import CourseCompletionEmailHistory
from openedx.features.sdaia_features.course_progress.tasks import send_user_course_progress_email
from openedx.features.sdaia_features.course_progress.tasks import send_user_course_progress_email, send_user_course_completion_email
from openedx.features.sdaia_features.course_progress.utils import get_user_course_progress
from xmodule.modulestore.django import modulestore

Expand All @@ -24,6 +25,7 @@ def send_course_progress_milestones_achievement_emails(**kwargs):
Receives the BlockCompletion signal and sends the email to
the user if he completes a specific course progress threshold.
"""
logger.info(f"\n\n\n inside send_course_progress_milestones_achievement_emails \n\n\n")
instance = kwargs['instance']
if not instance.context_key.is_course:
return # Content in a library or some other thing that doesn't support milestones
Expand Down Expand Up @@ -57,3 +59,12 @@ def send_course_progress_milestones_achievement_emails(**kwargs):
for course_completion_percentages_for_email in course_completion_percentages_for_emails:
if user_completion_percentage >= course_completion_percentages_for_email > progress_last_email_sent_at:
send_user_course_progress_email.delay(user_completion_percentage, progress_last_email_sent_at, course_completion_percentages_for_email, str(course_key), user_id)


@receiver(COURSE_GRADE_NOW_PASSED, dispatch_uid="course_completion")
def send_course_completion_email(sender, user, course_id, **kwargs): # pylint: disable=unused-argument
"""
Listen for a signal indicating that the user has passed a course run.
"""
logger.info(f"\n\n\n inside send_course_completion_email \n\n\n")
send_user_course_completion_email.delay(user.id, str(course_id))
70 changes: 64 additions & 6 deletions openedx/features/sdaia_features/course_progress/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
from django.contrib.sites.models import Site
from edx_ace import ace
from edx_ace.recipient import Recipient
from opaque_keys.edx.keys import CourseKey

from lms.djangoapps.grades.api import CourseGradeFactory
from openedx.core.djangoapps.ace_common.message import BaseMessageType
from openedx.core.djangoapps.ace_common.template_context import get_base_template_context
from openedx.core.djangoapps.content.block_structure.api import get_block_structure_manager
from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from openedx.core.lib.celery.task_utils import emulate_http_request
from openedx.features.sdaia_features.course_progress.models import CourseCompletionEmailHistory
from xmodule.modulestore.django import modulestore
Expand All @@ -25,14 +28,26 @@

class UserCourseProgressEmail(BaseMessageType):
"""
Message Type Class for User Activation
Message Type Class for User Course Progress Email
"""
APP_LABEL = 'course_progress'

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.options['transactional'] = True


class UserCourseCompletionEmail(BaseMessageType):
"""
Message Type Class for User Course Completion Email
"""
APP_LABEL = 'course_progress'

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.options['transactional'] = True


@shared_task
def send_user_course_progress_email(current_progress, progress_last_email_sent_at, course_completion_percentages_for_email, course_key, user_id):
"""
Expand All @@ -42,7 +57,7 @@ def send_user_course_progress_email(current_progress, progress_last_email_sent_a
course_id = CourseKey.from_string(course_key)
course = modulestore().get_course(course_id)

site = Site.objects.get(id=site_id) if site_id else (Site.objects.first() or Site.objects.get_current())
site = Site.objects.first() or Site.objects.get_current()
message_context = get_base_template_context(site)
course_home_url = get_learning_mfe_home_url(course_key=course_key, url_fragment='home')
platform_name = configuration_helpers.get_value_for_org(
Expand All @@ -69,12 +84,55 @@ def send_user_course_progress_email(current_progress, progress_last_email_sent_a
user_context={'full_name': user.profile.name}
)
ace.send(msg)
logger.info('Proctoring requirements email sent to user:')
logger.info('course progress email sent to user:')
user_completion_progress_email_history = CourseCompletionEmailHistory.objects.get(user=user, course_key=course_key)
user_completion_progress_email_history.last_progress_email_sent = course_completion_percentages_for_email
user_completion_progress_email_history.save()
return True
except Exception as e: # pylint: disable=broad-except
logger.exception(str(e))
logger.exception('Could not send email for proctoring requirements to user')
return False
logger.exception('Could not send course progress email sent to user')
return False


@shared_task
def send_user_course_completion_email(user_id, course_key):
course_id = CourseKey.from_string(course_key)
user = User.objects.get(id=user_id)
collected_block_structure = get_block_structure_manager(course_id).get_collected()
course_grade = CourseGradeFactory().read(user, collected_block_structure=collected_block_structure)
passing_grade = int(course_grade.percent * 100)

course = modulestore().get_course(course_id)
site = Site.objects.first() or Site.objects.get_current()
message_context = get_base_template_context(site)
course_progress_url = get_learning_mfe_home_url(course_key=course_key, url_fragment='progress')
platform_name = configuration_helpers.get_value_for_org(
course.org,
'PLATFORM_NAME',
settings.PLATFORM_NAME
)

context={
'course_key': course_key,
'platform_name': platform_name,
'course_name': course.display_name,
'course_progress_url': course_progress_url,
'passing_grade': passing_grade,
}
message_context.update(context)
user_language_pref = get_user_preference(user, LANGUAGE_KEY) or settings.LANGUAGE_CODE
try:
with emulate_http_request(site, user):
msg = UserCourseCompletionEmail(context=message_context).personalize(
recipient=Recipient(0, user.email),
language=user_language_pref,
user_context={'full_name': user.profile.name}
)
ace.send(msg)
logger.info('course completion email sent to user:')
return True
except Exception as e: # pylint: disable=broad-except
logger.exception(str(e))
logger.exception('Could not send course completion email sent to user')
return False
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- {% extends 'ace_common/edx_ace/common/base_body.html' %} -->

{% load i18n %}
{% load static %}
{% block content %}
<p style="color: rgba(0,0,0,.75);">
{% autoescape off %}
{# xss-lint: disable=django-blocktrans-missing-escape-filter #}
{% blocktrans %}Great job!{% endblocktrans %}
{% endautoescape %}
<br />
</p>
<p style="color: rgba(0,0,0,.75);">
{% autoescape off %}
{# xss-lint: disable=django-blocktrans-missing-escape-filter #}
{% blocktrans %}{{full_name}}{% endblocktrans %}
{% endautoescape %}
<br />
</p>
<p style="color: rgba(0,0,0,.75);">
{% autoescape off %}
{# xss-lint: disable=django-blocktrans-missing-escape-filter #}
{% blocktrans %}You’ve completed "{{ course_name }}". {% endblocktrans %}
{% endautoescape %}
<br />
</p>
<p style="color: rgba(0,0,0,.75);">
{% autoescape off %}
{# xss-lint: disable=django-blocktrans-missing-escape-filter #}
{% blocktrans %}Your certificate/badge has been issued and is accessible via the following {% endblocktrans %}<a href="{{ course_progress_url }}">{% blocktrans %}URL{% endblocktrans %}</a>.
{% endautoescape %}
<br />
</p>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% load i18n %}{% autoescape off %}
{% blocktrans %}Great job!{% endblocktrans %}
{% blocktrans %}{{ full_name }}{% endblocktrans %}
{% blocktrans %}You’ve completed "{{ course_name }}".{% endblocktrans %}
{% blocktrans %}Your certificate/badge has been issued and is accessible via the following {% endblocktrans %}<a href="{{ course_progress_url }}">{% blocktrans %}URL{% endblocktrans %}</a>.
{% endautoescape %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ platform_name }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- {% extends 'ace_common/edx_ace/common/base_head.html' %} -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% load i18n %}
{% autoescape off %}
{% blocktrans %}{{ platform_name }} - {{ course_name }} | Course Completion 🎉{% endblocktrans %}
{% endautoescape %}

0 comments on commit 8d7173c

Please sign in to comment.