diff --git a/openedx/features/sdaia_features/course_progress/signals.py b/openedx/features/sdaia_features/course_progress/signals.py index d0c507baf7bf..b3a9bd66fa90 100644 --- a/openedx/features/sdaia_features/course_progress/signals.py +++ b/openedx/features/sdaia_features/course_progress/signals.py @@ -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 @@ -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 @@ -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)) \ No newline at end of file diff --git a/openedx/features/sdaia_features/course_progress/tasks.py b/openedx/features/sdaia_features/course_progress/tasks.py index ed29b06828f2..006c6e34dcfe 100644 --- a/openedx/features/sdaia_features/course_progress/tasks.py +++ b/openedx/features/sdaia_features/course_progress/tasks.py @@ -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 @@ -25,7 +28,18 @@ 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' @@ -33,6 +47,7 @@ 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): """ @@ -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( @@ -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 \ No newline at end of file + 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 diff --git a/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/body.html b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/body.html new file mode 100644 index 000000000000..fcbf39107c83 --- /dev/null +++ b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/body.html @@ -0,0 +1,34 @@ + + +{% load i18n %} +{% load static %} +{% block content %} +

+ {% autoescape off %} + {# xss-lint: disable=django-blocktrans-missing-escape-filter #} + {% blocktrans %}Great job!{% endblocktrans %} + {% endautoescape %} +
+

+

+ {% autoescape off %} + {# xss-lint: disable=django-blocktrans-missing-escape-filter #} + {% blocktrans %}{{full_name}}{% endblocktrans %} + {% endautoescape %} +
+

+

+ {% autoescape off %} + {# xss-lint: disable=django-blocktrans-missing-escape-filter #} + {% blocktrans %}You’ve completed "{{ course_name }}". {% endblocktrans %} + {% endautoescape %} +
+

+

+ {% autoescape off %} + {# xss-lint: disable=django-blocktrans-missing-escape-filter #} + {% blocktrans %}Your certificate/badge has been issued and is accessible via the following {% endblocktrans %}{% blocktrans %}URL{% endblocktrans %}. + {% endautoescape %} +
+

+{% endblock %} \ No newline at end of file diff --git a/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/body.txt b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/body.txt new file mode 100644 index 000000000000..5d2bb3de8c6b --- /dev/null +++ b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/body.txt @@ -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 %}{% blocktrans %}URL{% endblocktrans %}. +{% endautoescape %} diff --git a/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/from_name.txt b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/from_name.txt new file mode 100644 index 000000000000..dcbc23c00480 --- /dev/null +++ b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/from_name.txt @@ -0,0 +1 @@ +{{ platform_name }} diff --git a/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/head.html b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/head.html new file mode 100644 index 000000000000..463307296e06 --- /dev/null +++ b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/head.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/subject.txt b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/subject.txt new file mode 100644 index 000000000000..f1e01f238c78 --- /dev/null +++ b/openedx/features/sdaia_features/course_progress/templates/course_progress/edx_ace/usercoursecompletionemail/email/subject.txt @@ -0,0 +1,4 @@ +{% load i18n %} +{% autoescape off %} +{% blocktrans %}{{ platform_name }} - {{ course_name }} | Course Completion 🎉{% endblocktrans %} +{% endautoescape %} \ No newline at end of file