edx-enterprise icon indicating copy to clipboard operation
edx-enterprise copied to clipboard

Admins cannot enroll enterprise learners to "Invite Only" courses

Open tecoholic opened this issue 1 year ago • 0 comments

Description

The "Manage Learners" page of an enterprise customer should ideally provide the same UX as the "Instructor" > "Membership" when it comes to enrollment when used by users with staff rights. However, this is not the case when it comes to the "Invite Only" courses. Trying to invite users to "Invite Only" courses works only on the LMS and errors out in the "Manage Learners" page.

Steps to reproduce

  1. Set up devstack with dev.provision.lms+studio+discovery+ecommerce and run using dev.up....
  2. Set up enterprise-catalog
  3. Create some enterprise test data using make lms-shell and ./manage.py lms seed_enterprise_devstack_data

The following steps are for creating a new course to verify the bug. But you could also do the test using the default "Demo Course". In that case, feel free to skip the following steps and jump the next section.

  1. Create a course in studio and mark it "Invite Only" = true in "Advanced Settings"
  2. Set the course start date before the current date and end date after current date
  3. In the LMS Admin, add a "Course Mode" like "Honor" or "Professional" for the course
  4. Fetch the details to discovery using make discovery-shell and ./manage.py refresh_course_metadata
  5. Go to the course runs admin page on discovery and edit the course run and ensure type is not "Empty" and set it to the same as the "Course Mode" from the previous step
  6. Drop into discovery shell and update the index using make discovery-shell and ./manage.py update_index --disable-change-limit. Verify that the output says a NON ZERO number of course runs were indexed.
  7. Drop into the catalog shell make app-shell and update the enterprise-catalog's data /manage.py update_content_metadata --force
  8. Open the enterprise catalog admin and verify that the test catalog is available and content metadata for the "course run" of the course we created above is available.

Once the course run is setup and made a part of the "Test Enterprise"'s catalog:

Open course

  1. Go to Enterprise Customers page > "Test Customer" > "Manage Learners"
  2. Enter the email of an existing user, for example: [email protected] and the course ID of the course to test, select the course enrollment track, enter a reason like Testing and click Submit.
  3. The request would succeed and a message show up on the top.

Invite Only

  1. Now go the course's "Advanced Settings" in the studio, and mark "Invite Only" value to true and save.
  2. Switch to the "Manage Learners" page
  3. Try enrolling another user in the same course as above, this would result in the "Internal Server Erorr'

image

The error in the logs:

edx.devstack.lms                  | 2023-05-05 11:10:05,280 ERROR 1074 [openedx.core.djangoapps.enrollments.views] [user 4] [ip 172.23.0.9] views.py:864 - An error occurred while creating the new course enrollment for user [test-enterprise_learner_1] in course run [course-v1:ENT+ENT101+2023]
edx.devstack.lms                  | Traceback (most recent call last):
edx.devstack.lms                  |   File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/enrollments/data.py", line 151, in create_course_enrollment
edx.devstack.lms                  |     enrollment = CourseEnrollment.enroll(
edx.devstack.lms                  |   File "/edx/app/edxapp/edx-platform/common/djangoapps/student/models/course_enrollment.py", line 696, in enroll
edx.devstack.lms                  |     raise EnrollmentClosedError
edx.devstack.lms                  | common.djangoapps.student.models.course_enrollment.EnrollmentClosedError
edx.devstack.lms                  |
edx.devstack.lms                  | During handling of the above exception, another exception occurred:
edx.devstack.lms                  |
edx.devstack.lms                  | Traceback (most recent call last):
edx.devstack.lms                  |   File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/enrollments/views.py", line 817, in post
edx.devstack.lms                  |     response = api.add_enrollment(
edx.devstack.lms                  |   File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/enrollments/api.py", line 265, in add_enrollment
edx.devstack.lms                  |     enrollment = _data_api().create_course_enrollment(
edx.devstack.lms                  |   File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/enrollments/data.py", line 158, in create_course_enrollment
edx.devstack.lms                  |     raise CourseEnrollmentClosedError(str(err))  # lint-amnesty, pylint: disable=raise-missing-from
edx.devstack.lms                  | openedx.core.djangoapps.enrollments.errors.CourseEnrollmentClosedError
edx.devstack.lms                  | [05/May/2023 11:10:05] "POST /api/enrollment/v1/enrollment HTTP/1.1" 400 147
edx.devstack.lms                  | 2023-05-05 11:10:05,296 ERROR 1074 [root] [user None] [ip None] signals.py:22 - Uncaught exception from None
edx.devstack.lms                  | Traceback (most recent call last):
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
edx.devstack.lms                  |     response = get_response(request)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
edx.devstack.lms                  |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
edx.devstack.lms                  |   File "/usr/lib/python3.8/contextlib.py", line 75, in inner
edx.devstack.lms                  |     return func(*args, **kwds)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
edx.devstack.lms                  |     response = view_func(request, *args, **kwargs)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
edx.devstack.lms                  |     response = view_func(request, *args, **kwargs)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 232, in inner
edx.devstack.lms                  |     return view(request, *args, **kwargs)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
edx.devstack.lms                  |     return self.dispatch(request, *args, **kwargs)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
edx.devstack.lms                  |     return handler(request, *args, **kwargs)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/enterprise/admin/views.py", line 826, in post
edx.devstack.lms                  |     self._enroll_users(
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/enterprise/admin/views.py", line 696, in _enroll_users
edx.devstack.lms                  |     succeeded, pending, failed = enroll_users_in_course(
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/enterprise/utils.py", line 2091, in enroll_users_in_course
edx.devstack.lms                  |     succeeded = enroll_user(enterprise_customer, user, course_mode, course_id)
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/enterprise/utils.py", line 1719, in enroll_user
edx.devstack.lms                  |     enrollment_client.enroll_user_in_course(
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/enterprise/api_client/lms.py", line 158, in enroll_user_in_course
edx.devstack.lms                  |     response.raise_for_status()
edx.devstack.lms                  |   File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/requests/models.py", line 1021, in raise_for_status
edx.devstack.lms                  |     raise HTTPError(http_error_msg, response=self)
edx.devstack.lms                  | requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http://edx.devstack.lms:18000/api/enrollment/v1/enrollment
edx.devstack.lms                  | Internal Server Error: /admin/enterprise/enterprisecustomer/0e528e21-cdc0-45d8-a02b-e5829930e289/manage_learners

Expected behaviour

The learner should be enrolled in the course and the intimation email sent to them.

tecoholic avatar May 05 '23 12:05 tecoholic