From 440773a72d7c78d7d10f1781d1aa7b435b0dfb58 Mon Sep 17 00:00:00 2001 From: Alexander Sheehan Date: Mon, 30 Nov 2020 23:34:07 -0800 Subject: [PATCH] Adding signals and receivers for assessment level reporting to integrated channels --- .../grades/subsection_grade_factory.py | 8 ++++++++ openedx/core/djangoapps/signals/signals.py | 9 +++++++++ .../features/enterprise_support/signals.py | 20 +++++++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/grades/subsection_grade_factory.py b/lms/djangoapps/grades/subsection_grade_factory.py index 35b6047c2f..8947656715 100644 --- a/lms/djangoapps/grades/subsection_grade_factory.py +++ b/lms/djangoapps/grades/subsection_grade_factory.py @@ -9,6 +9,7 @@ from logging import getLogger from lazy import lazy from submissions import api as submissions_api +from openedx.core.djangoapps.signals.signals import COURSE_ASSESSMENT_GRADE_CHANGED from lms.djangoapps.courseware.model_data import ScoresClient from lms.djangoapps.grades.config import assume_zero_if_absent, should_persist_grades from lms.djangoapps.grades.models import PersistentSubsectionGrade @@ -104,6 +105,13 @@ class SubsectionGradeFactory(object): ) self._update_saved_subsection_grade(subsection.location, grade_model) + COURSE_ASSESSMENT_GRADE_CHANGED.send_robust( + sender=None, + user=self.student, + subsection_id=calculated_grade.location, + subsection_grade=calculated_grade.graded_total.earned + ) + return calculated_grade @lazy diff --git a/openedx/core/djangoapps/signals/signals.py b/openedx/core/djangoapps/signals/signals.py index b0fd6cafa0..64dae48bcb 100644 --- a/openedx/core/djangoapps/signals/signals.py +++ b/openedx/core/djangoapps/signals/signals.py @@ -17,6 +17,15 @@ COURSE_CERT_REVOKED = Signal(providing_args=["user", "course_key", "mode", "stat COURSE_CERT_DATE_CHANGE = Signal(providing_args=["course_key"]) +COURSE_ASSESSMENT_GRADE_CHANGED = Signal( + providing_args=[ + 'user', + 'course_id', + 'subsection_id', + 'subsection_grade', + ] +) + # Signal that indicates that a user has passed a course. COURSE_GRADE_NOW_PASSED = Signal( providing_args=[ diff --git a/openedx/features/enterprise_support/signals.py b/openedx/features/enterprise_support/signals.py index 7d7f472aea..d120a55961 100644 --- a/openedx/features/enterprise_support/signals.py +++ b/openedx/features/enterprise_support/signals.py @@ -11,12 +11,12 @@ from django.contrib.auth.models import User from django.db.models.signals import post_save, pre_save from django.dispatch import receiver from enterprise.models import EnterpriseCourseEnrollment, EnterpriseCustomer, EnterpriseCustomerUser -from integrated_channels.integrated_channel.tasks import transmit_single_learner_data +from integrated_channels.integrated_channel.tasks import transmit_single_learner_data, transmit_subsection_learner_data from slumber.exceptions import HttpClientError from lms.djangoapps.email_marketing.tasks import update_user from openedx.core.djangoapps.commerce.utils import ecommerce_api_client -from openedx.core.djangoapps.signals.signals import COURSE_GRADE_NOW_PASSED +from openedx.core.djangoapps.signals.signals import COURSE_GRADE_NOW_PASSED, COURSE_ASSESSMENT_GRADE_CHANGED from openedx.features.enterprise_support.api import enterprise_enabled from openedx.features.enterprise_support.tasks import clear_enterprise_customer_data_consent_share_cache from openedx.features.enterprise_support.utils import clear_data_consent_share_cache, is_enterprise_learner @@ -86,6 +86,22 @@ def handle_enterprise_learner_passing_grade(sender, user, course_id, **kwargs): transmit_single_learner_data.apply_async(kwargs=kwargs) +@receiver(COURSE_ASSESSMENT_GRADE_CHANGED) +def handle_enterprise_learner_subsection(sender, user, course_id, subsection_id, subsection_grade, **kwargs): # pylint: disable=unused-argument + """ + Listen for an enterprise learner completing a subsection, transmit data to relevant integrated channel. + """ + if enterprise_enabled() and is_enterprise_learner(user): + kwargs = { + 'username': str(user.username), + 'course_run_id': str(course_id), + 'subsection_id': str(subsection_id), + 'grade': str(subsection_grade), + } + + transmit_subsection_learner_data.apply_async(kwargs=kwargs) + + @receiver(UNENROLL_DONE) def refund_order_voucher(sender, course_enrollment, skip_refund=False, **kwargs): # pylint: disable=unused-argument """