def test_get_course_final_price(self, ecommerce_api_client_mock): mode = { 'sku': 'verified-sku', 'min_price': 200, 'original_price': 500, } self._setup_ecommerce_api_client(client_mock=ecommerce_api_client_mock, method_name='baskets.calculate.get', return_value={ 'total_incl_tax': 100, }) assert EcommerceApiClient( self.user).get_course_final_price(mode) == '$100'
def test_raise_error_missing_course_discovery_api(self): message = 'To get a ecommerce_api_client, this package must be installed in an Open edX environment.' with raises(NotConnectedToOpenEdX) as excinfo: EcommerceApiClient(mock.Mock(spec=User)) assert message == str(excinfo.value)
def enterprise_learners(self, request, pk): """ Creates a set of enterprise_learners by enrolling them in the specified course. """ enterprise_customer = self.get_object() serializer = serializers.EnterpriseCustomerBulkEnrollmentsSerializer( data=request.data, context={ 'enterprise_customer': enterprise_customer, 'request_user': request.user, }) if serializer.is_valid(raise_exception=True): singular_email = serializer.validated_data.get('email') emails = set() already_linked_emails = [] duplicate_emails = [] errors = [] if singular_email: emails.add(singular_email) try: for email in emails: try: already_linked = validate_email_to_link( email, ignore_existing=True) except ValidationError as error: errors.append(error) else: if already_linked: already_linked_emails.append( (email, already_linked.enterprise_customer)) elif email in emails: duplicate_emails.append(email) else: emails.add(email) except ValidationError as exc: errors.append(exc) if errors: return Response(errors, status=HTTP_400_BAD_REQUEST) for email in emails: models.EnterpriseCustomerUser.objects.link_user( enterprise_customer, email) course_run_key = serializer.validated_data.get('course_run_key') mode = serializer.validated_data.get('course_mode') if course_run_key: this_customer_linked_emails = [ email for email, customer in already_linked_emails if customer == enterprise_customer ] linked_learners = list(emails) + this_customer_linked_emails if linked_learners: discount = serializer.validated_data.get('discount', 0.0) enrollment_reason = serializer.validated_data.get('reason') succeeded, pending, _ = enroll_users_in_course( enterprise_customer=enterprise_customer, course_id=course_run_key, course_mode=mode, emails=emails, enrollment_requester=request.user, enrollment_reason=enrollment_reason, discount=discount, sales_force_id=serializer.validated_data.get( 'salesforce_id'), ) if serializer.validated_data.get('notify'): enterprise_customer.notify_enrolled_learners( catalog_api_user=request.user, course_id=course_run_key, users=succeeded + pending, ) paid_modes = ['verified', 'professional'] if mode in paid_modes: enrollments = [{ "lms_user_id": success.id, "email": success.email, "username": success.username, "course_run_key": course_run_key, "discount_percentage": float(discount), "enterprise_customer_name": enterprise_customer.name, "enterprise_customer_uuid": str(enterprise_customer.uuid), "mode": mode, "sales_force_id": serializer.validated_data.get('salesforce_id'), } for success in succeeded] EcommerceApiClient(get_ecommerce_worker_user( )).create_manual_enrollment_orders(enrollments) return Response(status=HTTP_202_ACCEPTED) return Response(status=HTTP_400_BAD_REQUEST)
def _enroll_users(cls, request, enterprise_customer, emails, mode, course_id=None, notify=True, enrollment_reason=None, sales_force_id=None, discount=0.0): """ Enroll the users with the given email addresses to the course. Args: cls (type): The EnterpriseCustomerManageLearnersView class itself request: The HTTP request the enrollment is being created by enterprise_customer: The instance of EnterpriseCustomer whose attached users we're enrolling emails: An iterable of strings containing email addresses to enroll in a course mode: The enrollment mode the users will be enrolled in the course with course_id: The ID of the course in which we want to enroll notify: Whether to notify (by email) the users that have been enrolled """ pending_messages = [] paid_modes = ['verified', 'professional'] succeeded, pending, failed = enroll_users_in_course( enterprise_customer=enterprise_customer, course_id=course_id, course_mode=mode, emails=sorted(emails), enrollment_requester=request.user, enrollment_reason=enrollment_reason, discount=discount, sales_force_id=sales_force_id, ) all_successes = succeeded + pending if notify: enterprise_customer.notify_enrolled_learners( catalog_api_user=request.user, course_id=course_id, users=all_successes, ) if succeeded: pending_messages.append( cls.get_success_enrollment_message(succeeded, course_id)) if failed: pending_messages.append( cls.get_failed_enrollment_message(failed, course_id)) if pending: pending_messages.append( cls.get_pending_enrollment_message(pending, course_id)) if mode in paid_modes: # Create an order to track the manual enrollments of non-pending accounts enrollments = [{ "lms_user_id": success.id, "email": success.email, "username": success.username, "course_run_key": course_id, "discount_percentage": float(discount), "enterprise_customer_name": enterprise_customer.name, "enterprise_customer_uuid": str(enterprise_customer.uuid), "mode": mode, "sales_force_id": sales_force_id, } for success in succeeded] EcommerceApiClient( get_ecommerce_worker_user()).create_manual_enrollment_orders( enrollments) cls.send_messages(request, pending_messages)
def _enroll_users( cls, request, enterprise_customer, emails, mode, course_id=None, program_details=None, notify=True, enrollment_reason=None ): """ Enroll the users with the given email addresses to the courses specified, either specifically or by program. Args: cls (type): The EnterpriseCustomerManageLearnersView class itself request: The HTTP request the enrollment is being created by enterprise_customer: The instance of EnterpriseCustomer whose attached users we're enrolling emails: An iterable of strings containing email addresses to enroll in a course mode: The enrollment mode the users will be enrolled in the course with course_id: The ID of the course in which we want to enroll program_details: Details about a program in which we want to enroll notify: Whether to notify (by email) the users that have been enrolled """ pending_messages = [] if course_id: succeeded, pending, failed = cls.enroll_users_in_course( enterprise_customer=enterprise_customer, course_id=course_id, course_mode=mode, emails=emails, enrollment_requester=request.user, enrollment_reason=enrollment_reason, ) all_successes = succeeded + pending if notify: enterprise_customer.notify_enrolled_learners( catalog_api_user=request.user, course_id=course_id, users=all_successes, ) if succeeded: pending_messages.append(cls.get_success_enrollment_message(succeeded, course_id)) if failed: pending_messages.append(cls.get_failed_enrollment_message(failed, course_id)) if pending: pending_messages.append(cls.get_pending_enrollment_message(pending, course_id)) if program_details: succeeded, pending, failed = cls.enroll_users_in_program( enterprise_customer=enterprise_customer, program_details=program_details, course_mode=mode, emails=emails, enrollment_requester=request.user, enrollment_reason=enrollment_reason, ) all_successes = succeeded + pending if notify: cls.notify_program_learners( enterprise_customer=enterprise_customer, program_details=program_details, users=all_successes ) program_identifier = program_details.get('title', program_details.get('uuid', _('the program'))) if succeeded: pending_messages.append(cls.get_success_enrollment_message(succeeded, program_identifier)) if failed: pending_messages.append(cls.get_failed_enrollment_message(failed, program_identifier)) if pending: pending_messages.append(cls.get_pending_enrollment_message(pending, program_identifier)) enrollments = [{ "lms_user_id": success.id, "email": success.email, "username": success.username, "course_run_key": course_id, } for success in succeeded] # Create an order to track the manual enrollments of non-pending accounts EcommerceApiClient(get_ecommerce_worker_user()).create_manual_enrollment_orders(enrollments) cls.send_messages(request, pending_messages)