Ejemplo n.º 1
0
    def enroll_user(cls, enterprise_customer, user, course_mode, *course_ids):
        """
        Enroll a single user in any number of courses using a particular course mode.

        Args:
            enterprise_customer: The EnterpriseCustomer which is sponsoring the enrollment
            user: The user who needs to be enrolled in the course
            course_mode: The mode with which the enrollment should be created
            *course_ids: An iterable containing any number of course IDs to eventually enroll the user in.

        Returns:
            Boolean: Whether or not enrollment succeeded for all courses specified
        """
        enterprise_customer_user, __ = EnterpriseCustomerUser.objects.get_or_create(
            enterprise_customer=enterprise_customer, user_id=user.id)
        enrollment_client = EnrollmentApiClient()
        succeeded = True
        for course_id in course_ids:
            try:
                enrollment_client.enroll_user_in_course(
                    user.username, course_id, course_mode)
            except HttpClientError as exc:
                # Check if user is already enrolled then we should ignore exception
                if cls.is_user_enrolled(user, course_id, course_mode):
                    succeeded = True
                else:
                    succeeded = False
                    default_message = 'No error message provided'
                    try:
                        error_message = json.loads(exc.content.decode()).get(
                            'message', default_message)
                    except ValueError:
                        error_message = default_message
                    logging.error(
                        'Error while enrolling user %(user)s: %(message)s',
                        dict(user=user.username, message=error_message))
            if succeeded:
                __, created = EnterpriseCourseEnrollment.objects.get_or_create(
                    enterprise_customer_user=enterprise_customer_user,
                    course_id=course_id,
                    defaults={
                        'source':
                        EnterpriseEnrollmentSource.get_source(
                            EnterpriseEnrollmentSource.MANUAL)
                    })
                if created:
                    track_enrollment('admin-enrollment', user.id, course_id)
        return succeeded
Ejemplo n.º 2
0
def create_enterprise_enrollment(course_id, enterprise_customer_user_id):
    """
    Create enterprise enrollment for user if course_id part of catalog for the ENT customer.
    """
    enterprise_customer_user = EnterpriseCustomerUser.objects.get(
        id=enterprise_customer_user_id)
    # Prevent duplicate records from being created if possible
    # before we need to make a call to discovery
    if EnterpriseCourseEnrollment.objects.filter(
            enterprise_customer_user=enterprise_customer_user,
            course_id=course_id,
    ).exists():
        LOGGER.info(("EnterpriseCourseEnrollment record exists for user %s "
                     "on course %s. Exiting task."),
                    enterprise_customer_user.user_id, course_id)
        return

    enterprise_customer = enterprise_customer_user.enterprise_customer
    if enterprise_customer.catalog_contains_course(course_id):
        LOGGER.info(("Creating EnterpriseCourseEnrollment for user %s "
                     "on course %s for enterprise_customer %s"),
                    enterprise_customer_user.user_id, course_id,
                    enterprise_customer)

        # On Create we set the Source to be ENROLLMENT_TASK here.  This Source
        # is generalized from being just a B2C Source type because it is possible
        # to reach this task before the EnterpriseCustomerEnrollment is created
        # depending on timing.
        #
        # We have made changes elsewhere to avoid this issue, but in the mean time
        # we believe a Source of ENROLLMENT_TASK is more clear.

        EnterpriseCourseEnrollment.objects.create(
            course_id=course_id,
            enterprise_customer_user=enterprise_customer_user,
            source=EnterpriseEnrollmentSource.get_source(
                EnterpriseEnrollmentSource.ENROLLMENT_TASK))
    def handle(self, *args, **options):
        LOGGER.info("Command has started...")
        enterprise_customer_uuid_filter = options.get(
            'enterprise_customer_uuid')
        records_created = 0
        records_failed = 0

        missing_enrollment_data = self._fetch_course_enrollment_data(
            enterprise_customer_uuid_filter)
        LOGGER.info('System has %s missing enrollments',
                    len(missing_enrollment_data))
        for item in missing_enrollment_data:
            course_exist_in_catalog = False
            user_id = item['user_id']
            course_run_id = item['course_run_id']
            enterprise_customer_uuid = item['enterprise_customer_uuid']

            LOGGER.info(
                'Trying to create the enrollment for user [%s] in course [%s] for enterprise customer [%s]',
                user_id, course_run_id, enterprise_customer_uuid)

            # pylint: disable=no-member
            enterprise_customer = EnterpriseCustomer.objects.get(
                uuid=enterprise_customer_uuid)

            try:
                LOGGER.info(
                    'Checking whether course [%s] exists in enterprise customer [%s] - [%s] catalog',
                    course_run_id, enterprise_customer_uuid,
                    enterprise_customer.name)
                course_exist_in_catalog = enterprise_customer.catalog_contains_course(
                    course_run_id)
            except Exception as exc:  # pylint: disable=broad-except
                records_failed += 1
                LOGGER.warning(
                    'Course [%s] does not exist in EnterpriseCustomer [%s] due to this exception: [%s]',
                    course_run_id, enterprise_customer.uuid, str(exc))

            if course_exist_in_catalog:
                enterprise_customer_user = EnterpriseCustomerUser.objects.filter(
                    enterprise_customer=enterprise_customer_uuid,
                    user_id=user_id)

                # This is an extra check for preventing the exception.
                # We already have implemented the solution for this (soft deletion).
                if enterprise_customer_user.exists():
                    enterprise_customer_user = enterprise_customer_user.first()
                    # pylint: disable=no-member
                    __, created = EnterpriseCourseEnrollment.objects.get_or_create(
                        enterprise_customer_user=enterprise_customer_user,
                        course_id=course_run_id,
                        defaults={
                            'source':
                            EnterpriseEnrollmentSource.get_source(
                                EnterpriseEnrollmentSource.MANAGEMENT_COMMAND)
                        })
                    if created:
                        # if we have enrolled the user in a course then we should
                        # active this record and inactive all the other records.
                        enterprise_customer_user.active = True
                        enterprise_customer_user.save()
                        EnterpriseCustomerUser.inactivate_other_customers(
                            user_id, enterprise_customer)

                        records_created += 1
                        LOGGER.info(
                            'EnterpriseCourseEnrollment created: EnterpriseCustomer [%s] - User [%s] - CourseRun [%s]',
                            enterprise_customer_uuid, user_id, course_run_id)
                    else:
                        LOGGER.warning(
                            'EnterpriseCourseEnrollment exists: EnterpriseCustomer [%s] - User [%s] - CourseRun [%s]',
                            enterprise_customer_uuid, user_id, course_run_id)
                else:
                    LOGGER.info(
                        'User [%s] is not linked with EnterpriseCustomer - [%s]',
                        user_id,
                        enterprise_customer.uuid,
                    )

        LOGGER.info('Created %s missing EnterpriseCourseEnrollments.',
                    records_created)
        LOGGER.info('Exception raised for %s records.', records_failed)
Ejemplo n.º 4
0
    def enroll_users_in_course(
        cls,
        enterprise_customer,
        course_id,
        course_mode,
        emails,
        enrollment_requester=None,
        enrollment_reason=None,
        discount=0.0,
        sales_force_id=None,
    ):
        """
        Enroll existing users in a course, and create a pending enrollment for nonexisting users.

        Args:
            enterprise_customer: The EnterpriseCustomer which is sponsoring the enrollment
            course_id (str): The unique identifier of the course in which we're enrolling
            course_mode (str): The mode with which we're enrolling in the course
            emails: An iterable of email addresses which need to be enrolled
            enrollment_requester (User): Admin user who is requesting the enrollment.
            enrollment_reason (str): A reason for enrollment.
            discount (Decimal): Percentage discount for enrollment.
            sales_force_id (str): Salesforce opportunity id.

        Returns:
            successes: A list of users who were successfully enrolled in the course
            pending: A list of PendingEnterpriseCustomerUsers who were successfully linked and had
                pending enrollments created for them in the database
            failures: A list of users who could not be enrolled in the course
        """
        existing_users, unregistered_emails = cls.get_users_by_email(emails)

        successes = []
        pending = []
        failures = []

        for user in existing_users:
            succeeded = cls.enroll_user(enterprise_customer, user, course_mode,
                                        course_id)
            if succeeded:
                successes.append(user)
                if enrollment_requester and enrollment_reason:
                    create_manual_enrollment_audit(
                        enrollment_requester,
                        user.email,
                        UNENROLLED_TO_ENROLLED,
                        enrollment_reason,
                        course_id,
                        role=MANUAL_ENROLLMENT_ROLE,
                    )
            else:
                failures.append(user)

        for email in unregistered_emails:
            pending_user = enterprise_customer.enroll_user_pending_registration(
                email,
                course_mode,
                course_id,
                enrollment_source=EnterpriseEnrollmentSource.get_source(
                    EnterpriseEnrollmentSource.MANUAL),
                discount=discount,
                sales_force_id=sales_force_id,
            )
            pending.append(pending_user)
            if enrollment_requester and enrollment_reason:
                create_manual_enrollment_audit(
                    enrollment_requester,
                    email,
                    UNENROLLED_TO_ALLOWEDTOENROLL,
                    enrollment_reason,
                    course_id,
                    role=MANUAL_ENROLLMENT_ROLE,
                )

        return successes, pending, failures
Ejemplo n.º 5
0
    def enroll_users_in_program(
            cls,
            enterprise_customer,
            program_details,
            course_mode,
            emails,
            cohort=None,
            enrollment_requester=None,
            enrollment_reason=None
    ):
        """
        Enroll existing users in all courses in a program, and create pending enrollments for nonexisting users.

        Args:
            enterprise_customer: The EnterpriseCustomer which is sponsoring the enrollment
            program_details: The details of the program in which we're enrolling
            course_mode (str): The mode with which we're enrolling in the program
            emails: An iterable of email addresses which need to be enrolled

        Returns:
            successes: A list of users who were successfully enrolled in all courses of the program
            pending: A list of PendingEnterpriseCustomerUsers who were successfully linked and had
                pending enrollments created for them in the database
            failures: A list of users who could not be enrolled in the program
        """
        existing_users, unregistered_emails = cls.get_users_by_email(emails)
        course_ids = get_course_runs_from_program(program_details)

        successes = []
        pending = []
        failures = []

        for user in existing_users:
            succeeded = cls.enroll_user(enterprise_customer, user, course_mode, *course_ids)
            if succeeded:
                successes.append(user)
                if enrollment_requester and enrollment_reason:
                    for course_id in course_ids:
                        create_manual_enrollment_audit(
                            enrollment_requester,
                            user.email,
                            UNENROLLED_TO_ENROLLED,
                            enrollment_reason,
                            course_id,
                            role=MANUAL_ENROLLMENT_ROLE,
                        )
            else:
                failures.append(user)

        for email in unregistered_emails:
            pending_user = enterprise_customer.enroll_user_pending_registration(
                email,
                course_mode,
                *course_ids,
                cohort=cohort,
                enrollment_source=EnterpriseEnrollmentSource.get_source(EnterpriseEnrollmentSource.MANUAL)
            )
            pending.append(pending_user)
            if enrollment_requester and enrollment_reason:
                for course_id in course_ids:
                    create_manual_enrollment_audit(
                        enrollment_requester,
                        email,
                        UNENROLLED_TO_ALLOWEDTOENROLL,
                        enrollment_reason,
                        course_id,
                        role=MANUAL_ENROLLMENT_ROLE,
                    )

        return successes, pending, failures