diff --git a/common/djangoapps/util/milestones_helpers.py b/common/djangoapps/util/milestones_helpers.py index d1514d0dee..ad26ad238c 100644 --- a/common/djangoapps/util/milestones_helpers.py +++ b/common/djangoapps/util/milestones_helpers.py @@ -175,6 +175,18 @@ def fulfill_course_milestone(course_key, user): milestones_api.add_user_milestone({'id': user.id}, milestone) +def remove_course_milestones(course_key, user, relationship): + """ + Remove all user milestones for the course specified by course_key. + """ + if not settings.FEATURES.get('MILESTONES_APP', False): + return None + from milestones import api as milestones_api + course_milestones = milestones_api.get_course_milestones(course_key=course_key, relationship=relationship) + for milestone in course_milestones: + milestones_api.remove_user_milestone({'id': user.id}, milestone) + + def get_required_content(course, user): """ Queries milestones subsystem to see if the specified course is gated on one or more milestones, @@ -321,6 +333,19 @@ def get_course_content_milestones(course_id, content_id, relationship): return milestones_api.get_course_content_milestones(course_id, content_id, relationship) +def remove_course_content_user_milestones(course_key, content_key, user, relationship): + """ + Removes the specified User-Milestone link from the system for the specified course content module. + """ + if not settings.FEATURES.get('MILESTONES_APP', False): + return [] + from milestones import api as milestones_api + + course_content_milestones = milestones_api.get_course_content_milestones(course_key, content_key, relationship) + for milestone in course_content_milestones: + milestones_api.remove_user_milestone({'id': user.id}, milestone) + + def remove_content_references(content_id): """ Client API operation adapter/wrapper diff --git a/lms/djangoapps/instructor_task/api.py b/lms/djangoapps/instructor_task/api.py index a1bb562536..5ad4cc07de 100644 --- a/lms/djangoapps/instructor_task/api.py +++ b/lms/djangoapps/instructor_task/api.py @@ -38,6 +38,7 @@ from instructor_task.api_helper import ( submit_task, ) from bulk_email.models import CourseEmail +from util import milestones_helpers def get_running_instructor_tasks(course_id): @@ -269,6 +270,8 @@ def submit_delete_entrance_exam_state_for_student(request, usage_key, student): Module state for all problems in entrance exam will be deleted for specified student. + All User Milestones of entrance exam will be removed for the specified student + Parameters are `usage_key`, which must be a :class:`Location` representing entrance exam section and the `student` as a User object. @@ -286,6 +289,14 @@ def submit_delete_entrance_exam_state_for_student(request, usage_key, student): # check arguments: make sure entrance exam(section) exists for given usage_key modulestore().get_item(usage_key) + # Remove Content milestones that user has completed + milestones_helpers.remove_course_content_user_milestones( + course_key=usage_key.course_key, + content_key=usage_key, + user=student, + relationship='fulfills' + ) + task_type = 'delete_problem_state' task_class = delete_problem_state task_input, task_key = encode_entrance_exam_and_student_input(usage_key, student)