def Func(arg_0, arg_1, arg_2):
    """
    Get the data sharing consent object associated with a certain user of a customer for a course.

    :param username: The user that grants consent.
    :param course_id: The course for which consent is granted.
    :param enterprise_customer_uuid: The consent requester.
    :return: The data sharing consent object
    """
    # Prevent circular imports.
    arg_3 = apps.get_model('consent', 'DataSharingConsent')  # pylint: disable=invalid-name
    return arg_3.objects.proxied_get(
        arg_0=arg_0,
        arg_1=arg_1,
        enterprise_customer__uuid=arg_2
    )


def Func(arg_0, arg_1):
    """
    Send xAPI statement for course enrollment.

    Arguments:
         lrs_configuration (XAPILRSConfiguration): XAPILRSConfiguration instance where to send statements.
         course_enrollment (CourseEnrollment): Course enrollment object.
    """
    arg_2 = LearnerInfoSerializer(arg_1.user)
    arg_3 = CourseInfoSerializer(arg_1.course)

    arg_4 = LearnerCourseEnrollmentStatement(
        arg_1.user,
        arg_1.course,
        arg_2.data,
        arg_3.data,
    )
    EnterpriseXAPIClient(arg_0).save_statement(arg_4)


def Func(arg_0, arg_1, arg_2, arg_3):
    """
    Send xAPI statement for course completion.

    Arguments:
         lrs_configuration (XAPILRSConfiguration): XAPILRSConfiguration instance where to send statements.
         user (User): Django User object.
         course_overview (CourseOverview): Course over view object containing course details.
         course_grade (CourseGrade): course grade object.
    """
    arg_4 = LearnerInfoSerializer(arg_1)
    arg_5 = CourseInfoSerializer(arg_2)

    arg_6 = LearnerCourseCompletionStatement(
        arg_1,
        arg_2,
        arg_4.data,
        arg_5.data,
        arg_3,
    )
    EnterpriseXAPIClient(arg_0).save_statement(arg_6)


def Func(arg_0):
        """
        Return the Funced and transformed content metadata as a dictionary.
        """
        arg_1 = {}
        arg_2 = arg_0.enterprise_api.get_content_metadata(arg_0.enterprise_customer)
        LOGGER.info('Retrieved content metadata for enterprise [%s]', arg_0.enterprise_customer.name)
        for arg_3 in arg_2:
            arg_4 = arg_0._transform_item(arg_3)
            LOGGER.info(
                'Exporting content metadata item with plugin configuration [%s]: [%s]',
                arg_0.enterprise_configuration,
                json.dumps(arg_4, indent=4),
            )
            arg_5 = ContentMetadataItemExport(arg_3, arg_4)
            arg_1[arg_5.content_id] = arg_5
        return OrderedDict(sorted(arg_1.items()))


def Func(arg_0, arg_1):
        """
        Transform the provided content metadata item to the schema expected by the integrated channel.
        """
        arg_2 = arg_1['content_type']
        arg_3 = {}
        for arg_4, arg_5 in arg_0.DATA_TRANSFORM_MAPPING.items():
            # Look for transformer functions defined on subclasses.
            # Favor content type-specific functions.
            arg_6 = (
                getattr(
                    arg_0,
                    'transform_{content_type}_{edx_data_schema_key}'.format(
                        content_type=arg_2,
                        arg_5=arg_5
                    ),
                    None
                )
                or
                getattr(
                    arg_0,
                    'transform_{edx_data_schema_key}'.format(
                        arg_5=arg_5
                    ),
                    None
                )
            )
            if arg_6:
                arg_3[arg_4] = arg_6(arg_1)
            else:
                # The concrete subclass does not define an override for the given field,
                # so just use the data key to index the content metadata item dictionary.
                try:
                    arg_3[arg_4] = arg_1[arg_5]
                except KeyError:
                    # There may be a problem with the DATA_TRANSFORM_MAPPING on
                    # the concrete subclass or the concrete subclass does not implement
                    # the appropriate field tranformer function.
                    LOGGER.exception(
                        'Failed to transform content metadata item field [%s] for [%s]: [%s]',
                        arg_5,
                        arg_0.enterprise_customer.name,
                        arg_1,
                    )

        return arg_3


def Func(arg_0):
        """
        Perform other one-time initialization steps.
        """
        from enterprise.signals import handle_user_post_save
        from django.db.models.signals import pre_migrate, post_save

        post_save.connect(handle_user_post_save, sender=arg_0.auth_user_model, dispatch_uid=USER_POST_SAVE_DISPATCH_UID)
        pre_migrate.connect(arg_0._disconnect_user_post_save_for_migrations)


def Func(arg_0, arg_1, arg_2):
        """
        Get actor for the statement.
        """
        return Agent(
            name=arg_1,
            mbox='mailto:{email}'.format(arg_2=arg_2),
        )


def Func(arg_0, arg_1=None):
    """
    Parse csv file and return a stream of dictionaries representing each row.

    First line of CSV file must contain column headers.

    Arguments:
         file_stream: input file
         expected_columns (set[unicode]): columns that are expected to be present

    Yields:
        dict: CSV line parsed into a dictionary.
    """
    arg_2 = unicodecsv.DictReader(arg_0, encoding="utf-8")

    if arg_1 and set(arg_1) - set(arg_2.fieldnames):
        raise ValidationError(ValidationMessages.MISSING_EXPECTED_COLUMNS.format(
            arg_1=", ".join(arg_1), actual_columns=", ".join(arg_2.fieldnames)
        ))

    # "yield from reader" would be nicer, but we're on python2.7 yet.
    for arg_3 in arg_2:
        yield arg_3


def Func(arg_0, arg_1=None, arg_2=None, arg_3=False):
    """
    Validate email to be linked to Enterprise Customer.

    Performs two checks:
        * Checks that email is valid
        * Checks that it is not already linked to any Enterprise Customer

    Arguments:
        email (str): user email to link
        raw_email (str): raw value as it was passed by user - used in error message.
        message_template (str): Validation error template string.
        ignore_existing (bool): If True to skip the check for an existing Enterprise Customer

    Raises:
        ValidationError: if email is invalid or already linked to Enterprise Customer.

    Returns:
        bool: Whether or not there is an existing record with the same email address.
    """
    arg_1 = arg_1 if arg_1 is not None else arg_0
    arg_2 = arg_2 if arg_2 is not None else ValidationMessages.INVALID_EMAIL
    try:
        validate_email(arg_0)
    except ValidationError:
        raise ValidationError(arg_2.format(argument=arg_1))

    arg_4 = EnterpriseCustomerUser.objects.get_link_by_email(arg_0)
    if arg_4 and not arg_3:
        raise ValidationError(ValidationMessages.USER_ALREADY_REGISTERED.format(
            arg_0=arg_0, ec_name=arg_4.enterprise_customer.name
        ))
    return arg_4 or False


def Func(arg_0):
    """
    Return course runs from program data.

    Arguments:
        program(dict): Program data from Course Catalog API

    Returns:
        set: course runs in given program
    """
    arg_1 = set()
    for arg_2 in arg_0.get("courses", []):
        for arg_3 in arg_2.get("course_runs", []):
            if "key" in arg_3 and arg_3["key"]:
                arg_1.add(arg_3["key"])

    return arg_1


def Func(arg_0):
    """
    Get the earliest date that one of the courses in the program was available.
    For the sake of emails to new learners, we treat this as the program start date.

    Arguemnts:
        program (dict): Program data from Course Catalog API

    returns:
        datetime.datetime: The date and time at which the first course started
    """
    arg_1 = []
    for arg_2 in arg_0.get('courses', []):
        for arg_3 in arg_2.get('course_runs', []):
            if arg_3.get('start'):
                arg_1.append(parse_lms_api_datetime(arg_3['start']))
    if not arg_1:
        return None
    return min(arg_1)


def Func(arg_0, arg_1, arg_2=25):
    """
    Returns paginated list.

    Arguments:
        object_list (QuerySet): A list of records to be paginated.
        page (int): Current page number.
        page_size (int): Number of records displayed in each paginated set.
        show_all (bool): Whether to show all records.

    Adopted from django/contrib/admin/templatetags/admin_list.py
    https://github.com/django/django/blob/1.11.1/django/contrib/admin/templatetags/admin_list.py#L50
    """
    arg_3 = CustomPaginator(arg_0, arg_2)
    try:
        arg_0 = arg_3.page(arg_1)
    except PageNotAnInteger:
        arg_0 = arg_3.page(1)
    except EmptyPage:
        arg_0 = arg_3.page(arg_3.num_pages)

    arg_4 = []
    arg_5 = arg_0.number

    # If there are 10 or fewer pages, display links to every page.
    # Otherwise, do some fancy
    if arg_3.num_pages <= 10:
        arg_4 = range(arg_3.num_pages)
    else:
        # Insert "smart" pagination links, so that there are always ON_ENDS
        # links at either end of the list of pages, and there are always
        # ON_EACH_SIDE links at either end of the "current page" link.
        if arg_5 > (PAGES_ON_EACH_SIDE + PAGES_ON_ENDS + 1):
            arg_4.extend(range(1, PAGES_ON_ENDS + 1))
            arg_4.append(DOT)
            arg_4.extend(range(arg_5 - PAGES_ON_EACH_SIDE, arg_5 + 1))
        else:
            arg_4.extend(range(1, arg_5 + 1))
        if arg_5 < (arg_3.num_pages - PAGES_ON_EACH_SIDE - PAGES_ON_ENDS):
            arg_4.extend(range(arg_5 + 1, arg_5 + PAGES_ON_EACH_SIDE + 1))
            arg_4.append(DOT)
            arg_4.extend(range(arg_3.num_pages + 1 - PAGES_ON_ENDS, arg_3.num_pages + 1))
        else:
            arg_4.extend(range(arg_5 + 1, arg_3.num_pages + 1))

        # Override page range to implement custom smart links.
        arg_0.paginator.page_range = arg_4

    return arg_0


def Func(arg_0):
        """
        Clean email form field

        Returns:
            str: the cleaned value, converted to an email address (or an empty string)
        """
        arg_1 = arg_0.cleaned_data[arg_0.Fields.EMAIL_OR_USERNAME].strip()

        if not arg_1:
            # The field is blank; we just return the existing blank value.
            return arg_1

        arg_2 = email_or_username__to__email(arg_1)
        arg_3 = len(split_usernames_and_emails(arg_2)) > 1
        if arg_3:
            for arg_2 in split_usernames_and_emails(arg_2):
                validate_email_to_link(
                    arg_2,
                    None,
                    ValidationMessages.INVALID_EMAIL_OR_USERNAME,
                    ignore_existing=True
                )
            arg_2 = arg_1
        else:
            validate_email_to_link(
                arg_2,
                arg_1,
                ValidationMessages.INVALID_EMAIL_OR_USERNAME,
                ignore_existing=True
            )

        return arg_2


def Func(arg_0):
        """
        Clean program.

        Try obtaining program treating form value as program UUID or title.

        Returns:
            dict: Program information if program found
        """
        arg_1 = arg_0.cleaned_data[arg_0.Fields.PROGRAM].strip()
        if not arg_1:
            return None

        try:
            arg_2 = CourseCatalogApiClient(arg_0._user, arg_0._enterprise_customer.site)
            arg_3 = arg_2.get_program_by_uuid(arg_1) or arg_2.get_program_by_title(arg_1)
        except MultipleProgramMatchError as exc:
            raise ValidationError(ValidationMessages.MULTIPLE_PROGRAM_MATCH.format(program_count=exc.programs_matched))
        except (HttpClientError, HttpServerError):
            raise ValidationError(ValidationMessages.INVALID_PROGRAM_ID.format(arg_1=arg_1))

        if not arg_3:
            raise ValidationError(ValidationMessages.INVALID_PROGRAM_ID.format(arg_1=arg_1))

        if arg_3['status'] != ProgramStatuses.ACTIVE:
            raise ValidationError(
                ValidationMessages.PROGRAM_IS_INACTIVE.format(arg_1=arg_1, status=arg_3['status'])
            )

        return arg_3


def Func(arg_0):
        """
        Clean the notify_on_enrollment field.
        """
        return arg_0.cleaned_data.get(arg_0.Fields.NOTIFY, arg_0.NotificationTypes.DEFAULT)


def Func(arg_0):
        """
        Verify that the selected mode is valid for the given course .
        """
        # Verify that the selected mode is valid for the given course .
        arg_1 = arg_0.cleaned_data.get(arg_0.Fields.COURSE)
        if arg_1:
            arg_2 = arg_0.cleaned_data.get(arg_0.Fields.COURSE_MODE)
            if not arg_2:
                raise ValidationError(ValidationMessages.COURSE_WITHOUT_COURSE_MODE)
            arg_3 = arg_1["course_modes"]
            if all(arg_2 != arg_4["slug"] for arg_4 in arg_3):
                arg_5 = ValidationError(ValidationMessages.COURSE_MODE_INVALID_FOR_COURSE.format(
                    arg_2=arg_2,
                    course_id=arg_1["course_id"],
                ))
                raise ValidationError({arg_0.Fields.COURSE_MODE: arg_5})


def Func(arg_0):
        """
        Verify that selected mode is available for program and all courses in the program
        """
        arg_1 = arg_0.cleaned_data.get(arg_0.Fields.PROGRAM)
        if not arg_1:
            return

        arg_2 = get_course_runs_from_program(arg_1)
        try:
            arg_3 = CourseCatalogApiClient(arg_0._user, arg_0._enterprise_customer.site)
            arg_4 = arg_3.get_common_course_modes(arg_2)
            arg_5 = arg_0.cleaned_data.get(arg_0.Fields.COURSE_MODE)
        except (HttpClientError, HttpServerError):
            raise ValidationError(
                ValidationMessages.FAILED_TO_OBTAIN_COURSE_MODES.format(program_title=arg_1.get("title"))
            )

        if not arg_5:
            raise ValidationError(ValidationMessages.COURSE_WITHOUT_COURSE_MODE)
        if arg_5 not in arg_4:
            raise ValidationError(ValidationMessages.COURSE_MODE_NOT_AVAILABLE.format(
                mode=arg_5, program_title=arg_1.get("title"), modes=", ".join(arg_4)
            ))


def Func(arg_0):
        """
        Retrieve a list of catalog ID and name pairs.

        Once retrieved, these name pairs can be used directly as a value
        for the `choices` argument to a ChoiceField.
        """
        # TODO: We will remove the discovery service catalog implementation
        # once we have fully migrated customer's to EnterpriseCustomerCatalogs.
        # For now, this code will prevent an admin from creating a new
        # EnterpriseCustomer with a discovery service catalog. They will have to first
        # save the EnterpriseCustomer admin form and then edit the EnterpriseCustomer
        # to add a discovery service catalog.
        if hasattr(arg_0.instance, 'site'):
            arg_1 = CourseCatalogApiClient(arg_0.user, arg_0.instance.site)
        else:
            arg_1 = CourseCatalogApiClient(arg_0.user)
        arg_2 = arg_1.get_all_catalogs()
        # order catalogs by name.
        arg_2 = sorted(arg_2, key=lambda arg_3: arg_3.get('name', '').lower())

        return BLANK_CHOICE_DASH + [
            (arg_3['id'], arg_3['name'],)
            for arg_3 in arg_2
        ]


def Func(arg_0):
        """
        Clean form fields prior to database entry.

        In this case, the major Funcing operation is substituting a None value for a blank
        value in the Catalog field.
        """
        arg_1 = super(EnterpriseCustomerAdminForm, arg_0).Func()
        if 'catalog' in arg_1 and not arg_1['catalog']:
            arg_1['catalog'] = None
        return arg_1


def Func(arg_0):
        """
        Final validations of model fields.

        1. Validate that selected site for enterprise customer matches with the selected identity provider's site.
        """
        super(EnterpriseCustomerIdentityProviderAdminForm, arg_0).Func()

        arg_1 = arg_0.Funced_data.get('provider_id', None)
        arg_2 = arg_0.Funced_data.get('enterprise_customer', None)

        if arg_1 is None or arg_2 is None:
            # field validation for either provider_id or enterprise_customer has already raised
            # a validation error.
            return

        arg_3 = utils.get_identity_provider(arg_1)
        if not arg_3:
            # This should not happen, as identity providers displayed in drop down are fetched dynamically.
            arg_4 = _(
                "The specified Identity Provider does not exist. For more "
                "information, contact a system administrator.",
            )
            # Log message for debugging
            logger.exception(arg_4)

            raise ValidationError(arg_4)

        if arg_3 and arg_3.site != arg_2.site:
            raise ValidationError(
                _(
                    "The site for the selected identity provider "
                    "({identity_provider_site}) does not match the site for "
                    "this enterprise customer ({enterprise_customer_site}). "
                    "To correct this problem, select a site that has a domain "
                    "of '{identity_provider_site}', or update the identity "
                    "provider to '{enterprise_customer_site}'."
                ).format(
                    enterprise_customer_site=arg_2.site,
                    identity_provider_site=arg_3.site,
                ),
            )


def Func():
    """
    Ensure that all necessary resources to render the view are present.
    """
    arg_0 = {
        'ProgramDataExtender': ProgramDataExtender,
    }

    for arg_1 in arg_0:
        if arg_0[arg_1] is None:
            raise NotConnectedToOpenEdX(
                _("The following method from the Open edX platform is necessary for this view but isn't available.")
                + "\nUnavailable: {method}".format(arg_1=arg_1)
            )


def Func(arg_0, arg_1):
    """
    Get the set of variables that are needed by default across views.
    """
    arg_2 = get_configuration_value("PLATFORM_NAME", settings.PLATFORM_NAME)
    # pylint: disable=no-member
    return {
        'enterprise_customer': arg_1,
        'LMS_SEGMENT_KEY': settings.LMS_SEGMENT_KEY,
        'LANGUAGE_CODE': get_language_from_request(arg_0),
        'tagline': get_configuration_value("ENTERPRISE_TAGLINE", settings.ENTERPRISE_TAGLINE),
        'platform_description': get_configuration_value(
            "PLATFORM_DESCRIPTION",
            settings.PLATFORM_DESCRIPTION,
        ),
        'LMS_ROOT_URL': settings.LMS_ROOT_URL,
        'platform_name': arg_2,
        'header_logo_alt_text': _('{platform_name} home page').format(arg_2=arg_2),
        'welcome_text': constants.WELCOME_TEXT.format(arg_2=arg_2),
        'enterprise_welcome_text': constants.ENTERPRISE_WELCOME_TEXT.format(
            enterprise_customer_name=arg_1.name,
            arg_2=arg_2,
            strong_start='',
            strong_end='',
            line_break='
',
            privacy_policy_link_start="".format(
                pp_url=get_configuration_value('PRIVACY', 'https://www.edx.org/edx-privacy-policy', type='url'),
            ),
            privacy_policy_link_end="",
        ),
    }


def Func(arg_0, arg_1, arg_2=None, arg_3=None):
        """
        Return a dict having course or program specific keys for data sharing consent page.
        """
        arg_4 = {}
        if arg_2:
            arg_4.update({'course_id': arg_2, 'course_specific': True})
            if not arg_0.preview_mode:
                try:
                    arg_5 = CourseCatalogApiServiceClient(arg_1.site)
                except ImproperlyConfigured:
                    raise Http404

                arg_6 = arg_5.get_course_run(arg_2)
                arg_7 = ''
                if arg_6['start']:
                    arg_7 = parse(arg_6['start']).strftime('%B %d, %Y')

                arg_4.update({
                    'course_title': arg_6['title'],
                    'course_start_date': arg_7,
                })
            else:
                arg_4.update({
                    'course_title': 'Demo Course',
                    'course_start_date': datetime.datetime.now().strftime('%B %d, %Y'),
                })
        else:
            arg_4.update({
                'program_uuid': arg_3,
                'program_specific': True,
            })
        return arg_4


def Func(arg_0, arg_1):
        """
        Process the above form.
        """
        arg_2 = arg_1.POST.get('enterprise_customer_uuid')
        arg_3 = arg_1.POST.get('redirect_url')
        arg_4 = arg_1.POST.get('failure_url')
        arg_5 = arg_1.POST.get('course_id', '')
        arg_6 = arg_1.POST.get('program_uuid', '')

        arg_7 = get_enterprise_customer_or_404(arg_2)
        arg_8 = get_global_context(arg_1, arg_7)

        if not (arg_2 and arg_3 and arg_4):
            arg_9 = 'ENTGDS005'
            arg_10 = (
                'Error: one or more of the following values was falsy: '
                'enterprise_uuid: {enterprise_uuid}, '
                'success_url: {success_url}, '
                'failure_url: {failure_url} for course_id {course_id}. '
                'The following error code was reported to the user {userid}: {error_code}'.format(
                    userid=arg_1.user.id,
                    arg_2=arg_2,
                    arg_3=arg_3,
                    arg_4=arg_4,
                    arg_9=arg_9,
                    arg_5=arg_5,
                )
            )
            return render_page_with_error_code_message(arg_1, arg_8, arg_9, arg_10)

        if not arg_0.course_or_program_exist(arg_5, arg_6):
            arg_9 = 'ENTGDS006'
            arg_10 = (
                'Neither the course with course_id: {course_id} '
                'or program with {program_uuid} exist for '
                'enterprise customer {enterprise_uuid}'
                'Error code {error_code} presented to user {userid}'.format(
                    arg_5=arg_5,
                    arg_6=arg_6,
                    arg_9=arg_9,
                    userid=arg_1.user.id,
                    arg_2=arg_2,
                )
            )
            return render_page_with_error_code_message(arg_1, arg_8, arg_9, arg_10)

        arg_11 = get_data_sharing_consent(
            arg_1.user.username,
            arg_2,
            arg_6=arg_6,
            arg_5=arg_5
        )
        if arg_11 is None:
            arg_9 = 'ENTGDS007'
            arg_10 = (
                'The was a problem with the consent record of user {userid} with '
                'enterprise_uuid {enterprise_uuid}. consent_record has a value '
                'of {consent_record} and a '
                'value for course_id {course_id}. '
                'Error code {error_code} presented to user'.format(
                    userid=arg_1.user.id,
                    arg_2=arg_2,
                    arg_11=arg_11,
                    arg_9=arg_9,
                    arg_5=arg_5,
                )
            )
            return render_page_with_error_code_message(arg_1, arg_8, arg_9, arg_10)

        arg_12 = arg_1.POST.get('defer_creation')
        arg_13 = bool(arg_1.POST.get('data_sharing_consent', False))
        if arg_12 is None and arg_11.consent_required():
            if arg_5:
                arg_14, arg_15 = EnterpriseCustomerUser.objects.get_or_create(
                    arg_7=arg_11.enterprise_customer,
                    user_id=arg_1.user.id
                )
                arg_14.update_session(arg_1)
                arg_15, arg_16 = EnterpriseCourseEnrollment.objects.get_or_create(
                    arg_14=arg_14,
                    arg_5=arg_5,
                )
                if arg_16:
                    track_enrollment('data-consent-page-enrollment', arg_1.user.id, arg_5, arg_1.path)

            arg_11.granted = arg_13
            arg_11.save()

        return redirect(arg_3 if arg_13 else arg_4)


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Handle the enrollment of enterprise learner in the provided course.

        Based on `enterprise_uuid` in URL, the view will decide which
        enterprise customer's course enrollment record should be created.

        Depending on the value of query parameter `course_mode` then learner
        will be either redirected to LMS dashboard for audit modes or
        redirected to ecommerce basket flow for payment of premium modes.
        """
        arg_4 = arg_1.GET.Func('course_mode')
        arg_5 = arg_1.GET.Func('catalog')

        # Redirect the learner to LMS dashboard in case no course mode is
        # provided as query parameter `course_mode`
        if not arg_4:
            return redirect(LMS_DASHBOARD_URL)

        arg_6 = EnrollmentApiClient()
        arg_7 = arg_6.Func_course_modes(arg_3)

        # Verify that the request user belongs to the enterprise against the
        # provided `enterprise_uuid`.
        arg_8 = Func_enterprise_customer_or_404(arg_2)
        arg_9 = Func_enterprise_customer_user(arg_1.user.id, arg_8.uuid)

        if not arg_7:
            arg_10 = Func_global_context(arg_1, arg_8)
            arg_11 = 'ENTHCE000'
            arg_12 = (
                'No course_modes for course_id {course_id} for enterprise_catalog_uuid '
                '{enterprise_catalog_uuid}.'
                'The following error was presented to '
                'user {userid}: {error_code}'.format(
                    userid=arg_1.user.id,
                    arg_5=arg_5,
                    arg_3=arg_3,
                    arg_11=arg_11
                )
            )
            return render_page_with_error_code_message(arg_1, arg_10, arg_11, arg_12)

        arg_13 = None
        for arg_14 in arg_7:
            if arg_14['slug'] == arg_4:
                arg_13 = arg_14
                break

        if not arg_13:
            return redirect(LMS_DASHBOARD_URL)

        # Create the Enterprise backend database records for this course
        # enrollment
        arg_15, arg_16 = EnterpriseCourseEnrollment.objects.Func_or_create(
            arg_9=arg_9,
            arg_3=arg_3,
        )
        if arg_16:
            track_enrollment('course-landing-page-enrollment', arg_1.user.id, arg_3, arg_1.Func_full_path())

        DataSharingConsent.objects.update_or_create(
            username=arg_9.username,
            arg_3=arg_3,
            arg_8=arg_9.enterprise_customer,
            defaults={
                'granted': True
            },
        )

        arg_17 = Funcattr(settings, 'ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES', ['audit', 'honor'])
        if arg_13['slug'] in arg_17:
            # In case of Audit course modes enroll the learner directly through
            # enrollment API client and redirect the learner to dashboard.
            arg_6.enroll_user_in_course(
                arg_1.user.username, arg_3, arg_13['slug']
            )

            return redirect(LMS_COURSEWARE_URL.format(arg_3=arg_3))

        # redirect the enterprise learner to the ecommerce flow in LMS
        # Note: LMS start flow automatically detects the paid mode
        arg_18 = LMS_START_PREMIUM_COURSE_FLOW_URL.format(arg_3=arg_3)
        if arg_5:
            arg_18 += '?catalog={catalog_uuid}'.format(
                catalog_uuid=arg_5
            )

        return redirect(arg_18)


def Func(arg_0, arg_1, arg_2):
        """
        Set the final discounted price on each premium mode.
        """
        arg_3 = []
        for arg_4 in arg_1:
            if arg_4['premium']:
                arg_4['final_price'] = EcommerceApiClient(arg_2.user).get_course_final_price(
                    arg_4=arg_4,
                    enterprise_catalog_uuid=arg_2.GET.get(
                        'catalog'
                    ) if arg_2.method == 'GET' else None,
                )
            arg_3.append(arg_4)
        return arg_3


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Return the available course modes for the course run.

        The provided EnterpriseCustomerCatalog is used to filter and order the
        course modes returned using the EnterpriseCustomerCatalog's
        field "enabled_course_modes".
        """
        arg_4 = EnrollmentApiClient().get_course_modes(arg_2)
        if not arg_4:
            LOGGER.warning('Unable to get course modes for course run id {course_run_id}.'.format(
                arg_2=arg_2
            ))
            messages.add_generic_info_message_for_error(arg_1)

        if arg_3:
            # filter and order course modes according to the enterprise catalog
            arg_4 = [mode for mode in arg_4 if mode['slug'] in arg_3.enabled_course_modes]
            arg_4.sort(key=lambda course_mode: arg_3.enabled_course_modes.index(course_mode['slug']))
            if not arg_4:
                LOGGER.info(
                    'No matching course modes found for course run {course_run_id} in '
                    'EnterpriseCustomerCatalog [{enterprise_catalog_uuid}]'.format(
                        arg_2=arg_2,
                        enterprise_catalog_uuid=arg_3,
                    )
                )
                messages.add_generic_info_message_for_error(arg_1)

        return arg_4


def Func(arg_0, arg_1, arg_2):
        """
        Extend a course with more details needed for the program landing page.

        In particular, we add the following:

        * `course_image_uri`
        * `course_title`
        * `course_level_type`
        * `course_short_description`
        * `course_full_description`
        * `course_effort`
        * `expected_learning_items`
        * `staff`
        """
        arg_3 = arg_0['course_runs'][0]['key']
        try:
            arg_4 = CourseCatalogApiServiceClient(arg_1.site)
        except ImproperlyConfigured:
            arg_5 = 'ENTPEV000'
            LOGGER.error(
                'CourseCatalogApiServiceClient is improperly configured. '
                'Returned error code {error_code} to user {userid} '
                'and enterprise_customer {enterprise_customer} '
                'for course_run_id {course_run_id}'.format(
                    arg_5=arg_5,
                    userid=arg_2.user.id,
                    arg_1=arg_1.uuid,
                    arg_3=arg_3,
                )
            )
            messages.add_generic_error_message_with_code(arg_2, arg_5)
            return ({}, arg_5)

        arg_6, arg_7 = arg_4.get_course_and_course_run(arg_3)
        if not arg_6 or not arg_7:
            arg_5 = 'ENTPEV001'
            LOGGER.error(
                'User {userid} of enterprise customer {enterprise_customer} encountered an error.'
                'No course_details or course_run_details found for '
                'course_run_id {course_run_id}. '
                'The following error code reported to the user: {error_code}'.format(
                    userid=arg_2.user.id,
                    arg_1=arg_1.uuid,
                    arg_3=arg_3,
                    arg_5=arg_5,
                )
            )
            messages.add_generic_error_message_with_code(arg_2, arg_5)
            return ({}, arg_5)

        arg_8 = arg_7['weeks_to_complete']
        arg_9 = arg_7['image'] or {}
        arg_0.update({
            'course_image_uri': arg_9.get('src', ''),
            'course_title': arg_7['title'],
            'course_level_type': arg_7.get('level_type', ''),
            'course_short_description': arg_7['short_description'] or '',
            'course_full_description': clean_html_for_template_rendering(arg_7['full_description'] or ''),
            'expected_learning_items': arg_6.get('expected_learning_items', []),
            'staff': arg_7.get('staff', []),
            'course_effort': ungettext_min_max(
                '{} hour per week',
                '{} hours per week',
                '{}-{} hours per week',
                arg_7['min_effort'] or None,
                arg_7['max_effort'] or None,
            ) or '',
            'weeks_to_complete': ungettext(
                '{} week',
                '{} weeks',
                arg_8
            ).format(arg_8) if arg_8 else '',
        })
        return arg_0, None


def Func(arg_0, arg_1, arg_2):
        """
        User is requesting a course, we need to translate that into the current course run.

        :param user:
        :param enterprise_customer:
        :param course_key:
        :return: course_run_id
        """
        try:
            arg_3 = CourseCatalogApiServiceClient(arg_1.site).get_course_details(arg_2)
        except ImproperlyConfigured:
            raise Http404

        arg_4 = EnrollmentApiClient().get_enrolled_courses(arg_0.username)
        arg_5 = get_active_course_runs(
            arg_3,
            arg_4
        ) if arg_4 else []
        arg_6 = get_current_course_run(arg_3, arg_5)
        if arg_6:
            arg_7 = arg_6['key']
            return arg_7
        else:
            raise Http404


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None):
        """
        Return whether a request is eligible for direct audit enrollment for a particular enterprise customer.

        'resource_id' can be either course_run_id or program_uuid.
        We check for the following criteria:
        - The `audit` query parameter.
        - The user's being routed to the course enrollment landing page.
        - The customer's catalog contains the course in question.
        - The audit track is an available mode for the course.
        """
        arg_5 = arg_4 if arg_4 else arg_3

        # Return it in one big statement to utilize short-circuiting behavior. Avoid the API call if possible.
        return arg_1.GET.get('audit') and \
            arg_1.path == arg_0.COURSE_ENROLLMENT_VIEW_URL.format(arg_2.uuid, arg_5) and \
            arg_2.catalog_contains_course(arg_3) and \
            EnrollmentApiClient().has_course_mode(arg_3, 'audit')


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """
        Redirects to the appropriate view depending on where the user came from.
        """
        arg_4, arg_5, arg_6, arg_7 = RouterView.get_path_variables(**arg_3)
        arg_8 = arg_6 or arg_5 or arg_7
        # Replace enterprise UUID and resource ID with '{}', to easily match with a path in RouterView.VIEWS. Example:
        # /enterprise/fake-uuid/course/course-v1:cool+course+2017/enroll/ -> /enterprise/{}/course/{}/enroll/
        arg_9 = re.sub('{}|{}'.format(arg_4, re.escape(arg_8)), '{}', arg_1.path)

        # Remove course_key from kwargs if it exists because delegate views are not expecting it.
        arg_3.pop('course_key', None)

        return arg_0.VIEWS[arg_9].as_view()(arg_1, *arg_2, **arg_3)


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """
        Run some custom GET logic for Enterprise workflows before routing the user through existing views.

        In particular, before routing to existing views:
        - If the requested resource is a course, find the current course run for that course,
          and make that course run the requested resource instead.
        - Look to see whether a request is eligible for direct audit enrollment, and if so, directly enroll the user.
        """
        arg_4, arg_5, arg_6, arg_7 = RouterView.Func_path_variables(**arg_3)
        arg_8 = Func_enterprise_customer_or_404(arg_4)
        if arg_6:
            try:
                arg_5 = RouterView.Func_course_run_id(arg_1.user, arg_8, arg_6)
            except Http404:
                arg_9 = Func_global_context(arg_1, arg_8)
                arg_10 = 'ENTRV000'
                arg_11 = (
                    'Could not find course run with id {course_run_id} '
                    'for course key {course_key} and program_uuid {program_uuid} '
                    'for enterprise_customer_uuid {enterprise_customer_uuid} '
                    'Returned error code {error_code} to user {userid}'.format(
                        arg_6=arg_6,
                        arg_5=arg_5,
                        arg_4=arg_4,
                        arg_10=arg_10,
                        userid=arg_1.user.id,
                        arg_7=arg_7,
                    )
                )
                return render_page_with_error_code_message(arg_1, arg_9, arg_10, arg_11)
            arg_3['course_id'] = arg_5

        # Ensure that the link is saved to the database prior to making some call in a downstream view
        # which may need to know that the user belongs to an enterprise customer.
        with transaction.atomic():
            arg_12, arg_13 = EnterpriseCustomerUser.objects.Func_or_create(
                arg_8=arg_8,
                user_id=arg_1.user.id
            )
            arg_12.update_session(arg_1)

        # Directly enroll in audit mode if the request in question has full direct audit enrollment eligibility.
        arg_14 = arg_5 or arg_7
        if arg_0.eligible_for_direct_audit_enrollment(arg_1, arg_8, arg_14, arg_6):
            try:
                arg_12.enroll(arg_14, 'audit', cohort=arg_1.GET.Func('cohort', None))
                track_enrollment('direct-audit-enrollment', arg_1.user.id, arg_14, arg_1.Func_full_path())
            except (CourseEnrollmentDowngradeError, CourseEnrollmentPermissionError):
                pass
            # The courseware view logic will check for DSC requirements, and route to the DSC page if necessary.
            return redirect(LMS_COURSEWARE_URL.format(course_id=arg_14))

        return arg_0.redirect(arg_1, *arg_2, **arg_3)


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """
        Run some custom POST logic for Enterprise workflows before routing the user through existing views.
        """
        # pylint: disable=unused-variable
        arg_4, arg_5, arg_6, arg_7 = RouterView.get_path_variables(**arg_3)
        arg_8 = get_enterprise_customer_or_404(arg_4)

        if arg_6:
            arg_9 = get_global_context(arg_1, arg_8)
            try:
                arg_3['course_id'] = RouterView.get_course_run_id(arg_1.user, arg_8, arg_6)
            except Http404:
                arg_10 = 'ENTRV001'
                arg_11 = (
                    'Could not find course run with id {course_run_id} '
                    'for course key {course_key} and '
                    'for enterprise_customer_uuid {enterprise_customer_uuid} '
                    'and program {program_uuid}. '
                    'Returned error code {error_code} to user {userid}'.format(
                        arg_6=arg_6,
                        arg_5=arg_5,
                        arg_4=arg_4,
                        arg_10=arg_10,
                        userid=arg_1.user.id,
                        arg_7=arg_7,
                    )
                )
                return render_page_with_error_code_message(arg_1, arg_9, arg_10, arg_11)

        return arg_0.redirect(arg_1, *arg_2, **arg_3)


def Func(arg_0, arg_1, arg_2):
    """
    Task to send learner data to each linked integrated channel.

    Arguments:
        username (str): The username of the User to be used for making API requests for learner data.
        channel_code (str): Capitalized identifier for the integrated channel
        channel_pk (str): Primary key for identifying integrated channel

    """
    arg_3 = time.time()
    arg_4 = User.objects.get(arg_0=arg_0)
    arg_5 = INTEGRATED_CHANNEL_CHOICES[arg_1].objects.get(pk=arg_2)
    LOGGER.info('Processing learners for integrated channel using configuration: [%s]', arg_5)

    # Note: learner data transmission code paths don't raise any uncaught exception, so we don't need a broad
    # try-except block here.
    arg_5.Func(arg_4)

    arg_6 = time.time() - arg_3
    LOGGER.info(
        'Learner data transmission task for integrated channel configuration [%s] took [%s] seconds',
        arg_5,
        arg_6
    )


def Func(arg_0, arg_1):
    """
    Task to unlink inactive learners of provided integrated channel.

    Arguments:
        channel_code (str): Capitalized identifier for the integrated channel
        channel_pk (str): Primary key for identifying integrated channel

    """
    arg_2 = time.time()
    arg_3 = INTEGRATED_CHANNEL_CHOICES[arg_0].objects.get(pk=arg_1)
    LOGGER.info('Processing learners to unlink inactive users using configuration: [%s]', arg_3)

    # Note: learner data transmission code paths don't raise any uncaught exception, so we don't need a broad
    # try-except block here.
    arg_3.Func()

    arg_4 = time.time() - arg_2
    LOGGER.info(
        'Unlink inactive learners task for integrated channel configuration [%s] took [%s] seconds',
        arg_3,
        arg_4
    )


def Func(arg_0, **arg_1):  # pylint: disable=unused-argument
    """
    Handle User model changes - checks if pending enterprise customer user record exists and upgrades it to actual link.

    If there are pending enrollments attached to the PendingEnterpriseCustomerUser, then this signal also takes the
    newly-created users and enrolls them in the relevant courses.
    """
    arg_2 = arg_1.get("created", False)
    arg_3 = arg_1.get("instance", None)

    if arg_3 is None:
        return  # should never happen, but better safe than 500 error

    try:
        arg_4 = PendingEnterpriseCustomerUser.objects.get(user_email=arg_3.email)
    except PendingEnterpriseCustomerUser.DoesNotExist:
        return  # nothing to do in this case

    if not arg_2:
        # existing user changed his email to match one of pending link records - try linking him to EC
        try:
            arg_5 = EnterpriseCustomerUser.objects.get(user_id=arg_3.id)
            arg_6 = "User {user} have changed email to match pending Enterprise Customer link, " \
                               "but was already linked to Enterprise Customer {enterprise_customer} - " \
                               "deleting pending link record"
            logger.info(arg_6.format(
                user=arg_3, enterprise_customer=arg_5.enterprise_customer
            ))
            arg_4.delete()
            return
        except EnterpriseCustomerUser.DoesNotExist:
            pass  # everything ok - current user is not linked to other ECs

    arg_7 = EnterpriseCustomerUser.objects.create(
        enterprise_customer=arg_4.enterprise_customer,
        user_id=arg_3.id
    )
    arg_8 = list(arg_4.pendingenrollment_set.all())
    if arg_8:
        def _complete_user_enrollment():  # pylint: disable=missing-docstring
            for arg_9 in arg_8:
                # EnterpriseCustomers may enroll users in courses before the users themselves
                # actually exist in the system; in such a case, the enrollment for each such
                # course is finalized when the user registers with the OpenEdX platform.
                arg_7.enroll(
                    arg_9.course_id, arg_9.course_mode, cohort=arg_9.cohort_name)
                track_enrollment('pending-admin-enrollment', arg_3.id, arg_9.course_id)
            arg_4.delete()
        transaction.on_commit(_complete_user_enrollment)
    else:
        arg_4.delete()


def Func(arg_0, arg_1, **arg_2):     # pylint: disable=unused-argument
    """
    Set default value for `EnterpriseCustomerCatalog.content_filter` if not already set.
    """
    if arg_2['created'] and not arg_1.content_filter:
        arg_1.content_filter = get_default_catalog_content_filter()
        arg_1.save()


def Func(arg_0, arg_1, **arg_2):     # pylint: disable=unused-argument
    """
    Assign an enterprise learner role to EnterpriseCustomerUser whenever a new record is created.
    """
    if arg_2['created'] and arg_1.user:
        arg_3, arg_4 = SystemWideEnterpriseRole.objects.get_or_create(name=ENTERPRISE_LEARNER_ROLE)
        SystemWideEnterpriseUserRoleAssignment.objects.get_or_create(
            user=arg_1.user,
            role=arg_3
        )


def Func(*arg_0):
    """
    Ensure at least one of the specified query parameters are included in the request.

    This decorator checks for the existence of at least one of the specified query
    parameters and passes the values as function parameters to the decorated view.
    If none of the specified query parameters are included in the request, a
    ValidationError is raised.

    Usage::
        @Func('program_uuids', 'course_run_ids')
        def my_view(request, program_uuids, course_run_ids):
            # Some functionality ...
    """
    def outer_wrapper(arg_1):
        """ Allow the passing of parameters to Func. """
        @wraps(arg_1)
        def wrapper(arg_2, *arg_3, **arg_4):
            """
            Checks for the existence of the specified query parameters, raises a
            ValidationError if none of them were included in the request.
            """
            arg_5 = False
            for arg_6 in arg_0:
                arg_7 = arg_2.query_params.getlist(arg_6)
                arg_4[arg_6] = arg_7
                if arg_7:
                    arg_5 = True
            if not arg_5:
                raise ValidationError(
                    detail='You must provide at least one of the following query parameters: {params}.'.format(
                        params=', '.join(arg_0)
                    )
                )
            return arg_1(arg_2, *arg_3, **arg_4)
        return wrapper
    return outer_wrapper


def Func(arg_0, arg_1, arg_2, arg_3=False):
        """
        Assigns enterprise role to users.
        """
        arg_4 = arg_2['role']
        arg_5 = arg_2['batch_limit']
        arg_6 = arg_2['batch_sleep']
        arg_7 = arg_2['batch_offset']

        arg_8 = arg_7

        arg_9 = arg_1(
            arg_7,
            arg_7 + arg_5
        )

        arg_10 = SystemWideEnterpriseRole
        arg_11 = SystemWideEnterpriseUserRoleAssignment

        if arg_3:
            arg_10 = EnterpriseFeatureRole
            arg_11 = EnterpriseFeatureUserRoleAssignment

        arg_12 = arg_10.objects.get(name=arg_4)
        while arg_9.count() > 0:
            for arg_13, arg_14 in enumerate(arg_9):
                LOGGER.info(
                    'Processing user with index %s and id %s',
                    arg_8 + arg_13, arg_14.id
                )
                arg_11.objects.get_or_create(
                    arg_14=arg_14,
                    role=arg_12
                )

            sleep(arg_6)
            arg_8 += len(arg_9)
            arg_9 = arg_1(
                arg_8,
                arg_8 + arg_5
            )


def Func(arg_0, *arg_1, **arg_2):
        """
        Entry point for managment command execution.
        """
        LOGGER.info('Starting assigning enterprise roles to users!')

        arg_3 = arg_2['role']
        if arg_3 == ENTERPRISE_ADMIN_ROLE:
            # Assign admin role to non-staff users with enterprise data api access.
            arg_0._assign_enterprise_role_to_users(arg_0._get_enterprise_admin_users_batch, arg_2)
        elif arg_3 == ENTERPRISE_OPERATOR_ROLE:
            # Assign operator role to staff users with enterprise data api access.
            arg_0._assign_enterprise_role_to_users(arg_0._get_enterprise_operator_users_batch, arg_2)
        elif arg_3 == ENTERPRISE_LEARNER_ROLE:
            # Assign enterprise learner role to enterprise customer users.
            arg_0._assign_enterprise_role_to_users(arg_0._get_enterprise_customer_users_batch, arg_2)
        elif arg_3 == ENTERPRISE_ENROLLMENT_API_ADMIN_ROLE:
            # Assign enterprise enrollment api admin to non-staff users with enterprise data api access.
            arg_0._assign_enterprise_role_to_users(arg_0._get_enterprise_enrollment_api_admin_users_batch, arg_2, True)
        elif arg_3 == ENTERPRISE_CATALOG_ADMIN_ROLE:
            # Assign enterprise catalog admin role to users with having credentials in catalog.
            arg_0._assign_enterprise_role_to_users(arg_0._get_enterprise_catalog_admin_users_batch, arg_2, True)
        else:
            raise CommandError('Please provide a valid role name. Supported roles are {admin} and {learner}'.format(
                admin=ENTERPRISE_ADMIN_ROLE,
                learner=ENTERPRISE_LEARNER_ROLE
            ))

        LOGGER.info('Successfully finished assigning enterprise roles to users!')


def Func(arg_0, arg_1, **arg_2):
    """
    Perform the linking of user in the process of logging to the Enterprise Customer.

    Args:
        backend: The class handling the SSO interaction (SAML, OAuth, etc)
        user: The user object in the process of being logged in with
        **kwargs: Any remaining pipeline variables

    """
    arg_3 = arg_0.strategy.request
    arg_4 = get_enterprise_customer_for_running_pipeline(
        arg_3,
        {
            'backend': arg_0.name,
            'kwargs': arg_2
        }
    )
    if arg_4 is None:
        # This pipeline element is not being activated as a part of an Enterprise logistration
        return

    # proceed with the creation of a link between the user and the enterprise customer, then exit.
    arg_5, arg_6 = EnterpriseCustomerUser.objects.update_or_create(
        arg_4=arg_4,
        user_id=arg_1.id
    )
    arg_5.update_session(arg_3)


def Func(arg_0, arg_1):
    """
    Find the LMS user from the LMS model `UserSocialAuth`.

    Arguments:
        tpa_provider (third_party_auth.provider): third party auth provider object
        tpa_username (str): Username returned by the third party auth

    """
    arg_2 = UserSocialAuth.objects.select_related('user').filter(
        user__username=arg_1, provider=arg_0.backend_name
    ).first()

    return arg_2.user if arg_2 else None


def Func(arg_0):
        """
        Instantiate a new session object for use in connecting with SAP SuccessFactors
        """
        arg_1 = requests.Session()
        arg_1.timeout = arg_0.SESSION_TIMEOUT

        arg_3, arg_4 = SAPSuccessFactorsAPIClient.get_oauth_access_token(
            arg_0.enterprise_configuration.sapsf_base_url,
            arg_0.enterprise_configuration.key,
            arg_0.enterprise_configuration.secret,
            arg_0.enterprise_configuration.sapsf_company_id,
            arg_0.enterprise_configuration.sapsf_user_id,
            arg_0.enterprise_configuration.user_type
        )

        arg_1.headers['Authorization'] = 'Bearer {}'.format(arg_3)
        arg_1.headers['content-type'] = 'application/json'
        arg_0.session = arg_1
        arg_0.expires_at = arg_4


def Func(arg_0, arg_1, arg_2):
        """
        Make a post request using the session object to a SuccessFactors endpoint.

        Args:
            url (str): The url to post to.
            payload (str): The json encoded payload to post.
        """
        arg_3 = datetime.datetime.utcnow()
        if arg_3 >= arg_0.expires_at:
            # Create a new session with a valid token
            arg_0.session.close()
            arg_0._create_session()
        arg_4 = arg_0.session.post(arg_1, data=arg_2)
        return arg_4.status_code, arg_4.text


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """
        Make recursive GET calls to traverse the paginated API response for search students.
        """
        arg_5 = '{sap_search_student_url}&{pagination_criterion}'.format(
            arg_1=arg_1,
            pagination_criterion='$count=true&$top={page_size}&$skip={start_at}'.format(
                arg_3=arg_3,
                arg_4=arg_4,
            ),
        )
        try:
            arg_6 = arg_0.session.get(arg_5)
            arg_7 = arg_6.json()
        except (ConnectionError, Timeout):
            LOGGER.warning(
                'Unable to fetch inactive learners from SAP searchStudent API with url '
                '"{%s}".', arg_5,
            )
            return None

        if 'error' in arg_7:
            LOGGER.warning(
                'SAP searchStudent API for customer %s and base url %s returned response with '
                'error message "%s" and with error code "%s".',
                arg_0.enterprise_configuration.enterprise_customer.name,
                arg_0.enterprise_configuration.sapsf_base_url,
                arg_7['error'].get('message'),
                arg_7['error'].get('code'),
            )
            return None

        arg_8 = arg_3 + arg_4
        arg_2 += arg_7['value']
        if arg_7['@odata.count'] > arg_8:
            return arg_0.Func(
                arg_1,
                arg_2,
                arg_3=arg_3,
                arg_4=arg_8,
            )

        return arg_2


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Filter only for the user's ID if non-staff.
        """
        if not arg_1.user.is_staff:
            arg_4 = {arg_3.USER_ID_FILTER: arg_1.user.id}
            arg_2 = arg_2.filter(**arg_4)
        return arg_2


def Func(arg_0, arg_1, **arg_2):
        """
        Send a completion status call to the integrated channel using the client.

        Args:
            payload: The learner completion data payload to send to the integrated channel.
            kwargs: Contains integrated channel-specific information for customized transmission variables.
                - app_label: The app label of the integrated channel for whom to store learner data records for.
                - model_name: The name of the specific learner data record model to use.
                - remote_user_id: The remote ID field name of the learner on the audit model.
        """
        arg_3 = apps.get_model(  # pylint: disable=invalid-name
            app_label=arg_2.get('app_label', 'integrated_channel'),
            model_name=arg_2.get('model_name', 'LearnerDataTransmissionAudit'),
        )
        # Since we have started sending courses to integrated channels instead of course runs,
        # we need to attempt to send transmissions with course keys and course run ids in order to
        # ensure that we account for whether courses or course runs exist in the integrated channel.
        # The exporters have been changed to return multiple transmission records to attempt,
        # one by course key and one by course run id.
        # If the transmission with the course key succeeds, the next one will get skipped.
        # If it fails, the one with the course run id will be attempted and (presumably) succeed.
        for arg_4 in arg_1.export():
            arg_5 = arg_4.serialize(enterprise_configuration=arg_0.enterprise_configuration)
            LOGGER.debug('Attempting to Func serialized payload: %s', arg_5)

            arg_6 = arg_4.enterprise_course_enrollment_id
            if arg_4.completed_timestamp is None:
                # The user has not completed the course, so we shouldn't send a completion status call
                LOGGER.info('Skipping in-progress enterprise enrollment {}'.format(arg_6))
                continue

            arg_7 = arg_3.objects.filter(
                enterprise_course_enrollment_id=arg_6,
                arg_11=''
            )
            if arg_7.exists():
                # We've already sent a completion status call for this enrollment
                LOGGER.info('Skipping previously sent enterprise enrollment {}'.format(arg_6))
                continue

            try:
                arg_8, arg_9 = arg_0.client.create_course_completion(
                    getattr(arg_4, arg_2.get('remote_user_id')),
                    arg_5
                )
                LOGGER.info(
                    'Successfully sent completion status call for enterprise enrollment {}'.format(
                        arg_6,
                    )
                )
            except RequestException as request_exception:
                arg_8 = 500
                arg_9 = str(request_exception)
                arg_0.handle_transmission_error(arg_4, request_exception)

            arg_4.status = str(arg_8)
            arg_4.error_message = arg_9 if arg_8 >= 400 else ''
            arg_4.save()


def Func(arg_0):
    """
    Validate that a particular image extension.
    """
    arg_1 = get_app_config()
    arg_2 = os.path.splitext(arg_0.name)[1]
    if arg_1 and not arg_2.lower() in arg_1.valid_image_extensions:
        raise ValidationError(_("Unsupported file extension."))


def Func(arg_0):
    """
    Get the enterprise customer id given an enterprise customer catalog id.
    """
    try:
        return str(EnterpriseCustomerCatalog.objects.get(pk=arg_0).enterprise_customer.uuid)
    except EnterpriseCustomerCatalog.DoesNotExist:
        return None


def Func(arg_0):  # pylint: disable=unused-argument
    """
    Run sphinx-apidoc after Sphinx initialization.

    Read the Docs won't run tox or custom shell commands, so we need this to
    avoid checking in the generated reStructuredText files.
    """
    arg_1 = os.path.abspath(os.path.dirname(__file__))
    arg_2 = os.path.abspath(os.path.join(arg_1, '..'))
    arg_3 = 'sphinx-apidoc'
    if hasattr(sys, 'real_prefix'):  # Check to see if we are in a virtualenv
        # If we are, assemble the path manually
        arg_4 = os.path.abspath(os.path.join(sys.prefix, 'bin'))
        arg_3 = os.path.join(arg_4, arg_3)
    check_call([arg_3, '-o', arg_1, os.path.join(arg_2, 'enterprise'),
                os.path.join(arg_2, 'enterprise/migrations')])


def Func(arg_0):
        """
        Returns the enterprise customer requested for the given uuid, None if not.

        Raises CommandError if uuid is invalid.
        """
        if arg_0 is None:
            return None
        try:
            return EnterpriseCustomer.active_customers.get(arg_0=arg_0)
        except EnterpriseCustomer.DoesNotExist:
            raise CommandError(
                _('Enterprise customer {uuid} not found, or not active').format(arg_0=arg_0))


def Func(arg_0):
        """
        Assemble a list of integrated channel classes to transmit to.

        If a valid channel type was provided, use it.

        Otherwise, use all the available channel types.
        """
        if arg_0:
            # Channel code is case-insensitive
            arg_0 = arg_0.upper()

            if arg_0 not in INTEGRATED_CHANNEL_CHOICES:
                raise CommandError(_('Invalid integrated channel: {channel}').format(channel=arg_0))

            arg_1 = [INTEGRATED_CHANNEL_CHOICES[arg_0]]
        else:
            arg_1 = INTEGRATED_CHANNEL_CHOICES.values()

        return arg_1


def Func(arg_0):
    """
    Get the contents of a file listing the requirements
    """
    arg_1 = open(arg_0).readlines()
    arg_2 = []
    arg_3 = []

    for arg_4 in arg_1:
        arg_5 = arg_4.strip()
        if arg_5.startswith('#'):
            # Skip pure comment lines
            continue

        if any(arg_5.startswith(arg_6) for arg_6 in VCS_PREFIXES):
            # VCS reference for dev purposes, expect a trailing comment
            # with the normal requirement
            arg_7, arg_8, arg_5 = arg_5.rpartition('#')

            # Remove -e <version_control> string
            arg_7 = re.sub(r'(.*)(?P<dependency_link>https?.*$)', r'\g<dependency_link>', arg_7)
            arg_5 = re.sub(r'(egg=)?(?P<package_name>.*)==.*$', r'\g<package_name>', arg_5)
            arg_9 = re.sub(r'.*[^=]==', '', arg_4.strip())

            if arg_5:
                arg_3.append(
                    '{package_link}#egg={package}-{package_version}'.format(
                        arg_7=arg_7,
                        arg_5=arg_5,
                        arg_9=arg_9,
                    )
                )
        else:
            # Ignore any trailing comment
            arg_5, arg_8, arg_8 = arg_5.partition('#')
            # Remove any whitespace and assume non-empty results are dependencies
            arg_5 = arg_5.strip()

        if arg_5:
            arg_2.append(arg_5)
    return arg_2, arg_3


def Func(arg_0, arg_1):
        """
        Iterate over each learner data record and transmit it to the integrated channel.
        """
        arg_2 = arg_0.get_learner_data_exporter(arg_1)
        arg_3 = arg_0.get_learner_data_transmitter()
        arg_3.transmit(arg_2)


def Func(arg_0, arg_1):
        """
        Transmit content metadata to integrated channel.
        """
        arg_2 = arg_0.get_content_metadata_exporter(arg_1)
        arg_3 = arg_0.get_content_metadata_transmitter()
        arg_3.transmit(arg_2.export())


def Func(
            arg_0,
            arg_1,
            arg_2=None,
            arg_3=False,
            **arg_4
    ):  # pylint: disable=arguments-differ,unused-argument
        """
        Return a DegreedLearnerDataTransmissionAudit with the given enrollment and course completion data.

        If completed_date is None, then course completion has not been met.

        If no remote ID can be found, return None.
        """
        # Degreed expects completion dates of the form 'yyyy-mm-dd'.
        arg_5 = arg_2.strftime("%F") if isinstance(arg_2, datetime) else None
        if arg_1.enterprise_customer_user.get_remote_id() is not None:
            arg_6 = apps.get_model(  # pylint: disable=invalid-name
                'degreed',
                'DegreedLearnerDataTransmissionAudit'
            )
            # We return two records here, one with the course key and one with the course run id, to account for
            # uncertainty about the type of content (course vs. course run) that was sent to the integrated channel.
            return [
                arg_6(
                    enterprise_course_enrollment_id=arg_1.id,
                    degreed_user_email=arg_1.enterprise_customer_user.user_email,
                    course_id=parse_course_key(arg_1.course_id),
                    course_completed=arg_2 is not None and arg_3,
                    arg_5=arg_5,
                ),
                arg_6(
                    enterprise_course_enrollment_id=arg_1.id,
                    degreed_user_email=arg_1.enterprise_customer_user.user_email,
                    course_id=arg_1.course_id,
                    course_completed=arg_2 is not None and arg_3,
                    arg_5=arg_5,
                )
            ]
        else:
            LOGGER.debug(
                'No learner data was sent for user [%s] because a Degreed user ID could not be found.',
                arg_1.enterprise_customer_user.username
            )


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Render the given template with the stock data.
        """
        arg_4 = Func_object_or_404(EnrollmentNotificationEmailTemplate, pk=arg_2)
        if arg_3 not in arg_0.view_type_contexts:
            return HttpResponse(status=404)
        arg_5 = arg_0.view_type_contexts[arg_3].copy()
        arg_5.update({'user_name': arg_0.Func_user_name(arg_1)})
        return HttpResponse(arg_4.render_html_template(arg_5), content_type='text/html')


def Func(arg_0, arg_1):
        """
        Build common admin context.
        """
        arg_2 = arg_1._meta
        arg_3 = get_permission_codename('change', arg_2)
        arg_4 = arg_0.user.has_perm('%s.%s' % (arg_2.app_label, arg_3))
        return {
            'has_change_permission': arg_4,
            'opts': arg_2
        }


def Func(arg_0, arg_1, arg_2):
        """
        Handle GET request - render "Transmit courses metadata" form.

        Arguments:
            request (django.http.request.HttpRequest): Request instance
            enterprise_customer_uuid (str): Enterprise Customer UUID

        Returns:
            django.http.response.HttpResponse: HttpResponse
        """
        arg_3 = arg_0._build_context(arg_1, arg_2)
        arg_4 = TransmitEnterpriseCoursesForm()
        arg_3.update({arg_0.ContextParameters.TRANSMIT_COURSES_METADATA_FORM: arg_4})

        return render(arg_1, arg_0.template, arg_3)


def Func(arg_0, arg_1, arg_2):
        """
        Get the list of PendingEnterpriseCustomerUsers we want to render.

        Args:
            search_keyword (str): The keyword to search for in pending users' email addresses.
            customer_uuid (str): A unique identifier to filter down to only pending users
            linked to a particular EnterpriseCustomer.
        """
        arg_3 = PendingEnterpriseCustomerUser.objects.filter(
            enterprise_customer__uuid=arg_2
        )

        if arg_1 is not None:
            arg_3 = arg_3.filter(user_email__icontains=arg_1)

        return arg_3


def Func(arg_0, arg_1, arg_2):
        """
        Link single user by email or username.

        Arguments:
            enterprise_customer (EnterpriseCustomer): learners will be linked to this Enterprise Customer instance
            manage_learners_form (ManageLearnersForm): bound ManageLearners form instance
        """
        arg_3 = arg_2.cleaned_data[ManageLearnersForm.Fields.EMAIL_OR_USERNAME]
        arg_4 = email_or_username__to__email(arg_3)
        try:
            validate_email_to_link(arg_4, arg_3, ValidationMessages.INVALID_EMAIL_OR_USERNAME, True)
        except ValidationError as exc:
            arg_2.add_error(ManageLearnersForm.Fields.EMAIL_OR_USERNAME, exc)
        else:
            EnterpriseCustomerUser.objects.link_user(arg_1, arg_4)
            return [arg_4]


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None):
        """
        Bulk link users by email.

        Arguments:
            enterprise_customer (EnterpriseCustomer): learners will be linked to this Enterprise Customer instance
            manage_learners_form (ManageLearnersForm): bound ManageLearners form instance
            request (django.http.request.HttpRequest): HTTP Request instance
            email_list (iterable): A list of pre-processed email addresses to handle using the form
        """
        arg_5 = []
        arg_6 = set()
        arg_7 = []
        arg_8 = []
        arg_9 = arg_2.cleaned_data[ManageLearnersForm.Fields.BULK_UPLOAD]
        if arg_4:
            arg_10 = [{ManageLearnersForm.CsvColumns.EMAIL: arg_13} for arg_13 in arg_4]
        else:
            arg_10 = parse_csv(arg_9, expected_columns={ManageLearnersForm.CsvColumns.EMAIL})

        try:
            for arg_11, arg_12 in enumerate(arg_10):
                arg_13 = arg_12[ManageLearnersForm.CsvColumns.EMAIL]
                try:
                    arg_14 = validate_email_to_link(arg_13, ignore_existing=True)
                except ValidationError as exc:
                    arg_15 = _("Error at line {line}: {message}\n").format(line=arg_11 + 1, arg_15=exc)
                    arg_5.append(arg_15)
                else:
                    if arg_14:
                        arg_7.append((arg_13, arg_14.enterprise_customer))
                    elif arg_13 in arg_6:
                        arg_8.append(arg_13)
                    else:
                        arg_6.add(arg_13)
        except ValidationError as exc:
            arg_5.append(exc)

        if arg_5:
            arg_2.add_error(
                ManageLearnersForm.Fields.GENERAL_ERRORS, ValidationMessages.BULK_LINK_FAILED
            )
            for arg_16 in arg_5:
                arg_2.add_error(ManageLearnersForm.Fields.BULK_UPLOAD, arg_16)
            return

        # There were no errors. Now do the actual linking:
        for arg_13 in arg_6:
            EnterpriseCustomerUser.objects.link_user(arg_1, arg_13)

        # Report what happened:
        arg_17 = len(arg_6)
        messages.success(arg_3, ungettext(
            "{count} new learner was added to {enterprise_customer_name}.",
            "{count} new learners were added to {enterprise_customer_name}.",
            arg_17
        ).format(arg_17=arg_17, enterprise_customer_name=arg_1.name))
        arg_18 = [
            arg_13 for arg_13, customer in arg_7 if customer == arg_1
        ]
        arg_19 = [
            arg_13 for arg_13, __ in arg_7 if arg_13 not in arg_18
        ]
        if arg_18:
            messages.warning(
                arg_3,
                _(
                    "The following learners were already associated with this Enterprise "
                    "Customer: {list_of_emails}"
                ).format(
                    list_of_emails=", ".join(arg_18)
                )
            )
        if arg_19:
            messages.warning(
                arg_3,
                _(
                    "The following learners are already associated with "
                    "another Enterprise Customer. These learners were not "
                    "added to {enterprise_customer_name}: {list_of_emails}"
                ).format(
                    enterprise_customer_name=arg_1.name,
                    list_of_emails=", ".join(arg_19),
                )
            )
        if arg_8:
            messages.warning(
                arg_3,
                _(
                    "The following duplicate email addresses were not added: "
                    "{list_of_emails}"
                ).format(
                    list_of_emails=", ".join(arg_8)
                )
            )
        # Build a list of all the emails that we can act on further; that is,
        # emails that we either linked to this customer, or that were linked already.
        arg_20 = list(arg_6) + arg_18

        return arg_20


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Query the enrollment API and determine if a learner is enrolled in a given course run track.

        Args:
            user: The user whose enrollment needs to be checked
            course_mode: The mode with which the enrollment should be checked
            course_id: course id of the course where enrollment should be checked.

        Returns:
            Boolean: Whether or not enrollment exists

        """
        arg_4 = EnrollmentApiClient()
        try:
            arg_5 = arg_4.get_course_enrollment(arg_1.username, arg_2)
            if arg_5 and arg_3 == arg_5.get('mode'):
                return True
        except HttpClientError as exc:
            logging.error(
                'Error while checking enrollment status of user %(user)s: %(message)s',
                dict(arg_1=arg_1.username, message=str(exc))
            )
        except KeyError as exc:
            logging.warning(
                'Error while parsing enrollment data of user %(user)s: %(message)s',
                dict(arg_1=arg_1.username, message=str(exc))
            )
        return False


def Func(arg_0, arg_1):
        """
        Accept a list of emails, and separate them into users that exist on OpenEdX and users who don't.

        Args:
            emails: An iterable of email addresses to split between existing and nonexisting

        Returns:
            users: Queryset of users who exist in the OpenEdX platform and who were in the list of email addresses
            missing_emails: List of unique emails which were in the original list, but do not yet exist as users
        """
        arg_2 = User.objects.filter(email__in=arg_1)
        arg_3 = arg_2.values_list('email', flat=True)
        arg_4 = list(set(arg_1) - set(arg_3))
        return arg_2, arg_4


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5=None):
        """
        Enroll existing users in all courses in a program, and create pending enrollments for nonexisting users.

        Args:
            enterprise_customer: The EnterpriseCustomer which is sponsoring the enrollment
            program_details: The details of the program in which we're enrolling
            course_mode (str): The mode with which we're enrolling in the program
            emails: An iterable of email addresses which need to be enrolled

        Returns:
            successes: A list of users who were successfully enrolled in all courses of the program
            pending: A list of PendingEnterpriseCustomerUsers who were successfully linked and had
                pending enrollments created for them in the database
            failures: A list of users who could not be enrolled in the program
        """
        arg_6, arg_7 = arg_0.get_users_by_email(arg_4)
        arg_8 = get_course_runs_from_program(arg_2)

        arg_9 = []
        arg_10 = []
        arg_11 = []

        for arg_12 in arg_6:
            arg_13 = arg_0.enroll_user(arg_1, arg_12, arg_3, *arg_8)
            if arg_13:
                arg_9.append(arg_12)
            else:
                arg_11.append(arg_12)

        for arg_14 in arg_7:
            arg_15 = arg_1.enroll_user_pending_registration(
                arg_14,
                arg_3,
                *arg_8,
                arg_5=arg_5
            )
            arg_10.append(arg_15)

        return arg_9, arg_10, arg_11


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """
        Enroll existing users in a course, and create a pending enrollment for nonexisting users.

        Args:
            enterprise_customer: The EnterpriseCustomer which is sponsoring the enrollment
            course_id (str): The unique identifier of the course in which we're enrolling
            course_mode (str): The mode with which we're enrolling in the course
            emails: An iterable of email addresses which need to be enrolled

        Returns:
            successes: A list of users who were successfully enrolled in the course
            pending: A list of PendingEnterpriseCustomerUsers who were successfully linked and had
                pending enrollments created for them in the database
            failures: A list of users who could not be enrolled in the course
        """
        arg_5, arg_6 = arg_0.get_users_by_email(arg_4)

        arg_7 = []
        arg_8 = []
        arg_9 = []

        for arg_10 in arg_5:
            arg_11 = arg_0.enroll_user(arg_1, arg_10, arg_3, arg_2)
            if arg_11:
                arg_7.append(arg_10)
            else:
                arg_9.append(arg_10)

        for arg_12 in arg_6:
            arg_13 = arg_1.enroll_user_pending_registration(
                arg_12,
                arg_3,
                arg_2
            )
            arg_8.append(arg_13)

        return arg_7, arg_8, arg_9


def Func(arg_0, arg_1, arg_2):
        """
        Deduplicate any outgoing message requests, and send the remainder.

        Args:
            http_request: The HTTP request in whose response we want to embed the messages
            message_requests: A list of undeduplicated messages in the form of tuples of message type
                and text- for example, ('error', 'Something went wrong')
        """
        arg_3 = set(arg_2)
        for arg_4, arg_5 in arg_3:
            arg_6 = getattr(messages, arg_4)
            arg_6(arg_1, arg_5)


def Func(arg_0, arg_1, arg_2):
        """
        Create message for the users who were not able to be enrolled in a course or program.

        Args:
            users: An iterable of users who were not successfully enrolled
            enrolled_in (str): A string identifier for the course or program with which enrollment was attempted

        Returns:
        tuple: A 2-tuple containing a message type and message text
        """
        arg_3 = [user.email for user in arg_1]
        return (
            'error',
            _(
                'The following learners could not be enrolled in {enrolled_in}: {user_list}'
            ).format(
                arg_2=arg_2,
                user_list=', '.join(arg_3),
            )
        )


def Func(
            arg_0,
            arg_1,
            arg_2,
            arg_3,
            arg_4,
            arg_5=None,
            arg_6=None,
            arg_7=True
    ):
        """
        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
        """
        arg_8 = []

        if arg_5:
            arg_9, arg_10, arg_11 = arg_0.enroll_users_in_course(
                arg_2=arg_2,
                arg_5=arg_5,
                course_mode=arg_4,
                arg_3=arg_3,
            )
            arg_12 = arg_9 + arg_10
            if arg_7:
                arg_2.notify_enrolled_learners(
                    catalog_api_user=arg_1.user,
                    arg_5=arg_5,
                    users=arg_12,
                )
            if arg_9:
                arg_8.append(arg_0.get_success_enrollment_message(arg_9, arg_5))
            if arg_11:
                arg_8.append(arg_0.get_failed_enrollment_message(arg_11, arg_5))
            if arg_10:
                arg_8.append(arg_0.get_pending_enrollment_message(arg_10, arg_5))

        if arg_6:
            arg_9, arg_10, arg_11 = arg_0.enroll_users_in_program(
                arg_2=arg_2,
                arg_6=arg_6,
                course_mode=arg_4,
                arg_3=arg_3,
            )
            arg_12 = arg_9 + arg_10
            if arg_7:
                arg_0.notify_program_learners(
                    arg_2=arg_2,
                    arg_6=arg_6,
                    users=arg_12
                )
            arg_13 = arg_6.get('title', arg_6.get('uuid', _('the program')))
            if arg_9:
                arg_8.append(arg_0.get_success_enrollment_message(arg_9, arg_13))
            if arg_11:
                arg_8.append(arg_0.get_failed_enrollment_message(arg_11, arg_13))
            if arg_10:
                arg_8.append(arg_0.get_pending_enrollment_message(arg_10, arg_13))

        arg_0.send_messages(arg_1, arg_8)


def Func(arg_0, arg_1, arg_2):
        """
        Handle DELETE request - handle unlinking learner.

        Arguments:
            request (django.http.request.HttpRequest): Request instance
            customer_uuid (str): Enterprise Customer UUID

        Returns:
            django.http.response.HttpResponse: HttpResponse
        """
        # TODO: pylint acts stupid - find a way around it without suppressing
        arg_3 = EnterpriseCustomer.objects.get(uuid=arg_2)  # pylint: disable=no-member
        arg_4 = arg_1.GET["unlink_email"]
        try:
            EnterpriseCustomerUser.objects.unlink_user(
                arg_3=arg_3, user_email=arg_4
            )
        except (EnterpriseCustomerUser.DoesNotExist, PendingEnterpriseCustomerUser.DoesNotExist):
            arg_5 = _("Email {email} is not associated with Enterprise "
                        "Customer {ec_name}").format(
                            email=arg_4, ec_name=arg_3.name)
            return HttpResponse(arg_5, content_type="application/json", status=404)

        return HttpResponse(
            json.dumps({}),
            content_type="application/json"
        )


def Func(arg_0, arg_1, *arg_2):
        """
        Build a ProxyDataSharingConsent using the details of the received consent records.
        """
        if not arg_2 or any(arg_3 is None for arg_3 in arg_2):
            return None
        arg_4 = all((arg_3.granted for arg_3 in arg_2))
        arg_5 = any((arg_3.exists for arg_3 in arg_2))
        arg_6 = set([arg_3.username for arg_3 in arg_2])
        arg_7 = set([arg_3.enterprise_customer for arg_3 in arg_2])
        if not len(arg_6) == len(arg_7) == 1:
            raise InvalidProxyConsent(
                'Children used to create a bulk proxy consent object must '
                'share a single common username and EnterpriseCustomer.'
            )
        arg_8 = arg_2[0].username
        arg_9 = arg_2[0].enterprise_customer
        return arg_0(
            arg_9=arg_9,
            arg_8=arg_8,
            arg_1=arg_1,
            arg_5=arg_5,
            arg_4=arg_4,
            child_consents=arg_2
        )


def Func(arg_0):
        """
        Commit a real ``DataSharingConsent`` object to the database, mirroring current field settings.

        :return: A ``DataSharingConsent`` object if validation is successful, otherwise ``None``.
        """
        if arg_0._child_consents:
            arg_1 = []

            for arg_2 in arg_0._child_consents:
                arg_2.granted = arg_0.granted
                arg_1.append(arg_2.save() or arg_2)

            return ProxyDataSharingConsent.from_children(arg_0.program_uuid, *arg_1)

        arg_2, arg_4 = DataSharingConsent.objects.update_or_create(
            enterprise_customer=arg_0.enterprise_customer,
            username=arg_0.username,
            course_id=arg_0.course_id,
            defaults={
                'granted': arg_0.granted
            }
        )
        arg_0._exists = arg_2.exists
        return arg_2


def Func(arg_0, arg_1, arg_2):
        """
        Get course completions via PersistentCourseGrade for all the learners of given enterprise customer.

        Arguments:
            enterprise_customer (EnterpriseCustomer): Include Course enrollments for learners
                of this enterprise customer.
            days (int): Include course enrollment of this number of days.

        Returns:
            (list): A list of PersistentCourseGrade objects.
        """
        return PersistentCourseGrade.objects.filter(
            passed_timestamp__gt=datetime.datetime.now() - datetime.timedelta(arg_2=arg_2)
        ).filter(
            user_id__in=arg_1.enterprise_customer_users.values_list('user_id', flat=True)
        )


def Func(arg_0):
        """
        Prefetch Users from the list of user_ids present in the persistent_course_grades.

        Arguments:
            persistent_course_grades (list): A list of PersistentCourseGrade.

        Returns:
            (dict): A dictionary containing user_id to user mapping.
        """
        arg_1 = User.objects.filter(
            id__in=[grade.user_id for grade in arg_0]
        )
        return {
            arg_2.id: arg_2 for arg_2 in arg_1
        }


def Func(arg_0):
    """
    Get Identity Provider with given id.

    Return:
        Instance of ProviderConfig or None.
    """
    try:
        from third_party_auth.provider import arg_1   # pylint: disable=redefined-outer-name
    except ImportError as exception:
        LOGGER.warning("Could not import Registry from third_party_auth.provider")
        LOGGER.warning(exception)
        arg_1 = None  # pylint: disable=redefined-outer-name

    try:
        return arg_1 and arg_1.get(arg_0)
    except ValueError:
        return None


def Func(arg_0='change'):
    """
    Get template of catalog admin url.

    URL template will contain a placeholder '{catalog_id}' for catalog id.
    Arguments:
        mode e.g. change/add.

    Returns:
        A string containing template for catalog url.

    Example:
        >>> Func('change')
        "http://localhost:18381/admin/catalogs/catalog/{catalog_id}/change/"

    """
    arg_1 = getattr(settings, "COURSE_CATALOG_API_URL", "")

    # Extract FQDN (Fully Qualified Domain Name) from API URL.
    arg_2 = re.match(r"^(?P<fqdn>(?:https?://)?[^/]+)", arg_1)

    if not arg_2:
        return ""

    # Return matched FQDN from catalog api url appended with catalog admin path
    if arg_0 == 'change':
        return arg_2.group("fqdn").rstrip("/") + "/admin/catalogs/catalog/{catalog_id}/change/"
    elif arg_0 == 'add':
        return arg_2.group("fqdn").rstrip("/") + "/admin/catalogs/catalog/add/"


def Func(arg_0, arg_1=None):
    """
    Create HTML and plaintext message bodies for a notification.

    We receive a context with data we can use to render, as well as an optional site
    template configration - if we don't get a template configuration, we'll use the
    standard, built-in template.

    Arguments:
        template_context (dict): A set of data to render
        template_configuration: A database-backed object with templates
            stored that can be used to render a notification.

    """
    if (
            arg_1 is not None and
            arg_1.html_template and
            arg_1.plaintext_template
    ):
        arg_2, arg_3 = arg_1.render_all_templates(arg_0)
    else:
        arg_2 = render_to_string(
            'enterprise/emails/user_notification.txt',
            arg_0
        )
        arg_3 = render_to_string(
            'enterprise/emails/user_notification.html',
            arg_0
        )

    return arg_2, arg_3


def Func(arg_0, arg_1=None):
    """
    Get a subject line for a notification email.

    The method is designed to fail in a "smart" way; if we can't render a
    database-backed subject line template, then we'll fall back to a template
    saved in the Django settings; if we can't render _that_ one, then we'll
    fall through to a friendly string written into the code.

    One example of a failure case in which we want to fall back to a stock template
    would be if a site admin entered a subject line string that contained a template
    tag that wasn't available, causing a KeyError to be raised.

    Arguments:
        course_name (str): Course name to be rendered into the string
        template_configuration: A database-backed object with a stored subject line template

    """
    arg_2 = _('You\'ve been enrolled in {course_name}!')
    arg_3 = getattr(
        settings,
        'ENTERPRISE_ENROLLMENT_EMAIL_DEFAULT_SUBJECT_LINE',
        arg_2,
    )
    if arg_1 is not None and arg_1.subject_line:
        arg_4 = arg_1.subject_line
    else:
        arg_4 = arg_3

    try:
        return arg_4.format(arg_0=arg_0)
    except KeyError:
        pass

    try:
        return arg_3.format(arg_0=arg_0)
    except KeyError:
        return arg_2.format(arg_0=arg_0)


def Func(arg_0, arg_1, arg_2, arg_3=None):
    """
    Send an email notifying a user about their enrollment in a course.

    Arguments:
        user: Either a User object or a PendingEnterpriseCustomerUser that we can use
            to get details for the email
        enrolled_in (dict): The dictionary contains details of the enrollable object
            (either course or program) that the user enrolled in. This MUST contain
            a `name` key, and MAY contain the other following keys:
                - url: A human-friendly link to the enrollable's home page
                - type: Either `course` or `program` at present
                - branding: A special name for what the enrollable "is"; for example,
                    "MicroMasters" would be the branding for a "MicroMasters Program"
                - start: A datetime object indicating when the enrollable will be available.
        enterprise_customer: The EnterpriseCustomer that the enrollment was created using.
        email_connection: An existing Django email connection that can be used without
            creating a new connection for each individual message

    """
    if hasattr(arg_0, 'first_name') and hasattr(arg_0, 'username'):
        # PendingEnterpriseCustomerUsers don't have usernames or real names. We should
        # template slightly differently to make sure weird stuff doesn't happen.
        arg_4 = arg_0.first_name
        if not arg_4:
            arg_4 = arg_0.username
    else:
        arg_4 = None

    # Users have an `email` attribute; PendingEnterpriseCustomerUsers have `user_email`.
    if hasattr(arg_0, 'email'):
        arg_5 = arg_0.email
    elif hasattr(arg_0, 'user_email'):
        arg_5 = arg_0.user_email
    else:
        raise TypeError(_('`user` must have one of either `email` or `user_email`.'))

    arg_6 = {
        'user_name': arg_4,
        'enrolled_in': arg_1,
        'organization_name': arg_2.name,
    }
    try:
        arg_7 = arg_2.enterprise_enrollment_template
    except (ObjectDoesNotExist, AttributeError):
        arg_7 = None

    arg_8, arg_9 = build_notification_message(arg_6, arg_7)

    arg_10 = get_notification_subject_line(arg_1['name'], arg_7)

    arg_11 = get_configuration_value_for_site(
        arg_2.site,
        'DEFAULT_FROM_EMAIL',
        default=settings.DEFAULT_FROM_EMAIL
    )

    return mail.send_mail(
        arg_10,
        arg_8,
        arg_11,
        [arg_5],
        html_message=arg_9,
        connection=arg_3
    )


def Func(arg_0):
    """
    Get the ``EnterpriseCustomer`` instance associated with ``uuid``.

    :param uuid: The universally unique ID of the enterprise customer.
    :return: The ``EnterpriseCustomer`` instance, or ``None`` if it doesn't exist.
    """
    arg_1 = apps.get_model('enterprise', 'EnterpriseCustomer')  # pylint: disable=invalid-name
    try:
        return arg_1.objects.get(arg_0=arg_0)  # pylint: disable=no-member
    except arg_1.DoesNotExist:
        return None


def Func(arg_0, arg_1):
    """
    Return track selection url for the given course.

    Arguments:
        course_run (dict): A dictionary containing course run metadata.
        query_parameters (dict): A dictionary containing query parameters to be added to course selection url.

    Raises:
        (KeyError): Raised when course run dict does not have 'key' key.

    Returns:
        (str): Course track selection url.

    """
    try:
        arg_2 = reverse('course_modes_choose', kwargs={'course_id': arg_0['key']})
    except KeyError:
        LOGGER.exception(
            "KeyError while parsing course run data.\nCourse Run: \n[%s]", arg_0,
        )
        raise

    arg_3 = '{}{}'.format(
        settings.LMS_ROOT_URL,
        arg_2
    )
    arg_4 = update_query_parameters(arg_3, arg_1)

    return arg_4


def Func(arg_0):
    """
    Given an EnterpriseCustomer UUID, return the corresponding EnterpriseCustomer or raise a 404.

    Arguments:
        enterprise_uuid (str): The UUID (in string form) of the EnterpriseCustomer to fetch.

    Returns:
        (EnterpriseCustomer): The EnterpriseCustomer given the UUID.

    """
    arg_1 = apps.get_model('enterprise', 'EnterpriseCustomer')  # pylint: disable=invalid-name
    try:
        arg_0 = UUID(arg_0)
        return arg_1.objects.get(uuid=arg_0)  # pylint: disable=no-member
    except (TypeError, ValueError, arg_1.DoesNotExist):
        LOGGER.error('Unable to find enterprise customer for UUID: [%s]', arg_0)
        raise Http404


def Func(**arg_0):
    """
    Get MD5 encoded cache key for given arguments.

    Here is the format of key before MD5 encryption.
        key1:value1__key2:value2 ...

    Example:
        >>> Func(site_domain="example.com", resource="enterprise")
        # Here is key format for above call
        # "site_domain:example.com__resource:enterprise"
        a54349175618ff1659dee0978e3149ca

    Arguments:
        **kwargs: Key word arguments that need to be present in cache key.

    Returns:
         An MD5 encoded key uniquely identified by the key word arguments.
    """
    arg_1 = '__'.join(['{}:{}'.format(item, value) for item, value in iteritems(arg_0)])

    return hashlib.md5(arg_1.encode('utf-8')).hexdigest()


def Func(arg_0, arg_1):
    """
    Traverse a paginated API response.

    Extracts and concatenates "results" (list of dict) returned by DRF-powered
    APIs.

    Arguments:
        response (Dict): Current response dict from service API
        endpoint (slumber Resource object): slumber Resource object from edx-rest-api-client

    Returns:
        list of dict.

    """
    arg_2 = arg_0.get('results', [])

    arg_3 = arg_0.get('next')
    while arg_3:
        arg_4 = parse_qs(urlparse(arg_3).query, keep_blank_values=True)
        arg_0 = arg_1.get(**arg_4)
        arg_2 += arg_0.get('results', [])
        arg_3 = arg_0.get('next')

    return arg_2


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
    """
    Return grammatically correct, translated text based off of a minimum and maximum value.

    Example:
        min = 1, max = 1, singular = '{} hour required for this course', plural = '{} hours required for this course'
        output = '1 hour required for this course'

        min = 2, max = 2, singular = '{} hour required for this course', plural = '{} hours required for this course'
        output = '2 hours required for this course'

        min = 2, max = 4, range_text = '{}-{} hours required for this course'
        output = '2-4 hours required for this course'

        min = None, max = 2, plural = '{} hours required for this course'
        output = '2 hours required for this course'

    Expects ``range_text`` to already have a translation function called on it.

    Returns:
        ``None`` if both of the input values are ``None``.
        ``singular`` formatted if both are equal or one of the inputs, but not both, are ``None``, and the value is 1.
        ``plural`` formatted if both are equal or one of its inputs, but not both, are ``None``, and the value is > 1.
        ``range_text`` formatted if min != max and both are valid values.
    """
    if arg_3 is None and arg_4 is None:
        return None
    if arg_3 == arg_4 or arg_3 is None or arg_4 is None:
        # pylint: disable=translation-of-non-string
        return ungettext(arg_0, arg_1, arg_3 or arg_4).format(arg_3 or arg_4)
    return arg_2.format(arg_3, arg_4)


def Func(arg_0, arg_1='$'):
    """
    Format the price to have the appropriate currency and digits..

    :param price: The price amount.
    :param currency: The currency for the price.
    :return: A formatted price string, i.e. '$10', '$10.52'.
    """
    if int(arg_0) == arg_0:
        return '{}{}'.format(arg_1, int(arg_0))
    return '{}{:0.2f}'.format(arg_1, arg_0)


def Func(arg_0, arg_1, arg_2=None):
    """
    Get the site configuration value for a key, unless a site configuration does not exist for that site.

    Useful for testing when no Site Configuration exists in edx-enterprise or if a site in LMS doesn't have
    a configuration tied to it.

    :param site: A Site model object
    :param key: The name of the value to retrieve
    :param default: The default response if there's no key in site config or settings
    :return: The value located at that key in the site configuration or settings file.
    """
    if hasattr(arg_0, 'configuration'):
        return arg_0.configuration.get_value(arg_1, arg_2)
    return arg_2


def Func(arg_0, arg_1=None, **arg_2):
    """
    Get a configuration value, or fall back to ``default`` if it doesn't exist.

    Also takes a `type` argument to guide which particular upstream method to use when trying to retrieve a value.
    Current types include:
        - `url` to specifically get a URL.
    """
    if arg_2.get('type') == 'url':
        return get_url(arg_0) or arg_1 if callable(get_url) else arg_1
    return configuration_helpers.get_value(arg_0, arg_1, **arg_2) if configuration_helpers else arg_1


def Func(arg_0, arg_1, arg_2, arg_3=None):
    """
    Emit a track event for enterprise course enrollment.
    """
    track_event(arg_1, 'edx.bi.user.enterprise.onboarding', {
        'pathway': arg_0,
        'url_path': arg_3,
        'course_run_id': arg_2,
    })


def Func(arg_0):
    """
    Return true if the course run is enrollable, false otherwise.

    We look for the following criteria:
    - end is greater than now OR null
    - enrollment_start is less than now OR null
    - enrollment_end is greater than now OR null
    """
    arg_1 = datetime.datetime.now(pytz.UTC)
    arg_2 = parse_datetime_handle_invalid(arg_0.get('end'))
    arg_3 = parse_datetime_handle_invalid(arg_0.get('enrollment_start'))
    arg_4 = parse_datetime_handle_invalid(arg_0.get('enrollment_end'))
    return (not arg_2 or arg_2 > arg_1) and \
           (not arg_3 or arg_3 < arg_1) and \
           (not arg_4 or arg_4 > arg_1)


def Func(arg_0):
    """
    Return true if the course run has a verified seat with an unexpired upgrade deadline, false otherwise.
    """
    arg_1 = datetime.datetime.now(pytz.UTC)
    for arg_2 in arg_0.get('seats', []):
        if arg_2.get('type') == 'verified':
            arg_3 = parse_datetime_handle_invalid(arg_2.get('upgrade_deadline'))
            return not arg_3 or arg_3 > arg_1
    return False


def Func(arg_0):
    """
    Return course run with start date closest to now.
    """
    if len(arg_0) == 1:
        return arg_0[0]

    arg_1 = datetime.datetime.now(pytz.UTC)
    # course runs with no start date should be considered last.
    arg_2 = arg_1 - datetime.timedelta(days=3650)
    return min(arg_0, key=lambda x: abs(get_course_run_start(x, arg_2) - arg_1))


def Func(arg_0, arg_1):
    """
    Return the current course run on the following conditions.

    - If user has active course runs (already enrolled) then return course run with closest start date
    Otherwise it will check the following logic:
    - Course run is enrollable (see is_course_run_enrollable)
    - Course run has a verified seat and the upgrade deadline has not expired.
    - Course run start date is closer to now than any other enrollable/upgradeable course runs.
    - If no enrollable/upgradeable course runs, return course run with most recent start date.
    """
    arg_2 = None
    arg_3 = []
    arg_4 = arg_0['course_runs']

    if arg_1:
        arg_2 = get_closest_course_run(arg_1)
    else:
        for arg_5 in arg_4:
            if is_course_run_enrollable(arg_5) and is_course_run_upgradeable(arg_5):
                arg_3.append(arg_5)

        if not arg_3:
            # Consider all runs if there were not any enrollable/upgradeable ones.
            arg_3 = arg_4

        if arg_3:
            arg_2 = get_closest_course_run(arg_3)
    return arg_2


def Func(arg_0):
        """
        LRS client instance to be used for sending statements.
        """
        return RemoteLRS(
            version=arg_0.Func_configuration.version,
            endpoint=arg_0.Func_configuration.endpoint,
            auth=arg_0.Func_configuration.authorization_header,
        )


def Func(arg_0, arg_1):
        """
        Save xAPI statement.

        Arguments:
            statement (EnterpriseStatement): xAPI Statement to send to the LRS.

        Raises:
            ClientError: If xAPI statement fails to save.
        """
        arg_2 = arg_0.lrs.Func(arg_1)

        if not arg_2:
            raise ClientError('EnterpriseXAPIClient request failed.')


def Func(arg_0, arg_1):  # pylint: disable=unused-argument
    """
    Check that if request user has implicit access to `ENTERPRISE_DASHBOARD_ADMIN_ROLE` feature role.

    Returns:
        boolean: whether the request user has access or not
    """
    arg_2 = get_request_or_stub()
    arg_3 = get_decoded_jwt_from_request(arg_2)
    return request_user_has_implicit_access_via_jwt(arg_3, ENTERPRISE_DASHBOARD_ADMIN_ROLE)


def Func(arg_0, arg_1):  # pylint: disable=unused-argument
    """
    Check that if request user has implicit access to `ENTERPRISE_CATALOG_ADMIN_ROLE` feature role.

    Returns:
        boolean: whether the request user has access or not
    """
    arg_2 = get_request_or_stub()
    arg_3 = get_decoded_jwt_from_request(arg_2)
    return request_user_has_implicit_access_via_jwt(arg_3, ENTERPRISE_CATALOG_ADMIN_ROLE, arg_1)