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)
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)
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)
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)
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)
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', )