def create(self, request):
        """
        Create a new workgroup and its cohort.
        """
        assignment_type = request.data.get('assignment_type', CourseCohort.RANDOM)
        if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
            message = "Not a valid assignment type, '{}'".format(assignment_type)
            return Response({'details': message}, status.HTTP_400_BAD_REQUEST)
        response = super(WorkgroupsViewSet, self).create(request)
        if response.status_code == status.HTTP_201_CREATED:
            # create the workgroup cohort
            workgroup = get_object_or_404(self.queryset, pk=response.data['id'])
            course_key = get_course_key(workgroup.project.course_id)
            add_cohort(course_key, workgroup.cohort_name, assignment_type)

        return response
Example #2
0
    def create(self, request):
        """
        Create a new workgroup and its cohort.
        """
        assignment_type = request.DATA.get("assignment_type", CourseCohort.RANDOM)
        if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
            message = "Not a valid assignment type, '{}'".format(assignment_type)
            return Response({"details": message}, status.HTTP_400_BAD_REQUEST)
        response = super(WorkgroupsViewSet, self).create(request)
        if response.status_code == status.HTTP_201_CREATED:
            # create the workgroup cohort
            workgroup = self.object
            course_descriptor, course_key, course_content = _get_course(
                self.request, self.request.user, workgroup.project.course_id
            )  # pylint: disable=W0612
            add_cohort(course_key, workgroup.cohort_name, assignment_type)

        return response
Example #3
0
    def create(self, request):
        """
        Create a new workgroup and its cohort.
        """
        assignment_type = request.data.get('assignment_type',
                                           CourseCohort.RANDOM)
        if assignment_type not in dict(
                CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
            message = "Not a valid assignment type, '{}'".format(
                assignment_type)
            return Response({'details': message}, status.HTTP_400_BAD_REQUEST)
        response = super(WorkgroupsViewSet, self).create(request)
        if response.status_code == status.HTTP_201_CREATED:
            # create the workgroup cohort
            workgroup = get_object_or_404(self.queryset,
                                          pk=response.data['id'])
            course_key = get_course_key(workgroup.project.course_id)
            add_cohort(course_key, workgroup.cohort_name, assignment_type)

        return response
Example #4
0
    def users(self, request, pk):
        """
        Add a User to a Workgroup
        """
        if request.method == "GET":
            users = User.objects.filter(workgroups=pk)
            response_data = []
            if users:
                for user in users:
                    serializer = UserSerializer(user)
                    response_data.append(serializer.data)  # pylint: disable=E1101
            return Response(response_data, status=status.HTTP_200_OK)
        elif request.method == "POST":
            user_id = request.DATA.get("id")
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = "User {} does not exist".format(user_id)
                return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)

            workgroup = self.get_object()

            # Ensure the user is not already assigned to a project for this course
            existing_projects = Project.objects.filter(course_id=workgroup.project.course_id).filter(
                workgroups__users__id=user.id
            )
            if len(existing_projects):
                message = "User {} already assigned to a project for this course".format(user_id)
                return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)

            try:
                workgroup.add_user(user)
            except ValidationError as e:
                return Response({"detail": unicode(e)}, status.HTTP_400_BAD_REQUEST)

            workgroup.save()

            # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy
            # workgroup)
            course_descriptor, course_key, course_content = _get_course(
                self.request, user, workgroup.project.course_id
            )  # pylint: disable=W0612
            try:
                cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
                add_user_to_cohort(cohort, user.username)
            except ObjectDoesNotExist:
                # This use case handles cases where a workgroup might have been created before
                # the notion of a cohorted discussion. So we need to backfill in the data
                assignment_type = request.DATA.get("assignment_type", CourseCohort.RANDOM)
                if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
                    message = "Not a valid assignment type, '{}'".format(assignment_type)
                    return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
                cohort = add_cohort(course_key, workgroup.cohort_name, assignment_type)
                for workgroup_user in workgroup.users.all():
                    add_user_to_cohort(cohort, workgroup_user.username)
            return Response({}, status=status.HTTP_201_CREATED)
        else:
            user_id = request.DATA.get("id")
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = "User {} does not exist".format(user_id)
                return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
            workgroup = self.get_object()
            course_descriptor, course_key, course_content = _get_course(
                self.request, user, workgroup.project.course_id
            )  # pylint: disable=W0612
            cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
            workgroup.remove_user(user)
            remove_user_from_cohort(cohort, user.username)
            return Response({}, status=status.HTTP_204_NO_CONTENT)
Example #5
0
 def _create_verified_cohort(self, name=DEFAULT_VERIFIED_COHORT_NAME):
     """ Create a verified cohort. """
     add_cohort(self.course.id, name, CourseCohort.MANUAL)
Example #6
0
 def _create_named_random_cohort(self, name):
     """ Create a random cohort with the supplied name. """
     return add_cohort(self.course.id, name, CourseCohort.RANDOM)
Example #7
0
 def _create_verified_cohort(self):
     add_cohort(self.course.id, VERIFIED_COHORT_NAME, CourseCohort.MANUAL)
    def handle(self, *args, **options):

        self.stdout.write('### Checking CourseUserGroup group types\n')
        error = False
        for course_group in CourseUserGroup.objects.all():
            if course_group.group_type != CourseUserGroup.COHORT:
                if options['fix']:
                    self.stdout.write(
                        'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})\n'.format(
                            course_group.name, course_group.group_type)
                    )
                    course_group.group_type = CourseUserGroup.COHORT
                    course_group.save()
                else:
                    error = True
                    self.stdout.write(
                        'CourseUserGroup with an invalid group_type found: {} (type: {})\n'.format(
                            course_group.name, course_group.group_type)
                    )

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write('\n### Checking user cohorts\n')
        error = False
        users = User.objects.all()
        _courses = modulestore().get_courses()
        courses = [c for c in _courses if isinstance(c, CourseDescriptor)]
        # for each course, check if users are in atleast and only 1 cohort
        for course in courses:
            for user in users:
                if not CourseEnrollment.is_enrolled(user, course.id):
                    continue
                try:
                    CourseUserGroup.objects.get(course_id=course.id,
                                                users__id=user.id)
                except CourseUserGroup.DoesNotExist:
                    if options['fix']:
                        # create a "default_cohort" is it doesn't already exist
                        try:
                            default_cohort = get_cohort_by_name(course.id, CourseUserGroup.default_cohort_name)
                        except CourseUserGroup.DoesNotExist:
                            default_cohort = add_cohort(
                                course.id, CourseUserGroup.default_cohort_name, CourseCohort.RANDOM
                            )
                            self.stdout.write(
                                'Default cohort "{}" created for course "{}"'.format(
                                    default_cohort.name, course.display_name
                                )
                            )
                        add_user_to_cohort(default_cohort, user.username)
                        self.stdout.write(
                            'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort\n'.format(
                                user.username, course.display_name, default_cohort.name)
                        )
                    else:
                        error = True
                        self.stdout.write(
                            'User "{}" is not in a cohort in course "{}".\n'.format(
                                user.username, course.display_name)
                        )
                except MultipleObjectsReturned:
                    self.stdout.write(
                        'User "{}" is in multiple cohorts in course "{}".\n'.format(
                            user.username, course.display_name)
                    )
                    if options['fix']:
                        user_cohorts = CourseUserGroup.objects.filter(course_id=course.id,
                                                                      users__id=user.id).all()
                        for cohort in user_cohorts[1:]:
                            remove_user_from_cohort(cohort, user.username)
                            self.stdout.write(
                                "User '{}' has been removed from cohort '{}' in course '{}'.\n".format(
                                    user.username, cohort.name, course.display_name
                                )
                            )
                        self.stdout.write(
                            "User '{}' is now only in cohort '{}' in course '{}'.\n".format(
                                # pylint: disable=undefined-loop-variable
                                user.username, cohort.name, course.display_name
                            )
                        )
                    else:
                        error = True

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write('\nTo fix issues, run the script with the "--fix" option.\n')
 def _create_verified_cohort(self, name=DEFAULT_VERIFIED_COHORT_NAME):
     """ Create a verified cohort. """
     add_cohort(self.course.id, name, CourseCohort.MANUAL)
    def post(self, request):
        log.info(request.data)
        username = request.data.get('username')
        try:
            user = User.objects.get(username=username)
        except ObjectDoesNotExist:
            log.error(u"User {username} does not exist".format(username=username))
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"User {username} does not exist".format(username=username)}
            )

        course_id = request.data.get('course_id')
        if not course_id:
            log.error(u"Course ID must be specified to create a new enrollment.")
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            log.error(u"No course '{course_id}' found for enrollment".format(course_id=course_id))
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        course_is_cohorted = is_course_cohorted(course_key)
        if not course_is_cohorted:
            log.info(u"Course {course_id} is not cohorted.".format(course_id=course_id))
            return Response(
                status=status.HTTP_200_OK,
                data={"message": u"Course {course_id} is not cohorted.".format(course_id=course_id)}
            )

        action = request.data.get('action')
        if action not in [u'add', u'delete']:
            log.error(u"Available actions are 'add' and 'delete'.")
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Available actions are 'add' and 'delete'."}
            )

        cohort_exists = is_cohort_exists(course_key, VERIFIED)
        if not cohort_exists:
            if action == u'add':
                log.info(u"Cohort VERIFIED doesn't exist for course {} so let's create it!".format(course_id))
                cohort = add_cohort(course_key, VERIFIED, 'manual')
                log.info(u"Cohort VEIFIED created for the course {}".format(course_id))
            else:
                log.info(u"There aren't cohort verified for {course_id}".format(course_id=course_id))
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"There aren't cohort verified for {course_id}".format(course_id=course_id)}
                )
        else:
            cohort = get_cohort_by_name(course_key, VERIFIED)

        enrollment = CourseEnrollment.objects.get(
            user__username=username, course_id=course_key
        )
        if not enrollment or not enrollment.is_active:
            if action == u'add':
                log.error(u"Failed to add user into verified cohort. User {username} not enrolled or unenrolled in course {course_id}.".format(username=username, course_id=course_id))
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": u"User {username} not enrolled or unenrolled in course {course_id}.".format(
                        username=username,
                        course_id=course_id
                    )}
                )
            if action == u'delete':
                if not enrollment:
                    log.info(u"User {username} is not enrolled in course {course_id}. (!!!)".format(username=username, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={"message": u"User {username} is not enrolled in course {course_id}. (!!!)".format(
                            username=username,
                            course_id=course_id
                        )}
                    )
                else:
                    log.info(u"User {username} was unenrolled from course {course_id}.".format(username=username, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={"message": u"User {username} was unenrolled from course {course_id}.".format(
                            username=username,
                            course_id=course_id
                        )}
                    )

        course_cohorts = CourseUserGroup.objects.filter(
            course_id=course_key,
            users__id=user.id,
            group_type=CourseUserGroup.COHORT
        )

        default_group = None
        for group in CourseUserGroup.objects.filter(course_id=course_key, group_type=CourseUserGroup.COHORT):
            if group.name.lower() == "default" or group.name.lower() == "default group":
                default_group = group
        if not default_group:
            log.info(u"Cohort DEFAULT doesn't exist for course {} so let's create it!".format(course_id))
            default_group = add_cohort(course_key, "Default Group", 'random')
            log.info(u"Cohort 'Default Group' succesfully created for the course {}".format(course_id))

        # remove user from verified cohort and add to default
        if action == u'delete':
            # let's check, that user not already presented into other cohort
            if course_cohorts.exists():
                if course_cohorts.first().name == default_group.name:
                    log.warning(
                        u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(
                            username=username, cohort_name=default_group.name, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={
                            "message": u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(
                                username=username,
                                cohort_name=default_group.name,
                                course_id=course_id
                            )}
                    )
                elif course_cohorts.first().name == VERIFIED:
                    try:
                        add_user_to_cohort(default_group, username)
                        log.info(
                            u"User {username} succesfully moved into default cohort {cohort_name} in course {course_id}".format(
                                username=username, cohort_name=default_group.name, course_id=course_id))
                    except ValueError:
                        log.warning(
                            u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(
                                username=username, cohort_name=default_group.name, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={
                            "message": u"User {username} moved into default cohort {cohort_name} in course {course_id}".format(
                                username=username,
                                cohort_name=default_group.name,
                                course_id=course_id
                            )}
                    )
                else:
                    log.warning(u"Moving user {username} into default cohort {cohort_name} from verified in course {course_id}".format(username=username, cohort_name=default_group.name, course_id=course_id))
                    try:
                        add_user_to_cohort(default_group, username)
                        log.info(u"User {username} succesfully moved into default cohort {cohort_name} in course {course_id}".format(username=username, cohort_name=default_group.name, course_id=course_id))
                    except ValueError:
                        log.warning(u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(username=username, cohort_name=default_group.name, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={"message": u"User {username} already present in non-verified cohort {cohort_name} in course {course_id}".format(
                                username=username, cohort_name=course_cohorts.first().name, course_id=course_id
                        )}
                    )

        if action == u"add":
            message = add_user_into_verified_cohort(course_cohorts, cohort, user)
            if not message:
                message = u"User {username} added to cohort {cohort_name} into course {course_id}".format(username=user.username, cohort_name=cohort.name, course_id=course_id)
            log.info(message)
            return Response(
                status=status.HTTP_200_OK,
                data={"message":message}
            )
    def post(self, request):
        """
        Enrolls the list of users in a verified course mode.
        """
        # Get the users, Course ID, and Mode from the request.

        users = request.data.get('users', [])

        if len(users) == 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Users must be specified to create a new enrollment."}
            )

        course_id = request.data.get('course_details', {}).get('course_id')

        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)}
            )

        # use verified course mode by default
        mode = request.data.get('mode', CourseMode.VERIFIED)

        bad_users = []
        list_users = []
        for username in users:
            try:
                user = User.objects.get(username=username)
                list_users.append(user)
            except ObjectDoesNotExist:
                bad_users.append(username)

        if len(bad_users) > 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={'message': u'Users: {} does not exist.'.format(', '.join(bad_users))}
            )

        for user in list_users:
            embargo_response = embargo_api.get_embargo_response(request, course_key, user)

            if embargo_response:
                return embargo_response

        current_username = None
        try:
            is_active = request.data.get('is_active')
            # Check if the requested activation status is None or a Boolean
            if is_active is not None and not isinstance(is_active, bool):
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={'message': u"'{value}' is an invalid enrollment activation status.".format(value=is_active)}
                )

            enrollment_attributes = request.data.get('enrollment_attributes')
            errors = False
            already_paid = []  # list of users with verified enrollment
            not_enrolled = []  # list of not enrolled yet or unenrolled users
            for username in users:
                current_username = username
                enrollment = api.get_enrollment(username, unicode(course_key))
                if not enrollment:
                    not_enrolled.append(username)
                elif enrollment['is_active'] is not True:
                    not_enrolled.append(username)
                elif enrollment['mode'] == CourseMode.VERIFIED:
                    already_paid.append(username)
            msg_paid = u""
            msg_not_enrolled = u""
            if len(already_paid) > 0:
                msg_paid = u'Users: {} already paid for course.'.format(', '.join(already_paid))
                errors = True
            if len(not_enrolled) > 0:
                msg_not_enrolled = u'Users: {} not enrolled for course.'.format(', '.join(not_enrolled))
                errors = True
            if errors:
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": (u"'{course_id}'\n:{msg_paid}\n{msg_not_enrolled}").format(
                        course_id=course_id,
                        msg_paid=msg_paid,
                        msg_not_enrolled=msg_not_enrolled
                    ),
                    })

            # update for cohorts
            cohort_exists = is_cohort_exists(course_key, VERIFIED)
            if not cohort_exists:
                cohort = add_cohort(course_key, VERIFIED, 'manual')
            else:
                cohort = get_cohort_by_name(course_key, VERIFIED)

            for username in users:
                current_username = username
                api.update_enrollment(username, unicode(course_key), mode=mode, is_active=is_active)
                user = User.objects.get(username=username)
                course_cohorts = CourseUserGroup.objects.filter(
                    course_id=cohort.course_id,
                    users__id=user.id,
                    group_type=CourseUserGroup.COHORT
                )

                add_user_into_verified_cohort(course_cohorts, cohort, user)

            email_opt_in = request.data.get('email_opt_in', None)
            if email_opt_in is not None:
                org = course_key.org
                for username in users:
                    update_email_opt_in(username, org, email_opt_in)

            return Response(
                status=status.HTTP_200_OK,
                data={
                    "message": u"Success for course '{course_id}'.".format(course_id=course_id)
                })
        except CourseModeNotFoundError as error:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"The course mode '{mode}' is not available for course '{course_id}'."
                    ).format(mode="verified", course_id=course_id),
                    "course_details": error.data
                })
        except CourseEnrollmentExistsError as error:
            return Response(data=error.enrollment)
        except CourseEnrollmentError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while creating the new course enrollment for user "
                        u"'{username}' in course '{course_id}'"
                    ).format(username=current_username, course_id=course_id)
                }
            )
Example #12
0
    def users(self, request, pk):
        """
        Add a User to a Workgroup
        """
        if request.method == 'GET':
            users = User.objects.filter(workgroups=pk)
            response_data = []
            if users:
                for user in users:
                    serializer = UserSerializer(user,
                                                context={'request': request})
                    response_data.append(serializer.data)  # pylint: disable=E1101
            return Response(response_data, status=status.HTTP_200_OK)
        elif request.method == 'POST':
            user_id = request.data.get('id')
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = 'User {} does not exist'.format(user_id)
                return Response({"detail": message},
                                status.HTTP_400_BAD_REQUEST)

            workgroup = self.get_object()

            # Ensure the user is not already assigned to a project for this course
            existing_projects = Project.objects.filter(
                course_id=workgroup.project.course_id).filter(
                    workgroups__users__id=user.id)
            if len(existing_projects):
                message = 'User {} already assigned to a project for this course'.format(
                    user_id)
                return Response({"detail": message},
                                status.HTTP_400_BAD_REQUEST)

            try:
                workgroup.add_user(user)
            except ValidationError as e:
                return Response({"detail": unicode(e)},
                                status.HTTP_400_BAD_REQUEST)

            workgroup.save()

            # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy
            # workgroup)
            course_key = get_course_key(workgroup.project.course_id)
            try:
                cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
                add_user_to_cohort(cohort, user.username)
            except ObjectDoesNotExist:
                # This use case handles cases where a workgroup might have been created before
                # the notion of a cohorted discussion. So we need to backfill in the data
                assignment_type = request.data.get('assignment_type',
                                                   CourseCohort.RANDOM)
                if assignment_type not in dict(
                        CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
                    message = "Not a valid assignment type, '{}'".format(
                        assignment_type)
                    return Response({"detail": message},
                                    status.HTTP_400_BAD_REQUEST)
                workgroup = self.get_object()
                cohort = add_cohort(course_key, workgroup.cohort_name,
                                    assignment_type)
                for workgroup_user in workgroup.users.all():
                    add_user_to_cohort(cohort, workgroup_user.username)
            return Response({}, status=status.HTTP_201_CREATED)
        else:
            user_id = request.data.get('id')
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = 'User {} does not exist'.format(user_id)
                return Response({"detail": message},
                                status.HTTP_400_BAD_REQUEST)
            workgroup = self.get_object()
            course_key = get_course_key(workgroup.project.course_id)
            cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
            workgroup.remove_user(user)
            remove_user_from_cohort(cohort, user.username)
            return Response({}, status=status.HTTP_204_NO_CONTENT)
Example #13
0
    def post(self, request):
        username = request.DATA.get('username')
        try:
            user = User.objects.get(username=username)
        except ObjectDoesNotExist:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"User {username} does not exist".format(username=username)}
            )

        course_id = request.DATA.get('course_id')
        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        course_is_cohorted = is_course_cohorted(course_key)
        if not course_is_cohorted:
            return Response(
                status=status.HTTP_200_OK,
                data={"message": u"Course {course_id} is not cohorted.".format(course_id=course_id)}
            )

        action = request.DATA.get('action')
        if action not in [u'add', u'delete']:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Available actions are 'add' and 'delete'."}
            )

        cohort_exists = is_cohort_exists(course_key, VERIFIED)
        if not cohort_exists:
            if action == u'add':
                cohort = add_cohort(course_key, VERIFIED, 'manual')
            else:
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"There aren't cohort verified for {course_id}".format(course_id=course_id)}
                )
        else:
            cohort = get_cohort_by_name(course_key, VERIFIED)

        enrollment = CourseEnrollment.objects.get(
            user__username=username, course_id=course_key
        )
        if not enrollment or not enrollment.is_active:
            if action == u'add':
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": u"User {username} not enrolled or unenrolled in course {course_id}.".format(
                        username=username,
                        course_id=course_id
                    )}
                )
            if action == u'delete':
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} not enrolled or unenrolled in course {course_id}.".format(
                        username=username,
                        course_id=course_id
                    )}
                )

        course_cohorts = CourseUserGroup.objects.filter(
            course_id=course_key,
            users__id=user.id,
            group_type=CourseUserGroup.COHORT
        )

        # remove user from verified cohort
        if action == u'delete':
            if not course_cohorts.exists() or course_cohorts[0].name != cohort.name:
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} already was removed from cohort {cohort_name}".format(
                        username=username,
                        cohort_name=cohort.name
                    )}
                )
            else:
                cohort.users.remove(user)
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} removed from cohort {cohort_name}".format(
                        username=username,
                        cohort_name=cohort.name
                    )}
                )

        if course_cohorts.exists():
            if course_cohorts[0] == cohort:
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} already present in cohort {cohort_name}".format(
                        username=username,
                        cohort_name=cohort.name
                    )}
                )

        add_user_into_verified_cohort(course_cohorts, cohort, user)

        return Response(
            status=status.HTTP_200_OK,
            data={"message": u"User {username} added to cohort {cohort_name}".format(
                username=user.username,
                cohort_name=cohort.name
            )}
        )
Example #14
0
    def post(self, request):
        """
        Enrolls the list of users in a verified course mode.
        """
        # Get the users, Course ID, and Mode from the request.

        users = request.DATA.get('users', [])

        if len(users) == 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Users must be specified to create a new enrollment."}
            )

        course_id = request.DATA.get('course_details', {}).get('course_id')

        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)}
            )

        # use verified course mode by default
        mode = request.DATA.get('mode', CourseMode.VERIFIED)

        bad_users = []
        list_users = []
        for username in users:
            try:
                user = User.objects.get(username=username)
                list_users.append(user)
            except ObjectDoesNotExist:
                bad_users.append(username)

        if len(bad_users) > 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={'message': u'Users: {} does not exist.'.format(', '.join(bad_users))}
            )

        for user in list_users:
            embargo_response = embargo_api.get_embargo_response(request, course_key, user)

            if embargo_response:
                return embargo_response

        current_username = None
        try:
            is_active = request.DATA.get('is_active')
            # Check if the requested activation status is None or a Boolean
            if is_active is not None and not isinstance(is_active, bool):
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={'message': u"'{value}' is an invalid enrollment activation status.".format(value=is_active)}
                )

            enrollment_attributes = request.DATA.get('enrollment_attributes')
            errors = False
            already_paid = []  # list of users with verified enrollment
            not_enrolled = []  # list of not enrolled yet or unenrolled users
            for username in users:
                current_username = username
                enrollment = api.get_enrollment(username, unicode(course_key))
                if not enrollment:
                    not_enrolled.append(username)
                elif enrollment['is_active'] is not True:
                    not_enrolled.append(username)
                elif enrollment['mode'] == CourseMode.VERIFIED:
                    already_paid.append(username)
            msg_paid = u""
            msg_not_enrolled = u""
            if len(already_paid) > 0:
                msg_paid = u'Users: {} already paid for course.'.format(', '.join(already_paid))
                errors = True
            if len(not_enrolled) > 0:
                msg_not_enrolled = u'Users: {} not enrolled for course.'.format(', '.join(not_enrolled))
                errors = True
            if errors:
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": (u"'{course_id}'\n:{msg_paid}\n{msg_not_enrolled}").format(
                        course_id=course_id,
                        msg_paid=msg_paid,
                        msg_not_enrolled=msg_not_enrolled
                    ),
                    })

            # update for cohorts
            cohort_exists = is_cohort_exists(course_key, VERIFIED)
            if not cohort_exists:
                cohort = add_cohort(course_key, VERIFIED, 'manual')
            else:
                cohort = get_cohort_by_name(course_key, VERIFIED)

            for username in users:
                current_username = username
                api.update_enrollment(username, unicode(course_key), mode=mode, is_active=is_active)
                user = User.objects.get(username=username)
                course_cohorts = CourseUserGroup.objects.filter(
                    course_id=cohort.course_id,
                    users__id=user.id,
                    group_type=CourseUserGroup.COHORT
                )

                add_user_into_verified_cohort(course_cohorts, cohort, user)

            email_opt_in = request.DATA.get('email_opt_in', None)
            if email_opt_in is not None:
                org = course_key.org
                for username in users:
                    update_email_opt_in(username, org, email_opt_in)

            return Response(
                status=status.HTTP_200_OK,
                data={
                    "message": u"Success for course '{course_id}'.".format(course_id=course_id)
                })
        except CourseModeNotFoundError as error:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"The course mode '{mode}' is not available for course '{course_id}'."
                    ).format(mode="verified", course_id=course_id),
                    "course_details": error.data
                })
        except CourseNotFoundError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        except CourseEnrollmentExistsError as error:
            return Response(data=error.enrollment)
        except CourseEnrollmentError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while creating the new course enrollment for user "
                        u"'{username}' in course '{course_id}'"
                    ).format(username=current_username, course_id=course_id)
                }
            )
Example #15
0
 def _create_named_random_cohort(self, name):
     return add_cohort(self.course.id, name, CourseCohort.RANDOM)
Example #16
0
 def _create_verified_cohort(self):
     add_cohort(self.course.id, VERIFIED_COHORT_NAME, CourseCohort.MANUAL)
Example #17
0
 def _create_named_random_cohort(self, name):
     return add_cohort(self.course.id, name, CourseCohort.RANDOM)
 def _create_named_random_cohort(self, name):
     """ Create a random cohort with the supplied name. """
     return add_cohort(self.course.id, name, CourseCohort.RANDOM)
    def handle(self, *args, **options):

        self.stdout.write('### Checking CourseUserGroup group types\n')
        error = False
        for course_group in CourseUserGroup.objects.all():
            if course_group.group_type != CourseUserGroup.COHORT:
                if options['fix']:
                    self.stdout.write(
                        'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})\n'
                        .format(course_group.name, course_group.group_type))
                    course_group.group_type = CourseUserGroup.COHORT
                    course_group.save()
                else:
                    error = True
                    self.stdout.write(
                        'CourseUserGroup with an invalid group_type found: {} (type: {})\n'
                        .format(course_group.name, course_group.group_type))

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write('\n### Checking user cohorts\n')
        error = False
        users = User.objects.all()
        _courses = modulestore().get_courses()
        courses = [c for c in _courses if isinstance(c, CourseDescriptor)]
        # for each course, check if users are in atleast and only 1 cohort
        for course in courses:
            for user in users:
                if not CourseEnrollment.is_enrolled(user, course.id):
                    continue
                try:
                    CourseUserGroup.objects.get(course_id=course.id,
                                                users__id=user.id)
                except CourseUserGroup.DoesNotExist:
                    if options['fix']:
                        # create a "default_cohort" is it doesn't already exist
                        try:
                            default_cohort = get_cohort_by_name(
                                course.id, CourseUserGroup.default_cohort_name)
                        except CourseUserGroup.DoesNotExist:
                            default_cohort = add_cohort(
                                course.id, CourseUserGroup.default_cohort_name,
                                CourseCohort.RANDOM)
                            self.stdout.write(
                                'Default cohort "{}" created for course "{}"'.
                                format(default_cohort.name,
                                       course.display_name))
                        add_user_to_cohort(default_cohort, user.username)
                        self.stdout.write(
                            'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort\n'
                            .format(user.username, course.display_name,
                                    default_cohort.name))
                    else:
                        error = True
                        self.stdout.write(
                            'User "{}" is not in a cohort in course "{}".\n'.
                            format(user.username, course.display_name))
                except MultipleObjectsReturned:
                    self.stdout.write(
                        'User "{}" is in multiple cohorts in course "{}".\n'.
                        format(user.username, course.display_name))
                    if options['fix']:
                        user_cohorts = CourseUserGroup.objects.filter(
                            course_id=course.id, users__id=user.id).all()
                        for cohort in user_cohorts[1:]:
                            remove_user_from_cohort(cohort, user.username)
                            self.stdout.write(
                                "User '{}' has been removed from cohort '{}' in course '{}'.\n"
                                .format(user.username, cohort.name,
                                        course.display_name))
                        self.stdout.write(
                            "User '{}' is now only in cohort '{}' in course '{}'.\n"
                            .format(
                                # pylint: disable=undefined-loop-variable
                                user.username,
                                cohort.name,
                                course.display_name))
                    else:
                        error = True

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write(
            '\nTo fix issues, run the script with the "--fix" option.\n')