diff --git a/cms/static/js/certificates/factories/certificates_page_factory.js b/cms/static/js/certificates/factories/certificates_page_factory.js index cb935ddb065c8268e4dc17f82d920244d4bc12c1..a367f52ccef7a1bbc8ef89fb7701d94230ca83ed 100644 --- a/cms/static/js/certificates/factories/certificates_page_factory.js +++ b/cms/static/js/certificates/factories/certificates_page_factory.js @@ -20,8 +20,8 @@ define([ ], function($, CertificatesCollection, Certificate, CertificatesPage, CertificatePreview) { 'use strict'; - return function(certificatesJson, certificateUrl, courseOutlineUrl, course_modes, certificate_web_view_url, - is_active, certificate_activation_handler_url) { + return function(certificatesJson, certificateUrl, courseOutlineUrl, courseModes, certificateWebViewUrl, + isActive, certificateActivationHandlerUrl) { // Initialize the model collection, passing any necessary options to the constructor var certificatesCollection = new CertificatesCollection(certificatesJson, { parse: true, @@ -31,12 +31,12 @@ function($, CertificatesCollection, Certificate, CertificatesPage, CertificatePr // associating the certificate_preview globally. // need to show / hide this view in some other places. - if (!window.certWebPreview && certificate_web_view_url) { + if (!window.certWebPreview && certificateWebViewUrl) { window.certWebPreview = new CertificatePreview({ - course_modes: course_modes, - certificate_web_view_url: certificate_web_view_url, - certificate_activation_handler_url: certificate_activation_handler_url, - is_active: is_active + course_modes: courseModes, + certificate_web_view_url: certificateWebViewUrl, + certificate_activation_handler_url: certificateActivationHandlerUrl, + is_active: isActive }); } diff --git a/lms/djangoapps/grades/api/v1/gradebook_views.py b/lms/djangoapps/grades/api/v1/gradebook_views.py index b772ea2ce2f47e625413ea0050f98c04d3914a77..cffa6d5cf5806aadbd6ee9990a76ae84e591b795 100644 --- a/lms/djangoapps/grades/api/v1/gradebook_views.py +++ b/lms/djangoapps/grades/api/v1/gradebook_views.py @@ -1,6 +1,7 @@ """ Defines an endpoint for gradebook data related to a course. """ +import logging from collections import namedtuple from contextlib import contextmanager from functools import wraps @@ -53,6 +54,8 @@ from track.event_transaction_utils import ( from xmodule.modulestore.django import modulestore from xmodule.util.misc import get_default_short_labeler +log = logging.getLogger(__name__) + @contextmanager def bulk_gradebook_view_context(course_key, users): @@ -666,6 +669,7 @@ class GradebookBulkUpdateView(GradeViewMixin, PaginatedAPIView): user = self._get_single_user(request, course_key, requested_user_id) usage_key = UsageKey.from_string(requested_usage_id) except (USER_MODEL.DoesNotExist, InvalidKeyError, CourseEnrollment.DoesNotExist) as exc: + self._log_update_result(request.user, requested_user_id, requested_usage_id, success=False) result.append(GradebookUpdateResponseItem( user_id=requested_user_id, usage_id=requested_usage_id, @@ -685,6 +689,7 @@ class GradebookBulkUpdateView(GradeViewMixin, PaginatedAPIView): if subsection: subsection_grade_model = self._create_subsection_grade(user, course, subsection) else: + self._log_update_result(request.user, requested_user_id, requested_usage_id, success=False) result.append(GradebookUpdateResponseItem( user_id=requested_user_id, usage_id=requested_usage_id, @@ -694,7 +699,11 @@ class GradebookBulkUpdateView(GradeViewMixin, PaginatedAPIView): continue if subsection_grade_model: - self._create_override(request.user, subsection_grade_model, **user_data['grade']) + override = self._create_override(request.user, subsection_grade_model, **user_data['grade']) + + self._log_update_result( + request.user, requested_user_id, requested_usage_id, subsection_grade_model, override, True + ) result.append(GradebookUpdateResponseItem( user_id=user.id, usage_id=text_type(usage_key), @@ -754,6 +763,7 @@ class GradebookBulkUpdateView(GradeViewMixin, PaginatedAPIView): ) # Emit events to let our tracking system to know we updated subsection grade subsection_grade_calculated(subsection_grade_model) + return override def _clean_override_data(self, override_data): """ @@ -771,3 +781,22 @@ class GradebookBulkUpdateView(GradeViewMixin, PaginatedAPIView): if field in allowed_fields: stripped_data[field] = override_data[field] return stripped_data + + @staticmethod + def _log_update_result( + request_user, + user_id, usage_id, + subsection_grade_model=None, + subsection_grade_override=None, + success=False + ): + + log.info( + 'Grades: Bulk_Update, UpdatedByUser: %s, User: %s, Usage: %s, Grade: %s, GradeOverride: %s, Success: %s', + request_user.id, + user_id, + usage_id, + subsection_grade_model, + subsection_grade_override, + success + )