Exemple #1
0
    def patch(self, request, **kwargs):
        """
        Modify the program enrollments for a list of learners
        """
        if len(request.data) > MAX_ENROLLMENT_RECORDS:
            return Response(
                status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                content_type='application/json',
            )

        program_uuid = kwargs['program_uuid']
        student_data = self._request_data_by_student_key(request, program_uuid)
        if None in student_data:
            return Response('invalid enrollment record',
                            status.HTTP_422_UNPROCESSABLE_ENTITY)

        response_data = {}
        response_data.update(
            self._remove_duplicate_entries(request, student_data))

        existing_enrollments = {
            enrollment.external_user_key: enrollment
            for enrollment in ProgramEnrollment.bulk_read_by_student_key(
                program_uuid, student_data)
        }

        enrollments_to_create = {}

        for external_user_key in student_data.keys():
            if external_user_key not in existing_enrollments:
                student_data.pop(external_user_key)
                response_data[
                    external_user_key] = CourseEnrollmentResponseStatuses.NOT_IN_PROGRAM

        for external_user_key, enrollment in existing_enrollments.items():
            student = {
                key: value
                for key, value in student_data[external_user_key].items()
                if key == 'status'
            }
            enrollment_serializer = ProgramEnrollmentSerializer(enrollment,
                                                                data=student,
                                                                partial=True)
            if enrollment_serializer.is_valid():
                enrollments_to_create[(
                    external_user_key,
                    enrollment.curriculum_uuid)] = enrollment_serializer
                enrollment_serializer.save()
                response_data[external_user_key] = student['status']
            else:
                serializer_is_invalid = enrollment_serializer.errors['status'][
                    0].code == 'invalid_choice'
                if 'status' in enrollment_serializer.errors and serializer_is_invalid:
                    response_data[
                        external_user_key] = CourseEnrollmentResponseStatuses.INVALID_STATUS

        return self._get_created_or_updated_response(request,
                                                     enrollments_to_create,
                                                     response_data,
                                                     status.HTTP_200_OK)
Exemple #2
0
    def post(self, request, *args, **kwargs):
        """
        Create program enrollments for a list of learners
        """
        if len(request.data) > MAX_ENROLLMENT_RECORDS:
            return Response(
                status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                content_type='application/json',
            )

        program_uuid = kwargs['program_uuid']
        student_data = self._request_data_by_student_key(request, program_uuid)
        if None in student_data:
            return Response('invalid enrollment record',
                            status.HTTP_422_UNPROCESSABLE_ENTITY)

        response_data = {}
        response_data.update(
            self._remove_duplicate_entries(request, student_data))
        response_data.update(
            self._remove_existing_entries(program_uuid, student_data))

        enrollments_to_create = {}

        for student_key, data in student_data.items():
            curriculum_uuid = data['curriculum_uuid']

            try:
                existing_user = get_user_by_program_id(student_key,
                                                       program_uuid)
                if existing_user:
                    data['user'] = existing_user.id
            except ProviderDoesNotExistException:
                pass  # IDP has not yet been set up, just create waiting enrollments

            serializer = ProgramEnrollmentSerializer(data=data)
            if serializer.is_valid():
                enrollments_to_create[(student_key,
                                       curriculum_uuid)] = serializer
                response_data[student_key] = data.get('status')
            else:
                if 'status' in serializer.errors and serializer.errors[
                        'status'][0].code == 'invalid_choice':
                    response_data[
                        student_key] = CourseEnrollmentResponseStatuses.INVALID_STATUS
                else:
                    return Response('invalid enrollment record',
                                    status.HTTP_422_UNPROCESSABLE_ENTITY)

        # TODO: make this a bulk save - https://openedx.atlassian.net/browse/EDUCATOR-4305
        for (student_key,
             _), enrollment_serializer in enrollments_to_create.items():
            enrollment_serializer.save()

        return self._get_created_or_updated_response(request,
                                                     enrollments_to_create,
                                                     response_data)
Exemple #3
0
    def post(self, request, *args, **kwargs):
        """
        Create program enrollments for a list of learners
        """
        if len(request.data) > MAX_ENROLLMENT_RECORDS:
            return Response(
                status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                content_type='application/json',
            )

        program_uuid = kwargs['program_uuid']
        student_data = self._request_data_by_student_key(request, program_uuid)

        response_data = {}
        response_data.update(self._remove_duplicate_entries(request, student_data))
        response_data.update(self._remove_existing_entries(program_uuid, student_data))

        enrollments_to_create = {}

        for student_key, data in student_data.items():
            curriculum_uuid = data['curriculum_uuid']
            existing_user = get_user_by_program_id(student_key, program_uuid)

            if existing_user:
                data['user'] = existing_user.id

            serializer = ProgramEnrollmentSerializer(data=data)
            if serializer.is_valid():
                enrollments_to_create[(student_key, curriculum_uuid)] = serializer
                response_data[student_key] = data.get('status')
            else:
                if 'status' in serializer.errors and serializer.errors['status'][0].code == 'invalid_choice':
                    response_data[student_key] = CourseEnrollmentResponseStatuses.INVALID_STATUS
                else:
                    return Response(
                        'invalid enrollment record',
                        status.HTTP_422_UNPROCESSABLE_ENTITY
                    )

        # TODO: make this a bulk save - https://openedx.atlassian.net/browse/EDUCATOR-4305
        for (student_key, _), enrollment_serializer in enrollments_to_create.items():
            enrollment_serializer.save()

        return self._get_created_or_updated_response(request, enrollments_to_create, response_data)
Exemple #4
0
    def patch(self, request, **kwargs):
        """
        Modify the program enrollments for a list of learners
        """
        if len(request.data) > MAX_ENROLLMENT_RECORDS:
            return Response(
                status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                content_type='application/json',
            )

        program_uuid = kwargs['program_uuid']
        student_data = self._request_data_by_student_key(request, program_uuid)

        response_data = {}
        response_data.update(self._remove_duplicate_entries(request, student_data))

        existing_enrollments = {
            enrollment.external_user_key: enrollment
            for enrollment in
            ProgramEnrollment.bulk_read_by_student_key(program_uuid, student_data)
        }

        enrollments_to_create = {}

        for external_user_key in student_data.keys():
            if external_user_key not in existing_enrollments:
                student_data.pop(external_user_key)
                response_data[external_user_key] = CourseEnrollmentResponseStatuses.NOT_IN_PROGRAM

        for external_user_key, enrollment in existing_enrollments.items():
            student = {key: value for key, value in student_data[external_user_key].items() if key == 'status'}
            enrollment_serializer = ProgramEnrollmentSerializer(enrollment, data=student, partial=True)
            if enrollment_serializer.is_valid():
                enrollments_to_create[(external_user_key, enrollment.curriculum_uuid)] = enrollment_serializer
                enrollment_serializer.save()
                response_data[external_user_key] = student['status']
            else:
                serializer_is_invalid = enrollment_serializer.errors['status'][0].code == 'invalid_choice'
                if 'status' in enrollment_serializer.errors and serializer_is_invalid:
                    response_data[external_user_key] = CourseEnrollmentResponseStatuses.INVALID_STATUS

        return self._get_created_or_updated_response(request, enrollments_to_create, response_data, status.HTTP_200_OK)
Exemple #5
0
 def setUp(self):
     """
     Set up the test data used in the specific tests
     """
     super(ProgramEnrollmentSerializerTests, self).setUp()
     self.user = UserFactory.create()
     self.enrollment = ProgramEnrollment.objects.create(
         user=self.user,
         external_user_key='abc',
         program_uuid=uuid4(),
         curriculum_uuid=uuid4(),
         status='enrolled')
     self.serializer = ProgramEnrollmentSerializer(instance=self.enrollment)
Exemple #6
0
    def post(self, request, *args, **kwargs):
        """
        This is the POST for ProgramEnrollments
        """
        if len(request.data) > 25:
            return Response(
                status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                content_type='application/json',
            )

        program_uuid = kwargs['program_uuid']
        student_data = OrderedDict((
            row.get('external_user_key'),
            {
                'program_uuid': program_uuid,
                'curriculum_uuid': row.get('curriculum_uuid'),
                'status': row.get('status'),
                'external_user_key': row.get('external_user_key'),
            })
            for row in request.data
        )

        key_counter = Counter([enrollment.get('external_user_key') for enrollment in request.data])

        response_data = {}
        for student_key, count in key_counter.items():
            if count > 1:
                response_data[student_key] = CourseEnrollmentResponseStatuses.DUPLICATED
                student_data.pop(student_key)

        existing_enrollments = ProgramEnrollment.bulk_read_by_student_key(program_uuid, student_data)
        for enrollment in existing_enrollments:
            response_data[enrollment.external_user_key] = CourseEnrollmentResponseStatuses.CONFLICT
            student_data.pop(enrollment.external_user_key)

        enrollments_to_create = {}

        for student_key, data in student_data.items():
            curriculum_uuid = data['curriculum_uuid']
            existing_user = get_user_by_program_id(student_key, program_uuid)

            if existing_user:
                data['user'] = existing_user.id

            serializer = ProgramEnrollmentSerializer(data=data)
            if serializer.is_valid():
                enrollments_to_create[(student_key, curriculum_uuid)] = serializer
                response_data[student_key] = data.get('status')
            else:
                if 'status' in serializer.errors and serializer.errors['status'][0].code == 'invalid_choice':
                    response_data[student_key] = CourseEnrollmentResponseStatuses.INVALID_STATUS
                else:
                    return Response(
                        'invalid enrollment record',
                        status.HTTP_422_UNPROCESSABLE_ENTITY
                    )

        for enrollment_serializer in enrollments_to_create.values():
            # create the model
            enrollment_serializer.save()
            # TODO: make this a bulk save

        if not enrollments_to_create:
            return Response(
                status=status.HTTP_422_UNPROCESSABLE_ENTITY,
                data=response_data,
                content_type='application/json',
            )

        if len(request.data) != len(enrollments_to_create):
            return Response(
                status=status.HTTP_207_MULTI_STATUS,
                data=response_data,
                content_type='application/json',
            )

        return Response(
            status=status.HTTP_201_CREATED,
            data=response_data,
            content_type='application/json',
        )