def add_course_requirements(self):
        """
        Add requirements to course.
        """
        requirements = ({
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {
                "min_grade": 0.8
            }
        }, {
            "namespace": "new_grade",
            "name": "new_grade",
            "display_name": "new_grade",
            "criteria": {
                "min_grade": 0.8
            },
        })

        for i, requirement in enumerate(requirements):
            credit_requirement, _ = CreditRequirement.add_or_update_course_requirement(
                self.credit_course, requirement, i)
            CreditRequirementStatus.add_or_update_requirement_status(
                self.old_username, credit_requirement, "satisfied",
                {"final_grade": 0.95})
예제 #2
0
def remove_credit_requirement_status(username, course_key, req_namespace, req_name):
    """
    Remove the user's requirement status.

    This will remove the record from the credit requirement status table.
    The user will still be eligible for the credit in a course.

    Args:
        username (str): Username of the user
        course_key (CourseKey): Identifier for the course associated
                                with the requirement.
        req_namespace (str): Namespace of the requirement
                            (e.g. "grade" or "reverification")
        req_name (str): Name of the requirement
                        (e.g. "grade" or the location of the ICRV XBlock)

    Example:
        >>> remove_credit_requirement_status(
                "staff",
                CourseKey.from_string("course-v1-edX-DemoX-1T2015"),
                "reverification",
                "i4x://edX/DemoX/edx-reverification-block/assessment_uuid".
            )

    """

    # Find the requirement we're trying to remove
    req_to_remove = CreditRequirement.get_course_requirements(course_key, namespace=req_namespace, name=req_name)

    # If we can't find the requirement, then the most likely explanation
    # is that there was a lag removing the credit requirements after the course
    # was published.  We *could* attempt to remove the requirement here,
    # but that could cause serious performance issues if many users attempt to
    # lock the row at the same time.
    # Instead, we skip removing the requirement and log an error.
    if not req_to_remove:
        log.error(
            (
                u'Could not remove credit requirement in course "%s" '
                u'with namespace "%s" and name "%s" '
                u'because the requirement does not exist. '
            ),
            unicode(course_key), req_namespace, req_name
        )
        return

    # Remove the requirement status
    CreditRequirementStatus.remove_requirement_status(
        username, req_to_remove
    )
예제 #3
0
    def post(self, request):
        """
        POST /api/user/v1/accounts/retire_misc/

        {
            'username': '******'
        }

        Retires the user with the given username in the LMS.
        """

        username = request.data['username']

        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(
                username)
            RevisionPluginRevision.retire_user(retirement.user)
            ArticleRevision.retire_user(retirement.user)
            PendingNameChange.delete_by_user_value(retirement.user,
                                                   field='user')
            PasswordHistory.retire_user(retirement.user.id)
            course_enrollments = CourseEnrollment.objects.filter(
                user=retirement.user)
            ManualEnrollmentAudit.retire_manual_enrollments(
                course_enrollments, retirement.retired_email)

            CreditRequest.retire_user(retirement)
            ApiAccessRequest.retire_user(retirement.user)
            CreditRequirementStatus.retire_user(retirement)

            # This signal allows code in higher points of LMS to retire the user as necessary
            USER_RETIRE_LMS_MISC.send(sender=self.__class__,
                                      user=retirement.user)

            # This signal allows code in higher points of LMS to unsubscribe the user
            # from various types of mailings.
            USER_RETIRE_MAILINGS.send(sender=self.__class__,
                                      email=retirement.original_email,
                                      new_email=retirement.retired_email,
                                      user=retirement.user)
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_400_BAD_REQUEST)
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc),
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
예제 #4
0
def get_credit_requirement_status(course_key, username, namespace=None, name=None):
    """ Retrieve the user's status for each credit requirement in the course.

    Args:
        course_key (CourseKey): The identifier for course
        username (str): The identifier of the user

    Example:
        >>> get_credit_requirement_status("course-v1-edX-DemoX-1T2015", "john")

                [
                    {
                        "namespace": "reverification",
                        "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                        "display_name": "In Course Reverification",
                        "criteria": {},
                        "reason": {},
                        "status": "failed",
                        "status_date": "2015-06-26 07:49:13",
                    },
                    {
                        "namespace": "proctored_exam",
                        "name": "i4x://edX/DemoX/proctoring-block/final_uuid",
                        "display_name": "Proctored Mid Term Exam",
                        "criteria": {},
                        "reason": {},
                        "status": "satisfied",
                        "status_date": "2015-06-26 11:07:42",
                    },
                    {
                        "namespace": "grade",
                        "name": "i4x://edX/DemoX/proctoring-block/final_uuid",
                        "display_name": "Minimum Passing Grade",
                        "criteria": {"min_grade": 0.8},
                        "reason": {"final_grade": 0.95},
                        "status": "satisfied",
                        "status_date": "2015-06-26 11:07:44",
                    },
                ]

    Returns:
        list of requirement statuses
    """
    requirements = CreditRequirement.get_course_requirements(course_key, namespace=namespace, name=name)
    requirement_statuses = CreditRequirementStatus.get_statuses(requirements, username)
    requirement_statuses = dict((o.requirement, o) for o in requirement_statuses)
    statuses = []
    for requirement in requirements:
        requirement_status = requirement_statuses.get(requirement)
        statuses.append({
            "namespace": requirement.namespace,
            "name": requirement.name,
            "display_name": requirement.display_name,
            "criteria": requirement.criteria,
            "reason": requirement_status.reason if requirement_status else None,
            "status": requirement_status.status if requirement_status else None,
            "status_date": requirement_status.modified if requirement_status else None,
        })
    return statuses
예제 #5
0
파일: views.py 프로젝트: mreyk/edx-platform
    def post(self, request):
        """
        POST /api/user/v1/accounts/retire_misc/

        {
            'username': '******'
        }

        Retires the user with the given username in the LMS.
        """

        username = request.data['username']

        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(username)
            RevisionPluginRevision.retire_user(retirement.user)
            ArticleRevision.retire_user(retirement.user)
            PendingNameChange.delete_by_user_value(retirement.user, field='user')
            PasswordHistory.retire_user(retirement.user.id)
            course_enrollments = CourseEnrollment.objects.filter(user=retirement.user)
            ManualEnrollmentAudit.retire_manual_enrollments(course_enrollments, retirement.retired_email)

            CreditRequest.retire_user(retirement.original_username, retirement.retired_username)
            ApiAccessRequest.retire_user(retirement.user)
            CreditRequirementStatus.retire_user(retirement.user.username)

            # This signal allows code in higher points of LMS to retire the user as necessary
            USER_RETIRE_LMS_MISC.send(sender=self.__class__, user=retirement.user)

            # This signal allows code in higher points of LMS to unsubscribe the user
            # from various types of mailings.
            USER_RETIRE_MAILINGS.send(
                sender=self.__class__,
                email=retirement.original_email,
                new_email=retirement.retired_email,
                user=retirement.user
            )
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_400_BAD_REQUEST)
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
예제 #6
0
    def post(self, request):
        """
        POST /api/user/v1/accounts/retire_misc/

        {
            'username': '******'
        }

        Retires the user with the given username in the LMS.
        """

        username = request.data['username']
        if is_username_retired(username):
            return Response(status=status.HTTP_404_NOT_FOUND)

        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(
                username)
            RevisionPluginRevision.retire_user(retirement.user)
            ArticleRevision.retire_user(retirement.user)
            PendingNameChange.delete_by_user_value(retirement.user,
                                                   field='user')
            PasswordHistory.retire_user(retirement.user.id)
            course_enrollments = CourseEnrollment.objects.filter(
                user=retirement.user)
            ManualEnrollmentAudit.retire_manual_enrollments(
                course_enrollments, retirement.retired_email)

            CreditRequest.retire_user(retirement.original_username,
                                      retirement.retired_username)
            ApiAccessRequest.retire_user(retirement.user)
            CreditRequirementStatus.retire_user(retirement.user.username)
            SurveyAnswer.retire_user(retirement.user.id)

        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_400_BAD_REQUEST)
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc),
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
def get_credit_requirement_status(course_key, username, namespace=None, name=None):
    """ Retrieve the user's status for each credit requirement in the course.

    Args:
        course_key (CourseKey): The identifier for course
        username (str): The identifier of the user

    Example:
        >>> get_credit_requirement_status("course-v1-edX-DemoX-1T2015", "john")

                [
                    {
                        "namespace": "proctored_exam",
                        "name": "i4x://edX/DemoX/proctoring-block/final_uuid",
                        "display_name": "Proctored Mid Term Exam",
                        "criteria": {},
                        "reason": {},
                        "status": "satisfied",
                        "status_date": "2015-06-26 11:07:42",
                        "order": 1,
                    },
                    {
                        "namespace": "grade",
                        "name": "i4x://edX/DemoX/proctoring-block/final_uuid",
                        "display_name": "Minimum Passing Grade",
                        "criteria": {"min_grade": 0.8},
                        "reason": {"final_grade": 0.95},
                        "status": "satisfied",
                        "status_date": "2015-06-26 11:07:44",
                        "order": 2,
                    },
                ]

    Returns:
        list of requirement statuses
    """
    requirements = CreditRequirement.get_course_requirements(course_key, namespace=namespace, name=name)
    requirement_statuses = CreditRequirementStatus.get_statuses(requirements, username)
    requirement_statuses = {o.requirement: o for o in requirement_statuses}
    statuses = []
    for requirement in requirements:
        requirement_status = requirement_statuses.get(requirement)
        statuses.append({
            "namespace": requirement.namespace,
            "name": requirement.name,
            "display_name": requirement.display_name,
            "criteria": requirement.criteria,
            "reason": requirement_status.reason if requirement_status else None,
            "status": requirement_status.status if requirement_status else None,
            "status_date": requirement_status.modified if requirement_status else None,
            # We retain the old name "order" in the API because changing APIs takes a lot more coordination.
            "order": requirement.sort_value,
        })
    return statuses
예제 #8
0
    def test_retire_user(self):
        self.add_course_requirements()

        retirement_succeeded = CreditRequirementStatus.retire_user(self.old_username)
        self.assertTrue(retirement_succeeded)

        old_username_records_exist = CreditRequirementStatus.objects.filter(username=self.old_username).exists()
        self.assertFalse(old_username_records_exist)

        new_username_records_exist = CreditRequirementStatus.objects.filter(username=self.retired_username).exists()
        self.assertTrue(new_username_records_exist)
예제 #9
0
    def test_retire_user(self):
        self.add_course_requirements()

        retirement_succeeded = CreditRequirementStatus.retire_user(self.old_username)
        self.assertTrue(retirement_succeeded)

        old_username_records_exist = CreditRequirementStatus.objects.filter(
            username=self.old_username
        ).exists()
        self.assertFalse(old_username_records_exist)

        new_username_records_exist = CreditRequirementStatus.objects.filter(username=self.retired_username).exists()
        self.assertTrue(new_username_records_exist)
    def test_retire_user(self):
        self.add_course_requirements()

        retirement_succeeded = CreditRequirementStatus.retire_user(
            self.retirement)
        assert retirement_succeeded

        old_username_records_exist = CreditRequirementStatus.objects.filter(
            username=self.old_username).exists()
        assert not old_username_records_exist

        new_username_records_exist = CreditRequirementStatus.objects.filter(
            username=self.retirement.retired_username).exists()
        assert new_username_records_exist
예제 #11
0
    def add_course_requirements(self):
        """
        Add requirements to course.
        """
        requirements = (
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "new_grade",
                "name": "new_grade",
                "display_name": "new_grade",
                "criteria": {
                    "min_grade": 0.8
                },
            }
        )

        for i, requirement in enumerate(requirements):
            credit_requirement, _ = CreditRequirement.add_or_update_course_requirement(
                self.credit_course,
                requirement,
                i
            )
            CreditRequirementStatus.add_or_update_requirement_status(
                self.old_username,
                credit_requirement,
                "satisfied",
                {
                    "final_grade": 0.95
                }
            )
예제 #12
0
def set_credit_requirement_status(user, course_key, req_namespace, req_name, status="satisfied", reason=None):
    """
    Update the user's requirement status.

    This will record whether the user satisfied or failed a particular requirement
    in a course.  If the user has satisfied all requirements, the user will be marked
    as eligible for credit in the course.

    Args:
        user(User): User object to set credit requirement for.
        course_key (CourseKey): Identifier for the course associated with the requirement.
        req_namespace (str): Namespace of the requirement (e.g. "grade" or "reverification")
        req_name (str): Name of the requirement (e.g. "grade" or the location of the ICRV XBlock)

    Keyword Arguments:
        status (str): Status of the requirement (either "satisfied" or "failed")
        reason (dict): Reason of the status
    """
    # Check whether user has credit eligible enrollment.
    enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course_key)
    has_credit_eligible_enrollment = (CourseMode.is_credit_eligible_slug(enrollment_mode) and is_active)

    # Refuse to set status of requirement if the user enrollment is not credit eligible.
    if not has_credit_eligible_enrollment:
        return

    # Do not allow students who have requested credit to change their eligibility
    if CreditRequest.get_user_request_status(user.username, course_key):
        log.info(
            u'Refusing to set status of requirement with namespace "%s" and name "%s" because the '
            u'user "%s" has already requested credit for the course "%s".',
            req_namespace, req_name, user.username, course_key
        )
        return

    # Do not allow a student who has earned eligibility to un-earn eligibility
    eligible_before_update = CreditEligibility.is_user_eligible_for_credit(course_key, user.username)
    if eligible_before_update and status == 'failed':
        log.info(
            u'Refusing to set status of requirement with namespace "%s" and name "%s" to "failed" because the '
            u'user "%s" is already eligible for credit in the course "%s".',
            req_namespace, req_name, user.username, course_key
        )
        return

    # Retrieve all credit requirements for the course
    # We retrieve all of them to avoid making a second query later when
    # we need to check whether all requirements have been satisfied.
    reqs = CreditRequirement.get_course_requirements(course_key)

    # Find the requirement we're trying to set
    req_to_update = next((
        req for req in reqs
        if req.namespace == req_namespace and req.name == req_name
    ), None)

    # If we can't find the requirement, then the most likely explanation
    # is that there was a lag updating the credit requirements after the course
    # was published.  We *could* attempt to create the requirement here,
    # but that could cause serious performance issues if many users attempt to
    # lock the row at the same time.
    # Instead, we skip updating the requirement and log an error.
    if req_to_update is None:
        log.error(
            (
                u'Could not update credit requirement in course "%s" '
                u'with namespace "%s" and name "%s" '
                u'because the requirement does not exist. '
                u'The user "%s" should have had his/her status updated to "%s".'
            ),
            unicode(course_key), req_namespace, req_name, user.username, status
        )
        return

    # Update the requirement status
    CreditRequirementStatus.add_or_update_requirement_status(
        user.username, req_to_update, status=status, reason=reason
    )

    # If we're marking this requirement as "satisfied", there's a chance that the user has met all eligibility
    # requirements, and should be notified. However, if the user was already eligible, do not send another notification.
    if status == "satisfied" and not eligible_before_update:
        is_eligible, eligibility_record_created = CreditEligibility.update_eligibility(reqs, user.username, course_key)
        if eligibility_record_created and is_eligible:
            try:
                send_credit_notifications(user.username, course_key)
            except Exception:  # pylint: disable=broad-except
                log.exception("Error sending email")
예제 #13
0
def set_credit_requirement_status(user,
                                  course_key,
                                  req_namespace,
                                  req_name,
                                  status="satisfied",
                                  reason=None):
    """
    Update the user's requirement status.

    This will record whether the user satisfied or failed a particular requirement
    in a course.  If the user has satisfied all requirements, the user will be marked
    as eligible for credit in the course.

    Args:
        user(User): User object to set credit requirement for.
        course_key (CourseKey): Identifier for the course associated with the requirement.
        req_namespace (str): Namespace of the requirement (e.g. "grade" or "reverification")
        req_name (str): Name of the requirement (e.g. "grade" or the location of the ICRV XBlock)

    Keyword Arguments:
        status (str): Status of the requirement (either "satisfied" or "failed")
        reason (dict): Reason of the status
    """
    # Check whether user has credit eligible enrollment.
    enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
        user, course_key)
    has_credit_eligible_enrollment = (
        CourseMode.is_credit_eligible_slug(enrollment_mode) and is_active)

    # Refuse to set status of requirement if the user enrollment is not credit eligible.
    if not has_credit_eligible_enrollment:
        return

    # Do not allow students who have requested credit to change their eligibility
    if CreditRequest.get_user_request_status(user.username, course_key):
        log.info(
            u'Refusing to set status of requirement with namespace "%s" and name "%s" because the '
            u'user "%s" has already requested credit for the course "%s".',
            req_namespace, req_name, user.username, course_key)
        return

    # Do not allow a student who has earned eligibility to un-earn eligibility
    eligible_before_update = CreditEligibility.is_user_eligible_for_credit(
        course_key, user.username)
    if eligible_before_update and status == 'failed':
        log.info(
            u'Refusing to set status of requirement with namespace "%s" and name "%s" to "failed" because the '
            u'user "%s" is already eligible for credit in the course "%s".',
            req_namespace, req_name, user.username, course_key)
        return

    # Retrieve all credit requirements for the course
    # We retrieve all of them to avoid making a second query later when
    # we need to check whether all requirements have been satisfied.
    reqs = CreditRequirement.get_course_requirements(course_key)

    # Find the requirement we're trying to set
    req_to_update = next(
        (req for req in reqs
         if req.namespace == req_namespace and req.name == req_name), None)

    # If we can't find the requirement, then the most likely explanation
    # is that there was a lag updating the credit requirements after the course
    # was published.  We *could* attempt to create the requirement here,
    # but that could cause serious performance issues if many users attempt to
    # lock the row at the same time.
    # Instead, we skip updating the requirement and log an error.
    if req_to_update is None:
        log.error(
            (u'Could not update credit requirement in course "%s" '
             u'with namespace "%s" and name "%s" '
             u'because the requirement does not exist. '
             u'The user "%s" should have had his/her status updated to "%s".'),
            unicode(course_key), req_namespace, req_name, user.username,
            status)
        return

    # Update the requirement status
    CreditRequirementStatus.add_or_update_requirement_status(user.username,
                                                             req_to_update,
                                                             status=status,
                                                             reason=reason)

    # If we're marking this requirement as "satisfied", there's a chance that the user has met all eligibility
    # requirements, and should be notified. However, if the user was already eligible, do not send another notification.
    if status == "satisfied" and not eligible_before_update:
        is_eligible, eligibility_record_created = CreditEligibility.update_eligibility(
            reqs, user.username, course_key)
        if eligibility_record_created and is_eligible:
            try:
                send_credit_notifications(user.username, course_key)
            except Exception:  # pylint: disable=broad-except
                log.exception("Error sending email")
예제 #14
0
def get_credit_requirement_status(course_key, username, namespace=None, name=None):
    """ Retrieve the user's status for each credit requirement in the course.

    Args:
        course_key (CourseKey): The identifier for course
        username (str): The identifier of the user

    Example:
        >>> get_credit_requirement_status("course-v1-edX-DemoX-1T2015", "john")

                [
                    {
                        "namespace": "reverification",
                        "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                        "display_name": "In Course Reverification",
                        "criteria": {},
                        "reason": {},
                        "status": "failed",
                        "status_date": "2015-06-26 07:49:13",
                        "order": 0,
                    },
                    {
                        "namespace": "proctored_exam",
                        "name": "i4x://edX/DemoX/proctoring-block/final_uuid",
                        "display_name": "Proctored Mid Term Exam",
                        "criteria": {},
                        "reason": {},
                        "status": "satisfied",
                        "status_date": "2015-06-26 11:07:42",
                        "order": 1,
                    },
                    {
                        "namespace": "grade",
                        "name": "i4x://edX/DemoX/proctoring-block/final_uuid",
                        "display_name": "Minimum Passing Grade",
                        "criteria": {"min_grade": 0.8},
                        "reason": {"final_grade": 0.95},
                        "status": "satisfied",
                        "status_date": "2015-06-26 11:07:44",
                        "order": 2,
                    },
                ]

    Returns:
        list of requirement statuses
    """
    requirements = CreditRequirement.get_course_requirements(course_key, namespace=namespace, name=name)
    requirement_statuses = CreditRequirementStatus.get_statuses(requirements, username)
    requirement_statuses = dict((o.requirement, o) for o in requirement_statuses)
    statuses = []
    for requirement in requirements:
        requirement_status = requirement_statuses.get(requirement)
        statuses.append({
            "namespace": requirement.namespace,
            "name": requirement.name,
            "display_name": requirement.display_name,
            "criteria": requirement.criteria,
            "reason": requirement_status.reason if requirement_status else None,
            "status": requirement_status.status if requirement_status else None,
            "status_date": requirement_status.modified if requirement_status else None,
            "order": requirement.order,
        })
    return statuses
예제 #15
0
 def test_retire_user_with_data(self):
     retirement_succeeded = CreditRequirementStatus.retire_user(
         self.retired_username)
     self.assertFalse(retirement_succeeded)
예제 #16
0
def set_credit_requirement_status(username, course_key, req_namespace, req_name, status="satisfied", reason=None):
    """
    Update the user's requirement status.

    This will record whether the user satisfied or failed a particular requirement
    in a course.  If the user has satisfied all requirements, the user will be marked
    as eligible for credit in the course.

    Args:
        username (str): Username of the user
        course_key (CourseKey): Identifier for the course associated with the requirement.
        req_namespace (str): Namespace of the requirement (e.g. "grade" or "reverification")
        req_name (str): Name of the requirement (e.g. "grade" or the location of the ICRV XBlock)

    Keyword Arguments:
        status (str): Status of the requirement (either "satisfied" or "failed")
        reason (dict): Reason of the status

    Example:
        >>> set_credit_requirement_status(
                "staff",
                CourseKey.from_string("course-v1-edX-DemoX-1T2015"),
                "reverification",
                "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                status="satisfied",
                reason={}
            )

    """
    # Check if we're already eligible for credit.
    # If so, short-circuit this process.
    if CreditEligibility.is_user_eligible_for_credit(course_key, username):
        log.info(
            u'Skipping update of credit requirement with namespace "%s" '
            u'and name "%s" because the user "%s" is already eligible for credit '
            u'in the course "%s".',
            req_namespace, req_name, username, course_key
        )
        return

    # Retrieve all credit requirements for the course
    # We retrieve all of them to avoid making a second query later when
    # we need to check whether all requirements have been satisfied.
    reqs = CreditRequirement.get_course_requirements(course_key)

    # Find the requirement we're trying to set
    req_to_update = next((
        req for req in reqs
        if req.namespace == req_namespace and req.name == req_name
    ), None)

    # If we can't find the requirement, then the most likely explanation
    # is that there was a lag updating the credit requirements after the course
    # was published.  We *could* attempt to create the requirement here,
    # but that could cause serious performance issues if many users attempt to
    # lock the row at the same time.
    # Instead, we skip updating the requirement and log an error.
    if req_to_update is None:
        log.error(
            (
                u'Could not update credit requirement in course "%s" '
                u'with namespace "%s" and name "%s" '
                u'because the requirement does not exist. '
                u'The user "%s" should have had his/her status updated to "%s".'
            ),
            unicode(course_key), req_namespace, req_name, username, status
        )
        return

    # Update the requirement status
    CreditRequirementStatus.add_or_update_requirement_status(
        username, req_to_update, status=status, reason=reason
    )

    # If we're marking this requirement as "satisfied", there's a chance
    # that the user has met all eligibility requirements.
    if status == "satisfied":
        is_eligible, eligibility_record_created = CreditEligibility.update_eligibility(reqs, username, course_key)
        if eligibility_record_created and is_eligible:
            try:
                send_credit_notifications(username, course_key)
            except Exception:  # pylint: disable=broad-except
                log.error("Error sending email")
예제 #17
0
 def test_retire_user_without_data(self):
     retirement_succeeded = CreditRequirementStatus.retire_user(self.retirement)
     self.assertFalse(retirement_succeeded)
 def test_retire_user_without_data(self):
     retirement_succeeded = CreditRequirementStatus.retire_user(
         self.retirement)
     assert not retirement_succeeded